Browse Source

test

release/v0.1
jl777 9 years ago
parent
commit
672ff4a599
  1. 75
      basilisk/basilisk.c
  2. 57
      basilisk/basilisk.h
  3. 432
      basilisk/basilisk_DEX.c
  4. 178
      basilisk/basilisk_MSG.c
  5. 339
      basilisk/basilisk_bitcoin.c
  6. 4
      basilisk/basilisk_ping.c
  7. 517
      basilisk/basilisk_swap.c
  8. 116
      deprecated/iguana_instantdex.c
  9. 38
      deprecated/obsolete.h
  10. 33
      iguana/exchanges/bitcoin.c
  11. 11
      iguana/exchanges777.h
  12. 2
      iguana/iguana.sources
  13. 6
      iguana/iguana_accept.c
  14. 3
      iguana/iguana_chains.c
  15. 110
      iguana/iguana_exchanges.c
  16. 4
      iguana/iguana_msg.c
  17. 2
      iguana/iguana_peers.c
  18. 54
      iguana/iguana_scripts.c
  19. 4
      iguana/swaps/iguana_BTCswap.c
  20. 24
      includes/iguana_apideclares.h
  21. 2
      includes/iguana_defines.h
  22. 6
      includes/iguana_structs.h

75
basilisk/basilisk.c

@ -392,48 +392,12 @@ int32_t basilisk_relayid(struct supernet_info *myinfo,uint32_t ipbits)
#include "basilisk_ether.c"
#include "basilisk_waves.c"
#include "basilisk_lisk.c"
#include "basilisk_CMD.c"
#include "basilisk_MSG.c"
#include "basilisk_swap.c"
#include "basilisk_DEX.c"
#include "basilisk_ping.c"
#include "../includes/iguana_apidefs.h"
#include "../includes/iguana_apideclares.h"
HASH_ARRAY_STRING(basilisk,balances,hash,vals,hexstr)
{
return(basilisk_standardservice("BAL",myinfo,0,hash,vals,hexstr,1));
//return(basilisk_standardcmd(myinfo,"BAL",activecoin,remoteaddr,basilisktag,vals,coin->basilisk_balances,coin->basilisk_balancesmetric));
}
HASH_ARRAY_STRING(basilisk,value,hash,vals,hexstr)
{
return(basilisk_standardservice("VAL",myinfo,0,hash,vals,hexstr,1));
//return(basilisk_standardcmd(myinfo,"VAL",activecoin,remoteaddr,basilisktag,vals,coin->basilisk_value,coin->basilisk_valuemetric));
}
HASH_ARRAY_STRING(basilisk,rawtx,hash,vals,hexstr)
{
char *retstr=0,*symbol; uint32_t basilisktag; struct basilisk_item *ptr,Lptr; int32_t timeoutmillis;
if ( (symbol= jstr(vals,"symbol")) != 0 || (symbol= jstr(vals,"coin")) != 0 )
{
if ( (coin= iguana_coinfind(symbol)) != 0 )
{
basilisktag = juint(vals,"basilisktag");
if ( juint(vals,"burn") == 0 )
jaddnum(vals,"burn",0.0001);
if ( (timeoutmillis= juint(vals,"timeout")) <= 0 )
timeoutmillis = BASILISK_TIMEOUT;
if ( (ptr= basilisk_bitcoinrawtx(&Lptr,myinfo,coin,remoteaddr,basilisktag,timeoutmillis,vals)) != 0 )
{
retstr = ptr->retstr;
}
if ( ptr != &Lptr )
free(ptr);
}
}
return(retstr);
}
#include "../includes/iguana_apiundefs.h"
#include "basilisk_CMD.c"
void basilisk_functions(struct iguana_info *coin,int32_t protocol)
{
@ -579,22 +543,19 @@ void basilisk_msgprocess(struct supernet_info *myinfo,void *_addr,uint32_t sende
{ (void *)"BYE", &basilisk_respond_goodbye }, // disconnect
// gecko chains
//{ (void *)"NEW", &basilisk_respond_newgeckochain }, // creates new virtual gecko chain
///{ (void *)"GEN", &basilisk_respond_geckogenesis }, // returns genesis list
{ (void *)"GET", &basilisk_respond_geckoget }, // requests headers, block or tx
{ (void *)"HDR", &basilisk_respond_geckoheaders }, // reports headers
{ (void *)"BLK", &basilisk_respond_geckoblock }, // reports block
{ (void *)"MEM", &basilisk_respond_mempool }, // reports mempool
{ (void *)"GTX", &basilisk_respond_geckotx }, // reports tx
//{ (void *)"SEQ", &basilisk_respond_hashstamps }, // BTCD and BTC recent hashes from timestamp
// 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 *)"RLY", &basilisk_respond_relays },
{ (void *)"DEX", &basilisk_respond_DEX },
{ (void *)"RID", &basilisk_respond_RID },
{ (void *)"CHS", &basilisk_respond_CHS },
{ (void *)"QID", &basilisk_respond_QID },
{ (void *)"ACC", &basilisk_respond_ACC },
{ (void *)"OUT", &basilisk_respond_OUT }, // send MSG to hash/id/num
{ (void *)"MSG", &basilisk_respond_MSG }, // get MSG (hash, id, num)
// encrypted data for jumblr
{ (void *)"HOP", &basilisk_respond_forward }, // message forwarding
@ -748,7 +709,7 @@ void basilisk_p2p(void *_myinfo,void *_addr,char *senderip,uint8_t *data,int32_t
void basilisks_loop(void *arg)
{
struct iguana_info *virt,*tmpcoin,*btcd; struct basilisk_item *tmp,*pending; int32_t iter,maxmillis,flag=0; struct supernet_info *myinfo = arg;
struct iguana_info *virt,*tmpcoin,*btcd; struct basilisk_message *msg,*tmpmsg; struct basilisk_item *tmp,*pending; uint32_t now; int32_t iter,maxmillis,flag=0; struct supernet_info *myinfo = arg;
iter = 0;
while ( 1 )
{
@ -783,18 +744,32 @@ void basilisks_loop(void *arg)
//for (i=0; i<IGUANA_MAXCOINS; i++)
// if ( (coin= Coins[i]) != 0 && coin->RELAYNODE == 0 && coin->VALIDATENODE == 0 && coin->active != 0 && coin->chain->userpass[0] != 0 && coin->MAXPEERS == 1 )
// basilisk_bitcoinscan(coin,blockspace,&RAWMEM);
basilisk_requests_poll(myinfo);
now = (uint32_t)time(NULL);
portable_mutex_lock(&myinfo->messagemutex);
HASH_ITER(hh,myinfo->messagetable,msg,tmpmsg)
{
if ( now > msg->expiration )
{
printf("delete expired message.%p\n",msg);
HASH_DELETE(hh,myinfo->messagetable,msg);
free(msg);
}
}
portable_mutex_unlock(&myinfo->messagemutex);
usleep(100000);
}
}
void basilisks_init(struct supernet_info *myinfo)
{
//iguana_initQ(&myinfo->basilisks.submitQ,"submitQ");
//iguana_initQ(&myinfo->basilisks.resultsQ,"resultsQ");
iguana_initQ(&myinfo->msgQ,"messageQ");
portable_mutex_init(&myinfo->allcoins_mutex);
portable_mutex_init(&myinfo->basilisk_mutex);
portable_mutex_init(&myinfo->DEX_mutex);
portable_mutex_init(&myinfo->DEX_swapmutex);
portable_mutex_init(&myinfo->DEX_reqmutex);
portable_mutex_init(&myinfo->gecko_mutex);
portable_mutex_init(&myinfo->messagemutex);
myinfo->basilisks.launched = iguana_launch(iguana_coinfind("BTCD"),"basilisks_loop",basilisks_loop,myinfo,IGUANA_PERMTHREAD);
}

57
basilisk/basilisk.h

@ -29,6 +29,52 @@
//#define BASILISK_MAXBLOCKLAG 600
#define BASILISK_HDROFFSET ((int32_t)(sizeof(bits256)+sizeof(struct iguana_msghdr)+sizeof(uint32_t)))
#define INSTANTDEX_DECKSIZE 777
#define INSTANTDEX_LOCKTIME (7200 + 600*2)
#define INSTANTDEX_INSURANCEDIV ((7 * INSTANTDEX_DECKSIZE) >> 3)
#define INSTANTDEX_PUBEY "03bc2c7ba671bae4a6fc835244c9762b41647b9827d4780a89a949b984a8ddcc06"
#define INSTANTDEX_RMD160 "ca1e04745e8ca0c60d8c5881531d51bec470743f"
#define TIERNOLAN_RMD160 "daedddd8dbe7a2439841ced40ba9c3d375f98146"
#define INSTANTDEX_BTC "1KRhTPvoxyJmVALwHFXZdeeWFbcJSbkFPu"
#define INSTANTDEX_BTCD "RThtXup6Zo7LZAi8kRWgjAyi1s4u6U9Cpf"
struct basilisk_request
{
uint32_t requestid,timestamp,quoteid;
uint64_t srcamount;
bits256 hash;
char src[8],dest[8];
char volatile_start,message[43];
uint64_t destamount;
uint32_t relaybits;
bits256 desthash;
} __attribute__((packed));
struct bitcoin_statetx
{
bits256 txid;
uint64_t amount,change,inputsum;
char destaddr[64];
char txbytes[];
};
struct basilisk_swap
{
struct basilisk_request req;
struct supernet_info *myinfo; bits256 myhash,otherhash;
uint32_t statebits,started,expiration,finished,dead,reftime,locktime;
struct iguana_info *bobcoin,*alicecoin; char bobstr[64],alicestr[64];
int32_t bobconfirms,aliceconfirms,iambob,reclaimed;
uint64_t alicesatoshis,bobsatoshis,bobinsurance,aliceinsurance;
bits256 privkeys[INSTANTDEX_DECKSIZE],myprivs[2],mypubs[2],otherpubs[2],pubA0,pubB0,pubB1,privAm,pubAm,privBn,pubBn;
uint64_t otherdeck[INSTANTDEX_DECKSIZE][2],deck[INSTANTDEX_DECKSIZE][2];
int32_t choosei,otherchoosei,cutverified,otherverifiedcut,numpubs,havestate,otherhavestate;
uint8_t secretAm[20],secretBn[20];
struct bitcoin_statetx *deposit,*payment,*alicepayment,*myfee,*otherfee,*reclaim;
};
struct basilisk_value { bits256 txid; int64_t value; int32_t height; int16_t vout; char coinaddr[64]; };
struct basilisk_item
@ -39,6 +85,8 @@ struct basilisk_item
char symbol[32],CMD[4],remoteaddr[64],*retstr;
};
struct basilisk_message { struct queueitem DL; UT_hash_handle hh; uint32_t datalen,expiration; uint8_t key[63],keylen; uint8_t data[]; };
struct basilisk_info
{
//queue_t resultsQ,submitQ;
@ -47,15 +95,6 @@ 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];
uint32_t relaybits;
} __attribute__((packed));
struct basilisk_relaystatus
{
uint8_t pingdelay;

432
basilisk/basilisk_DEX.c

@ -14,54 +14,83 @@
******************************************************************************/
// included from basilisk.c
// requestid is invariant for a specific request
// quoteid is invariant for a specific request after dest fields are set
uint32_t basilisk_requestid(struct basilisk_request *rp)
{
struct basilisk_request R;
R = *rp;
memset(&R,0,(long)&R.volatile_start - (long)&R);
return(calc_crc32(0,(void *)((long)&R + sizeof(R.requestid)),sizeof(R) - sizeof(R.requestid)));
}
uint32_t basilisk_quoteid(struct basilisk_request *rp)
{
struct basilisk_request R;
R = *rp;
memset(R.message,0,sizeof(R.message));
R.relaybits = 0;
return(calc_crc32(0,(void *)((long)&R + sizeof(R.requestid)),sizeof(R) - sizeof(R.requestid)));
}
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->timestamp),&rp->timestamp); // must be 2nd
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);
len += iguana_rwvarstr(rwflag,&serialized[len],sizeof(rp->dest)-1,rp->dest);
len += iguana_rwbignum(rwflag,&serialized[len],sizeof(rp->desthash),rp->desthash.bytes);
len += iguana_rwnum(rwflag,&serialized[len],sizeof(rp->destamount),&rp->destamount);
len += iguana_rwvarstr(rwflag,&serialized[len],sizeof(rp->message)-1,rp->message);
if ( rp->quoteid != 0 && basilisk_quoteid(rp) != rp->quoteid )
printf("basilisk_rwDEXquote: quoteid.%u mismatch %u\n",basilisk_quoteid(rp),rp->quoteid);
if ( basilisk_quoteid(rp) != rp->requestid )
printf("basilisk_rwDEXquote: requestid.%u mismatch %u\n",basilisk_requestid(rp),rp->requestid);
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)
uint32_t basilisk_request_enqueue(struct supernet_info *myinfo,int32_t queueflag,struct basilisk_request *finalR,bits256 hash,char *src,uint64_t srcamount,bits256 desthash,char *dest,uint64_t destamount,char *message,int32_t calcquoteid)
{
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 )
{
if ( strlen(message) > sizeof(R.message)-1 )
printf("message.(%s) too long\n",message);
strncpy(R.message,message,sizeof(R.message)-1);
R.crc = calc_crc32(0,(void *)((long)&R + sizeof(R.crc)),sizeof(R) - sizeof(R.crc));
}
R.desthash = desthash;
R.destamount = destamount;
if ( calcquoteid != 0 )
R.quoteid = basilisk_quoteid(&R);
R.requestid = basilisk_requestid(&R);
*finalR = R;
len = basilisk_rwDEXquote(1,serialized+1,&R);
serialized[0] = len;
if ( (item= calloc(1,sizeof(*item) + len + 1)) != 0 )
if ( queueflag != 0 && (item= calloc(1,sizeof(*item) + len + 1)) != 0 )
{
serialized[0] = len;
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(R.requestid);
}
return(-1);
return(0);
}
cJSON *basilisk_requestjson(uint32_t relaybits,struct basilisk_request *rp)
{
char ipaddr[64]; cJSON *item = cJSON_CreateObject();
char ipaddr[64]; cJSON *msgobj,*item = cJSON_CreateObject();
expand_ipbits(ipaddr,relaybits);
jaddstr(item,"relay",ipaddr);
jaddbits256(item,"hash",rp->hash);
@ -74,46 +103,68 @@ cJSON *basilisk_requestjson(uint32_t relaybits,struct basilisk_request *rp)
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);
if ( rp->message[0] != 0 && (msgobj= cJSON_Parse(rp->message)) != 0 )
jadd(item,"message",msgobj);
return(item);
}
char *basilisk_start(struct supernet_info *myinfo,struct basilisk_request *rp,uint32_t statebits)
{
cJSON *retjson; struct basilisk_request R; char msgjsonstr[64];
sprintf(msgjsonstr,"{\"state\":%u\"}",statebits);
if ( basilisk_request_enqueue(myinfo,1,&R,rp->hash,rp->src,rp->srcamount,rp->desthash,rp->dest,rp->destamount,msgjsonstr,myinfo->RELAYID < 0) == rp->requestid )
{
if ( myinfo->RELAYID >= 0 && (bits256_cmp(rp->hash,myinfo->myaddr.persistent) == 0 || bits256_cmp(rp->desthash,myinfo->myaddr.persistent) == 0) )
{
printf("START thread to complete %u/%u for (%s %.8f) <- (%s %.8f)\n",rp->requestid,R.quoteid,rp->src,dstr(rp->srcamount),rp->dest,dstr(rp->destamount));
if ( basilisk_thread_start(myinfo,&R) != 0 )
{
basilisk_request_enqueue(myinfo,1,&R,rp->hash,rp->src,rp->srcamount,rp->desthash,rp->dest,rp->destamount,msgjsonstr,1);
return(clonestr("{\"result\":\"started atomic swap thread\"}"));
}
else return(clonestr("{\"error\":\"couldnt atomic swap thread\"}"));
}
else if ( myinfo->RELAYID < 0 )
{
retjson = cJSON_CreateObject();
jaddstr(retjson,"result","basilisk node needs to start atomic thread locally");
jadd(retjson,"req",basilisk_requestjson(myinfo->myaddr.myipbits,rp));
return(jprint(retjson,1));
} else return(clonestr("{\"error\":\"unexpected basilisk_start not mine and amrelay\"}"));
} else return(clonestr("{\"error\":\"couldnt enqueue chosen\"}"));
}
// end of swap code
struct basilisk_request *basilisk_parsejson(struct basilisk_request *rp,cJSON *reqjson)
{
uint32_t requestid,quoteid; char *msgstr;
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");
requestid = juint(reqjson,"requestid");
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 ( jobj(reqjson,"message") != 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\"}"));
msgstr = jprint(jobj(reqjson,"message"),0);
if ( strlen(msgstr) > sizeof(rp->message)-1 )
printf("basilisk_parsejson msgstr.(%s) too long\n",msgstr);
safecopy(rp->message,msgstr,sizeof(rp->message));
free(msgstr);
}
if ( quoteid != 0 )
{
rp->quoteid = basilisk_quoteid(rp);
if ( quoteid != rp->quoteid )
printf("basilisk_parsejson quoteid.%u != %u error\n",quoteid,rp->quoteid);
}
rp->requestid = basilisk_requestid(rp);
if ( requestid != rp->requestid )
printf("basilisk_parsejson requestid.%u != %u error\n",requestid,rp->requestid);
return(rp);
}
struct basilisk_relay *basilisk_request_ensure(struct supernet_info *myinfo,uint32_t senderipbits,int32_t numrequests)
@ -148,12 +199,12 @@ int32_t basilisk_ping_processDEX(struct supernet_info *myinfo,uint32_t senderipb
{
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 )
crc = basilisk_requestid(&R);
if ( crc == R.requestid )
{
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("crc.%08x error vs %08x\n",crc,R.requestid);
} else printf("relay num.%d >= max.%d\n",relay->numrequests,relay->maxrequests);
} else len += clen;
}
@ -201,6 +252,30 @@ int32_t basilisk_ping_genDEX(struct supernet_info *myinfo,uint8_t *data,int32_t
return(datalen);
}
static int _cmp_requests(const void *a,const void *b)
{
#define uint32_a (*(struct basilisk_request *)a).requestid
#define uint32_b (*(struct basilisk_request *)b).requestid
if ( uint32_b > uint32_a )
return(1);
else if ( uint32_b < uint32_a )
return(-1);
else
{
#undef uint32_a
#undef uint32_b
#define uint32_a (*(struct basilisk_request *)a).quoteid
#define uint32_b (*(struct basilisk_request *)b).quoteid
if ( uint32_b > uint32_a )
return(1);
else if ( uint32_b < uint32_a )
return(-1);
}
return(0);
#undef uint32_a
#undef uint32_b
}
struct basilisk_request *_basilisk_requests_uniq(struct supernet_info *myinfo,int32_t *nump,uint8_t *space,int32_t spacesize)
{
int32_t i,j,n,k,m; struct basilisk_relay *relay; struct basilisk_request *requests,*rp;
@ -228,10 +303,20 @@ struct basilisk_request *_basilisk_requests_uniq(struct supernet_info *myinfo,in
}
}
}
qsort(requests,m,sizeof(*requests),_cmp_requests);
*nump = m;
return(requests);
}
char *basilisk_respond_swapstatus(struct supernet_info *myinfo,bits256 hash,uint32_t requestid,uint32_t quoteid)
{
cJSON *array,*retjson;
array = cJSON_CreateArray();
retjson = cJSON_CreateObject();
jadd(retjson,"result",array);
return(jprint(retjson,1));
}
char *basilisk_respond_requests(struct supernet_info *myinfo,bits256 hash,uint32_t requestid,uint32_t quoteid)
{
int32_t i,num=0; cJSON *retjson,*array; struct basilisk_request *requests,*rp; uint8_t space[16384];
@ -242,7 +327,7 @@ char *basilisk_respond_requests(struct supernet_info *myinfo,bits256 hash,uint32
for (i=0; i<num; i++)
{
rp = &requests[i];
if ( (requestid == 0 || rp->requestid == requestid) && ((quoteid == 0 && rp->quoteid != 0) || quoteid == rp->quoteid) )
if ( rp->requestid == requestid && (quoteid == 0 || quoteid == rp->quoteid) && (bits256_cmp(hash,rp->hash) == 0 || bits256_cmp(hash,rp->desthash) == 0) )
jaddi(array,basilisk_requestjson(rp->relaybits,rp));
}
}
@ -254,71 +339,82 @@ char *basilisk_respond_requests(struct supernet_info *myinfo,bits256 hash,uint32
return(jprint(retjson,1));
}
char *basilisk_respond_choose(struct supernet_info *myinfo,bits256 hash,uint32_t requestid,uint64_t destamount)
char *basilisk_respond_accept(struct supernet_info *myinfo,uint32_t requestid,uint32_t quoteid,char *msgjsonstr)
{
int32_t i,num=0,alreadythere = 0; uint32_t quoteid; char *retstr; struct basilisk_request *requests,*rp,*resprp=0; uint8_t space[16384];
quoteid = (requestid ^ hash.uints[0]);
int32_t i,num=0; char *retstr=0; struct basilisk_request *requests,*rp; uint8_t space[16384];
portable_mutex_lock(&myinfo->DEX_reqmutex);
if ( (requests= _basilisk_requests_uniq(myinfo,&num,space,sizeof(space))) != 0 )
{
for (i=0; i<num; i++)
{
rp = &requests[i];
if ( rp->requestid == requestid )
if ( rp->requestid == requestid && rp->quoteid == quoteid )
{
if ( rp->quoteid == 0 )
resprp = rp;
else if ( rp->quoteid == quoteid )
{
alreadythere = 1;
break;
}
retstr = basilisk_start(myinfo,rp,1);
break;
}
}
}
portable_mutex_unlock(&myinfo->DEX_reqmutex);
if ( requests != (void *)space )
free(requests);
if ( alreadythere == 0 )
{
if ( resprp == 0 )
retstr = clonestr("{\"error\":\"couldnt find to requestid to choose\"}");
else retstr = basilisk_choose(myinfo,hash,resprp,destamount,quoteid);
} else retstr = clonestr("{\"result\":\"quoteid already there\"}");
portable_mutex_unlock(&myinfo->DEX_reqmutex);
if ( retstr == 0 )
retstr = clonestr("{\"error\":\"couldnt find to requestid to choose\"}");
return(retstr);
}
// respond to incoming RID, CHS, DEX, QST
// respond to incoming RID, ACC, 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_requests(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)
char *basilisk_respond_SWP(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_requests(myinfo,hash,juint(valsobj,"requestid"),juint(valsobj,"quoteid")));
return(basilisk_respond_swapstatus(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)
char *basilisk_respond_ACC(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));
uint32_t requestid,quoteid; char *retstr,*msgstr=0;
if ( (requestid= juint(valsobj,"requestid")) != 0 && (quoteid= juint(valsobj,"quoteid")) != 0 )
{
if ( jobj(valsobj,"message") != 0 )
msgstr = jprint(jobj(valsobj,"message"),0);
retstr = basilisk_respond_accept(myinfo,requestid,quoteid,msgstr);
if ( msgstr != 0 )
free(msgstr);
return(retstr);
}
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;
char *dest,*src,*msgstr=0,*retstr=0,buf[256]; uint32_t requestid,i; uint64_t destamount=0,satoshis; bits256 desthash; struct basilisk_request R;
if ( (dest= jstr(valsobj,"dest")) != 0 && (src= jstr(valsobj,"src")) != 0 && (satoshis= j64bits(valsobj,"satoshis")) != 0 )
{
memset(desthash.bytes,0,sizeof(desthash));
if ( (destamount= j64bits(valsobj,"destsatoshis")) != 0 )
{
desthash = jbits256(valsobj,"desthash");
for (i=0; i<4; i++)
if ( desthash.ulongs[i] != 0 )
break;
if ( i != 4 )
destamount = 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 )
if ( jobj(valsobj,"message") != 0 )
msgstr = jprint(jobj(valsobj,"message"),0);
if ( (requestid= basilisk_request_enqueue(myinfo,1,&R,hash,src,satoshis,desthash,dest,destamount,msgstr,destamount != 0)) != 0 )
{
sprintf(buf,"{\"result\":\"DEX request added\",\"request\":%u}",basilisktag);
sprintf(buf,"{\"result\":\"DEX request added\",\"request\":%u}",requestid);
retstr = clonestr(buf);
} else retstr = clonestr("{\"error\":\"DEX quote couldnt be created\"}");
if ( msgstr != 0 )
free(msgstr);
}
return(retstr);
}
@ -326,6 +422,19 @@ char *basilisk_respond_DEX(struct supernet_info *myinfo,char *CMD,void *addr,cha
#include "../includes/iguana_apidefs.h"
#include "../includes/iguana_apideclares.h"
THREE_STRINGS_AND_DOUBLE(tradebot,aveprice,comment,base,rel,basevolume)
{
double retvals[4],aveprice; cJSON *retjson = cJSON_CreateObject();
aveprice = instantdex_avehbla(myinfo,retvals,base,rel,basevolume);
jaddstr(retjson,"result","success");
jaddnum(retjson,"aveprice",aveprice);
jaddnum(retjson,"avebid",retvals[0]);
jaddnum(retjson,"bidvol",retvals[1]);
jaddnum(retjson,"aveask",retvals[2]);
jaddnum(retjson,"askvol",retvals[3]);
return(jprint(retjson,1));
}
ZERO_ARGS(InstantDEX,allcoins)
{
struct iguana_info *tmp; cJSON *array,*retjson = cJSON_CreateObject();
@ -348,17 +457,17 @@ STRING_ARG(InstantDEX,available,source)
} else return(clonestr("{\"error\":\"specified coin is not active\"}"));
}
THREE_STRINGS_AND_DOUBLE(InstantDEX,request,message,dest,source,amount)
HASH_ARRAY_STRING(InstantDEX,request,hash,vals,hexstr)
{
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);
cJSON *msgobj = cJSON_CreateObject();
jadd64bits(msgobj,"min",jdouble(vals,"minprice") * jdouble(vals,"amount") * SATOSHIDEN);
jaddnum(msgobj,"auto",juint(vals,"autoflag"));
jadd(vals,"message",msgobj);
if ( jobj(vals,"desthash") == 0 )
jaddbits256(vals,"desthash",hash);
jadd64bits(vals,"satoshis",jdouble(vals,"amount") * SATOSHIDEN);
jadd64bits(vals,"destsatoshis",jdouble(vals,"destamount") * SATOSHIDEN);
return(basilisk_standardservice("DEX",myinfo,0,myinfo->myaddr.persistent,vals,"",1));
}
INT_ARG(InstantDEX,incoming,requestid)
@ -377,42 +486,41 @@ INT_ARG(InstantDEX,incoming,requestid)
}
}
TWO_INTS(InstantDEX,qstatus,requestid,quoteid)
TWO_INTS(InstantDEX,swapstatus,requestid,quoteid)
{
cJSON *vals; char *retstr;
if ( myinfo->RELAYID >= 0 )
return(basilisk_respond_requests(myinfo,myinfo->myaddr.persistent,requestid,quoteid));
return(basilisk_respond_swapstatus(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);
retstr = basilisk_standardservice("SWP",myinfo,0,myinfo->myaddr.persistent,vals,"",1);
free_json(vals);
return(retstr);
}
}
INT_AND_DOUBLE(InstantDEX,choose,requestid,destamount)
TWO_INTS(InstantDEX,accept,requestid,quoteid)
{
cJSON *vals,*retjson; char *retstr; struct basilisk_request R,*other; uint32_t quoteid;
struct basilisk_request R,*other; cJSON *vals,*retjson; char *retstr,*msgjsonstr = "{\"state\":1}";
if ( myinfo->RELAYID >= 0 )
return(basilisk_respond_choose(myinfo,myinfo->myaddr.persistent,requestid,destamount*SATOSHIDEN));
return(basilisk_respond_accept(myinfo,requestid,quoteid,msgjsonstr));
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 )
jaddnum(vals,"requestid",requestid);
jadd(vals,"message",cJSON_Parse(msgjsonstr));
if ( (retstr= basilisk_standardservice("ACC",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));
other = basilisk_parsejson(&R,jobj(retjson,"req"));
if ( basilisk_thread_start(myinfo,other) != 0 )
printf("START thread to complete %u/%u for %s %.8f) <- (%s %.8f)\n",other->requestid,R.quoteid,other->src,dstr(other->srcamount),other->dest,dstr(other->destamount));
else printf("ERROR starting atomic swap thread\n");
free(retjson);
}
}
@ -422,62 +530,136 @@ INT_AND_DOUBLE(InstantDEX,choose,requestid,destamount)
}
#include "../includes/iguana_apiundefs.h"
int32_t basilisk_request_pending(struct supernet_info *myinfo,struct basilisk_request *rp,uint32_t requestid)
int32_t basilisk_request_cmpref(struct basilisk_request *ref,struct basilisk_request *rp)
{
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++)
if ( bits256_cmp(rp->hash,ref->hash) != 0 || memcmp(rp->src,ref->src,sizeof(ref->src)) != 0 || memcmp(rp->dest,ref->dest,sizeof(ref->dest)) != 0 || rp->srcamount != ref->srcamount || rp->timestamp != ref->timestamp )
{
relay = &myinfo->relays[j];
if ( (n= relay->numrequests) > 0 )
printf("basilisk_request_listprocess mismatched hash\n");
return(-1);
} else return(0);
}
double basilisk_request_listprocess(struct supernet_info *myinfo,struct basilisk_request *issueR,struct basilisk_request *list,int32_t n)
{
int32_t i,noquoteflag=0,havequoteflag=0,myrequest=0,maxi=-1,autoflag=0; cJSON *statejson,*msgobj=0; uint64_t destamount,minamount = 0,maxamount = 0; uint32_t pendingid,statebits; struct basilisk_swap *active; double metric = 0.;
memset(issueR,0,sizeof(*issueR));
printf("need to verify null quoteid is list[0]\n");
if ( (active= basilisk_request_started(myinfo,list[0].requestid)) != 0 )
pendingid = active->req.quoteid;
if ( bits256_cmp(myinfo->myaddr.persistent,list[0].hash) == 0 ) // my request
myrequest = 1;
if ( list[0].message[0] != 0 && (msgobj= cJSON_Parse(list[0].message)) != 0 )
{
autoflag = juint(msgobj,"auto");
minamount = j64bits(msgobj,"min");
}
for (i=0; i<n; i++)
{
if ( basilisk_request_cmpref(&list[0],&list[i]) != 0 )
return(-1);
if ( list[i].quoteid != 0 )
{
for (i=0; i<n; i++)
havequoteflag++;
if ( pendingid == 0 )
{
if ( relay->requests[i].requestid == requestid && relay->requests[i].quoteid == quoteid )
if ( list[i].destamount > maxamount )
{
alreadystarted = 1;
break;
maxamount = list[i].destamount;
maxi = i;
}
}
else if ( active != 0 && pendingid == list[i].quoteid )
{
if ( (statejson= cJSON_Parse(list[i].message)) != 0 )
{
statebits = juint(statejson,"state");
if ( bitweight(statebits) > bitweight(active->statebits) )
{
// advance statemachine
//active->statebits = statebits;
printf("req statbits.%x -> %x\n",active->statebits,statebits);
}
free(statejson);
}
}
} else noquoteflag++;
}
if ( myrequest == 0 && pendingid == 0 && noquoteflag != 0 )
{
double retvals[4],aveprice;
aveprice = instantdex_avehbla(myinfo,retvals,list[0].src,list[0].dest,dstr(list[0].srcamount));
destamount = 0.99 * aveprice * list[0].srcamount;
if ( destamount >= maxamount && destamount >= minamount )
{
metric = 1.;
*issueR = list[0];
issueR->desthash = myinfo->myaddr.persistent;
issueR->destamount = destamount;
}
}
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 )
else if ( myrequest != 0 && pendingid == 0 && maxi >= 0 ) // automatch best quote
{
if ( basilisk_request_pending(myinfo,&R,rp->requestid) == 0 )
if ( maxamount > minamount && autoflag != 0 && time(NULL) > BASILISK_DEXDURATION/2 )
{
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");
printf("automatch quoteid.%u triggered %.8f > %.8f\n",list[maxi].quoteid,dstr(maxamount),dstr(minamount));
*issueR = list[maxi];
if ( minamount > 0 )
metric = (dstr(maxamount) / dstr(minamount)) - 1.;
else metric = 1.;
}
}
if ( msgobj != 0 )
free_json(msgobj);
return(metric);
}
void basilisk_requests_poll(struct supernet_info *myinfo)
{
char *retstr; cJSON *retjson,*array,*item; int32_t i,n;
char *retstr; cJSON *retjson,*array,*item; int32_t i,n,m; struct basilisk_request tmpR,R,issueR,refR,list[BASILISK_MAXRELAYS*10]; double metric=0.,hwm = 0.;
memset(&issueR,0,sizeof(issueR));
if ( (retstr= InstantDEX_incoming(myinfo,0,0,0,0)) != 0 )
{
if ( (retjson= cJSON_Parse(retstr)) != 0 )
{
if ( (array= jarray(&n,retjson,"result")) != 0 )
{
for (i=0; i<n; i++)
for (i=m=0; i<n; i++)
{
item = jitem(array,i);
if ( i != 0 )
{
basilisk_parsejson(&R,item);
if ( refR.requestid == R.requestid )
list[m++] = R;
else
{
if ( (metric= basilisk_request_listprocess(myinfo,&tmpR,list,m)) > hwm )
issueR = tmpR, hwm = metric;
m = 0;
}
}
if ( m < sizeof(list)/sizeof(*list) )
basilisk_parsejson(&list[m++],item);
}
if ( m > 0 && m < sizeof(list)/sizeof(*list) )
if ( (metric= basilisk_request_listprocess(myinfo,&tmpR,list,m)) > hwm )
issueR = tmpR, hwm = metric;
}
free_json(retjson);
}
free(retstr);
}
if ( hwm > 0. )
{
if ( bits256_cmp(myinfo->myaddr.persistent,issueR.hash) == 0 ) // my request
{
if ( (retstr= InstantDEX_accept(myinfo,0,0,0,issueR.requestid,issueR.quoteid)) != 0 )
free(retstr);
}
else if ( issueR.quoteid == 0 )
{
if ( (retstr= basilisk_start(myinfo,&issueR,0)) != 0 )
free(retstr);
} else printf("basilisk_requests_poll unexpected hwm issueR\n");
}
}

178
basilisk/basilisk_MSG.c

@ -0,0 +1,178 @@
/******************************************************************************
* 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
char *basilisk_respond_sendmessage(struct supernet_info *myinfo,uint8_t *key,int32_t keylen,uint8_t *data,int32_t datalen,int32_t sendping)
{
struct basilisk_message *msg;
msg = calloc(1,sizeof(*msg) + datalen);
msg->expiration = (uint32_t)time(NULL) + INSTANTDEX_LOCKTIME*2;
memcpy(msg->key,key,keylen);
msg->datalen = datalen;
memcpy(msg->data,data,datalen);
portable_mutex_lock(&myinfo->messagemutex);
HASH_ADD_KEYPTR(hh,myinfo->messagetable,msg->key,msg->keylen,msg);
portable_mutex_unlock(&myinfo->messagemutex);
if ( sendping != 0 )
{
queue_enqueue("basilisk_message",&myinfo->msgQ,&msg->DL,0);
return(clonestr("{\"result\":\"message added to hashtable\"}"));
} else return(0);
}
int32_t basilisk_ping_processMSG(struct supernet_info *myinfo,uint32_t senderipbits,uint8_t *data,int32_t datalen)
{
int32_t i,msglen,len=0; uint8_t num,keylen,*msg,*key;
if ( (num= data[len++]) > 0 )
{
for (i=0; i<num; i++)
{
keylen = data[len++];
key = &data[len], len += keylen;
len += iguana_rwnum(0,&data[len],sizeof(msglen),&msglen);
msg = &data[len], len += msglen;
basilisk_respond_sendmessage(myinfo,key,keylen,msg,msglen,0);
}
}
return(len);
}
int32_t basilisk_ping_genMSG(struct supernet_info *myinfo,uint8_t *data,int32_t maxlen)
{
struct basilisk_message *msg; int32_t datalen = 0;
if ( maxlen > sizeof(msg->key) && (msg= queue_dequeue(&myinfo->msgQ,0)) != 0 ) // oneshot ping
{
data[datalen++] = 1;
data[datalen++] = msg->keylen;
memcpy(&data[datalen],msg->key,msg->keylen), datalen += msg->keylen;
iguana_rwnum(1,data,sizeof(msg->datalen),&msg->datalen);
if ( maxlen > datalen+msg->datalen )
memcpy(&data[datalen],msg->data,msg->datalen), datalen += msg->datalen;
else
{
printf("basilisk_ping_genMSG message doesnt fit %d vs %d\n",maxlen,datalen+msg->datalen);
datalen = 0;
}
} data[datalen++] = 0;
return(datalen);
}
char *basilisk_respond_getmessage(struct supernet_info *myinfo,uint8_t *key,int32_t keylen)
{
cJSON *retjson; struct basilisk_message *msg; char *ptr = 0,strbuf[16384];
retjson = cJSON_CreateObject();
portable_mutex_lock(&myinfo->messagemutex);
HASH_FIND(hh,myinfo->messagetable,key,keylen,msg);
if ( msg != 0 )
{
if ( basilisk_addhexstr(&ptr,retjson,strbuf,sizeof(strbuf),msg->data,msg->datalen) != 0 )
jaddstr(retjson,"result","success");
else jaddstr(retjson,"error","couldnt add message");
} else jaddstr(retjson,"error","no message");
portable_mutex_unlock(&myinfo->messagemutex);
return(jprint(retjson,1));
}
// respond to incoming OUT, MSG
int32_t basilisk_messagekey(uint8_t *key,bits256 hash,cJSON *valsobj)
{
uint32_t channel,msgid; int32_t keylen = 0;
channel = juint(valsobj,"channel");
msgid = juint(valsobj,"msgid");
keylen += iguana_rwbignum(1,&key[keylen],sizeof(hash),hash.bytes);
keylen += iguana_rwnum(1,&key[keylen],sizeof(uint32_t),&channel);
keylen += iguana_rwnum(1,&key[keylen],sizeof(uint32_t),&msgid);
return(keylen);
}
char *basilisk_respond_OUT(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)
{
int32_t keylen; uint8_t key[64];
keylen = basilisk_messagekey(key,hash,valsobj);
return(basilisk_respond_sendmessage(myinfo,key,keylen,data,datalen,1));
}
char *basilisk_respond_MSG(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)
{
int32_t keylen; uint8_t key[64];
keylen = basilisk_messagekey(key,hash,valsobj);
return(basilisk_respond_getmessage(myinfo,key,keylen));
}
#include "../includes/iguana_apidefs.h"
#include "../includes/iguana_apideclares.h"
HASH_ARRAY_STRING(basilisk,getmessage,hash,vals,hexstr)
{
return(basilisk_standardservice("MSG",myinfo,0,hash,vals,hexstr,1));
}
HASH_ARRAY_STRING(basilisk,sendmessage,hash,vals,hexstr)
{
return(basilisk_standardservice("OUT",myinfo,0,hash,vals,hexstr,1));
}
#include "../includes/iguana_apiundefs.h"
int32_t basilisk_channelsend(struct supernet_info *myinfo,bits256 hash,uint32_t channel,uint32_t msgid,uint8_t *data,int32_t datalen)
{
char *retstr,*hexstr,strbuf[16384],*ptr = 0; int32_t retval = -1; cJSON *retjson,*valsobj;
if ( (hexstr= basilisk_addhexstr(&ptr,0,strbuf,sizeof(strbuf),data,datalen)) != 0 )
{
valsobj = cJSON_CreateObject();
jaddnum(valsobj,"channel",channel);
jaddnum(valsobj,"msgid",msgid);
if ( (retstr= basilisk_sendmessage(myinfo,0,0,0,hash,valsobj,hexstr)) != 0 )
{
if ( (retjson= cJSON_Parse(retstr)) != 0 )
{
if ( jobj(retjson,"error") == 0 )
retval = 0;
free_json(retjson);
}
free(retstr);
}
free_json(valsobj);
if ( ptr != 0 )
free(ptr);
}
return(retval);
}
int32_t basilisk_channelget(struct supernet_info *myinfo,bits256 hash,uint32_t channel,uint32_t msgid,uint8_t *data,int32_t maxlen)
{
char *retstr,*hexstr; cJSON *valsobj,*retjson; int32_t datalen,retval = -1;
valsobj = cJSON_CreateObject();
jaddnum(valsobj,"channel",channel);
jaddnum(valsobj,"msgid",msgid);
if ( (retstr= basilisk_getmessage(myinfo,0,0,0,hash,valsobj,0)) != 0 )
{
if ( (retjson= cJSON_Parse(retstr)) != 0 )
{
if ( (hexstr= jstr(retjson,"data")) != 0 && (datalen= is_hexstr(hexstr,0)) > 0 )
{
if ( datalen < maxlen )
{
decode_hex(data,datalen,hexstr);
retval = datalen;
}
}
free_json(retjson);
}
free(retstr);
}
free_json(valsobj);
return(retval);
}

339
basilisk/basilisk_bitcoin.c

@ -13,13 +13,13 @@
* *
******************************************************************************/
struct bitcoin_rawtxdependents
/*struct bitcoin_rawtxdependents
{
int64_t spentsatoshis,outputsum,cost,change;
int32_t numptrs,numresults;
char **results,*coinaddrs;
struct basilisk_item *ptrs[];
};
};*/
#ifdef bitcoincancalculatebalances
int64_t bitcoin_value(struct iguana_info *coin,bits256 txid,int16_t vout,char *coinaddr)
@ -649,3 +649,338 @@ void *basilisk_bitcoinrawtx(struct basilisk_item *Lptr,struct supernet_info *myi
return(basilisk_issueremote(myinfo,0,&numsent,"RAW",coin->symbol,1,valsobj,juint(valsobj,"fanout"),juint(valsobj,"minresults"),basilisktag,timeoutmillis,coin->basilisk_rawtxmetric,0,0,0,BASILISK_DEFAULTDIFF));
}
#ifdef later
int32_t instantdex_outputinsurance(char *coinaddr,uint8_t addrtype,uint8_t *script,int64_t insurance,uint64_t r,uint64_t dest)
{
uint8_t rmd160[20]; int32_t n = 0;
decode_hex(rmd160,sizeof(rmd160),(dest % 10) == 9 ? TIERNOLAN_RMD160 : INSTANTDEX_RMD160);
//script[n++] = sizeof(r);
//n += iguana_rwnum(1,&script[n],sizeof(r),&r);
//script[n++] = SCRIPT_OP_DROP;
bitcoin_address(coinaddr,addrtype,rmd160,20);
n = bitcoin_standardspend(script,n,rmd160);
return(n);
}
void iguana_addinputs(struct iguana_info *coin,struct bitcoin_spend *spend,cJSON *txobj,uint32_t sequence)
{
int32_t i,j,plen; uint8_t *pubkeyptrs[16];
for (i=0; i<spend->numinputs; i++)
{
spend->inputs[i].sequence = sequence;
for (j=0; j<16; j++)
{
if ( (plen= bitcoin_pubkeylen(spend->inputs[i].pubkeys[j])) < 0 )
break;
pubkeyptrs[j] = spend->inputs[i].pubkeys[j];
}
bitcoin_txinput(coin,txobj,spend->inputs[i].txid,spend->inputs[i].vout,spend->inputs[i].sequence,spend->inputs[i].spendscript,spend->inputs[i].spendlen,spend->inputs[i].p2shscript,spend->inputs[i].p2shlen,j>0?pubkeyptrs:0,j);
}
}
struct bitcoin_statetx *instantdex_signtx(char *str,struct supernet_info *myinfo,struct iguana_info *coin,uint32_t locktime,char *scriptstr,int64_t satoshis,int64_t txfee,int32_t minconf,int32_t myside)
{
struct iguana_waddress *waddr; struct iguana_waccount *wacct; struct bitcoin_statetx *tx=0; char coinaddr[64],wifstr[64]; char *rawtx=0,*signedtx,*retstr; bits256 signedtxid; uint32_t basilisktag; int32_t flag,completed; cJSON *valsobj,*vins=0,*retjson=0,*privkey,*addresses;
if ( (waddr= iguana_getaccountaddress(myinfo,coin,0,0,coin->changeaddr,"change")) == 0 )
{
printf("no change addr error\n");
return(0);
}
privkey = cJSON_CreateArray();
addresses = cJSON_CreateArray();
if ( coin->changeaddr[0] == 0 )
bitcoin_address(coin->changeaddr,coin->chain->pubtype,waddr->rmd160,20);
//bitcoin_pubkey33(myinfo->ctx,pubkey33,myinfo->persistent_priv);
bitcoin_address(coinaddr,coin->chain->pubtype,myinfo->persistent_pubkey33,33);
//printf("%s persistent.(%s) (%s) change.(%s) scriptstr.(%s)\n",coin->symbol,myinfo->myaddr.BTC,coinaddr,coin->changeaddr,scriptstr);
if ( (waddr= iguana_waddresssearch(myinfo,&wacct,coinaddr)) != 0 )
{
bitcoin_priv2wif(wifstr,waddr->privkey,coin->chain->wiftype);
jaddistr(privkey,waddr->wifstr);
}
basilisktag = (uint32_t)rand();
jaddistr(addresses,coinaddr);
valsobj = cJSON_CreateObject();
jadd(valsobj,"addresses",addresses);
jaddstr(valsobj,"coin",coin->symbol);
jaddstr(valsobj,"spendscript",scriptstr);
jaddstr(valsobj,"changeaddr",coin->changeaddr);
jadd64bits(valsobj,"satoshis",satoshis);
jadd64bits(valsobj,"txfee",txfee);
jaddnum(valsobj,"minconf",minconf);
jaddnum(valsobj,"basilisktag",basilisktag);
jaddnum(valsobj,"locktime",locktime);
jaddnum(valsobj,"timeout",30000);
if ( (retstr= basilisk_rawtx(myinfo,coin,0,0,myinfo->myaddr.persistent,valsobj,"")) != 0 )
{
//printf("%s got.(%s)\n",str,retstr);
flag = 0;
if ( (retjson= cJSON_Parse(retstr)) != 0 )
{
if ( (rawtx= jstr(retjson,"rawtx")) != 0 && (vins= jobj(retjson,"vins")) != 0 )
flag = 1;
else printf("missing rawtx.%p or vins.%p\n",rawtx,vins);
} else printf("error parsing.(%s)\n",retstr);
if ( flag != 0 && vins != 0 )
{
//printf("vins.(%s)\n",jprint(vins,0));
if ( (signedtx= iguana_signrawtx(myinfo,coin,&signedtxid,&completed,vins,rawtx,privkey)) != 0 )
{
iguana_unspentslock(myinfo,coin,vins);
tx = calloc(1,sizeof(*tx) + strlen(signedtx) + 1);
strcpy(tx->txbytes,signedtx);
tx->txid = signedtxid;
printf("%s %s.%s\n",myside != 0 ? "BOB" : "ALICE",str,signedtx);
free(signedtx);
} else printf("error signrawtx\n"); //do a very short timeout so it finishes via local poll
}
if ( retjson != 0 )
free_json(retjson);
if ( flag == 2 )
{
free_json(vins);
printf("Free rawtx\n");
free(rawtx);
}
free(retstr);
} else printf("error creating %s feetx\n",myside != 0 ? "BOB" : "ALICE");
free_json(addresses);
return(tx);
}
struct bitcoin_statetx *instantdex_feetx(struct supernet_info *myinfo,struct instantdex_accept *A,struct basilisk_swap *swap,struct iguana_info *coin)
{
int32_t n; uint8_t paymentscript[128]; char scriptstr[512],coinaddr[64]; struct bitcoin_statetx *ptr = 0; uint64_t r;
r = swap->mine.orderid;
n = instantdex_outputinsurance(coinaddr,coin->chain->pubtype,paymentscript,swap->insurance + swap->bobcoin->chain->txfee,r,r * (strcmp("BTC",coin->symbol) == 0));
init_hexbytes_noT(scriptstr,paymentscript,n);
printf("instantdex_feetx %s %.8f (%s)\n",coin->symbol,dstr(swap->insurance + swap->bobcoin->chain->txfee),scriptstr);
if ( (ptr= instantdex_signtx("feetx",myinfo,coin,0,scriptstr,swap->insurance + swap->bobcoin->chain->txfee,coin->txfee,0,A->offer.myside)) != 0 )
strcpy(ptr->destaddr,coinaddr);
return(ptr);
}
int32_t instantdex_feetxverify(struct supernet_info *myinfo,struct iguana_info *coin,struct basilisk_swap *swap,cJSON *argjson)
{
cJSON *txobj; bits256 txid; uint32_t n; int32_t i,retval = -1,extralen=65536; int64_t insurance; uint64_t r;
struct iguana_msgtx msgtx; uint8_t script[512],serialized[8192],*extraspace=0; char coinaddr[64];
if ( swap->otherfee != 0 )
{
extraspace = calloc(1,extralen);
if ( (txobj= bitcoin_hex2json(coin,&txid,&msgtx,swap->otherfee->txbytes,extraspace,extralen,serialized)) != 0 )
{
r = swap->other.orderid;
if ( strcmp(coin->symbol,"BTC") == 0 )
insurance = swap->insurance + swap->bobcoin->chain->txfee;
else insurance = swap->altinsurance + swap->alicecoin->chain->txfee;
n = instantdex_outputinsurance(coinaddr,coin->chain->pubtype,script,insurance,r,r * (strcmp("BTC",coin->symbol) == 0));
if ( n == msgtx.vouts[0].pk_scriptlen )
{
if ( memcmp(script,msgtx.vouts[0].pk_script,n) == 0 )
{
printf("feetx script verified.(%s)\n",swap->otherfee->txbytes);
retval = 0;
}
else
{
for (i=0; i<n; i++)
printf("%02x",script[i]);
printf(" fee script\n");
for (i=0; i<n; i++)
printf("%02x",msgtx.vouts[0].pk_script[i]);
printf(" feetx mismatched\n");
printf("FEETX.(%s)\n",jprint(txobj,0));
}
} else printf("pk_scriptlen %d mismatch %d\n",msgtx.vouts[0].pk_scriptlen,n);
free_json(txobj);
} else printf("error converting (%s) txobj\n",swap->otherfee->txbytes);
} else printf("no feetx to verify\n");
if ( extraspace != 0 )
free(extraspace);
return(retval);
}
struct bitcoin_statetx *instantdex_bobtx(struct supernet_info *myinfo,struct basilisk_swap *swap,struct iguana_info *coin,int64_t amount,int32_t depositflag)
{
int32_t n,secretstart; struct bitcoin_statetx *ptr = 0; uint8_t script[1024]; uint32_t locktime; int64_t satoshis; char scriptstr[512];
if ( coin == 0 )
return(0);
satoshis = amount + depositflag*swap->insurance*100 + swap->bobcoin->chain->txfee;
n = instantdex_bobscript(script,0,&locktime,&secretstart,swap,depositflag);
if ( n < 0 )
{
printf("instantdex_bobtx couldnt generate bobscript deposit.%d\n",depositflag);
return(0);
}
printf("locktime.%u amount %.8f satoshis %.8f\n",locktime,dstr(amount),dstr(satoshis));
init_hexbytes_noT(scriptstr,script,n);
if ( (ptr= instantdex_signtx(depositflag != 0 ? "deposit" : "payment",myinfo,coin,locktime,scriptstr,satoshis,coin->txfee,swap->mine.minconfirms,swap->mine.offer.myside)) != 0 )
{
bitcoin_address(ptr->destaddr,coin->chain->p2shtype,script,n);
printf("BOBTX.%d (%s) -> %s\n",depositflag,ptr->txbytes,ptr->destaddr);
} else printf("sign error for bottx\n");
return(ptr);
}
int32_t instantdex_paymentverify(struct supernet_info *myinfo,struct iguana_info *coin,struct basilisk_swap *swap,cJSON *argjson,int32_t depositflag)
{
cJSON *txobj; bits256 txid; uint32_t n,locktime; int32_t i,secretstart,retval = -1,extralen=65536; uint64_t x;
struct iguana_msgtx msgtx; uint8_t script[512],serialized[8192],*extraspace=0; int64_t amount;
if ( coin != 0 && swap->deposit != 0 )
{
amount = swap->BTCsatoshis + depositflag*swap->insurance*100 + swap->bobcoin->chain->txfee;
if ( (n= instantdex_bobscript(script,0,&locktime,&secretstart,swap,depositflag)) <= 0 )
return(retval);
extraspace = calloc(1,extralen);
if ( (txobj= bitcoin_hex2json(coin,&txid,&msgtx,swap->deposit->txbytes,extraspace,extralen,serialized)) != 0 )
{
memcpy(&script[secretstart],&msgtx.vouts[0].pk_script[secretstart],20);
printf("locktime.%u amount %.8f satoshis %.8f\n",locktime,dstr(amount),dstr(amount));
if ( msgtx.lock_time == locktime && msgtx.vouts[0].value == amount && n == msgtx.vouts[0].pk_scriptlen )
{
if ( memcmp(script,msgtx.vouts[0].pk_script,n) == 0 )
{
iguana_rwnum(0,&script[secretstart],sizeof(x),&x);
printf("deposit script verified\n");
if ( x == swap->otherdeck[swap->choosei][0] )
retval = 0;
else printf("deposit script verified but secret mismatch x.%llx vs otherdeck %llx\n",(long long)x,(long long)swap->otherdeck[swap->choosei][0]);
}
else
{
for (i=0; i<n; i++)
printf("%02x ",script[i]);
printf("script\n");
for (i=0; i<n; i++)
printf("%02x ",msgtx.vouts[0].pk_script[i]);
printf("deposit\n");
}
}
free_json(txobj);
}
}
if ( extraspace != 0 )
free(extraspace);
return(retval);
}
int32_t instantdex_altpaymentverify(struct supernet_info *myinfo,struct iguana_info *coin,struct basilisk_swap *swap,cJSON *argjson)
{
cJSON *txobj; bits256 txid; uint32_t n; int32_t i,retval = -1,extralen = 65536;
struct iguana_msgtx msgtx; uint8_t script[512],serialized[8192],*extraspace=0; char *altmsigaddr=0,msigaddr[64];
if ( swap->altpayment != 0 && (altmsigaddr= jstr(argjson,"altmsigaddr")) != 0 )
{
extraspace = calloc(1,extralen);
if ( (txobj= bitcoin_hex2json(coin,&txid,&msgtx,swap->altpayment->txbytes,extraspace,extralen,serialized)) != 0 )
{
n = instantdex_alicescript(script,0,msigaddr,coin->chain->p2shtype,swap->pubAm,swap->pubBn);
if ( strcmp(msigaddr,altmsigaddr) == 0 && n == msgtx.vouts[0].pk_scriptlen )
{
if ( memcmp(script,msgtx.vouts[0].pk_script,n) == 0 )
{
printf("altpayment script verified\n");
retval = 0;
}
else
{
for (i=0; i<n; i++)
printf("%02x ",script[i]);
printf(" altscript\n");
for (i=0; i<n; i++)
printf("%02x ",msgtx.vouts[0].pk_script[i]);
printf(" altpayment\n");
}
} else printf("msig mismatch.(%s %s) or n.%d != %d\n",msigaddr,altmsigaddr,n,msgtx.vouts[0].pk_scriptlen);
free_json(txobj);
} else printf("bitcoin_hex2json error\n");
} else printf("no altpayment.%p or no altmsig.%s\n",swap->altpayment,altmsigaddr!=0?altmsigaddr:"");
if ( extraspace != 0 )
free(extraspace);
return(retval);
}
struct bitcoin_statetx *instantdex_alicetx(struct supernet_info *myinfo,struct iguana_info *alicecoin,char *msigaddr,bits256 pubAm,bits256 pubBn,int64_t amount,struct basilisk_swap *swap)
{
int32_t n; uint8_t script[1024]; char scriptstr[2048]; struct bitcoin_statetx *ptr = 0;
if ( alicecoin != 0 )
{
if ( bits256_nonz(pubAm) == 0 || bits256_nonz(pubBn) == 0 )
{
printf("instantdex_bobtx null pubAm.%llx or pubBn.%llx\n",(long long)pubAm.txid,(long long)pubBn.txid);
return(0);
}
n = instantdex_alicescript(script,0,msigaddr,alicecoin->chain->p2shtype,pubAm,pubBn);
init_hexbytes_noT(scriptstr,script,n);
if ( (ptr= instantdex_signtx("altpayment",myinfo,alicecoin,0,scriptstr,amount,alicecoin->txfee,swap->mine.minconfirms,swap->mine.offer.myside)) != 0 )
{
strcpy(ptr->destaddr,msigaddr);
printf("ALICETX (%s) -> %s\n",ptr->txbytes,ptr->destaddr);
}
}
return(ptr);
}
cJSON *BTC_makeclaimfunc(struct supernet_info *myinfo,struct exchange_info *exchange,struct basilisk_swap *swap,cJSON *argjson,cJSON *newjson,uint8_t **serdatap,int32_t *serdatalenp)
{
int32_t got_payment=1,bob_reclaimed=0;
*serdatap = 0, *serdatalenp = 0;
if ( instantdex_isbob(swap) == 0 )
{
// [BLOCKING: payfound] now Alice's turn to make sure payment is confrmed and send in claim or see bob's reclaim and reclaim
if ( got_payment != 0 )
{
//swap->privAm = swap->privkeys[swap->otherchoosei];
// sign if/else payment
}
else if ( bob_reclaimed != 0 )
{
}
}
else
{
// [BLOCKING: privM] Bob waits for privM either from Alice or alt blockchain
if ( bits256_nonz(swap->privAm) != 0 )
{
// a multisig tx for alicecoin
}
}
return(newjson);
}
#endif
#include "../includes/iguana_apidefs.h"
#include "../includes/iguana_apideclares.h"
HASH_ARRAY_STRING(basilisk,balances,hash,vals,hexstr)
{
return(basilisk_standardservice("BAL",myinfo,0,hash,vals,hexstr,1));
}
HASH_ARRAY_STRING(basilisk,value,hash,vals,hexstr)
{
return(basilisk_standardservice("VAL",myinfo,0,hash,vals,hexstr,1));
}
HASH_ARRAY_STRING(basilisk,rawtx,hash,vals,hexstr)
{
char *retstr=0,*symbol; uint32_t basilisktag; struct basilisk_item *ptr,Lptr; int32_t timeoutmillis;
if ( (symbol= jstr(vals,"symbol")) != 0 || (symbol= jstr(vals,"coin")) != 0 )
{
if ( (coin= iguana_coinfind(symbol)) != 0 )
{
basilisktag = juint(vals,"basilisktag");
if ( juint(vals,"burn") == 0 )
jaddnum(vals,"burn",0.0001);
if ( (timeoutmillis= juint(vals,"timeout")) <= 0 )
timeoutmillis = BASILISK_TIMEOUT;
if ( (ptr= basilisk_bitcoinrawtx(&Lptr,myinfo,coin,remoteaddr,basilisktag,timeoutmillis,vals)) != 0 )
{
retstr = ptr->retstr;
}
if ( ptr != &Lptr )
free(ptr);
}
}
return(retstr);
}
#include "../includes/iguana_apiundefs.h"

4
basilisk/basilisk_ping.c

@ -172,7 +172,10 @@ void basilisk_ping_process(struct supernet_info *myinfo,struct iguana_peer *addr
len += n;
}
if ( len <= datalen-sizeof(sn) )
{
len += basilisk_ping_processDEX(myinfo,senderipbits,&data[len],datalen-len);
len += basilisk_ping_processMSG(myinfo,senderipbits,&data[len],datalen-len);
}
if ( len != datalen )
printf("PING got %d, processed.%d from (%s)\n",datalen,len,ipbuf);
//else printf("\n");
@ -189,6 +192,7 @@ int32_t basilisk_ping_gen(struct supernet_info *myinfo,uint8_t *data,int32_t max
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);
datalen += basilisk_ping_genMSG(myinfo,&data[datalen],maxlen - datalen);
//for (i=0; i<datalen; i++)
// printf("%02x",data[i]);
//printf(" <- output ping sn.%d\n",sn);

517
basilisk/basilisk_swap.c

@ -0,0 +1,517 @@
/******************************************************************************
* 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 iguana_numconfirms(struct supernet_info *myinfo,struct iguana_info *coin,bits256 txid)
{
return(10);
}
bits256 instantdex_derivekeypair(struct supernet_info *myinfo,bits256 *newprivp,uint8_t pubkey[33],bits256 privkey,bits256 orderhash)
{
bits256 sharedsecret;
sharedsecret = curve25519_shared(privkey,orderhash);
vcalc_sha256cat(newprivp->bytes,orderhash.bytes,sizeof(orderhash),sharedsecret.bytes,sizeof(sharedsecret));
return(bitcoin_pubkey33(myinfo->ctx,pubkey,*newprivp));
}
int32_t instantdex_pubkeyargs(struct supernet_info *myinfo,struct basilisk_swap *swap,int32_t numpubs,bits256 privkey,bits256 hash,int32_t firstbyte)
{
char buf[3]; int32_t i,n,m,len=0; bits256 pubi; uint64_t txid; uint8_t secret160[20],pubkey[33];
sprintf(buf,"%c0",'A' - 0x02 + firstbyte);
if ( numpubs > 2 )
{
if ( swap->numpubs+2 >= numpubs )
return(numpubs);
printf(">>>>>> start generating %s\n",buf);
}
for (i=n=m=0; i<numpubs*100 && n<numpubs; i++)
{
pubi = instantdex_derivekeypair(myinfo,&privkey,pubkey,privkey,hash);
//printf("i.%d n.%d numpubs.%d %02x vs %02x\n",i,n,numpubs,pubkey[0],firstbyte);
if ( pubkey[0] != firstbyte )
continue;
if ( n < 2 )
{
if ( bits256_nonz(swap->mypubs[n]) == 0 )
{
swap->myprivs[n] = privkey;
memcpy(swap->mypubs[n].bytes,pubkey+1,sizeof(bits256));
}
}
if ( swap->numpubs < INSTANTDEX_DECKSIZE )
{
swap->privkeys[m] = privkey;
calc_rmd160_sha256(secret160,privkey.bytes,sizeof(privkey));
memcpy(&txid,secret160,sizeof(txid));
len += iguana_rwnum(1,(uint8_t *)&swap->deck[m][0],sizeof(txid),&txid);
len += iguana_rwnum(1,(uint8_t *)&swap->deck[m][1],sizeof(pubi.txid),&pubi.txid);
m++;
if ( m > swap->numpubs )
swap->numpubs = m;
}
n++;
}
if ( n > 2 || m > 2 )
printf("n.%d m.%d len.%d numpubs.%d\n",n,m,len,swap->numpubs);
return(n);
}
char *instantdex_choosei(struct basilisk_swap *swap,cJSON *newjson,cJSON *argjson,uint8_t *serdata,int32_t datalen)
{
int32_t i,j,max,len = 0; uint64_t x;
if ( swap->choosei < 0 && serdata != 0 && datalen == sizeof(swap->deck) )
{
max = (int32_t)(sizeof(swap->otherdeck) / sizeof(*swap->otherdeck));
for (i=0; i<max; i++)
for (j=0; j<2; j++)
len += iguana_rwnum(1,(uint8_t *)&swap->otherdeck[i][j],sizeof(x),&serdata[len]);
OS_randombytes((uint8_t *)&swap->choosei,sizeof(swap->choosei));
if ( swap->choosei < 0 )
swap->choosei = -swap->choosei;
swap->choosei %= max;
jaddnum(newjson,"mychoosei",swap->choosei);
printf(" %s send mychoosei.%d of max.%d deck.(%llx %llx)\n",swap->iambob!=0?"BOB":"alice",swap->choosei,max,(long long)swap->otherdeck[0][0],(long long)swap->otherdeck[0][1]);
return(0);
}
else
{
printf("choosei.%d or null serdata.%p or invalid datalen.%d vs %d\n",swap->choosei,serdata,datalen,(int32_t)sizeof(swap->deck));
return(clonestr("{\"error\":\"instantdex_BTCswap offer no cut\"}"));
}
}
void instantdex_privkeyextract(struct supernet_info *myinfo,struct basilisk_swap *swap,uint8_t *serdata,int32_t serdatalen)
{
int32_t i,j,wrongfirstbyte,errs,len = 0; bits256 otherpriv,pubi; uint8_t secret160[20],otherpubkey[33],pubkey[33]; uint64_t txid;
if ( swap->cutverified == 0 && swap->choosei >= 0 && serdatalen == sizeof(swap->privkeys) )
{
for (i=wrongfirstbyte=errs=0; i<sizeof(swap->privkeys)/sizeof(*swap->privkeys); i++)
{
for (j=0; j<32; j++)
otherpriv.bytes[j] = serdata[len++];
if ( i == swap->choosei )
{
if ( bits256_nonz(otherpriv) != 0 )
{
printf("got privkey in slot.%d my choosei??\n",i);
errs++;
}
if ( swap->iambob != 0 )
{
if ( otherpubkey[0] == 0x02 )
{
if ( bits256_nonz(swap->privkeys[i]) != 0 )
{
swap->privBn = swap->privkeys[i];
calc_rmd160_sha256(swap->secretBn,swap->privBn.bytes,sizeof(swap->privBn));
printf("set secretBn\n");
swap->pubBn = bitcoin_pubkey33(myinfo->ctx,pubkey,swap->privBn);
}
} else printf("wrong first byte.%02x\n",otherpubkey[0]);
}
else
{
if ( otherpubkey[0] == 0x03 )
{
if ( bits256_nonz(swap->privkeys[i]) != 0 )
{
swap->privAm = swap->privkeys[i];
calc_rmd160_sha256(swap->secretAm,swap->privAm.bytes,sizeof(swap->privAm));
printf("set secretAm\n");
swap->pubAm = bitcoin_pubkey33(myinfo->ctx,pubkey,swap->privAm);
}
} else printf("wrong first byte.%02x\n",otherpubkey[0]);
}
continue;
}
pubi = bitcoin_pubkey33(myinfo->ctx,otherpubkey,otherpriv);
calc_rmd160_sha256(secret160,otherpriv.bytes,sizeof(otherpriv));
memcpy(&txid,secret160,sizeof(txid));
if ( otherpubkey[0] != (swap->iambob ^ 1) + 0x02 )
{
wrongfirstbyte++;
printf("wrongfirstbyte[%d] %02x\n",i,otherpubkey[0]);
}
else if ( swap->otherdeck[i][1] != pubi.txid )
{
printf("otherdeck[%d] priv ->pub mismatch %llx != %llx\n",i,(long long)swap->otherdeck[i][1],(long long)pubi.txid);
errs++;
}
else if ( swap->otherdeck[i][0] != txid )
{
printf("otherdeck[%d] priv mismatch %llx != %llx\n",i,(long long)swap->otherdeck[i][0],(long long)txid);
errs++;
}
}
if ( errs == 0 && wrongfirstbyte == 0 )
swap->cutverified = 1, printf("CUT VERIFIED\n");
else printf("failed verification: wrong firstbyte.%d errs.%d\n",wrongfirstbyte,errs);
}
}
struct basilisk_swap *bitcoin_swapinit(struct supernet_info *myinfo,struct basilisk_swap *swap)
{
struct iguana_info *coin;
if ( strcmp("BTC",swap->req.src) == 0 )
{
swap->bobcoin = iguana_coinfind("BTC");
swap->bobsatoshis = swap->req.srcamount;
swap->bobconfirms = (1 + sqrt(dstr(swap->bobsatoshis) * .1));
swap->alicecoin = iguana_coinfind(swap->req.dest);
swap->alicesatoshis = swap->req.destamount;
swap->aliceconfirms = swap->bobconfirms * 3;
}
else if ( strcmp("BTC",swap->req.dest) == 0 )
{
swap->bobcoin = iguana_coinfind("BTC");
swap->bobsatoshis = swap->req.destamount;
swap->bobconfirms = (1 + sqrt(dstr(swap->bobsatoshis) * .1));
swap->alicecoin = iguana_coinfind(swap->req.src);
swap->alicesatoshis = swap->req.srcamount;
swap->aliceconfirms = swap->bobconfirms * 3;
}
else
{
if ( (coin= iguana_coinfind(swap->req.src)) != 0 )
{
if ( coin->chain->havecltv != 0 )
{
swap->bobcoin = coin;
swap->bobsatoshis = swap->req.srcamount;
swap->alicecoin = iguana_coinfind(swap->req.dest);
swap->alicesatoshis = swap->req.destamount;
}
else if ( (coin= iguana_coinfind(swap->req.dest)) != 0 )
{
if ( coin->chain->havecltv != 0 )
{
swap->bobcoin = coin;
swap->bobsatoshis = swap->req.destamount;
swap->alicecoin = iguana_coinfind(swap->req.src);
swap->alicesatoshis = swap->req.srcamount;
}
}
}
}
if ( swap->bobcoin == 0 || swap->alicecoin == 0 )
{
printf("missing BTC.%p or missing alicecoin.%p\n",swap->bobcoin,swap->alicecoin);
free(swap);
return(0);
}
if ( swap->bobconfirms == 0 )
swap->bobconfirms = swap->bobcoin->chain->minconfirms;
if ( swap->aliceconfirms == 0 )
swap->aliceconfirms = swap->alicecoin->chain->minconfirms;
swap->bobinsurance = (swap->bobsatoshis / INSTANTDEX_INSURANCEDIV);
swap->aliceinsurance = (swap->alicesatoshis / INSTANTDEX_INSURANCEDIV);
strcpy(swap->bobstr,swap->bobcoin->symbol);
strcpy(swap->alicestr,swap->alicecoin->symbol);
swap->started = (uint32_t)time(NULL);
swap->expiration = swap->req.timestamp + INSTANTDEX_LOCKTIME*2;
swap->locktime = swap->expiration + INSTANTDEX_LOCKTIME;
swap->choosei = swap->otherchoosei = -1;
swap->myhash = myinfo->myaddr.persistent;
if ( bits256_cmp(swap->myhash,swap->req.hash) == 0 )
{
swap->otherhash = swap->req.desthash;
if ( strcmp(swap->req.src,swap->bobstr) == 0 )
swap->iambob = 1;
else if ( strcmp(swap->req.dest,swap->alicestr) != 0 )
{
printf("neither bob nor alice error\n");
return(0);
}
}
else if ( bits256_cmp(swap->myhash,swap->req.desthash) == 0 )
{
swap->otherhash = swap->req.hash;
if ( strcmp(swap->req.dest,swap->bobstr) == 0 )
swap->iambob = 1;
else if ( strcmp(swap->req.src,swap->alicestr) != 0 )
{
printf("neither alice nor bob error\n");
return(0);
}
}
else
{
printf("neither src nor dest error\n");
return(0);
}
if ( bits256_nonz(myinfo->persistent_priv) == 0 || instantdex_pubkeyargs(myinfo,swap,2 + INSTANTDEX_DECKSIZE,myinfo->persistent_priv,swap->myhash,0x02+swap->iambob) != 2 + INSTANTDEX_DECKSIZE )
{
printf("couldnt generate privkeys\n");
return(0);
}
return(swap);
}
// end of alice/bob code
void basilisk_swap_finished(struct supernet_info *myinfo,struct basilisk_swap *swap)
{
swap->finished = (uint32_t)time(NULL);
// save to permanent storage
}
void basilisk_swap_purge(struct supernet_info *myinfo,struct basilisk_swap *swap)
{
int32_t i,n;
portable_mutex_lock(&myinfo->DEX_swapmutex);
n = myinfo->numswaps;
for (i=0; i<n; i++)
if ( myinfo->swaps[i] == swap )
{
myinfo->swaps[i] = myinfo->swaps[--myinfo->numswaps];
myinfo->swaps[myinfo->numswaps] = 0;
basilisk_swap_finished(myinfo,swap);
break;
}
portable_mutex_unlock(&myinfo->DEX_swapmutex);
}
void basilisk_swaploop(void *_swap)
{
uint8_t *data; int32_t maxlen,datalen,numconfirms; struct supernet_info *myinfo; struct basilisk_swap *swap = _swap;
myinfo = swap->myinfo;
printf("start swap\n");
maxlen = sizeof(*swap);
data = malloc(maxlen);
while ( time(NULL) < swap->expiration )
{
// iterate swap statemachine
if ( (swap->statebits & 0x01) == 0 ) // wait for pubkeys
{
if ( (datalen= basilisk_channelget(myinfo,myinfo->myaddr.persistent,swap->req.quoteid,0x01,data,maxlen)) == sizeof(swap->otherdeck) )
{
swap->statebits |= 0x01;
}
}
else if ( (swap->statebits & 0x02) == 0 ) // send pubkeys
{
datalen = sizeof(swap->deck);
if ( basilisk_channelsend(myinfo,swap->otherhash,swap->req.quoteid,0x01,data,datalen) == 0 )
swap->statebits |= 0x02;
}
else if ( (swap->statebits & 0x04) == 0 ) // wait for choosei
{
datalen = sizeof(swap->otherchoosei);
if ( (datalen= basilisk_channelget(myinfo,myinfo->myaddr.persistent,swap->req.quoteid,0x04,data,maxlen)) > 0 )
{
// set otherchoosei
swap->statebits |= 0x04;
}
}
else if ( (swap->statebits & 0x08) == 0 ) // send choosei
{
datalen = sizeof(swap->choosei);
if ( basilisk_channelsend(myinfo,swap->otherhash,swap->req.quoteid,0x04,data,datalen) == 0 )
swap->statebits |= 0x08;
}
else if ( (swap->statebits & 0x10) == 0 ) // wait for all but one privkeys
{
if ( (datalen= basilisk_channelget(myinfo,myinfo->myaddr.persistent,swap->req.quoteid,0x10,data,maxlen)) == sizeof(swap->privkeys) )
{
// verify privkeys
swap->statebits |= 0x10;
}
}
else if ( (swap->statebits & 0x20) == 0 ) // send all but one privkeys
{
datalen = sizeof(swap->privkeys);
if ( basilisk_channelsend(myinfo,swap->otherhash,swap->req.quoteid,0x10,data,datalen) == 0 )
swap->statebits |= 0x20;
}
else if ( (swap->statebits & 0x40) == 0 ) // send fee
{
datalen = strlen(swap->myfee->txbytes);
if ( basilisk_channelsend(myinfo,swap->otherhash,swap->req.quoteid,0x80,data,datalen) == 0 )
swap->statebits |= 0x40;
}
else if ( (swap->statebits & 0x80) == 0 ) // wait for fee
{
if ( (datalen= basilisk_channelget(myinfo,myinfo->myaddr.persistent,swap->req.quoteid,0x80,data,maxlen)) > 0 )
{
// verify and submit otherfee
swap->statebits |= 0x80;
}
}
else // both sides have setup required data and paid txfee
{
if ( swap->iambob != 0 )
{
if ( (swap->statebits & 0x100) == 0 )
{
datalen = strlen(swap->deposit->txbytes);
if ( basilisk_channelsend(myinfo,swap->otherhash,swap->req.quoteid,0x200,data,datalen) == 0 )
swap->statebits |= 0x100;
}
// [BLOCKING: altfound] make sure altpayment is confirmed and send payment
else if ( (swap->statebits & 0x1000) == 0 )
{
if ( (datalen= basilisk_channelget(myinfo,myinfo->myaddr.persistent,swap->req.quoteid,0x1000,data,maxlen)) > 0 )
{
// verify alicepayment and submit, set confirmed height
swap->statebits |= 0x1000;
}
}
else if ( (swap->statebits & 0x2000) == 0 )
{
if ( iguana_numconfirms(myinfo,swap->alicecoin,swap->alicepayment->txid) >= swap->aliceconfirms )
swap->statebits |= 0x2000;
}
else if ( (swap->statebits & 0x4000) == 0 )
{
datalen = strlen(swap->payment->txbytes);
if ( basilisk_channelsend(myinfo,swap->otherhash,swap->req.quoteid,0x8000,data,datalen) == 0 )
swap->statebits |= 0x4000;
}
// [BLOCKING: privM] Bob waits for privM either from Alice or alice blockchain
else if ( (swap->statebits & 0x40000) == 0 )
{
if ( (datalen= basilisk_channelget(myinfo,myinfo->myaddr.persistent,swap->req.quoteid,0x40000,data,maxlen)) > 0 )
{
// submit claim
swap->statebits |= 0x40000;
}
else if ( iguana_numconfirms(myinfo,swap->alicecoin,swap->alicepayment->txid) >= 0 )
{
// submit claim
swap->statebits |= 0x40000;
}
else if ( time(NULL) > swap->locktime )
{
// submit reclaim of deposittxid
swap->statebits |= 0x40000;
}
}
else if ( (swap->statebits & 0x80000) == 0 )
{
if ( (numconfirms= iguana_numconfirms(myinfo,swap->alicecoin,swap->alicepayment->txid)) >= 0 )
{
if ( numconfirms >= swap->aliceconfirms )
swap->statebits |= 0x80000;
else printf("detected alicepayment claim numconfirms.%d\n",numconfirms);
}
}
}
else
{
// [BLOCKING: depfound] Alice waits for deposit to confirm and sends altpayment
if ( (swap->statebits & 0x200) == 0 )
{
if ( (datalen= basilisk_channelget(myinfo,myinfo->myaddr.persistent,swap->req.quoteid,0x200,data,maxlen)) > 0 )
{
// verify deposit and submit, set confirmed height
swap->statebits |= 0x200;
}
}
else if ( (swap->statebits & 0x400) == 0 )
{
if ( iguana_numconfirms(myinfo,swap->bobcoin,swap->deposit->txid) >= swap->bobconfirms )
swap->statebits |= 0x400;
}
else if ( (swap->statebits & 0x800) == 0 )
{
datalen = strlen(swap->alicepayment->txbytes);
if ( basilisk_channelsend(myinfo,swap->otherhash,swap->req.quoteid,0x1000,data,datalen) == 0 )
swap->statebits |= 0x800;
}
// [BLOCKING: payfound] make sure payment is confrmed and send in claim or see bob's reclaim and reclaim
else if ( (swap->statebits & 0x8000) == 0 )
{
if ( (datalen= basilisk_channelget(myinfo,myinfo->myaddr.persistent,swap->req.quoteid,0x8000,data,maxlen)) > 0 )
{
// verify payment and submit, set confirmed height
swap->statebits |= 0x8000;
}
else if ( iguana_numconfirms(myinfo,swap->bobcoin,swap->deposit->txid) >= 0 )
{
// reclaim and exit
swap->reclaimed = 1;
swap->statebits |= 0x8000;
}
}
else if ( (swap->statebits & 0x10000) == 0 )
{
if ( swap->reclaim != 0 )
{
if ( iguana_numconfirms(myinfo,swap->alicecoin,swap->reclaim->txid) >= swap->aliceconfirms )
swap->statebits |= 0x10000;
}
else if ( iguana_numconfirms(myinfo,swap->bobcoin,swap->payment->txid) >= swap->bobconfirms )
swap->statebits |= 0x10000;
}
else if ( (swap->statebits & 0x20000) == 0 )
{
// send privM
// submit claim
datalen = sizeof(swap->privAm);
if ( basilisk_channelsend(myinfo,swap->otherhash,swap->req.quoteid,0x40000,data,datalen) == 0 )
swap->statebits |= 0x20000;
}
else if ( (swap->statebits & 0x40000) == 0 )
{
if ( iguana_numconfirms(myinfo,swap->alicecoin,swap->payment->txid) >= swap->bobconfirms )
swap->statebits |= 0x40000;
}
}
}
sleep(3);
}
printf("swap finished statebits %x\n",swap->statebits);
basilisk_swap_purge(myinfo,swap);
}
struct basilisk_swap *basilisk_thread_start(struct supernet_info *myinfo,struct basilisk_request *rp)
{
int32_t i; struct basilisk_swap *swap = 0;
portable_mutex_lock(&myinfo->DEX_swapmutex);
for (i=0; i<myinfo->numswaps; i++)
if ( myinfo->swaps[i]->req.requestid == rp->requestid )
{
printf("basilisk_thread_start error trying to start requestid.%u which is already started\n",rp->requestid);
break;
}
if ( i == myinfo->numswaps && i < sizeof(myinfo->swaps)/sizeof(*myinfo->swaps) )
{
swap = calloc(1,sizeof(*swap));
swap->req = *rp;
swap->myinfo = myinfo;
if ( bitcoin_swapinit(myinfo,swap) != 0 )
{
myinfo->swaps[myinfo->numswaps++] = swap;
iguana_launch(iguana_coinfind("BTCD"),"basilisk_swaploop",basilisk_swaploop,swap,IGUANA_PERMTHREAD);
} else free(swap), swap = 0;
}
portable_mutex_unlock(&myinfo->DEX_swapmutex);
return(swap);
}
struct basilisk_swap *basilisk_request_started(struct supernet_info *myinfo,uint32_t requestid)
{
int32_t i; struct basilisk_swap *active = 0;
portable_mutex_lock(&myinfo->DEX_swapmutex);
for (i=0; i<myinfo->numswaps; i++)
if ( myinfo->swaps[i]->req.requestid == requestid )
{
active = myinfo->swaps[i];
break;
}
portable_mutex_unlock(&myinfo->DEX_swapmutex);
return(active);
}

116
iguana/iguana_instantdex.c → deprecated/iguana_instantdex.c

@ -503,106 +503,6 @@ 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 i; struct exchange_quote *quote;
//printf("instantdex_updatesources.%s update dir.%d numquotes.%d\n",exchange->name,dir,numquotes);
for (i=0; i<numquotes; i++)
{
quote = &quotes[i << 1];
//printf("n.%d ind.%d i.%d dir.%d price %.8f vol %.8f\n",n,ind,i,dir,quote->price,quote->volume);
if ( quote->price > SMALLVAL )
{
sortbuf[n] = *quote;
sortbuf[n].val = ind;
sortbuf[n].exchangebits = exchange->exchangebits;
//printf("sortbuf[%d] <-\n",n*2);
if ( ++n >= max )
break;
}
}
return(n);
}
double instantdex_aveprice(struct supernet_info *myinfo,struct exchange_quote *sortbuf,int32_t max,double *totalvolp,char *base,char *rel,double basevolume,cJSON *argjson)
{
char *str; double totalvol,pricesum; uint32_t timestamp;
struct exchange_quote quote; int32_t i,n,dir,num,depth = 100;
struct exchange_info *exchange; struct exchange_request *req,*active[64];
timestamp = (uint32_t)time(NULL);
if ( basevolume < 0. )
basevolume = -basevolume, dir = -1;
else dir = 1;
memset(sortbuf,0,sizeof(*sortbuf) * max);
if ( base != 0 && rel != 0 && basevolume > SMALLVAL )
{
for (i=num=0; i<myinfo->numexchanges && num < sizeof(active)/sizeof(*active); i++)
{
if ( (exchange= myinfo->tradingexchanges[i]) != 0 )
{
if ( (req= exchanges777_baserelfind(exchange,base,rel,'M')) == 0 )
{
if ( (str= exchanges777_Qprices(exchange,base,rel,30,1,depth,argjson,1,exchange->commission)) != 0 )
free(str);
req = exchanges777_baserelfind(exchange,base,rel,'M');
}
if ( req == 0 )
{
if ( (*exchange->issue.supports)(exchange,base,rel,argjson) != 0 )
printf("unexpected null req.(%s %s) %s\n",base,rel,exchange->name);
}
else
{
//printf("active.%s\n",exchange->name);
active[num++] = req;
}
}
}
for (i=n=0; i<num; i++)
{
if ( dir < 0 && active[i]->numbids > 0 )
n = instantdex_updatesources(active[i]->exchange,sortbuf,n,max,i,1,active[i]->bidasks,active[i]->numbids);
else if ( dir > 0 && active[i]->numasks > 0 )
n = instantdex_updatesources(active[i]->exchange,sortbuf,n,max,i,-1,&active[i]->bidasks[1],active[i]->numasks);
}
//printf("dir.%d %s/%s numX.%d n.%d\n",dir,base,rel,num,n);
if ( dir < 0 )
revsort64s(&sortbuf[0].satoshis,n,sizeof(*sortbuf));
else sort64s(&sortbuf[0].satoshis,n,sizeof(*sortbuf));
for (totalvol=pricesum=i=0; i<n && totalvol < basevolume; i++)
{
quote = sortbuf[i];
//printf("n.%d i.%d price %.8f %.8f %.8f\n",n,i,dstr(sortbuf[i].satoshis),sortbuf[i].price,quote.volume);
if ( quote.satoshis != 0 )
{
pricesum += (quote.price * quote.volume);
totalvol += quote.volume;
printf("i.%d of %d %12.8f vol %.8f %s | aveprice %.8f total vol %.8f\n",i,n,sortbuf[i].price,quote.volume,active[quote.val]->exchange->name,pricesum/totalvol,totalvol);
}
}
if ( totalvol > 0. )
{
*totalvolp = totalvol;
return(pricesum / totalvol);
}
}
*totalvolp = 0;
return(0);
}
double instantdex_avehbla(struct supernet_info *myinfo,double retvals[4],char *base,char *rel,double basevolume)
{
double avebid,aveask,bidvol,askvol; struct exchange_quote sortbuf[256]; cJSON *argjson;
argjson = cJSON_CreateObject();
aveask = instantdex_aveprice(myinfo,sortbuf,sizeof(sortbuf)/sizeof(*sortbuf),&askvol,base,rel,basevolume,argjson);
avebid = instantdex_aveprice(myinfo,sortbuf,sizeof(sortbuf)/sizeof(*sortbuf),&bidvol,base,rel,-basevolume,argjson);
free_json(argjson);
retvals[0] = avebid, retvals[1] = bidvol, retvals[2] = aveask, retvals[3] = askvol;
if ( avebid > SMALLVAL && aveask > SMALLVAL )
return((avebid + aveask) * .5);
else return(0);
}
int32_t instantdex_bidaskdir(struct instantdex_offer *offer)
{
if ( offer->myside == 0 && offer->acceptdir > 0 ) // base
@ -1567,6 +1467,7 @@ void instantdex_update(struct supernet_info *myinfo)
}*/
}
/*
#include "../includes/iguana_apidefs.h"
TWO_STRINGS_AND_TWO_DOUBLES(InstantDEX,maxaccept,base,rel,maxprice,basevolume)
@ -1656,19 +1557,6 @@ THREE_STRINGS(atomic,claim,myorderid,otherid,txname)
}
}
THREE_STRINGS_AND_DOUBLE(tradebot,aveprice,comment,base,rel,basevolume)
{
double retvals[4],aveprice; cJSON *retjson = cJSON_CreateObject();
aveprice = instantdex_avehbla(myinfo,retvals,base,rel,basevolume);
jaddstr(retjson,"result","success");
jaddnum(retjson,"aveprice",aveprice);
jaddnum(retjson,"avebid",retvals[0]);
jaddnum(retjson,"bidvol",retvals[1]);
jaddnum(retjson,"aveask",retvals[2]);
jaddnum(retjson,"askvol",retvals[3]);
return(jprint(retjson,1));
}
cJSON *instantdex_reportjson(cJSON *item,char *name)
{
cJSON *newjson = cJSON_CreateObject(); uint64_t dateval;
@ -1719,4 +1607,4 @@ TWO_STRINGS(InstantDEX,events,base,rel)
}
#include "../includes/iguana_apiundefs.h"
*/

38
deprecated/obsolete.h

@ -18214,6 +18214,44 @@ len = 0;
return(basilisk_waitresponse(myinfo,"RAW",coin->symbol,remoteaddr,&Lptr,vals,ptr));
} else return(clonestr("{\"error\":\"error issuing basilisk rawtx\"}"));
} //else return(retstr);*/
/*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;
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,rp->hash,rp->src,rp->srcamount*aveprice,myinfo->myaddr.persistent,rp->dest,rp->srcamount*aveprice,message,quoteid) != rp->requestid )
printf("error creating quoteid\n");
}
}
}*/
#endif
#endif

33
iguana/exchanges/bitcoin.c

@ -418,7 +418,7 @@ double UPDATE(struct exchange_info *exchange,char *base,char *rel,struct exchang
myinfo = SuperNET_MYINFO(0);
bids = cJSON_CreateArray();
asks = cJSON_CreateArray();
instantdex_offerfind(myinfo,exchange,bids,asks,0,base,rel,0);
//instantdex_offerfind(myinfo,exchange,bids,asks,0,base,rel,0);
//printf("bids.(%s) asks.(%s)\n",jprint(bids,0),jprint(asks,0));
retjson = cJSON_CreateObject();
cJSON_AddItemToObject(retjson,"bids",bids);
@ -494,12 +494,12 @@ int32_t is_valid_BTCother(char *other)
uint64_t TRADE(int32_t dotrade,char **retstrp,struct exchange_info *exchange,char *base,char *rel,int32_t dir,double price,double volume,cJSON *argjson)
{
char *str,*retstr,coinaddr[64]; int32_t added; uint64_t txid = 0; cJSON *json=0; struct instantdex_accept *ap; struct supernet_info *myinfo; struct iguana_info *other;
myinfo = SuperNET_MYINFO(0);//SuperNET_accountfind(argjson);
//char *str,*retstr,coinaddr[64]; int32_t added; uint64_t txid = 0; cJSON *json=0; struct instantdex_accept *ap; struct supernet_info *myinfo; struct iguana_info *other;
//myinfo = SuperNET_MYINFO(0);//SuperNET_accountfind(argjson);
//printf("TRADE with myinfo.%p\n",myinfo);
if ( retstrp != 0 )
*retstrp = 0;
if ( strcmp(base,"BTC") == 0 || strcmp(base,"btc") == 0 )
/*if ( strcmp(base,"BTC") == 0 || strcmp(base,"btc") == 0 )
{
base = rel;
rel = "BTC";
@ -547,32 +547,35 @@ uint64_t TRADE(int32_t dotrade,char **retstrp,struct exchange_info *exchange,cha
*retstrp = retstr;
}
}
return(txid);
return(txid);*/
return(0);
}
char *ORDERSTATUS(struct exchange_info *exchange,uint64_t orderid,cJSON *argjson)
{
struct instantdex_accept *ap; struct bitcoin_swapinfo *swap; cJSON *retjson;
//struct instantdex_accept *ap; struct bitcoin_swapinfo *swap;
cJSON *retjson;
retjson = cJSON_CreateObject();
struct supernet_info *myinfo;// = SuperNET_accountfind(argjson);
myinfo = SuperNET_MYINFO(0);//SuperNET_accountfind(argjson);
if ( (swap= instantdex_statemachinefind(myinfo,exchange,orderid)) != 0 )
/*if ( (swap= instantdex_statemachinefind(myinfo,exchange,orderid)) != 0 )
jadd(retjson,"result",instantdex_statemachinejson(swap));
else if ( (ap= instantdex_offerfind(myinfo,exchange,0,0,orderid,"*","*",0)) != 0 )
jadd(retjson,"result",instantdex_acceptjson(ap));
else if ( (swap= instantdex_historyfind(myinfo,exchange,orderid)) != 0 )
jadd(retjson,"result",instantdex_historyjson(swap));
else jaddstr(retjson,"error","couldnt find orderid");
else jaddstr(retjson,"error","couldnt find orderid");*/
return(jprint(retjson,1));
}
char *CANCELORDER(struct exchange_info *exchange,uint64_t orderid,cJSON *argjson)
{
struct instantdex_accept *ap = 0; cJSON *retjson; struct bitcoin_swapinfo *swap=0;
struct supernet_info *myinfo;// = SuperNET_accountfind(argjson);
myinfo = SuperNET_MYINFO(0);//SuperNET_accountfind(argjson);
//struct instantdex_accept *ap = 0; struct bitcoin_swapinfo *swap=0;
cJSON *retjson;
//struct supernet_info *myinfo;// = SuperNET_accountfind(argjson);
//myinfo = SuperNET_MYINFO(0);//SuperNET_accountfind(argjson);
retjson = cJSON_CreateObject();
if ( (ap= instantdex_offerfind(myinfo,exchange,0,0,orderid,"*","*",0)) != 0 )
/*if ( (ap= instantdex_offerfind(myinfo,exchange,0,0,orderid,"*","*",0)) != 0 )
{
ap->dead = (uint32_t)time(NULL);
jadd(retjson,"orderid",instantdex_acceptjson(ap));
@ -582,7 +585,7 @@ char *CANCELORDER(struct exchange_info *exchange,uint64_t orderid,cJSON *argjson
{
jadd(retjson,"orderid",instantdex_statemachinejson(swap));
jaddstr(retjson,"result","killed statemachine orderid, but might have pending");
}
}*/
return(jprint(retjson,1));
}
@ -592,7 +595,7 @@ char *OPENORDERS(struct exchange_info *exchange,cJSON *argjson)
myinfo = SuperNET_MYINFO(0);//SuperNET_accountfind(argjson);
bids = cJSON_CreateArray();
asks = cJSON_CreateArray();
instantdex_offerfind(myinfo,exchange,bids,asks,0,"*","*",0);
//instantdex_offerfind(myinfo,exchange,bids,asks,0,"*","*",0);
retjson = cJSON_CreateObject();
jaddstr(retjson,"result","success");
jadd(retjson,"bids",bids);
@ -606,7 +609,7 @@ char *TRADEHISTORY(struct exchange_info *exchange,cJSON *argjson)
portable_mutex_lock(&exchange->mutexH);
DL_FOREACH_SAFE(exchange->history,swap,tmp)
{
jaddi(retjson,instantdex_historyjson(swap));
//jaddi(retjson,instantdex_historyjson(swap));
}
portable_mutex_unlock(&exchange->mutexH);
return(jprint(retjson,1));

11
iguana/exchanges777.h

@ -42,7 +42,7 @@
#define INSTANTDEX_MINPERC 50
#define INSTANTDEX_OFFERDURATION 600
#define INSTANTDEX_LOCKTIME 360
//#define INSTANTDEX_LOCKTIME 3600
#define EXCHANGES777_MINPOLLGAP 1
#define EXCHANGES777_MAXDEPTH 200
@ -133,13 +133,6 @@ struct instantdex_accept
struct instantdex_offer offer;
};
struct bitcoin_statetx
{
bits256 txid;
uint64_t amount,change,inputsum;
char destaddr[64];
char txbytes[];
};
struct instantdex_stateinfo
{
@ -155,7 +148,7 @@ struct bitcoin_eventitem { struct queueitem DL; cJSON *argjson,*newjson; int32_t
struct bitcoin_swapinfo
{
struct bitcoin_swapinfo *next,*prev; portable_mutex_t mutex;
queue_t eventsQ; struct bitcoin_eventitem *pollevent;
queue_t eventsQ; //struct bitcoin_eventitem *pollevent;
bits256 privkeys[INSTANTDEX_DECKSIZE],myprivs[2],mypubs[2],otherpubs[2],pubA0,pubB0,pubB1,privAm,pubAm,privBn,pubBn;
bits256 myorderhash,otherorderhash,mypubkey,othertrader,bothorderhash;
uint64_t otherdeck[INSTANTDEX_DECKSIZE][2],deck[INSTANTDEX_DECKSIZE][2];

2
iguana/iguana.sources

@ -1,2 +1,2 @@
SOURCES := iguana_bundles.c iguana_stake.c iguana_interpreter.c mini-gmp.c main.c iguana_payments.c iguana_spendvectors.c iguana_sign.c iguana_txidfind.c iguana_realtime.c iguana_volatiles.c peggy_price.c iguana_chains.c iguana_ramchain.c iguana_secp.c pangea_api.c peggy_ramkv.c iguana_exchanges.c iguana_recv.c pangea_bets.c peggy_serdes.c SuperNET_keys.c iguana_rpc.c pangea_hand.c peggy_tx.c cards777.c iguana_init.c iguana_scripts.c pangea_json.c peggy_txind.c iguana777.c iguana_instantdex.c iguana_tradebots.c pangea_summary.c peggy_update.c iguana_accept.c iguana_json.c iguana_tx.c peggy.c poker.c iguana_bitmap.c iguana_msg.c iguana_unspents.c peggy_accts.c ramchain_api.c iguana_blocks.c iguana_peers.c iguana_wallet.c peggy_consensus.c ../gecko/gecko.c ../basilisk/basilisk.c ../datachain/datachain.c secp256k1/src/secp256k1.c
SOURCES := iguana_bundles.c iguana_stake.c iguana_interpreter.c mini-gmp.c main.c iguana_payments.c iguana_spendvectors.c iguana_sign.c iguana_txidfind.c iguana_realtime.c iguana_volatiles.c peggy_price.c iguana_chains.c iguana_ramchain.c iguana_secp.c pangea_api.c peggy_ramkv.c iguana_exchanges.c iguana_recv.c pangea_bets.c peggy_serdes.c SuperNET_keys.c iguana_rpc.c pangea_hand.c peggy_tx.c cards777.c iguana_init.c iguana_scripts.c pangea_json.c peggy_txind.c iguana777.c iguana_tradebots.c pangea_summary.c peggy_update.c iguana_accept.c iguana_json.c iguana_tx.c peggy.c poker.c iguana_bitmap.c iguana_msg.c iguana_unspents.c peggy_accts.c ramchain_api.c iguana_blocks.c iguana_peers.c iguana_wallet.c peggy_consensus.c ../gecko/gecko.c ../basilisk/basilisk.c ../datachain/datachain.c secp256k1/src/secp256k1.c

6
iguana/iguana_accept.c

@ -110,7 +110,7 @@ void iguana_acceptloop(void *args)
coin->peers->active[i].A.port = cli_addr.sin_port;
coin->peers->active[i].ready = (uint32_t)time(NULL);
flag = 1;
instantdex_peerhas_clear(coin,&coin->peers->active[i]);
//instantdex_peerhas_clear(coin,&coin->peers->active[i]);
//iguana_iAkill(coin,&coin->peers->active[i],0);
//sleep(1);
break;
@ -233,7 +233,7 @@ int32_t iguana_process_msgrequestQ(struct supernet_info *myinfo,struct iguana_in
{
}
else if ( msg->type == MSG_QUOTE )
/*else if ( msg->type == MSG_QUOTE )
{
if ( (len= instantdex_quoterequest(myinfo,coin,&coin->blockspace[sizeof(struct iguana_msghdr)],coin->blockspacesize,msg->addr,msg->hash2)) > 0 )
{
@ -241,7 +241,7 @@ int32_t iguana_process_msgrequestQ(struct supernet_info *myinfo,struct iguana_in
//iguana_msgparser(coin,msg->addr,0,0,0,(void *)coin->blockspace,&coin->blockspace[sizeof(struct iguana_msghdr)],len);
iguana_queue_send(msg->addr,0,coin->blockspace,"quote",len);
}
}
}*/
}
free(msg);
}

3
iguana/iguana_chains.c

@ -300,6 +300,8 @@ void iguana_chainparms(struct iguana_chain *chain,cJSON *argjson)
chain->estblocktime = juint(argjson,"blocktime");
if ( chain->estblocktime == 0 )
chain->estblocktime = 60;
if ( chain->havecltv == 0 )
chain->havecltv = juint(argjson,"havecltv");
path = jstr(argjson,"path");
if ( jobj(argjson,"conf") == 0 )
conf[0] = 0;
@ -451,6 +453,7 @@ void iguana_chaininit(struct iguana_chain *chain,int32_t hasheaders,cJSON *argjs
{
chain->unitval = 0x1d;
chain->txfee = 10000;
chain->havecltv = 1;
}
else chain->txfee = 1000000;
if ( chain->unitval == 0 )

110
iguana/iguana_exchanges.c

@ -22,6 +22,106 @@
//char *Exchange_names[] = { "poloniex", "bittrex", "btc38", "huobi", "bitstamp", "bitfinex", "btce", "coinbase", "okcoin", "lakebtc", "quadriga", "truefx", "ecb", "instaforex", "fxcm", "yahoo" };
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;
//printf("instantdex_updatesources.%s update dir.%d numquotes.%d\n",exchange->name,dir,numquotes);
for (i=0; i<numquotes; i++)
{
quote = &quotes[i << 1];
//printf("n.%d ind.%d i.%d dir.%d price %.8f vol %.8f\n",n,ind,i,dir,quote->price,quote->volume);
if ( quote->price > SMALLVAL )
{
sortbuf[n] = *quote;
sortbuf[n].val = ind;
sortbuf[n].exchangebits = exchange->exchangebits;
//printf("sortbuf[%d] <-\n",n*2);
if ( ++n >= max )
break;
}
}
return(n);
}
double instantdex_aveprice(struct supernet_info *myinfo,struct exchange_quote *sortbuf,int32_t max,double *totalvolp,char *base,char *rel,double basevolume,cJSON *argjson)
{
char *str; double totalvol,pricesum; uint32_t timestamp;
struct exchange_quote quote; int32_t i,n,dir,num,depth = 100;
struct exchange_info *exchange; struct exchange_request *req,*active[64];
timestamp = (uint32_t)time(NULL);
if ( basevolume < 0. )
basevolume = -basevolume, dir = -1;
else dir = 1;
memset(sortbuf,0,sizeof(*sortbuf) * max);
if ( base != 0 && rel != 0 && basevolume > SMALLVAL )
{
for (i=num=0; i<myinfo->numexchanges && num < sizeof(active)/sizeof(*active); i++)
{
if ( (exchange= myinfo->tradingexchanges[i]) != 0 )
{
if ( (req= exchanges777_baserelfind(exchange,base,rel,'M')) == 0 )
{
if ( (str= exchanges777_Qprices(exchange,base,rel,30,1,depth,argjson,1,exchange->commission)) != 0 )
free(str);
req = exchanges777_baserelfind(exchange,base,rel,'M');
}
if ( req == 0 )
{
if ( (*exchange->issue.supports)(exchange,base,rel,argjson) != 0 )
printf("unexpected null req.(%s %s) %s\n",base,rel,exchange->name);
}
else
{
//printf("active.%s\n",exchange->name);
active[num++] = req;
}
}
}
for (i=n=0; i<num; i++)
{
if ( dir < 0 && active[i]->numbids > 0 )
n = instantdex_updatesources(active[i]->exchange,sortbuf,n,max,i,1,active[i]->bidasks,active[i]->numbids);
else if ( dir > 0 && active[i]->numasks > 0 )
n = instantdex_updatesources(active[i]->exchange,sortbuf,n,max,i,-1,&active[i]->bidasks[1],active[i]->numasks);
}
//printf("dir.%d %s/%s numX.%d n.%d\n",dir,base,rel,num,n);
if ( dir < 0 )
revsort64s(&sortbuf[0].satoshis,n,sizeof(*sortbuf));
else sort64s(&sortbuf[0].satoshis,n,sizeof(*sortbuf));
for (totalvol=pricesum=i=0; i<n && totalvol < basevolume; i++)
{
quote = sortbuf[i];
//printf("n.%d i.%d price %.8f %.8f %.8f\n",n,i,dstr(sortbuf[i].satoshis),sortbuf[i].price,quote.volume);
if ( quote.satoshis != 0 )
{
pricesum += (quote.price * quote.volume);
totalvol += quote.volume;
printf("i.%d of %d %12.8f vol %.8f %s | aveprice %.8f total vol %.8f\n",i,n,sortbuf[i].price,quote.volume,active[quote.val]->exchange->name,pricesum/totalvol,totalvol);
}
}
if ( totalvol > 0. )
{
*totalvolp = totalvol;
return(pricesum / totalvol);
}
}
*totalvolp = 0;
return(0);
}
double instantdex_avehbla(struct supernet_info *myinfo,double retvals[4],char *base,char *rel,double basevolume)
{
double avebid,aveask,bidvol,askvol; struct exchange_quote sortbuf[256]; cJSON *argjson;
argjson = cJSON_CreateObject();
aveask = instantdex_aveprice(myinfo,sortbuf,sizeof(sortbuf)/sizeof(*sortbuf),&askvol,base,rel,basevolume,argjson);
avebid = instantdex_aveprice(myinfo,sortbuf,sizeof(sortbuf)/sizeof(*sortbuf),&bidvol,base,rel,-basevolume,argjson);
free_json(argjson);
retvals[0] = avebid, retvals[1] = bidvol, retvals[2] = aveask, retvals[3] = askvol;
if ( avebid > SMALLVAL && aveask > SMALLVAL )
return((avebid + aveask) * .5);
else return(0);
}
void prices777_processprice(struct exchange_info *exchange,char *base,char *rel,struct exchange_quote *bidasks,int32_t maxdepth)
{
@ -583,7 +683,7 @@ char *exchanges777_process(struct exchange_info *exchange,int32_t *retvalp,struc
return(retstr);
}
void iguana_statemachineupdate(struct supernet_info *myinfo,struct exchange_info *exchange)
/*void iguana_statemachineupdate(struct supernet_info *myinfo,struct exchange_info *exchange)
{
int32_t timemod,modwidth = 10; struct iguana_info *coin; struct bitcoin_swapinfo *swap,*tmp; struct iguana_bundlereq *req;
timemod = time(NULL) % modwidth;
@ -603,7 +703,7 @@ void iguana_statemachineupdate(struct supernet_info *myinfo,struct exchange_info
myfree(req->hashes,(req->n+1) * sizeof(*req->hashes)), req->hashes = 0;
}
//iguana_inv2poll(myinfo,coin);
}
}*/
void exchanges777_loop(void *ptr)
{
@ -680,11 +780,11 @@ void exchanges777_loop(void *ptr)
tradebot_timeslices(exchange);
if ( time(NULL) > exchange->lastpoll+exchange->pollgap )
{
if ( strcmp(exchange->name,"bitcoin") == 0 )
/*if ( strcmp(exchange->name,"bitcoin") == 0 )
{
iguana_statemachineupdate(myinfo,exchange);
//printf("InstantDEX call update\n");
}
}*/
if ( (req= queue_dequeue(&exchange->pricesQ,0)) != 0 )
{
//printf("check %s pricesQ (%s %s)\n",exchange->name,req->base,req->rel);
@ -943,7 +1043,7 @@ struct exchange_info *exchange_create(char *exchangestr,cJSON *argjson)
exchange->commission *= .01;
printf("ADDEXCHANGE.(%s) [%s, %s, %s] commission %.3f%% -> exchangeid.%d\n",exchangestr,exchange->apikey,exchange->userid,exchange->apisecret,exchange->commission * 100.,exchangeid);
Exchanges[exchangeid] = exchange;
instantdex_FSMinit();
//instantdex_FSMinit();
iguana_launch(0,"exchangeloop",(void *)exchanges777_loop,exchange,IGUANA_EXCHANGETHREAD);
return(exchange);
}

4
iguana/iguana_msg.c

@ -761,7 +761,7 @@ int32_t iguana_intvectors(struct iguana_info *coin,struct iguana_peer *addr,int3
}
blockhashes[n++] = hash;
}
else if ( type == MSG_QUOTE )
/*else if ( type == MSG_QUOTE )
{
if ( quotes == 0 )
{
@ -769,7 +769,7 @@ int32_t iguana_intvectors(struct iguana_info *coin,struct iguana_peer *addr,int3
q = 1;
}
quotes[q++] = hash;
}
}*/
else if ( type == MSG_FILTERED_BLOCK )
printf(" %d of %d: merkle.%llx\n",i,(int32_t)x,(long long)hash.txid);
else printf("what type is %d\n",type);

2
iguana/iguana_peers.c

@ -1147,7 +1147,7 @@ void iguana_dedicatedloop(struct supernet_info *myinfo,struct iguana_info *coin,
printf("error creating peer's files\n");
return;
}
instantdex_peerhas_clear(coin,addr);
//instantdex_peerhas_clear(coin,addr);
#ifdef IGUANA_PEERALLOC
int32_t i; int64_t remaining; struct OS_memspace *mem[sizeof(addr->SEROUT)/sizeof(*addr->SEROUT)];
for (i=0; i<sizeof(addr->SEROUT)/sizeof(*addr->SEROUT); i++)

54
iguana/iguana_scripts.c

@ -95,6 +95,60 @@ int32_t bitcoin_p2shscript(uint8_t *script,int32_t n,const uint8_t *p2shscript,c
return(n);
}
int32_t instantdex_bobscript(uint8_t *script,int32_t n,uint32_t *locktimep,int32_t *secretstartp,struct basilisk_swap *swap,int32_t depositflag)
{
uint8_t pubkeyA[33],pubkeyB[33],*secret160; bits256 cltvpub,destpub; int32_t i;
*locktimep = swap->locktime;
if ( depositflag != 0 )
{
*locktimep += INSTANTDEX_LOCKTIME;
cltvpub = swap->pubA0;
destpub = swap->pubB0;
secret160 = swap->secretBn;
pubkeyA[0] = 0x02;
pubkeyB[0] = 0x03;
}
else
{
cltvpub = swap->pubB1;
destpub = swap->pubA0;
secret160 = swap->secretAm;
pubkeyA[0] = 0x03;
pubkeyB[0] = 0x02;
}
if ( bits256_nonz(cltvpub) == 0 || bits256_nonz(destpub) == 0 )
return(-1);
for (i=0; i<20; i++)
if ( secret160[i] != 0 )
break;
if ( i == 20 )
return(-1);
memcpy(pubkeyA+1,cltvpub.bytes,sizeof(cltvpub));
memcpy(pubkeyB+1,destpub.bytes,sizeof(destpub));
script[n++] = SCRIPT_OP_IF;
n = bitcoin_checklocktimeverify(script,n,*locktimep);
n = bitcoin_pubkeyspend(script,n,pubkeyA);
script[n++] = SCRIPT_OP_ELSE;
if ( secretstartp != 0 )
*secretstartp = n + 2;
n = bitcoin_revealsecret160(script,n,secret160);
n = bitcoin_pubkeyspend(script,n,pubkeyB);
script[n++] = SCRIPT_OP_ENDIF;
return(n);
}
int32_t instantdex_alicescript(uint8_t *script,int32_t n,char *msigaddr,uint8_t altps2h,bits256 pubAm,bits256 pubBn)
{
uint8_t p2sh160[20]; struct vin_info V;
memset(&V,0,sizeof(V));
memcpy(&V.signers[0].pubkey[1],pubAm.bytes,sizeof(pubAm)), V.signers[0].pubkey[0] = 0x02;
memcpy(&V.signers[1].pubkey[1],pubBn.bytes,sizeof(pubBn)), V.signers[1].pubkey[0] = 0x03;
V.M = V.N = 2;
n = bitcoin_MofNspendscript(p2sh160,script,n,&V);
bitcoin_address(msigaddr,altps2h,p2sh160,sizeof(p2sh160));
return(n);
}
int32_t bitcoin_changescript(struct iguana_info *coin,uint8_t *changescript,int32_t n,uint64_t *changep,char *changeaddr,uint64_t inputsatoshis,uint64_t satoshis,uint64_t txfee)
{
uint8_t addrtype,rmd160[20]; int32_t len;

4
iguana/swaps/iguana_BTCswap.c

@ -1120,12 +1120,12 @@ char *instantdex_statemachine(struct instantdex_stateinfo *states,int32_t numsta
}
else
{
if ( 0 && strcmp(cmdstr,"poll") != 0 )
/*if ( 0 && strcmp(cmdstr,"poll") != 0 )
{
if ( swap->pollevent != 0 )
instantdex_eventfree(swap->pollevent);
swap->pollevent = instantdex_event("poll",argjson,newjson,serdata,serdatalen);
}
}*/
if ( jstr(newjson,"virtevent") != 0 )
{
printf("VIRTEVENT.(%s)\n",jstr(newjson,"virtevent"));

24
includes/iguana_apideclares.h

@ -15,20 +15,22 @@
ZERO_ARGS(InstantDEX,allcoins);
STRING_ARG(InstantDEX,available,source);
THREE_STRINGS_AND_DOUBLE(InstantDEX,request,message,dest,source,amount);
//THREE_STRINGS_AND_THREE_DOUBLES(InstantDEX,request,message,dest,source,amount,mindestamount,autoflag);
HASH_ARRAY_STRING(InstantDEX,request,hash,vals,hexstr);
INT_ARG(InstantDEX,incoming,requestid);
INT_AND_DOUBLE(InstantDEX,choose,requestid,destamount);
TWO_INTS(InstantDEX,qstatus,requestid,quoteid);
TWO_INTS(InstantDEX,accept,requestid,quoteid);
TWO_INTS(InstantDEX,swapstatus,requestid,quoteid);
HASH_ARRAY_STRING(basilisk,genesis_opreturn,hash,vals,hexstr);
HASH_ARRAY_STRING(basilisk,balances,hash,vals,hexstr);
HASH_ARRAY_STRING(basilisk,value,hash,vals,hexstr);
HASH_ARRAY_STRING(basilisk,rawtx,hash,vals,hexstr);
//INT_AND_ARRAY(basilisk,result,basilisktag,vals);
//HASH_ARRAY_STRING(basilisk,geckogenesis,hash,vals,hexstr);
//HASH_ARRAY_STRING(basilisk,newgeckochain,hash,vals,hexstr);
HASH_ARRAY_STRING(basilisk,getmessage,hash,vals,hexstr);
HASH_ARRAY_STRING(basilisk,sendmessage,hash,vals,hexstr);
HASH_ARRAY_STRING(basilisk,geckoheaders,hash,vals,hexstr);
HASH_ARRAY_STRING(basilisk,geckoblock,hash,vals,hexstr);
HASH_ARRAY_STRING(basilisk,geckotx,hash,vals,hexstr);
@ -138,8 +140,8 @@ P2SH_SPENDAPI(iguana,spendmsig,activecoin,vintxid,vinvout,destaddress,destamount
STRING_AND_INT(iguana,bundleaddresses,activecoin,height);
STRING_AND_INT(iguana,bundlehashes,activecoin,height);
TWO_STRINGS_AND_TWO_DOUBLES(InstantDEX,minaccept,base,rel,minprice,basevolume);
TWO_STRINGS_AND_TWO_DOUBLES(InstantDEX,maxaccept,base,rel,maxprice,basevolume);
//TWO_STRINGS_AND_TWO_DOUBLES(InstantDEX,minaccept,base,rel,minprice,basevolume);
//TWO_STRINGS_AND_TWO_DOUBLES(InstantDEX,maxaccept,base,rel,maxprice,basevolume);
THREE_STRINGS_AND_THREE_DOUBLES(InstantDEX,buy,exchange,base,rel,price,volume,dotrade);
THREE_STRINGS_AND_THREE_DOUBLES(InstantDEX,sell,exchange,base,rel,price,volume,dotrade);
THREE_STRINGS_AND_DOUBLE(InstantDEX,withdraw,exchange,base,destaddr,amount);
@ -153,13 +155,13 @@ STRING_ARG(InstantDEX,tradehistory,exchange);
THREE_STRINGS_AND_THREE_INTS(InstantDEX,orderbook,exchange,base,rel,depth,allfields,ignore);
STRING_AND_INT(InstantDEX,pollgap,exchange,pollgap);
TWO_STRINGS(InstantDEX,events,base,rel);
//TWO_STRINGS(InstantDEX,events,base,rel);
ZERO_ARGS(InstantDEX,allexchanges);
STRING_ARG(InstantDEX,allpairs,exchange);
THREE_STRINGS(InstantDEX,supports,exchange,base,rel);
THREE_STRINGS(atomic,approve,myorderid,otherid,txname);
THREE_STRINGS(atomic,claim,myorderid,otherid,txname);
//THREE_STRINGS(atomic,approve,myorderid,otherid,txname);
//THREE_STRINGS(atomic,claim,myorderid,otherid,txname);
//TWOSTRINGS_AND_TWOHASHES_AND_TWOINTS(InstantDEX,proposal,reference,message,basetxid,reltxid,duration,flags);
//TWOSTRINGS_AND_TWOHASHES_AND_TWOINTS(InstantDEX,accept,reference,message,basetxid,reltxid,duration,flags);

2
includes/iguana_defines.h

@ -150,7 +150,7 @@ extern int32_t IGUANA_NUMHELPERS;
#define MSG_TX 1
#define MSG_BLOCK 2
#define MSG_FILTERED_BLOCK 3
#define MSG_QUOTE 253
//#define MSG_QUOTE 253
#define MSG_BUNDLE 254
#define MSG_BUNDLE_HEADERS 255

6
includes/iguana_structs.h

@ -49,7 +49,7 @@ struct iguana_chain
char use_addmultisig,do_opreturn;
int32_t estblocktime,protover;
bits256 genesishash2,PoWtarget,PoStargets[16]; int32_t numPoStargets,PoSheights[16];
uint8_t zcash,auxpow,alertpubkey[65];
uint8_t zcash,auxpow,havecltv,alertpubkey[65];
uint16_t targetspacing,targettimespan; uint32_t nBits,normal_txversion,locktime_txversion;
};
@ -463,8 +463,10 @@ 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,DEX_reqmutex;
portable_mutex_t allcoins_mutex,gecko_mutex,basilisk_mutex,DEX_mutex,DEX_reqmutex,DEX_swapmutex;
struct queueitem *DEX_quotes;
struct basilisk_swap *swaps[256]; int32_t numswaps;
struct basilisk_message *messagetable; portable_mutex_t messagemutex; queue_t msgQ;
void *ctx;
uint8_t *pingbuf;
struct delayedPoW_info dPoW;

Loading…
Cancel
Save