Browse Source

test

release/v0.1
jl777 9 years ago
parent
commit
1a6f68a672
  1. 30
      iguana/exchanges/bitcoin.c
  2. 37
      iguana/exchanges777.h
  3. 2
      iguana/iguana777.c
  4. 1
      iguana/iguana777.h
  5. 48
      iguana/iguana_exchanges.c
  6. 369
      iguana/iguana_instantdex.c
  7. 39
      iguana/iguana_tradebots.c
  8. 7
      iguana/main.c
  9. 2
      iguana/swaps/iguana_BTCswap.c

30
iguana/exchanges/bitcoin.c

@ -336,18 +336,11 @@ static char *BASERELS[][2] = { {"btcd","btc"}, {"nxt","btc"}, {"asset","btc"} };
double UPDATE(struct exchange_info *exchange,char *base,char *rel,struct exchange_quote *bidasks,int32_t maxdepth,double commission,cJSON *argjson,int32_t invert) double UPDATE(struct exchange_info *exchange,char *base,char *rel,struct exchange_quote *bidasks,int32_t maxdepth,double commission,cJSON *argjson,int32_t invert)
{ {
struct iguana_bundlereq *req; cJSON *retjson,*bids,*asks; double hbla; struct iguana_info *coin; struct supernet_info *myinfo; cJSON *retjson,*bids,*asks; double hbla; struct supernet_info *myinfo;
myinfo = SuperNET_MYINFO(0); myinfo = SuperNET_MYINFO(0);
coin = iguana_coinfind("BTCD");
while ( (req= queue_dequeue(&exchange->recvQ,0)) != 0 )
{
if ( instantdex_recvquotes(coin,req,req->hashes,req->n) != 0 )
myfree(req->hashes,(req->n+1) * sizeof(*req->hashes)), req->hashes = 0;
}
iguana_inv2poll(myinfo,coin);
bids = cJSON_CreateArray(); bids = cJSON_CreateArray();
asks = cJSON_CreateArray(); asks = cJSON_CreateArray();
instantdex_offerfind(myinfo,exchange,bids,asks,0,base,rel,1,0); instantdex_offerfind(myinfo,exchange,bids,asks,0,base,rel,0);
//printf("bids.(%s) asks.(%s)\n",jprint(bids,0),jprint(asks,0)); //printf("bids.(%s) asks.(%s)\n",jprint(bids,0),jprint(asks,0));
retjson = cJSON_CreateObject(); retjson = cJSON_CreateObject();
cJSON_AddItemToObject(retjson,"bids",bids); cJSON_AddItemToObject(retjson,"bids",bids);
@ -476,9 +469,9 @@ 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(); retjson = cJSON_CreateObject();
struct supernet_info *myinfo = SuperNET_accountfind(argjson); struct supernet_info *myinfo = SuperNET_accountfind(argjson);
if ( (swap= instantdex_statemachinefind(myinfo,exchange,orderid,1)) != 0 ) if ( (swap= instantdex_statemachinefind(myinfo,exchange,orderid)) != 0 )
jadd(retjson,"result",instantdex_statemachinejson(swap)); jadd(retjson,"result",instantdex_statemachinejson(swap));
else if ( (ap= instantdex_offerfind(myinfo,exchange,0,0,orderid,"*","*",1,0)) != 0 ) else if ( (ap= instantdex_offerfind(myinfo,exchange,0,0,orderid,"*","*",0)) != 0 )
jadd(retjson,"result",instantdex_acceptjson(ap)); jadd(retjson,"result",instantdex_acceptjson(ap));
else if ( (swap= instantdex_historyfind(myinfo,exchange,orderid)) != 0 ) else if ( (swap= instantdex_historyfind(myinfo,exchange,orderid)) != 0 )
jadd(retjson,"result",instantdex_historyjson(swap)); jadd(retjson,"result",instantdex_historyjson(swap));
@ -491,13 +484,13 @@ char *CANCELORDER(struct exchange_info *exchange,uint64_t orderid,cJSON *argjson
struct instantdex_accept *ap = 0; cJSON *retjson; struct bitcoin_swapinfo *swap=0; struct instantdex_accept *ap = 0; cJSON *retjson; struct bitcoin_swapinfo *swap=0;
struct supernet_info *myinfo = SuperNET_accountfind(argjson); struct supernet_info *myinfo = SuperNET_accountfind(argjson);
retjson = cJSON_CreateObject(); retjson = cJSON_CreateObject();
if ( (ap= instantdex_offerfind(myinfo,exchange,0,0,orderid,"*","*",1,0)) != 0 ) if ( (ap= instantdex_offerfind(myinfo,exchange,0,0,orderid,"*","*",0)) != 0 )
{ {
ap->dead = (uint32_t)time(NULL); ap->dead = (uint32_t)time(NULL);
jadd(retjson,"orderid",instantdex_acceptjson(ap)); jadd(retjson,"orderid",instantdex_acceptjson(ap));
jaddstr(retjson,"result","killed orderid, but might have pending"); jaddstr(retjson,"result","killed orderid, but might have pending");
} }
else if ( (swap= instantdex_statemachinefind(myinfo,exchange,orderid,1)) != 0 ) else if ( (swap= instantdex_statemachinefind(myinfo,exchange,orderid)) != 0 )
{ {
jadd(retjson,"orderid",instantdex_statemachinejson(swap)); jadd(retjson,"orderid",instantdex_statemachinejson(swap));
jaddstr(retjson,"result","killed statemachine orderid, but might have pending"); jaddstr(retjson,"result","killed statemachine orderid, but might have pending");
@ -510,7 +503,7 @@ char *OPENORDERS(struct exchange_info *exchange,cJSON *argjson)
cJSON *retjson,*bids,*asks; struct supernet_info *myinfo = SuperNET_accountfind(argjson); cJSON *retjson,*bids,*asks; struct supernet_info *myinfo = SuperNET_accountfind(argjson);
bids = cJSON_CreateArray(); bids = cJSON_CreateArray();
asks = cJSON_CreateArray(); asks = cJSON_CreateArray();
instantdex_offerfind(myinfo,exchange,bids,asks,0,"*","*",1,0); instantdex_offerfind(myinfo,exchange,bids,asks,0,"*","*",0);
retjson = cJSON_CreateObject(); retjson = cJSON_CreateObject();
jaddstr(retjson,"result","success"); jaddstr(retjson,"result","success");
jadd(retjson,"bids",bids); jadd(retjson,"bids",bids);
@ -520,14 +513,13 @@ char *OPENORDERS(struct exchange_info *exchange,cJSON *argjson)
char *TRADEHISTORY(struct exchange_info *exchange,cJSON *argjson) char *TRADEHISTORY(struct exchange_info *exchange,cJSON *argjson)
{ {
struct bitcoin_swapinfo PAD,*swap; cJSON *retjson = cJSON_CreateArray(); struct bitcoin_swapinfo *swap,*tmp; cJSON *retjson = cJSON_CreateArray();
memset(&PAD,0,sizeof(PAD)); portable_mutex_lock(&exchange->mutexH);
queue_enqueue("historyQ",&exchange->historyQ,&PAD.DL,0); DL_FOREACH_SAFE(exchange->history,swap,tmp)
while ( (swap= queue_dequeue(&exchange->historyQ,0)) != 0 && swap != &PAD )
{ {
jaddi(retjson,instantdex_historyjson(swap)); jaddi(retjson,instantdex_historyjson(swap));
queue_enqueue("historyQ",&exchange->historyQ,&swap->DL,0);
} }
portable_mutex_unlock(&exchange->mutexH);
return(jprint(retjson,1)); return(jprint(retjson,1));
} }

37
iguana/exchanges777.h

@ -64,10 +64,13 @@ struct exchange_info
{ {
struct exchange_funcs issue; struct exchange_funcs issue;
char name[16],apikey[MAX_JSON_FIELD],apisecret[MAX_JSON_FIELD],tradepassword[MAX_JSON_FIELD],userid[MAX_JSON_FIELD]; char name[16],apikey[MAX_JSON_FIELD],apisecret[MAX_JSON_FIELD],tradepassword[MAX_JSON_FIELD],userid[MAX_JSON_FIELD];
uint32_t exchangeid,pollgap,lastpoll; portable_mutex_t mutex; uint32_t exchangeid,pollgap,lastpoll; portable_mutex_t mutex,mutexH,mutexS,mutexP,mutexR,mutexT;
uint64_t lastnonce,exchangebits; double commission; uint64_t lastnonce,exchangebits; double commission;
void *privatedata; void *privatedata;
CURL *cHandle; queue_t requestQ,pricesQ,statemachineQ,tradebotsQ,acceptableQ,historyQ,recvQ; struct tradebot_info *tradebots;
struct bitcoin_swapinfo *statemachines,*history;
struct instantdex_accept *offers;
CURL *cHandle; queue_t recvQ,pricesQ,requestQ;
}; };
struct instantdex_msghdr struct instantdex_msghdr
@ -115,7 +118,8 @@ struct instantdex_offer
struct instantdex_accept struct instantdex_accept
{ {
struct queueitem DL; uint8_t peerhas[IGUANA_MAXPEERS/8]; struct instantdex_accept *next,*prev;
uint8_t peerhas[IGUANA_MAXPEERS/8];
uint64_t pendingvolume64,orderid; uint64_t pendingvolume64,orderid;
uint32_t dead; int32_t didstate:31,reported:1; uint32_t dead; int32_t didstate:31,reported:1;
struct instantdex_offer offer; struct instantdex_offer offer;
@ -130,9 +134,19 @@ struct bitcoin_statetx
char txbytes[]; char txbytes[];
}; };
struct instantdex_stateinfo
{
char name[24]; int16_t ind,initialstate;
cJSON *(*process)(struct supernet_info *myinfo,struct exchange_info *exchange,struct bitcoin_swapinfo *swap,cJSON *argjson,cJSON *newjson,uint8_t **serdatap,int32_t *serdatalenp);
cJSON *(*timeout)(struct supernet_info *myinfo,struct exchange_info *exchange,struct bitcoin_swapinfo *swap,cJSON *argjson,cJSON *newjson,uint8_t **serdatap,int32_t *serdatalenp);
int16_t timeoutind,errorind;
struct instantdex_event *events; int32_t numevents;
};
struct bitcoin_swapinfo struct bitcoin_swapinfo
{ {
struct queueitem DL; //struct queueitem DL;
struct bitcoin_swapinfo *next,*prev;
struct instantdex_accept mine,other; struct instantdex_accept mine,other;
bits256 privkeys[INSTANTDEX_DECKSIZE+2],mypubs[2],otherpubs[2],privAm,pubAm,privBn,pubBn; bits256 privkeys[INSTANTDEX_DECKSIZE+2],mypubs[2],otherpubs[2],privAm,pubAm,privBn,pubBn;
bits256 myorderhash,otherorderhash,mypubkey,othertrader; bits256 myorderhash,otherorderhash,mypubkey,othertrader;
@ -146,18 +160,9 @@ struct bitcoin_swapinfo
struct instantdex_event { char cmdstr[24],sendcmd[16]; int16_t nextstateind; }; struct instantdex_event { char cmdstr[24],sendcmd[16]; int16_t nextstateind; };
struct instantdex_stateinfo
{
char name[24]; int16_t ind,initialstate;
cJSON *(*process)(struct supernet_info *myinfo,struct exchange_info *exchange,struct bitcoin_swapinfo *swap,cJSON *argjson,cJSON *newjson,uint8_t **serdatap,int32_t *serdatalenp);
cJSON *(*timeout)(struct supernet_info *myinfo,struct exchange_info *exchange,struct bitcoin_swapinfo *swap,cJSON *argjson,cJSON *newjson,uint8_t **serdatap,int32_t *serdatalenp);
int16_t timeoutind,errorind;
struct instantdex_event *events; int32_t numevents;
};
#define instantdex_isbob(swap) (swap)->mine.offer.myside #define instantdex_isbob(swap) (swap)->mine.offer.myside
struct instantdex_accept *instantdex_offerfind(struct supernet_info *myinfo,struct exchange_info *exchange,cJSON *bids,cJSON *asks,uint64_t orderid,char *base,char *rel,int32_t requeue,int32_t report); struct instantdex_accept *instantdex_offerfind(struct supernet_info *myinfo,struct exchange_info *exchange,cJSON *bids,cJSON *asks,uint64_t orderid,char *base,char *rel,int32_t report);
cJSON *instantdex_acceptjson(struct instantdex_accept *ap); cJSON *instantdex_acceptjson(struct instantdex_accept *ap);
cJSON *instantdex_historyjson(struct bitcoin_swapinfo *swap); cJSON *instantdex_historyjson(struct bitcoin_swapinfo *swap);
struct bitcoin_swapinfo *instantdex_historyfind(struct supernet_info *myinfo,struct exchange_info *exchange,uint64_t orderid); struct bitcoin_swapinfo *instantdex_historyfind(struct supernet_info *myinfo,struct exchange_info *exchange,uint64_t orderid);
@ -181,7 +186,9 @@ double instaforex_price(struct exchange_info *exchange,char *base,char *rel,stru
char *instantdex_createaccept(struct supernet_info *myinfo,struct instantdex_accept **aptrp,struct exchange_info *exchange,char *base,char *rel,double price,double basevolume,int32_t acceptdir,char *mysidestr,int32_t duration,uint64_t offerer,int32_t queueflag,uint8_t minperc); char *instantdex_createaccept(struct supernet_info *myinfo,struct instantdex_accept **aptrp,struct exchange_info *exchange,char *base,char *rel,double price,double basevolume,int32_t acceptdir,char *mysidestr,int32_t duration,uint64_t offerer,int32_t queueflag,uint8_t minperc);
char *instantdex_sendcmd(struct supernet_info *myinfo,struct instantdex_offer *offer,cJSON *argjson,char *cmdstr,bits256 desthash,int32_t hops,void *extra,int32_t extralen,struct iguana_peer *addr); char *instantdex_sendcmd(struct supernet_info *myinfo,struct instantdex_offer *offer,cJSON *argjson,char *cmdstr,bits256 desthash,int32_t hops,void *extra,int32_t extralen,struct iguana_peer *addr);
char *instantdex_sendoffer(struct supernet_info *myinfo,struct exchange_info *exchange,struct instantdex_accept *ap,cJSON *argjson); // Bob sending to network (Alice) char *instantdex_sendoffer(struct supernet_info *myinfo,struct exchange_info *exchange,struct instantdex_accept *ap,cJSON *argjson); // Bob sending to network (Alice)
struct bitcoin_swapinfo *instantdex_statemachinefind(struct supernet_info *myinfo,struct exchange_info *exchange,uint64_t orderid,int32_t requeueflag); struct bitcoin_swapinfo *instantdex_statemachinefind(struct supernet_info *myinfo,struct exchange_info *exchange,uint64_t orderid);
char *instantdex_checkoffer(struct supernet_info *myinfo,uint64_t *txidp,struct exchange_info *exchange,struct instantdex_accept *ap,cJSON *json); char *instantdex_checkoffer(struct supernet_info *myinfo,uint64_t *txidp,struct exchange_info *exchange,struct instantdex_accept *ap,cJSON *json);
void tradebot_timeslices(struct exchange_info *exchange);
struct instantdex_stateinfo *BTC_initFSM(int32_t *n);
#endif #endif

2
iguana/iguana777.c

@ -146,7 +146,7 @@ int32_t iguana_inv2poll(struct supernet_info *myinfo,struct iguana_info *coin)
{ {
struct exchange_info *exchange; int32_t i,n=0; struct iguana_peer *addr; struct exchange_info *exchange; int32_t i,n=0; struct iguana_peer *addr;
//printf("iguana_inv2poll exchange.%p %s maxpeers.%d\n",exchanges777_find("bitcoin"),coin->symbol,coin->MAXPEERS); //printf("iguana_inv2poll exchange.%p %s maxpeers.%d\n",exchanges777_find("bitcoin"),coin->symbol,coin->MAXPEERS);
if ( (exchange= exchanges777_find("bitcoin")) != 0 && strcmp(coin->symbol,"BTCD") == 0 ) if ( coin != 0 && (exchange= exchanges777_find("bitcoin")) != 0 && strcmp(coin->symbol,"BTCD") == 0 )
{ {
if ( time(NULL) > coin->lastinv2+10 ) if ( time(NULL) > coin->lastinv2+10 )
{ {

1
iguana/iguana777.h

@ -981,6 +981,7 @@ struct iguana_bundlereq *instantdex_recvquotes(struct iguana_info *coin,struct i
struct exchange_info *exchange_create(char *exchangestr,cJSON *argjson); struct exchange_info *exchange_create(char *exchangestr,cJSON *argjson);
int32_t iguana_inv2poll(struct supernet_info *myinfo,struct iguana_info *coin); int32_t iguana_inv2poll(struct supernet_info *myinfo,struct iguana_info *coin);
struct iguana_bundlereq *iguana_bundlereq(struct iguana_info *coin,struct iguana_peer *addr,int32_t type,int32_t datalen); struct iguana_bundlereq *iguana_bundlereq(struct iguana_info *coin,struct iguana_peer *addr,int32_t type,int32_t datalen);
void instantdex_FSMinit();
extern int32_t HDRnet,netBLOCKS; extern int32_t HDRnet,netBLOCKS;

48
iguana/iguana_exchanges.c

@ -583,10 +583,29 @@ char *exchanges777_process(struct exchange_info *exchange,int32_t *retvalp,struc
return(retstr); return(retstr);
} }
void iguana_statemachineupdate(struct supernet_info *myinfo,struct exchange_info *exchange)
{
struct iguana_info *coin; struct bitcoin_swapinfo *swap,*tmp; struct iguana_bundlereq *req;
coin = iguana_coinfind("BTCD");
portable_mutex_lock(&exchange->mutex);
DL_FOREACH_SAFE(exchange->statemachines,swap,tmp)
{
printf("FSM.(%llu / %llu) (%s/%s) state.(%s)\n",(long long)swap->mine.orderid,(long long)swap->other.orderid,swap->mine.offer.base,swap->mine.offer.rel,swap->state->name);
}
portable_mutex_unlock(&exchange->mutex);
while ( (req= queue_dequeue(&exchange->recvQ,0)) != 0 )
{
if ( instantdex_recvquotes(coin,req,req->hashes,req->n) != 0 )
myfree(req->hashes,(req->n+1) * sizeof(*req->hashes)), req->hashes = 0;
}
iguana_inv2poll(myinfo,coin);
}
void exchanges777_loop(void *ptr) void exchanges777_loop(void *ptr)
{ {
struct peggy_info *PEGS; struct exchange_info *exchange = ptr; struct peggy_info *PEGS; struct supernet_info *myinfo; struct exchange_info *exchange = ptr;
int32_t flag,retval,i,peggyflag = 0; struct exchange_request *req; char *retstr; void *bot; int32_t flag,retval,i,peggyflag = 0; struct exchange_request *req; char *retstr;
myinfo = SuperNET_MYINFO(0);
if ( strcmp(exchange->name,"PAX") == 0 ) if ( strcmp(exchange->name,"PAX") == 0 )
{ {
PEGS = calloc(1,sizeof(*PEGS)); PEGS = calloc(1,sizeof(*PEGS));
@ -596,7 +615,7 @@ void exchanges777_loop(void *ptr)
_crypto_update(PEGS,PEGS->cryptovols,&PEGS->data,1,peggyflag); _crypto_update(PEGS,PEGS->cryptovols,&PEGS->data,1,peggyflag);
PEGS->lastupdate = (uint32_t)time(NULL); PEGS->lastupdate = (uint32_t)time(NULL);
} }
printf("exchanges loop.(%s) %p\n",exchange->name,&exchange->requestQ); printf("exchanges loop.(%s)\n",exchange->name);
while ( 1 ) while ( 1 )
{ {
if ( peggyflag != 0 ) if ( peggyflag != 0 )
@ -654,15 +673,14 @@ void exchanges777_loop(void *ptr)
free(req); free(req);
} }
} }
if ( (bot= queue_dequeue(&exchange->tradebotsQ,0)) != 0 ) tradebot_timeslices(exchange);
tradebot_timeslice(exchange,bot);
if ( time(NULL) > exchange->lastpoll+exchange->pollgap ) if ( time(NULL) > exchange->lastpoll+exchange->pollgap )
{ {
/*if ( strcmp(exchange->name,"bitcoin") == 0 ) if ( strcmp(exchange->name,"bitcoin") == 0 )
{ {
instantdex_update(SuperNET_MYINFO(0)); iguana_statemachineupdate(myinfo,exchange);
//printf("InstantDEX call update\n"); //printf("InstantDEX call update\n");
}*/ }
if ( (req= queue_dequeue(&exchange->pricesQ,0)) != 0 ) if ( (req= queue_dequeue(&exchange->pricesQ,0)) != 0 )
{ {
//printf("check %s pricesQ (%s %s)\n",exchange->name,req->base,req->rel); //printf("check %s pricesQ (%s %s)\n",exchange->name,req->base,req->rel);
@ -895,14 +913,15 @@ struct exchange_info *exchange_create(char *exchangestr,cJSON *argjson)
} }
exchange = calloc(1,sizeof(*exchange)); exchange = calloc(1,sizeof(*exchange));
portable_mutex_init(&exchange->mutex); portable_mutex_init(&exchange->mutex);
portable_mutex_init(&exchange->mutexS);
portable_mutex_init(&exchange->mutexH);
portable_mutex_init(&exchange->mutexP);
portable_mutex_init(&exchange->mutexR);
portable_mutex_init(&exchange->mutexT);
exchange->issue = *Exchange_funcs[i]; exchange->issue = *Exchange_funcs[i];
iguana_initQ(&exchange->pricesQ,"prices");
iguana_initQ(&exchange->requestQ,"request");
iguana_initQ(&exchange->acceptableQ,"acceptable");
iguana_initQ(&exchange->tradebotsQ,"tradebots");
iguana_initQ(&exchange->recvQ,"recvQ"); iguana_initQ(&exchange->recvQ,"recvQ");
iguana_initQ(&exchange->historyQ,"history"); iguana_initQ(&exchange->pricesQ,"pricesQ");
iguana_initQ(&exchange->statemachineQ,"statemachineQ"); iguana_initQ(&exchange->requestQ,"requestQ");
exchange->exchangeid = exchangeid; exchange->exchangeid = exchangeid;
safecopy(exchange->name,exchangestr,sizeof(exchange->name)); safecopy(exchange->name,exchangestr,sizeof(exchange->name));
exchange->exchangebits = stringbits(exchange->name); exchange->exchangebits = stringbits(exchange->name);
@ -920,6 +939,7 @@ struct exchange_info *exchange_create(char *exchangestr,cJSON *argjson)
exchange->commission *= .01; 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); 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; Exchanges[exchangeid] = exchange;
instantdex_FSMinit();
iguana_launch(0,"exchangeloop",(void *)exchanges777_loop,exchange,IGUANA_EXCHANGETHREAD); iguana_launch(0,"exchangeloop",(void *)exchanges777_loop,exchange,IGUANA_EXCHANGETHREAD);
return(exchange); return(exchange);
} }

369
iguana/iguana_instantdex.c

@ -50,6 +50,62 @@ void instantdex_swapfree(struct instantdex_accept *A,struct bitcoin_swapinfo *sw
} }
} }
int32_t instantdex_unbasebits(char *base,uint64_t basebits)
{
char tmp[9];
unstringbits(tmp,basebits);
if ( iguana_coinfind(tmp) == 0 )
{
sprintf(base,"%lld",(long long)basebits);
return(1);
}
else
{
strcmp(base,tmp);
return(0);
}
}
uint64_t instantdex_basebits(char *base)
{
if ( is_decimalstr(base) != 0 )
return(calc_nxt64bits(base));
else return(stringbits(base));
}
uint64_t instantdex_decodehash(char *base,char *rel,int64_t *pricep,uint64_t *accountp,bits256 encodedhash)
{
int32_t i; uint64_t offerid;
base[4] = rel[4] = 0;
for (i=0; i<4; i++)
{
base[i] = encodedhash.bytes[8 + i];
rel[i] = encodedhash.bytes[12 + i];
}
iguana_rwnum(0,(void *)&encodedhash.ulongs[2],sizeof(uint64_t),pricep);
iguana_rwnum(0,(void *)&encodedhash.ulongs[3],sizeof(uint64_t),accountp);
iguana_rwnum(0,(void *)&encodedhash.ulongs[0],sizeof(uint64_t),&offerid);
return(encodedhash.ulongs[0]);
}
bits256 instantdex_encodehash(char *base,char *rel,int64_t price,uint64_t orderid,uint64_t account)
{
bits256 encodedhash; int32_t i; char _base[4],_rel[4];
iguana_rwnum(1,(void *)&encodedhash.ulongs[0],sizeof(uint64_t),&orderid);
memset(_base,0,sizeof(_base));
memset(_rel,0,sizeof(_rel));
strncpy(_base,base,4);
strncpy(_rel,rel,4);
for (i=0; i<4; i++)
{
encodedhash.bytes[8 + i] = _base[i];
encodedhash.bytes[12 + i] = _rel[i];
}
iguana_rwnum(1,(void *)&encodedhash.ulongs[2],sizeof(uint64_t),&price);
iguana_rwnum(1,(void *)&encodedhash.ulongs[3],sizeof(uint64_t),&account);
return(encodedhash);
}
cJSON *instantdex_defaultprocess(struct supernet_info *myinfo,struct exchange_info *exchange,struct bitcoin_swapinfo *swap,cJSON *argjson,cJSON *newjson,uint8_t **serdatap,int32_t *serdatalenp) cJSON *instantdex_defaultprocess(struct supernet_info *myinfo,struct exchange_info *exchange,struct bitcoin_swapinfo *swap,cJSON *argjson,cJSON *newjson,uint8_t **serdatap,int32_t *serdatalenp)
{ {
uint8_t *serdata = *serdatap; int32_t serdatalen = *serdatalenp; uint8_t *serdata = *serdatap; int32_t serdatalen = *serdatalenp;
@ -217,6 +273,12 @@ double instantdex_FSMtest(struct instantdex_stateinfo *states,int32_t numstates,
return(sum / maxiters); return(sum / maxiters);
} }
void instantdex_FSMinit()
{
if ( BTC_states == 0 )
BTC_states = BTC_initFSM(&BTC_numstates);
}
cJSON *InstantDEX_argjson(char *reference,char *message,char *othercoinaddr,char *otherNXTaddr,int32_t iter,int32_t val,int32_t val2) cJSON *InstantDEX_argjson(char *reference,char *message,char *othercoinaddr,char *otherNXTaddr,int32_t iter,int32_t val,int32_t val2)
{ {
cJSON *argjson = cJSON_CreateObject(); cJSON *argjson = cJSON_CreateObject();
@ -381,12 +443,15 @@ char *instantdex_sendcmd(struct supernet_info *myinfo,struct instantdex_offer *o
} }
else else
{ {
hexstr = malloc(msg->sig.allocsize*2 + 1); if ( (hexstr= malloc(msg->sig.allocsize*2 + 1)) != 0 )
init_hexbytes_noT(hexstr,(uint8_t *)msg,msg->sig.allocsize); {
if ( (retstr= SuperNET_categorymulticast(myinfo,0,myinfo->instantdex_category,desthash,hexstr,0,hops,1,argjson,0)) != 0 ) init_hexbytes_noT(hexstr,(uint8_t *)msg,msg->sig.allocsize);
free(retstr); if ( (retstr= SuperNET_categorymulticast(myinfo,0,myinfo->instantdex_category,desthash,hexstr,0,hops,1,argjson,0)) != 0 )
free(retstr);
free(hexstr);
}
} }
free(msg); //free(hexstr), free(msg);
return(jprint(argjson,1)); return(jprint(argjson,1));
} }
else else
@ -650,65 +715,78 @@ cJSON *instantdex_historyjson(struct bitcoin_swapinfo *swap)
struct bitcoin_swapinfo *instantdex_historyfind(struct supernet_info *myinfo,struct exchange_info *exchange,uint64_t orderid) struct bitcoin_swapinfo *instantdex_historyfind(struct supernet_info *myinfo,struct exchange_info *exchange,uint64_t orderid)
{ {
struct bitcoin_swapinfo PAD,*swap,*retswap = 0; uint32_t now; struct bitcoin_swapinfo *swap,*tmp,*retswap = 0;
now = (uint32_t)time(NULL); portable_mutex_lock(&exchange->mutexH);
portable_mutex_lock(&exchange->mutex); DL_FOREACH_SAFE(exchange->history,swap,tmp)
memset(&PAD,0,sizeof(PAD));
queue_enqueue("historyQ",&exchange->historyQ,&PAD.DL,0);
while ( (swap= queue_dequeue(&exchange->historyQ,0)) != 0 && swap != &PAD )
{ {
if ( orderid == swap->mine.orderid ) if ( orderid == swap->mine.orderid )
{
retswap = swap; retswap = swap;
queue_enqueue("historyQ",&exchange->historyQ,&swap->DL,0); break;
}
} }
portable_mutex_unlock(&exchange->mutex); portable_mutex_unlock(&exchange->mutexH);
return(retswap); return(retswap);
} }
struct bitcoin_swapinfo *instantdex_statemachinefind(struct supernet_info *myinfo,struct exchange_info *exchange,uint64_t orderid,int32_t requeueflag) void instantdex_historyadd(struct exchange_info *exchange,struct bitcoin_swapinfo *swap)
{
portable_mutex_lock(&exchange->mutexH);
DL_APPEND(exchange->history,swap);
portable_mutex_unlock(&exchange->mutexH);
}
void instantdex_statemachineadd(struct exchange_info *exchange,struct bitcoin_swapinfo *swap)
{
portable_mutex_lock(&exchange->mutexS);
DL_APPEND(exchange->statemachines,swap);
portable_mutex_unlock(&exchange->mutexS);
}
void instantdex_offeradd(struct exchange_info *exchange,struct instantdex_accept *ap)
{ {
struct bitcoin_swapinfo PAD,*swap,*retswap = 0; uint32_t now;
now = (uint32_t)time(NULL);
portable_mutex_lock(&exchange->mutex); portable_mutex_lock(&exchange->mutex);
memset(&PAD,0,sizeof(PAD)); DL_APPEND(exchange->offers,ap);
queue_enqueue("statemachineQ",&exchange->statemachineQ,&PAD.DL,0); portable_mutex_unlock(&exchange->mutex);
while ( (swap= queue_dequeue(&exchange->statemachineQ,0)) != 0 && swap != &PAD ) }
struct bitcoin_swapinfo *instantdex_statemachinefind(struct supernet_info *myinfo,struct exchange_info *exchange,uint64_t orderid)
{
struct bitcoin_swapinfo *tmp,*swap,*retswap = 0; uint32_t now;
now = (uint32_t)time(NULL);
portable_mutex_lock(&exchange->mutexS);
DL_FOREACH_SAFE(exchange->statemachines,swap,tmp)
{ {
if ( now < swap->expiration && swap->mine.dead == 0 && swap->other.dead == 0 ) if ( now < swap->expiration && swap->mine.dead == 0 && swap->other.dead == 0 )
{ {
if ( orderid == swap->mine.orderid || orderid == swap->other.orderid ) if ( orderid == swap->mine.orderid || orderid == swap->other.orderid )
{ {
if ( retswap != 0 && requeueflag == 0 )
queue_enqueue("statemachineQ",&exchange->statemachineQ,&retswap->DL,0);
retswap = swap; retswap = swap;
break;
} }
} }
else else
{ {
strcpy(swap->status,"expired"); strcpy(swap->status,"expired");
printf("expired pending, need to take action, send timeout event\n"); printf("expired pending, need to take action, send timeout event\n");
queue_enqueue("historyQ",&exchange->historyQ,&swap->DL,0); DL_DELETE(exchange->statemachines,swap);
instantdex_historyadd(exchange,swap);
continue; continue;
} }
if ( swap != retswap || requeueflag != 0 )
queue_enqueue("statemachineQ",&exchange->statemachineQ,&swap->DL,0);
} }
//printf("found statemachine.%p\n",retswap); //printf("found statemachine.%p\n",retswap);
portable_mutex_unlock(&exchange->mutex); portable_mutex_unlock(&exchange->mutexS);
return(retswap); return(retswap);
} }
struct instantdex_accept *instantdex_offerfind(struct supernet_info *ignore,struct exchange_info *exchange,cJSON *bids,cJSON *asks,uint64_t orderid,char *base,char *rel,int32_t requeue,int32_t report) struct instantdex_accept *instantdex_offerfind(struct supernet_info *ignore,struct exchange_info *exchange,cJSON *bids,cJSON *asks,uint64_t orderid,char *base,char *rel,int32_t report)
{ {
struct instantdex_accept PAD,*ap,*retap = 0; uint32_t now; cJSON *item,*offerobj; char *type; struct instantdex_accept *tmp,*ap,*retap = 0; uint32_t now; cJSON *item,*offerobj; char *type;
if ( exchange == 0 ) if ( exchange == 0 )
return(0); return(0);
portable_mutex_lock(&exchange->mutex);
now = (uint32_t)time(NULL); now = (uint32_t)time(NULL);
memset(&PAD,0,sizeof(PAD)); portable_mutex_lock(&exchange->mutex);
//printf("before loop.%d\n",queue_size(&exchange->acceptableQ)); DL_FOREACH_SAFE(exchange->offers,ap,tmp)
queue_enqueue("acceptableQ",&exchange->acceptableQ,&PAD.DL,0);
while ( (ap= queue_dequeue(&exchange->acceptableQ,0)) != 0 && ap != &PAD )
{ {
if ( now < ap->offer.expiration && ap->dead == 0 ) if ( now < ap->offer.expiration && ap->dead == 0 )
{ {
@ -720,8 +798,6 @@ struct instantdex_accept *instantdex_offerfind(struct supernet_info *ignore,stru
ap->reported = 1; ap->reported = 1;
printf("MARK as reported %llu\n",(long long)ap->orderid); printf("MARK as reported %llu\n",(long long)ap->orderid);
} }
if ( retap != 0 )
queue_enqueue("acceptableQ",&exchange->acceptableQ,&retap->DL,0);
retap = ap; retap = ap;
if ( (item= instantdex_acceptjson(ap)) != 0 ) if ( (item= instantdex_acceptjson(ap)) != 0 )
{ {
@ -736,12 +812,12 @@ struct instantdex_accept *instantdex_offerfind(struct supernet_info *ignore,stru
free_json(item); free_json(item);
} else printf("error generating acceptjson.%llu\n",(long long)ap->orderid); } else printf("error generating acceptjson.%llu\n",(long long)ap->orderid);
} }
if ( ap != retap || requeue != 0 ) }
{ else
//printf("requeue.%p\n",ap); {
queue_enqueue("acceptableQ",&exchange->acceptableQ,&ap->DL,0); DL_DELETE(exchange->offers,ap);
} free(ap);
} else free(ap); }
} }
portable_mutex_unlock(&exchange->mutex); portable_mutex_unlock(&exchange->mutex);
//printf("offerfind -> retap.%p Qsize.%d\n",retap,queue_size(&exchange->acceptableQ)); //printf("offerfind -> retap.%p Qsize.%d\n",retap,queue_size(&exchange->acceptableQ));
@ -750,91 +826,87 @@ struct instantdex_accept *instantdex_offerfind(struct supernet_info *ignore,stru
int32_t instantdex_peerhas_clear(struct iguana_info *coin,struct iguana_peer *addr) int32_t instantdex_peerhas_clear(struct iguana_info *coin,struct iguana_peer *addr)
{ {
struct instantdex_accept PAD,*ap; struct exchange_info *exchange; int32_t ind,num = 0; struct instantdex_accept *tmp,*ap; struct exchange_info *exchange; int32_t ind,num = 0;
if ( addr != 0 && (exchange= exchanges777_find("bitcoin")) != 0 ) if ( addr != 0 && (exchange= exchanges777_find("bitcoin")) != 0 )
{ {
//printf("clear all bits for addrind.%d\n",addr->addrind); //printf("clear all bits for addrind.%d\n",addr->addrind);
portable_mutex_lock(&exchange->mutex);
ind = addr->addrind; ind = addr->addrind;
memset(&PAD,0,sizeof(PAD)); portable_mutex_lock(&exchange->mutex);
queue_enqueue("acceptableQ",&exchange->acceptableQ,&PAD.DL,0); DL_FOREACH_SAFE(exchange->offers,ap,tmp)
while ( (ap= queue_dequeue(&exchange->acceptableQ,0)) != 0 && ap != &PAD )
{ {
CLEARBIT(ap->peerhas,ind); CLEARBIT(ap->peerhas,ind);
queue_enqueue("acceptableQ",&exchange->acceptableQ,&ap->DL,0);
} }
portable_mutex_unlock(&exchange->mutex); portable_mutex_unlock(&exchange->mutex);
} }
return(num); return(num);
} }
int32_t instantdex_unbasebits(char *base,uint64_t basebits) struct instantdex_accept *instantdex_acceptable(struct supernet_info *myinfo,struct exchange_info *exchange,struct instantdex_accept *A,double minperc)
{ {
char tmp[9]; struct instantdex_accept *tmp,*ap,*retap = 0; double aveprice;
unstringbits(tmp,basebits); uint64_t minvol,bestprice64 = 0; uint32_t now; int32_t offerdir;
if ( iguana_coinfind(tmp) == 0 ) if ( exchange == 0 )
{
sprintf(base,"%lld",(long long)basebits);
return(1);
}
else
{ {
strcmp(base,tmp); printf("instantdex_acceptable null exchange\n");
return(0); return(0);
} }
} aveprice = 0;//instantdex_avehbla(myinfo,retvals,A->offer.base,A->offer.rel,dstr(A->offer.basevolume64));
now = (uint32_t)time(NULL);
uint64_t instantdex_basebits(char *base) offerdir = instantdex_bidaskdir(&A->offer);
{ minvol = (A->offer.basevolume64 * minperc * .01);
if ( is_decimalstr(base) != 0 ) printf("instantdex_acceptable offerdir.%d (%s/%s) minperc %.3f minvol %.8f vs %.8f\n",offerdir,A->offer.base,A->offer.rel,minperc,dstr(minvol),dstr(A->offer.basevolume64));
return(calc_nxt64bits(base)); portable_mutex_lock(&exchange->mutex);
else return(stringbits(base)); DL_FOREACH_SAFE(exchange->offers,ap,tmp)
}
uint64_t instantdex_decodehash(char *base,char *rel,int64_t *pricep,uint64_t *accountp,bits256 encodedhash)
{
int32_t i; uint64_t offerid;
base[4] = rel[4] = 0;
for (i=0; i<4; i++)
{
base[i] = encodedhash.bytes[8 + i];
rel[i] = encodedhash.bytes[12 + i];
}
iguana_rwnum(0,(void *)&encodedhash.ulongs[2],sizeof(uint64_t),pricep);
iguana_rwnum(0,(void *)&encodedhash.ulongs[3],sizeof(uint64_t),accountp);
iguana_rwnum(0,(void *)&encodedhash.ulongs[0],sizeof(uint64_t),&offerid);
return(encodedhash.ulongs[0]);
}
bits256 instantdex_encodehash(char *base,char *rel,int64_t price,uint64_t orderid,uint64_t account)
{
bits256 encodedhash; int32_t i; char _base[4],_rel[4];
iguana_rwnum(1,(void *)&encodedhash.ulongs[0],sizeof(uint64_t),&orderid);
memset(_base,0,sizeof(_base));
memset(_rel,0,sizeof(_rel));
strncpy(_base,base,4);
strncpy(_rel,rel,4);
for (i=0; i<4; i++)
{ {
encodedhash.bytes[8 + i] = _base[i]; //printf("ap.%p account.%llu dir.%d\n",ap,(long long)ap->offer.account,offerdir);
encodedhash.bytes[12 + i] = _rel[i]; if ( now > ap->offer.expiration || ap->dead != 0 )//|| A->offer.account == ap->offer.account )
{
//printf("now.%u skip expired %u/dead.%u or my order orderid.%llu from %llu\n",now,ap->offer.expiration,ap->dead,(long long)ap->orderid,(long long)ap->offer.account);
}
else if ( A->offer.account != myinfo->myaddr.nxt64bits && ap->offer.account != myinfo->myaddr.nxt64bits )
{
}
else if ( strcmp(ap->offer.base,A->offer.base) != 0 || strcmp(ap->offer.rel,A->offer.rel) != 0 )
{
//printf("skip mismatched.(%s/%s) orderid.%llu from %llu\n",ap->offer.base,ap->offer.rel,(long long)ap->orderid,(long long)ap->offer.account);
}
else if ( offerdir*instantdex_bidaskdir(&ap->offer) > 0 )
{
//printf("skip same direction %d orderid.%llu from %llu\n",instantdex_bidaskdir(&ap->offer),(long long)ap->orderid,(long long)ap->offer.account);
}
else if ( minvol > ap->offer.basevolume64 - ap->pendingvolume64 )
{
//printf("skip too small order %.8f vs %.8f orderid.%llu from %llu\n",dstr(minvol),dstr(ap->offer.basevolume64)-dstr(ap->pendingvolume64),(long long)ap->orderid,(long long)ap->offer.account);
}
else if ( (offerdir > 0 && ap->offer.price64 > A->offer.price64) || (offerdir < 0 && ap->offer.price64 < A->offer.price64) )
{
//printf("skip out of band dir.%d offer %.8f vs %.8f orderid.%llu from %llu\n",offerdir,dstr(ap->offer.price64),dstr(A->offer.price64),(long long)ap->orderid,(long long)ap->offer.account);
}
else
{
if ( bestprice64 == 0 || (offerdir > 0 && ap->offer.price64 < bestprice64) || (offerdir < 0 && ap->offer.price64 > bestprice64) )
{
printf(">>>> MATCHED better price dir.%d offer %.8f vs %.8f orderid.%llu from %llu\n",offerdir,dstr(ap->offer.price64),dstr(A->offer.price64),(long long)ap->orderid,(long long)ap->offer.account);
bestprice64 = ap->offer.price64;
retap = ap;
}
}
} }
iguana_rwnum(1,(void *)&encodedhash.ulongs[2],sizeof(uint64_t),&price); portable_mutex_unlock(&exchange->mutex);
iguana_rwnum(1,(void *)&encodedhash.ulongs[3],sizeof(uint64_t),&account); //printf("after acceptable Qsize.%d retap.%p\n",queue_size(&exchange->acceptableQ),retap);
return(encodedhash); return(retap);
} }
int32_t instantdex_inv2data(struct supernet_info *myinfo,struct iguana_info *coin,struct iguana_peer *addr,struct exchange_info *exchange) int32_t instantdex_inv2data(struct supernet_info *myinfo,struct iguana_info *coin,struct iguana_peer *addr,struct exchange_info *exchange)
{ {
struct instantdex_accept PAD,*ap; uint32_t now,n=0,len; bits256 encodedhash,hashes[100]; uint8_t serialized[100*36 + 1024]; struct instantdex_accept *tmp,*ap; uint32_t now,n=0,len; bits256 encodedhash,hashes[100]; uint8_t serialized[100*36 + 1024];
//printf("instantdex_inv2data exchange.%p (%s)\n",exchange,addr->ipaddr); //printf("instantdex_inv2data exchange.%p (%s)\n",exchange,addr->ipaddr);
if ( exchange == 0 ) if ( exchange == 0 )
return(0); return(0);
portable_mutex_lock(&exchange->mutex); portable_mutex_lock(&exchange->mutex);
now = (uint32_t)time(NULL); now = (uint32_t)time(NULL);
memset(&PAD,0,sizeof(PAD)); DL_FOREACH_SAFE(exchange->offers,ap,tmp)
queue_enqueue("acceptableQ",&exchange->acceptableQ,&PAD.DL,0);
while ( (ap= queue_dequeue(&exchange->acceptableQ,0)) != 0 && ap != &PAD )
{ {
if ( now < ap->offer.expiration && ap->dead == 0 ) if ( now < ap->offer.expiration && ap->dead == 0 )
{ {
@ -844,8 +916,12 @@ int32_t instantdex_inv2data(struct supernet_info *myinfo,struct iguana_info *coi
hashes[n++] = encodedhash; hashes[n++] = encodedhash;
printf("%llu ",(long long)ap->orderid); printf("%llu ",(long long)ap->orderid);
} }
queue_enqueue("acceptableQ",&exchange->acceptableQ,&ap->DL,0); }
} else free(ap); else
{
DL_DELETE(exchange->offers,ap);
free(ap);
}
} }
portable_mutex_unlock(&exchange->mutex); portable_mutex_unlock(&exchange->mutex);
if ( n > 0 ) if ( n > 0 )
@ -862,7 +938,7 @@ struct instantdex_accept *instantdex_quotefind(struct supernet_info *myinfo,stru
char base[9],rel[9]; int64_t pricetoshis; uint64_t orderid,account; char base[9],rel[9]; int64_t pricetoshis; uint64_t orderid,account;
orderid = instantdex_decodehash(base,rel,&pricetoshis,&account,encodedhash); orderid = instantdex_decodehash(base,rel,&pricetoshis,&account,encodedhash);
//printf("search for orderid.%llu (%s/%s) %.8f from %llu\n",(long long)orderid,base,rel,dstr(pricetoshis),(long long)account); //printf("search for orderid.%llu (%s/%s) %.8f from %llu\n",(long long)orderid,base,rel,dstr(pricetoshis),(long long)account);
return(instantdex_offerfind(myinfo,exchanges777_find("bitcoin"),0,0,orderid,base,rel,1,0)); return(instantdex_offerfind(myinfo,exchanges777_find("bitcoin"),0,0,orderid,base,rel,0));
} }
struct iguana_bundlereq *instantdex_recvquotes(struct iguana_info *coin,struct iguana_bundlereq *req,bits256 *quotes,int32_t n) struct iguana_bundlereq *instantdex_recvquotes(struct iguana_info *coin,struct iguana_bundlereq *req,bits256 *quotes,int32_t n)
@ -954,69 +1030,6 @@ void instantdex_propagate(struct supernet_info *myinfo,struct exchange_info *exc
} }
} }
struct instantdex_accept *instantdex_acceptable(struct supernet_info *myinfo,struct exchange_info *exchange,struct instantdex_accept *A,double minperc)
{
struct instantdex_accept PAD,*ap,*retap = 0; double aveprice;//,retvals[4];
uint64_t minvol,bestprice64 = 0; uint32_t now; int32_t offerdir;
if ( exchange == 0 )
{
printf("instantdex_acceptable null exchange\n");
return(0);
}
portable_mutex_lock(&exchange->mutex);
aveprice = 0;//instantdex_avehbla(myinfo,retvals,A->offer.base,A->offer.rel,dstr(A->offer.basevolume64));
now = (uint32_t)time(NULL);
offerdir = instantdex_bidaskdir(&A->offer);
minvol = (A->offer.basevolume64 * minperc * .01);
printf("instantdex_acceptable.%d offerdir.%d (%s/%s) minperc %.3f minvol %.8f vs %.8f\n",queue_size(&exchange->acceptableQ),offerdir,A->offer.base,A->offer.rel,minperc,dstr(minvol),dstr(A->offer.basevolume64));
memset(&PAD,0,sizeof(PAD));
queue_enqueue("acceptableQ",&exchange->acceptableQ,&PAD.DL,0);
while ( (ap= queue_dequeue(&exchange->acceptableQ,0)) != 0 && ap != &PAD )
{
//printf("ap.%p account.%llu dir.%d\n",ap,(long long)ap->offer.account,offerdir);
if ( now > ap->offer.expiration || ap->dead != 0 || A->offer.account == ap->offer.account )
{
//printf("now.%u skip expired %u/dead.%u or my order orderid.%llu from %llu\n",now,ap->offer.expiration,ap->dead,(long long)ap->orderid,(long long)ap->offer.account);
}
else if ( A->offer.account != myinfo->myaddr.nxt64bits && ap->offer.account != myinfo->myaddr.nxt64bits )
{
}
else if ( strcmp(ap->offer.base,A->offer.base) != 0 || strcmp(ap->offer.rel,A->offer.rel) != 0 )
{
//printf("skip mismatched.(%s/%s) orderid.%llu from %llu\n",ap->offer.base,ap->offer.rel,(long long)ap->orderid,(long long)ap->offer.account);
}
else if ( offerdir*instantdex_bidaskdir(&ap->offer) > 0 )
{
//printf("skip same direction %d orderid.%llu from %llu\n",instantdex_bidaskdir(&ap->offer),(long long)ap->orderid,(long long)ap->offer.account);
}
else if ( minvol > ap->offer.basevolume64 - ap->pendingvolume64 )
{
//printf("skip too small order %.8f vs %.8f orderid.%llu from %llu\n",dstr(minvol),dstr(ap->offer.basevolume64)-dstr(ap->pendingvolume64),(long long)ap->orderid,(long long)ap->offer.account);
}
else if ( (offerdir > 0 && ap->offer.price64 > A->offer.price64) || (offerdir < 0 && ap->offer.price64 < A->offer.price64) )
{
//printf("skip out of band dir.%d offer %.8f vs %.8f orderid.%llu from %llu\n",offerdir,dstr(ap->offer.price64),dstr(A->offer.price64),(long long)ap->orderid,(long long)ap->offer.account);
}
else
{
if ( bestprice64 == 0 || (offerdir > 0 && ap->offer.price64 < bestprice64) || (offerdir < 0 && ap->offer.price64 > bestprice64) )
{
printf(">>>> MATCHED better price dir.%d offer %.8f vs %.8f orderid.%llu from %llu\n",offerdir,dstr(ap->offer.price64),dstr(A->offer.price64),(long long)ap->orderid,(long long)ap->offer.account);
bestprice64 = ap->offer.price64;
if ( retap != 0 )
queue_enqueue("acceptableQ",&exchange->acceptableQ,&retap->DL,0);
retap = ap;
}
}
if ( ap != retap )
queue_enqueue("acceptableQ",&exchange->acceptableQ,&ap->DL,0);
else free(ap);
}
portable_mutex_unlock(&exchange->mutex);
//printf("after acceptable Qsize.%d retap.%p\n",queue_size(&exchange->acceptableQ),retap);
return(retap);
}
// NXTrequest: // NXTrequest:
// sends NXT assetid, volume and desired // sends NXT assetid, volume and desired
@ -1168,11 +1181,11 @@ char *instantdex_checkoffer(struct supernet_info *myinfo,uint64_t *txidp,struct
*txidp = myap->orderid; *txidp = myap->orderid;
if ( (otherap= instantdex_acceptable(myinfo,exchange,myap,myap->offer.minperc)) == 0 ) if ( (otherap= instantdex_acceptable(myinfo,exchange,myap,myap->offer.minperc)) == 0 )
{ {
if ( instantdex_offerfind(myinfo,exchange,0,0,myap->orderid,myap->offer.base,myap->offer.rel,1,0) == 0 ) if ( instantdex_offerfind(myinfo,exchange,0,0,myap->orderid,myap->offer.base,myap->offer.rel,0) == 0 )
{ {
printf("instantdex_checkoffer add.%llu from.%llu to acceptableQ\n",(long long)myap->orderid,(long long)myap->offer.account); printf("instantdex_checkoffer add.%llu from.%llu to acceptableQ\n",(long long)myap->orderid,(long long)myap->offer.account);
queue_enqueue("acceptableQ",&exchange->acceptableQ,&myap->DL,0); instantdex_offeradd(exchange,myap);
if ( instantdex_offerfind(myinfo,exchange,0,0,myap->orderid,myap->offer.base,myap->offer.rel,1,0) == 0 ) if ( instantdex_offerfind(myinfo,exchange,0,0,myap->orderid,myap->offer.base,myap->offer.rel,0) == 0 )
printf("cant find just added to acceptableQ\n"); printf("cant find just added to acceptableQ\n");
} }
return(jprint(instantdex_offerjson(&myap->offer,myap->orderid),1)); return(jprint(instantdex_offerjson(&myap->offer,myap->orderid),1));
@ -1185,7 +1198,7 @@ char *instantdex_checkoffer(struct supernet_info *myinfo,uint64_t *txidp,struct
{ {
printf("STATEMACHINEQ.(%llu / %llu)\n",(long long)swap->mine.orderid,(long long)swap->other.orderid); printf("STATEMACHINEQ.(%llu / %llu)\n",(long long)swap->mine.orderid,(long long)swap->other.orderid);
//queue_enqueue("acceptableQ",&exchange->acceptableQ,&swap->DL,0); //queue_enqueue("acceptableQ",&exchange->acceptableQ,&swap->DL,0);
queue_enqueue("statemachineQ",&exchange->statemachineQ,&swap->DL,0); instantdex_statemachineadd(exchange,swap);
if ( (newjson= instantdex_parseargjson(myinfo,exchange,swap,argjson,1)) == 0 ) if ( (newjson= instantdex_parseargjson(myinfo,exchange,swap,argjson,1)) == 0 )
return(clonestr("{\"error\":\"instantdex_checkoffer null newjson\"}")); return(clonestr("{\"error\":\"instantdex_checkoffer null newjson\"}"));
return(instantdex_sendcmd(myinfo,&swap->mine.offer,newjson,"BTCoffer",GENESIS_PUBKEY,INSTANTDEX_HOPS,swap->deck,sizeof(swap->deck),0)); return(instantdex_sendcmd(myinfo,&swap->mine.offer,newjson,"BTCoffer",GENESIS_PUBKEY,INSTANTDEX_HOPS,swap->deck,sizeof(swap->deck),0));
@ -1232,7 +1245,7 @@ char *instantdex_gotoffer(struct supernet_info *myinfo,struct exchange_info *exc
{ {
printf("create statemachine\n"); printf("create statemachine\n");
//queue_enqueue("acceptableQ",&exchange->acceptableQ,&swap->DL,0); //queue_enqueue("acceptableQ",&exchange->acceptableQ,&swap->DL,0);
queue_enqueue("statemachineQ",&exchange->statemachineQ,&swap->DL,0); instantdex_statemachineadd(exchange,swap);
if ( (retstr= instantdex_choosei(swap,newjson,argjson,serdata,serdatalen)) != 0 ) if ( (retstr= instantdex_choosei(swap,newjson,argjson,serdata,serdatalen)) != 0 )
return(retstr); return(retstr);
else else
@ -1246,8 +1259,6 @@ char *instantdex_gotoffer(struct supernet_info *myinfo,struct exchange_info *exc
char *instantdex_parse(struct supernet_info *myinfo,struct instantdex_msghdr *msg,cJSON *argjson,char *remoteaddr,uint64_t signerbits,struct instantdex_offer *offer,bits256 orderhash,uint8_t *serdata,int32_t serdatalen) char *instantdex_parse(struct supernet_info *myinfo,struct instantdex_msghdr *msg,cJSON *argjson,char *remoteaddr,uint64_t signerbits,struct instantdex_offer *offer,bits256 orderhash,uint8_t *serdata,int32_t serdatalen)
{ {
char cmdstr[16],*retstr; struct exchange_info *exchange; struct instantdex_accept A,*ap = 0; bits256 traderpub; cJSON *newjson; struct bitcoin_swapinfo *swap; char cmdstr[16],*retstr; struct exchange_info *exchange; struct instantdex_accept A,*ap = 0; bits256 traderpub; cJSON *newjson; struct bitcoin_swapinfo *swap;
if ( BTC_states == 0 )
BTC_states = BTC_initFSM(&BTC_numstates);
exchange = exchanges777_find("bitcoin"); exchange = exchanges777_find("bitcoin");
memset(cmdstr,0,sizeof(cmdstr)), memcpy(cmdstr,msg->cmd,sizeof(msg->cmd)); memset(cmdstr,0,sizeof(cmdstr)), memcpy(cmdstr,msg->cmd,sizeof(msg->cmd));
if ( argjson != 0 ) if ( argjson != 0 )
@ -1266,7 +1277,7 @@ char *instantdex_parse(struct supernet_info *myinfo,struct instantdex_msghdr *ms
A.offer.minperc = INSTANTDEX_MINPERC; A.offer.minperc = INSTANTDEX_MINPERC;
else if ( A.offer.minperc > 100 ) else if ( A.offer.minperc > 100 )
A.offer.minperc = 100; A.offer.minperc = 100;
if ( (swap= instantdex_statemachinefind(myinfo,exchange,A.orderid,1)) != 0 ) if ( (swap= instantdex_statemachinefind(myinfo,exchange,A.orderid)) != 0 )
{ {
printf("found existing state machine %llu\n",(long long)A.orderid); printf("found existing state machine %llu\n",(long long)A.orderid);
newjson = instantdex_parseargjson(myinfo,exchange,swap,argjson,0); newjson = instantdex_parseargjson(myinfo,exchange,swap,argjson,0);
@ -1291,12 +1302,12 @@ char *instantdex_parse(struct supernet_info *myinfo,struct instantdex_msghdr *ms
else else
{ {
printf("no matching trade for %s %llu -> InstantDEX_minaccept isbob.%d\n",cmdstr,(long long)A.orderid,A.offer.myside); printf("no matching trade for %s %llu -> InstantDEX_minaccept isbob.%d\n",cmdstr,(long long)A.orderid,A.offer.myside);
if ( instantdex_offerfind(myinfo,exchange,0,0,A.orderid,"*","*",1,0) == 0 ) if ( instantdex_offerfind(myinfo,exchange,0,0,A.orderid,"*","*",0) == 0 )
{ {
ap = calloc(1,sizeof(*ap)); ap = calloc(1,sizeof(*ap));
*ap = A; *ap = A;
printf("acceptableQ <- %llu\n",(long long)ap->orderid); printf("acceptableQ <- %llu\n",(long long)ap->orderid);
queue_enqueue("acceptableQ",&exchange->acceptableQ,&ap->DL,0); instantdex_offeradd(exchange,ap);
return(clonestr("{\"result\":\"added new order to orderbook\"}")); return(clonestr("{\"result\":\"added new order to orderbook\"}"));
} else return(clonestr("{\"result\":\"order was already in orderbook\"}")); } else return(clonestr("{\"result\":\"order was already in orderbook\"}"));
} }
@ -1316,8 +1327,6 @@ char *InstantDEX_hexmsg(struct supernet_info *myinfo,struct category_info *cat,v
uint8_t *serdata; struct supernet_info *myinfos[64]; struct instantdex_offer rawoffer; uint8_t *serdata; struct supernet_info *myinfos[64]; struct instantdex_offer rawoffer;
uint64_t signerbits; uint8_t tmp[sizeof(msg->sig)]; char *retstr = 0; uint64_t signerbits; uint8_t tmp[sizeof(msg->sig)]; char *retstr = 0;
bits256 orderhash,traderpub; cJSON *retjson,*item,*argjson = 0; bits256 orderhash,traderpub; cJSON *retjson,*item,*argjson = 0;
if ( BTC_states == 0 )
BTC_states = BTC_initFSM(&BTC_numstates);
datalen = len - (int32_t)sizeof(msg->sig); datalen = len - (int32_t)sizeof(msg->sig);
serdata = (void *)((long)msg + sizeof(msg->sig)); serdata = (void *)((long)msg + sizeof(msg->sig));
//printf("a signed datalen.%d allocsize.%d crc.%x\n",datalen,msg->sig.allocsize,calc_crc32(0,serdata,datalen)); //printf("a signed datalen.%d allocsize.%d crc.%x\n",datalen,msg->sig.allocsize,calc_crc32(0,serdata,datalen));
@ -1404,13 +1413,13 @@ char *instantdex_createaccept(struct supernet_info *myinfo,struct instantdex_acc
printf("myside.(%s) != base.%s or rel.%s\n",mysidestr,base,rel); printf("myside.(%s) != base.%s or rel.%s\n",mysidestr,base,rel);
} }
instantdex_acceptset(ap,base,rel,duration,myside,acceptdir,price,basevolume,account,0,minperc); instantdex_acceptset(ap,base,rel,duration,myside,acceptdir,price,basevolume,account,0,minperc);
if ( instantdex_offerfind(myinfo,exchange,0,0,ap->orderid,ap->offer.base,ap->offer.rel,1,0) == 0 ) if ( instantdex_offerfind(myinfo,exchange,0,0,ap->orderid,ap->offer.base,ap->offer.rel,0) == 0 )
{ {
instantdex_propagate(myinfo,exchange,ap); instantdex_propagate(myinfo,exchange,ap);
if ( queueflag != 0 ) if ( queueflag != 0 )
{ {
printf("acceptableQ <- %llu\n",(long long)ap->orderid); printf("acceptableQ <- %llu\n",(long long)ap->orderid);
queue_enqueue("acceptableQ",&exchange->acceptableQ,&ap->DL,0); instantdex_offeradd(exchange,ap);
} }
retstr = jprint(instantdex_acceptjson(ap),1); retstr = jprint(instantdex_acceptjson(ap),1);
//printf("acceptableQ %llu (%s)\n",(long long)ap->orderid,retstr); //printf("acceptableQ %llu (%s)\n",(long long)ap->orderid,retstr);
@ -1474,7 +1483,7 @@ char *instantdex_statemachineget(struct supernet_info *myinfo,struct bitcoin_swa
{ {
orderid = j64bits(argjson,"myorderid"); orderid = j64bits(argjson,"myorderid");
otherorderid = j64bits(argjson,"otherid"); otherorderid = j64bits(argjson,"otherid");
if ( (swap= instantdex_statemachinefind(myinfo,exchange,orderid,1)) != 0 ) if ( (swap= instantdex_statemachinefind(myinfo,exchange,orderid)) != 0 )
{ {
if ( swap->other.orderid != otherorderid ) if ( swap->other.orderid != otherorderid )
return(clonestr("{\"error\":\"statemachine otherid mismatch\"}")); return(clonestr("{\"error\":\"statemachine otherid mismatch\"}"));
@ -1555,7 +1564,7 @@ TWO_STRINGS(InstantDEX,events,base,rel)
{ {
bids = cJSON_CreateArray(); bids = cJSON_CreateArray();
asks = cJSON_CreateArray(); asks = cJSON_CreateArray();
instantdex_offerfind(myinfo,exchange,bids,asks,0,base,rel,1,1); instantdex_offerfind(myinfo,exchange,bids,asks,0,base,rel,1);
if ( (n= cJSON_GetArraySize(bids)) > 0 ) if ( (n= cJSON_GetArraySize(bids)) > 0 )
{ {
for (i=0; i<n; i++) for (i=0; i<n; i++)

39
iguana/iguana_tradebots.c

@ -27,7 +27,7 @@ struct tradebot_trade
struct tradebot_info struct tradebot_info
{ {
struct queueitem DL; struct tradebot_info *next,*prev;
struct supernet_info *myinfo; struct supernet_info *myinfo;
char name[128],exchangestr[32],base[32],rel[32]; char name[128],exchangestr[32],base[32],rel[32];
int32_t dir,numtrades,estimatedtrades; int32_t dir,numtrades,estimatedtrades;
@ -88,10 +88,9 @@ cJSON *tradebot_json(struct supernet_info *myinfo,struct exchange_info *exchange
struct tradebot_info *tradebot_find(struct supernet_info *myinfo,struct exchange_info *exchange,char *botname,cJSON *array,char *base,char *rel) struct tradebot_info *tradebot_find(struct supernet_info *myinfo,struct exchange_info *exchange,char *botname,cJSON *array,char *base,char *rel)
{ {
struct tradebot_info PAD,*bot,*retbot = 0; struct tradebot_info *tmp,*bot,*retbot = 0;
memset(&PAD,0,sizeof(PAD)); portable_mutex_lock(&exchange->mutexT);
queue_enqueue("tradebotsQ",&exchange->tradebotsQ,&PAD.DL,0); DL_FOREACH_SAFE(exchange->tradebots,bot,tmp)
while ( (bot= queue_dequeue(&exchange->tradebotsQ,0)) != 0 && bot != &PAD )
{ {
if ( botname != 0 && strcmp(botname,bot->name) == 0 ) if ( botname != 0 && strcmp(botname,bot->name) == 0 )
retbot = bot; retbot = bot;
@ -99,11 +98,18 @@ struct tradebot_info *tradebot_find(struct supernet_info *myinfo,struct exchange
jaddi(array,tradebot_json(myinfo,exchange,bot)); jaddi(array,tradebot_json(myinfo,exchange,bot));
if ( base != 0 && rel != 0 && strcmp(base,bot->base) == 0 && strcmp(rel,bot->rel) == 0 ) if ( base != 0 && rel != 0 && strcmp(base,bot->base) == 0 && strcmp(rel,bot->rel) == 0 )
retbot = bot; retbot = bot;
queue_enqueue("tradebotsQ",&exchange->tradebotsQ,&bot->DL,0);
} }
portable_mutex_unlock(&exchange->mutexT);
return(retbot); return(retbot);
} }
void tradebot_add(struct exchange_info *exchange,struct tradebot_info *bot)
{
portable_mutex_lock(&exchange->mutexT);
DL_APPEND(exchange->tradebots,bot);
portable_mutex_unlock(&exchange->mutexT);
}
struct tradebot_info *tradebot_create(struct supernet_info *myinfo,struct exchange_info *exchange,char *base,char *rel,int32_t dir,double price,double volume,int32_t duration) struct tradebot_info *tradebot_create(struct supernet_info *myinfo,struct exchange_info *exchange,char *base,char *rel,int32_t dir,double price,double volume,int32_t duration)
{ {
struct tradebot_info *bot; struct tradebot_info *bot;
@ -120,7 +126,7 @@ struct tradebot_info *tradebot_create(struct supernet_info *myinfo,struct exchan
bot->expiration = bot->started + duration; bot->expiration = bot->started + duration;
bot->estimatedtrades = (duration / TRADEBOTS_GAPTIME) + 1; bot->estimatedtrades = (duration / TRADEBOTS_GAPTIME) + 1;
sprintf(bot->name,"%s_%s_%s.%d",exchange->name,base,rel,bot->started); sprintf(bot->name,"%s_%s_%s.%d",exchange->name,base,rel,bot->started);
queue_enqueue("tradebotsQ",&exchange->tradebotsQ,&bot->DL,0); tradebot_add(exchange,bot);
} }
return(bot); return(bot);
} }
@ -156,8 +162,23 @@ void tradebot_timeslice(struct exchange_info *exchange,void *_bot)
} }
} }
} }
queue_enqueue("tradebotsQ",&exchange->tradebotsQ,&bot->DL,0); }
} else free(bot); else
{
DL_DELETE(exchange->tradebots,bot);
free(bot);
}
}
void tradebot_timeslices(struct exchange_info *exchange)
{
struct tradebot_info *bot,*tmp;
portable_mutex_lock(&exchange->mutexT);
DL_FOREACH_SAFE(exchange->tradebots,bot,tmp)
{
tradebot_timeslice(exchange,bot);
}
portable_mutex_unlock(&exchange->mutexT);
} }
char *tradebot_launch(struct supernet_info *myinfo,char *exchangestr,char *base,char *rel,int32_t dir,double price,double volume,int32_t duration,char *remoteaddr,cJSON *json) char *tradebot_launch(struct supernet_info *myinfo,char *exchangestr,char *base,char *rel,int32_t dir,double price,double volume,int32_t duration,char *remoteaddr,cJSON *json)

7
iguana/main.c

@ -1159,7 +1159,7 @@ void iguana_appletests(struct supernet_info *myinfo)
if ( 1 && (str= SuperNET_JSON(myinfo,cJSON_Parse("{\"RELAY\":1,\"VALIDATE\":1,\"prefetchlag\":-1,\"agent\":\"iguana\",\"method\":\"addcoin\",\"startpend\":4,\"endpend\":4,\"services\":129,\"maxpeers\":64,\"newcoin\":\"BTCD\",\"active\":1,\"numhelpers\":4,\"poll\":100}"),0,myinfo->rpcport)) != 0 ) if ( 1 && (str= SuperNET_JSON(myinfo,cJSON_Parse("{\"RELAY\":1,\"VALIDATE\":1,\"prefetchlag\":-1,\"agent\":\"iguana\",\"method\":\"addcoin\",\"startpend\":4,\"endpend\":4,\"services\":129,\"maxpeers\":64,\"newcoin\":\"BTCD\",\"active\":1,\"numhelpers\":4,\"poll\":100}"),0,myinfo->rpcport)) != 0 )
{ {
free(str); free(str);
if ( 1 && (str= SuperNET_JSON(myinfo,cJSON_Parse("{\"RELAY\":1,\"VALIDATE\":1,\"prefetchlag\":-1,\"agent\":\"iguana\",\"method\":\"addcoin\",\"startpend\":4,\"endpend\":4,\"services\":129,\"maxpeers\":64,\"newcoin\":\"BTC\",\"active\":0,\"numhelpers\":4,\"poll\":100}"),0,myinfo->rpcport)) != 0 ) if ( 0 && (str= SuperNET_JSON(myinfo,cJSON_Parse("{\"RELAY\":1,\"VALIDATE\":1,\"prefetchlag\":-1,\"agent\":\"iguana\",\"method\":\"addcoin\",\"startpend\":4,\"endpend\":4,\"services\":129,\"maxpeers\":64,\"newcoin\":\"BTC\",\"active\":0,\"numhelpers\":4,\"poll\":100}"),0,myinfo->rpcport)) != 0 )
{ {
free(str); free(str);
if ( 0 && (str= SuperNET_JSON(myinfo,cJSON_Parse("{\"agent\":\"SuperNET\",\"method\":\"login\",\"handle\":\"alice\",\"password\":\"alice\",\"passphrase\":\"alice\"}"),0,myinfo->rpcport)) != 0 ) if ( 0 && (str= SuperNET_JSON(myinfo,cJSON_Parse("{\"agent\":\"SuperNET\",\"method\":\"login\",\"handle\":\"alice\",\"password\":\"alice\",\"passphrase\":\"alice\"}"),0,myinfo->rpcport)) != 0 )
@ -1315,7 +1315,7 @@ int32_t iguana_isbigendian()
void iguana_main(void *arg) void iguana_main(void *arg)
{ {
int32_t usessl = 0, ismainnet = 1; struct supernet_info *myinfo; int32_t usessl = 0, ismainnet = 1; struct supernet_info *myinfo; cJSON *argjson = 0;
if ( (BIGENDIAN= iguana_isbigendian()) > 0 ) if ( (BIGENDIAN= iguana_isbigendian()) > 0 )
printf("BIGENDIAN\n"); printf("BIGENDIAN\n");
else if ( BIGENDIAN == 0 ) else if ( BIGENDIAN == 0 )
@ -1332,6 +1332,9 @@ void iguana_main(void *arg)
iguana_urlinit(myinfo,ismainnet,usessl); iguana_urlinit(myinfo,ismainnet,usessl);
category_init(myinfo); category_init(myinfo);
exchange_create("bitcoin",0); exchange_create("bitcoin",0);
argjson = arg != 0 ? cJSON_Parse(arg) : cJSON_Parse("{}");
iguana_coinadd("BTC",argjson);
free_json(argjson);
iguana_helpinit(myinfo); iguana_helpinit(myinfo);
iguana_commandline(myinfo,arg); iguana_commandline(myinfo,arg);
#ifdef __APPLE__ #ifdef __APPLE__

2
iguana/swaps/iguana_BTCswap.c

@ -971,7 +971,7 @@ char *instantdex_statemachine(struct instantdex_stateinfo *states,int32_t numsta
uint32_t i; struct iguana_info *altcoin=0,*coinbtc=0; struct instantdex_stateinfo *state=0; cJSON *origjson = newjson; uint32_t i; struct iguana_info *altcoin=0,*coinbtc=0; struct instantdex_stateinfo *state=0; cJSON *origjson = newjson;
if ( swap == 0 || (state= swap->state) == 0 || (coinbtc= iguana_coinfind("BTC")) == 0 || (altcoin= iguana_coinfind(swap->mine.offer.base)) == 0 ) if ( swap == 0 || (state= swap->state) == 0 || (coinbtc= iguana_coinfind("BTC")) == 0 || (altcoin= iguana_coinfind(swap->mine.offer.base)) == 0 )
{ {
printf("state.%s btc.%p altcoin.%p\n",state->name,coinbtc,altcoin); printf("state.%s btc.%p altcoin.%p (%s)\n",state->name,coinbtc,altcoin,swap->mine.offer.base);
return(clonestr("{\"error\":\"instantdex_BTCswap missing coin info\"}")); return(clonestr("{\"error\":\"instantdex_BTCswap missing coin info\"}"));
} }
printf("%llu/%llu cmd.(%s) state.(%s)\n",(long long)swap->mine.orderid,(long long)swap->other.orderid,cmdstr,swap->state->name); printf("%llu/%llu cmd.(%s) state.(%s)\n",(long long)swap->mine.orderid,(long long)swap->other.orderid,cmdstr,swap->state->name);

Loading…
Cancel
Save