Browse Source

test

release/v0.1
jl777 9 years ago
parent
commit
fbadf74d51
  1. 240
      basilisk/basilisk.c
  2. 12
      basilisk/basilisk.h
  3. 34
      basilisk/basilisk_CMD.c
  4. 449
      basilisk/basilisk_DEX.c
  5. 218
      basilisk/basilisk_ping.c
  6. 2
      crypto777/bitcoind_RPC.c
  7. 5
      iguana/SuperNET_keys.c
  8. 2
      iguana/iguana777.c
  9. 4
      iguana/iguana_exchanges.c
  10. 45
      iguana/iguana_instantdex.c
  11. 4
      iguana/iguana_json.c
  12. 10
      iguana/iguana_peers.c
  13. 2
      iguana/iguana_recv.c
  14. 2
      iguana/tests/aveprice
  15. 4
      includes/iguana_apideclares.h
  16. 2
      includes/iguana_apidefs.h
  17. 1
      includes/iguana_apiundefs.h
  18. 1
      includes/iguana_funcs.h
  19. 5
      includes/iguana_structs.h

240
basilisk/basilisk.c

@ -378,12 +378,23 @@ char *basilisk_standardservice(char *CMD,struct supernet_info *myinfo,void *_add
return(retstr); return(retstr);
} }
int32_t basilisk_relayid(struct supernet_info *myinfo,uint32_t ipbits)
{
int32_t j;
for (j=0; j<myinfo->numrelays; j++)
if ( myinfo->relays[j].ipbits == ipbits )
return(j);
return(-1);
}
#include "basilisk_bitcoin.c" #include "basilisk_bitcoin.c"
#include "basilisk_nxt.c" #include "basilisk_nxt.c"
#include "basilisk_ether.c" #include "basilisk_ether.c"
#include "basilisk_waves.c" #include "basilisk_waves.c"
#include "basilisk_lisk.c" #include "basilisk_lisk.c"
#include "basilisk_CMD.c" #include "basilisk_CMD.c"
#include "basilisk_DEX.c"
#include "basilisk_ping.c"
#include "../includes/iguana_apidefs.h" #include "../includes/iguana_apidefs.h"
#include "../includes/iguana_apideclares.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; j<myinfo->numrelays; 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; i<myinfo->numrelays; 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; i<numvirts; i++)
{
memcpy(symbol,&data[len],6), len += 6;
len += iguana_rwvarint32(0,&data[len],&height);
printf("(%s %d).%p ",symbol,height,addr);
if ( myinfo->numrelays > 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+j<virt->blocks.hwmchain.height && j<3; j++)
basilisk_blocksend(myinfo,btcd,virt,addr,height+j);
}
}
}
}
for (i=0; i<numrelays; i++)
{
if ( len > 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<sn; i++)
{
clen = data[len++];
memcpy(serialized,&data[len],clen);
len += basilisk_rwDEXquote(0,serialized,&hash,src,&amount,dest,&timestamp,message);
printf("(%s (%s %.8f) -> %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; i<datalen; i++)
printf("%02x",data[i]);
printf(" <- input ping from.(%s) numrelays.%d numvirts.%d\n",ipbuf,numrelays,numvirts);
}
int32_t basilisk_relays_ping(struct supernet_info *myinfo,uint8_t *data,int32_t maxlen)
{
struct iguana_info *virt,*tmpcoin; struct queueitem *item,*tmp; uint8_t clen; int32_t i,iter,offset,datalen = 0; uint32_t n; uint16_t sn; uint32_t timestamp,now;
data[datalen++] = myinfo->numrelays;
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; i<myinfo->numrelays; 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),&timestamp);
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; i<datalen; i++)
printf("%02x",data[i]);
printf(" <- output ping sn.%d\n",sn);
return(datalen);
}
void test_ping(struct supernet_info *myinfo)
{
//uint8_t data[8192]; int32_t datalen;
//datalen = basilisk_relays_ping(myinfo,data,sizeof(data));
//basilisk_respond_ping(myinfo,0,0,data,datalen);
}
void basilisk_msgprocess(struct supernet_info *myinfo,void *_addr,uint32_t senderipbits,char *type,uint32_t basilisktag,uint8_t *data,int32_t datalen) void basilisk_msgprocess(struct supernet_info *myinfo,void *_addr,uint32_t senderipbits,char *type,uint32_t basilisktag,uint8_t *data,int32_t datalen)
{ {
cJSON *valsobj; char *symbol,*retstr=0,remoteaddr[64],CMD[4],cmd[4]; int32_t height,origlen,from_basilisk,i,timeoutmillis,flag,numrequired,jsonlen; uint8_t *origdata; struct iguana_info *coin=0; bits256 hash; struct iguana_peer *addr = _addr; cJSON *valsobj; char *symbol,*retstr=0,remoteaddr[64],CMD[4],cmd[4]; int32_t height,origlen,from_basilisk,i,timeoutmillis,flag,numrequired,jsonlen; uint8_t *origdata; struct iguana_info *coin=0; bits256 hash; struct iguana_peer *addr = _addr;
@ -783,7 +591,10 @@ void basilisk_msgprocess(struct supernet_info *myinfo,void *_addr,uint32_t sende
// unencrypted low level functions, used by higher level protocols and virtual network funcs // unencrypted low level functions, used by higher level protocols and virtual network funcs
{ (void *)"ADD", &basilisk_respond_addrelay }, // relays register with each other bus { (void *)"ADD", &basilisk_respond_addrelay }, // relays register with each other bus
//{ (void *)"RLY", &basilisk_respond_relays }, //{ (void *)"RLY", &basilisk_respond_relays },
{ (void *)"DEX", &basilisk_respond_instantdex }, { (void *)"DEX", &basilisk_respond_DEX },
{ (void *)"RID", &basilisk_respond_RID },
{ (void *)"CHS", &basilisk_respond_CHS },
{ (void *)"QID", &basilisk_respond_QID },
// encrypted data for jumblr // encrypted data for jumblr
{ (void *)"HOP", &basilisk_respond_forward }, // message forwarding { (void *)"HOP", &basilisk_respond_forward }, // message forwarding
@ -920,7 +731,7 @@ void basilisk_p2p(void *_myinfo,void *_addr,char *senderip,uint8_t *data,int32_t
{ {
if ( strcmp(type,"PIN") == 0 && myinfo->RELAYID >= 0 ) if ( strcmp(type,"PIN") == 0 && myinfo->RELAYID >= 0 )
{ {
basilisk_respond_ping(myinfo,_addr,ipbits,data,datalen); basilisk_ping_process(myinfo,_addr,ipbits,data,datalen);
} }
} }
else else
@ -966,23 +777,7 @@ void basilisks_loop(void *arg)
//printf("my RELAYID.%d\n",myinfo->RELAYID); //printf("my RELAYID.%d\n",myinfo->RELAYID);
//portable_mutex_unlock(&myinfo->allcoins_mutex); //portable_mutex_unlock(&myinfo->allcoins_mutex);
if ( (rand() % 10) == 0 && myinfo->RELAYID >= 0 ) if ( (rand() % 10) == 0 && myinfo->RELAYID >= 0 )
{ basilisk_ping_send(myinfo,btcd);
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; i<myinfo->numrelays; 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);
}
}
}
} }
//fprintf(stderr,"i "); //fprintf(stderr,"i ");
//for (i=0; i<IGUANA_MAXCOINS; i++) //for (i=0; i<IGUANA_MAXCOINS; i++)
@ -999,6 +794,7 @@ void basilisks_init(struct supernet_info *myinfo)
portable_mutex_init(&myinfo->allcoins_mutex); portable_mutex_init(&myinfo->allcoins_mutex);
portable_mutex_init(&myinfo->basilisk_mutex); portable_mutex_init(&myinfo->basilisk_mutex);
portable_mutex_init(&myinfo->DEX_mutex); portable_mutex_init(&myinfo->DEX_mutex);
portable_mutex_init(&myinfo->DEX_reqmutex);
portable_mutex_init(&myinfo->gecko_mutex); portable_mutex_init(&myinfo->gecko_mutex);
myinfo->basilisks.launched = iguana_launch(iguana_coinfind("BTCD"),"basilisks_loop",basilisks_loop,myinfo,IGUANA_PERMTHREAD); myinfo->basilisks.launched = iguana_launch(iguana_coinfind("BTCD"),"basilisks_loop",basilisks_loop,myinfo,IGUANA_PERMTHREAD);
} }

12
basilisk/basilisk.h

@ -47,6 +47,14 @@ struct basilisk_info
struct basilisk_value values[8192]; int32_t numvalues; 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 struct basilisk_relaystatus
{ {
uint8_t pingdelay; uint8_t pingdelay;
@ -54,8 +62,8 @@ struct basilisk_relaystatus
struct basilisk_relay struct basilisk_relay
{ {
bits256 pubkey; int32_t relayid,oldrelayid; uint32_t ipbits,lastping; bits256 pubkey; int32_t relayid,oldrelayid; uint32_t ipbits,lastping; uint8_t pubkey33[33];
uint8_t pubkey33[33]; struct basilisk_request *requests; int32_t maxrequests,numrequests;
struct basilisk_relaystatus direct,reported[BASILISK_MAXRELAYS]; struct basilisk_relaystatus direct,reported[BASILISK_MAXRELAYS];
}; };

34
basilisk/basilisk_CMD.c

@ -124,40 +124,6 @@ void basilisk_request_goodbye(struct supernet_info *myinfo)
free_json(valsobj); 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,&timestamp,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 *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; char *ipaddr,*retstr=0;

449
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; i<sn; i++)
{
clen = data[len++];
if ( len+clen <= datalen )
{
if ( relay->numrequests < 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; i<sn; i++)
{
if ( len+clen <= datalen )
{
clen = data[len++];
len += clen;
}
}
}
portable_mutex_unlock(&myinfo->DEX_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),&timestamp);
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; j<myinfo->numrelays; j++)
{
relay = &myinfo->relays[j];
if ( (n= relay->numrequests) > 0 )
{
for (i=0; i<n; i++)
{
rp = &relay->requests[i];
if ( (requestid == 0 || rp->requestid == requestid) && ((quoteid == 0 && rp->quoteid != 0) || quoteid == rp->quoteid) )
{
for (k=0; k<m; k++)
if ( memcmp(&requests[k],rp,sizeof(requests[k])) == 0 )
break;
if ( k == m )
{
requests[m++] = *rp;
jaddi(array,basilisk_requestjson(relay->ipbits,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; j<myinfo->numrelays; j++)
{
relay = &myinfo->relays[j];
if ( (n= relay->numrequests) > 0 )
{
for (i=0; i<n; i++)
{
if ( relay->requests[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; j<myinfo->numrelays; j++)
{
relay = &myinfo->relays[j];
if ( (n= relay->numrequests) > 0 )
{
for (i=0; i<n; i++)
{
if ( relay->requests[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");
}
}
}

218
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; i<numvirts; i++)
{
memcpy(symbol,&data[len],6), len += 6;
len += iguana_rwvarint32(0,&data[len],&height);
printf("(%s %d).%p ",symbol,height,addr);
if ( myinfo->numrelays > 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+j<virt->blocks.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; i<myinfo->numrelays; 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<numrelays; i++)
{
if ( len > 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; i<datalen; i++)
// printf("%02x",data[i]);
//printf(" <- input ping from.(%s) numrelays.%d numvirts.%d\n",ipbuf,numrelays,numvirts);
}
int32_t basilisk_ping_gen(struct supernet_info *myinfo,uint8_t *data,int32_t maxlen)
{
int32_t i,datalen = 0;
data[datalen++] = myinfo->numrelays;
datalen += basilisk_ping_genvirts(myinfo,&data[datalen],maxlen - datalen);
for (i=0; i<myinfo->numrelays; 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; i<datalen; i++)
// printf("%02x",data[i]);
//printf(" <- output ping sn.%d\n",sn);
return(datalen);
}
void basilisk_ping_send(struct supernet_info *myinfo,struct iguana_info *btcd)
{
struct iguana_peer *addr; struct basilisk_relay *rp; int32_t i,datalen=0;
if ( myinfo->pingbuf == 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; i<myinfo->numrelays; 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);
}
}
}

2
crypto777/bitcoind_RPC.c

@ -16,7 +16,7 @@
#include "OS_portable.h" #include "OS_portable.h"
#ifdef __APPLE__ #ifdef __APPLE__
//#define LIQUIDITY_PROVIDER #define LIQUIDITY_PROVIDER
#endif #endif
#ifdef LIQUIDITY_PROVIDER #ifdef LIQUIDITY_PROVIDER

5
iguana/SuperNET_keys.c

@ -86,11 +86,12 @@ char *SuperNET_parsemainargs(struct supernet_info *myinfo,bits256 *wallethashp,b
exchanges = jarray(&n,json,"exchanges"); exchanges = jarray(&n,json,"exchanges");
if ( jobj(json,"coins") != 0 ) if ( jobj(json,"coins") != 0 )
coinargs = argjsonstr; coinargs = argjsonstr;
free_json(json);
} }
} }
if ( exchanges != 0 ) //if ( exchanges != 0 )
exchanges777_init(myinfo,exchanges,0); exchanges777_init(myinfo,exchanges,0);
if ( json != 0 )
free_json(json);
*wallethashp = wallethash, *wallet2privp = wallet2priv; *wallethashp = wallethash, *wallet2privp = wallet2priv;
return(coinargs); return(coinargs);
} }

2
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 ) if ( (bp= iguana_bundlecreate(coin,&bundlei,0,*(bits256 *)coin->chain->genesis_hashdata,zero,1)) != 0 )
bp->bundleheight = 0; bp->bundleheight = 0;
iguana_datachain_scan(myinfo,coin,CRYPTO777_RMD160); iguana_datachain_scan(myinfo,coin,CRYPTO777_RMD160);
void test_ping(struct supernet_info *myinfo);
test_ping(myinfo);
} }
void iguana_coinloop(void *arg) void iguana_coinloop(void *arg)

4
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; int32_t i,n; cJSON *argjson,*item; struct exchange_info *exchange;
if ( (exchange= exchanges777_find("bitcoin")) == 0 && (exchange= exchange_create("bitcoin",0)) != 0 ) if ( (exchange= exchanges777_find("bitcoin")) == 0 && (exchange= exchange_create("bitcoin",0)) != 0 )
myinfo->tradingexchanges[myinfo->numexchanges++] = exchange; myinfo->tradingexchanges[myinfo->numexchanges++] = exchange;
if ( 0 && exchanges != 0 ) if ( exchanges != 0 )
{ {
n = cJSON_GetArraySize(exchanges); n = cJSON_GetArraySize(exchanges);
for (i=0; i<n; i++) for (i=0; i<n; i++)
@ -981,7 +981,7 @@ void exchanges777_init(struct supernet_info *myinfo,cJSON *exchanges,int32_t sle
myinfo->tradingexchanges[myinfo->numexchanges++] = exchange; myinfo->tradingexchanges[myinfo->numexchanges++] = exchange;
} }
} }
if ( 0 ) if ( 1 )
{ {
argjson = cJSON_CreateObject(); argjson = cJSON_CreateObject();
for (i=0; i<sizeof(Exchange_funcs)/sizeof(*Exchange_funcs); i++) for (i=0; i<sizeof(Exchange_funcs)/sizeof(*Exchange_funcs); i++)

45
iguana/iguana_instantdex.c

@ -506,7 +506,7 @@ char *instantdex_sendcmd(struct supernet_info *myinfo,struct instantdex_offer *o
int32_t instantdex_updatesources(struct exchange_info *exchange,struct exchange_quote *sortbuf,int32_t n,int32_t max,int32_t ind,int32_t dir,struct exchange_quote *quotes,int32_t numquotes) int32_t instantdex_updatesources(struct exchange_info *exchange,struct exchange_quote *sortbuf,int32_t n,int32_t max,int32_t ind,int32_t dir,struct exchange_quote *quotes,int32_t numquotes)
{ {
int32_t i; struct exchange_quote *quote; int32_t i; struct exchange_quote *quote;
//printf("instantdex_updatesources update dir.%d numquotes.%d\n",dir,numquotes); //printf("instantdex_updatesources.%s update dir.%d numquotes.%d\n",exchange->name,dir,numquotes);
for (i=0; i<numquotes; i++) for (i=0; i<numquotes; i++)
{ {
quote = &quotes[i << 1]; quote = &quotes[i << 1];
@ -1718,48 +1718,5 @@ TWO_STRINGS(InstantDEX,events,base,rel)
//return(clonestr("[{\"h\":14,\"m\":44,\"s\":32,\"date\":1407877200000,\"bid\":30,\"ask\":35},{\"date\":1407877200000,\"bid\":40,\"ask\":44},{\"date\":1407877200000,\"bid\":49,\"ask\":45},{\"date\":1407877200000,\"ask\":28},{\"date\":1407877200000,\"ask\":52}]")); //return(clonestr("[{\"h\":14,\"m\":44,\"s\":32,\"date\":1407877200000,\"bid\":30,\"ask\":35},{\"date\":1407877200000,\"bid\":40,\"ask\":44},{\"date\":1407877200000,\"bid\":49,\"ask\":45},{\"date\":1407877200000,\"ask\":28},{\"date\":1407877200000,\"ask\":52}]"));
} }
ZERO_ARGS(InstantDEX,allcoins)
{
return(clonestr("{\"result\":[\"BTC\", \"BTCD\", \"LTC\", \"SYS\", \"ZEC\"]}"));
}
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)
{
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" #include "../includes/iguana_apiundefs.h"

4
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_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_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_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_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"))) #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 // API functions
#define ZERO_ARGS IGUANA_HELP0 #define ZERO_ARGS IGUANA_HELP0
#define INT_ARG IGUANA_HELP_I #define INT_ARG IGUANA_HELP_I
#define INT_AND_DOUBLE IGUANA_HELP_ID
#define TWO_INTS IGUANA_HELP_II #define TWO_INTS IGUANA_HELP_II
#define STRING_ARG IGUANA_HELP_S #define STRING_ARG IGUANA_HELP_S
#define TWO_STRINGS IGUANA_HELP_SS #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_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_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_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_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_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))) #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 // API functions
#define ZERO_ARGS IGUANA_DISPATCH0 #define ZERO_ARGS IGUANA_DISPATCH0
#define INT_ARG IGUANA_DISPATCH_I #define INT_ARG IGUANA_DISPATCH_I
#define INT_AND_DOUBLE IGUANA_DISPATCH_ID
#define TWO_INTS IGUANA_DISPATCH_II #define TWO_INTS IGUANA_DISPATCH_II
#define STRING_ARG IGUANA_DISPATCH_S #define STRING_ARG IGUANA_DISPATCH_S
#define TWO_STRINGS IGUANA_DISPATCH_SS #define TWO_STRINGS IGUANA_DISPATCH_SS

10
iguana/iguana_peers.c

@ -639,9 +639,13 @@ void _iguana_processmsg(struct iguana_info *coin,int32_t usock,struct iguana_pee
myfree(buf,len); myfree(buf,len);
return; return;
} }
int32_t i; for (i=0; i<sizeof(H); i++) static uint32_t counter;
printf("%02x",((uint8_t *)&H)[i]); if ( counter++ < 10 )
printf(" invalid header.%s received from (%s) len.%d\n",H.command,addr->ipaddr,len); {
int32_t i; for (i=0; i<sizeof(H); i++)
printf("%02x",((uint8_t *)&H)[i]);
printf(" invalid header.%s received from (%s) len.%d\n",H.command,addr->ipaddr,len);
}
//addr->dead = 1; //addr->dead = 1;
} }
// printf("%s recv error on hdr errno.%d (%s) -> zombify\n",addr->ipaddr,-recvlen,strerror(-recvlen)); // printf("%s recv error on hdr errno.%d (%s) -> zombify\n",addr->ipaddr,-recvlen,strerror(-recvlen));

2
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 ) if ( _iguana_chainlink(coin,block) == 0 )
{ {
next = block; next = block;
for (i=n=0; i<coin->chain->bundlesize && n == 0; i++) for (i=n=0; i<coin->chain->bundlesize && n < 60; i++)
{ {
if ( (block= iguana_blockfind("recvblock",coin,block->RO.prev_block)) == 0 ) if ( (block= iguana_blockfind("recvblock",coin,block->RO.prev_block)) == 0 )
break; break;

2
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}"

4
includes/iguana_apideclares.h

@ -17,8 +17,8 @@ ZERO_ARGS(InstantDEX,allcoins);
STRING_ARG(InstantDEX,available,source); STRING_ARG(InstantDEX,available,source);
THREE_STRINGS_AND_DOUBLE(InstantDEX,request,message,dest,source,amount); THREE_STRINGS_AND_DOUBLE(InstantDEX,request,message,dest,source,amount);
INT_ARG(InstantDEX,incoming,requestid); INT_ARG(InstantDEX,incoming,requestid);
INT_ARG(InstantDEX,choose,quoteid); INT_AND_DOUBLE(InstantDEX,choose,requestid,destamount);
INT_ARG(InstantDEX,qstatus,quoteid); TWO_INTS(InstantDEX,qstatus,requestid,quoteid);
HASH_ARRAY_STRING(basilisk,genesis_opreturn,hash,vals,hexstr); HASH_ARRAY_STRING(basilisk,genesis_opreturn,hash,vals,hexstr);

2
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_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_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_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_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_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) #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 // API functions
#define ZERO_ARGS IGUANA_CFUNC0 #define ZERO_ARGS IGUANA_CFUNC0
#define INT_ARG IGUANA_CFUNC_I #define INT_ARG IGUANA_CFUNC_I
#define INT_AND_DOUBLE IGUANA_CFUNC_ID
#define TWO_INTS IGUANA_CFUNC_II #define TWO_INTS IGUANA_CFUNC_II
#define STRING_ARG IGUANA_CFUNC_S #define STRING_ARG IGUANA_CFUNC_S
#define TWO_STRINGS IGUANA_CFUNC_SS #define TWO_STRINGS IGUANA_CFUNC_SS

1
includes/iguana_apiundefs.h

@ -17,6 +17,7 @@
#undef DOUBLE_ARG #undef DOUBLE_ARG
#undef ARRAY_OBJ_INT #undef ARRAY_OBJ_INT
#undef STRING_AND_ARRAY #undef STRING_AND_ARRAY
#undef INT_AND_DOUBLE
#undef INT_AND_ARRAY #undef INT_AND_ARRAY
#undef INT_ARRAY_STRING #undef INT_ARRAY_STRING
#undef TWO_ARRAYS #undef TWO_ARRAYS

1
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_RTramchainalloc(char *fname,struct iguana_info *coin,struct iguana_bundle *bp);
void iguana_update_balances(struct iguana_info *coin); void iguana_update_balances(struct iguana_info *coin);
void iguana_RTspendvectors(struct iguana_info *coin,struct iguana_bundle *bp); 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" #include "../includes/iguana_api.h"

5
includes/iguana_structs.h

@ -463,12 +463,13 @@ struct supernet_info
struct exchange_info *tradingexchanges[SUPERNET_MAXEXCHANGES]; int32_t numexchanges; struct exchange_info *tradingexchanges[SUPERNET_MAXEXCHANGES]; int32_t numexchanges;
struct iguana_waccount *wallet; struct iguana_waccount *wallet;
struct iguana_info *allcoins; int32_t allcoins_being_added,allcoins_numvirts; 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; void *ctx;
uint8_t *pingbuf;
struct delayedPoW_info dPoW; struct delayedPoW_info dPoW;
struct basilisk_relay relays[BASILISK_MAXRELAYS]; struct basilisk_relay relays[BASILISK_MAXRELAYS];
int32_t numrelays,RELAYID; int32_t numrelays,RELAYID;
struct queueitem *DEX_quotes;
// compatibility // compatibility
bits256 pangea_category,instantdex_category; bits256 pangea_category,instantdex_category;
}; };

Loading…
Cancel
Save