diff --git a/iguana/SuperNET.h b/iguana/SuperNET.h index eb37d7f2f..53349142b 100644 --- a/iguana/SuperNET.h +++ b/iguana/SuperNET.h @@ -109,7 +109,7 @@ struct category_chain struct category_info { UT_hash_handle hh; queue_t Q; - int32_t (*process_func)(struct supernet_info *myinfo,void *data,int32_t datalen,char *remoteaddr); + char *(*processfunc)(struct supernet_info *myinfo,void *data,int32_t datalen,char *remoteaddr); struct category_chain *cchain; bits256 hash; void *info; struct category_info *sub; }; @@ -139,8 +139,8 @@ void *category_info(bits256 categoryhash,bits256 subhash); void *category_infoset(bits256 categoryhash,bits256 subhash,void *info); struct category_info *category_find(bits256 categoryhash,bits256 subhash); void SuperNET_hexmsgprocess(struct supernet_info *myinfo,cJSON *json,char *hexmsg,char *remoteaddr); -struct category_info *category_processfunc(bits256 categoryhash,int32_t (*process_func)(struct supernet_info *myinfo,void *data,int32_t datalen,char *remoteaddr)); -int32_t pangea_hexmsg(struct supernet_info *myinfo,void *data,int32_t len,char *remoteaddr); +struct category_info *category_processfunc(bits256 categoryhash,char *(*process_func)(struct supernet_info *myinfo,void *data,int32_t datalen,char *remoteaddr)); +char *pangea_hexmsg(struct supernet_info *myinfo,void *data,int32_t len,char *remoteaddr); void pangea_queues(struct supernet_info *myinfo); int32_t SuperNET_str2hex(uint8_t *hex,char *str); diff --git a/iguana/SuperNET_category.c b/iguana/SuperNET_category.c index 8fca7663f..18289bc7e 100644 --- a/iguana/SuperNET_category.c +++ b/iguana/SuperNET_category.c @@ -74,12 +74,12 @@ void *category_infoset(bits256 categoryhash,bits256 subhash,void *info) return(0); } -struct category_info *category_processfunc(bits256 categoryhash,int32_t (*process_func)(struct supernet_info *myinfo,void *data,int32_t datalen,char *remoteaddr)) +struct category_info *category_processfunc(bits256 categoryhash,char *(*process_func)(struct supernet_info *myinfo,void *data,int32_t datalen,char *remoteaddr)) { struct category_info *cat; if ( (cat= category_find(categoryhash,GENESIS_PUBKEY)) != 0 ) { - cat->process_func = process_func; + cat->processfunc = process_func; return(cat); } return(0); diff --git a/iguana/SuperNET_hexmsg.c b/iguana/SuperNET_hexmsg.c index 1b3601eee..2ce8c3fd6 100644 --- a/iguana/SuperNET_hexmsg.c +++ b/iguana/SuperNET_hexmsg.c @@ -75,7 +75,7 @@ void SuperNET_hexmsgadd(struct supernet_info *myinfo,bits256 categoryhash,bits25 void SuperNET_hexmsgprocess(struct supernet_info *myinfo,cJSON *json,char *hexmsg,char *remoteaddr) { - int32_t len,flag=0; uint8_t _buf[8192],*buf = _buf; bits256 categoryhash; struct category_info *cat; + int32_t len,flag=0; char *str; uint8_t _buf[8192],*buf = _buf; bits256 categoryhash; struct category_info *cat; if ( hexmsg != 0 ) { len = (int32_t)strlen(hexmsg); @@ -88,9 +88,10 @@ void SuperNET_hexmsgprocess(struct supernet_info *myinfo,cJSON *json,char *hexms categoryhash = jbits256(json,"categoryhash"); if ( (cat= category_find(categoryhash,GENESIS_PUBKEY)) != 0 ) { - if ( cat->process_func != 0 ) + if ( cat->processfunc != 0 ) { - (*cat->process_func)(myinfo,buf,len,remoteaddr); + if ( (str= (*cat->processfunc)(myinfo,buf,len,remoteaddr)) != 0 ) + free(str); flag = 1; //printf("PROCESSFUNC\n"); } diff --git a/iguana/exchanges/bitfinex.c b/iguana/exchanges/bitfinex.c index 2d39df913..49cd25daf 100755 --- a/iguana/exchanges/bitfinex.c +++ b/iguana/exchanges/bitfinex.c @@ -27,11 +27,11 @@ #define WITHDRAW bitfinex ## _withdraw #define CHECKBALANCE bitfinex ## _checkbalance -double UPDATE(struct exchange_info *exchange,char *base,char *rel,struct exchange_quote *quotes,int32_t maxdepth,cJSON *argjson) +double UPDATE(struct exchange_info *exchange,char *base,char *rel,struct exchange_quote *quotes,int32_t maxdepth,double commission,cJSON *argjson) { char url[1024]; sprintf(url,"https://api.bitfinex.com/v1/book/%s%s",base,rel); - return(exchanges777_standardprices(exchange,base,rel,url,quotes,"price","amount",maxdepth,0)); + return(exchanges777_standardprices(exchange,commission,base,rel,url,quotes,"price","amount",maxdepth,0)); } int32_t SUPPORTS(struct exchange_info *exchange,char *base,char *rel,cJSON *argjson) diff --git a/iguana/exchanges/bitstamp.c b/iguana/exchanges/bitstamp.c index 7317f501d..864e5c737 100755 --- a/iguana/exchanges/bitstamp.c +++ b/iguana/exchanges/bitstamp.c @@ -28,11 +28,11 @@ #define EXCHANGE_AUTHURL "https://www.bitstamp.net/api" #define CHECKBALANCE bitstamp ## _checkbalance -double UPDATE(struct exchange_info *exchange,char *base,char *rel,struct exchange_quote *quotes,int32_t maxdepth,cJSON *argjson) +double UPDATE(struct exchange_info *exchange,char *base,char *rel,struct exchange_quote *quotes,int32_t maxdepth,double commission,cJSON *argjson) { char url[1024]; sprintf(url,"https://www.bitstamp.net/api/order_book/"); - return(exchanges777_standardprices(exchange,base,rel,url,quotes,0,0,maxdepth,0)); + return(exchanges777_standardprices(exchange,commission,base,rel,url,quotes,0,0,maxdepth,0)); } int32_t SUPPORTS(struct exchange_info *exchange,char *base,char *rel,cJSON *argjson) diff --git a/iguana/exchanges/bittrex.c b/iguana/exchanges/bittrex.c index a7cf592d2..adfcc2136 100755 --- a/iguana/exchanges/bittrex.c +++ b/iguana/exchanges/bittrex.c @@ -27,7 +27,7 @@ #define WITHDRAW bittrex ## _withdraw #define CHECKBALANCE bittrex ## _checkbalance -double UPDATE(struct exchange_info *exchange,char *base,char *rel,struct exchange_quote *quotes,int32_t maxdepth,cJSON *argjson) +double UPDATE(struct exchange_info *exchange,char *base,char *rel,struct exchange_quote *quotes,int32_t maxdepth,double commission,cJSON *argjson) { cJSON *json,*obj; char *jsonstr,market[128],url[1024]; double hbla = 0.; sprintf(market,"%s-%s",rel,base); @@ -38,7 +38,7 @@ double UPDATE(struct exchange_info *exchange,char *base,char *rel,struct exchang if ( (json = cJSON_Parse(jsonstr)) != 0 ) { if ( (obj= cJSON_GetObjectItem(json,"success")) != 0 && is_cJSON_True(obj) != 0 ) - hbla = exchanges777_json_orderbook(exchange,base,rel,quotes,maxdepth,json,"result","buy","sell","Rate","Quantity"); + hbla = exchanges777_json_orderbook(exchange,commission,base,rel,quotes,maxdepth,json,"result","buy","sell","Rate","Quantity"); free_json(json); } free(jsonstr); diff --git a/iguana/exchanges/btc38.c b/iguana/exchanges/btc38.c index d2d82082e..4dd3c42f2 100755 --- a/iguana/exchanges/btc38.c +++ b/iguana/exchanges/btc38.c @@ -28,7 +28,7 @@ #define EXCHANGE_AUTHURL "http://www.btc38.com/trade/t_api" #define CHECKBALANCE btc38 ## _checkbalance -double UPDATE(struct exchange_info *exchange,char *base,char *rel,struct exchange_quote *quotes,int32_t maxdepth,cJSON *argjson) +double UPDATE(struct exchange_info *exchange,char *base,char *rel,struct exchange_quote *quotes,int32_t maxdepth,double commission,cJSON *argjson) { char url[1024],lrel[16],lbase[16]; strcpy(lrel,rel), strcpy(lbase,base); @@ -36,7 +36,7 @@ double UPDATE(struct exchange_info *exchange,char *base,char *rel,struct exchang if ( strcmp(lbase,"cny") == 0 && strcmp(lrel,"btc") == 0 ) sprintf(url,"http://api.btc38.com/v1/depth.php?c=%s&mk_type=%s","btc","cny"); else sprintf(url,"http://api.btc38.com/v1/depth.php?c=%s&mk_type=%s",lbase,lrel); - return(exchanges777_standardprices(exchange,base,rel,url,quotes,0,0,maxdepth,0)); + return(exchanges777_standardprices(exchange,commission,base,rel,url,quotes,0,0,maxdepth,0)); } int32_t SUPPORTS(struct exchange_info *exchange,char *_base,char *_rel,cJSON *argjson) diff --git a/iguana/exchanges/btce.c b/iguana/exchanges/btce.c index 89a6223d9..3aff2dbeb 100755 --- a/iguana/exchanges/btce.c +++ b/iguana/exchanges/btce.c @@ -28,14 +28,14 @@ #define EXCHANGE_AUTHURL "https://btc-e.com/tapi" #define CHECKBALANCE btce ## _checkbalance -double UPDATE(struct exchange_info *exchange,char *base,char *rel,struct exchange_quote *quotes,int32_t maxdepth,cJSON *argjson) +double UPDATE(struct exchange_info *exchange,char *base,char *rel,struct exchange_quote *quotes,int32_t maxdepth,double commission,cJSON *argjson) { char field[64],url[1024],lbase[16],lrel[16]; strcpy(lrel,rel), strcpy(lbase,base); tolowercase(lrel), tolowercase(lbase); sprintf(field,"%s_%s",lbase,lrel); sprintf(url,"https://btc-e.com/api/3/depth/%s",field); - return(exchanges777_standardprices(exchange,base,rel,url,quotes,0,0,maxdepth,field)); + return(exchanges777_standardprices(exchange,commission,base,rel,url,quotes,0,0,maxdepth,field)); } int32_t SUPPORTS(struct exchange_info *exchange,char *base,char *rel,cJSON *argjson) diff --git a/iguana/exchanges/coinbase.c b/iguana/exchanges/coinbase.c index 2f77a6dc1..a78d90e97 100755 --- a/iguana/exchanges/coinbase.c +++ b/iguana/exchanges/coinbase.c @@ -28,11 +28,11 @@ #define EXCHANGE_AUTHURL "https://api.exchange.coinbase.com" #define CHECKBALANCE coinbase ## _checkbalance -double UPDATE(struct exchange_info *exchange,char *base,char *rel,struct exchange_quote *quotes,int32_t maxdepth,cJSON *argjson) +double UPDATE(struct exchange_info *exchange,char *base,char *rel,struct exchange_quote *quotes,int32_t maxdepth,double commission,cJSON *argjson) { char url[1024]; sprintf(url,"https://api.exchange.coinbase.com/products/%s-%s/book?level=2",base,rel); - return(exchanges777_standardprices(exchange,base,rel,url,quotes,0,0,maxdepth,0)); + return(exchanges777_standardprices(exchange,commission,base,rel,url,quotes,0,0,maxdepth,0)); } int32_t SUPPORTS(struct exchange_info *exchange,char *base,char *rel,cJSON *argjson) diff --git a/iguana/exchanges/huobi.c b/iguana/exchanges/huobi.c index ef1950f24..aefd0d2c7 100755 --- a/iguana/exchanges/huobi.c +++ b/iguana/exchanges/huobi.c @@ -27,12 +27,12 @@ #define WITHDRAW huobi ## _withdraw #define CHECKBALANCE huobi ## _checkbalance -double UPDATE(struct exchange_info *exchange,char *base,char *rel,struct exchange_quote *quotes,int32_t maxdepth,cJSON *argjson) +double UPDATE(struct exchange_info *exchange,char *base,char *rel,struct exchange_quote *quotes,int32_t maxdepth,double commission,cJSON *argjson) { char url[1024],lbase[16]; strcpy(lbase,base), tolowercase(lbase); sprintf(url,"http://api.huobi.com/staticmarket/depth_%s_json.js ",lbase); - return(exchanges777_standardprices(exchange,base,rel,url,quotes,0,0,maxdepth,0)); + return(exchanges777_standardprices(exchange,commission,base,rel,url,quotes,0,0,maxdepth,0)); } int32_t SUPPORTS(struct exchange_info *exchange,char *base,char *rel,cJSON *argjson) diff --git a/iguana/exchanges/lakebtc.c b/iguana/exchanges/lakebtc.c index a0329dc7b..6ad50d337 100755 --- a/iguana/exchanges/lakebtc.c +++ b/iguana/exchanges/lakebtc.c @@ -27,7 +27,7 @@ #define WITHDRAW lakebtc ## _withdraw #define CHECKBALANCE lakebtc ## _checkbalance -double UPDATE(struct exchange_info *exchange,char *base,char *rel,struct exchange_quote *quotes,int32_t maxdepth,cJSON *argjson) +double UPDATE(struct exchange_info *exchange,char *base,char *rel,struct exchange_quote *quotes,int32_t maxdepth,double commission,cJSON *argjson) { char url[1024]; if ( strcmp(rel,"USD") == 0 ) @@ -35,7 +35,7 @@ double UPDATE(struct exchange_info *exchange,char *base,char *rel,struct exchang else if ( strcmp(rel,"CNY") == 0 ) sprintf(url,"https://www.LakeBTC.com/api_v1/bcorderbook_cny"); else printf("illegal lakebtc pair.(%s/%s)\n",base,rel); - return(exchanges777_standardprices(exchange,base,rel,url,quotes,0,0,maxdepth,0)); + return(exchanges777_standardprices(exchange,commission,base,rel,url,quotes,0,0,maxdepth,0)); } int32_t SUPPORTS(struct exchange_info *exchange,char *base,char *rel,cJSON *argjson) diff --git a/iguana/exchanges/okcoin.c b/iguana/exchanges/okcoin.c index e4f7ae88e..a9ccb703d 100755 --- a/iguana/exchanges/okcoin.c +++ b/iguana/exchanges/okcoin.c @@ -28,7 +28,7 @@ #define EXCHANGE_AUTHURL "https://www.okcoin.com/api/v1" #define CHECKBALANCE okcoin ## _checkbalance -double UPDATE(struct exchange_info *exchange,char *base,char *rel,struct exchange_quote *quotes,int32_t maxdepth,cJSON *argjson) +double UPDATE(struct exchange_info *exchange,char *base,char *rel,struct exchange_quote *quotes,int32_t maxdepth,double commission,cJSON *argjson) { char url[1024],lrel[16],lbase[16]; strcpy(lrel,rel), strcpy(lbase,base); @@ -41,7 +41,7 @@ double UPDATE(struct exchange_info *exchange,char *base,char *rel,struct exchang exit(-1); return(0); } - return(exchanges777_standardprices(exchange,base,rel,url,quotes,0,0,maxdepth,0)); + return(exchanges777_standardprices(exchange,commission,base,rel,url,quotes,0,0,maxdepth,0)); } int32_t SUPPORTS(struct exchange_info *exchange,char *base,char *rel,cJSON *argjson) diff --git a/iguana/exchanges/poloniex.c b/iguana/exchanges/poloniex.c index 8d4e77172..1a6b2279d 100755 --- a/iguana/exchanges/poloniex.c +++ b/iguana/exchanges/poloniex.c @@ -28,12 +28,12 @@ #define EXCHANGE_AUTHURL "https://poloniex.com/tradingApi" #define CHECKBALANCE poloniex ## _checkbalance -double UPDATE(struct exchange_info *exchange,char *base,char *rel,struct exchange_quote *quotes,int32_t maxdepth,cJSON *argjson) +double UPDATE(struct exchange_info *exchange,char *base,char *rel,struct exchange_quote *quotes,int32_t maxdepth,double commission,cJSON *argjson) { char market[128],url[1024]; sprintf(market,"%s_%s",rel,base); sprintf(url,"https://poloniex.com/public?command=returnOrderBook¤cyPair=%s&depth=%d",market,maxdepth); - return(exchanges777_standardprices(exchange,base,rel,url,quotes,0,0,maxdepth,0)); + return(exchanges777_standardprices(exchange,commission,base,rel,url,quotes,0,0,maxdepth,0)); } int32_t SUPPORTS(struct exchange_info *exchange,char *base,char *rel,cJSON *argjson) diff --git a/iguana/exchanges/quadriga.c b/iguana/exchanges/quadriga.c index a8bde3910..a27bf02b7 100755 --- a/iguana/exchanges/quadriga.c +++ b/iguana/exchanges/quadriga.c @@ -27,13 +27,13 @@ #define WITHDRAW quadriga ## _withdraw #define CHECKBALANCE quadriga ## _checkbalance -double UPDATE(struct exchange_info *exchange,char *base,char *rel,struct exchange_quote *quotes,int32_t maxdepth,cJSON *argjson) +double UPDATE(struct exchange_info *exchange,char *base,char *rel,struct exchange_quote *quotes,int32_t maxdepth,double commission,cJSON *argjson) { char url[1024],lrel[16],lbase[16]; strcpy(lrel,rel), strcpy(lbase,base); tolowercase(lrel), tolowercase(lbase); sprintf(url,"https://api.quadrigacx.com/v2/order_book?book=%s_%s",lbase,lrel); - return(exchanges777_standardprices(exchange,base,rel,url,quotes,0,0,maxdepth,0)); + return(exchanges777_standardprices(exchange,commission,base,rel,url,quotes,0,0,maxdepth,0)); } int32_t SUPPORTS(struct exchange_info *exchange,char *base,char *rel,cJSON *argjson) diff --git a/iguana/exchanges777.h b/iguana/exchanges777.h index 26ed88b4f..d7ba30fba 100755 --- a/iguana/exchanges777.h +++ b/iguana/exchanges777.h @@ -20,27 +20,17 @@ #include #include +#define EXCHANGES777_MINPOLLGAP 3 #define EXCHANGES777_MAXDEPTH 200 #define EXCHANGES777_DEFAULT_TIMEOUT 30 struct exchange_info; struct exchange_quote { double price,volume; uint64_t orderid,offerNXT; uint32_t timestamp; }; -struct exchange_request -{ - struct queueitem DL; - cJSON *argjson; char **retstrp; - double price,volume,hbla,lastbid,lastask; - uint64_t orderid; - int32_t dir,depth,func,numbids,numasks; - char base[16],rel[16],destaddr[64],invert,allflag,dotrade; - struct exchange_quote bidasks[]; -}; - struct exchange_funcs { char name[32]; - double (*price)(struct exchange_info *exchange,char *base,char *rel,struct exchange_quote *quotes,int32_t maxdepth,cJSON *argjson); + double (*price)(struct exchange_info *exchange,char *base,char *rel,struct exchange_quote *quotes,int32_t maxdepth,double commission,cJSON *argjson); int32_t (*supports)(struct exchange_info *exchange,char *base,char *rel,cJSON *argjson); char *(*parsebalance)(struct exchange_info *exchange,double *balancep,char *coinstr,cJSON *argjson); cJSON *(*balances)(struct exchange_info *exchange,cJSON *argjson); @@ -63,6 +53,11 @@ struct exchange_info }; void *curl_post(void **cHandlep,char *url,char *userpass,char *postfields,char *hdr0,char *hdr1,char *hdr2,char *hdr3); +char *InstantDEX_hexmsg(struct supernet_info *myinfo,void *data,int32_t len,char *remoteaddr); +char *instantdex_sendcmd(struct supernet_info *myinfo,cJSON *argjson,char *cmdstr,char *ipaddr,int32_t hops); +char *exchanges777_Qprices(struct exchange_info *exchange,char *base,char *rel,int32_t maxseconds,int32_t allfields,int32_t depth,cJSON *argjson,int32_t monitor,double commission); +struct exchange_info *exchanges777_info(char *exchangestr,int32_t sleepflag,cJSON *json,char *remoteaddr); +char *exchanges777_unmonitor(struct exchange_info *exchange,char *base,char *rel); void prices777_processprice(struct exchange_info *exchange,char *base,char *rel,struct exchange_quote *bidasks,int32_t maxdepth); #endif diff --git a/iguana/iguana.sources b/iguana/iguana.sources index d20a93ac1..9ad5d06e4 100755 --- a/iguana/iguana.sources +++ b/iguana/iguana.sources @@ -1,3 +1,3 @@ #iguana_html.c -SOURCES := SuperNET.c SuperNET_category.c SuperNET_hexmsg.c pangea_api.c pangea_bets.c cards777.c pangea_summary.c pangea_json.c pangea_hand.c poker.c ramchain_api.c iguana_tx.c iguana_wallet.c iguana_pubkeys.c iguana_recv.c iguana_bundles.c iguana_msg.c iguana_rpc.c iguana777.c iguana_chains.c iguana_peers.c iguana_accept.c iguana_bitmap.c iguana_init.c iguana_ramchain.c iguana_blocks.c iguana_json.c main.c +SOURCES := SuperNET.c SuperNET_category.c SuperNET_hexmsg.c iguana_exchanges.c iguana_tradebots.c iguana_instantdex.c pangea_api.c pangea_bets.c cards777.c pangea_summary.c pangea_json.c pangea_hand.c poker.c ramchain_api.c iguana_tx.c iguana_wallet.c iguana_pubkeys.c iguana_recv.c iguana_bundles.c iguana_msg.c iguana_rpc.c iguana777.c iguana_chains.c iguana_peers.c iguana_accept.c iguana_bitmap.c iguana_init.c iguana_ramchain.c iguana_blocks.c iguana_json.c main.c diff --git a/iguana/iguana_exchanges.c b/iguana/iguana_exchanges.c index a74b1cd1f..35c50bd8a 100755 --- a/iguana/iguana_exchanges.c +++ b/iguana/iguana_exchanges.c @@ -19,6 +19,17 @@ #define EXCHANGE777_ISPENDING 2 #define EXCHANGE777_REQUEUE 3 +struct exchange_request +{ + struct queueitem DL; + cJSON *argjson; char **retstrp; + double price,volume,hbla,lastbid,lastask,commission; + uint64_t orderid; uint32_t timedout; + int32_t dir,depth,func,numbids,numasks; + char base[32],rel[32],destaddr[64],invert,allflag,dotrade; + struct exchange_quote bidasks[]; +}; + char *Exchange_names[] = { "bitfinex", "btc38", "bitstamp", "btce", "poloniex", "bittrex", "huobi", "coinbase", "okcoin", "lakebtc", "quadriga", "truefx", "ecb", "instaforex", "fxcm", "yahoo" }; struct exchange_info *Exchanges[sizeof(Exchange_names)/sizeof(*Exchange_names)]; @@ -27,15 +38,20 @@ void prices777_processprice(struct exchange_info *exchange,char *base,char *rel, } -cJSON *exchanges777_quotejson(struct exchange_quote *quote,int32_t allflag) +cJSON *exchanges777_quotejson(struct exchange_quote *quote,int32_t allflag,double pricesum,double totalvol) { cJSON *json; char str[65]; if ( allflag != 0 ) { json = cJSON_CreateObject(); + if ( totalvol > SMALLVAL ) + pricesum /= totalvol; jaddnum(json,"price",quote->price); jaddnum(json,"volume",quote->volume); - jaddstr(json,"time",utc_str(str,quote->timestamp)); + jaddnum(json,"aveprice",pricesum); + jaddnum(json,"cumulative",totalvol); + if ( quote->timestamp != 0 ) + jaddstr(json,"time",utc_str(str,quote->timestamp)); if ( quote->orderid > 0 ) jadd64bits(json,"orderid",quote->orderid); if ( quote->offerNXT > 0 ) @@ -46,7 +62,9 @@ cJSON *exchanges777_quotejson(struct exchange_quote *quote,int32_t allflag) char *exchanges777_orderbook_jsonstr(struct exchange_info *exchange,char *_base,char *_rel,struct exchange_quote *bidasks,int32_t maxdepth,int32_t invert,int32_t allflag) { - struct exchange_quote *bid,*ask; cJSON *json,*bids,*asks; double highbid,lowask; uint32_t timestamp; + struct exchange_quote *bid,*ask,A,B; cJSON *json,*bids,*asks; + double highbid,lowask,price,volume,bidsum,asksum,bidvol,askvol; + uint32_t timestamp; int32_t slot,numbids,numasks,enda,endb; char baserel[64],base[64],rel[64],str[65]; if ( invert == 0 ) { @@ -60,20 +78,54 @@ char *exchanges777_orderbook_jsonstr(struct exchange_info *exchange,char *_base, } json = cJSON_CreateObject(), bids = cJSON_CreateArray(), asks = cJSON_CreateArray(); highbid = lowask = 0.; - for (slot=numbids=numasks=enda=endb=0; slotprice > SMALLVAL ) + if ( endb == 0 && (price= bid->price) > SMALLVAL ) { - jaddi(bids,exchanges777_quotejson(bid,allflag)); - if ( numbids++ == 0 ) - highbid = bid->price; + volume = bid->volume; + if ( invert == 0 ) + { + bidsum += (price * volume), bidvol += volume; + //printf("bid %f %f vol %f, cumulative %f %f\n",bid->price,price,volume,bidsum/bidvol,bidvol); + jaddi(bids,exchanges777_quotejson(bid,allflag,bidsum,bidvol)); + if ( numbids++ == 0 ) + highbid = price; + } + else + { + volume *= price; + price = 1. / price; + A = *bid; + A.price = price, A.volume = volume; + asksum += (price * volume), askvol += volume; + jaddi(asks,exchanges777_quotejson(&A,allflag,asksum,askvol)); + if ( numasks++ == 0 ) + lowask = price; + } } else endb = 1; - if ( enda == 0 && ask->price > SMALLVAL ) + if ( enda == 0 && (price= ask->price) > SMALLVAL ) { - jaddi(asks,exchanges777_quotejson(ask,allflag)); - if ( numasks++ == 0 ) - lowask = ask->price; + volume = ask->volume; + if ( invert == 0 ) + { + asksum += (price * volume), askvol += volume; + jaddi(asks,exchanges777_quotejson(ask,allflag,asksum,askvol)); + if ( numasks++ == 0 ) + lowask = price; + } + else + { + volume *= price; + price = 1. / price; + B = *ask; + B.price = price, B.volume = volume; + bidsum += (price * volume), bidvol += volume; + jaddi(bids,exchanges777_quotejson(&B,allflag,bidsum,bidvol)); + if ( numbids++ == 0 ) + highbid = price; + } } else enda = 1; } jaddstr(json,"exchange",exchange->name); @@ -108,7 +160,7 @@ char *exchanges777_orderbook_jsonstr(struct exchange_info *exchange,char *_base, return(jprint(json,1)); } -void exchanges777_json_quotes(struct exchange_info *exchange,char *base,char *rel,double *lastbidp,double *lastaskp,double *hblap,struct exchange_quote *bidasks,cJSON *bids,cJSON *asks,int32_t maxdepth,char *pricefield,char *volfield,uint32_t reftimestamp) +void exchanges777_json_quotes(struct exchange_info *exchange,double commission,char *base,char *rel,double *lastbidp,double *lastaskp,double *hblap,struct exchange_quote *bidasks,cJSON *bids,cJSON *asks,int32_t maxdepth,char *pricefield,char *volfield,uint32_t reftimestamp) { int32_t i,slot,n=0,m=0,dir,bidask,slot_ba,numitems,numbids,numasks; uint64_t orderid,offerNXT; cJSON *item; struct exchange_quote *quote; uint32_t timestamp; double price,volume,hbla = 0.; @@ -128,7 +180,7 @@ void exchanges777_json_quotes(struct exchange_info *exchange,char *base,char *re if ( maxdepth != 0 && m > maxdepth ) m = maxdepth; } - for (i=0; i SMALLVAL && volume > SMALLVAL ) { - if ( exchange->commission != 0. ) + if ( commission != 0. ) { //printf("price %f fee %f -> ",price,prices->commission * price); if ( bidask == 0 ) - price -= exchange->commission * price; - else price += exchange->commission * price; + price -= commission * price; + else price += commission * price; //printf("%f\n",price); } - quote = (bidask == 0) ? &bidasks[numbids<<1] : &bidasks[(numbids<<1) + 1]; + quote = (bidask == 0) ? &bidasks[numbids<<1] : &bidasks[(numasks<<1) + 1]; quote->price = price, quote->volume = volume, quote->timestamp = timestamp, quote->orderid = orderid, quote->offerNXT = offerNXT; if ( bidask == 0 ) slot_ba = (numbids++ << 1); @@ -179,7 +231,7 @@ void exchanges777_json_quotes(struct exchange_info *exchange,char *base,char *re hbla = price; else hbla = 0.5 * (hbla + price); } - printf("%d,%d: %-8s %s %5s/%-5s %13.8f vol %13.8f | invert %13.8f vol %13.8f | timestamp.%u\n",numbids,numasks,exchange->name,dir>0?"bid":"ask",base,rel,price,volume,1./price,volume*price,timestamp); + printf("%d,%d: %-8s %s %5s/%-5s %13.8f vol %13.8f | i %13.8f vol %13.8f | t.%u\n",numbids,numasks,exchange->name,dir>0?"bid":"ask",base,rel,price,volume,1./price,volume*price,timestamp); } } } @@ -187,7 +239,7 @@ void exchanges777_json_quotes(struct exchange_info *exchange,char *base,char *re *hblap = hbla; } -double exchanges777_json_orderbook(struct exchange_info *exchange,char *base,char *rel,struct exchange_quote *bidasks,int32_t maxdepth,cJSON *json,char *resultfield,char *bidfield,char *askfield,char *pricefield,char *volfield) +double exchanges777_json_orderbook(struct exchange_info *exchange,double commission,char *base,char *rel,struct exchange_quote *bidasks,int32_t maxdepth,cJSON *json,char *resultfield,char *bidfield,char *askfield,char *pricefield,char *volfield) { cJSON *obj = 0,*bidobj=0,*askobj=0; double lastbid,lastask,hbla = 0.; int32_t numasks=0,numbids=0; if ( resultfield == 0 ) @@ -200,13 +252,13 @@ double exchanges777_json_orderbook(struct exchange_info *exchange,char *base,cha askobj = jarray(&numasks,obj,askfield); if ( bidobj != 0 || askobj != 0 ) { - exchanges777_json_quotes(exchange,base,rel,&lastbid,&lastask,&hbla,bidasks,bidobj,askobj,maxdepth,pricefield,volfield,0); + exchanges777_json_quotes(exchange,commission,base,rel,&lastbid,&lastask,&hbla,bidasks,bidobj,askobj,maxdepth,pricefield,volfield,0); } } return(hbla); } -double exchanges777_standardprices(struct exchange_info *exchange,char *base,char *rel,char *url,struct exchange_quote *quotes,char *price,char *volume,int32_t maxdepth,char *field) +double exchanges777_standardprices(struct exchange_info *exchange,double commission,char *base,char *rel,char *url,struct exchange_quote *quotes,char *price,char *volume,int32_t maxdepth,char *field) { char *jsonstr; cJSON *json; double hbla = 0.; if ( (jsonstr= issue_curl(url)) != 0 ) @@ -215,7 +267,7 @@ double exchanges777_standardprices(struct exchange_info *exchange,char *base,cha printf("(%s) -> (%s)\n",url,jsonstr); if ( (json= cJSON_Parse(jsonstr)) != 0 ) { - hbla = exchanges777_json_orderbook(exchange,base,rel,quotes,maxdepth,json,field,"bids","asks",price,volume); + hbla = exchanges777_json_orderbook(exchange,commission,base,rel,quotes,maxdepth,json,field,"bids","asks",price,volume); free_json(json); } free(jsonstr); @@ -288,7 +340,7 @@ int32_t flipstr_for_exchange(struct exchange_info *exchange,char *pairstr,char * int32_t cny_flip(char *market,char *coinname,char *base,char *rel,int32_t dir,double *pricep,double *volumep) { - char pairstr[512],lbase[16],lrel[16],*refstr=0; + char pairstr[512],lbase[32],lrel[32],*refstr=0; strcpy(lbase,base), tolowercase(lbase), strcpy(lrel,rel), tolowercase(lrel); if ( strcmp(lbase,"cny") == 0 || strcmp(lrel,"cny") == 0 ) { @@ -339,7 +391,7 @@ char *exchange_extractorderid(int32_t historyflag,char *status,uint64_t quoteid, int32_t baserel_polarity(char *pairs[][2],int32_t n,char *_base,char *_rel) { - int32_t i; char base[16],rel[16]; + int32_t i; char base[32],rel[32]; strcpy(base,_base), tolowercase(base); strcpy(rel,_rel), tolowercase(rel); for (i=0; ibidasks,0,req->depth * sizeof(*req->bidasks) * 2); - (*exchange->issue.price)(exchange,req->base,req->rel,req->bidasks,req->depth,req->argjson); + (*exchange->issue.price)(exchange,req->base,req->rel,req->bidasks,req->depth,req->commission,req->argjson); retstr = exchanges777_orderbook_jsonstr(exchange,req->base,req->rel,req->bidasks,req->depth,req->invert,req->allflag); break; case 'S': @@ -429,15 +481,17 @@ void exchanges777_loop(void *ptr) retstr = 0; if ( (req= queue_dequeue(&exchange->requestQ,0)) != 0 ) { - printf("dequeued %s.%c\n",exchange->name,req->func); + //printf("dequeued %s.%c\n",exchange->name,req->func); retstr = exchanges777_process(exchange,&retval,req); if ( retval == EXCHANGE777_DONE ) { if ( retstr != 0 ) { - if ( req->retstrp != 0 ) + if ( req->retstrp != 0 && req->timedout == 0 ) *req->retstrp = retstr; else free(retstr); + if ( req->timedout != 0 ) + printf("timedout.%u req finally finished at %u\n",req->timedout,(uint32_t)time(NULL)); } free(req); flag++; @@ -459,12 +513,15 @@ void exchanges777_loop(void *ptr) } if ( flag == 0 && time(NULL) > exchange->lastpoll+exchange->pollgap ) { - printf("check %s pricesQ\n",exchange->name); if ( (req= queue_dequeue(&exchange->pricesQ,0)) != 0 ) { - exchange->lastpoll = (uint32_t)time(NULL); - req->hbla = (*exchange->issue.price)(exchange,req->base,req->rel,req->bidasks,req->depth,req->argjson); - prices777_processprice(exchange,req->base,req->rel,req->bidasks,req->depth); + if ( req->base[0] != 0 ) + { + //printf("check %s pricesQ (%s %s)\n",exchange->name,req->base,req->rel); + exchange->lastpoll = (uint32_t)time(NULL); + req->hbla = (*exchange->issue.price)(exchange,req->base,req->rel,req->bidasks,req->depth,req->commission,req->argjson); + prices777_processprice(exchange,req->base,req->rel,req->bidasks,req->depth); + } queue_enqueue("pricesQ",&exchange->pricesQ,&req->DL,0); } } @@ -473,6 +530,25 @@ void exchanges777_loop(void *ptr) } } +char *exchanges777_unmonitor(struct exchange_info *exchange,char *base,char *rel) +{ + struct exchange_request PAD,*req; char *retstr = 0; + memset(&PAD,0,sizeof(PAD)); + queue_enqueue("pricesQ",&exchange->pricesQ,&PAD.DL,0); + while ( (req= queue_dequeue(&exchange->pricesQ,0)) != 0 && req != &PAD ) + { + if ( strcmp(base,req->base) == 0 || strcmp(rel,req->rel) == 0 ) + { + printf("unmonitor.%s (%s %s)\n",exchange->name,base,rel); + free(req); + retstr = clonestr("{\"result\":\"unmonitored\"}"); + } else queue_enqueue("pricesQ",&exchange->pricesQ,&req->DL,0); + } + if ( retstr == 0 ) + retstr = clonestr("{\"error\":\"cant find base/rel pair to unmonitor\"}"); + return(retstr); +} + char *exchanges777_submit(struct exchange_info *exchange,char **retstrp,struct exchange_request *req,int32_t func,int32_t maxseconds) { int32_t i; @@ -481,36 +557,54 @@ char *exchanges777_submit(struct exchange_info *exchange,char **retstrp,struct e maxseconds = EXCHANGES777_DEFAULT_TIMEOUT; queue_enqueue("exchangeQ",&exchange->requestQ,&req->DL,0); for (i=0; itimedout = (uint32_t)time(NULL); return(clonestr("{\"error\":\"request timed out\"}")); } char *exchanges777_Qtrade(struct exchange_info *exchange,char *base,char *rel,int32_t maxseconds,int32_t dotrade,int32_t dir,double price,double volume,cJSON *argjson) { - struct exchange_request *req; char *retstr = 0; - if ( base[0] == 0 || rel[0] == 0 ) + struct exchange_request *req; int32_t polarity; char *retstr = 0; + if ( base[0] == 0 || rel[0] == 0 || (polarity= (*exchange->issue.supports)(exchange,base,rel,argjson)) == 0 || price < SMALLVAL || volume < SMALLVAL ) return(clonestr("{\"error\":\"invalid base or rel\"}")); req = calloc(1,sizeof(*req)); req->argjson = argjson; req->retstrp = &retstr; safecopy(req->base,base,sizeof(req->base)); safecopy(req->rel,rel,sizeof(req->rel)); - req->price = price, req->volume = volume; - req->dir = dir, req->dotrade = dotrade; + if ( polarity < 0 ) + dir *= -1, volume *= price, price = 1. / price; + req->price = price, req->volume = volume, req->dir = dir; + req->dotrade = dotrade; return(exchanges777_submit(exchange,&retstr,req,'T',maxseconds)); } -char *exchanges777_Qprices(struct exchange_info *exchange,char *base,char *rel,int32_t maxseconds,int32_t allfields,int32_t invert,int32_t depth,cJSON *argjson) +char *exchanges777_Qprices(struct exchange_info *exchange,char *base,char *rel,int32_t maxseconds,int32_t allfields,int32_t depth,cJSON *argjson,int32_t monitor,double commission) { - struct exchange_request *req; char *retstr = 0; - if ( base[0] == 0 || rel[0] == 0 ) + struct exchange_request *req; char *retstr = 0; int32_t polarity; + if ( base[0] == 0 || rel[0] == 0 || (polarity= (*exchange->issue.supports)(exchange,base,rel,argjson)) == 0 ) return(clonestr("{\"error\":\"invalid base or rel\"}")); + if ( depth <= 0 ) + depth = 1; req = calloc(1,sizeof(*req) + sizeof(*req->bidasks)*depth*2); req->argjson = argjson; req->retstrp = &retstr; safecopy(req->base,base,sizeof(req->base)); safecopy(req->rel,rel,sizeof(req->rel)); - req->depth = depth, req->allflag = allfields, req->invert = invert; - return(exchanges777_submit(exchange,&retstr,req,'Q',maxseconds)); + req->depth = depth, req->allflag = allfields; + req->invert = (polarity < 0); + if ( (req->commission= commission) == 0. ) + req->commission = exchange->commission; + if ( monitor == 0 ) + return(exchanges777_submit(exchange,&retstr,req,'Q',maxseconds)); + else + { + req->func = 'Q'; + queue_enqueue("pricesQ",&exchange->pricesQ,&req->DL,0); + return(clonestr("{\"result\":\"start monitoring\"}")); + } } char *exchanges777_Qrequest(struct exchange_info *exchange,int32_t func,char *base,char *rel,int32_t maxseconds,uint64_t orderid,char *destaddr,double amount,cJSON *argjson) @@ -578,7 +672,8 @@ struct exchange_info *exchange_create(char *exchangestr,cJSON *argjson) iguana_initQ(&exchange->pendingQ[1],"pending1"); exchange->exchangeid = exchangeid; safecopy(exchange->name,exchangestr,sizeof(exchange->name)); - exchange->pollgap = juint(argjson,"pollgap"); + if ( (exchange->pollgap= juint(argjson,"pollgap")) < EXCHANGES777_MINPOLLGAP ) + exchange->pollgap = EXCHANGES777_MINPOLLGAP; if ( (key= jstr(argjson,"apikey")) != 0 || (key= jstr(argjson,"key")) != 0 ) safecopy(exchange->apikey,key,sizeof(exchange->apikey)); if ( (secret= jstr(argjson,"apisecret")) != 0 || (secret= jstr(argjson,"secret")) != 0 ) @@ -594,9 +689,11 @@ struct exchange_info *exchange_create(char *exchangestr,cJSON *argjson) return(exchange); } -struct exchange_info *exchanges777_info(char *exchangestr,int32_t sleepflag,cJSON *json) +struct exchange_info *exchanges777_info(char *exchangestr,int32_t sleepflag,cJSON *json,char *remoteaddr) { struct exchange_info *exchange; + if ( remoteaddr != 0 ) + return(0); if ( (exchange= exchanges777_find(exchangestr)) == 0 ) { if ( (exchange= exchange_create(exchangestr,json)) != 0 ) @@ -611,9 +708,17 @@ struct exchange_info *exchanges777_info(char *exchangestr,int32_t sleepflag,cJSO void exchanges777_init(int32_t sleepflag) { - int32_t i; cJSON *argjson = cJSON_CreateObject(); - for (i=0; icommission)); else return(clonestr("{\"error\":\"cant find or create exchange\"}")); } THREE_STRINGS_AND_THREE_DOUBLES(InstantDEX,buy,exchange,base,rel,price,volume,dotrade) { struct exchange_info *ptr; - if ( (ptr= exchanges777_info(exchange,1,json)) != 0 ) + if ( (ptr= exchanges777_info(exchange,1,json,remoteaddr)) != 0 ) return(exchanges777_Qtrade(ptr,base,rel,juint(json,"maxseconds"),dotrade,1,price,volume,json)); else return(clonestr("{\"error\":\"cant find or create exchange\"}")); } @@ -637,7 +742,7 @@ THREE_STRINGS_AND_THREE_DOUBLES(InstantDEX,buy,exchange,base,rel,price,volume,do THREE_STRINGS_AND_THREE_DOUBLES(InstantDEX,sell,exchange,base,rel,price,volume,dotrade) { struct exchange_info *ptr; - if ( (ptr= exchanges777_info(exchange,1,json)) != 0 ) + if ( (ptr= exchanges777_info(exchange,1,json,remoteaddr)) != 0 ) return(exchanges777_Qtrade(ptr,base,rel,juint(json,"maxseconds"),dotrade,-1,price,volume,json)); else return(clonestr("{\"error\":\"cant find or create exchange\"}")); } @@ -645,7 +750,7 @@ THREE_STRINGS_AND_THREE_DOUBLES(InstantDEX,sell,exchange,base,rel,price,volume,d THREE_STRINGS_AND_DOUBLE(InstantDEX,withdraw,exchange,base,destaddr,amount) { struct exchange_info *ptr; - if ( (ptr= exchanges777_info(exchange,1,json)) != 0 ) + if ( (ptr= exchanges777_info(exchange,1,json,remoteaddr)) != 0 ) return(exchanges777_Qrequest(ptr,'W',base,0,juint(json,"maxseconds"),0,destaddr,amount,json)); else return(clonestr("{\"error\":\"cant find or create exchange\"}")); } @@ -653,7 +758,7 @@ THREE_STRINGS_AND_DOUBLE(InstantDEX,withdraw,exchange,base,destaddr,amount) THREE_STRINGS(InstantDEX,supports,exchange,base,rel) { struct exchange_info *ptr; - if ( (ptr= exchanges777_info(exchange,1,json)) != 0 ) + if ( (ptr= exchanges777_info(exchange,1,json,remoteaddr)) != 0 ) return(exchanges777_Qrequest(ptr,'S',base,rel,juint(json,"maxseconds"),0,0,0,json)); else return(clonestr("{\"error\":\"cant find or create exchange\"}")); } @@ -661,7 +766,7 @@ THREE_STRINGS(InstantDEX,supports,exchange,base,rel) TWO_STRINGS(InstantDEX,balance,exchange,base) { struct exchange_info *ptr; - if ( (ptr= exchanges777_info(exchange,1,json)) != 0 ) + if ( (ptr= exchanges777_info(exchange,1,json,remoteaddr)) != 0 ) return(exchanges777_Qrequest(ptr,'B',base,0,juint(json,"maxseconds"),0,0,0,json)); else return(clonestr("{\"error\":\"cant find or create exchange\"}")); } @@ -669,7 +774,7 @@ TWO_STRINGS(InstantDEX,balance,exchange,base) TWO_STRINGS(InstantDEX,orderstatus,exchange,orderid) { struct exchange_info *ptr; - if ( (ptr= exchanges777_info(exchange,1,json)) != 0 ) + if ( (ptr= exchanges777_info(exchange,1,json,remoteaddr)) != 0 ) return(exchanges777_Qrequest(ptr,'P',0,0,juint(json,"maxseconds"),calc_nxt64bits(orderid),0,0,json)); else return(clonestr("{\"error\":\"cant find or create exchange\"}")); } @@ -677,7 +782,7 @@ TWO_STRINGS(InstantDEX,orderstatus,exchange,orderid) TWO_STRINGS(InstantDEX,cancelorder,exchange,orderid) { struct exchange_info *ptr; - if ( (ptr= exchanges777_info(exchange,1,json)) != 0 ) + if ( (ptr= exchanges777_info(exchange,1,json,remoteaddr)) != 0 ) return(exchanges777_Qrequest(ptr,'C',0,0,juint(json,"maxseconds"),calc_nxt64bits(orderid),0,0,json)); else return(clonestr("{\"error\":\"cant find or create exchange\"}")); } @@ -685,7 +790,7 @@ TWO_STRINGS(InstantDEX,cancelorder,exchange,orderid) STRING_ARG(InstantDEX,openorders,exchange) { struct exchange_info *ptr; - if ( (ptr= exchanges777_info(exchange,1,json)) != 0 ) + if ( (ptr= exchanges777_info(exchange,1,json,remoteaddr)) != 0 ) return(exchanges777_Qrequest(ptr,'O',0,0,juint(json,"maxseconds"),0,0,0,json)); else return(clonestr("{\"error\":\"cant find or create exchange\"}")); } @@ -693,7 +798,7 @@ STRING_ARG(InstantDEX,openorders,exchange) STRING_ARG(InstantDEX,tradehistory,exchange) { struct exchange_info *ptr; - if ( (ptr= exchanges777_info(exchange,1,json)) != 0 ) + if ( (ptr= exchanges777_info(exchange,1,json,remoteaddr)) != 0 ) return(exchanges777_Qrequest(ptr,'H',0,0,juint(json,"maxseconds"),0,0,0,json)); else return(clonestr("{\"error\":\"cant find or create exchange\"}")); } @@ -701,7 +806,7 @@ STRING_ARG(InstantDEX,tradehistory,exchange) THREE_STRINGS(InstantDEX,apikeypair,exchange,apikey,apisecret) { struct exchange_info *ptr; - if ( (ptr= exchanges777_info(exchange,1,json)) != 0 ) + if ( (ptr= exchanges777_info(exchange,1,json,remoteaddr)) != 0 ) { if ( apikey != 0 && apikey[0] != 0 && apisecret != 0 && apisecret[0] != 0 ) { @@ -715,7 +820,7 @@ THREE_STRINGS(InstantDEX,apikeypair,exchange,apikey,apisecret) THREE_STRINGS(InstantDEX,setuserid,exchange,userid,tradepassword) { struct exchange_info *ptr; - if ( (ptr= exchanges777_info(exchange,1,json)) != 0 ) + if ( (ptr= exchanges777_info(exchange,1,json,remoteaddr)) != 0 ) { safecopy(ptr->userid,userid,sizeof(ptr->userid)); safecopy(ptr->tradepassword,tradepassword,sizeof(ptr->tradepassword)); @@ -723,4 +828,13 @@ THREE_STRINGS(InstantDEX,setuserid,exchange,userid,tradepassword) } else return(clonestr("{\"error\":\"cant find or create exchange\"}")); } +STRING_AND_INT(InstantDEX,pollgap,exchange,pollgap) +{ + struct exchange_info *ptr; + if ( (ptr= exchanges777_info(exchange,1,json,remoteaddr)) != 0 ) + { + ptr->pollgap = pollgap; + return(clonestr("{\"result\":\"set pollgap\"}")); + } else return(clonestr("{\"error\":\"cant find or create exchange\"}")); +} #include "../includes/iguana_apiundefs.h" diff --git a/iguana/iguana_instantdex.c b/iguana/iguana_instantdex.c new file mode 100755 index 000000000..f21852c7c --- /dev/null +++ b/iguana/iguana_instantdex.c @@ -0,0 +1,271 @@ +/****************************************************************************** + * Copyright © 2014-2016 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. * + * * + ******************************************************************************/ + +#include "exchanges777.h" + +struct instantdex_msghdr +{ + struct acct777_sig sig __attribute__((packed)); + char cmd[8]; + uint8_t serialized[]; +} __attribute__((packed)); + +int32_t instantdex_rwdata(int32_t rwflag,uint64_t cmdbits,uint8_t *data,int32_t datalen) +{ + // need to inplace serialize/deserialize here + return(datalen); +} + +struct instantdex_msghdr *instantdex_msgcreate(struct supernet_info *myinfo,struct instantdex_msghdr *msg,int32_t datalen) +{ + bits256 otherpubkey; uint64_t signerbits; uint32_t timestamp; uint8_t buf[sizeof(msg->sig)],*data; + memset(&msg->sig,0,sizeof(msg->sig)); + datalen += (int32_t)(sizeof(*msg) - sizeof(msg->sig)); + data = (void *)((long)msg + sizeof(msg->sig)); + otherpubkey = acct777_msgpubkey(data,datalen); + timestamp = (uint32_t)time(NULL); + acct777_sign(&msg->sig,myinfo->privkey,otherpubkey,timestamp,data,datalen); + if ( (signerbits= acct777_validate(&msg->sig,acct777_msgprivkey(data,datalen),msg->sig.pubkey)) != 0 ) + { + int32_t i; char str[65],str2[65]; + for (i=0; i>>>>>>>>>>>>>>> validated [%ld] len.%d (%s + %s)\n",(long)data-(long)msg,datalen,bits256_str(str,acct777_msgprivkey(data,datalen)),bits256_str(str2,msg->sig.pubkey)); + memset(buf,0,sizeof(buf)); + acct777_rwsig(1,buf,&msg->sig); + memcpy(&msg->sig,buf,sizeof(buf)); + return(msg); + } else printf("error validating instantdex msg\n"); + return(0); +} + +char *instantdex_sendcmd(struct supernet_info *myinfo,cJSON *argjson,char *cmdstr,char *ipaddr,int32_t hops) +{ + char *reqstr,hexstr[8192]; uint8_t _msg[4096]; uint64_t nxt64bits; int32_t datalen; + bits256 instantdexhash; struct instantdex_msghdr *msg; + msg = (struct instantdex_msghdr *)_msg; + memset(msg,0,sizeof(*msg)); + instantdexhash = calc_categoryhashes(0,"InstantDEX",0); + category_subscribe(myinfo,instantdexhash,GENESIS_PUBKEY); + if ( ipaddr == 0 || ipaddr[0] == 0 || strncmp(ipaddr,"127.0.0.1",strlen("127.0.0.1")) == 0 ) + return(clonestr("{\"error\":\"no ipaddr, need to send your ipaddr for now\"}")); + jaddstr(argjson,"cmd",cmdstr); + jaddstr(argjson,"agent","SuperNET"); + jaddstr(argjson,"method","DHT"); + jaddstr(argjson,"traderip",ipaddr); + jaddbits256(argjson,"categoryhash",instantdexhash); + jaddbits256(argjson,"traderpub",myinfo->myaddr.persistent); + nxt64bits = acct777_nxt64bits(myinfo->myaddr.persistent); + reqstr = jprint(argjson,1); + datalen = (int32_t)(strlen(reqstr) + 1); + memcpy(msg->serialized,reqstr,datalen); + free(reqstr); + if ( (datalen+sizeof(*msg))*2+1 < sizeof(hexstr) && instantdex_msgcreate(myinfo,msg,datalen) != 0 ) + { + printf("instantdex send.(%s)\n",cmdstr); + init_hexbytes_noT(hexstr,(uint8_t *)msg,msg->sig.allocsize); + return(SuperNET_categorymulticast(myinfo,0,instantdexhash,GENESIS_PUBKEY,hexstr,0,hops,1)); + } + else + { + printf("cant msgcreate\n"); + return(clonestr("{\"error\":\"couldnt create instantdex message\"}")); + } +} + +char *instantdex_reqprice(struct supernet_info *myinfo,struct instantdex_msghdr *msg,cJSON *argjson,char *remoteaddr,uint64_t signerbits,uint8_t *data,int32_t datalen) +{ + if ( argjson != 0 ) + { + return(clonestr("{\"result\":\"reqprice response not sent\"}")); + return(clonestr("{\"result\":\"reqprice response sent\"}")); + } else return(clonestr("{\"error\":\"reqprice needs argjson\"}")); +} + +char *instantdex_proposal(struct supernet_info *myinfo,struct instantdex_msghdr *msg,cJSON *argjson,char *remoteaddr,uint64_t signerbits,uint8_t *data,int32_t datalen) +{ + if ( argjson != 0 ) + { + return(clonestr("{\"result\":\"proposal ignored\"}")); + return(clonestr("{\"result\":\"proposal accepted\"}")); + } else return(clonestr("{\"error\":\"response needs argjson\"}")); +} + +char *instantdex_accepted(struct supernet_info *myinfo,struct instantdex_msghdr *msg,cJSON *argjson,char *remoteaddr,uint64_t signerbits,uint8_t *data,int32_t datalen) +{ + if ( argjson != 0 ) + { + return(clonestr("{\"result\":\"proposal was accepted, confirmation sent\"}")); + } else return(clonestr("{\"error\":\"response needs argjson\"}")); +} + +char *instantdex_confirmed(struct supernet_info *myinfo,struct instantdex_msghdr *msg,cJSON *argjson,char *remoteaddr,uint64_t signerbits,uint8_t *data,int32_t datalen) +{ + if ( argjson != 0 ) + { + return(clonestr("{\"result\":\"proposal was confirmed\"}")); + } else return(clonestr("{\"error\":\"response needs argjson\"}")); +} + +char *instantdex_parse(struct supernet_info *myinfo,struct instantdex_msghdr *msg,cJSON *argjson,char *remoteaddr,uint64_t signerbits,uint8_t *data,int32_t datalen) +{ + static struct { char *cmdstr; char *(*func)(struct supernet_info *myinfo,struct instantdex_msghdr *msg,cJSON *argjson,char *remoteaddr,uint64_t signerbits,uint8_t *data,int32_t datalen); uint64_t cmdbits; } cmds[] = + { + { "reqprice", instantdex_reqprice }, { "proposal", instantdex_proposal }, + { "accepted", instantdex_accepted }, { "confirmed", instantdex_confirmed }, + }; + char *retstr = 0; int32_t i; uint64_t cmdbits; + if ( cmds[0].cmdbits == 0 ) + { + for (i=0; icmd); + for (i=0; isig)]; char *retstr = 0; + acct777_rwsig(0,(void *)&msg->sig,(void *)tmp); + memcpy(&msg->sig,tmp,sizeof(msg->sig)); + datalen = len - (int32_t)sizeof(msg->sig); + data = (void *)((long)msg + sizeof(msg->sig)); + if ( remoteaddr != 0 && remoteaddr[0] == 0 && strcmp("127.0.0.1",remoteaddr) == 0 && ((uint8_t *)msg)[len-1] == 0 && (argjson= cJSON_Parse((char *)msg)) != 0 ) + { + printf("instantdex_hexmsg RESULT.(%s)\n",jprint(argjson,0)); + retstr = instantdex_parse(myinfo,msg,argjson,0,myinfo->myaddr.nxt64bits,0,0); + free_json(argjson); + return(retstr); + } + //printf("msg.%p len.%d data.%p datalen.%d crc.%u %s\n",msg,len,data,datalen,calc_crc32(0,(void *)msg,len),bits256_str(str,msg->sig.pubkey)); + //return(0); + else if ( (signerbits= acct777_validate(&msg->sig,acct777_msgprivkey(data,datalen),msg->sig.pubkey)) != 0 ) + { + flag++; + printf("<<<<<<<<<<<<< sigsize.%ld VALIDATED [%ld] len.%d t%u allocsize.%d (%s) [%d]\n",sizeof(msg->sig),(long)data-(long)msg,datalen,msg->sig.timestamp,msg->sig.allocsize,(char *)msg->serialized,data[datalen-1]); + if ( data[datalen-1] == 0 && (argjson= cJSON_Parse((char *)msg->serialized)) != 0 ) + retstr = instantdex_parse(myinfo,msg,argjson,remoteaddr,signerbits,data,datalen); + else + { + newlen = (int32_t)(msg->sig.allocsize - sizeof(*msg)); + data = msg->serialized; + if ( msg->serialized[len - 1] == 0 ) + { + if ( (argjson= cJSON_Parse((char *)msg->serialized)) != 0 ) + { + n = (int32_t)(strlen((char *)msg->serialized) + 1); + newlen -= n; + if ( n >= 0 ) + data = &msg->serialized[n]; + else data = 0; + } + } + if ( data != 0 ) + retstr = instantdex_parse(myinfo,msg,argjson,remoteaddr,signerbits,data,newlen); + } + } + if ( argjson != 0 ) + free_json(argjson); + return(retstr); +} + +#include "../includes/iguana_apidefs.h" + +THREE_STRINGS_AND_DOUBLE(InstantDEX,request,reference,base,rel,volume) +{ + int32_t hops = 3; cJSON *argjson; + if ( remoteaddr == 0 ) + { + argjson = cJSON_CreateObject(); + jaddstr(argjson,"ref",reference); + jaddstr(argjson,"base",base); + jaddstr(argjson,"rel",rel); + jaddnum(argjson,"volume",volume); + return(instantdex_sendcmd(myinfo,argjson,"request",myinfo->ipaddr,hops)); + } else return(clonestr("{\"error\":\"InstantDEX API request only local usage!\"}")); +} + +cJSON *InstantDEX_argjson(char *reference,char *message,bits256 basetxid,bits256 reltxid,int32_t iter,int32_t val,int32_t val2) +{ + cJSON *argjson = cJSON_CreateObject(); + jaddstr(argjson,"ref",reference); + if ( message != 0 && message[0] != 0 ) + jaddstr(argjson,"message",message); + jaddbits256(argjson,"basetxid",basetxid); + jaddbits256(argjson,"reltxid",reltxid); + if ( iter != 3 ) + { + jaddnum(argjson,"duration",val); + jaddnum(argjson,"flags",val2); + } + else + { + if ( val > 0 ) + jaddnum(argjson,"baseheight",val); + if ( val2 > 0 ) + jaddnum(argjson,"relheight",val2); + } + return(argjson); +} + +TWOSTRINGS_AND_TWOHASHES_AND_TWOINTS(InstantDEX,proposal,reference,message,basetxid,reltxid,duration,flags) +{ + int32_t hops = 3; cJSON *argjson; char *retstr; + if ( remoteaddr == 0 ) + { + argjson = InstantDEX_argjson(reference,message,basetxid,reltxid,1,duration,flags); + retstr = instantdex_sendcmd(myinfo,argjson,"proposal",myinfo->ipaddr,hops); + free_json(argjson); + return(retstr); + } else return(clonestr("{\"error\":\"InstantDEX API proposal only local usage!\"}")); +} + +TWOSTRINGS_AND_TWOHASHES_AND_TWOINTS(InstantDEX,accept,reference,message,basetxid,reltxid,duration,flags) +{ + int32_t hops = 3; cJSON *argjson; char *retstr; + if ( remoteaddr == 0 ) + { + argjson = InstantDEX_argjson(reference,message,basetxid,reltxid,2,duration,flags); + retstr = instantdex_sendcmd(myinfo,argjson,"accept",myinfo->ipaddr,hops); + free_json(argjson); + return(retstr); + } else return(clonestr("{\"error\":\"InstantDEX API accept only local usage!\"}")); +} + +TWOSTRINGS_AND_TWOHASHES_AND_TWOINTS(InstantDEX,confirm,reference,message,basetxid,reltxid,baseheight,relheight) +{ + int32_t hops = 3; cJSON *argjson; char *retstr; + if ( remoteaddr == 0 ) + { + argjson = InstantDEX_argjson(reference,message,basetxid,reltxid,3,baseheight,relheight); + retstr = instantdex_sendcmd(myinfo,argjson,"confirm",myinfo->ipaddr,hops); + free_json(argjson); + return(retstr); + } else return(clonestr("{\"error\":\"InstantDEX API confirm only local usage!\"}")); +} + + +#include "../includes/iguana_apiundefs.h" + diff --git a/iguana/iguana_tradebots.c b/iguana/iguana_tradebots.c new file mode 100755 index 000000000..27cd3cf3f --- /dev/null +++ b/iguana/iguana_tradebots.c @@ -0,0 +1,60 @@ +/****************************************************************************** + * Copyright © 2014-2016 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. * + * * + ******************************************************************************/ + +#include "exchanges777.h" + + +#include "../includes/iguana_apidefs.h" + +THREE_STRINGS_AND_DOUBLE(tradebot,monitor,exchange,base,rel,commission) +{ + int32_t allfields = 1,depth = 50; struct exchange_info *ptr; + if ( remoteaddr == 0 ) + { + if ( (ptr= exchanges777_info(exchange,1,json,remoteaddr)) != 0 ) + return(exchanges777_Qprices(ptr,base,rel,30,allfields,depth,json,1,commission * .01)); + else return(clonestr("{\"error\":\"couldnt find/create exchange info\"}")); + } else return(clonestr("{\"error\":\"tradebots only local usage!\"}")); +} + +THREE_STRINGS(tradebot,unmonitor,exchange,base,rel) +{ + struct exchange_info *ptr; + if ( remoteaddr == 0 ) + { + if ( (ptr= exchanges777_info(exchange,1,json,remoteaddr)) != 0 ) + return(exchanges777_unmonitor(ptr,base,rel)); + else return(clonestr("{\"error\":\"couldnt find/create exchange info\"}")); + } else return(clonestr("{\"error\":\"tradebots only local usage!\"}")); +} + +THREE_STRINGS_AND_THREE_DOUBLES(tradebot,accumulate,exchange,base,rel,price,volume,duration) +{ + if ( remoteaddr == 0 ) + { + return(clonestr("{\"result\":\"start accumulating\"}")); + } else return(clonestr("{\"error\":\"tradebots only local usage!\"}")); +} + +THREE_STRINGS_AND_THREE_DOUBLES(tradebot,divest,exchange,base,rel,price,volume,duration) +{ + if ( remoteaddr == 0 ) + { + return(clonestr("{\"result\":\"start divesting\"}")); + } else return(clonestr("{\"error\":\"tradebots only local usage!\"}")); +} + +#include "../includes/iguana_apiundefs.h" + diff --git a/iguana/pangea_api.c b/iguana/pangea_api.c index 8f26a5337..21d3ccb0f 100755 --- a/iguana/pangea_api.c +++ b/iguana/pangea_api.c @@ -439,7 +439,7 @@ void pangea_parse(struct supernet_info *myinfo,struct pangea_msghdr *pm,cJSON *a } } -int32_t pangea_hexmsg(struct supernet_info *myinfo,void *data,int32_t len,char *remoteaddr) +char *pangea_hexmsg(struct supernet_info *myinfo,void *data,int32_t len,char *remoteaddr) { static struct { char *cmdstr; void (*func)(PANGEA_HANDARGS); uint64_t cmdbits; } tablecmds[] = { @@ -455,7 +455,7 @@ int32_t pangea_hexmsg(struct supernet_info *myinfo,void *data,int32_t len,char * { "showdown", pangea_showdown }, { "summary", pangea_summary }, }; struct pangea_msghdr *pm = data; cJSON *argjson; bits256 tablehash; - uint64_t cmdbits; uint8_t *serialized; uint8_t tmp[sizeof(pm->sig)]; char str[65],str2[65]; + uint64_t cmdbits; uint8_t *serialized; uint8_t tmp[sizeof(pm->sig)]; char *retstr=0,str[65],str2[65]; struct table_info *tp; int32_t i,allocsize,datalen,flag = 0; if ( tablecmds[0].cmdbits == 0 ) { @@ -468,10 +468,11 @@ int32_t pangea_hexmsg(struct supernet_info *myinfo,void *data,int32_t len,char * serialized = (void *)((long)pm + sizeof(pm->sig)); if ( remoteaddr != 0 && remoteaddr[0] == 0 && strcmp("127.0.0.1",remoteaddr) == 0 && ((uint8_t *)pm)[len-1] == 0 && (argjson= cJSON_Parse((char *)pm)) != 0 ) { + // ?? iguana_rwbignum(0,pm->tablehash.bytes,sizeof(bits256),tablehash.bytes); printf("pangea_hexmsg RESULT.(%s)\n",jprint(argjson,0)); pangea_parse(myinfo,pm,argjson,remoteaddr); free_json(argjson); - return(1); + return(retstr); } //printf("pm.%p len.%d serialized.%p datalen.%d crc.%u %s\n",pm,len,serialized,datalen,calc_crc32(0,(void *)pm,len),bits256_str(str,pm->sig.pubkey)); //return(0); @@ -520,7 +521,7 @@ int32_t pangea_hexmsg(struct supernet_info *myinfo,void *data,int32_t len,char * printf("%02x",serialized[i]); printf("<<<<<<<<<<<<< sigsize.%ld SIG ERROR [%ld] len.%d (%s + %s)\n",sizeof(pm->sig),(long)serialized-(long)pm,datalen,bits256_str(str,acct777_msgprivkey(serialized,datalen)),bits256_str(str2,pm->sig.pubkey)); } - return(flag); + return(retstr); } void pangea_update(struct supernet_info *myinfo) diff --git a/iguana/pnacl/Release/iguana.nmf b/iguana/pnacl/Release/iguana.nmf new file mode 100644 index 000000000..9d37ed227 --- /dev/null +++ b/iguana/pnacl/Release/iguana.nmf @@ -0,0 +1,12 @@ +{ + "program": { + "portable": { + "pnacl-translate": { + "url": "iguana.pexe" + }, + "pnacl-debug": { + "url": "iguana_unstripped.bc" + } + } + } +} diff --git a/iguana/pnacl/Release/iguana.pexe b/iguana/pnacl/Release/iguana.pexe new file mode 100644 index 000000000..6b2bb4fd7 Binary files /dev/null and b/iguana/pnacl/Release/iguana.pexe differ diff --git a/includes/iguana_apideclares.h b/includes/iguana_apideclares.h index b041d7f9b..b4f0ff64d 100755 --- a/includes/iguana_apideclares.h +++ b/includes/iguana_apideclares.h @@ -32,6 +32,18 @@ TWO_STRINGS(InstantDEX,orderstatus,exchange,orderid); TWO_STRINGS(InstantDEX,cancelorder,exchange,orderid); STRING_ARG(InstantDEX,openorders,exchange); STRING_ARG(InstantDEX,tradehistory,exchange); +STRING_AND_INT(InstantDEX,pollgap,exchange,pollgap); + +THREE_STRINGS_AND_DOUBLE(InstantDEX,request,reference,base,rel,volume); +TWOSTRINGS_AND_TWOHASHES_AND_TWOINTS(InstantDEX,proposal,reference,message,basetxid,reltxid,duration,flags); + +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); + +THREE_STRINGS_AND_DOUBLE(tradebot,monitor,exchange,base,rel,commission); +THREE_STRINGS(tradebot,unmonitor,exchange,base,rel); +THREE_STRINGS_AND_THREE_DOUBLES(tradebot,accumulate,exchange,base,rel,price,volume,duration); +THREE_STRINGS_AND_THREE_DOUBLES(tradebot,divest,exchange,base,rel,price,volume,duration); /*HASH_AND_ARRAY(pangea,userturn,tablehash,params); HASH_AND_ARRAY(pangea,status,tableid,params);