Browse Source

Merge pull request #6 from jl777/beta

beta update
beta
ca333 8 years ago
committed by GitHub
parent
commit
9589ad5757
  1. 2
      .gitignore
  2. 8
      crypto777/OS_time.c
  3. 2
      crypto777/bitcoind_RPC.c
  4. 58
      iguana/dpow/dpow_prices.c
  5. 56
      iguana/exchanges/LP_coins.c
  6. 91
      iguana/exchanges/LP_commands.c
  7. 46
      iguana/exchanges/LP_forwarding.c
  8. 22
      iguana/exchanges/LP_include.h
  9. 89
      iguana/exchanges/LP_nativeDEX.c
  10. 135
      iguana/exchanges/LP_ordermatch.c
  11. 42
      iguana/exchanges/LP_prices.c
  12. 8
      iguana/exchanges/LP_remember.c
  13. 26
      iguana/exchanges/LP_rpc.c
  14. 315
      iguana/exchanges/LP_scan.c
  15. 65
      iguana/exchanges/LP_statemachine.c
  16. 20
      iguana/exchanges/LP_transaction.c
  17. 52
      iguana/exchanges/LP_utxos.c
  18. 86
      iguana/exchanges/README.md
  19. 2
      iguana/exchanges/autotrade
  20. 2
      iguana/exchanges/bestfit
  21. 4
      iguana/exchanges/client
  22. 4
      iguana/exchanges/client_osx
  23. 3
      iguana/exchanges/coins
  24. 6
      iguana/exchanges/install
  25. 2
      iguana/exchanges/inv
  26. 2
      iguana/exchanges/orderbook
  27. 3
      iguana/exchanges/ordermatch
  28. 1
      iguana/exchanges/passphrase
  29. 1
      iguana/exchanges/randval
  30. 2
      iguana/exchanges/register
  31. 4
      iguana/exchanges/run
  32. 4
      iguana/exchanges/run_osx
  33. 2
      iguana/exchanges/trade
  34. 1
      iguana/m_mm
  35. 3
      iguana/m_splitfund
  36. 1
      iguana/orderbooks.h

2
.gitignore

@ -471,3 +471,5 @@ iguana/marketmaker.dSYM/Contents/Info.plist
iguana/client
iguana/marketmaker.dSYM/Contents/Resources/DWARF/marketmaker
iguana/confs/97f18454bb61e9eb7a827cfbefe42fbf7ae2832dc74c4812bdaef8bcf5c10474

8
crypto777/OS_time.c

@ -578,8 +578,8 @@ int32_t OS_conv_unixtime(struct tai *tp,int32_t *secondsp,time_t timestamp) // g
int32_t conv_date(int32_t *secondsp,char *date)
{
char origdate[64],tmpdate[64]; int32_t year,month,day,hour,min,sec,len;
strcpy(origdate,date), strcpy(tmpdate,date), tmpdate[8 + 2] = 0;
char origdate[512],tmpdate[512]; int32_t year,month,day,hour,min,sec,len;
safecopy(origdate,date,sizeof(origdate)), safecopy(tmpdate,date,sizeof(tmpdate)), tmpdate[8 + 2] = 0;
year = atoi(tmpdate), month = atoi(tmpdate+5), day = atoi(tmpdate+8);
*secondsp = 0;
if ( (len= (int32_t)strlen(date)) <= 10 )
@ -591,8 +591,8 @@ int32_t conv_date(int32_t *secondsp,char *date)
if ( hour >= 0 && hour < 24 && min >= 0 && min < 60 && sec >= 0 && sec < 60 )
*secondsp = (3600*hour + 60*min + sec);
else printf("ERROR: seconds.%d %d %d %d, len.%d\n",*secondsp,hour,min,sec,len);
}
//printf("(%s) -> Y.%d M.%d D.%d %d:%d:%d\n",date,year,month,day,hour,min,sec);
//printf("(%s) -> Y.%d M.%d D.%d %d:%d:%d\n",date,year,month,day,hour,min,sec);
} //else printf("short len.(%s) from (%s)\n",date,origdate);
sprintf(origdate,"%d-%02d-%02d",year,month,day); //2015-07-25T22:34:31Z
if ( strcmp(tmpdate,origdate) != 0 )
{

2
crypto777/bitcoind_RPC.c

@ -204,7 +204,7 @@ try_again:
numretries++;
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,s.ptr,res);
free(s.ptr);
return(0);
}

58
iguana/dpow/dpow_prices.c

@ -1275,25 +1275,33 @@ int32_t PAX_ecbparse(char *date,double *prices,char *url,int32_t basenum)
printf("(%s)\n",jsonstr);
if ( (json= cJSON_Parse(jsonstr)) != 0 )
{
copy_cJSON(&tmp,jobj(json,"date")), safecopy(date,tmp.buf,64);
if ( (basestr= jstr(json,"base")) != 0 && strcmp(basestr,CURRENCIES[basenum]) == 0 && (ratesobj= jobj(json,"rates")) != 0 && (item= ratesobj->child) != 0 )
if ( jobj(json,"error") != 0 || jobj(json,"date") == 0 )
{
while ( item != 0 )
printf("Got error from fixer.io (%s)\n",jsonstr);
sleep(10);
}
else
{
copy_cJSON(&tmp,jobj(json,"date")), safecopy(date,tmp.buf,64);
if ( (basestr= jstr(json,"base")) != 0 && strcmp(basestr,CURRENCIES[basenum]) == 0 && (ratesobj= jobj(json,"rates")) != 0 && (item= ratesobj->child) != 0 )
{
if ( (relstr= get_cJSON_fieldname(item)) != 0 && (relnum= PAX_basenum(relstr)) >= 0 )
while ( item != 0 )
{
i = basenum*MAX_CURRENCIES + relnum;
prices[i] = item->valuedouble;
//if ( basenum == JPYNUM )
// prices[i] *= 100.;
// else if ( relnum == JPYNUM )
// prices[i] /= 100.;
count++;
if ( Debuglevel > 2 )
printf("(%02d:%02d %f) ",basenum,relnum,prices[i]);
sprintf(name,"%s%s",CURRENCIES[basenum],CURRENCIES[relnum]);
} else printf("cant find.(%s)\n",relstr);//, getchar();
item = item->next;
if ( (relstr= get_cJSON_fieldname(item)) != 0 && (relnum= PAX_basenum(relstr)) >= 0 )
{
i = basenum*MAX_CURRENCIES + relnum;
prices[i] = item->valuedouble;
//if ( basenum == JPYNUM )
// prices[i] *= 100.;
// else if ( relnum == JPYNUM )
// prices[i] /= 100.;
count++;
if ( Debuglevel > 2 )
printf("(%02d:%02d %f) ",basenum,relnum,prices[i]);
sprintf(name,"%s%s",CURRENCIES[basenum],CURRENCIES[relnum]);
} else printf("cant find.(%s)\n",relstr);//, getchar();
item = item->next;
}
}
}
free_json(json);
@ -1322,12 +1330,13 @@ int32_t PAX_ecbprices(char *date,double *prices,int32_t year,int32_t month,int32
{
for (basenum=0; basenum<sizeof(CURRENCIES)/sizeof(*CURRENCIES); basenum++)
{
if ( strcmp(CURRENCIES[basenum],"XAU") == 0 )
if ( strcmp(CURRENCIES[basenum],"XAU") == 0 || basenum >= MAX_CURRENCIES )
break;
if ( iter == 0 )
{
sprintf(url,"%s%s",baseurl,CURRENCIES[basenum]);
count += PAX_ecbparse(basenum == 0 ? date : tmpdate,prices,url,basenum);
usleep(100000);
if ( (basenum != 0 && strcmp(tmpdate,date) != 0) || (checkdate[0] != 0 && strcmp(checkdate,date) != 0) )
{
//printf("date mismatch (%s) != (%s) or checkdate.(%s)\n",tmpdate,date,checkdate);
@ -1338,7 +1347,7 @@ int32_t PAX_ecbprices(char *date,double *prices,int32_t year,int32_t month,int32
{
for (nonz=i=0; i<sizeof(CURRENCIES)/sizeof(*CURRENCIES); i++)
{
if ( strcmp(CURRENCIES[i],"XAU") == 0 )
if ( strcmp(CURRENCIES[i],"XAU") == 0 || i >= MAX_CURRENCIES )
break;
if ( prices[MAX_CURRENCIES*basenum + i] != 0. )
nonz++;
@ -1358,6 +1367,7 @@ int32_t ecb_matrix(double basevals[MAX_CURRENCIES],double matrix[MAX_CURRENCIES]
FILE *fp=0; double price,bid,ask; int32_t n=0,datenum,relid,baseid,year=0,seconds,month=0,day=0,loaded = 0; char name[16],fname[64],_date[64];
if ( date == 0 )
date = _date, memset(_date,0,sizeof(_date));
//printf("ecb_matrix(%s)\n",date);
sprintf(fname,"%s/ECB/%s",GLOBAL_DBDIR,date), OS_compatible_path(fname);
if ( date[0] != 0 && (fp= fopen(fname,"rb")) != 0 )
{
@ -1365,7 +1375,7 @@ int32_t ecb_matrix(double basevals[MAX_CURRENCIES],double matrix[MAX_CURRENCIES]
loaded = 1;
else printf("fread error\n");
fclose(fp);
} //else printf("ecb_matrix.(%s) load error fp.%p\n",fname,fp);
} else printf("ecb_matrix.(%s) load error fp.%p\n",fname,fp);
datenum = conv_date(&seconds,date);
year = datenum / 10000, month = (datenum / 100) % 100, day = (datenum % 100);
if ( loaded == 0 )
@ -1779,13 +1789,20 @@ double PAX_val(uint32_t pval,int32_t baseid)
void PAX_genecbsplines(struct PAX_data *dp)
{
static portable_mutex_t mutex; static int32_t initflag;
int32_t i,j,datenum,seconds,numsamples; double prices[128][MAX_SPLINES],splineval,diff; uint32_t pvals[MAX_CURRENCIES],utc32[MAX_SPLINES],timestamp; struct tai t;
if ( initflag == 0 )
{
portable_mutex_init(&mutex);
initflag = 1;
}
portable_mutex_lock(&mutex);
for (i=numsamples=0; i<28; i++)
{
datenum = OS_conv_unixtime(&t,&seconds,(uint32_t)time(NULL)-(28-i+1)*24*3600);
expand_datenum(dp->edate,datenum);
timestamp = OS_conv_datenum(datenum,12,0,0);
//printf("i.%d datenum.%d %s t%u\n",i,datenum,dp->edate,timestamp);
printf("i.%d datenum.%d %s t%u\n",i,datenum,dp->edate,timestamp);
if ( (datenum= ecb_matrix(dp->basevals,dp->ecbmatrix,dp->edate)) > 0 )
{
utc32[numsamples] = timestamp;
@ -1812,6 +1829,7 @@ void PAX_genecbsplines(struct PAX_data *dp)
//printf("%s splineval %f vs %f %f %f\n",CURRENCIES[j],prices[j][numsamples-1],prices[j][numsamples],prices[j][numsamples+1],prices[j][numsamples+2]);
PAX_genspline(&dp->splines[j],j,CURRENCIES[j],utc32,prices[j],numsamples+3,prices[j]);
}
portable_mutex_unlock(&mutex);
}
int32_t PAX_idle(struct supernet_info *myinfo)//struct PAX_data *argdp,int32_t idlegap)

56
iguana/exchanges/LP_coins.c

@ -173,15 +173,37 @@ cJSON *LP_coinjson(struct iguana_info *coin)
return(item);
}
static struct iguana_info *LP_coins; static int32_t LP_numcoins;
cJSON *LP_coinsjson()
{
int32_t i; cJSON *array = cJSON_CreateArray();
for (i=0; i<LP_numcoins; i++)
jaddi(array,LP_coinjson(&LP_coins[i]));
struct iguana_info *coin,*tmp; cJSON *array = cJSON_CreateArray();
HASH_ITER(hh,LP_coins,coin,tmp)
{
jaddi(array,LP_coinjson(coin));
}
return(array);
}
struct iguana_info *LP_coinsearch(char *symbol)
{
struct iguana_info *coin;
portable_mutex_lock(&LP_coinmutex);
HASH_FIND(hh,LP_coins,symbol,strlen(symbol),coin);
portable_mutex_unlock(&LP_coinmutex);
return(coin);
}
struct iguana_info *LP_coinadd(struct iguana_info *cdata)
{
struct iguana_info *coin = calloc(1,sizeof(*coin));
//printf("%s: (%s) (%s)\n",symbol,cdata.serverport,cdata.userpass);
*coin = *cdata;
portable_mutex_init(&coin->txmutex);
portable_mutex_lock(&LP_coinmutex);
HASH_ADD_KEYPTR(hh,LP_coins,coin->symbol,strlen(coin->symbol),coin);
portable_mutex_unlock(&LP_coinmutex);
return(coin);
}
int32_t LP_coininit(struct iguana_info *coin,char *symbol,char *name,char *assetname,int32_t isPoS,uint16_t port,uint8_t pubtype,uint8_t p2shtype,uint8_t wiftype,uint64_t txfee,double estimatedrate,int32_t longestchain,uint8_t taddr)
{
char *name2;
@ -203,26 +225,6 @@ int32_t LP_coininit(struct iguana_info *coin,char *symbol,char *name,char *asset
return(LP_userpass(coin->userpass,symbol,assetname,name,name2));
}
struct iguana_info *LP_coinadd(struct iguana_info *cdata)
{
struct iguana_info *coin;
//printf("%s: (%s) (%s)\n",symbol,cdata.serverport,cdata.userpass);
LP_coins = realloc(LP_coins,sizeof(*LP_coins) * (LP_numcoins+1));
coin = &LP_coins[LP_numcoins];
*coin = *cdata;
LP_numcoins++;
return(coin);
}
struct iguana_info *LP_coinsearch(char *symbol)
{
int32_t i;
for (i=0; i<LP_numcoins; i++)
if ( strcmp(LP_coins[i].symbol,symbol) == 0 )
return(&LP_coins[i]);
return(0);
}
int32_t LP_isdisabled(char *base,char *rel)
{
struct iguana_info *coin;
@ -235,7 +237,7 @@ int32_t LP_isdisabled(char *base,char *rel)
struct iguana_info *LP_coinfind(char *symbol)
{
struct iguana_info *coin,cdata; int32_t isPoS,longestchain = 1000000; uint16_t port; uint64_t txfee; double estimatedrate; uint8_t pubtype,p2shtype,wiftype; char *name,*assetname;
struct iguana_info *coin,cdata; int32_t isPoS,longestchain = 1; uint16_t port; uint64_t txfee; double estimatedrate; uint8_t pubtype,p2shtype,wiftype; char *name,*assetname;
if ( (coin= LP_coinsearch(symbol)) != 0 )
return(coin);
if ( (port= LP_rpcport(symbol)) == 0 )
@ -267,7 +269,7 @@ struct iguana_info *LP_coinfind(char *symbol)
coin->inactive = 0;
else if ( strcmp(symbol,"BTC") == 0 )
{
coin->inactive = !IAMLP * (uint32_t)time(NULL);
coin->inactive = (uint32_t)time(NULL); // * !IAMLP
printf("BTC inactive.%u\n",coin->inactive);
}
}
@ -280,7 +282,7 @@ struct iguana_info *LP_coinfind(char *symbol)
struct iguana_info *LP_coincreate(cJSON *item)
{
struct iguana_info cdata,*coin=0; int32_t isPoS,longestchain = 1000000; uint16_t port; uint64_t txfee; double estimatedrate; uint8_t pubtype,p2shtype,wiftype; char *name=0,*symbol,*assetname=0;
struct iguana_info cdata,*coin=0; int32_t isPoS,longestchain = 1; uint16_t port; uint64_t txfee; double estimatedrate; uint8_t pubtype,p2shtype,wiftype; char *name=0,*symbol,*assetname=0;
if ( (symbol= jstr(item,"coin")) != 0 && symbol[0] != 0 && strlen(symbol) < 16 && LP_coinfind(symbol) == 0 && (port= juint(item,"rpcport")) != 0 )
{
isPoS = jint(item,"isPoS");

91
iguana/exchanges/LP_commands.c

@ -66,7 +66,10 @@ myprice(base, rel)\n\
enable(coin)\n\
disable(coin)\n\
inventory(coin)\n\
autotrade(base, rel, price, volume, timeout)\n\
bestfit(rel, relvolume)\n\
ordermatch(base, txfee=0, rel, desttxfee=0, price, txid, vout, feetxid, feevout, duration=3600)\n\
trade(price, timeout=10, duration=3600, <quotejson returned from ordermatch>)\n\
autotrade(base, rel, price, relvolume, timeout=10, duration=3600)\n\
swapstatus()\n\
swapstatus(requestid, quoteid)\n\
public API:\n \
@ -74,7 +77,7 @@ getcoins()\n\
getpeers()\n\
getutxos()\n\
getutxos(coin, lastn)\n\
orderbook(base, rel)\n\
orderbook(base, rel, duration=3600)\n\
getprices(base, rel)\n\
trust(pubkey, trust)\n\
register(pubkey,pushaddr)\n\
@ -101,7 +104,7 @@ forwardhex(pubkey,hex)\n\
return(clonestr("{\"error\":\"authentication error\"}"));
if ( base != 0 && rel != 0 )
{
double price;
double price,bid,ask;
if ( LP_isdisabled(base,rel) != 0 )
return(clonestr("{\"error\":\"at least one of coins disabled\"}"));
price = jdouble(argjson,"price");
@ -116,7 +119,6 @@ forwardhex(pubkey,hex)\n\
}
else if ( strcmp(method,"myprice") == 0 )
{
double bid,ask;
if ( LP_myprice(&bid,&ask,base,rel) > SMALLVAL )
{
retjson = cJSON_CreateObject();
@ -127,16 +129,38 @@ forwardhex(pubkey,hex)\n\
return(jprint(retjson,1));
} else return(clonestr("{\"error\":\"no price set\"}"));
}
else if ( strcmp(method,"ordermatch") == 0 )
{
if ( price > SMALLVAL )
return(LP_ordermatch(base,j64bits(argjson,"txfee"),price,rel,jbits256(argjson,"txid"),jint(argjson,"vout"),jbits256(argjson,"feetxid"),jint(argjson,"feevout"),j64bits(argjson,"desttxfee"),jint(argjson,"duration")));
else return(clonestr("{\"error\":\"no price set\"}"));
}
else if ( strcmp(method,"trade") == 0 )
{
struct LP_quoteinfo Q;
if ( price > SMALLVAL || jobj(argjson,"quote") != 0 )
{
LP_quoteparse(&Q,jobj(argjson,"quote"));
return(LP_trade(ctx,myipaddr,pubsock,profitmargin,&Q,price,jint(argjson,"timeout"),jint(argjson,"duration")));
} else return(clonestr("{\"error\":\"no price set or no quote object\"}"));
}
else if ( strcmp(method,"autotrade") == 0 )
{
if ( price > SMALLVAL )
{
printf("price set (%s/%s) <- %.8f\n",rel,base,1./price);
LP_mypriceset(rel,base,1./price);
return(LP_autotrade(ctx,myipaddr,pubsock,profitmargin,base,rel,price,jdouble(argjson,"volume"),jint(argjson,"timeout")));
return(LP_autotrade(ctx,myipaddr,pubsock,profitmargin,base,rel,price,jdouble(argjson,"relvolume"),jint(argjson,"timeout"),jint(argjson,"duration")));
} else return(clonestr("{\"error\":\"no price set\"}"));
}
}
else if ( rel != 0 && strcmp(method,"bestfit") == 0 )
{
double relvolume;
if ( (relvolume= jdouble(argjson,"relvolume")) > SMALLVAL )
return(LP_bestfit(rel,relvolume));
else return(clonestr("{\"error\":\"no relvolume set\"}"));
}
else if ( (coin= jstr(argjson,"coin")) != 0 )
{
if ( strcmp(method,"enable") == 0 )
@ -184,9 +208,9 @@ forwardhex(pubkey,hex)\n\
return(LP_pubkey_trustset(jbits256(argjson,"pubkey"),jint(argjson,"trust")));
}
if ( LP_isdisabled(base,rel) != 0 )
retstr = clonestr("{\"error\":\"at least one of coins disabled\"}");
return(clonestr("{\"result\":\"at least one of coins disabled\"}"));
else if ( LP_isdisabled(jstr(argjson,"coin"),0) != 0 )
retstr = clonestr("{\"error\":\"coin is disabled\"}");
retstr = clonestr("{\"result\":\"coin is disabled\"}");
else if ( strcmp(method,"reserved") == 0 )
retstr = LP_quotereceived(argjson);
else if ( strcmp(method,"connected") == 0 )
@ -202,7 +226,7 @@ forwardhex(pubkey,hex)\n\
else if ( strcmp(method,"getprices") == 0 )
return(LP_prices());
else if ( strcmp(method,"orderbook") == 0 )
return(LP_orderbook(base,rel));
return(LP_orderbook(base,rel,jint(argjson,"duration")));
else if ( strcmp(method,"registerall") == 0 )
return(LP_registerall(jint(argjson,"numnodes")));
else if ( strcmp(method,"forward") == 0 )
@ -213,8 +237,8 @@ forwardhex(pubkey,hex)\n\
//printf("FORWARDED.(%s)\n",jprint(argjson,0));
if ( LP_forward(ctx,myipaddr,pubsock,profitmargin,jbits256(argjson,"pubkey"),jprint(reqjson,1),1) > 0 )
retstr = clonestr("{\"result\":\"success\"}");
else retstr = clonestr("{\"error\":\"error forwarding\"}");
} else retstr = clonestr("{\"error\":\"cant recurse forwards\"}");
else retstr = clonestr("{\"result\":\"error forwarding\"}");
} else retstr = clonestr("{\"result\":\"cant recurse forwards\"}");
}
else if ( strcmp(method,"keepalive") == 0 )
@ -231,32 +255,43 @@ forwardhex(pubkey,hex)\n\
{
if ( LP_utxoaddjson(1,LP_mypubsock,argjson) != 0 )
return(clonestr("{\"result\":\"success\",\"notifyutxo\":\"received\"}"));
else return(clonestr("{\"error\":\"couldnt add utxo\"}"));
else return(clonestr("{\"result\":\"couldnt add utxo\"}"));
}
else if ( IAMLP != 0 )
else
{
if ( strcmp(method,"register") == 0 )
if ( IAMLP != 0 )
{
retstr = LP_register(jbits256(argjson,"client"),jstr(argjson,"pushaddr"),juint(argjson,"pushport"));
//printf("got (%s) from register\n",retstr!=0?retstr:"");
return(retstr);
if ( strcmp(method,"register") == 0 )
{
retstr = LP_register(jbits256(argjson,"client"),jstr(argjson,"pushaddr"),juint(argjson,"pushport"));
//printf("got (%s) from register\n",retstr!=0?retstr:"");
return(retstr);
}
else if ( strcmp(method,"lookup") == 0 )
return(LP_lookup(jbits256(argjson,"client")));
else if ( strcmp(method,"forwardhex") == 0 )
retstr = LP_forwardhex(ctx,pubsock,jbits256(argjson,"pubkey"),jstr(argjson,"hex"));
else if ( strcmp(method,"psock") == 0 )
{
if ( myipaddr == 0 || myipaddr[0] == 0 || strcmp(myipaddr,"127.0.0.1") == 0 )
{
if ( LP_mypeer != 0 )
myipaddr = LP_mypeer->ipaddr;
else printf("LP_psock dont have actual ipaddr?\n");
}
return(LP_psock(myipaddr,jint(argjson,"ispaired")));
}
else if ( strcmp(method,"notify") == 0 )
retstr = clonestr("{\"result\":\"success\",\"notify\":\"received\"}");
}
else if ( strcmp(method,"lookup") == 0 )
return(LP_lookup(jbits256(argjson,"client")));
else if ( strcmp(method,"forwardhex") == 0 )
retstr = LP_forwardhex(ctx,pubsock,jbits256(argjson,"pubkey"),jstr(argjson,"hex"));
else if ( strcmp(method,"psock") == 0 )
else
{
if ( myipaddr == 0 || myipaddr[0] == 0 || strcmp(myipaddr,"127.0.0.1") == 0 )
if ( strcmp(method,"register") == 0 )
{
if ( LP_mypeer != 0 )
myipaddr = LP_mypeer->ipaddr;
else printf("LP_psock dont have actual ipaddr?\n");
printf("nonLP got (%s)\n",jprint(argjson,0));
retstr = clonestr("{\"result\":\"success\",\"register\":\"received\"}");
}
return(LP_psock(myipaddr,jint(argjson,"ispaired")));
}
else if ( strcmp(method,"notify") == 0 )
retstr = clonestr("{\"result\":\"success\",\"notify\":\"received\"}");
}
if ( retstr != 0 )
{

46
iguana/exchanges/LP_forwarding.c

@ -42,10 +42,10 @@ struct LP_forwardinfo *LP_forwardfind(bits256 pubkey)
char *LP_lookup(bits256 pubkey)
{
if ( bits256_nonz(pubkey) == 0 )
return(clonestr("{\"error\":\"illegal pubkey\"}"));
return(clonestr("{\"result\":\"illegal pubkey\"}"));
if ( LP_forwardfind(pubkey) != 0 )
return(clonestr("{\"result\":\"success\",\"forwarding\":1}"));
else return(clonestr("{\"error\":\"notfound\"}"));
else return(clonestr("{\"result\":\"notfound\"}"));
}
int32_t LP_hello(struct LP_forwardinfo *ptr)
@ -108,9 +108,9 @@ char *LP_register(bits256 pubkey,char *ipaddr,uint16_t port)
{
struct LP_forwardinfo *ptr=0; int32_t pushsock; char pushaddr[64];
if ( ipaddr == 0 || ipaddr[0] == 0 || is_ipaddr(ipaddr) == 0 || bits256_nonz(pubkey) == 0 )
return(clonestr("{\"error\":\"illegal ipaddr or null pubkey\"}"));
return(clonestr("{\"result\":\"illegal ipaddr or null pubkey\"}"));
nanomsg_transportname(0,pushaddr,ipaddr,port);
char str[65]; printf("register.(%s) %s\n",pushaddr,bits256_str(str,pubkey));
//char str[65]; printf("register.(%s) %s\n",pushaddr,bits256_str(str,pubkey));
if ( (ptr= LP_forwardfind(pubkey)) != 0 )
{
ptr->lasttime = (uint32_t)time(NULL);
@ -123,16 +123,16 @@ char *LP_register(bits256 pubkey,char *ipaddr,uint16_t port)
{
//printf("cant mark (%s)\n",ptr->pushaddr);
}
char str[65]; printf("%u recreate pushsock for %s <- %s\n",(uint32_t)time(NULL),pushaddr,bits256_str(str,pubkey));
char str[65]; printf("%u recreate pushsock for %s <- %s %s\n",(uint32_t)time(NULL),ptr->pushaddr,pushaddr,bits256_str(str,pubkey));
strcpy(ptr->pushaddr,pushaddr);
if ( (ptr->pushsock= LP_pushsock_create(ptr,pushaddr)) < 0 )
return(clonestr("{\"error\":\"couldnt recreate pushsock\",\"registered\":0}"));
return(clonestr("{\"result\":\"success\",\"status\":\"couldnt recreate pushsock\",\"registered\":0}"));
} //else printf("no need to create identical endpoint\n");
}
return(clonestr("{\"error\":\"already registered\",\"registered\":1}"));
return(clonestr("{\"result\":\"success\",\"status\":\"already registered\",\"registered\":1}"));
}
else if ( (pushsock= LP_pushsock_create(0,pushaddr)) < 0 )
return(clonestr("{\"error\":\"couldnt create pushsock\"}"));
return(clonestr("{\"result\":\"success\",\"status\":\"couldnt create pushsock\"}"));
else
{
ptr = calloc(1,sizeof(*ptr));
@ -143,7 +143,7 @@ char *LP_register(bits256 pubkey,char *ipaddr,uint16_t port)
portable_mutex_lock(&LP_forwardmutex);
HASH_ADD_KEYPTR(hh,LP_forwardinfos,&ptr->pubkey,sizeof(ptr->pubkey),ptr);
portable_mutex_unlock(&LP_forwardmutex);
char str[65]; printf("registered (%s) -> (%s) pushsock.%d\n",bits256_str(str,pubkey),pushaddr,ptr->pushsock);
//char str[65]; printf("registered (%s) -> (%s) pushsock.%d\n",bits256_str(str,pubkey),pushaddr,ptr->pushsock);
LP_hello(ptr);
return(LP_lookup(pubkey));
}
@ -151,7 +151,7 @@ char *LP_register(bits256 pubkey,char *ipaddr,uint16_t port)
int32_t LP_forwarding_register(bits256 pubkey,char *publicaddr,uint16_t publicport,int32_t max)
{
char *retstr,ipaddr[64]; cJSON *retjson; struct LP_peerinfo *peer,*tmp; int32_t j,n=0,retval = -1;
char *argstr,ipaddr[64]; cJSON *argjson; struct LP_peerinfo *peer,*tmp; int32_t j,n=0,arglen;
if ( publicaddr == 0 || publicaddr[0] == 0 || bits256_nonz(pubkey) == 0 )
{
char str[65]; printf("LP_forwarding_register illegal publicaddr.(%s):%u or null pubkey (%s)\n",publicaddr,publicport,bits256_str(str,pubkey));
@ -161,10 +161,27 @@ int32_t LP_forwarding_register(bits256 pubkey,char *publicaddr,uint16_t publicpo
if ( publicaddr[j] >= '0' && publicaddr[j] <= '9' )
break;
parse_ipaddr(ipaddr,publicaddr+j);
argjson = cJSON_CreateObject();
jaddstr(argjson,"agent","stats");
jaddstr(argjson,"method","register");
jaddbits256(argjson,"client",pubkey);
jaddstr(argjson,"pushaddr",ipaddr);
jaddnum(argjson,"pushport",publicport);
argstr = jprint(argjson,1);
arglen = (int32_t)strlen(argstr) + 1;
HASH_ITER(hh,LP_peerinfos,peer,tmp)
{
if ( strcmp(LP_myipaddr,peer->ipaddr) == 0 )
continue;
if ( peer->pushsock >= 0 )
{
if ( LP_send(peer->pushsock,argstr,arglen,0) != arglen )
printf("error sending command to %s:%u\n",peer->ipaddr,peer->port);
else printf("sent register to %s:%u\n",peer->ipaddr,peer->port);
n++;
}
//printf("register.(%s) %s %u with (%s)\n",publicaddr,ipaddr,publicport,peer->ipaddr);
if ( (retstr= issue_LP_register(peer->ipaddr,peer->port,pubkey,ipaddr,publicport)) != 0 )
/*if ( (retstr= issue_LP_register(peer->ipaddr,peer->port,pubkey,ipaddr,publicport)) != 0 )
{
//printf("[%s] LP_register.(%s) returned.(%s)\n",publicaddr,peer->ipaddr,retstr);
if ( (retjson= cJSON_Parse(retstr)) != 0 )
@ -176,8 +193,9 @@ int32_t LP_forwarding_register(bits256 pubkey,char *publicaddr,uint16_t publicpo
free(retstr);
} else printf("timeout registering with %s errs.%d good.%d\n",peer->ipaddr,peer->errors,peer->good);
if ( retval == 0 )
break;
break;*/
}
free(argstr);
return(n);
}
@ -216,7 +234,7 @@ char *LP_forwardhex(void *ctx,int32_t pubsock,bits256 pubkey,char *hexstr)
{
struct LP_forwardinfo *ptr=0; uint8_t *data; int32_t datalen=0,sentbytes=0; char *msg,*retstr=0; cJSON *retjson=0,*argjson=0,*reqjson=0;
if ( hexstr == 0 || hexstr[0] == 0 )
return(clonestr("{\"error\":\"nohex\"}"));
return(clonestr("{\"result\":\"nohex\"}"));
datalen = (int32_t)strlen(hexstr) >> 1;
data = malloc(datalen);
decode_hex(data,datalen,hexstr);
@ -266,7 +284,7 @@ char *LP_forwardhex(void *ctx,int32_t pubsock,bits256 pubkey,char *hexstr)
msg = jprint(reqjson,0);
LP_send(pubsock,msg,(int32_t)strlen(msg)+1,1);
}
retstr = clonestr("{\"error\":\"notfound\"}");
retstr = clonestr("{\"result\":\"notfound\"}");
}
free(data);
if ( reqjson != 0 )

22
iguana/exchanges/LP_include.h

@ -29,6 +29,9 @@
#define MAINLOOP_PERSEC 10
#define MAX_PSOCK_PORT 60000
#define MIN_PSOCK_PORT 10000
#define LP_MEMPOOL_TIMEINCR 10
#define LP_GETINFO_INCR 30
#define LP_ORDERBOOK_DURATION 3600
#define LP_HTTP_TIMEOUT 2 // 1 is too small due to edge cases of time(NULL)
#define LP_MAXPEER_ERRORS 3
@ -36,10 +39,10 @@
#define LP_PEERGOOD_ERRORDECAY 0.9
#define LP_SWAPSTEP_TIMEOUT 3
#define LP_AUTOTRADE_TIMEOUT 3
#define LP_AUTOTRADE_TIMEOUT 10
#define LP_MIN_TXFEE 10000
#define LP_MINVOL 3
#define LP_MINCLIENTVOL 6
#define LP_MINVOL 10
#define LP_MINCLIENTVOL 20
#define LP_DEXFEE(destsatoshis) ((destsatoshis) / INSTANTDEX_INSURANCEDIV)
#define LP_DEPOSITSATOSHIS(satoshis) ((satoshis) + (satoshis >> 3))
@ -157,10 +160,21 @@ struct basilisk_swapinfo
uint8_t userdata_bobrefund[256],userdata_bobrefundlen;
};
struct LP_outpoint { bits256 spendtxid; uint64_t value,interest; int32_t spendvini,spendheight; };
struct LP_transaction
{
UT_hash_handle hh;
bits256 txid; int32_t height,numvouts,numvins; uint32_t timestamp;
struct LP_outpoint outpoints[];
};
struct iguana_info
{
UT_hash_handle hh;
portable_mutex_t txmutex; struct LP_transaction *transactions;
uint64_t txfee; double estimatedrate,profitmargin;
int32_t longestchain; uint32_t counter,inactive;
int32_t longestchain,firstrefht,firstscanht,lastscanht; uint32_t counter,inactive,lastmempool,lastgetinfo;
uint8_t pubtype,p2shtype,isPoS,wiftype,taddr;
char symbol[16],smartaddr[64],userpass[1024],serverport[128];
};

89
iguana/exchanges/LP_nativeDEX.c

@ -17,16 +17,21 @@
// LP_nativeDEX.c
// marketmaker
//
// activate orderbook timeouts
// verify bid volumes
// stats
// auto-utxo creation
#include <stdio.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;
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;
int32_t LP_canbind;
#include "LP_network.c"
struct LP_utxoinfo *LP_utxoinfos[2],*LP_utxoinfos2[2];
struct LP_peerinfo *LP_peerinfos,*LP_mypeer;
struct LP_forwardinfo *LP_forwardinfos;
struct iguana_info *LP_coins;
char *activecoins[] = { "BTC", "KMD" };
char GLOBAL_DBDIR[] = { "DB" };
@ -192,18 +197,18 @@ int32_t LP_subsock_check(void *ctx,char *myipaddr,int32_t pubsock,int32_t sock,d
void LP_utxo_spentcheck(int32_t pubsock,struct LP_utxoinfo *utxo,double profitmargin)
{
struct _LP_utxoinfo u; char str[65],destaddr[64]; uint32_t now = (uint32_t)time(NULL);
struct _LP_utxoinfo u; char str[65]; uint32_t now = (uint32_t)time(NULL);
//printf("%s lag.%d\n",bits256_str(str,utxo->txid),now-utxo->lastspentcheck);
if ( utxo->T.spentflag == 0 && now > utxo->T.lastspentcheck+60 )
{
u = (utxo->iambob != 0) ? utxo->deposit : utxo->fee;
utxo->T.lastspentcheck = now;
if ( LP_txvalue(destaddr,utxo->coin,utxo->payment.txid,utxo->payment.vout) == 0 )
if ( LP_txvalue(0,utxo->coin,utxo->payment.txid,utxo->payment.vout) == 0 )
{
printf("txid.%s %s/v%d %.8f has been spent\n",utxo->coin,bits256_str(str,utxo->payment.txid),utxo->payment.vout,dstr(utxo->payment.value));
LP_spentnotify(utxo,0);
}
else if ( LP_txvalue(destaddr,utxo->coin,u.txid,u.vout) == 0 )
else if ( LP_txvalue(0,utxo->coin,u.txid,u.vout) == 0 )
{
printf("txid2.%s %s/v%d %.8f has been spent\n",utxo->coin,bits256_str(str,u.txid),u.vout,dstr(u.value));
LP_spentnotify(utxo,1);
@ -238,7 +243,7 @@ int32_t LP_peer_utxosquery(struct LP_peerinfo *mypeer,uint16_t myport,int32_t pu
int32_t LP_mainloop_iter(void *ctx,char *myipaddr,struct LP_peerinfo *mypeer,int32_t pubsock,char *pushaddr,uint16_t pushport,int32_t pullsock,uint16_t myport,char *passphrase,double profitmargin)
{
static uint32_t counter,lastforward,numpeers;
struct LP_utxoinfo *utxo,*utmp; char *retstr,*origipaddr; struct LP_peerinfo *peer,*tmp; uint32_t now; int32_t nonz = 0,n=0,lastn=-1;
struct LP_utxoinfo *utxo,*utmp; struct iguana_info *coin,*ctmp; char *retstr,*origipaddr; struct LP_peerinfo *peer,*tmp; uint32_t now; int32_t nonz = 0,n=0,lastn=-1;
now = (uint32_t)time(NULL);
if ( (origipaddr= myipaddr) == 0 )
origipaddr = "127.0.0.1";
@ -284,7 +289,7 @@ int32_t LP_mainloop_iter(void *ctx,char *myipaddr,struct LP_peerinfo *mypeer,int
{
if ( (retstr= LP_registerall(0)) != 0 )
free(retstr);
//LP_forwarding_register(LP_mypubkey,pushaddr,pushport,10);
LP_forwarding_register(LP_mypubkey,pushaddr,pushport,10);
lastforward = now;
}
}
@ -332,6 +337,57 @@ int32_t LP_mainloop_iter(void *ctx,char *myipaddr,struct LP_peerinfo *mypeer,int
//LP_deadman_switch = 0;
}
}
HASH_ITER(hh,LP_coins,coin,ctmp) // firstrefht,firstscanht,lastscanht
{
cJSON *obj; int32_t height; bits256 zero;
//printf("%s ref.%d scan.%d to %d, longest.%d\n",coin->symbol,coin->firstrefht,coin->firstscanht,coin->lastscanht,coin->longestchain);
if ( coin->inactive != 0 )
continue;
memset(zero.bytes,0,sizeof(zero));
if ( time(NULL) > coin->lastgetinfo+LP_GETINFO_INCR )
{
if ( (obj= LP_getinfo(coin->symbol)) != 0 )
{
if ( (height= jint(obj,"blocks")) > coin->longestchain )
{
coin->longestchain = height;
if ( coin->firstrefht != 0 )
printf(">>>>>>>>>> set %s longestchain %d (ref.%d [%d, %d])\n",coin->symbol,height,coin->firstrefht,coin->firstscanht,coin->lastscanht);
} else LP_mempoolscan(coin->symbol,zero);
free_json(obj);
} else printf("error getting info.%s\n",coin->symbol);
coin->lastgetinfo = (uint32_t)time(NULL);
}
if ( coin->firstrefht == 0 )
continue;
else if ( coin->firstscanht == 0 )
coin->lastscanht = coin->firstscanht = coin->firstrefht;
else if ( coin->firstrefht < coin->firstscanht )
{
printf("detected %s firstrefht.%d < firstscanht.%d\n",coin->symbol,coin->firstrefht,coin->firstscanht);
coin->lastscanht = coin->firstscanht = coin->firstrefht;
}
if ( coin->lastscanht == coin->longestchain )
continue;
else if ( coin->lastscanht > coin->longestchain )
{
printf("detected chain rewind lastscanht.%d vs longestchain.%d, first.%d ref.%d\n",coin->lastscanht,coin->longestchain,coin->firstscanht,coin->firstrefht);
LP_undospends(coin,coin->longestchain-1);
LP_mempoolscan(coin->symbol,zero);
coin->lastscanht = coin->longestchain - 1;
if ( coin->firstscanht < coin->lastscanht )
coin->lastscanht = coin->firstscanht;
continue;
}
printf("%s ref.%d scan.%d to %d, longest.%d\n",coin->symbol,coin->firstrefht,coin->firstscanht,coin->lastscanht,coin->longestchain);
if ( LP_blockinit(coin,coin->lastscanht) < 0 )
{
printf("blockinit.%s %d error\n",coin->symbol,coin->lastscanht);
continue;
}
coin->lastscanht++;
break;
}
counter++;
return(nonz);
}
@ -401,7 +457,12 @@ void LP_initpeers(int32_t pubsock,struct LP_peerinfo *mypeer,char *myipaddr,uint
void LPinit(uint16_t myport,uint16_t mypullport,uint16_t mypubport,double profitmargin,char *passphrase,int32_t amclient,char *userhome,cJSON *argjson)
{
char *myipaddr=0; long filesize,n; int32_t timeout,pullsock=-1,pubsock=-1; struct LP_peerinfo *mypeer=0; char pushaddr[128],subaddr[128],bindaddr[128]; void *ctx = bitcoin_ctx();
char *myipaddr=0,*retstr; long filesize,n; int32_t timeout,pullsock=-1,pubsock=-1; struct LP_peerinfo *mypeer=0; char pushaddr[128],subaddr[128],bindaddr[128]; void *ctx = bitcoin_ctx();
if ( passphrase == 0 || passphrase[0] == 0 )
{
printf("jeezy says we cant use the nullstring as passphrase and I agree\n");
exit(-1);
}
IAMLP = !amclient;
#ifndef __linux__
if ( IAMLP != 0 )
@ -417,11 +478,16 @@ void LPinit(uint16_t myport,uint16_t mypullport,uint16_t mypubport,double profit
if ( jobj(argjson,"canbind") == 0 )
{
#ifndef __linux__
LP_canbind = 1;
LP_canbind = IAMLP;
#else
LP_canbind = IAMLP;
#endif
} else LP_canbind = jint(argjson,"canbind");
}
else
{
LP_canbind = jint(argjson,"canbind");
printf(">>>>>>>>>>> set LP_canbind.%d\n",LP_canbind);
}
if ( LP_canbind > 1000 && LP_canbind < 65536 )
LP_fixed_pairport = LP_canbind;
if ( LP_canbind != 0 )
@ -443,6 +509,7 @@ void LPinit(uint16_t myport,uint16_t mypullport,uint16_t mypubport,double profit
portable_mutex_init(&LP_networkmutex);
portable_mutex_init(&LP_forwardmutex);
portable_mutex_init(&LP_psockmutex);
portable_mutex_init(&LP_coinmutex);
portable_mutex_init(&LP_pubkeymutex);
if ( profitmargin == 0. || profitmargin == 0.01 )
{
@ -486,7 +553,7 @@ void LPinit(uint16_t myport,uint16_t mypullport,uint16_t mypubport,double profit
strcpy(LP_publicaddr,pushaddr);
LP_publicport = mypullport;
LP_deadman_switch = (uint32_t)time(NULL);
printf("my command address is (%s) pullsock.%d pullport.%u\n",pushaddr,pullsock,mypullport);
printf("canbind.%d my command address is (%s) pullsock.%d pullport.%u\n",LP_canbind,pushaddr,pullsock,mypullport);
LP_initcoins(ctx,pubsock,jobj(argjson,"coins"),passphrase);
if ( IAMLP != 0 && OS_thread_create(malloc(sizeof(pthread_t)),NULL,(void *)LP_psockloop,(void *)&myipaddr) != 0 )
{
@ -498,6 +565,8 @@ void LPinit(uint16_t myport,uint16_t mypullport,uint16_t mypubport,double profit
printf("error launching stats rpcloop for port.%u\n",myport);
exit(-1);
}
if ( (retstr= basilisk_swapentry(0,0)) != 0 )
free(retstr);
while ( 1 )
{
//fprintf(stderr,".");

135
iguana/exchanges/LP_ordermatch.c

@ -269,12 +269,12 @@ double LP_quote_validate(struct LP_utxoinfo **autxop,struct LP_utxoinfo **butxop
return(-11);
}
qprice = ((double)qp->destsatoshis / qp->satoshis);
if ( qp->satoshis < (srcvalue >> LP_MINVOL) )
if ( qp->satoshis < (srcvalue / LP_MINVOL) )
{
printf("utxo payment %.8f is less than half covered by Q %.8f\n",dstr(srcvalue),dstr(qp->satoshis));
return(-12);
}
if ( qp->destsatoshis < (destvalue >> LP_MINCLIENTVOL) )
if ( qp->destsatoshis < (destvalue / LP_MINCLIENTVOL) )
{
printf("destsatoshis %.8f is less than half of value %.8f\n",dstr(qp->destsatoshis),dstr(destvalue));
return(-13);
@ -560,21 +560,20 @@ int32_t LP_tradecommand(void *ctx,char *myipaddr,int32_t pubsock,cJSON *argjson,
return(retval);
}
char *LP_autotrade(void *ctx,char *myipaddr,int32_t mypubsock,double profitmargin,char *base,char *rel,double maxprice,double volume,int32_t timeout)
struct LP_utxoinfo *LP_bestutxo(double *ordermatchpricep,int64_t *bestdestsatoshisp,struct LP_utxoinfo *autxo,char *base,double maxprice,int32_t duration,int64_t txfee,int64_t desttxfee)
{
int64_t satoshis,destsatoshis,desttxfee,txfee,bestdestsatoshis=0; bits256 txid,pubkey; char *obookstr,*retstr; cJSON *orderbook,*asks,*item,*bestitem=0; struct LP_utxoinfo *autxo,*butxo,*bestutxo = 0; int32_t i,vout,numasks,DEXselector=0; uint32_t expiration; double ordermatchprice,bestmetric,metric,bestprice=0.,vol,price; struct LP_quoteinfo Q; struct LP_pubkeyinfo *pubp;
if ( maxprice <= 0. || volume <= 0. || LP_priceinfofind(base) == 0 || LP_priceinfofind(rel) == 0 )
return(clonestr("{\"error\":\"invalid parameter\"}"));
if ( (autxo= LP_utxo_bestfit(rel,SATOSHIDEN * volume)) == 0 )
return(clonestr("{\"error\":\"cant find utxo that is big enough\"}"));
bestmetric = ordermatchprice = 0.;
if ( (desttxfee= LP_getestimatedrate(rel) * LP_AVETXSIZE) < LP_MIN_TXFEE )
int64_t satoshis,destsatoshis; bits256 txid,pubkey; char *obookstr; cJSON *orderbook,*asks,*item; struct LP_utxoinfo *butxo,*bestutxo = 0; int32_t i,vout,numasks; double bestmetric=0.,metric,vol,price,bestprice = 0.; struct LP_pubkeyinfo *pubp;
*ordermatchpricep = 0.;
*bestdestsatoshisp = 0;
if ( duration <= 0 )
duration = LP_ORDERBOOK_DURATION;
if ( maxprice <= 0. || LP_priceinfofind(base) == 0 )
return(0);
if ( (desttxfee= LP_getestimatedrate(autxo->coin) * LP_AVETXSIZE) < LP_MIN_TXFEE )
desttxfee = LP_MIN_TXFEE;
if ( (txfee= LP_getestimatedrate(base) * LP_AVETXSIZE) < LP_MIN_TXFEE )
txfee = LP_MIN_TXFEE;
if ( timeout == 0 )
timeout = LP_AUTOTRADE_TIMEOUT;
if ( (obookstr= LP_orderbook(base,rel)) != 0 )
if ( (obookstr= LP_orderbook(base,autxo->coin,duration)) != 0 )
{
if ( (orderbook= cJSON_Parse(obookstr)) != 0 )
{
@ -598,33 +597,34 @@ char *LP_autotrade(void *ctx,char *myipaddr,int32_t mypubsock,double profitmargi
vout = jint(item,"vout");
vol = jdouble(item,"volume");
metric = price / bestprice;
if ( (butxo= LP_utxofind(1,txid,vout)) != 0 && (long long)(vol*SATOSHIDEN) == butxo->S.satoshis && LP_isavailable(butxo) > 0 && LP_ismine(butxo) == 0 && butxo->T.bestflag == 0 )
if ( (butxo= LP_utxofind(1,txid,vout)) != 0 && (long long)(vol*SATOSHIDEN) == butxo->S.satoshis && LP_isavailable(butxo) > 0 && LP_ismine(butxo) == 0 )//&& butxo->T.bestflag == 0 )
{
destsatoshis = ((butxo->S.satoshis - txfee) * price);
if ( destsatoshis > autxo->payment.value-desttxfee-1 )
destsatoshis = autxo->payment.value-desttxfee-1;
satoshis = (destsatoshis / price + 0.0000000049) - txfee;
if ( metric < 1.2 && destsatoshis > desttxfee && destsatoshis-desttxfee > (autxo->payment.value >> LP_MINCLIENTVOL) && satoshis-txfee > (butxo->S.satoshis >> LP_MINVOL) && satoshis <= butxo->payment.value-txfee )
if ( metric < 1.2 && destsatoshis > desttxfee && destsatoshis-desttxfee > (autxo->payment.value / LP_MINCLIENTVOL) && satoshis-txfee > (butxo->S.satoshis / LP_MINVOL) && satoshis <= butxo->payment.value-txfee )
{
printf("value %.8f price %.8f/%.8f best %.8f destsatoshis %.8f * metric %.8f -> (%f)\n",dstr(autxo->payment.value),price,bestprice,bestmetric,dstr(destsatoshis),metric,dstr(destsatoshis) * metric * metric * metric);
metric = dstr(destsatoshis) * metric * metric * metric;
if ( bestmetric == 0. || metric < bestmetric )
{
bestutxo = butxo;
ordermatchprice = price;
bestdestsatoshis = destsatoshis;
*ordermatchpricep = price;
*bestdestsatoshisp = destsatoshis;
bestmetric = metric;
printf("set best!\n");
}
} else printf("skip.(%d %d %d %d %d) metric %f destsatoshis %.8f value %.8f destvalue %.8f txfees %.8f %.8f sats %.8f\n",metric < 1.2,destsatoshis > desttxfee,destsatoshis-desttxfee > (autxo->payment.value >> LP_MINCLIENTVOL),satoshis-txfee > (butxo->S.satoshis >> LP_MINVOL),satoshis < butxo->payment.value-txfee,metric,dstr(destsatoshis),dstr(butxo->S.satoshis),dstr(autxo->payment.value),dstr(txfee),dstr(desttxfee),dstr(satoshis));
} else printf("skip.(%d %d %d %d %d) metric %f destsatoshis %.8f value %.8f destvalue %.8f txfees %.8f %.8f sats %.8f\n",metric < 1.2,destsatoshis > desttxfee,destsatoshis-desttxfee > (autxo->payment.value / LP_MINCLIENTVOL),satoshis-txfee > (butxo->S.satoshis / LP_MINVOL),satoshis < butxo->payment.value-txfee,metric,dstr(destsatoshis),dstr(butxo->S.satoshis),dstr(autxo->payment.value),dstr(txfee),dstr(desttxfee),dstr(satoshis));
}
else
{
if ( butxo != 0 )
printf("%llu %llu %d %d %d: ",(long long)(vol*SATOSHIDEN),(long long)butxo->S.satoshis,vol*SATOSHIDEN == butxo->S.satoshis,LP_isavailable(butxo) > 0,LP_ismine(butxo) == 0);
printf("cant find butxo.%p or value mismatch %.8f != %.8f\n",butxo,vol,butxo!=0?dstr(butxo->S.satoshis):0);
printf("cant find butxo.%p or value mismatch %.8f != %.8f or bestflag.%d\n",butxo,vol,butxo!=0?dstr(butxo->S.satoshis):0,butxo->T.bestflag);
//if ( (butxo= LP_utxofind(1,txid,vout)) != 0 && (long long)(vol*SATOSHIDEN) == butxo->S.satoshis && LP_isavailable(butxo) > 0 && LP_ismine(butxo) == 0 && butxo->T.bestflag == 0 )
}
}
} else printf("self trading or blacklisted peer\n");
} else break;
}
}
@ -632,41 +632,80 @@ char *LP_autotrade(void *ctx,char *myipaddr,int32_t mypubsock,double profitmargi
}
free(obookstr);
}
if ( bestutxo == 0 || ordermatchprice == 0. || bestdestsatoshis == 0 )
if ( bestutxo == 0 || *ordermatchpricep == 0. || *bestdestsatoshisp == 0 )
return(0);
return(bestutxo);
}
char *LP_bestfit(char *rel,double relvolume)
{
struct LP_utxoinfo *autxo;
if ( relvolume <= 0. || LP_priceinfofind(rel) == 0 )
return(clonestr("{\"error\":\"invalid parameter\"}"));
if ( (autxo= LP_utxo_bestfit(rel,SATOSHIDEN * relvolume)) == 0 )
return(clonestr("{\"error\":\"cant find utxo that is big enough\"}"));
return(jprint(LP_utxojson(autxo),1));
}
char *LP_ordermatch(char *base,int64_t txfee,double maxprice,char *rel,bits256 txid,int32_t vout,bits256 feetxid,int32_t feevout,int64_t desttxfee,int32_t duration)
{
struct LP_quoteinfo Q; int64_t bestdestsatoshis = 0; double ordermatchprice = 0.; struct LP_utxoinfo *autxo,*bestutxo;
if ( desttxfee == 0 && (desttxfee= LP_getestimatedrate(rel) * LP_AVETXSIZE) < LP_MIN_TXFEE )
desttxfee = LP_MIN_TXFEE;
if ( txfee == 0 && (txfee= LP_getestimatedrate(base) * LP_AVETXSIZE) < LP_MIN_TXFEE )
txfee = LP_MIN_TXFEE;
if ( (autxo= LP_utxopairfind(0,txid,vout,feetxid,feevout)) == 0 )
return(clonestr("{\"error\":\"cant find alice utxopair\"}"));
if ( (bestutxo= LP_bestutxo(&ordermatchprice,&bestdestsatoshis,autxo,base,maxprice,duration,txfee,desttxfee)) == 0 || ordermatchprice == 0. || bestdestsatoshis == 0 )
return(clonestr("{\"error\":\"cant find ordermatch utxo\"}"));
if ( LP_quoteinfoinit(&Q,bestutxo,rel,ordermatchprice,bestdestsatoshis) < 0 )
return(clonestr("{\"error\":\"cant set ordermatch quote\"}"));
if ( LP_quotedestinfo(&Q,autxo->payment.txid,autxo->payment.vout,autxo->fee.txid,autxo->fee.vout,LP_mypubkey,autxo->coinaddr) < 0 )
return(clonestr("{\"error\":\"cant set ordermatch quote info\"}"));
bestutxo->T.bestflag = (uint32_t)time(NULL);
return(jprint(LP_quotejson(&Q),1));
}
char *LP_trade(void *ctx,char *myipaddr,int32_t mypubsock,double profitmargin,struct LP_quoteinfo *qp,double maxprice,int32_t timeout,int32_t duration)
{
struct LP_utxoinfo *bobutxo,*aliceutxo; char *retstr; cJSON *bestitem=0; int32_t DEXselector=0; uint32_t expiration; double price; struct LP_pubkeyinfo *pubp;
if ( (aliceutxo= LP_utxopairfind(0,qp->desttxid,qp->destvout,qp->feetxid,qp->feevout)) == 0 )
{
char str[65],str2[65]; printf("dest.(%s)/v%d fee.(%s)/v%d\n",bits256_str(str,qp->desttxid),qp->destvout,bits256_str(str2,qp->feetxid),qp->feevout);
return(clonestr("{\"error\":\"cant find alice utxopair\"}"));
}
printf("aliceutxo.%p\n",aliceutxo);
if ( (bobutxo= LP_utxopairfind(1,qp->txid,qp->vout,qp->txid2,qp->vout2)) == 0 )
return(clonestr("{\"error\":\"cant find bob utxopair\"}"));
printf("bobutxo.%p\n",bobutxo);
bobutxo->T.bestflag = (uint32_t)time(NULL);
if ( (retstr= LP_registerall(0)) != 0 )
free(retstr);
price = LP_query(ctx,myipaddr,mypubsock,profitmargin,"request",&Q);
bestitem = LP_quotejson(&Q);
price = LP_query(ctx,myipaddr,mypubsock,profitmargin,"request",qp);
bestitem = LP_quotejson(qp);
if ( price > SMALLVAL )
{
if ( price <= maxprice )
{
price = LP_query(ctx,myipaddr,mypubsock,profitmargin,"connect",&Q);
LP_requestinit(&Q.R,Q.srchash,Q.desthash,base,Q.satoshis,Q.destcoin,Q.destsatoshis,Q.timestamp,Q.quotetime,DEXselector);
price = LP_query(ctx,myipaddr,mypubsock,profitmargin,"connect",qp);
LP_requestinit(&qp->R,qp->srchash,qp->desthash,bobutxo->coin,qp->satoshis,qp->destcoin,qp->destsatoshis,qp->timestamp,qp->quotetime,DEXselector);
expiration = (uint32_t)time(NULL) + timeout;
while ( time(NULL) < expiration )
{
if ( autxo->S.swap != 0 )
if ( aliceutxo->S.swap != 0 )
break;
sleep(1);
}
if ( autxo->S.swap == 0 )
if ( aliceutxo->S.swap == 0 )
{
if ( (pubp= LP_pubkeyadd(bestutxo->pubkey)) != 0 )
if ( (pubp= LP_pubkeyadd(bobutxo->pubkey)) != 0 )
pubp->numerrors++;
jaddstr(bestitem,"status","couldnt establish connection");
} else jaddstr(bestitem,"status","connected");
jaddnum(bestitem,"quotedprice",price);
jaddnum(bestitem,"maxprice",maxprice);
jaddnum(bestitem,"requestid",Q.R.requestid);
jaddnum(bestitem,"quoteid",Q.R.quoteid);
printf("Alice r.%u q.%u\n",Q.R.requestid,Q.R.quoteid);
jaddnum(bestitem,"requestid",qp->R.requestid);
jaddnum(bestitem,"quoteid",qp->R.quoteid);
printf("Alice r.%u qp->%u\n",qp->R.requestid,qp->R.quoteid);
}
else
{
@ -680,11 +719,39 @@ char *LP_autotrade(void *ctx,char *myipaddr,int32_t mypubsock,double profitmargi
jaddnum(bestitem,"maxprice",maxprice);
jaddstr(bestitem,"status","no response to request");
}
if ( autxo->S.swap == 0 )
LP_availableset(autxo);
if ( aliceutxo->S.swap == 0 )
LP_availableset(aliceutxo);
return(jprint(bestitem,0));
}
char *LP_autotrade(void *ctx,char *myipaddr,int32_t mypubsock,double profitmargin,char *base,char *rel,double maxprice,double relvolume,int32_t timeout,int32_t duration)
{
int64_t desttxfee,txfee,bestdestsatoshis=0; struct LP_utxoinfo *autxo,*bestutxo = 0; double ordermatchprice=0.; struct LP_quoteinfo Q;
if ( duration <= 0 )
duration = LP_ORDERBOOK_DURATION;
if ( timeout <= 0 )
timeout = LP_AUTOTRADE_TIMEOUT;
if ( maxprice <= 0. || relvolume <= 0. || LP_priceinfofind(base) == 0 || LP_priceinfofind(rel) == 0 )
return(clonestr("{\"error\":\"invalid parameter\"}"));
if ( (autxo= LP_utxo_bestfit(rel,SATOSHIDEN * relvolume)) == 0 )
return(clonestr("{\"error\":\"cant find utxo that is big enough\"}"));
if ( (desttxfee= LP_getestimatedrate(rel) * LP_AVETXSIZE) < LP_MIN_TXFEE )
desttxfee = LP_MIN_TXFEE;
if ( (txfee= LP_getestimatedrate(base) * LP_AVETXSIZE) < LP_MIN_TXFEE )
txfee = LP_MIN_TXFEE;
if ( (bestutxo= LP_bestutxo(&ordermatchprice,&bestdestsatoshis,autxo,base,maxprice,duration,txfee,desttxfee)) == 0 || ordermatchprice == 0. || bestdestsatoshis == 0 )
{
printf("bestutxo.%p ordermatchprice %.8f bestdestsatoshis %.8f\n",bestutxo,ordermatchprice,dstr(bestdestsatoshis));
return(clonestr("{\"error\":\"cant find ordermatch utxo\"}"));
}
if ( LP_quoteinfoinit(&Q,bestutxo,rel,ordermatchprice,bestdestsatoshis) < 0 )
return(clonestr("{\"error\":\"cant set ordermatch quote\"}"));
if ( LP_quotedestinfo(&Q,autxo->payment.txid,autxo->payment.vout,autxo->fee.txid,autxo->fee.vout,LP_mypubkey,autxo->coinaddr) < 0 )
return(clonestr("{\"error\":\"cant set ordermatch quote info\"}"));
printf("do quote.(%s)\n",jprint(LP_quotejson(&Q),1));
return(LP_trade(ctx,myipaddr,mypubsock,profitmargin,&Q,maxprice,timeout,duration));
}

42
iguana/exchanges/LP_prices.c

@ -18,7 +18,7 @@
// marketmaker
//
struct LP_orderbookentry { bits256 txid,txid2,pubkey; double price; uint64_t basesatoshis; int32_t vout,vout2; };
struct LP_orderbookentry { bits256 txid,txid2,pubkey; double price; uint64_t basesatoshis; int32_t vout,vout2,age; };
#define LP_MAXPRICEINFOS 256
struct LP_priceinfo
@ -482,11 +482,12 @@ cJSON *LP_orderbookjson(struct LP_orderbookentry *op)
jaddbits256(item,"txid",op->txid);
jaddnum(item,"vout",op->vout);
jaddbits256(item,"pubkey",op->pubkey);
jaddnum(item,"age",op->age);
}
return(item);
}
struct LP_orderbookentry *LP_orderbookentry(char *base,char *rel,bits256 txid,int32_t vout,bits256 txid2,int32_t vout2,double price,uint64_t basesatoshis,bits256 pubkey)
struct LP_orderbookentry *LP_orderbookentry(char *base,char *rel,bits256 txid,int32_t vout,bits256 txid2,int32_t vout2,double price,uint64_t basesatoshis,bits256 pubkey,int32_t age)
{
struct LP_orderbookentry *op;
if ( (op= calloc(1,sizeof(*op))) != 0 )
@ -498,6 +499,7 @@ struct LP_orderbookentry *LP_orderbookentry(char *base,char *rel,bits256 txid,in
op->price = price;
op->basesatoshis = basesatoshis;
op->pubkey = pubkey;
op->age = age;
}
return(op);
}
@ -537,12 +539,14 @@ int32_t LP_utxo_clientpublish(struct LP_utxoinfo *utxo)
return(n);
}
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 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)
{
struct LP_utxoinfo *utxo,*tmp; struct LP_pubkeyinfo *pubp=0; struct LP_priceinfo *basepp; struct LP_orderbookentry *op; double price; int32_t baseid,relid; uint64_t basesatoshis;
struct LP_utxoinfo *utxo,*tmp; struct LP_pubkeyinfo *pubp=0; struct LP_priceinfo *basepp; struct LP_orderbookentry *op; uint32_t oldest; double price; int32_t baseid,relid; uint64_t basesatoshis;
if ( (basepp= LP_priceinfoptr(&relid,base,rel)) != 0 )
baseid = basepp->ind;
else return(num);
now = (uint32_t)time(NULL);
oldest = now - duration;
HASH_ITER(hh,LP_utxoinfos[1],utxo,tmp)
{
if ( pubp == 0 || bits256_cmp(pubp->pubkey,utxo->pubkey) != 0 )
@ -550,7 +554,7 @@ int32_t LP_orderbook_utxoentries(uint32_t now,int32_t polarity,char *base,char *
if ( pubp != 0 && pubp->numerrors >= LP_MAXPUBKEY_ERRORS )
continue;
//char str[65],str2[65]; printf("check utxo.%s/v%d from %s\n",bits256_str(str,utxo->payment.txid),utxo->payment.vout,bits256_str(str2,utxo->pubkey));
if ( strcmp(base,utxo->coin) == 0 && LP_isavailable(utxo) > 0 && pubp != 0 && (price= pubp->matrix[baseid][relid]) > SMALLVAL )
if ( strcmp(base,utxo->coin) == 0 && LP_isavailable(utxo) > 0 && pubp != 0 && (price= pubp->matrix[baseid][relid]) > SMALLVAL && pubp->timestamp > oldest && pubp->timestamp <= now )
{
if ( LP_orderbookfind(*arrayp,cachednum,utxo->payment.txid,utxo->payment.vout) < 0 )
{
@ -558,7 +562,7 @@ int32_t LP_orderbook_utxoentries(uint32_t now,int32_t polarity,char *base,char *
basesatoshis = utxo->S.satoshis;
else basesatoshis = utxo->S.satoshis * price;
//char str[65]; printf("found utxo not in orderbook %s/v%d %.8f %.8f\n",bits256_str(str,utxo->payment.txid),utxo->payment.vout,dstr(basesatoshis),polarity > 0 ? price : 1./price);
if ( (op= LP_orderbookentry(base,rel,utxo->payment.txid,utxo->payment.vout,utxo->deposit.txid,utxo->deposit.vout,polarity > 0 ? price : 1./price,basesatoshis,utxo->pubkey)) != 0 )
if ( (op= LP_orderbookentry(base,rel,utxo->payment.txid,utxo->payment.vout,utxo->deposit.txid,utxo->deposit.vout,polarity > 0 ? price : 1./price,basesatoshis,utxo->pubkey,now - pubp->timestamp)) != 0 )
{
*arrayp = realloc(*arrayp,sizeof(*(*arrayp)) * (num+1));
(*arrayp)[num++] = op;
@ -571,36 +575,20 @@ int32_t LP_orderbook_utxoentries(uint32_t now,int32_t polarity,char *base,char *
return(num);
}
char *LP_orderbook(char *base,char *rel)
char *LP_orderbook(char *base,char *rel,int32_t duration)
{
uint32_t now,i; struct LP_priceinfo *basepp=0,*relpp=0; struct LP_orderbookentry **bids = 0,**asks = 0; cJSON *retjson,*array; int32_t numbids=0,numasks=0,cachenumbids,cachenumasks,baseid,relid;
if ( (basepp= LP_priceinfofind(base)) == 0 || (relpp= LP_priceinfofind(rel)) == 0 )
return(clonestr("{\"error\":\"base or rel not added\"}"));
if ( duration <= 0 )
duration = LP_ORDERBOOK_DURATION;
baseid = basepp->ind;
relid = relpp->ind;
now = (uint32_t)time(NULL);
/*struct LP_cacheinfo *ptr,*tmp;
HASH_ITER(hh,LP_cacheinfos,ptr,tmp)
{
if ( ptr->timestamp < now-3600*2 || ptr->price == 0. )
continue;
if ( strcmp(ptr->Q.srccoin,base) == 0 && strcmp(ptr->Q.destcoin,rel) == 0 )
{
asks = realloc(asks,sizeof(*asks) * (numasks+1));
if ( (op= LP_orderbookentry(base,rel,ptr->Q.txid,ptr->Q.vout,ptr->Q.txid2,ptr->Q.vout2,ptr->price,ptr->Q.satoshis,ptr->Q.srchash)) != 0 )
asks[numasks++] = op;
}
else if ( strcmp(ptr->Q.srccoin,rel) == 0 && strcmp(ptr->Q.destcoin,base) == 0 )
{
bids = realloc(bids,sizeof(*bids) * (numbids+1));
if ( (op= LP_orderbookentry(base,rel,ptr->Q.txid,ptr->Q.vout,ptr->Q.txid2,ptr->Q.vout2,1./ptr->price,ptr->Q.satoshis,ptr->Q.srchash)) != 0 )
bids[numbids++] = op;
}
}*/
cachenumbids = numbids, cachenumasks = numasks;
//printf("start cache.(%d %d) numbids.%d numasks.%d\n",cachenumbids,cachenumasks,numbids,numasks);
numasks = LP_orderbook_utxoentries(now,1,base,rel,&asks,numasks,cachenumasks);
numbids = LP_orderbook_utxoentries(now,-1,rel,base,&bids,numbids,cachenumbids);
numasks = LP_orderbook_utxoentries(now,1,base,rel,&asks,numasks,cachenumasks,duration);
numbids = LP_orderbook_utxoentries(now,-1,rel,base,&bids,numbids,cachenumbids,duration);
retjson = cJSON_CreateObject();
array = cJSON_CreateArray();
if ( numbids > 1 )

8
iguana/exchanges/LP_remember.c

@ -532,11 +532,17 @@ cJSON *basilisk_remember(int64_t *KMDtotals,int64_t *BTCtotals,uint32_t requesti
{
if ( (sentobj= LP_gettx(symbol,txid)) == 0 )
{
//printf("%s %s ready to broadcast\n",symbol,bits256_str(str2,txid));
char str2[65]; printf("%s %s ready to broadcast\n",symbol,bits256_str(str2,txid));
}
else
{
struct iguana_info *coin; int32_t ht = -1; uint32_t locktime,blocktime;
checktxid = jbits256(sentobj,"txid");
if ( (coin= LP_coinfind(symbol)) != 0 && (ht= LP_txheight(&locktime,&blocktime,coin,txid)) > 0 && ht > 0 )
{
if ( coin->firstrefht == 0 || ht < coin->firstrefht )
coin->firstrefht = ht;
}
if ( bits256_nonz(checktxid) == 0 )
checktxid = jbits256(sentobj,"hash");
if ( bits256_cmp(checktxid,txid) == 0 )

26
iguana/exchanges/LP_rpc.c

@ -73,6 +73,7 @@ char *issue_LP_clientgetutxos(char *destip,uint16_t destport,char *coin,int32_t
//return(retstr);
}
change to nanomsg write only, enforce fee, comms api
char *issue_LP_notify(char *destip,uint16_t destport,char *ipaddr,uint16_t port,double profitmargin,int32_t numpeers,int32_t numutxos)
{
char url[512],*retstr;
@ -115,24 +116,23 @@ char *issue_LP_notifyutxo(char *destip,uint16_t destport,struct LP_utxoinfo *utx
}
}
char *issue_LP_register(char *destip,uint16_t destport,bits256 pubkey,char *ipaddr,uint16_t pushport)
/*char *issue_LP_register(char *destip,uint16_t destport,bits256 pubkey,char *ipaddr,uint16_t pushport)
{
char url[512],str[65];//*retstr;
char url[512],str[65],*retstr;
sprintf(url,"http://%s:%u/api/stats/register?client=%s&pushaddr=%s&pushport=%u",destip,destport,bits256_str(str,pubkey),ipaddr,pushport);
return(LP_issue_curl("register",destip,destport,url));
//retstr = issue_curlt(url,LP_HTTP_TIMEOUT);
//printf("getutxo.(%s) -> (%s)\n",url,retstr!=0?retstr:"");
//return(retstr);
}
//return(LP_issue_curl("register",destip,destport,url));
retstr = issue_curlt(url,LP_HTTP_TIMEOUT);
//printf("register.(%s) -> (%s)\n",url,retstr!=0?retstr:"");
return(retstr);
}*/
char *issue_LP_psock(char *destip,uint16_t destport,int32_t ispaired)
{
char url[512];
char url[512],*retstr;
sprintf(url,"http://%s:%u/api/stats/psock?ispaired=%d",destip,destport,ispaired);
return(LP_issue_curl("psock",destip,destport,url));
//retstr = issue_curlt(url,LP_HTTP_TIMEOUT);
//printf("getutxo.(%s) -> (%s)\n",url,retstr!=0?retstr:"");
//return(retstr);
//return(LP_issue_curl("psock",destip,destport,url));
retstr = issue_curlt(url,LP_HTTP_TIMEOUT*3);
return(retstr);
}
uint16_t LP_psock_get(char *connectaddr,char *publicaddr,int32_t ispaired)
@ -197,7 +197,7 @@ cJSON *bitcoin_json(struct iguana_info *coin,char *method,char *params)
}
//usleep(1000);
//printf("dpow_gettxout.(%s)\n",retstr);
} else retjson = cJSON_Parse("{\"error\":\"disabled\"}");
} else retjson = cJSON_Parse("{\"result\":\"disabled\"}");
} else printf("bitcoin_json cant talk to NULL coin\n");
return(retjson);
}

315
iguana/exchanges/LP_scan.c

@ -18,154 +18,255 @@
// marketmaker
//
/*uint64_t oldLP_txvalue(char *symbol,bits256 txid,int32_t vout)
struct LP_transaction *LP_transactionfind(struct iguana_info *coin,bits256 txid)
{
uint64_t value = 0; double interest; cJSON *txobj,*vouts,*utxoobj; int32_t numvouts;
if ( (txobj= LP_gettx(symbol,txid)) != 0 )
struct LP_transaction *tx;
portable_mutex_lock(&coin->txmutex);
HASH_FIND(hh,coin->transactions,txid.bytes,sizeof(txid),tx);
portable_mutex_unlock(&coin->txmutex);
return(tx);
}
struct LP_transaction *LP_transactionadd(struct iguana_info *coin,bits256 txid,int32_t height,int32_t numvouts,int32_t numvins,uint32_t timestamp)
{
struct LP_transaction *tx; int32_t i;
if ( (tx= LP_transactionfind(coin,txid)) == 0 )
{
//char str[65]; printf("%s.(%s) txobj.(%s)\n",symbol,bits256_str(str,txid),jprint(txobj,0));
if ( (vouts= jarray(&numvouts,txobj,"vout")) != 0 && vout < numvouts )
//char str[65]; printf("%s ht.%d u.%u NEW TXID.(%s) vouts.[%d]\n",coin->symbol,height,timestamp,bits256_str(str,txid),numvouts);
//if ( bits256_nonz(txid) == 0 && tx->height == 0 )
// getchar();
tx = calloc(1,sizeof(*tx) + (sizeof(*tx->outpoints) * numvouts));
for (i=0; i<numvouts; i++)
tx->outpoints[i].spendvini = -1;
tx->height = height;
tx->numvouts = numvouts;
tx->numvins = numvins;
tx->timestamp = timestamp;
tx->txid = txid;
portable_mutex_lock(&coin->txmutex);
HASH_ADD_KEYPTR(hh,coin->transactions,tx->txid.bytes,sizeof(tx->txid),tx);
portable_mutex_unlock(&coin->txmutex);
} // else printf("warning adding already existing txid %s\n",bits256_str(str,tx->txid));
return(tx);
}
int32_t LP_txheight(uint32_t *timestampp,uint32_t *blocktimep,struct iguana_info *coin,bits256 txid)
{
bits256 blockhash; cJSON *blockobj,*txobj; int32_t height = 0;
if ( (txobj= LP_gettx(coin->symbol,txid)) != 0 )
{
*timestampp = juint(txobj,"locktime");
*blocktimep = juint(txobj,"blocktime");
blockhash = jbits256(txobj,"blockhash");
if ( bits256_nonz(blockhash) != 0 && (blockobj= LP_getblock(coin->symbol,blockhash)) != 0 )
{
utxoobj = jitem(vouts,vout);
if ( (value= jdouble(utxoobj,"amount")*SATOSHIDEN) == 0 && (value= jdouble(utxoobj,"value")*SATOSHIDEN) == 0 )
height = jint(blockobj,"height");
//printf("%s LP_txheight.%d\n",coin->symbol,height);
free_json(blockobj);
} //else printf("%s LP_txheight error (%s)\n",coin->symbol,jprint(txobj,0));
free_json(txobj);
}
return(height);
}
int32_t LP_undospends(struct iguana_info *coin,int32_t lastheight)
{
int32_t i,ht,num = 0; uint32_t timestamp,blocktime; struct LP_transaction *tx,*tmp;
HASH_ITER(hh,coin->transactions,tx,tmp)
{
for (i=0; i<tx->numvouts; i++)
{
if ( bits256_nonz(tx->outpoints[i].spendtxid) == 0 )
continue;
if ( (ht= tx->outpoints[i].spendheight) == 0 )
{
char str[65]; printf("%s LP_txvalue.%s strange utxo.(%s) vout.%d/%d\n",symbol,bits256_str(str,txid),jprint(utxoobj,0),vout,numvouts);
tx->outpoints[i].spendheight = LP_txheight(&timestamp,&blocktime,coin,tx->outpoints[i].spendtxid);
}
else if ( strcmp(symbol,"KMD") == 0 )
if ( (ht= tx->outpoints[i].spendheight) != 0 && ht > lastheight )
{
if ( (utxoobj= LP_gettxout(symbol,txid,vout)) != 0 )
{
if ( (interest= jdouble(utxoobj,"interest")) != 0. )
{
//printf("add interest of %.8f to %.8f\n",interest,dstr(value));
value += SATOSHIDEN * interest;
}
free_json(utxoobj);
}
char str[65]; printf("clear spend %s/v%d at ht.%d > lastheight.%d\n",bits256_str(str,tx->txid),i,ht,lastheight);
tx->outpoints[i].spendheight = 0;
tx->outpoints[i].spendvini = -1;
memset(tx->outpoints[i].spendtxid.bytes,0,sizeof(bits256));
}
}
free_json(txobj);
}
return(value);
}*/
return(num);
}
uint64_t LP_txvalue(char *coinaddr,char *symbol,bits256 txid,int32_t vout)
uint64_t LP_txinterestvalue(uint64_t *interestp,char *destaddr,struct iguana_info *coin,bits256 txid,int32_t vout)
{
uint64_t value = 0; double interest; cJSON *txobj,*sobj,*array; int32_t n; struct iguana_info *coin;
if ( (coin= LP_coinfind(symbol)) == 0 || coin->inactive != 0 )
return(0);
coinaddr[0] = 0;
if ( (txobj= LP_gettxout(symbol,txid,vout)) != 0 )
uint64_t interest,value = 0; cJSON *txobj,*sobj,*array; int32_t n=0;
*interestp = 0;
destaddr[0] = 0;
if ( (txobj= LP_gettxout(coin->symbol,txid,vout)) != 0 )
{
if ( (value= jdouble(txobj,"amount")*SATOSHIDEN) == 0 && (value= jdouble(txobj,"value")*SATOSHIDEN) == 0 )
{
char str[65]; printf("%s LP_txvalue.%s strange utxo.(%s) vout.%d\n",symbol,bits256_str(str,txid),jprint(txobj,0),vout);
char str[65]; printf("%s LP_txvalue.%s strange utxo.(%s) vout.%d\n",coin->symbol,bits256_str(str,txid),jprint(txobj,0),vout);
}
else if ( strcmp(symbol,"KMD") == 0 )
else if ( strcmp(coin->symbol,"KMD") == 0 )
{
if ( (interest= jdouble(txobj,"interest")) != 0. )
{
//printf("add interest of %.8f to %.8f\n",interest,dstr(value));
value += SATOSHIDEN * interest;
*interestp = SATOSHIDEN * interest;
}
}
if ( (sobj= jobj(txobj,"scriptPubKey")) != 0 && (array= jarray(&n,sobj,"addresses")) != 0 )
strcpy(coinaddr,jstri(array,0));
{
strcpy(destaddr,jstri(array,0));
if ( n > 1 )
printf("LP_txinterestvalue warning: violation of 1 output assumption n.%d\n",n);
} else printf("LP_txinterestvalue no addresses found?\n");
//char str[65]; printf("%.8f <- %s.(%s) txobj.(%s)\n",dstr(value),symbol,bits256_str(str,txid),jprint(txobj,0));
free_json(txobj);
}
return(value);
}
int32_t LP_vinscan(bits256 *spendtxidp,int32_t *spendvinip,char *symbol,bits256 txid,bits256 searchtxid,int32_t searchvout,bits256 searchtxid2,int32_t searchvout2)
int32_t LP_transactioninit(struct iguana_info *coin,bits256 txid)
{
cJSON *txobj,*vins,*vin; bits256 spenttxid; struct iguana_info *coin; int32_t j,numvins,spentvout,retval = -1;
memset(spendtxidp,0,sizeof(*spendtxidp));
*spendvinip = -1;
if ( (coin= LP_coinfind(symbol)) == 0 || coin->inactive != 0 )
return(retval);
if ( (txobj= LP_gettx(symbol,txid)) != 0 )
struct LP_transaction *tx; int32_t i,height,numvouts,numvins,spentvout; uint32_t timestamp,blocktime; cJSON *txobj,*vins,*vouts,*vout,*vin; bits256 spenttxid; char str[65];
if ( (txobj=LP_gettx(coin->symbol,txid)) != 0 )
{
if ( bits256_cmp(txid,jbits256(txobj,"txid")) != 0 )
{
char str[65]; printf("txid mismatch error %s vs %s\n",bits256_str(str,txid),jprint(txobj,0));
free_json(txobj);
return(-2);
}
height = LP_txheight(&timestamp,&blocktime,coin,txid);
if ( timestamp == 0 && height > 0 )
timestamp = blocktime;
vins = jarray(&numvins,txobj,"vin");
for (j=0; j<numvins; j++)
vouts = jarray(&numvouts,txobj,"vout");
if ( vouts != 0 && (tx= LP_transactionadd(coin,txid,height,numvouts,numvins,timestamp)) != 0 )
{
vin = jitem(vins,j);
spenttxid = jbits256(vin,"txid");
spentvout = jint(vin,"vout");
if ( spentvout == searchvout && bits256_cmp(spenttxid,searchtxid) == 0 )
for (i=0; i<numvouts; i++)
{
*spendtxidp = txid;
*spendvinip = j;
retval = 0;
break;
vout = jitem(vouts,i);
if ( (tx->outpoints[i].value= SATOSHIDEN * jdouble(vout,"value")) == 0 )
tx->outpoints[i].value = SATOSHIDEN * jdouble(vout,"amount");
tx->outpoints[i].interest = SATOSHIDEN * jdouble(vout,"interest");
}
else if ( spentvout == searchvout2 && bits256_cmp(spenttxid,searchtxid2) == 0 )
}
if ( vins != 0 )
{
for (i=0; i<numvins; i++)
{
*spendtxidp = txid;
*spendvinip = j;
retval = 1;
break;
vin = jitem(vins,i);
spenttxid = jbits256(vin,"txid");
spentvout = jint(vin,"vout");
if ( (tx= LP_transactionfind(coin,spenttxid)) != 0 )
{
if ( spentvout < tx->numvouts )
{
tx->outpoints[spentvout].spendtxid = txid;
tx->outpoints[spentvout].spendvini = i;
tx->outpoints[spentvout].spendheight = height;
//printf("spend %s %s/v%d at ht.%d\n",coin->symbol,bits256_str(str,tx->txid),spentvout,height);
} else printf("LP_transactioninint: %s spentvout.%d < numvouts.%d\n",bits256_str(str,spenttxid),spentvout,tx->numvouts);
}
}
}
free_json(txobj);
} else printf("unexpected missing txid\n"), retval = -3;
return(retval);
return(0);
} else printf("LP_transactioninit error for %s\n",bits256_str(str,txid));
return(-1);
}
int32_t LP_spendsearch(bits256 *spendtxidp,int32_t *indp,char *symbol,bits256 searchtxid,int32_t searchvout)
int32_t LP_blockinit(struct iguana_info *coin,int32_t height)
{
char destaddr[64]; struct iguana_info *coin; cJSON *blockjson,*txids,*txobj; bits256 hash,txid; int32_t h,i,j,numtxids,loadheight,errs = 0;
*indp = -1;
if ( (coin= LP_coinfind(symbol)) == 0 || coin->inactive != 0 )
return(0);
memset(spendtxidp,0,sizeof(*spendtxidp));
if ( LP_txvalue(destaddr,symbol,searchtxid,searchvout) > 0 )
return(0);
if ( (txobj= LP_gettx(symbol,searchtxid)) == 0 )
return(0);
hash = jbits256(txobj,"blockhash");
free_json(txobj);
if ( bits256_nonz(hash) == 0 )
int32_t i,numtx,checkht=-1; cJSON *blockobj,*txs; bits256 txid; struct LP_transaction *tx;
if ( (blockobj= LP_blockjson(&checkht,coin->symbol,0,height)) != 0 )
{
if ( (txs= jarray(&numtx,blockobj,"tx")) != 0 )
{
for (i=0; i<numtx; i++)
{
txid = jbits256i(txs,i);
if ( (tx= LP_transactionfind(coin,txid)) != 0 )
{
if ( tx->height == 0 )
tx->height = height;
else if ( tx->height != height )
{
printf("LP_blockinit: tx->height %d != %d\n",tx->height,height);
tx->height = height;
}
} else LP_transactioninit(coin,txid);
}
}
free_json(blockobj);
}
if ( checkht == height )
return(0);
if ( (blockjson= LP_getblock(symbol,hash)) == 0 )
else return(-1);
}
int64_t basilisk_txvalue(char *symbol,bits256 txid,int32_t vout)
{
char destaddr[64]; uint64_t value,interest = 0; struct iguana_info *coin;
if ( (coin= LP_coinfind(symbol)) == 0 || coin->inactive != 0 )
return(0);
loadheight = jint(blockjson,"height");
free_json(blockjson);
if ( loadheight <= 0 )
//char str[65]; printf("%s txvalue.(%s)\n",symbol,bits256_str(str,txid));
value = LP_txinterestvalue(&interest,destaddr,coin,txid,vout);
return(value + interest);
}
uint64_t LP_txvalue(char *coinaddr,char *symbol,bits256 txid,int32_t vout)
{
struct LP_transaction *tx; char _coinaddr[64]; uint64_t interest = 0,value = 0; struct iguana_info *coin;
if ( (coin= LP_coinfind(symbol)) == 0 || coin->inactive != 0 )
return(0);
while ( errs == 0 && *indp < 0 )
if ( coinaddr != 0 )
coinaddr[0] = 0;
if ( (tx= LP_transactionfind(coin,txid)) != 0 )
{
//printf("search %s ht.%d\n",symbol,loadheight);
if ( (blockjson= LP_blockjson(&h,symbol,0,loadheight)) != 0 && h == loadheight )
if ( vout < tx->numvouts )
{
if ( (txids= jarray(&numtxids,blockjson,"tx")) != 0 )
if ( bits256_nonz(tx->outpoints[vout].spendtxid) != 0 )
{
for (i=0; i<numtxids; i++)
char str[65]; printf("%s/v%d is spent\n",bits256_str(str,txid),vout);
return(0);
}
else
{
if ( coinaddr != 0 && strcmp(symbol,"KMD") == 0 )
{
txid = jbits256(jitem(txids,i),0);
if ( (j= LP_vinscan(spendtxidp,indp,symbol,txid,searchtxid,searchvout,searchtxid,searchvout)) >= 0 )
break;
value = LP_txinterestvalue(&tx->outpoints[vout].interest,coinaddr,coin,txid,vout);
}
//printf("return value %.8f + interest %.8f\n",dstr(tx->outpoints[vout].value),dstr(tx->outpoints[vout].interest));
return(tx->outpoints[vout].value + tx->outpoints[vout].interest);
}
free_json(blockjson);
} else errs++;
loadheight++;
} else printf("vout.%d >= tx->numvouts.%d\n",vout,tx->numvouts);
}
char str[65]; printf("reached %s ht.%d %s/v%d\n",symbol,loadheight,bits256_str(str,*spendtxidp),*indp);
if ( bits256_nonz(*spendtxidp) != 0 && *indp >= 0 )
return(loadheight);
else return(0);
if ( tx == 0 )
LP_transactioninit(coin,txid);
if ( coinaddr == 0 )
coinaddr = _coinaddr;
value = LP_txinterestvalue(&interest,coinaddr,coin,txid,vout);
//printf("coinaddr.(%s) value %.8f interest %.8f\n",coinaddr,dstr(value),dstr(interest));
return(value + interest);
}
int32_t LP_mempoolscan(char *symbol,bits256 txid)
int32_t LP_spendsearch(bits256 *spendtxidp,int32_t *indp,char *symbol,bits256 searchtxid,int32_t searchvout)
{
int32_t i,n; cJSON *array; struct iguana_info *coin;
struct LP_transaction *tx; struct iguana_info *coin;
*indp = -1;
if ( (coin= LP_coinfind(symbol)) == 0 || coin->inactive != 0 )
return(-1);
memset(spendtxidp,0,sizeof(*spendtxidp));
if ( (tx= LP_transactionfind(coin,searchtxid)) != 0 )
{
if ( searchvout < tx->numvouts && tx->outpoints[searchvout].spendvini >= 0 )
{
*spendtxidp = tx->outpoints[searchvout].spendtxid;
*indp = tx->outpoints[searchvout].spendvini;
return(tx->outpoints[searchvout].spendheight);
}
}
return(-1);
}
int32_t LP_mempoolscan(char *symbol,bits256 searchtxid)
{
int32_t i,n; cJSON *array; bits256 txid; struct iguana_info *coin; struct LP_transaction *tx;
if ( (coin= LP_coinfind(symbol)) == 0 || coin->inactive != 0 )
return(-1);
if ( (array= LP_getmempool(symbol)) != 0 )
@ -173,11 +274,16 @@ int32_t LP_mempoolscan(char *symbol,bits256 txid)
if ( is_cJSON_Array(array) != 0 && (n= cJSON_GetArraySize(array)) > 0 )
{
for (i=0; i<n; i++)
if ( bits256_cmp(txid,jbits256i(array,i)) == 0 )
{
txid = jbits256i(array,i);
if ( (tx= LP_transactionfind(coin,txid)) == 0 )
LP_transactioninit(coin,txid);
if ( bits256_cmp(txid,searchtxid) == 0 )
{
char str[65]; printf("found %s tx.(%s) in mempool slot.%d\n",symbol,bits256_str(str,txid),i);
return(i);
}
}
}
free_json(array);
}
@ -210,31 +316,30 @@ int32_t LP_waitmempool(char *symbol,bits256 txid,int32_t duration)
{
if ( LP_mempoolscan(symbol,txid) >= 0 )
return(0);
usleep(250000);
usleep(500000);
}
return(-1);
}
int32_t LP_mempool_vinscan(bits256 *spendtxidp,int32_t *spendvinp,char *symbol,bits256 searchtxid,int32_t searchvout,bits256 searchtxid2,int32_t searchvout2)
{
int32_t i,n; cJSON *array; bits256 mempooltxid; struct iguana_info *coin;
struct iguana_info *coin; int32_t selector; cJSON *array;
if ( symbol == 0 || symbol[0] == 0 || bits256_nonz(searchtxid) == 0 || bits256_nonz(searchtxid2) == 0 )
return(-1);
if ( (coin= LP_coinfind(symbol)) == 0 || coin->inactive != 0 )
return(-1);
if ( (array= LP_getmempool(symbol)) != 0 )
if ( time(NULL) > coin->lastmempool+LP_MEMPOOL_TIMEINCR )
{
if ( is_cJSON_Array(array) != 0 && (n= cJSON_GetArraySize(array)) > 0 )
if ( (array= LP_getmempool(symbol)) != 0 )
{
for (i=0; i<n; i++)
{
mempooltxid = jbits256i(array,i);
if ( (*spendvinp= LP_vinscan(spendtxidp,spendvinp,symbol,mempooltxid,searchtxid,searchvout,searchtxid2,searchvout2)) >= 0 )
return(i);
}
free_json(array);
coin->lastmempool = (uint32_t)time(NULL);
}
}
if ( (selector= LP_spendsearch(spendtxidp,spendvinp,symbol,searchtxid,searchvout)) >= 0 )
return(selector);
else if ( (selector= LP_spendsearch(spendtxidp,spendvinp,symbol,searchtxid2,searchvout2)) >= 0 )
return(selector);
return(-1);
}

65
iguana/exchanges/LP_statemachine.c

@ -17,6 +17,24 @@
// LP_statemachine.c
// marketmaker
//
/*struct LP_cacheinfo *ptr,*tmp;
HASH_ITER(hh,LP_cacheinfos,ptr,tmp)
{
if ( ptr->timestamp < now-3600*2 || ptr->price == 0. )
continue;
if ( strcmp(ptr->Q.srccoin,base) == 0 && strcmp(ptr->Q.destcoin,rel) == 0 )
{
asks = realloc(asks,sizeof(*asks) * (numasks+1));
if ( (op= LP_orderbookentry(base,rel,ptr->Q.txid,ptr->Q.vout,ptr->Q.txid2,ptr->Q.vout2,ptr->price,ptr->Q.satoshis,ptr->Q.srchash)) != 0 )
asks[numasks++] = op;
}
else if ( strcmp(ptr->Q.srccoin,rel) == 0 && strcmp(ptr->Q.destcoin,base) == 0 )
{
bids = realloc(bids,sizeof(*bids) * (numbids+1));
if ( (op= LP_orderbookentry(base,rel,ptr->Q.txid,ptr->Q.vout,ptr->Q.txid2,ptr->Q.vout2,1./ptr->price,ptr->Q.satoshis,ptr->Q.srchash)) != 0 )
bids[numbids++] = op;
}
}*/
/*void basilisk_swaps_init(struct supernet_info *myinfo)
{
@ -1432,4 +1450,51 @@ if ( (array= LP_tradecandidates(base)) != 0 )
LP_priceping(pubsock,utxo,"BTC",profitmargin);
else LP_priceping(pubsock,utxo,"KMD",profitmargin);
}*/
/*if ( LP_txvalue(destaddr,symbol,searchtxid,searchvout) > 0 )
return(0);
if ( (txobj= LP_gettx(symbol,searchtxid)) == 0 )
return(0);
hash = jbits256(txobj,"blockhash");
free_json(txobj);
if ( bits256_nonz(hash) == 0 )
return(0);
if ( (blockjson= LP_getblock(symbol,hash)) == 0 )
return(0);
loadheight = jint(blockjson,"height");
free_json(blockjson);
if ( loadheight <= 0 )
return(0);
while ( errs == 0 && *indp < 0 )
{
//printf("search %s ht.%d\n",symbol,loadheight);
if ( (blockjson= LP_blockjson(&h,symbol,0,loadheight)) != 0 && h == loadheight )
{
if ( (txids= jarray(&numtxids,blockjson,"tx")) != 0 )
{
for (i=0; i<numtxids; i++)
{
txid = jbits256(jitem(txids,i),0);
if ( (j= LP_vinscan(spendtxidp,indp,symbol,txid,searchtxid,searchvout,searchtxid,searchvout)) >= 0 )
break;
}
}
free_json(blockjson);
} else errs++;
loadheight++;
}
char str[65]; printf("reached %s ht.%d %s/v%d\n",symbol,loadheight,bits256_str(str,*spendtxidp),*indp);
if ( bits256_nonz(*spendtxidp) != 0 && *indp >= 0 )
return(loadheight);
else return(0);*/
/*if ( is_cJSON_Array(array) != 0 && (n= cJSON_GetArraySize(array)) > 0 )
{
for (i=0; i<n; i++)
{
mempooltxid = jbits256i(array,i);
if ( (selector= LP_vinscan(spendtxidp,spendvinp,symbol,mempooltxid,searchtxid,searchvout,searchtxid2,searchvout2)) >= 0 )
return(selector);
}
}*/

20
iguana/exchanges/LP_transaction.c

@ -13,12 +13,12 @@
* Removal or modification of this copyright notice is prohibited. *
* *
******************************************************************************/
//
// LP_transaction.c
// marketmaker
//
bits256 LP_broadcast(char *txname,char *symbol,char *txbytes,bits256 expectedtxid)
{
char *retstr; bits256 txid; cJSON *retjson,*errorobj; int32_t i,sentflag = 0;
@ -816,24 +816,6 @@ int32_t basilisk_swap_getsigscript(char *symbol,uint8_t *script,int32_t maxlen,b
return(scriptlen);
}
int64_t basilisk_txvalue(char *symbol,bits256 txid,int32_t vout)
{
cJSON *txobj,*vouts,*item; int32_t n; int64_t value = 0;
//char str[65]; printf("%s txvalue.(%s)\n",symbol,bits256_str(str,txid));
if ( (txobj= LP_gettx(symbol,txid)) != 0 )
{
//printf("txobj.(%s)\n",jprint(txobj,0));
if ( (vouts= jarray(&n,txobj,"vout")) != 0 )
{
item = jitem(vouts,vout);
if ( (value= jdouble(item,"amount") * SATOSHIDEN) == 0 )
value = jdouble(item,"value") * SATOSHIDEN;
}
free_json(txobj);
}
return(value);
}
bits256 _LP_swap_spendtxid(char *symbol,char *destaddr,char *coinaddr,bits256 utxotxid,int32_t vout)
{
char *retstr,*addr; cJSON *array,*item,*array2; int32_t i,n,m; bits256 spendtxid,txid;

52
iguana/exchanges/LP_utxos.c

@ -72,6 +72,18 @@ struct LP_utxoinfo *LP_utxofind(int32_t iambob,bits256 txid,int32_t vout)
return(utxo);
}
struct LP_utxoinfo *LP_utxopairfind(int32_t iambob,bits256 txid,int32_t vout,bits256 txid2,int32_t vout2)
{
struct LP_utxoinfo *utxo=0; struct _LP_utxoinfo u;
if ( (utxo= LP_utxofind(iambob,txid,vout)) != 0 )
{
u = (iambob != 0) ? utxo->deposit : utxo->fee;
if (vout2 == u.vout && bits256_cmp(u.txid,txid2) == 0 )
return(utxo);
}
return(0);
}
struct LP_utxoinfo *LP_utxo2find(int32_t iambob,bits256 txid2,int32_t vout2)
{
struct LP_utxoinfo *utxo=0;
@ -276,7 +288,7 @@ int32_t LP_iseligible(uint64_t *valp,uint64_t *val2p,int32_t iambob,char *symbol
if ( (val2= LP_txvalue(destaddr2,symbol,txid2,vout2)) >= threshold )
{
if ( strcmp(destaddr,destaddr2) != 0 )
printf("mismatched %s destaddr %s vs %s\n",symbol,destaddr,destaddr2);
printf("mismatched %s destaddr (%s) vs (%s)\n",symbol,destaddr,destaddr2);
else if ( (iambob == 0 && val2 > val) || (iambob != 0 && val2 <= satoshis) )
printf("iambob.%d ineligible due to offsides: val %.8f and val2 %.8f vs %.8f diff %lld\n",iambob,dstr(val),dstr(val2),dstr(satoshis),(long long)(val2 - val));
else
@ -342,7 +354,7 @@ struct LP_utxoinfo *LP_utxo_bestfit(char *symbol,uint64_t destsatoshis)
return(0);
HASH_ITER(hh,LP_utxoinfos[0],utxo,tmp)
{
//char str[65]; printf("check %s.%s\n",utxo->coin,bits256_str(str,utxo->payment.txid));
//char str[65]; printf("[%.8f vs %.8f] check %s.%s avail.%d ismine.%d >= %d\n",dstr(destsatoshis),dstr(utxo->S.satoshis),utxo->coin,bits256_str(str,utxo->payment.txid),LP_isavailable(utxo) > 0,LP_ismine(utxo) > 0,utxo->S.satoshis >= destsatoshis);
if ( strcmp(symbol,utxo->coin) == 0 && LP_isavailable(utxo) > 0 && LP_ismine(utxo) > 0 )
{
if ( utxo->S.satoshis >= destsatoshis && (bestutxo == 0 || utxo->S.satoshis < bestutxo->S.satoshis) )
@ -379,7 +391,7 @@ void LP_spentnotify(struct LP_utxoinfo *utxo,int32_t selector)
char *LP_spentcheck(cJSON *argjson)
{
char destaddr[64]; bits256 txid,checktxid; int32_t vout,checkvout; struct LP_utxoinfo *utxo; int32_t iambob,retval = 0;
bits256 txid,checktxid; int32_t vout,checkvout; struct LP_utxoinfo *utxo; int32_t iambob,retval = 0;
txid = jbits256(argjson,"txid");
vout = jint(argjson,"vout");
for (iambob=0; iambob<=1; iambob++)
@ -393,7 +405,7 @@ char *LP_spentcheck(cJSON *argjson)
checktxid = jbits256(argjson,"checktxid");
checkvout = jint(argjson,"checkvout");
}
if ( LP_txvalue(destaddr,utxo->coin,checktxid,checkvout) == 0 )
if ( LP_txvalue(0,utxo->coin,checktxid,checkvout) == 0 )
{
if ( LP_mypeer != 0 && LP_mypeer->numutxos > 0 )
LP_mypeer->numutxos--;
@ -432,13 +444,14 @@ struct LP_utxoinfo *LP_utxoadd(int32_t iambob,int32_t mypubsock,char *symbol,bit
}
if ( LP_iseligible(&val,&val2,iambob,symbol,txid,vout,tmpsatoshis,txid2,vout2,pubkey) <= 0 )
{
// iambob.0 utxoadd COQUI inactive.0 got ineligible txid value 1.20000000, value2 0.01000000, tmpsatoshis 1.20000000
printf("iambob.%d utxoadd %s inactive.%u got ineligible txid value %.8f, value2 %.8f, tmpsatoshis %.8f\n",iambob,symbol,coin->inactive,dstr(value),dstr(value2),dstr(tmpsatoshis));
return(0);
}
if ( dispflag != 0 )
printf("%.8f %.8f %s iambob.%d %s utxoadd.(%.8f %.8f) %s %s\n",dstr(val),dstr(val2),coinaddr,iambob,symbol,dstr(value),dstr(value2),bits256_str(str,txid),bits256_str(str2,txid2));
dispflag = 1;
if ( 0 && (selector= LP_mempool_vinscan(&spendtxid,&spendvini,symbol,txid,vout,txid2,vout2)) >= 0 )
if ( (selector= LP_mempool_vinscan(&spendtxid,&spendvini,symbol,txid,vout,txid2,vout2)) >= 0 )
{
printf("utxoadd selector.%d in mempool %s vini.%d",selector,bits256_str(str,spendtxid),spendvini);
return(0);
@ -457,7 +470,7 @@ struct LP_utxoinfo *LP_utxoadd(int32_t iambob,int32_t mypubsock,char *symbol,bit
char str[65],str2[65],str3[65],str4[65],str5[65],str6[65];
if ( dispflag != 0 )
printf("error on subsequent utxo iambob.%d %.8f %.8f add.(%s %s) when.(%s %s) %d %d %d %d %d %d %d %d %d %d %d pubkeys.(%s vs %s)\n",iambob,dstr(val),dstr(val2),bits256_str(str,txid),bits256_str(str2,txid2),bits256_str(str3,utxo->payment.txid),bits256_str(str4,utxo->deposit.txid),bits256_cmp(txid,utxo->payment.txid) != 0,bits256_cmp(txid2,u.txid) != 0,vout != utxo->payment.vout,tmpsatoshis != utxo->S.satoshis,vout2 != u.vout,value2 != u.value,strcmp(symbol,utxo->coin) != 0,strcmp(spendscript,utxo->spendscript) != 0,strcmp(coinaddr,utxo->coinaddr) != 0,bits256_cmp(pubkey,utxo->pubkey) != 0,value != utxo->payment.value,bits256_str(str5,pubkey),bits256_str(str6,utxo->pubkey));
if ( utxo->T.spentflag != 0 || LP_txvalue(utxo->coinaddr,utxo->coin,utxo->payment.txid,utxo->payment.vout) < utxo->payment.value || LP_txvalue(utxo->coinaddr,utxo->coin,u.txid,u.vout) < u.value )
if ( utxo->T.spentflag != 0 || LP_txvalue(0,utxo->coin,utxo->payment.txid,utxo->payment.vout) < utxo->payment.value || LP_txvalue(0,utxo->coin,u.txid,u.vout) < u.value )
{
if ( utxo->T.spentflag == 0 )
utxo->T.spentflag = (uint32_t)time(NULL);
@ -758,7 +771,7 @@ bits256 LP_privkeycalc(void *ctx,uint8_t *pubkey33,bits256 *pubkeyp,struct iguan
bitcoin_priv2wif(tmpstr,privkey,coin->wiftype);
bitcoin_addr2rmd160(coin->taddr,&tmptype,rmd160,coin->smartaddr);
LP_privkeyadd(privkey,rmd160);
if ( coin->pubtype != 60 || strcmp(coin->symbol,"KMD") == 0 )
if ( 0 && (coin->pubtype != 60 || strcmp(coin->symbol,"KMD") == 0) )
printf("%s (%s) %d wif.(%s) (%s)\n",coin->symbol,coin->smartaddr,coin->pubtype,tmpstr,passphrase);
if ( counter++ == 0 )
{
@ -767,8 +780,14 @@ bits256 LP_privkeycalc(void *ctx,uint8_t *pubkey33,bits256 *pubkeyp,struct iguan
userpub = curve25519(userpass,curve25519_basepoint9());
printf("userpass.(%s)\n",bits256_str(USERPASS,userpub));
}
if ( (retjson= LP_importprivkey(coin->symbol,tmpstr,coin->smartaddr,-1)) != 0 ) //coin->inactive == 0 &&
printf("importprivkey.%s -> (%s)\n",coin->symbol,jprint(retjson,1));
if ( (retjson= LP_importprivkey(coin->symbol,tmpstr,coin->smartaddr,-1)) != 0 )
{
if ( jobj(retjson,"error") != 0 )
{
printf("cant importprivkey.%s -> (%s), abort session\n",coin->symbol,jprint(retjson,1));
exit(-1);
}
}
}
LP_mypubkey = *pubkeyp = curve25519(privkey,curve25519_basepoint9());
//printf("privkey.(%s) -> LP_mypubkey.(%s)\n",bits256_str(str,privkey),bits256_str(str2,LP_mypubkey));
@ -777,19 +796,16 @@ bits256 LP_privkeycalc(void *ctx,uint8_t *pubkey33,bits256 *pubkeyp,struct iguan
void LP_privkey_updates(void *ctx,int32_t pubsock,char *passphrase,int32_t initonly)
{
int32_t i; struct iguana_info *coin; bits256 pubkey,privkey; uint8_t pubkey33[33];
struct iguana_info *coin,*tmp; bits256 pubkey,privkey; uint8_t pubkey33[33];
memset(privkey.bytes,0,sizeof(privkey));
pubkey = privkey;
for (i=0; i<LP_numcoins; i++)
HASH_ITER(hh,LP_coins,coin,tmp)
{
//printf("i.%d of %d\n",i,LP_numcoins);
if ( (coin= LP_coinfind(LP_coins[i].symbol)) != 0 )
{
if ( bits256_nonz(privkey) == 0 || coin->smartaddr[0] == 0 )
privkey = LP_privkeycalc(ctx,pubkey33,&pubkey,coin,passphrase,"");
if ( coin->inactive == 0 && initonly == 0 )
LP_privkey_init(pubsock,coin,privkey,pubkey,pubkey33);
}
if ( bits256_nonz(privkey) == 0 || coin->smartaddr[0] == 0 )
privkey = LP_privkeycalc(ctx,pubkey33,&pubkey,coin,passphrase,"");
if ( coin->inactive == 0 && initonly == 0 )
LP_privkey_init(pubsock,coin,privkey,pubkey,pubkey33);
}
}

86
iguana/exchanges/README.md

@ -1,23 +1,77 @@
You need to build iguana onetime from ~/SuperNET/iguana:
Latest Readme is at http://pad.supernet.org/barterdex-readme
DEPENDENCIES
First of all you are going to need to have the komodod daemon and the assetchains running.
Install dependency packages:
sudo apt-get install build-essential pkg-config libc6-dev m4 g++-multilib autoconf libtool libncurses5-dev unzip git python zlib1g-dev wget bsdmainutils automake libboost-all-dev libssl-dev libprotobuf-dev protobuf-compiler libqt4-dev libqrencode-dev libdb++-dev ntp ntpdate vim software-properties-common curl libcurl4-gnutls-dev cmake clang
Some Linux machines are now providing nanomsg package version 1.0. If it is available via package manager, you can install it from there. Else, you should use github repo of nanomsg and compile it yourself.
For Ubuntu 14.04 you need to install it yourself
cd /tmp
wget https://github.com/nanomsg/nanomsg/archive/1.0.0.tar.gz -O nanomsg-1.0.0.tar.gz
tar -xzvf nanomsg-1.0.0.tar.gz
cd nanomsg-1.0.0
mkdir build
cd build
cmake .. -DCMAKE_INSTALL_PREFIX=/usr
cmake --build .
sudo cmake --build . --target install
sudo ldconfig
Or the following for 16.04
git clone https://github.com/nanomsg/nanomsg
cd nanomsg
cmake .
make
sudo make install
sudo ldconfig
COMPILE LP NODE
To compile the BarterDEX you need to build iguana one time:
cd ~
git clone https://github.com/jl777/SuperNET
cd SuperNET/iguana
git checkout dev
./m_LP
Then launch it to run in background ../agents/iguana &
IGUANA DAEMON STARTUP
Then launch the iguana daemon by executing:
../agents/iguana &
Now iguana should be running and providing port 7778 API: 127.0.0.1:7778 page in the browser will show the API testpage, but for marketmaker these functions are not used very much. it is port 7779 that is used and the marketmaker program is what provides those functions.
From ~/SuperNET/iguana/exchanges:
BarterDEX EXCHANGE INSTALL
cd ~/SuperNET/iguana/exchanges
./install
Now in the ~/SuperNET/iguana/dexscripts directory you will have example scripts that you can change without new git updates overwriting them. Of course, if a new update to a script is made and you dont run install again then you wont have the latest versions. All these scripts are expecting a userpass file, which contains the definition of the $userpass variable to authenticate API access. This avoids evil webpages that try to issue port 7779 calls to steal your money. The userpass variable is linked to each passphrase and that is defined in the randval file. Put your passphrase in that file. You can find templates for these two files in the iguana/exchanges dir.
Next step is to actually start the marketmaker from ~/SuperNET/iguana/dexscripts. Use ./run for LP node and ./client for client mode
At first you wont know the value of userpass. To find out, just run any API script. The first one will return all the required data, the "userpass" field is first and you can copy that value and put it into ~/SuperNET/iguana/dexscripts/userpass file. If you dont, all subsequent API calls will get authorization errors.
Now, move to ~/SuperNET/iguana/dexscripts:
cd ~/SuperNET/iguana/dexscripts
Now in the ~/SuperNET/iguana/dexscripts directory you will have example scripts that you can change without new git updates overwriting them. These scripts will have example commands that you will need to customize to work with the coins you want to trade. Of course, if a new update to a script is made and you dont run install again then you wont have the latest versions.
For example: if you want to enable the JUMBLR coin, you need to edit the enable file:
nano ~SuperNET/iguana/dexscripts/enable
copy the default command and paste it below but with the coin edited to JUMBLR in this case:
curl --url "http://127.0.0.1:7779" --data "{\"userpass\":\"$userpass\",\"method\":\"enable\",\"coin\":\"JUMBLR\"}"
The same will happen for any other script in the dexscripts directory. You will need to edit the scripts to include or exclude the coins you want to trade.
IMPORTANT: All these scripts are expecting a userpass file, which contains the definition of the $userpass variable to authenticate API access. This avoids evil webpages that try to issue port 7779 calls to steal your money. At first you wont know the value of userpass. To find out, just run any API script. The first one will return all the required data, the "userpass" field is first and you can copy that value and put it into ~/SuperNET/iguana/dexscripts/userpass file. If you dont, all subsequent API calls will get authorization errors.The userpass variable is linked to each passphrase and that is defined in the passphrase file. Put your passphrase in that file. You can find templates for these two files in the iguana/exchanges dir. (you need to copy the edited version of these files to ~/SuperNET/iguana/dexscripts).
cd ~/SuperNET/iguana/dexscripts
./enable
(look for the userpass passphrase that will be generated and copy it)
Now you have to paste the passphrase in both userpass and passphrase files:
nano ./userpass
nano ./passphrase
( paste the passphrase generated into the files where it says: “<put the userpass value from the first API call here>”)
EXCHANGE CLIENT STARTUP
Next step is to actually start the marketmaker from ~/SuperNET/iguana/dexscripts.
cd ~/SuperNET/iguana/dexscripts
./client (for client mode) or
./run (for LPnode mode)
Assuming you created the userpass file properly, you can now issue barterDEX api calls using all the scripts in the dexscripts dir. Please look at these scripts, they are simple curl invocations of a couple lines. Nothing scary and should be self explanatory.
The help script displays all the api endpoints you should need. You can customize any of the dexscripts for your desired usage, make sure you edit them with the right coins, as if you issue a script for BTC it will do it for BTC instead of the coin you wanted. These scripts wont read your mind, they just do what is in them
FUNDING SMARTADDRESS
In order to start trading, you need to fund your smartaddress (as listed on the first API call return) from the getcoins API call.
To see which is your smart address go to ~/SuperNET/iguana/dexscritps and execute:
./getcoins
To make sure you have utxo pairs for both the bob and alice usage, it is best to send utxo in triplets of X, 1.2 X and 0.01 X. So if X is 10, send 10, 12, and 0.1 coins using sendtoaddress to your smartaddress. This means you will have to send 3 different transactions to the same address with 3 different quantities
for example:
If i want to fund my komodo smartaddress with 100 komodo i need to first send a tx with 100kmd then another tx with 120kmd and a third tx with only 10kmd
After this, it should appear in the inventory. To see the inventory you need to execute:
./inv
SETTING PRICE
To set price you need to edit the ./setprice script in the dexscripts folder. This scripts contains a curl command that looks like this:
curl --url "http://127.0.0.1:7779" --data "{\"userpass\":\"$userpass\",\"method\":\"setprice\",\"base\":\"REVS\",\"rel\":\"KMD\",\"price\":1.234}"
In this command you should edit the coin (in this case is REVS) and then set the price per coin based in Komodo. In the command above we are setting a price of 1.23KMD per REVS.
After you setprice (./setprice), then it will appear in orderbooks with that coin in either the base or rel.

2
iguana/exchanges/autotrade

@ -1,2 +1,2 @@
source userpass
curl --url "http://127.0.0.1:7779" --data "{\"userpass\":\"$userpass\",\"method\":\"autotrade\",\"base\":\"REVS\",\"rel\":\"KMD\",\"volume\":1.01,\"price\":1.234}"
curl --url "http://127.0.0.1:7779" --data "{\"userpass\":\"$userpass\",\"method\":\"autotrade\",\"base\":\"REVS\",\"rel\":\"KMD\",\"relvolume\":1.01,\"price\":1.234}"

2
iguana/exchanges/bestfit

@ -0,0 +1,2 @@
source userpass
curl --url "http://127.0.0.1:7779" --data "{\"userpass\":\"$userpass\",\"method\":\"bestfit\",\"rel\":\"KMD\",\"relvolume\":1.01}"

4
iguana/exchanges/client

@ -1,8 +1,8 @@
source randval
source passphrase
source coins
pkill -15 marketmaker;
git pull;
cd ..;
./m_mm;
./marketmaker "{\"gui\":\"nogui\",\"client\":1, \"userhome\":\"/${HOME#"/"}\", \"passphrase\":\"$randval\", \"coins\":$coins}" &
./marketmaker "{\"gui\":\"nogui\",\"client\":1, \"userhome\":\"/${HOME#"/"}\", \"passphrase\":\"$passphrase\", \"coins\":$coins}" &

4
iguana/exchanges/client_osx

@ -1,8 +1,8 @@
source randval
source passphrase
source coins
pkill -15 marketmaker;
git pull;
cd ..;
./m_mm;
./marketmaker "{\"gui\":\"nogui\",\"client\":1, \"userhome\":\"/${HOME#"/"}/Library/Application\ Support\", \"passphrase\":\"$randval\", \"coins\":$coins}" &
./marketmaker "{\"gui\":\"nogui\",\"client\":1, \"userhome\":\"/${HOME#"/"}/Library/Application\ Support\", \"passphrase\":\"$passphrase\", \"coins\":$coins}" &

3
iguana/exchanges/coins

@ -1 +1,4 @@
export coins="[{\"coin\":\"REVS\",\"active\":1, \"asset\":\"REVS\",\"rpcport\":10196}, {\"coin\":\"JUMBLR\",\"active\":1, \"asset\":\"JUMBLR\",\"rpcport\":15106}, {\"coin\":\"DOGE\", \"name\":\"dogecoin\", \"pubtype\":30, \"p2shtype\":5, \"wiftype\":128, \"txfee\":100000000}, {\"coin\":\"HUSH\",\"name\":\"hush\",\"rpcport\":8822,\"taddr\":28,\"pubtype\":184,\"p2shtype\":189,\"wiftype\":128,\"txfee\":10000 }, {\"active\":0,\"coin\":\"ZEC\",\"name\":\"zcash\",\"rpcport\":8232,\"taddr\":28,\"pubtype\":184,\"p2shtype\":189,\"wiftype\":128,\"txfee\":10000 }, {\"coin\":\"DGB\", \"name\":\"digibyte\", \"pubtype\":30, \"p2shtype\":5, \"wiftype\":128, \"txfee\":10000}, {\"coin\":\"MZC\", \"name\":\"mazacoin\", \"pubtype\":50, \"p2shtype\":9, \"wiftype\":224, \"txfee\":0}, {\"coin\":\"SYS\", \"name\":\"syscoin\", \"pubtype\":0, \"p2shtype\":5, \"wiftype\":128, \"txfee\":100000}, {\"coin\":\"UNO\", \"name\":\"unobtanium\", \"pubtype\":130, \"p2shtype\":30, \"wiftype\":224, \"txfee\":1000000}, {\"coin\":\"ZET\", \"name\":\"zetacoin\", \"pubtype\":80, \"p2shtype\":9, \"wiftype\":224, \"txfee\":10000}, {\"coin\":\"ZEC\", \"name\":\"zcash\", \"pubtype\":184, \"p2shtype\":189, \"wiftype\":128, \"txfee\":10000}, {\"coin\":\"BTM\", \"name\":\"bitmark\", \"pubtype\":85, \"p2shtype\":5, \"wiftype\":213, \"txfee\":0}, {\"coin\":\"CARB\", \"name\":\"carboncoin\", \"pubtype\":47, \"p2shtype\":5, \"wiftype\":175, \"txfee\":0}, {\"coin\":\"ANC\", \"name\":\"anoncoin\", \"pubtype\":23, \"p2shtype\":5, \"wiftype\":151, \"txfee\":2000000}, {\"coin\":\"FRK\", \"name\":\"franko\", \"pubtype\":35, \"p2shtype\":5, \"wiftype\":163, \"txfee\":0}, {\"coin\":\"GAME\", \"name\":\"gamecredits\", \"pubtype\":38, \"p2shtype\":5, \"wiftype\":166, \"txfee\":100000}, {\"coin\":\"LTC\", \"name\":\"litecoin\", \"rpcport\":9332, \"pubtype\":48, \"p2shtype\":5, \"wiftype\":176, \"txfee\":100000 }, {\"coin\":\"SUPERNET\",\"asset\":\"SUPERNET\",\"rpcport\":11341}, {\"coin\":\"WLC\",\"asset\":\"WLC\",\"rpcport\":12167}, {\"coin\":\"PANGEA\",\"asset\":\"PANGEA\",\"rpcport\":14068}, {\"coin\":\"DEX\",\"asset\":\"DEX\",\"rpcport\":11890}, {\"coin\":\"BET\",\"asset\":\"BET\",\"rpcport\":14250}, {\"coin\":\"CRYPTO\",\"asset\":\"CRYPTO\",\"rpcport\":8516}, {\"coin\":\"HODL\",\"asset\":\"HODL\",\"rpcport\":14431}, {\"coin\":\"SHARK\",\"asset\":\"SHARK\",\"rpcport\":10114}, {\"coin\":\"BOTS\",\"asset\":\"BOTS\",\"rpcport\":11964}, {\"coin\":\"MGW\",\"asset\":\"MGW\",\"rpcport\":12386}, {\"coin\":\"COQUI\",\"asset\":\"COQUI\",\"rpcport\":14276}, {\"coin\":\"KV\",\"asset\":\"KV\",\"rpcport\":8299}, {\"coin\":\"CEAL\",\"asset\":\"CEAL\",\"rpcport\":11116}, {\"coin\":\"MESH\",\"asset\":\"MESH\",\"rpcport\":9455}]"
#,{\"coin\":\"AUD\",\"asset\":\"AUD\",\"rpcport\":8045}, {\"coin\":\"BGN\",\"asset\":\"BGN\",\"rpcport\":9110}, {\"coin\":\"CAD\",\"asset\":\"CAD\",\"rpcport\":8720}, {\"coin\":\"CHF\",\"asset\":\"CHF\",\"rpcport\":15312}, {\"coin\":\"CNY\",\"asset\":\"CNY\",\"rpcport\":10384}, {\"coin\":\"CZK\",\"asset\":\"CZK\",\"rpcport\":9482}, {\"coin\":\"DKK\",\"asset\":\"DKK\",\"rpcport\":13830}, {\"coin\":\"EUR\",\"asset\":\"EUR\",\"rpcport\":8065}, {\"coin\":\"GBP\",\"asset\":\"GBP\",\"rpcport\":11505}, {\"coin\":\"HKD\",\"asset\":\"HKD\",\"rpcport\":15409}, {\"coin\":\"HRK\",\"asset\":\"HRK\",\"rpcport\":12617}, {\"coin\":\"HUF\",\"asset\":\"HUF\",\"rpcport\":13699}, {\"coin\":\"IDR\",\"asset\":\"IDR\",\"rpcport\":14459}, {\"coin\":\"ILS\",\"asset\":\"ILS\",\"rpcport\":14638}, {\"coin\":\"INR\",\"asset\":\"INR\",\"rpcport\":10536}, {\"coin\":\"JPY\",\"asset\":\"JPY\",\"rpcport\":13145}, {\"coin\":\"KRW\",\"asset\":\"KRW\",\"rpcport\":14020}, {\"coin\":\"MXN\",\"asset\":\"MXN\",\"rpcport\":13970}, {\"coin\":\"MYR\",\"asset\":\"MYR\",\"rpcport\":10688}, {\"coin\":\"NOK\",\"asset\":\"NOK\",\"rpcport\":11588}, {\"coin\":\"NZD\",\"asset\":\"NZD\",\"rpcport\":10915}, {\"coin\":\"PHP\",\"asset\":\"PHP\",\"rpcport\":11181}, {\"coin\":\"PLN\",\"asset\":\"PLN\",\"rpcport\":13493}, {\"coin\":\"BRL\",\"asset\":\"BRL\",\"rpcport\":9914}, {\"coin\":\"RON\",\"asset\":\"RON\",\"rpcport\":8675}, {\"coin\":\"RUB\",\"asset\":\"RUB\",\"rpcport\":8199}, {\"coin\":\"SEK\",\"asset\":\"SEK\",\"rpcport\":11447}, {\"coin\":\"SGD\",\"asset\":\"SGD\",\"rpcport\":14475}, {\"coin\":\"THB\",\"asset\":\"THB\",\"rpcport\":11847}, {\"coin\":\"TRY\",\"asset\":\"TRY\",\"rpcport\":13924}, {\"coin\":\"USD\",\"asset\":\"USD\",\"rpcport\":13967}, {\"coin\":\"ZAR\",\"asset\":\"ZAR\",\"rpcport\":15160}]"

6
iguana/exchanges/install

@ -1 +1,5 @@
cp autotrade client run_osx client_osx run coins disable enable forward myprice myprices getcoins getpeers getpeersIP getprices getutxos help inv lookup pub run_osx setprice status utxos ../dexscripts
cp trade ordermatch bestfit orderbook autotrade client run_osx client_osx run coins disable enable forward myprice myprices getcoins getpeers getpeersIP getprices getutxos help inv lookup pub setprice status utxos ../dexscripts
cd ../dexscripts
echo now in dexscripts directory where you can make customized scripts that wont conflict with git pull
#cp ../exchanges/passphrase ../exchanges/userpass .
echo you will need to have a passphrase file with your passphrase and userpass file with userpass value in dexscripts dir

2
iguana/exchanges/inv

@ -1,2 +1,2 @@
source userpass
curl --url "http://127.0.0.1:7779" --data "{\"userpass\":\"$userpass\",\"method\":\"inventory\",\"coin\":\"BTC\"}"
curl --url "http://127.0.0.1:7779" --data "{\"userpass\":\"$userpass\",\"method\":\"inventory\",\"coin\":\"KMD\"}"

2
iguana/exchanges/orderbook

@ -1,2 +1,2 @@
source userpass
curl --url "http://127.0.0.1:7779" --data "{\"userpass\":\"$userpass\",\"method\":\"orderbook\",\"base\":\"KMD\",\"rel\":\"BTC\"}"
curl --url "http://127.0.0.1:7779" --data "{\"userpass\":\"$userpass\",\"method\":\"orderbook\",\"base\":\"JUMBLR\",\"rel\":\"KMD\"}"

3
iguana/exchanges/ordermatch

@ -0,0 +1,3 @@
source userpass
#ordermatch(base, txfee=0, rel, desttxfee=0, price, txid, vout, feetxid, feevout, duration=3600)\n\
curl --url "http://127.0.0.1:7779" --data "{\"userpass\":\"$userpass\",\"method\":\"ordermatch\",\"base\":\"REVS\",\"rel\":\"KMD\",\"price\":1.234,\"duration\":600,\"txfee\":0,\"desttxfee\":0,\"txid\":\"$1\",\"vout\":$2,\"feetxid\":\"$3\",\"feevout\":$4}"

1
iguana/exchanges/passphrase

@ -0,0 +1 @@
export passphrase="<put a very strong passphrase here>"

1
iguana/exchanges/randval

@ -1 +0,0 @@
export randval="<put a very strong passphrase here>"

2
iguana/exchanges/register

@ -0,0 +1,2 @@
source userpass
curl --url "http://5.9.253.195:7779" --data "{\"userpass\":\"9bb4846d24136fc7c33515e45bccbab5c8fb7b57b411aa20057b371da9358255\",\"agent\":\"stats\",\"method\":\"register\",\"client\":\"6d3332be4904feafd326609bd76b66528dc7b2e2d75a7bd110c6bf8d19c4cf58\",\"pushaddr\":\"5.9.253.195\",\"pushport\":\"10000\"}"

4
iguana/exchanges/run

@ -1,7 +1,7 @@
source randval
source passphrase
source coins
pkill -15 marketmaker;
git pull;
cd ..;
./m_mm;
$1 ./marketmaker "{\"gui\":\"nogui\", \"profitmargin\":0.01, \"userhome\":\"/${HOME#"/"}\", \"passphrase\":\"$randval\", \"coins\":$coins}" &
$1 ./marketmaker "{\"gui\":\"nogui\", \"profitmargin\":0.01, \"userhome\":\"/${HOME#"/"}\", \"passphrase\":\"$passphrase\", \"coins\":$coins}" &

4
iguana/exchanges/run_osx

@ -1,7 +1,7 @@
source randval
source passphrase
source coins
pkill -15 marketmaker;
git pull;
cd ..;
./m_mm;
$1 ./marketmaker "{\"gui\":\"nogui\", \"profitmargin\":0.01, \"userhome\":\"/${HOME#"/"}/Library/Application\ Support\", \"passphrase\":\"$randval\", \"coins\":$coins}" &
$1 ./marketmaker "{\"gui\":\"nogui\", \"profitmargin\":0.01, \"userhome\":\"/${HOME#"/"}/Library/Application\ Support\", \"passphrase\":\"$passphrase\", \"coins\":$coins}" &

2
iguana/exchanges/trade

@ -0,0 +1,2 @@
source userpass
curl --url "http://127.0.0.1:7779" --data "{\"userpass\":\"$userpass\",\"method\":\"trade\",\"price\":1.234,\"base\":\"REVS\",\"rel\":\"KMD\",\"quote\":{}}"

1
iguana/m_mm

@ -1,2 +1,3 @@
cd secp256k1; ./m_unix; cd ..
cd ../crypto777; ./m_LP; cd ../iguana
gcc -g -o marketmaker -I../crypto777 exchanges/mm.c mini-gmp.c secp256k1.o ../agents/libcrypto777.a -lnanomsg -lcurl -lpthread -lm

3
iguana/m_splitfund

@ -16,7 +16,8 @@ curl --url "http://127.0.0.1:7776" --data "{\"coin\":\"HODL\",\"agent\":\"iguana
curl --url "http://127.0.0.1:7776" --data "{\"coin\":\"SHARK\",\"agent\":\"iguana\",\"method\":\"splitfunds\",\"satoshis\":\"50000\",\"sendflag\":1,\"duplicates\":10}"
curl --url "http://127.0.0.1:7776" --data "{\"coin\":\"BOTS\",\"agent\":\"iguana\",\"method\":\"splitfunds\",\"satoshis\":\"50000\",\"sendflag\":1,\"duplicates\":10}"
curl --url "http://127.0.0.1:7776" --data "{\"coin\":\"MGW\",\"agent\":\"iguana\",\"method\":\"splitfunds\",\"satoshis\":\"50000\",\"sendflag\":1,\"duplicates\":10}"
curl --url "http://127.0.0.1:7776" --data "{\"coin\":\"MVP\",\"agent\":\"iguana\",\"method\":\"splitfunds\",\"satoshis\":\"50000\",\"sendflag\":1,\"duplicates\":10}"
#curl --url "http://127.0.0.1:7776" --data "{\"coin\":\"MVP\",\"agent\":\"iguana\",\"method\":\"splitfunds\",\"satoshis\":\"50000\",\"sendflag\":1,\"duplicates\":10}"
curl --url "http://127.0.0.1:7776" --data "{\"coin\":\"COQUI\",\"agent\":\"iguana\",\"method\":\"splitfunds\",\"satoshis\":\"50000\",\"sendflag\":1,\"duplicates\":10}"
curl --url "http://127.0.0.1:7776" --data "{\"coin\":\"WLC\",\"agent\":\"iguana\",\"method\":\"splitfunds\",\"satoshis\":\"50000\",\"sendflag\":1,\"duplicates\":10}"
curl --url "http://127.0.0.1:7776" --data "{\"coin\":\"KV\",\"agent\":\"iguana\",\"method\":\"splitfunds\",\"satoshis\":\"50000\",\"sendflag\":1,\"duplicates\":10}"
curl --url "http://127.0.0.1:7776" --data "{\"coin\":\"CEAL\",\"agent\":\"iguana\",\"method\":\"splitfunds\",\"satoshis\":\"50000\",\"sendflag\":1,\"duplicates\":10}"

1
iguana/orderbooks.h

@ -3341,6 +3341,7 @@ int32_t prices_idle(int32_t peggyflag,int32_t idlegap)
if ( milliseconds() > lastdayupdate + 60000*60 )
{
lastdayupdate = milliseconds();
printf("call ecb_matrix.(%s)\n",dp->edate);
if ( (datenum= ecb_matrix(dp->ecbmatrix,dp->edate)) > 0 )
{
dp->ecbdatenum = datenum;

Loading…
Cancel
Save