From fbadf74d51cbdc18a361a382a617495d811751c6 Mon Sep 17 00:00:00 2001 From: jl777 Date: Tue, 28 Jun 2016 11:58:09 -0300 Subject: [PATCH] test --- basilisk/basilisk.c | 240 ++---------------- basilisk/basilisk.h | 12 +- basilisk/basilisk_CMD.c | 34 --- basilisk/basilisk_DEX.c | 449 ++++++++++++++++++++++++++++++++++ basilisk/basilisk_ping.c | 218 +++++++++++++++++ crypto777/bitcoind_RPC.c | 2 +- iguana/SuperNET_keys.c | 5 +- iguana/iguana777.c | 2 - iguana/iguana_exchanges.c | 4 +- iguana/iguana_instantdex.c | 45 +--- iguana/iguana_json.c | 4 + iguana/iguana_peers.c | 10 +- iguana/iguana_recv.c | 2 +- iguana/tests/aveprice | 2 + includes/iguana_apideclares.h | 4 +- includes/iguana_apidefs.h | 2 + includes/iguana_apiundefs.h | 1 + includes/iguana_funcs.h | 1 + includes/iguana_structs.h | 5 +- 19 files changed, 725 insertions(+), 317 deletions(-) create mode 100755 basilisk/basilisk_DEX.c create mode 100755 basilisk/basilisk_ping.c create mode 100755 iguana/tests/aveprice diff --git a/basilisk/basilisk.c b/basilisk/basilisk.c index cd9ace6f5..bc34e1b3f 100755 --- a/basilisk/basilisk.c +++ b/basilisk/basilisk.c @@ -378,12 +378,23 @@ char *basilisk_standardservice(char *CMD,struct supernet_info *myinfo,void *_add return(retstr); } +int32_t basilisk_relayid(struct supernet_info *myinfo,uint32_t ipbits) +{ + int32_t j; + for (j=0; jnumrelays; j++) + if ( myinfo->relays[j].ipbits == ipbits ) + return(j); + return(-1); +} + #include "basilisk_bitcoin.c" #include "basilisk_nxt.c" #include "basilisk_ether.c" #include "basilisk_waves.c" #include "basilisk_lisk.c" #include "basilisk_CMD.c" +#include "basilisk_DEX.c" +#include "basilisk_ping.c" #include "../includes/iguana_apidefs.h" #include "../includes/iguana_apideclares.h" @@ -560,209 +571,6 @@ void basilisk_wait(struct supernet_info *myinfo,struct iguana_info *coin) } } -int32_t baslisk_relay_report(struct supernet_info *myinfo,uint8_t *data,int32_t maxlen,struct basilisk_relaystatus *reported,uint8_t pingdelay) -{ - if ( reported != 0 ) - { - reported->pingdelay = pingdelay; - } - return(0); -} - -int32_t basilisk_relay_ping(struct supernet_info *myinfo,uint8_t *data,int32_t maxlen,struct basilisk_relay *rp) -{ - int32_t datalen = 0; - datalen = iguana_rwnum(1,&data[datalen],sizeof(rp->ipbits),&rp->ipbits); - data[datalen++] = rp->direct.pingdelay; - return(datalen); -} -int32_t basilisk_blocksend(struct supernet_info *myinfo,struct iguana_info *btcd,struct iguana_info *virt,struct iguana_peer *addr,int32_t height) -{ - int32_t blocklen; bits256 hash2; uint8_t *data = 0; char str[65],strbuf[8192],*blockstr,*allocptr = 0; struct iguana_block *block; - hash2 = iguana_blockhash(virt,height); - if ( (block= iguana_blockfind("bsend",virt,hash2)) != 0 ) - { - if ( block->height != height ) - { - printf("basilisk_blocksend: height.%d mismatch %d\n",block->height,height); - return(-1); - } - else if ( block->queued != 0 && block->req != 0 ) - { - memcpy(&blocklen,block->req,sizeof(blocklen)); - data = (uint8_t *)(void *)((long)block->req + sizeof(blocklen)); - } - } - if ( data == 0 ) - { - if ( (blocklen= iguana_peerblockrequest(virt,virt->blockspace,IGUANA_MAXPACKETSIZE,0,hash2,0)) > 0 ) - data = &virt->blockspace[sizeof(struct iguana_msghdr)]; - } - if ( data != 0 ) - { - blockstr = basilisk_addhexstr(&allocptr,0,strbuf,sizeof(strbuf),data,blocklen); - printf("RELAYID.%d send block.%d %s -> (%s) %s\n",myinfo->RELAYID,height,blockstr,addr->ipaddr,bits256_str(str,hash2)); - basilisk_blocksubmit(myinfo,btcd,virt,addr,blockstr,hash2,height); - if ( allocptr != 0 ) - free(allocptr); - return(0); - } else printf("blocklen.%d for hwm.%d height.%d %s\n",blocklen,virt->blocks.hwmchain.height,height,bits256_str(str,hash2)); - return(-1); -} - -int32_t basilisk_relay_unping(struct supernet_info *myinfo,uint8_t *data,int32_t maxlen,struct basilisk_relay *rp,int32_t i) -{ - uint8_t pingdelay; int32_t j,datalen = 0; uint32_t ipbits; - ipbits = rp->ipbits; - if ( maxlen < sizeof(ipbits)+1 ) - { - printf("unping error maxlen.%d is too small\n",maxlen); - return(-1); - } - datalen = iguana_rwnum(1,&data[datalen],sizeof(ipbits),&ipbits); - pingdelay = data[datalen++]; - for (j=0; jnumrelays; j++) - if ( myinfo->relays[j].ipbits == ipbits ) - { - datalen += baslisk_relay_report(myinfo,&data[datalen],maxlen-datalen,&rp->reported[j],pingdelay); - return(datalen); - } - datalen += baslisk_relay_report(myinfo,&data[datalen],maxlen-datalen,0,pingdelay); - return(datalen); -} - -void basilisk_respond_ping(struct supernet_info *myinfo,struct iguana_peer *addr,uint32_t senderipbits,uint8_t *data,int32_t datalen) -{ - int32_t diff,i,j,n,len = 0; struct iguana_info *btcd,*virt; char ipbuf[64],symbol[7]; struct basilisk_relay *rp; uint8_t numrelays,clen,serialized[256]; uint16_t sn; uint32_t numvirts,height,now = (uint32_t)time(NULL); - expand_ipbits(ipbuf,senderipbits); - btcd = iguana_coinfind("BTCD"); - for (i=0; inumrelays; i++) - { - rp = &myinfo->relays[i]; - rp->direct.pingdelay = 0; - if ( rp->ipbits == senderipbits ) - rp->lastping = now; - if ( rp->lastping == now ) - rp->direct.pingdelay = 1; - else - { - diff = (now - rp->lastping); - if ( diff < 0xff ) - rp->direct.pingdelay = diff; - } - } - numrelays = data[len++]; - len += iguana_rwvarint32(0,&data[len],&numvirts); - symbol[6] = 0; - for (i=0; inumrelays > 0 && addr != 0 && (virt= iguana_coinfind(symbol)) != 0 ) - { - if ( height > virt->longestchain ) - virt->longestchain = height; - if ( myinfo->numrelays > 0 && virt->blocks.hwmchain.height > height ) - { - diff = ((height % myinfo->numrelays) - myinfo->RELAYID); - diff *= diff; - diff++; - if ( (rand() % diff) == 0 ) - { - for (j=1; height+jblocks.hwmchain.height && j<3; j++) - basilisk_blocksend(myinfo,btcd,virt,addr,height+j); - } - } - } - } - for (i=0; i datalen ) - break; - if ( (n= basilisk_relay_unping(myinfo,&data[len],datalen-len,rp,i)) < 0 ) - break; - len += n; - } - if ( len <= datalen-sizeof(sn) ) - { - char src[16],dest[16],message[128]; bits256 hash; uint64_t amount; uint32_t timestamp; - len += iguana_rwnum(0,&data[len],sizeof(sn),&sn); - for (i=0; i %s) ",message,src,dstr(amount),dest); - } - } - if ( len != datalen ) - printf("PING got %d, processed.%d from (%s)\n",datalen,len,ipbuf); - else printf("\n"); - for (i=0; inumrelays; - for (iter=n=0; iter<2; iter++) - { - HASH_ITER(hh,myinfo->allcoins,virt,tmpcoin) - { - if ( virt != 0 && virt->virtualchain != 0 ) - { - if ( iter == 0 ) - n++; - else - { - memcpy(&data[datalen],virt->symbol,6), datalen += 6; - datalen += iguana_rwvarint32(1,&data[datalen],(uint32_t *)&virt->blocks.hwmchain.height); - } - } - } - if ( iter == 0 ) - datalen += iguana_rwvarint32(1,&data[datalen],&n); - } - for (i=0; inumrelays; i++) - datalen += basilisk_relay_ping(myinfo,&data[datalen],maxlen - datalen,&myinfo->relays[i]); - offset = datalen, datalen += sizeof(uint16_t); - i = 0; - now = (uint32_t)time(NULL); - portable_mutex_lock(&myinfo->DEX_mutex); - DL_FOREACH_SAFE(myinfo->DEX_quotes,item,tmp) - { - memcpy(&clen,&item[1],sizeof(clen)); - if ( datalen+clen < maxlen ) - { - memcpy(&data[datalen],&item[1],clen+1), datalen += (clen + 1); - i++; - } - iguana_rwnum(0,(void *)((long)&item[1] + 1),sizeof(timestamp),×tamp); - if ( now > timestamp + BASILISK_DEXDURATION ) - { - DL_DELETE(myinfo->DEX_quotes,item); - free(item); - } - } - portable_mutex_unlock(&myinfo->DEX_mutex); - sn = i; - iguana_rwnum(1,&data[offset],sizeof(sn),&sn); - for (i=0; iRELAYID >= 0 ) { - basilisk_respond_ping(myinfo,_addr,ipbits,data,datalen); + basilisk_ping_process(myinfo,_addr,ipbits,data,datalen); } } else @@ -966,23 +777,7 @@ void basilisks_loop(void *arg) //printf("my RELAYID.%d\n",myinfo->RELAYID); //portable_mutex_unlock(&myinfo->allcoins_mutex); if ( (rand() % 10) == 0 && myinfo->RELAYID >= 0 ) - { - struct iguana_peer *addr; struct basilisk_relay *rp; int32_t i,datalen=0; uint8_t data[32768]; // need bigger buffer - datalen = basilisk_relays_ping(myinfo,&data[sizeof(struct iguana_msghdr)],sizeof(data)-sizeof(struct iguana_msghdr)); - for (i=0; inumrelays; i++) - { - rp = &myinfo->relays[i]; - addr = 0; - if ( rp->ipbits == myinfo->myaddr.myipbits ) - basilisk_respond_ping(myinfo,0,myinfo->myaddr.myipbits,&data[sizeof(struct iguana_msghdr)],datalen); - else if ( (addr= iguana_peerfindipbits(btcd,rp->ipbits,1)) != 0 && addr->usock >= 0 ) - { - if ( iguana_queue_send(addr,0,data,"SuperNETPIN",datalen) <= 0 ) - printf("error sending %d to (%s)\n",datalen,addr->ipaddr); - //else printf("sent %d to (%s)\n",datalen,addr->ipaddr); - } - } - } + basilisk_ping_send(myinfo,btcd); } //fprintf(stderr,"i "); //for (i=0; iallcoins_mutex); portable_mutex_init(&myinfo->basilisk_mutex); portable_mutex_init(&myinfo->DEX_mutex); + portable_mutex_init(&myinfo->DEX_reqmutex); portable_mutex_init(&myinfo->gecko_mutex); myinfo->basilisks.launched = iguana_launch(iguana_coinfind("BTCD"),"basilisks_loop",basilisks_loop,myinfo,IGUANA_PERMTHREAD); } diff --git a/basilisk/basilisk.h b/basilisk/basilisk.h index 149494498..d4920bb4f 100755 --- a/basilisk/basilisk.h +++ b/basilisk/basilisk.h @@ -47,6 +47,14 @@ struct basilisk_info struct basilisk_value values[8192]; int32_t numvalues; }; +struct basilisk_request +{ + uint32_t crc,timestamp,requestid,quoteid; + uint64_t srcamount,destamount; + bits256 hash; + char src[8],dest[8],message[48]; +} __attribute__((packed)); + struct basilisk_relaystatus { uint8_t pingdelay; @@ -54,8 +62,8 @@ struct basilisk_relaystatus struct basilisk_relay { - bits256 pubkey; int32_t relayid,oldrelayid; uint32_t ipbits,lastping; - uint8_t pubkey33[33]; + bits256 pubkey; int32_t relayid,oldrelayid; uint32_t ipbits,lastping; uint8_t pubkey33[33]; + struct basilisk_request *requests; int32_t maxrequests,numrequests; struct basilisk_relaystatus direct,reported[BASILISK_MAXRELAYS]; }; diff --git a/basilisk/basilisk_CMD.c b/basilisk/basilisk_CMD.c index 36e53ae15..c94208799 100755 --- a/basilisk/basilisk_CMD.c +++ b/basilisk/basilisk_CMD.c @@ -124,40 +124,6 @@ void basilisk_request_goodbye(struct supernet_info *myinfo) free_json(valsobj); } -int32_t basilisk_rwDEXquote(int32_t rwflag,uint8_t *serialized,bits256 *hashp,char *src,uint64_t *amountp,char *dest,uint32_t *timestampp,char *message) -{ - int32_t len = 0; - len += iguana_rwnum(rwflag,&serialized[len],sizeof(*timestampp),timestampp); - len += iguana_rwbignum(rwflag,&serialized[len],sizeof(*hashp),hashp->bytes); - len += iguana_rwnum(rwflag,&serialized[len],sizeof(*amountp),amountp); - len += iguana_rwvarstr(rwflag,&serialized[len],8,src); - len += iguana_rwvarstr(rwflag,&serialized[len],8,dest); - if ( message == 0 ) - message = ""; - len += iguana_rwvarstr(rwflag,&serialized[len],128,message); - return(len); -} - -char *basilisk_respond_instantdex(struct supernet_info *myinfo,char *CMD,void *addr,char *remoteaddr,uint32_t basilisktag,cJSON *valsobj,uint8_t *data,int32_t datalen,bits256 hash,int32_t from_basilisk) -{ - char *dest,*src,*retstr=0; int32_t len; uint32_t timestamp; uint64_t satoshis; uint8_t serialized[64]; struct queueitem *item; - if ( (dest= jstr(valsobj,"dest")) != 0 && (src= jstr(valsobj,"src")) != 0 && (satoshis= j64bits(valsobj,"satoshis")) != 0 ) - { - char str[65]; printf("DEX.(%s %.8f) -> %s %s\n",src,dstr(satoshis),dest,bits256_str(str,hash)); - timestamp = (uint32_t)time(NULL); - len = basilisk_rwDEXquote(1,serialized+1,&hash,src,&satoshis,dest,×tamp,jstr(valsobj,"msg")); - serialized[0] = len; - item = calloc(1,sizeof(*item) + len + 1); - memcpy(&item[1],serialized,len + 1); - portable_mutex_lock(&myinfo->DEX_mutex); - DL_APPEND(myinfo->DEX_quotes,item); - portable_mutex_unlock(&myinfo->DEX_mutex); - retstr = clonestr("{\"result\":\"DEX quote added\"}"); - } - //instantdex_quotep2p(myinfo,0,addr,data,datalen); - return(retstr); -} - char *basilisk_respond_addrelay(struct supernet_info *myinfo,char *CMD,void *addr,char *remoteaddr,uint32_t basilisktag,cJSON *valsobj,uint8_t *data,int32_t datalen,bits256 hash,int32_t from_basilisk) { char *ipaddr,*retstr=0; diff --git a/basilisk/basilisk_DEX.c b/basilisk/basilisk_DEX.c new file mode 100755 index 000000000..ac212b97d --- /dev/null +++ b/basilisk/basilisk_DEX.c @@ -0,0 +1,449 @@ +/****************************************************************************** + * 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. * + * * + ******************************************************************************/ + +// included from basilisk.c + +int32_t basilisk_rwDEXquote(int32_t rwflag,uint8_t *serialized,struct basilisk_request *rp) +{ + int32_t len = 0; + len += iguana_rwnum(rwflag,&serialized[len],sizeof(rp->crc),&rp->crc); // must be 1st + len += iguana_rwnum(rwflag,&serialized[len],sizeof(rp->timestamp),&rp->timestamp); // must be 2nd + len += iguana_rwnum(rwflag,&serialized[len],sizeof(rp->requestid),&rp->requestid); + len += iguana_rwnum(rwflag,&serialized[len],sizeof(rp->quoteid),&rp->quoteid); + len += iguana_rwnum(rwflag,&serialized[len],sizeof(rp->srcamount),&rp->srcamount); + len += iguana_rwnum(rwflag,&serialized[len],sizeof(rp->destamount),&rp->destamount); + len += iguana_rwbignum(rwflag,&serialized[len],sizeof(rp->hash),rp->hash.bytes); + len += iguana_rwvarstr(rwflag,&serialized[len],sizeof(rp->src)-1,rp->src); + len += iguana_rwvarstr(rwflag,&serialized[len],sizeof(rp->src)-1,rp->dest); + len += iguana_rwvarstr(rwflag,&serialized[len],128,rp->message); + return(len); +} + +int32_t basilisk_request_enqueue(struct supernet_info *myinfo,bits256 hash,char *src,uint64_t srcamount,char *dest,uint64_t destamount,char *message,uint32_t requestid,uint32_t quoteid) +{ + uint8_t serialized[256]; int32_t len; struct queueitem *item; struct basilisk_request R; + memset(&R,0,sizeof(R)); + R.timestamp = (uint32_t)time(NULL); + R.hash = hash; + R.srcamount = srcamount; + R.destamount = destamount; + R.requestid = requestid; + R.quoteid = quoteid; + strncpy(R.src,src,sizeof(R.src)-1); + strncpy(R.dest,dest,sizeof(R.dest)-1); + if ( message != 0 ) + strncpy(R.message,message,sizeof(R.message)-1); + R.crc = calc_crc32(0,(void *)((long)&R + sizeof(R.crc)),sizeof(R) - sizeof(R.crc)); + len = basilisk_rwDEXquote(1,serialized+1,&R); + serialized[0] = len; + if ( (item= calloc(1,sizeof(*item) + len + 1)) != 0 ) + { + memcpy(&item[1],serialized,len + 1); + portable_mutex_lock(&myinfo->DEX_mutex); + DL_APPEND(myinfo->DEX_quotes,item); + portable_mutex_unlock(&myinfo->DEX_mutex); + return(0); + } + return(-1); +} + +cJSON *basilisk_requestjson(uint32_t relaybits,struct basilisk_request *rp) +{ + char ipaddr[64]; cJSON *item = cJSON_CreateObject(); + expand_ipbits(ipaddr,relaybits); + jaddstr(item,"relay",ipaddr); + jaddbits256(item,"hash",rp->hash); + jaddstr(item,"src",rp->src); + if ( rp->srcamount != 0 ) + jaddnum(item,"srcamount",dstr(rp->srcamount)); + jaddstr(item,"dest",rp->dest); + if ( rp->destamount != 0 ) + jaddnum(item,"destamount",dstr(rp->destamount)); + jaddnum(item,"timestamp",rp->timestamp); + jaddnum(item,"requestid",rp->requestid); + jaddnum(item,"quoteid",rp->quoteid); + if ( rp->message[0] != 0 ) + jaddstr(item,"message",rp->message); + return(item); +} + +struct basilisk_request *basilisk_parsejson(struct basilisk_request *rp,cJSON *reqjson) +{ + memset(rp,0,sizeof(*rp)); + rp->hash = jbits256(reqjson,"hash"); + rp->srcamount = j64bits(reqjson,"srcamount"); + rp->destamount = j64bits(reqjson,"destamount"); + rp->requestid = juint(reqjson,"requestid"); + rp->quoteid = juint(reqjson,"quoteid"); + rp->timestamp = juint(reqjson,"timestamp"); + safecopy(rp->src,jstr(reqjson,"src"),sizeof(rp->src)); + safecopy(rp->dest,jstr(reqjson,"dest"),sizeof(rp->dest)); + safecopy(rp->message,jstr(reqjson,"message"),sizeof(rp->message)); + rp->crc = calc_crc32(0,(void *)((long)rp + sizeof(rp->crc)),sizeof(*rp) - sizeof(rp->crc)); + return(rp); +} + +char *basilisk_choose(struct supernet_info *myinfo,bits256 hash,struct basilisk_request *other,uint64_t destamount,uint32_t quoteid) +{ + cJSON *retjson; + if ( basilisk_request_enqueue(myinfo,hash,other->src,other->srcamount,other->dest,destamount,"start",other->requestid,quoteid) == 0 ) + { + if ( bits256_cmp(hash,myinfo->myaddr.persistent) == 0 ) + { + printf("START thread to complete %u/%u for (%s %.8f) <- (%s %.8f)\n",other->requestid,quoteid,other->src,dstr(other->srcamount),other->dest,dstr(other->destamount)); + // other, myinfo->myaddr.persistent, destamount, quoteid + return(clonestr("{\"result\":\"started atomic thread\"}")); + } + else + { + retjson = cJSON_CreateObject(); + jaddstr(retjson,"result","need to start atomic thread"); + jadd(retjson,"other",basilisk_requestjson(myinfo->myaddr.myipbits,other)); + return(jprint(retjson,1)); + } + } else return(clonestr("{\"error\":\"couldnt enqueue chosen\"}")); +} + +struct basilisk_relay *basilisk_request_ensure(struct supernet_info *myinfo,uint32_t senderipbits,int32_t numrequests) +{ + int32_t j; struct basilisk_relay *relay = 0; + if ( (j= basilisk_relayid(myinfo,senderipbits)) >= 0 ) + { + relay = &myinfo->relays[j]; + if ( numrequests > relay->maxrequests ) + { + relay->maxrequests = numrequests; + relay->requests = realloc(relay->requests,sizeof(*relay->requests) * numrequests); + } + relay->numrequests = 0; + } + return(relay); +} + +int32_t basilisk_ping_processDEX(struct supernet_info *myinfo,uint32_t senderipbits,uint8_t *data,int32_t datalen) +{ + int32_t i,len=0; struct basilisk_relay *relay; struct basilisk_request R; uint8_t clen,serialized[256]; uint16_t sn; uint32_t crc; + portable_mutex_lock(&myinfo->DEX_reqmutex); + len += iguana_rwnum(0,&data[len],sizeof(sn),&sn); + if ( (relay= basilisk_request_ensure(myinfo,senderipbits,sn)) != 0 ) + { + for (i=0; inumrequests < relay->maxrequests ) + { + memcpy(serialized,&data[len],clen); + len += basilisk_rwDEXquote(0,serialized,&R); + crc = calc_crc32(0,(void *)((long)&R + sizeof(R.crc)),sizeof(R) - sizeof(R.crc)); + if ( crc == R.crc ) + { + relay->requests[relay->numrequests++] = R; + printf("(%s (%s %.8f) -> (%s %.8f) r.%u q.%u) ",R.message,R.src,dstr(R.srcamount),R.dest,dstr(R.destamount),R.requestid,R.quoteid); + } else printf("crc.%08x error vs %08x\n",crc,R.crc); + } else printf("relay num.%d >= max.%d\n",relay->numrequests,relay->maxrequests); + } else len += clen; + } + } + else + { + for (i=0; iDEX_reqmutex); + return(len); +} + +int32_t basilisk_ping_genDEX(struct supernet_info *myinfo,uint8_t *data,int32_t maxlen) +{ + struct queueitem *item,*tmp; uint8_t clen; int32_t i,datalen = 0; uint16_t sn; uint32_t timestamp,now; + datalen += sizeof(uint16_t); + i = 0; + now = (uint32_t)time(NULL); + portable_mutex_lock(&myinfo->DEX_mutex); + DL_FOREACH_SAFE(myinfo->DEX_quotes,item,tmp) + { + memcpy(&clen,&item[1],sizeof(clen)); + if ( datalen+clen < maxlen ) + { + memcpy(&data[datalen],&item[1],clen+1), datalen += (clen + 1); + i++; + } + iguana_rwnum(0,(void *)((long)&item[1] + 1),sizeof(timestamp),×tamp); + if ( now > timestamp + BASILISK_DEXDURATION ) + { + DL_DELETE(myinfo->DEX_quotes,item); + free(item); + } + } + portable_mutex_unlock(&myinfo->DEX_mutex); + sn = i; + iguana_rwnum(1,data,sizeof(sn),&sn); // fill in at beginning + return(datalen); +} + +char *basilisk_respond_incoming(struct supernet_info *myinfo,bits256 hash,uint32_t requestid,uint32_t quoteid) +{ + int32_t i,j,n,k,m; struct basilisk_relay *relay; cJSON *retjson,*array; struct basilisk_request requests[BASILISK_MAXRELAYS],*rp; + array = cJSON_CreateArray(); + portable_mutex_lock(&myinfo->DEX_reqmutex); + for (j=m=0; jnumrelays; j++) + { + relay = &myinfo->relays[j]; + if ( (n= relay->numrequests) > 0 ) + { + for (i=0; irequests[i]; + if ( (requestid == 0 || rp->requestid == requestid) && ((quoteid == 0 && rp->quoteid != 0) || quoteid == rp->quoteid) ) + { + for (k=0; kipbits,rp)); + } + } + } + } + } + portable_mutex_unlock(&myinfo->DEX_reqmutex); + retjson = cJSON_CreateObject(); + jadd(retjson,"result",array); + return(jprint(retjson,1)); +} + +char *basilisk_respond_choose(struct supernet_info *myinfo,bits256 hash,uint32_t requestid,uint64_t destamount) +{ + int32_t i,n,j,alreadythere = 0; uint32_t quoteid; char *retstr; struct basilisk_relay *relay; struct basilisk_request *rp=0; + quoteid = (requestid ^ hash.uints[0]); + portable_mutex_lock(&myinfo->DEX_reqmutex); + for (j=0; jnumrelays; j++) + { + relay = &myinfo->relays[j]; + if ( (n= relay->numrequests) > 0 ) + { + for (i=0; irequests[i].requestid == requestid ) + { + if ( relay->requests[i].quoteid == 0 ) + rp = &relay->requests[i]; + else if ( relay->requests[i].quoteid == quoteid ) + { + alreadythere = 1; + break; + } + } + } + } + if ( alreadythere != 0 ) + break; + } + if ( alreadythere == 0 ) + { + if ( rp == 0 ) + retstr = clonestr("{\"error\":\"couldnt find to requestid to choose\"}"); + else retstr = basilisk_choose(myinfo,hash,rp,destamount,quoteid); + } else retstr = clonestr("{\"result\":\"quoteid already there\"}"); + portable_mutex_unlock(&myinfo->DEX_reqmutex); + return(retstr); +} + +// respond to incoming RID, CHS, DEX, QST + +char *basilisk_respond_RID(struct supernet_info *myinfo,char *CMD,void *addr,char *remoteaddr,uint32_t basilisktag,cJSON *valsobj,uint8_t *data,int32_t datalen,bits256 hash,int32_t from_basilisk) +{ + return(basilisk_respond_incoming(myinfo,hash,juint(valsobj,"requestid"),0)); +} + +char *basilisk_respond_QID(struct supernet_info *myinfo,char *CMD,void *addr,char *remoteaddr,uint32_t basilisktag,cJSON *valsobj,uint8_t *data,int32_t datalen,bits256 hash,int32_t from_basilisk) +{ + return(basilisk_respond_incoming(myinfo,hash,juint(valsobj,"requestid"),juint(valsobj,"quoteid"))); +} + +char *basilisk_respond_CHS(struct supernet_info *myinfo,char *CMD,void *addr,char *remoteaddr,uint32_t basilisktag,cJSON *valsobj,uint8_t *data,int32_t datalen,bits256 hash,int32_t from_basilisk) +{ + uint32_t requestid; uint64_t destamount; + if ( (requestid= juint(valsobj,"requestid")) != 0 && (destamount= j64bits(valsobj,"destamount")) != 0 ) + return(basilisk_respond_choose(myinfo,hash,requestid,destamount)); + return(clonestr("{\"error\":\"need nonzero requestid and quoteid\"}")); +} + +char *basilisk_respond_DEX(struct supernet_info *myinfo,char *CMD,void *addr,char *remoteaddr,uint32_t basilisktag,cJSON *valsobj,uint8_t *data,int32_t datalen,bits256 hash,int32_t from_basilisk) +{ + char *dest,*src,*retstr=0,buf[256]; uint32_t zero=0; uint64_t satoshis; + if ( (dest= jstr(valsobj,"dest")) != 0 && (src= jstr(valsobj,"src")) != 0 && (satoshis= j64bits(valsobj,"satoshis")) != 0 ) + { + char str[65]; printf("DEX.(%s %.8f) -> %s %s\n",src,dstr(satoshis),dest,bits256_str(str,hash)); + if ( basilisk_request_enqueue(myinfo,hash,src,satoshis,dest,0,jstr(valsobj,"msg"),basilisktag,zero) == 0 ) + { + sprintf(buf,"{\"result\":\"DEX request added\",\"request\":%u}",basilisktag); + retstr = clonestr(buf); + } else retstr = clonestr("{\"error\":\"DEX quote couldnt be created\"}"); + } + return(retstr); +} + +#include "../includes/iguana_apidefs.h" +#include "../includes/iguana_apideclares.h" + +ZERO_ARGS(InstantDEX,allcoins) +{ + struct iguana_info *tmp; cJSON *array,*retjson = cJSON_CreateObject(); + array = cJSON_CreateArray(); + HASH_ITER(hh,myinfo->allcoins,coin,tmp) + { + jaddistr(array,coin->symbol); + } + jadd(retjson,"coins",array); + return(jprint(retjson,1)); +} + +STRING_ARG(InstantDEX,available,source) +{ + if ( (coin= iguana_coinfind(source)) != 0 ) + { + if ( myinfo->expiration != 0 ) + return(bitcoinrpc_getbalance(myinfo,coin,json,remoteaddr,"*",coin->chain->minconfirms,1,1<<30)); + else return(clonestr("{\"error\":\"need to unlock wallet\"}")); + } else return(clonestr("{\"error\":\"specified coin is not active\"}")); +} + +THREE_STRINGS_AND_DOUBLE(InstantDEX,request,message,dest,source,amount) +{ + struct basilisk_request R; char *retstr; cJSON *vals = cJSON_CreateObject(); + jaddstr(vals,"dest",dest); + jaddstr(vals,"src",source); + if ( strlen(message) < sizeof(R.message) ) + jaddstr(vals,"msg",message); + jadd64bits(vals,"satoshis",amount * SATOSHIDEN); + retstr = basilisk_standardservice("DEX",myinfo,0,myinfo->myaddr.persistent,vals,"",1); + free_json(vals); + return(retstr); +} + +INT_ARG(InstantDEX,incoming,requestid) +{ + cJSON *vals; char *retstr; + if ( myinfo->RELAYID >= 0 ) + return(basilisk_respond_incoming(myinfo,myinfo->myaddr.persistent,requestid,0)); + else + { + vals = cJSON_CreateObject(); + jaddnum(vals,"requestid",requestid); + jaddbits256(vals,"hash",myinfo->myaddr.persistent); + retstr = basilisk_standardservice("RID",myinfo,0,myinfo->myaddr.persistent,vals,"",1); + free_json(vals); + return(retstr); + } +} + +TWO_INTS(InstantDEX,qstatus,requestid,quoteid) +{ + cJSON *vals; char *retstr; + if ( myinfo->RELAYID >= 0 ) + return(basilisk_respond_incoming(myinfo,myinfo->myaddr.persistent,requestid,quoteid)); + else + { + vals = cJSON_CreateObject(); + jaddnum(vals,"quoteid",quoteid); + jaddbits256(vals,"hash",myinfo->myaddr.persistent); + retstr = basilisk_standardservice("QST",myinfo,0,myinfo->myaddr.persistent,vals,"",1); + free_json(vals); + return(retstr); + } +} + +INT_AND_DOUBLE(InstantDEX,choose,requestid,destamount) +{ + cJSON *vals,*retjson; char *retstr; struct basilisk_request R,*other; uint32_t quoteid; + if ( myinfo->RELAYID >= 0 ) + return(basilisk_respond_choose(myinfo,myinfo->myaddr.persistent,requestid,destamount*SATOSHIDEN)); + else + { + quoteid = (requestid ^ myinfo->myaddr.persistent.uints[0]); + vals = cJSON_CreateObject(); + jaddnum(vals,"requestid",requestid); + jaddnum(vals,"quoteid",quoteid); + jadd64bits(vals,"destamount",destamount*SATOSHIDEN); + jaddbits256(vals,"hash",myinfo->myaddr.persistent); + if ( (retstr= basilisk_standardservice("CHS",myinfo,0,myinfo->myaddr.persistent,vals,"",1)) != 0 ) + { + if ( (retjson= cJSON_Parse(retstr)) != 0 ) + { + other = basilisk_parsejson(&R,jobj(retjson,"other")); + // other, myinfo->myaddr.persistent, destamount, quoteid + printf("START thread to complete %u/%u for (%s %.8f) <- (%s %.8f)\n",other->requestid,quoteid,other->src,dstr(other->srcamount),other->dest,dstr(other->destamount)); + free(retjson); + } + } + free_json(vals); + return(retstr); + } +} + +#include "../includes/iguana_apiundefs.h" + + +int32_t basilisk_request_pending(struct supernet_info *myinfo,struct basilisk_request *rp,uint32_t requestid) +{ + int32_t i,j,n,alreadystarted = 0; struct basilisk_relay *relay; uint32_t quoteid; + quoteid = (requestid ^ myinfo->myaddr.persistent.uints[0]); + portable_mutex_lock(&myinfo->DEX_reqmutex); + for (j=0; jnumrelays; j++) + { + relay = &myinfo->relays[j]; + if ( (n= relay->numrequests) > 0 ) + { + for (i=0; irequests[i].requestid == requestid && relay->requests[i].quoteid == quoteid ) + { + alreadystarted = 1; + break; + } + } + } + } + portable_mutex_unlock(&myinfo->DEX_reqmutex); + return(alreadystarted); +} + +void basilisk_request_check(struct supernet_info *myinfo,struct basilisk_request *rp) +{ + double retvals[4],aveprice; struct basilisk_request R; struct iguana_info *src,*dest; char message[128]; uint32_t quoteid; + if ( (src= iguana_coinfind(rp->src)) != 0 && (dest= iguana_coinfind(rp->dest)) != 0 ) + { + if ( basilisk_request_pending(myinfo,&R,rp->requestid) == 0 ) + { + aveprice = instantdex_avehbla(myinfo,retvals,rp->src,rp->dest,dstr(rp->srcamount)); + quoteid = rp->requestid ^ myinfo->myaddr.persistent.uints[0]; + sprintf(message,"{\"price\":%.8f,\"requestid\":%u,\"quoteid\":%u}",aveprice,rp->requestid,quoteid); + if ( basilisk_request_enqueue(myinfo,myinfo->myaddr.persistent,rp->src,rp->srcamount*aveprice,rp->dest,rp->srcamount*aveprice,message,rp->requestid,quoteid) < 0 ) + printf("error creating quoteid\n"); + } + } +} + diff --git a/basilisk/basilisk_ping.c b/basilisk/basilisk_ping.c new file mode 100755 index 000000000..caf32605e --- /dev/null +++ b/basilisk/basilisk_ping.c @@ -0,0 +1,218 @@ +/****************************************************************************** + * 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. * + * * + ******************************************************************************/ + +// included from basilisk.c + +int32_t baslisk_relay_report(struct supernet_info *myinfo,uint8_t *data,int32_t maxlen,struct basilisk_relaystatus *reported,uint8_t pingdelay) +{ + if ( reported != 0 ) + { + reported->pingdelay = pingdelay; + } + return(0); +} + +int32_t basilisk_blocksend(struct supernet_info *myinfo,struct iguana_info *btcd,struct iguana_info *virt,struct iguana_peer *addr,int32_t height) +{ + int32_t blocklen; bits256 hash2; uint8_t *data = 0; char str[65],strbuf[8192],*blockstr,*allocptr = 0; struct iguana_block *block; + hash2 = iguana_blockhash(virt,height); + if ( (block= iguana_blockfind("bsend",virt,hash2)) != 0 ) + { + if ( block->height != height ) + { + printf("basilisk_blocksend: height.%d mismatch %d\n",block->height,height); + return(-1); + } + else if ( block->queued != 0 && block->req != 0 ) + { + memcpy(&blocklen,block->req,sizeof(blocklen)); + data = (uint8_t *)(void *)((long)block->req + sizeof(blocklen)); + } + } + if ( data == 0 ) + { + if ( (blocklen= iguana_peerblockrequest(virt,virt->blockspace,IGUANA_MAXPACKETSIZE,0,hash2,0)) > 0 ) + data = &virt->blockspace[sizeof(struct iguana_msghdr)]; + } + if ( data != 0 ) + { + blockstr = basilisk_addhexstr(&allocptr,0,strbuf,sizeof(strbuf),data,blocklen); + printf("RELAYID.%d send block.%d %s -> (%s) %s\n",myinfo->RELAYID,height,blockstr,addr->ipaddr,bits256_str(str,hash2)); + basilisk_blocksubmit(myinfo,btcd,virt,addr,blockstr,hash2,height); + if ( allocptr != 0 ) + free(allocptr); + return(0); + } else printf("blocklen.%d for hwm.%d height.%d %s\n",blocklen,virt->blocks.hwmchain.height,height,bits256_str(str,hash2)); + return(-1); +} + +int32_t basilisk_ping_processvirts(struct supernet_info *myinfo,struct iguana_info *btcd,struct iguana_peer *addr,uint8_t *data,int32_t datalen) +{ + int32_t diff,i,j,len = 0; struct iguana_info *virt; char symbol[7]; uint32_t numvirts,height; + len += iguana_rwvarint32(0,&data[len],&numvirts); + symbol[6] = 0; + for (i=0; inumrelays > 0 && addr != 0 && (virt= iguana_coinfind(symbol)) != 0 ) + { + if ( height > virt->longestchain ) + virt->longestchain = height; + if ( myinfo->numrelays > 0 && virt->blocks.hwmchain.height > height ) + { + diff = ((height % myinfo->numrelays) - myinfo->RELAYID); + diff *= diff; + diff++; + if ( (rand() % diff) == 0 ) + { + for (j=1; height+jblocks.hwmchain.height && j<3; j++) + basilisk_blocksend(myinfo,btcd,virt,addr,height+j); + } + } + } + } + return(len); +} + +int32_t basilisk_ping_genvirts(struct supernet_info *myinfo,uint8_t *data,int32_t maxlen) +{ + struct iguana_info *virt,*tmpcoin; int32_t iter,datalen = 0; uint32_t n; + for (iter=n=0; iter<2; iter++) + { + HASH_ITER(hh,myinfo->allcoins,virt,tmpcoin) + { + if ( virt != 0 && virt->virtualchain != 0 ) + { + if ( iter == 0 ) + n++; + else + { + memcpy(&data[datalen],virt->symbol,6), datalen += 6; + datalen += iguana_rwvarint32(1,&data[datalen],(uint32_t *)&virt->blocks.hwmchain.height); + } + } + } + if ( iter == 0 ) + datalen += iguana_rwvarint32(1,&data[datalen],&n); + } + return(datalen); +} + +int32_t basilisk_ping_genrelay(struct supernet_info *myinfo,uint8_t *data,int32_t maxlen,struct basilisk_relay *rp) +{ + int32_t datalen = 0; + datalen = iguana_rwnum(1,&data[datalen],sizeof(rp->ipbits),&rp->ipbits); + data[datalen++] = rp->direct.pingdelay; + return(datalen); +} + +int32_t basilisk_ping_processrelay(struct supernet_info *myinfo,uint8_t *data,int32_t maxlen,struct basilisk_relay *rp,int32_t i) +{ + uint8_t pingdelay; int32_t j,datalen = 0; uint32_t ipbits; + ipbits = rp->ipbits; + if ( maxlen < sizeof(ipbits)+1 ) + { + printf("unping error maxlen.%d is too small\n",maxlen); + return(-1); + } + datalen = iguana_rwnum(1,&data[datalen],sizeof(ipbits),&ipbits); + pingdelay = data[datalen++]; + if ( (j= basilisk_relayid(myinfo,ipbits)) >= 0 ) + { + datalen += baslisk_relay_report(myinfo,&data[datalen],maxlen-datalen,&rp->reported[j],pingdelay); + return(datalen); + } + printf("notified about unknown relay\n"); // parse it to match bytes sent + datalen += baslisk_relay_report(myinfo,&data[datalen],maxlen-datalen,0,pingdelay); + return(datalen); +} + +void basilisk_ping_process(struct supernet_info *myinfo,struct iguana_peer *addr,uint32_t senderipbits,uint8_t *data,int32_t datalen) +{ + int32_t diff,i,n,len = 0; struct iguana_info *btcd; char ipbuf[64]; struct basilisk_relay *rp; uint8_t numrelays; uint16_t sn; uint32_t now = (uint32_t)time(NULL); + expand_ipbits(ipbuf,senderipbits); + btcd = iguana_coinfind("BTCD"); + for (i=0; inumrelays; i++) + { + rp = &myinfo->relays[i]; + rp->direct.pingdelay = 0; + if ( rp->ipbits == senderipbits ) + rp->lastping = now; + if ( rp->lastping == now ) + rp->direct.pingdelay = 1; + else + { + diff = (now - rp->lastping); + if ( diff < 0xff ) + rp->direct.pingdelay = diff; + } + } + numrelays = data[len++]; + len += basilisk_ping_processvirts(myinfo,btcd,addr,&data[len],datalen - len); + for (i=0; i datalen ) + break; + if ( (n= basilisk_ping_processrelay(myinfo,&data[len],datalen-len,rp,i)) < 0 ) + break; + len += n; + } + if ( len <= datalen-sizeof(sn) ) + len += basilisk_ping_processDEX(myinfo,senderipbits,&data[len],datalen-len); + if ( len != datalen ) + printf("PING got %d, processed.%d from (%s)\n",datalen,len,ipbuf); + else printf("\n"); + //for (i=0; inumrelays; + datalen += basilisk_ping_genvirts(myinfo,&data[datalen],maxlen - datalen); + for (i=0; inumrelays; i++) + datalen += basilisk_ping_genrelay(myinfo,&data[datalen],maxlen - datalen,&myinfo->relays[i]); + datalen += basilisk_ping_genDEX(myinfo,&data[datalen],maxlen - datalen); + //for (i=0; ipingbuf == 0 ) + myinfo->pingbuf = malloc(IGUANA_MAXPACKETSIZE); + datalen = basilisk_ping_gen(myinfo,&myinfo->pingbuf[sizeof(struct iguana_msghdr)],IGUANA_MAXPACKETSIZE-sizeof(struct iguana_msghdr)); + for (i=0; inumrelays; i++) + { + rp = &myinfo->relays[i]; + addr = 0; + if ( rp->ipbits == myinfo->myaddr.myipbits ) + basilisk_ping_process(myinfo,0,myinfo->myaddr.myipbits,&myinfo->pingbuf[sizeof(struct iguana_msghdr)],datalen); + else if ( (addr= iguana_peerfindipbits(btcd,rp->ipbits,1)) != 0 && addr->usock >= 0 ) + { + if ( iguana_queue_send(addr,0,myinfo->pingbuf,"SuperNETPIN",datalen) <= 0 ) + printf("error sending %d to (%s)\n",datalen,addr->ipaddr); + //else printf("sent %d to (%s)\n",datalen,addr->ipaddr); + } + } +} + diff --git a/crypto777/bitcoind_RPC.c b/crypto777/bitcoind_RPC.c index f08488029..07c938fd3 100755 --- a/crypto777/bitcoind_RPC.c +++ b/crypto777/bitcoind_RPC.c @@ -16,7 +16,7 @@ #include "OS_portable.h" #ifdef __APPLE__ -//#define LIQUIDITY_PROVIDER +#define LIQUIDITY_PROVIDER #endif #ifdef LIQUIDITY_PROVIDER diff --git a/iguana/SuperNET_keys.c b/iguana/SuperNET_keys.c index de533e3ef..abf9d8794 100755 --- a/iguana/SuperNET_keys.c +++ b/iguana/SuperNET_keys.c @@ -86,11 +86,12 @@ char *SuperNET_parsemainargs(struct supernet_info *myinfo,bits256 *wallethashp,b exchanges = jarray(&n,json,"exchanges"); if ( jobj(json,"coins") != 0 ) coinargs = argjsonstr; - free_json(json); } } - if ( exchanges != 0 ) + //if ( exchanges != 0 ) exchanges777_init(myinfo,exchanges,0); + if ( json != 0 ) + free_json(json); *wallethashp = wallethash, *wallet2privp = wallet2priv; return(coinargs); } diff --git a/iguana/iguana777.c b/iguana/iguana777.c index a3f514f09..2d0781392 100755 --- a/iguana/iguana777.c +++ b/iguana/iguana777.c @@ -699,8 +699,6 @@ void iguana_callcoinstart(struct supernet_info *myinfo,struct iguana_info *coin) if ( (bp= iguana_bundlecreate(coin,&bundlei,0,*(bits256 *)coin->chain->genesis_hashdata,zero,1)) != 0 ) bp->bundleheight = 0; iguana_datachain_scan(myinfo,coin,CRYPTO777_RMD160); - void test_ping(struct supernet_info *myinfo); - test_ping(myinfo); } void iguana_coinloop(void *arg) diff --git a/iguana/iguana_exchanges.c b/iguana/iguana_exchanges.c index 1307eb1bd..77233cd20 100755 --- a/iguana/iguana_exchanges.c +++ b/iguana/iguana_exchanges.c @@ -971,7 +971,7 @@ void exchanges777_init(struct supernet_info *myinfo,cJSON *exchanges,int32_t sle int32_t i,n; cJSON *argjson,*item; struct exchange_info *exchange; if ( (exchange= exchanges777_find("bitcoin")) == 0 && (exchange= exchange_create("bitcoin",0)) != 0 ) myinfo->tradingexchanges[myinfo->numexchanges++] = exchange; - if ( 0 && exchanges != 0 ) + if ( exchanges != 0 ) { n = cJSON_GetArraySize(exchanges); for (i=0; itradingexchanges[myinfo->numexchanges++] = exchange; } } - if ( 0 ) + if ( 1 ) { argjson = cJSON_CreateObject(); for (i=0; iname,dir,numquotes); for (i=0; iexpiration != 0 ) - return(bitcoinrpc_getbalance(myinfo,coin,json,remoteaddr,"*",coin->chain->minconfirms,1,1<<30)); - else return(clonestr("{\"error\":\"need to unlock wallet\"}")); - } else return(clonestr("{\"error\":\"specified coin is not active\"}")); -} - -THREE_STRINGS_AND_DOUBLE(InstantDEX,request,message,dest,source,amount) -{ - char *retstr; cJSON *vals = cJSON_CreateObject(); - jaddstr(vals,"dest",dest); - jaddstr(vals,"src",source); - if ( strlen(message) < 128 ) - jaddstr(vals,"msg",message); - jadd64bits(vals,"satoshis",amount * SATOSHIDEN); - retstr = basilisk_standardservice("DEX",myinfo,0,myinfo->myaddr.persistent,vals,"",1); - free_json(vals); - return(retstr); -} - -INT_ARG(InstantDEX,incoming,requestid) -{ - return(clonestr("{\"result\":\"this will return array of incoming request objects\"}")); -} - -INT_ARG(InstantDEX,choose,quoteid) -{ - return(clonestr("{\"result\":\"this will choose one of the incoming requests and cancel the rest\"}")); -} - -INT_ARG(InstantDEX,qstatus,quoteid) -{ - return(clonestr("{\"result\":\"this will return status of pending quote\"}")); -} - #include "../includes/iguana_apiundefs.h" diff --git a/iguana/iguana_json.c b/iguana/iguana_json.c index eca450441..912900838 100755 --- a/iguana/iguana_json.c +++ b/iguana/iguana_json.c @@ -112,6 +112,7 @@ cJSON *SuperNET_helpjson() #define IGUANA_HELP_I(agent,name,val) array = helpjson(IGUANA_ARGS,#agent,#name,helparray(cJSON_CreateArray(),helpitem(#val,"int"))) #define IGUANA_HELP_II(agent,name,val,val2) array = helpjson(IGUANA_ARGS,#agent,#name,helparray2(cJSON_CreateArray(),helpitem(#val,"int"),helpitem(#val2,"int"))) +#define IGUANA_HELP_ID(agent,name,val,val2) array = helpjson(IGUANA_ARGS,#agent,#name,helparray2(cJSON_CreateArray(),helpitem(#val,"int"),helpitem(#val2,"float"))) #define IGUANA_HELP_IA(agent,name,val,obj) array = helpjson(IGUANA_ARGS,#agent,#name,helparray2(cJSON_CreateArray(),helpitem(#val,"int"),helpitem(#obj,"array"))) #define IGUANA_HELP_IIA(agent,name,val,val2,obj) array = helpjson(IGUANA_ARGS,#agent,#name,helparray3(cJSON_CreateArray(),helpitem(#val,"int"),helpitem(#val2,"int"),helpitem(#obj,"array"))) #define IGUANA_HELP_III(agent,name,val,val2,val3) array = helpjson(IGUANA_ARGS,#agent,#name,helparray3(cJSON_CreateArray(),helpitem(#val,"int"),helpitem(#val2,"int"),helpitem(#val3,"int"))) @@ -142,6 +143,7 @@ cJSON *SuperNET_helpjson() // API functions #define ZERO_ARGS IGUANA_HELP0 #define INT_ARG IGUANA_HELP_I +#define INT_AND_DOUBLE IGUANA_HELP_ID #define TWO_INTS IGUANA_HELP_II #define STRING_ARG IGUANA_HELP_S #define TWO_STRINGS IGUANA_HELP_SS @@ -932,6 +934,7 @@ char *SuperNET_parser(struct supernet_info *myinfo,char *agentstr,char *method,c #define IGUANA_DISPATCH0(agent,name) else if ( strcmp(#agent,agentstr) == 0 && strcmp(method,#name) == 0 ) return(agent ## _ ## name(IGUANA_ARGS)) #define IGUANA_DISPATCH_S(agent,name,str) else if ( strcmp(#agent,agentstr) == 0 && strcmp(method,#name) == 0 ) return(agent ## _ ## name(IGUANA_ARGS,jstr(json,#str))) #define IGUANA_DISPATCH_SS(agent,name,str,str2) else if ( strcmp(#agent,agentstr) == 0 && strcmp(method,#name) == 0 ) return(agent ## _ ## name(IGUANA_ARGS,jstr(json,#str),jstr(json,#str2))) +#define IGUANA_DISPATCH_ID(agent,name,dval,val) else if ( strcmp(#agent,agentstr) == 0 && strcmp(method,#name) == 0 ) return(agent ## _ ## name(IGUANA_ARGS,jdouble(json,#dval),jdouble(json,#val))) #define IGUANA_DISPATCH_SD(agent,name,str,val) else if ( strcmp(#agent,agentstr) == 0 && strcmp(method,#name) == 0 ) return(agent ## _ ## name(IGUANA_ARGS,jstr(json,#str),jdouble(json,#val))) #define IGUANA_DISPATCH_SSS(agent,name,str,str2,str3) else if ( strcmp(#agent,agentstr) == 0 && strcmp(method,#name) == 0 ) return(agent ## _ ## name(IGUANA_ARGS,jstr(json,#str),jstr(json,#str2),jstr(json,#str3))) #define IGUANA_DISPATCH_SSSS(agent,name,str,str2,str3,str4) else if ( strcmp(#agent,agentstr) == 0 && strcmp(method,#name) == 0 ) return(agent ## _ ## name(IGUANA_ARGS,jstr(json,#str),jstr(json,#str2),jstr(json,#str3),jstr(json,#str4))) @@ -985,6 +988,7 @@ char *SuperNET_parser(struct supernet_info *myinfo,char *agentstr,char *method,c // API functions #define ZERO_ARGS IGUANA_DISPATCH0 #define INT_ARG IGUANA_DISPATCH_I +#define INT_AND_DOUBLE IGUANA_DISPATCH_ID #define TWO_INTS IGUANA_DISPATCH_II #define STRING_ARG IGUANA_DISPATCH_S #define TWO_STRINGS IGUANA_DISPATCH_SS diff --git a/iguana/iguana_peers.c b/iguana/iguana_peers.c index 55a50060b..b7322e4cd 100755 --- a/iguana/iguana_peers.c +++ b/iguana/iguana_peers.c @@ -639,9 +639,13 @@ void _iguana_processmsg(struct iguana_info *coin,int32_t usock,struct iguana_pee myfree(buf,len); return; } - int32_t i; for (i=0; iipaddr,len); + static uint32_t counter; + if ( counter++ < 10 ) + { + int32_t i; for (i=0; iipaddr,len); + } //addr->dead = 1; } // printf("%s recv error on hdr errno.%d (%s) -> zombify\n",addr->ipaddr,-recvlen,strerror(-recvlen)); diff --git a/iguana/iguana_recv.c b/iguana/iguana_recv.c index 31462f3fa..a16b3b286 100755 --- a/iguana/iguana_recv.c +++ b/iguana/iguana_recv.c @@ -1124,7 +1124,7 @@ struct iguana_bundlereq *iguana_recvblock(struct iguana_info *coin,struct iguana if ( _iguana_chainlink(coin,block) == 0 ) { next = block; - for (i=n=0; ichain->bundlesize && n == 0; i++) + for (i=n=0; ichain->bundlesize && n < 60; i++) { if ( (block= iguana_blockfind("recvblock",coin,block->RO.prev_block)) == 0 ) break; diff --git a/iguana/tests/aveprice b/iguana/tests/aveprice new file mode 100755 index 000000000..cc176176e --- /dev/null +++ b/iguana/tests/aveprice @@ -0,0 +1,2 @@ +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"tradebot\",\"method\":\"aveprice\",\"base\":\"BTCD\",\"rel\":\"BTC\",\"basevolume\":1.0}" + diff --git a/includes/iguana_apideclares.h b/includes/iguana_apideclares.h index 930e3b6c5..8adf3386c 100755 --- a/includes/iguana_apideclares.h +++ b/includes/iguana_apideclares.h @@ -17,8 +17,8 @@ ZERO_ARGS(InstantDEX,allcoins); STRING_ARG(InstantDEX,available,source); THREE_STRINGS_AND_DOUBLE(InstantDEX,request,message,dest,source,amount); INT_ARG(InstantDEX,incoming,requestid); -INT_ARG(InstantDEX,choose,quoteid); -INT_ARG(InstantDEX,qstatus,quoteid); +INT_AND_DOUBLE(InstantDEX,choose,requestid,destamount); +TWO_INTS(InstantDEX,qstatus,requestid,quoteid); HASH_ARRAY_STRING(basilisk,genesis_opreturn,hash,vals,hexstr); diff --git a/includes/iguana_apidefs.h b/includes/iguana_apidefs.h index 2e37feb8b..7668e1475 100755 --- a/includes/iguana_apidefs.h +++ b/includes/iguana_apidefs.h @@ -16,6 +16,7 @@ #define IGUANA_CFUNC_IA(agent,name,val,array) char *agent ## _ ## name(IGUANA_ARGS,int32_t val,cJSON *array) #define IGUANA_CFUNC_IAS(agent,name,val,array,str) char *agent ## _ ## name(IGUANA_ARGS,int32_t val,cJSON *array,char *str) #define IGUANA_CFUNC_II(agent,name,val,val2) char *agent ## _ ## name(IGUANA_ARGS,int32_t val,int32_t val2) +#define IGUANA_CFUNC_ID(agent,name,val,val2) char *agent ## _ ## name(IGUANA_ARGS,int32_t val,double val2) #define IGUANA_CFUNC_III(agent,name,val,val2,val3) char *agent ## _ ## name(IGUANA_ARGS,int32_t val,int32_t val2,int32_t val3) #define IGUANA_CFUNC_SIII(agent,name,str,val,val2,val3) char *agent ## _ ## name(IGUANA_ARGS,char *str,int32_t val,int32_t val2,int32_t val3) #define IGUANA_CFUNC_IIA(agent,name,val,val2,array) char *agent ## _ ## name(IGUANA_ARGS,int32_t val,int32_t val2,cJSON *array) @@ -53,6 +54,7 @@ // API functions #define ZERO_ARGS IGUANA_CFUNC0 #define INT_ARG IGUANA_CFUNC_I +#define INT_AND_DOUBLE IGUANA_CFUNC_ID #define TWO_INTS IGUANA_CFUNC_II #define STRING_ARG IGUANA_CFUNC_S #define TWO_STRINGS IGUANA_CFUNC_SS diff --git a/includes/iguana_apiundefs.h b/includes/iguana_apiundefs.h index c69c0f2db..7f70ed381 100755 --- a/includes/iguana_apiundefs.h +++ b/includes/iguana_apiundefs.h @@ -17,6 +17,7 @@ #undef DOUBLE_ARG #undef ARRAY_OBJ_INT #undef STRING_AND_ARRAY +#undef INT_AND_DOUBLE #undef INT_AND_ARRAY #undef INT_ARRAY_STRING #undef TWO_ARRAYS diff --git a/includes/iguana_funcs.h b/includes/iguana_funcs.h index a6cf553c3..17c90f945 100755 --- a/includes/iguana_funcs.h +++ b/includes/iguana_funcs.h @@ -529,6 +529,7 @@ int32_t iguana_datachain_scan(struct supernet_info *myinfo,struct iguana_info *c void iguana_RTramchainalloc(char *fname,struct iguana_info *coin,struct iguana_bundle *bp); void iguana_update_balances(struct iguana_info *coin); void iguana_RTspendvectors(struct iguana_info *coin,struct iguana_bundle *bp); +double instantdex_avehbla(struct supernet_info *myinfo,double retvals[4],char *base,char *rel,double basevolume); #include "../includes/iguana_api.h" diff --git a/includes/iguana_structs.h b/includes/iguana_structs.h index 86789d567..027009dc7 100755 --- a/includes/iguana_structs.h +++ b/includes/iguana_structs.h @@ -463,12 +463,13 @@ struct supernet_info struct exchange_info *tradingexchanges[SUPERNET_MAXEXCHANGES]; int32_t numexchanges; struct iguana_waccount *wallet; struct iguana_info *allcoins; int32_t allcoins_being_added,allcoins_numvirts; - portable_mutex_t allcoins_mutex,gecko_mutex,basilisk_mutex,DEX_mutex; + portable_mutex_t allcoins_mutex,gecko_mutex,basilisk_mutex,DEX_mutex,DEX_reqmutex; + struct queueitem *DEX_quotes; void *ctx; + uint8_t *pingbuf; struct delayedPoW_info dPoW; struct basilisk_relay relays[BASILISK_MAXRELAYS]; int32_t numrelays,RELAYID; - struct queueitem *DEX_quotes; // compatibility bits256 pangea_category,instantdex_category; };