diff --git a/basilisk/basilisk.c b/basilisk/basilisk.c index 89ca07286..823656011 100755 --- a/basilisk/basilisk.c +++ b/basilisk/basilisk.c @@ -484,6 +484,7 @@ int32_t basilisk_relayid(struct supernet_info *myinfo,uint32_t ipbits) #include "basilisk_lisk.c" #include "basilisk_MSG.c" +#include "tradebots_marketmaker.c" #include "tradebots_liquidity.c" #include "basilisk_tradebot.c" #include "basilisk_swap.c" diff --git a/basilisk/basilisk.h b/basilisk/basilisk.h index eeb343919..45bbdd6b2 100755 --- a/basilisk/basilisk.h +++ b/basilisk/basilisk.h @@ -67,7 +67,7 @@ struct basilisk_swapinfo char bobstr[64],alicestr[64]; bits256 myhash,otherhash,orderhash; uint32_t statebits,otherstatebits,started,expiration,finished,dead,reftime,putduration,callduration; - int32_t bobconfirms,aliceconfirms,iambob,reclaimed; + int32_t bobconfirms,aliceconfirms,iambob,reclaimed,bobspent,alicespent; uint64_t alicesatoshis,bobsatoshis,bobinsurance,aliceinsurance; bits256 myprivs[2],mypubs[2],otherpubs[2],pubA0,pubA1,pubB0,pubB1,privAm,pubAm,privBn,pubBn; diff --git a/basilisk/basilisk_swap.c b/basilisk/basilisk_swap.c index 5b15e6420..2b0c72d91 100755 --- a/basilisk/basilisk_swap.c +++ b/basilisk/basilisk_swap.c @@ -570,6 +570,7 @@ int32_t basilisk_verify_bobpaid(struct supernet_info *myinfo,void *ptr,uint8_t * for (i=0; ialicespend.I.datalen; i++) printf("%02x",swap->alicespend.txbytes[i]); printf(" <- alicespend\n\n"); + swap->I.alicespent = 1; basilisk_txlog(myinfo,swap,&swap->alicespend,-1); return(retval); } @@ -587,6 +588,7 @@ int32_t basilisk_alicepayment_spend(struct supernet_info *myinfo,struct basilisk for (i=0; iI.datalen; i++) printf("%02x",dest->txbytes[i]); printf(" <- msigspend\n\n"); + swap->I.bobspent = 1; basilisk_txlog(myinfo,swap,dest,0); // bobspend or alicereclaim return(retval); } @@ -1738,6 +1740,19 @@ int32_t basilisk_swapiteration(struct supernet_info *myinfo,struct basilisk_swap return(retval); } +int32_t swapcompleted(struct supernet_info *myinfo,struct basilisk_swap *swap) +{ + if ( swap->I.iambob != 0 ) + return(swap->I.bobspent); + else return(swap->I.alicespent); +} + +cJSON *swapjson(struct supernet_info *myinfo,struct basilisk_swap *swap) +{ + cJSON *retjson = cJSON_CreateObject(); + return(retjson); +} + void basilisk_swaploop(void *_swap) { uint8_t *data; uint32_t expiration; uint32_t channel; int32_t retval=0,i,j,datalen,maxlen; struct supernet_info *myinfo; struct basilisk_swap *swap = _swap; @@ -1907,6 +1922,12 @@ void basilisk_swaploop(void *_swap) basilisk_swapsend(myinfo,swap,0x40000000,data,datalen,0x40000000,swap->I.crcs_mypriv); } } + if ( swapcompleted(myinfo,swap) > 0 ) // only if swap completed + { + if ( swap->I.iambob != 0 ) + tradebot_pendingadd(myinfo,swapjson(myinfo,swap),swap->I.req.src,dstr(swap->I.req.srcamount),swap->I.req.dest,dstr(swap->I.req.destamount)); + else tradebot_pendingadd(myinfo,swapjson(myinfo,swap),swap->I.req.dest,dstr(swap->I.req.destamount),swap->I.req.src,dstr(swap->I.req.srcamount)); + } printf("%s swap finished statebits %x\n",swap->I.iambob!=0?"BOB":"ALICE",swap->I.statebits); basilisk_swap_purge(myinfo,swap); free(data); diff --git a/basilisk/tradebots_liquidity.c b/basilisk/tradebots_liquidity.c index 1bf50a4b5..8d4ad02da 100755 --- a/basilisk/tradebots_liquidity.c +++ b/basilisk/tradebots_liquidity.c @@ -1056,7 +1056,7 @@ struct liquidity_info *_default_lifind(struct supernet_info *myinfo,int32_t *dir void _default_swap_balancingtrade(struct supernet_info *myinfo,struct basilisk_swap *swap,int32_t iambob) { // update balance, compare to target balance, issue balancing trade via central exchanges, if needed - struct liquidity_info *li; double vol,price,volume,srcamount,destamount,profitmargin,dir=0.,dotrade=1.; char base[64],rel[64]; int32_t idir; + struct liquidity_info *li; double vol,price,volume,srcamount,destamount,profitmargin,dir=0.,dotrade=1.; char base[64],rel[64]; int32_t idir; char *tradestr=0; cJSON *tradejson; srcamount = swap->I.req.srcamount; destamount = swap->I.req.destamount; profitmargin = (double)swap->I.req.profitmargin / 1000000.; @@ -1101,8 +1101,8 @@ void _default_swap_balancingtrade(struct supernet_info *myinfo,struct basilisk_s { printf("BOB: price %f * vol %f -> %s newprice %f margin %.2f%%\n",price,volume,dir < 0. ? "buy" : "sell",price + dir * price * profitmargin,100*profitmargin); if ( dir < 0. ) - InstantDEX_buy(myinfo,0,0,0,"poloniex",base,rel,price,volume,dotrade); - else InstantDEX_sell(myinfo,0,0,0,"poloniex",base,rel,price,volume,dotrade); + tradestr = InstantDEX_buy(myinfo,0,0,0,"poloniex",base,rel,price,volume,dotrade); + else tradestr = InstantDEX_sell(myinfo,0,0,0,"poloniex",base,rel,price,volume,dotrade); } } else @@ -1111,10 +1111,20 @@ void _default_swap_balancingtrade(struct supernet_info *myinfo,struct basilisk_s { printf("ALICE: price %f * vol %f -> %s newprice %f margin %.2f%%\n",price,volume,dir > 0. ? "buy" : "sell",price - dir * price * profitmargin,100*profitmargin); if ( dir > 0. ) - InstantDEX_buy(myinfo,0,0,0,"poloniex",base,rel,price,volume,dotrade); - else InstantDEX_sell(myinfo,0,0,0,"poloniex",base,rel,price,volume,dotrade); + tradestr = InstantDEX_buy(myinfo,0,0,0,"poloniex",base,rel,price,volume,dotrade); + else tradestr = InstantDEX_sell(myinfo,0,0,0,"poloniex",base,rel,price,volume,dotrade); } } + if ( tradestr != 0 ) + { + if ( (tradejson= cJSON_Parse(tradestr)) != 0 ) + { + if ( jobj(tradejson,"error") == 0 ) // balancing is opposite trade + tradebot_pendingadd(myinfo,tradejson,swap->I.req.dest,destamount,swap->I.req.src,srcamount); + else free_json(tradejson); + } + free(tradestr); + } } void tradebot_swap_balancingtrade(struct supernet_info *myinfo,struct basilisk_swap *swap,int32_t iambob) diff --git a/basilisk/tradebots_marketmaker.c b/basilisk/tradebots_marketmaker.c new file mode 100755 index 000000000..e5b81e81e --- /dev/null +++ b/basilisk/tradebots_marketmaker.c @@ -0,0 +1,211 @@ +/****************************************************************************** + * Copyright © 2014-2017 The SuperNET Developers. * + * * + * See the AUTHORS, DEVELOPER-AGREEMENT and LICENSE files at * + * the top-level directory of this distribution for the individual copyright * + * holder information and the developer policies on copyright and licensing. * + * * + * Unless otherwise agreed in a custom licensing agreement, no part of the * + * SuperNET software, including this file may be copied, modified, propagated * + * or distributed except according to the terms contained in the LICENSE file * + * * + * Removal or modification of this copyright notice is prohibited. * + * * + ******************************************************************************/ + +// included from basilisk.c + +// "currency":{"value":%.8f, "pending":%.8f} + +cJSON *tradebot_balancediff(cJSON *item,cJSON *anchoritem) // only item might be null +{ + double current[2],past[2]; int32_t i; cJSON *diffitem = jduplicate(anchoritem); + memset(current,0,sizeof(current)); + memset(past,0,sizeof(past)); + if ( jobj(diffitem,"value") != 0 ) + jdelete(diffitem,"value"); + if ( jobj(diffitem,"pending") != 0 ) + jdelete(diffitem,"pending"); + for (i=0; i<2; i++) + { + if ( current[i] != 0. || past[i] != 0. ) + jaddnum(diffitem,i == 0 ? "value" : "pending",current[i] - past[i]); + } + return(diffitem); +} + +cJSON *tradebot_balancesdiff(struct supernet_info *myinfo,cJSON *current,cJSON *anchor) +{ + cJSON *item,*anchoritem,*diffitem,*array; int32_t i,n; char *field; + if ( anchor == 0 ) + return(jduplicate(current)); + array = cJSON_CreateObject(); + n = cJSON_GetArraySize(current); + for (i=0; inumexchanges; i++) + { + value += 0;//InstantDEX_balance(myinfo,0,0,0,exchange,base); + } + return(value); +} + +void tradebot_pendingadd(struct supernet_info *myinfo,cJSON *tradejson,char *base,double basevolume,char *rel,double relvolume) +{ + portable_mutex_lock(&myinfo->pending_mutex); + // add to myinfo->trades + portable_mutex_unlock(&myinfo->pending_mutex); +} + +void tradebot_pendingremove(struct supernet_info *myinfo,char *base,double basevolume,char *rel,double relvolume) +{ + portable_mutex_lock(&myinfo->pending_mutex); + // remove from myinfo->trades + portable_mutex_unlock(&myinfo->pending_mutex); +} + +double tradebot_pending(struct supernet_info *myinfo,char *base) +{ + double pending = 0.; struct pending_trade *tp,*tmp; + portable_mutex_lock(&myinfo->pending_mutex); + HASH_ITER(hh,myinfo->trades,tp,tmp) + { + if ( strcmp(base,tp->base) == 0 ) + pending += tp->dir * tp->basevolume; + else if ( strcmp(base,tp->rel) == 0 ) + pending -= tp->dir * tp->relvolume; + } + portable_mutex_unlock(&myinfo->pending_mutex); + return(pending); +} + +#include "../includes/iguana_apidefs.h" +#include "../includes/iguana_apideclares.h" + +ZERO_ARGS(tradebot,allbalances) +{ + int32_t i,n; double value,pending; char *base; cJSON *item,*balances = cJSON_CreateObject(); + if ( myinfo->liquidity_currencies == 0 ) + myinfo->liquidity_currencies = cJSON_Parse("[\"KMD\", \"BTC\"]"); + if ( myinfo->liquidity_currencies != 0 && (n= cJSON_GetArraySize(myinfo->liquidity_currencies)) > 0 ) + { + for (i=0; iliquidity_currencies,i); + value = tradebot_balance(myinfo,base); + pending = tradebot_pending(myinfo,base); + item = cJSON_CreateObject(); + jaddnum(item,"value",value); + jaddnum(item,"pending",pending); + jadd(balances,base,item); + } + } + return(jprint(balances,1)); +} + +ZERO_ARGS(tradebot,anchor) +{ + FILE *fp; char *anchorstr,fname[512]; cJSON *anchor; int32_t retval = -1; + if ( (anchorstr= tradebot_allbalances(myinfo,0,0,0)) != 0 ) + { + if ( (anchor= cJSON_Parse(anchorstr)) != 0 ) + { + if ( jobj(anchor,"error") == 0 ) + { + sprintf(fname,"%s/anchor",GLOBAL_DBDIR), OS_compatible_path(fname); + if ( (fp= fopen(fname,"wb")) != 0 ) + { + if ( fwrite(anchorstr,1,strlen(anchorstr)+1,fp) == strlen(anchorstr)+1 ) + retval = 0; + fclose(fp); + } + } + } + free(anchorstr); + } + if ( retval == 0 ) + return(clonestr("{\"result\":\"success\"}")); + else return(clonestr("{\"error\":\"couldnt make anchor file\"}")); +} + +ZERO_ARGS(tradebot,portfolio) +{ + char *currentstr,*anchorstr,fname[512]; long fsize; cJSON *current,*anchor=0,*portfolio=0; + if ( (currentstr= tradebot_allbalances(myinfo,0,0,0)) != 0 ) + { + if ( (current= cJSON_Parse(currentstr)) != 0 ) + { + sprintf(fname,"%s/anchor",GLOBAL_DBDIR), OS_compatible_path(fname); + if ( (anchorstr= OS_filestr(&fsize,fname)) != 0 ) + { + anchor = cJSON_Parse(anchorstr); + free(anchorstr); + } + if ( anchor == 0 ) + anchor = cJSON_Parse("{}"); + portfolio = tradebot_balancesdiff(myinfo,current,anchor); + free_json(current); + } + free(currentstr); + } + if ( portfolio == 0 ) + return(clonestr("{\"result\":\"success\"}")); + else return(jprint(portfolio,1)); +} + +/*li.profit = jdouble(vals,"profit"); +li.refprice = jdouble(vals,"refprice"); +li.bid = jdouble(vals,"bid"); +li.ask = jdouble(vals,"ask"); +if ( (li.minvol= jdouble(vals,"minvol")) <= 0. ) +li.minvol = (strcmp("BTC",base) == 0) ? 0.0001 : 0.001; +if ( (li.maxvol= jdouble(vals,"maxvol")) < li.minvol ) +li.maxvol = li.minvol;*/ + +ARRAY_OBJ_INT(tradebot,goals,currencies,vals,targettime) +{ + static bits256 zero; char *targetcoin; int32_t i,n; + if ( currencies != 0 && vals != 0 ) + { + // init things so automatically updates refli.bid and refli.ask + // volume range with margin + // currency percentage value in BTC? target distribution, max percentage, min percentage` + // min price to sell, max price to buy, max volume + n = cJSON_GetArraySize(currencies); + for (i=0; i= 60 ) + { + denominator = (((uint64_t)365 * 24 * 60) / minutes); + if ( denominator == 0 ) + denominator = 1; // max KOMODO_INTEREST per transfer, do it at least annually! + if ( value > 25000LL*SATOSHIDEN && chainheight > 155949 ) + { + numerator = (value / 20); // assumes 5%! + interest = (numerator / denominator); + } + else if ( value >= 10*SATOSHIDEN ) + { + numerator = (value * KOMODO_INTEREST); + interest = (numerator / denominator) / SATOSHIDEN; + } + fprintf(stderr,"komodo_interest.%d %lld %.8f nLockTime.%u tiptime.%u minutes.%d interest %lld %.8f (%llu / %llu)\n",chainheight,(long long)value,(double)value/SATOSHIDEN,txlocktime,now,minutes,(long long)interest,(double)interest/SATOSHIDEN,(long long)numerator,(long long)denominator); + } + return(interest); +} + +uint64_t iguana_interest(struct supernet_info *myinfo,struct iguana_info *coin,bits256 txid,int32_t vout,uint64_t value) +{ + char *retstr; int32_t height; cJSON *retjson; struct iguana_txid T,*tx; uint64_t interest=0; if ( coin->FULLNODE < 0 ) // komodod is running { if ( (retjson= dpow_gettxout(myinfo,coin,txid,vout)) != 0 ) @@ -367,25 +389,9 @@ uint64_t iguana_interest(struct supernet_info *myinfo,struct iguana_info *coin,b } else // we have it local { - if ( (tx= iguana_txidfind(coin,&height,&T,txid,coin->bundlescount)) != 0 && tx->locktime >LOCKTIME_THRESHOLD ) + if ( (tx= iguana_txidfind(coin,&height,&T,txid,coin->bundlescount)) != 0 && tx->locktime > LOCKTIME_THRESHOLD ) { - if ( (minutes= ((uint32_t)time(NULL) - 60 - tx->locktime) / 60) >= 60 ) - { - denominator = (((uint64_t)365 * 24 * 60) / minutes); - if ( denominator == 0 ) - denominator = 1; // max KOMODO_INTEREST per transfer, do it at least annually! - if ( value > 25000LL*SATOSHIDEN && height > 155949 ) - { - numerator = (value / 20); // assumes 5%! - interest = (numerator / denominator); - } - else if ( value >= 10*SATOSHIDEN ) - { - numerator = (value * KOMODO_INTEREST); - interest = (numerator / denominator) / SATOSHIDEN; - } - fprintf(stderr,"komodo_interest %lld %.8f nLockTime.%u tiptime.%u minutes.%d interest %lld %.8f (%llu / %llu)\n",(long long)value,(double)value/SATOSHIDEN,tx->locktime,(uint32_t)time(NULL),minutes,(long long)interest,(double)interest/SATOSHIDEN,(long long)numerator,(long long)denominator); - } + interest = _iguana_interest((uint32_t)time(NULL),coin->longestchain,tx->locktime,value); } } char str[65]; printf("interest for %s.v%d %.8f %.8f\n",bits256_str(str,txid),vout,dstr(value),dstr(interest)); diff --git a/iguana/kmd_lookup.h b/iguana/kmd_lookup.h index 78c9a3618..478db9fb9 100755 --- a/iguana/kmd_lookup.h +++ b/iguana/kmd_lookup.h @@ -304,7 +304,7 @@ cJSON *kmd_transactionjson(int32_t height,struct kmd_transactionhh *ptr,char *ty return(obj); } -cJSON *kmd_unspentjson(int32_t height,struct kmd_transaction *tx,int32_t vout) +cJSON *kmd_unspentjson(struct iguana_info *coin,int32_t height,struct kmd_transaction *tx,int32_t vout) { cJSON *item = cJSON_CreateObject(); jaddstr(item,"type","received"); @@ -313,6 +313,8 @@ cJSON *kmd_unspentjson(int32_t height,struct kmd_transaction *tx,int32_t vout) jaddbits256(item,"txid",tx->txid); jaddnum(item,"vout",vout); jaddnum(item,"amount",dstr(tx->vouts[vout].amount)); + if ( strcmp(coin->symbol,"KMD") == 0 ) + jaddnum(item,"interest",dstr(_iguana_interest((uint32_t)time(NULL),coin->longestchain,tx->timestamp,tx->vouts[vout].amount))); return(item); } @@ -376,9 +378,9 @@ cJSON *kmd_gettxin(struct iguana_info *coin,bits256 txid,int32_t vout) return(cJSON_Parse("{\"error\":\"txid not found\"}")); } -cJSON *kmd_listaddress(struct iguana_info *coin,char *coinaddr,int32_t mode,cJSON *array,int32_t fulltx) +cJSON *kmd_listaddress(struct iguana_info *coin,char *coinaddr,int32_t mode,cJSON *array) { - struct kmd_addresshh *addr; struct kmd_transactionhh *ptr,*spent,*prev=0; uint8_t type_rmd160[21]; int32_t i,flag = 0; + struct kmd_addresshh *addr; struct kmd_transactionhh *ptr,*spent,*prev=0; uint8_t type_rmd160[21]; int32_t i; if ( array == 0 ) array = cJSON_CreateArray(); /*if ( time(NULL) > coin->kmd_lasttime+30 ) @@ -407,20 +409,20 @@ cJSON *kmd_listaddress(struct iguana_info *coin,char *coinaddr,int32_t mode,cJSO // printf("mode.%d [%d] %s ht.%d amount %.8f spent.%p\n",mode,coin->kmd_height,coinaddr,ptr->tx->height,dstr(ptr->tx->vouts[i].amount),spent); if ( (mode == 0 && spent == 0) || (mode == 1 && spent != 0) || mode == 2 ) { - if ( fulltx == 0 ) + //if ( fulltx == 0 ) { if ( mode == 0 ) - jaddi(array,kmd_unspentjson(coin->kmd_height,ptr->tx,i)); + jaddi(array,kmd_unspentjson(coin,coin->kmd_height,ptr->tx,i)); else if ( mode == 1 ) jaddi(array,kmd_spentjson(coin->kmd_height,ptr->tx,i,spent)); else if ( mode == 2 ) { if ( spent != 0 ) jaddi(array,kmd_spentjson(coin->kmd_height,ptr->tx,i,spent)); - else jaddi(array,kmd_unspentjson(coin->kmd_height,ptr->tx,i)); + else jaddi(array,kmd_unspentjson(coin,coin->kmd_height,ptr->tx,i)); } } - else if ( flag == 0 ) + /*else if ( flag == 0 ) { if ( mode == 0 ) jaddi(array,kmd_transactionjson(coin->kmd_height,ptr,"received")); @@ -436,7 +438,7 @@ cJSON *kmd_listaddress(struct iguana_info *coin,char *coinaddr,int32_t mode,cJSO else jaddi(array,kmd_transactionjson(coin->kmd_height,ptr,"received")); } flag = 1; - } + }*/ } if ( ptr->ptrs[i<<1] != 0 ) { @@ -455,12 +457,12 @@ cJSON *kmd_listaddress(struct iguana_info *coin,char *coinaddr,int32_t mode,cJSO cJSON *kmd_listunspent(struct iguana_info *coin,char *coinaddr) { - return(kmd_listaddress(coin,coinaddr,0,0,0)); + return(kmd_listaddress(coin,coinaddr,0,0)); } cJSON *kmd_listspent(struct iguana_info *coin,char *coinaddr) { - return(kmd_listaddress(coin,coinaddr,1,0,0)); + return(kmd_listaddress(coin,coinaddr,1,0)); } cJSON *kmd_listtransactions(struct iguana_info *coin,char *coinaddr,int32_t count,int32_t skip) @@ -470,17 +472,17 @@ cJSON *kmd_listtransactions(struct iguana_info *coin,char *coinaddr,int32_t coun // return(cJSON_Parse("[]")); if ( count == 0 ) count = 100; - array = kmd_listaddress(coin,coinaddr,0,0,0); - array = kmd_listaddress(coin,coinaddr,1,array,0); + array = kmd_listaddress(coin,coinaddr,0,0); + array = kmd_listaddress(coin,coinaddr,1,array); return(array); } -int64_t _kmd_getbalance(struct iguana_info *coin,char *coinaddr,uint64_t *receivedp,uint64_t *sentp) +int64_t _kmd_getbalance(struct iguana_info *coin,char *coinaddr,uint64_t *receivedp,uint64_t *sentp,uint64_t *interestp) { int32_t iter,i,n; cJSON *array,*item; uint64_t value; for (iter=1; iter<=2; iter++) { - if ( (array= kmd_listaddress(coin,coinaddr,iter,0,0)) != 0 ) + if ( (array= kmd_listaddress(coin,coinaddr,iter,0)) != 0 ) { if ( (n= cJSON_GetArraySize(array)) > 0 ) { @@ -490,8 +492,10 @@ int64_t _kmd_getbalance(struct iguana_info *coin,char *coinaddr,uint64_t *receiv if ( (value= jdouble(item,"amount")*SATOSHIDEN) != 0 || (value= jdouble(item,"value")*SATOSHIDEN) != 0 ) { if ( iter == 2 ) + { *receivedp += value; - else *sentp += value; + *interestp += jdouble(item,"interest") * SATOSHIDEN; + } else *sentp += value; } } } @@ -503,29 +507,31 @@ int64_t _kmd_getbalance(struct iguana_info *coin,char *coinaddr,uint64_t *receiv cJSON *kmd_getbalance(struct iguana_info *coin,char *coinaddr) { - cJSON *retjson; double netbalance=0.,fbalance; uint64_t s,r,sent=0,received=0; int64_t balance=0; struct kmd_addresshh *addr,*tmp; char address[64]; int32_t height = coin->kmd_height+1; + cJSON *retjson; double netbalance=0.,fbalance; uint64_t interest,i,s,r,sent=0,received=0; int64_t balance=0; struct kmd_addresshh *addr,*tmp; char address[64]; int32_t height = coin->kmd_height+1; retjson = cJSON_CreateObject(); fbalance = 0.; + interest = 0; if ( strcmp(coinaddr,"*") == 0 ) { HASH_ITER(hh,coin->kmd_addresses,addr,tmp) { bitcoin_address(address,addr->type_rmd160[0],&addr->type_rmd160[1],20); - s = r = 0; - balance += _kmd_getbalance(coin,address,&r,&s); + s = r = i = 0; + balance += _kmd_getbalance(coin,address,&r,&s,&i); netbalance += dstr(r); netbalance -= dstr(s); if ( (r - s) > 100000*SATOSHIDEN ) - printf("{\"address\":\"%s\",\"received\":%.8f,\"sent\":%.8f,\"balance\":%.8f,\"supply\":%.8f,\"supplyf\":%.8f}\n",address,dstr(r),dstr(s),dstr(r)-dstr(s),dstr(balance),netbalance); + printf("{\"address\":\"%s\",\"received\":%.8f,\"sent\":%.8f,\"balance\":%.8f,\"supply\":%.8f,\"supplyf\":%.8f,\"interest\":%.8f}\n",address,dstr(r),dstr(s),dstr(r)-dstr(s),dstr(balance),netbalance,dstr(interest)); received += r; sent += s; + interest += i; } if ( strcmp("KMD",coin->symbol) == 0 ) jaddnum(retjson,"interestpaid",dstr(balance) - 100000000 - (height*3)); } else { - balance = _kmd_getbalance(coin,coinaddr,&received,&sent); + balance = _kmd_getbalance(coin,coinaddr,&received,&sent,&interest); netbalance = dstr(balance); } jaddstr(retjson,"result","success"); @@ -534,7 +540,8 @@ cJSON *kmd_getbalance(struct iguana_info *coin,char *coinaddr) //if ( fabs(netbalance*SATOSHIDEN - balance) > 1 ) jaddnum(retjson,"balancef",netbalance+1./(SATOSHIDEN*2)-SMALLVAL); //else - jaddnum(retjson,"balance",dstr(balance)); + jaddnum(retjson,"balance",dstr(balance)); + jaddnum(retjson,"interest",dstr(interest)); jaddnum(retjson,"height",height); if ( strcmp("KMD",coin->symbol) == 0 ) jaddnum(retjson,"mined",height*3); @@ -550,7 +557,7 @@ char *kmd_bitcoinblockhashstr(char *coinstr,char *serverport,char *userpass,int3 hash2 = bits256_conv(blockhashstr); if ( blockhashstr == 0 || blockhashstr[0] == 0 || bits256_nonz(hash2) == 0 ) { - printf("couldnt get blockhash for %u, probably curl is disabled\n",height); + printf("%s couldnt get blockhash for %u, probably curl is disabled %p\n",coinstr,height,blockhashstr); if ( blockhashstr != 0 ) free(blockhashstr); if ( height == 0 ) diff --git a/iguana/main.c b/iguana/main.c index c451568cc..1b579f973 100755 --- a/iguana/main.c +++ b/iguana/main.c @@ -1725,6 +1725,7 @@ void iguana_main(void *arg) } strcpy(myinfo->rpcsymbol,"BTCD"); iguana_urlinit(myinfo,ismainnet,usessl); + portable_mutex_init(&myinfo->pending_mutex); portable_mutex_init(&myinfo->dpowmutex); portable_mutex_init(&myinfo->notarymutex); #if LIQUIDITY_PROVIDER diff --git a/iguana/tests/dexlistunspent2 b/iguana/tests/dexlistunspent2 index 721db4bf8..0a4c41ad8 100755 --- a/iguana/tests/dexlistunspent2 +++ b/iguana/tests/dexlistunspent2 @@ -1,2 +1,2 @@ #!/bin/bash -curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"listunspent2\",\"address\":\"RW3gz9fEadohRLZerK9r8zXkugk5swWHrf\",\"symbol\":\"KMD\"}" +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"listunspent2\",\"address\":\"R9eW4hVmhGYCExBSJ15vX61fEoENgDvHhj\",\"symbol\":\"KMD\"}" diff --git a/includes/iguana_apideclares.h b/includes/iguana_apideclares.h index a22544875..24951acf2 100755 --- a/includes/iguana_apideclares.h +++ b/includes/iguana_apideclares.h @@ -21,9 +21,12 @@ ZERO_ARGS(dpow,cancelratify); STRING_ARG(dpow,bindaddr,ipaddr); STRING_AND_INT(dpow,fundnotaries,symbol,numblocks); +ZERO_ARGS(pax,start); INT_ARG(passthru,paxfiats,mask); - - +TWO_STRINGS(zcash,passthru,function,hex); +TWO_STRINGS(komodo,passthru,function,hex); +TWO_STRINGS(dex,kvsearch,symbol,key); +THREE_STRINGS_AND_THREE_INTS(dex,kvupdate,symbol,key,value,flags,unused,unusedb); TWO_STRINGS(dex,send,hex,handler); HASH_AND_STRING(dex,gettransaction,txid,symbol); @@ -40,8 +43,6 @@ TWO_STRINGS(dex,validateaddress,symbol,address); TWO_STRINGS(dex,checkaddress,symbol,address); TWO_STRINGS(dex,listunspent,symbol,address); TWO_STRINGS_AND_TWO_DOUBLES(dex,listtransactions,symbol,address,count,skip); -TWO_STRINGS(dex,kvsearch,symbol,key); -THREE_STRINGS_AND_THREE_INTS(dex,kvupdate,symbol,key,value,flags,unused,unusedb); TWO_STRINGS(dex,listunspent2,symbol,address); TWO_STRINGS_AND_TWO_DOUBLES(dex,listtransactions2,symbol,address,count,skip); HASH_AND_STRING_AND_INT(dex,gettxin,txid,symbol,vout); @@ -49,27 +50,6 @@ TWO_STRINGS(dex,listspent,symbol,address); TWO_STRINGS(dex,getbalance,symbol,address); STRING_ARG(dex,explorer,symbol); -TWO_STRINGS(zcash,passthru,function,hex); -TWO_STRINGS(komodo,passthru,function,hex); - -ZERO_ARGS(pax,start); -HASH_ARRAY_STRING(tradebot,liquidity,hash,vals,targetcoin); -ZERO_ARGS(tradebot,amlp); -ZERO_ARGS(tradebot,notlp); -TWO_STRINGS(tradebot,gensvm,base,rel); -ZERO_ARGS(tradebot,openliquidity); - - -ZERO_ARGS(InstantDEX,allcoins); -STRING_ARG(InstantDEX,available,source); -HASH_ARRAY_STRING(InstantDEX,request,hash,vals,hexstr); - -INT_ARG(InstantDEX,incoming,requestid); -INT_ARG(InstantDEX,automatched,requestid); - -TWO_INTS(InstantDEX,accept,requestid,quoteid); -//TWO_INTS(InstantDEX,swapstatus,requestid,quoteid); - HASH_ARRAY_STRING(basilisk,genesis_opreturn,hash,vals,hexstr); HASH_ARRAY_STRING(basilisk,history,hash,vals,hexstr); INT_ARG(basilisk,paxfiats,mask); @@ -174,7 +154,6 @@ ZERO_ARGS(bitcoinrpc,gettxoutsetinfo); ZERO_ARGS(bitcoinrpc,getrawchangeaddress); SS_D_I_S(bitcoinrpc,move,fromaccount,toaccount,amount,minconf,comment); - THREE_INTS(iguana,splitfunds,satoshis,duplicates,sendflag); ZERO_ARGS(iguana,makekeypair); INT_AND_ARRAY(iguana,rates,unused,quotes); @@ -207,6 +186,13 @@ STRING_AND_INT(iguana,bundlehashes,activecoin,height); STRING_AND_INT(iguana,PoSweights,activecoin,height); STRING_ARG(iguana,stakers,activecoin); +ZERO_ARGS(InstantDEX,allcoins); +STRING_ARG(InstantDEX,available,source); +HASH_ARRAY_STRING(InstantDEX,request,hash,vals,hexstr); +INT_ARG(InstantDEX,incoming,requestid); +INT_ARG(InstantDEX,automatched,requestid); +TWO_INTS(InstantDEX,accept,requestid,quoteid); +//TWO_INTS(InstantDEX,swapstatus,requestid,quoteid); //TWO_STRINGS_AND_TWO_DOUBLES(InstantDEX,minaccept,base,rel,minprice,basevolume); //TWO_STRINGS_AND_TWO_DOUBLES(InstantDEX,maxaccept,base,rel,maxprice,basevolume); THREE_STRINGS_AND_THREE_DOUBLES(InstantDEX,buy,exchange,base,rel,price,volume,dotrade); @@ -219,7 +205,6 @@ TWO_STRINGS(InstantDEX,orderstatus,exchange,orderid); TWO_STRINGS(InstantDEX,cancelorder,exchange,orderid); STRING_ARG(InstantDEX,openorders,exchange); STRING_ARG(InstantDEX,tradehistory,exchange); - THREE_STRINGS_AND_THREE_INTS(InstantDEX,orderbook,exchange,base,rel,depth,allfields,ignore); STRING_AND_INT(InstantDEX,pollgap,exchange,pollgap); //TWO_STRINGS(InstantDEX,events,base,rel); @@ -234,6 +219,11 @@ THREE_STRINGS(InstantDEX,supports,exchange,base,rel); //TWOSTRINGS_AND_TWOHASHES_AND_TWOINTS(InstantDEX,accept,reference,message,basetxid,reltxid,duration,flags); //TWOSTRINGS_AND_TWOHASHES_AND_TWOINTS(InstantDEX,confirm,reference,message,basetxid,reltxid,baseheight,relheight); +HASH_ARRAY_STRING(tradebot,liquidity,hash,vals,targetcoin); +ZERO_ARGS(tradebot,amlp); +ZERO_ARGS(tradebot,notlp); +TWO_STRINGS(tradebot,gensvm,base,rel); +ZERO_ARGS(tradebot,openliquidity); THREE_STRINGS_AND_DOUBLE(tradebot,aveprice,comment,base,rel,basevolume); THREE_STRINGS_AND_DOUBLE(tradebot,monitor,exchange,base,rel,commission); STRING_AND_DOUBLE(tradebot,monitorall,exchange,commission); @@ -245,6 +235,10 @@ TWO_STRINGS(tradebot,status,exchange,botid); TWO_STRINGS(tradebot,pause,exchange,botid); TWO_STRINGS(tradebot,stop,exchange,botid); TWO_STRINGS(tradebot,resume,exchange,botid); +ZERO_ARGS(tradebot,allbalances); +ZERO_ARGS(tradebot,anchor); +ZERO_ARGS(tradebot,portfolio); +ARRAY_OBJ_INT(tradebot,goals,currencies,vals,targettime); #ifndef WIN32 /*HASH_ARG(pangea,call,tablehash); diff --git a/includes/iguana_funcs.h b/includes/iguana_funcs.h index b92103be1..8e048b21f 100755 --- a/includes/iguana_funcs.h +++ b/includes/iguana_funcs.h @@ -641,6 +641,7 @@ void iguana_fixsecp(struct supernet_info *myinfo); int32_t bitcoin_timelockspend(uint8_t *script,int32_t n,uint8_t rmd160[20],uint32_t timestamp); char *iguana_calcutxorawtx(struct supernet_info *myinfo,struct iguana_info *coin,cJSON **vinsp,cJSON *txobj,int64_t satoshis,char *changeaddr,int64_t txfee,cJSON *utxos,char *remoteaddr,struct vin_info *V,int32_t maxmode); +uint64_t _iguana_interest(uint32_t now,int32_t height,uint32_t txlocktime,uint64_t value); #include "../includes/iguana_api.h"