Browse Source

current pexe

release/v0.1
jl777 9 years ago
parent
commit
08ed8a6c76
  1. 178
      deprecated/obsolete.h
  2. 62
      iguana/exchanges/bitcoin.c
  3. 2
      iguana/exchanges/bitcoin.h
  4. 77
      iguana/exchanges777.h
  5. 533
      iguana/iguana_instantdex.c
  6. BIN
      iguana/pnacl/Release/iguana.pexe
  7. 329
      iguana/swaps/iguana_BTCswap.c

178
deprecated/obsolete.h

@ -13721,5 +13721,183 @@ len = 0;
else printf("BTCSWAP.(%s)\n",retstr);
return(retstr);
#endif
else if ( strcmp(cmdstr,"BTCdeckC") == 0 )
{
if ( ap->info == 0 )
{
printf("A (%s) null swap for orderid.%llu p.%p\n",cmdstr,(long long)ap->orderid,ap);
return(clonestr("{\"error\":\"no swap for orderid\"}"));
}
else
{
if ( ap->otherorderid == 0 )
{
ap->otherorderid = ap->orderid;
ap->otheroffer = ap->offer;
ap->offer = A.offer;
ap->orderid = A.orderid;
((struct bitcoin_swapinfo *)ap->info)->feetag64 = ap->orderid;
}
printf("add to statemachine\n");
queue_enqueue("statemachineQ",&exchange->statemachineQ,&ap->DL,0);
newjson = instantdex_parseargjson(myinfo,exchange,ap,argjson,0);
if ( (retstr= instantdex_addfeetx(myinfo,newjson,ap,ap->info,"BOB_sentoffer","ALICE_sentoffer")) == 0 )
{
return(instantdex_statemachine(BTC_states,BTC_numstates,myinfo,exchange,ap,cmdstr,argjson,newjson,serdata,serdatalen));
} else return(clonestr("{\"error\":\"couldnt add fee\"}"));
}
/*
for (iter=0; iter<2; iter++)
{
while ( (m= category_gethexmsg(myinfo,instantdexhash,iter == 0 ? GENESIS_PUBKEY : myinfo->myaddr.persistent)) != 0 )
{
//printf("gothexmsg len.%d\n",m->len);
pm = (struct instantdex_msghdr *)m->msg;
if ( m->remoteipbits != 0 )
expand_ipbits(remote,m->remoteipbits);
else remote[0] = 0;
if ( (str= InstantDEX_hexmsg(myinfo,pm,m->len,remote)) != 0 )
free(str);
free(m);
}
}*/
/* uint64_t satoshis[2]; int32_t offerdir = 0; double minperc; uint64_t insurance,relsatoshis;
bits256 orderhash,traderpub; struct iguana_info *coinbtc;
if ( (swap= ap->info) == 0 )
return(clonestr("{\"error\":\"no swapinfo set\"}"));
relsatoshis = instantdex_BTCsatoshis(ap->offer.price64,ap->offer.basevolume64);
if ( (minperc= jdouble(argjson,"m")) < INSTANTDEX_MINPERC )
minperc = INSTANTDEX_MINPERC;
offerdir = instantdex_bidaskdir(&ap->offer);
if ( 0 )
{
int32_t i;
for (i=0; i<sizeof(ap->offer); i++)
printf("%02x ",((uint8_t *)&ap->offer)[i]);
printf("swapset.%llu\n",(long long)ap->orderid);
}
if ( offerdir > 0 )
{
swap->bidid = ap->orderid;
swap->askid = ap->otherorderid;
}
else
{
swap->askid = ap->orderid;
swap->bidid = ap->otherorderid;
}
if ( bits256_nonz(swap->othertrader) == 0 )
swap->othertrader = traderpub;
else if ( bits256_cmp(traderpub,swap->othertrader) != 0 )
{
printf("competing offer received for (%s/%s) %.8f %.8f\n",ap->offer.base,ap->offer.rel,dstr(ap->offer.price64),dstr(ap->offer.basevolume64));
return(clonestr("{\"error\":\"no competing offers for now\"}"));
}
if ( bits256_nonz(swap->orderhash) == 0 )
swap->orderhash = orderhash;
else if ( bits256_cmp(orderhash,swap->orderhash) != 0 )
{
printf("orderhash %llx mismatch %llx\n",(long long)swap->orderhash.txid,(long long)orderhash.txid);
return(clonestr("{\"error\":\"orderhash mismatch???\"}"));
}
swap->satoshis[0] = ap->offer.basevolume64;
swap->satoshis[1] = relsatoshis;
swap->insurance = (relsatoshis * INSTANTDEX_INSURANCERATE + coinbtc->chain->txfee); // txfee
/* if ( ap->info == 0 )
//printf("gotoffer SETSWAP for orderid.%llu (%s)\n",(long long)ap->orderid,jprint(argjson,0));
swap->choosei = swap->otherschoosei = -1;
if ( (retstr= instantdex_swapset(myinfo,ap,argjson)) != 0 )
return(retstr);
swap->feetag64 = ap->orderid;*/
/*char *instantdex_swapset(struct supernet_info *myinfo,struct instantdex_accept *ap,cJSON *argjson)
{
uint64_t satoshis[2]; int32_t offerdir = 0; double minperc; uint64_t insurance,relsatoshis;
struct bitcoin_swapinfo *swap; bits256 orderhash,traderpub; struct iguana_info *coinbtc;
if ( (swap= ap->info) == 0 )
return(clonestr("{\"error\":\"no swapinfo set\"}"));
relsatoshis = instantdex_BTCsatoshis(ap->offer.price64,ap->offer.basevolume64);
traderpub = jbits256(argjson,"traderpub");
if ( (minperc= jdouble(argjson,"m")) < INSTANTDEX_MINPERC )
minperc = INSTANTDEX_MINPERC;
if ( (coinbtc= iguana_coinfind("BTC")) == 0 )
return(clonestr("{\"error\":\"no BTC found\"}"));
insurance = (satoshis[1] * INSTANTDEX_INSURANCERATE + coinbtc->chain->txfee);
offerdir = instantdex_bidaskdir(&ap->offer);
vcalc_sha256(0,orderhash.bytes,(void *)&ap->offer,sizeof(ap->offer));
if ( 0 )
{
int32_t i;
for (i=0; i<sizeof(ap->offer); i++)
printf("%02x ",((uint8_t *)&ap->offer)[i]);
printf("swapset.%llu\n",(long long)ap->orderid);
}
if ( offerdir > 0 )
{
swap->bidid = ap->orderid;
swap->askid = ap->otherorderid;
}
else
{
swap->askid = ap->orderid;
swap->bidid = ap->otherorderid;
}
if ( bits256_nonz(swap->othertrader) == 0 )
swap->othertrader = traderpub;
else if ( bits256_cmp(traderpub,swap->othertrader) != 0 )
{
printf("competing offer received for (%s/%s) %.8f %.8f\n",ap->offer.base,ap->offer.rel,dstr(ap->offer.price64),dstr(ap->offer.basevolume64));
return(clonestr("{\"error\":\"no competing offers for now\"}"));
}
if ( bits256_nonz(swap->orderhash) == 0 )
swap->orderhash = orderhash;
else if ( bits256_cmp(orderhash,swap->orderhash) != 0 )
{
printf("orderhash %llx mismatch %llx\n",(long long)swap->orderhash.txid,(long long)orderhash.txid);
return(clonestr("{\"error\":\"orderhash mismatch???\"}"));
}
swap->satoshis[0] = ap->offer.basevolume64;
swap->satoshis[1] = relsatoshis;
swap->insurance = (relsatoshis * INSTANTDEX_INSURANCERATE + coinbtc->chain->txfee); // txfee
return(0);
}
char *instantdex_sendoffer(struct supernet_info *myinfo,struct exchange_info *exchange,struct instantdex_accept *ap,cJSON *argjson) // Bob sending to network (Alice)
{
struct iguana_info *other; struct bitcoin_swapinfo *swap; int32_t isbob; cJSON *newjson; char *retstr;
if ( strcmp(ap->offer.rel,"BTC") != 0 )
return(clonestr("{\"error\":\"invalid othercoin\"}"));
else if ( (other= iguana_coinfind(ap->offer.base)) == 0 )
return(clonestr("{\"error\":\"invalid othercoin\"}"));
else if ( ap->offer.price64 <= 0 || ap->offer.basevolume64 <= 0 )
return(clonestr("{\"error\":\"illegal price or volume\"}"));
isbob = (ap->offer.myside == 1);
swap = calloc(1,sizeof(struct bitcoin_swapinfo));
swap->isbob = isbob;
swap->expiration = ap->offer.expiration;//(uint32_t)(time(NULL) + INSTANTDEX_LOCKTIME*isbob);
swap->choosei = swap->otherschoosei = -1;
swap->depositconfirms = swap->paymentconfirms = swap->altpaymentconfirms = swap->myfeeconfirms = swap->otherfeeconfirms = -1;
ap->info = swap;
printf("sendoffer SETSWAP for orderid.%llu ap.%p (%p)\n",(long long)ap->orderid,ap,swap);
if ( (retstr= instantdex_swapset(myinfo,ap,argjson)) != 0 )
return(retstr);
ap->orderid = swap->orderhash.txid;
if ( (newjson= instantdex_parseargjson(myinfo,exchange,ap,argjson,1)) == 0 )
return(clonestr("{\"error\":\"instantdex_BTCswap offer null newjson\"}"));
else
{
//instantdex_bobtx(myinfo,iguana_coinfind("BTCD"),&swap->deposittxid,swap->otherpubs[0],swap->mypubs[0],swap->privkeys[swap->choosei],ap->offer.expiration-INSTANTDEX_LOCKTIME*2,swap->satoshis[1],1);
//instantdex_alicetx(myinfo,iguana_coinfind("BTCD"),swap->altmsigaddr,&swap->altpaymenttxid,swap->pubAm,swap->pubBn,swap->satoshis[0]);
if ( 0 )
{
int32_t i;
for (i=0; i<sizeof(ap->offer); i++)
printf("%02x ",((uint8_t *)&ap->offer)[i]);
printf("BTCoffer.%llu\n",(long long)ap->orderid);
}
return(instantdex_sendcmd(myinfo,&ap->offer,newjson,"BTCoffer",GENESIS_PUBKEY,INSTANTDEX_HOPS,swap->deck,sizeof(swap->deck)));
}
}*/
#endif

62
iguana/exchanges/bitcoin.c

@ -2099,7 +2099,8 @@ 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,coinaddr[64]; uint64_t txid = 0; cJSON *tmp,*json=0; struct instantdex_accept *ap;
char *str,*retstr,coinaddr[64]; uint64_t txid = 0; cJSON *json=0;
struct instantdex_accept *ap;
struct supernet_info *myinfo; uint8_t pubkey[33]; struct iguana_info *other;
myinfo = SuperNET_accountfind(argjson);
//printf("TRADE with myinfo.%p\n",myinfo);
@ -2140,27 +2141,15 @@ uint64_t TRADE(int32_t dotrade,char **retstrp,struct exchange_info *exchange,cha
jaddnum(json,dir > 0 ? "maxprice" : "minprice",price);
jaddnum(json,"volume",volume);
jaddstr(json,"BTC",myinfo->myaddr.BTC);
jaddnum(json,"minperc",jdouble(argjson,"minperc"));
//printf("trade dir.%d (%s/%s) %.6f vol %.8f\n",dir,base,"BTC",price,volume);
if ( (str= instantdex_queueaccept(myinfo,&ap,exchange,base,"BTC",price,volume,-dir,dir > 0 ? "BTC" : base,INSTANTDEX_OFFERDURATION,myinfo->myaddr.nxt64bits,0)) != 0 && ap != 0 )
{
if ( (tmp= cJSON_Parse(str)) != 0 )
{
txid = j64bits(json,"orderid");
if ( (str= instantdex_sendoffer(myinfo,exchange,ap,json)) != 0 )
{
printf("add.%llu to acceptableQ\n",(long long)txid);
queue_enqueue("acceptableQ",&exchange->acceptableQ,&ap->DL,0);
//queue_enqueue("statemachineQ",&exchange->statemachineQ,&ap->DL,0);
json = cJSON_CreateObject();
printf("from TRADE\n");
jaddstr(json,"BTCoffer",str);
} else printf("null return from btcoffer\n");
free_json(tmp);
} else printf("queueaccept return parse error.(%s)\n",str);
} else printf("null return queueaccept\n");
if ( (str= instantdex_createaccept(myinfo,&ap,exchange,base,"BTC",price,volume,-dir,dir > 0 ? "BTC" : base,INSTANTDEX_OFFERDURATION,myinfo->myaddr.nxt64bits,0,jdouble(argjson,"minperc"))) != 0 && ap != 0 )
retstr = instantdex_checkoffer(myinfo,&txid,exchange,ap,json), free(str);
else printf("null return queueaccept\n");
if ( retstrp != 0 )
*retstrp = jprint(json,1);
else free_json(json);
*retstrp = retstr != 0 ? retstr : jprint(json,0);
else free(retstr);
free_json(json);
}
}
return(txid);
@ -2168,32 +2157,35 @@ uint64_t TRADE(int32_t dotrade,char **retstrp,struct exchange_info *exchange,cha
char *ORDERSTATUS(struct exchange_info *exchange,uint64_t orderid,cJSON *argjson)
{
struct instantdex_accept *ap; cJSON *retjson = cJSON_CreateObject();
struct instantdex_accept *ap; struct bitcoin_swapinfo *swap; cJSON *retjson;
retjson = cJSON_CreateObject();
struct supernet_info *myinfo = SuperNET_accountfind(argjson);
if ( (ap= instantdex_statemachinefind(myinfo,exchange,orderid,1)) != 0 )
jadd(retjson,"result",instantdex_statemachinejson(ap));
if ( (swap= instantdex_statemachinefind(myinfo,exchange,orderid,1)) != 0 )
jadd(retjson,"result",instantdex_statemachinejson(swap));
else if ( (ap= instantdex_offerfind(myinfo,exchange,0,0,orderid,"*","*",1)) != 0 )
jadd(retjson,"result",instantdex_acceptjson(ap));
else if ( (ap= instantdex_historyfind(myinfo,exchange,orderid)) != 0 )
jadd(retjson,"result",instantdex_historyjson(ap));
else if ( (swap= instantdex_historyfind(myinfo,exchange,orderid)) != 0 )
jadd(retjson,"result",instantdex_historyjson(swap));
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 instantdex_accept *ap = 0; cJSON *retjson; struct bitcoin_swapinfo *swap=0;
struct supernet_info *myinfo = SuperNET_accountfind(argjson);
retjson = cJSON_CreateObject();
if ( (ap= instantdex_offerfind(myinfo,exchange,0,0,orderid,"*","*",1)) != 0 )
jadd(retjson,"orderid",instantdex_acceptjson(ap));
else if ( (ap= instantdex_statemachinefind(myinfo,exchange,orderid,1)) != 0 )
jadd(retjson,"orderid",instantdex_statemachinejson(ap));
if ( ap != 0 )
{
ap->dead = (uint32_t)time(NULL);
jadd(retjson,"orderid",instantdex_acceptjson(ap));
jaddstr(retjson,"result","killed orderid, but might have pending");
} else jaddstr(retjson,"error","couldnt find orderid");
}
else if ( (swap= instantdex_statemachinefind(myinfo,exchange,orderid,1)) != 0 )
{
jadd(retjson,"orderid",instantdex_statemachinejson(swap));
jaddstr(retjson,"result","killed statemachine orderid, but might have pending");
}
return(jprint(retjson,1));
}
@ -2212,13 +2204,13 @@ char *OPENORDERS(struct exchange_info *exchange,cJSON *argjson)
char *TRADEHISTORY(struct exchange_info *exchange,cJSON *argjson)
{
struct instantdex_accept PAD,*ap; cJSON *retjson = cJSON_CreateArray();
struct bitcoin_swapinfo PAD,*swap; cJSON *retjson = cJSON_CreateArray();
memset(&PAD,0,sizeof(PAD));
queue_enqueue("historyQ",&exchange->historyQ,&PAD.DL,0);
while ( (ap= queue_dequeue(&exchange->historyQ,0)) != 0 && ap != &PAD )
while ( (swap= queue_dequeue(&exchange->historyQ,0)) != 0 && swap != &PAD )
{
jaddi(retjson,instantdex_historyjson(ap));
queue_enqueue("historyQ",&exchange->historyQ,&ap->DL,0);
jaddi(retjson,instantdex_historyjson(swap));
queue_enqueue("historyQ",&exchange->historyQ,&swap->DL,0);
}
return(jprint(retjson,1));
}

2
iguana/exchanges/bitcoin.h

@ -57,5 +57,7 @@ int32_t bitcoin_p2shspend(uint8_t *script,int32_t n,uint8_t rmd160[20]);
int32_t bitcoin_revealsecret160(uint8_t *script,int32_t n,uint8_t secret160[20]);
int32_t bitcoin_standardspend(uint8_t *script,int32_t n,uint8_t rmd160[20]);
cJSON *instantdex_statemachinejson(struct bitcoin_swapinfo *ap);
#endif

77
iguana/exchanges777.h

@ -19,6 +19,18 @@
#include <curl/curl.h>
#include <curl/easy.h>
#define INSTANTDEX_DECKSIZE 2000
#define INSTANTDEX_HOPS 2
#define INSTANTDEX_DURATION 60
#define INSTANTDEX_INSURANCERATE (1. / 777.)
#define INSTANTDEX_PUBEY "03bc2c7ba671bae4a6fc835244c9762b41647b9827d4780a89a949b984a8ddcc06"
#define INSTANTDEX_RMD160 "ca1e04745e8ca0c60d8c5881531d51bec470743f"
#define TIERNOLAN_RMD160 "daedddd8dbe7a2439841ced40ba9c3d375f98146"
#define INSTANTDEX_BTC "1KRhTPvoxyJmVALwHFXZdeeWFbcJSbkFPu"
#define INSTANTDEX_BTCD "RThtXup6Zo7LZAi8kRWgjAyi1s4u6U9Cpf"
#define INSTANTDEX_MINPERC 50.
#define INSTANTDEX_OFFERDURATION 300
#define INSTANTDEX_LOCKTIME 3600
@ -90,19 +102,63 @@ struct exchange_request
struct exchange_quote bidasks[];
};
struct instantdex_offer { char base[24],rel[24]; uint64_t price64,basevolume64,offer64; uint32_t expiration,nonce; char myside,acceptdir; };
struct instantdex_offer
{
char base[24],rel[24];
uint64_t price64,basevolume64,offer64;
uint32_t expiration,nonce;
char myside,acceptdir,minperc,pad;
};
struct instantdex_accept
{
struct queueitem DL; void *info;
uint64_t pendingvolume64,otherorderid,orderid,matchid; uint32_t dead; int32_t didstate;
struct instantdex_offer otheroffer,offer;
struct queueitem DL;
uint64_t pendingvolume64,orderid;
uint32_t dead; int32_t didstate;
struct instantdex_offer offer;
};
struct bitcoin_statetx
{
bits256 txid;
uint64_t amount,change,inputsum;
double numconfirms;
char destaddr[64];
char txbytes[];
};
struct bitcoin_swapinfo
{
struct queueitem DL;
struct instantdex_accept mine,other;
bits256 privkeys[INSTANTDEX_DECKSIZE+2],mypubs[2],otherpubs[2],privAm,pubAm,privBn,pubBn;
bits256 myorderhash,otherorderhash,mypubkey,othertrader;
uint64_t otherdeck[INSTANTDEX_DECKSIZE][2],deck[INSTANTDEX_DECKSIZE][2];
uint64_t altsatoshis,BTCsatoshis,insurance,altpremium,matched64;
int32_t isinitiator,choosei,otherchoosei,cutverified,otherverifiedcut;
struct bitcoin_statetx *deposit,*payment,*altpayment,*myfee,*otherfee;
char expectedcmdstr[16],status[16];
struct instantdex_stateinfo *state; uint32_t expiration,dead,reftime;
};
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) (strcmp("BTC",swap->mine.offer.rel) == 0)
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);
cJSON *instantdex_acceptjson(struct instantdex_accept *ap);
cJSON *instantdex_statemachinejson(struct instantdex_accept *ap);
cJSON *instantdex_historyjson(struct instantdex_accept *ap);
struct instantdex_accept *instantdex_acceptable(struct supernet_info *myinfo,struct exchange_info *exchange,struct instantdex_accept *A,uint64_t offerbits,double minperc);
cJSON *instantdex_historyjson(struct bitcoin_swapinfo *swap);
struct bitcoin_swapinfo *instantdex_historyfind(struct supernet_info *myinfo,struct exchange_info *exchange,uint64_t orderid);
struct instantdex_accept *instantdex_acceptable(struct supernet_info *myinfo,struct exchange_info *exchange,struct instantdex_accept *A,double minperc);
void *curl_post(void **cHandlep,char *url,char *userpass,char *postfields,char *hdr0,char *hdr1,char *hdr2,char *hdr3);
char *exchanges777_Qprices(struct exchange_info *exchange,char *base,char *rel,int32_t maxseconds,int32_t allfields,int32_t depth,cJSON *argjson,int32_t monitor,double commission);
@ -119,12 +175,11 @@ double truefx_price(struct exchange_info *exchange,char *base,char *rel,struct e
double fxcm_price(struct exchange_info *exchange,char *base,char *rel,struct exchange_quote *bidasks,int32_t maxdepth,double commission,cJSON *argjson,int32_t invert);
double instaforex_price(struct exchange_info *exchange,char *base,char *rel,struct exchange_quote *bidasks,int32_t maxdepth,double commission,cJSON *argjson,int32_t invert);
char *instantdex_queueaccept(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 txid,int32_t queueflag);
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);
void instantdex_update(struct supernet_info *myinfo);
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);
char *instantdex_sendoffer(struct supernet_info *myinfo,struct exchange_info *exchange,struct instantdex_accept *ap,cJSON *argjson); // Bob sending to network (Alice)
char *instantdex_selectqueue(struct exchange_info *exchange,struct instantdex_accept *ap,char *retstr);
struct instantdex_accept *instantdex_historyfind(struct supernet_info *myinfo,struct exchange_info *exchange,uint64_t orderid);
struct instantdex_accept *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,int32_t requeueflag);
char *instantdex_checkoffer(struct supernet_info *myinfo,uint64_t *txidp,struct exchange_info *exchange,struct instantdex_accept *ap,cJSON *json);
#endif

533
iguana/iguana_instantdex.c

@ -17,40 +17,19 @@
#include "exchanges777.h"
#define INSTANTDEX_HOPS 2
#define INSTANTDEX_DURATION 60
#define INSTANTDEX_INSURANCERATE (1. / 777.)
#define INSTANTDEX_PUBEY "03bc2c7ba671bae4a6fc835244c9762b41647b9827d4780a89a949b984a8ddcc06"
#define INSTANTDEX_RMD160 "ca1e04745e8ca0c60d8c5881531d51bec470743f"
#define TIERNOLAN_RMD160 "daedddd8dbe7a2439841ced40ba9c3d375f98146"
#define INSTANTDEX_BTC "1KRhTPvoxyJmVALwHFXZdeeWFbcJSbkFPu"
#define INSTANTDEX_BTCD "RThtXup6Zo7LZAi8kRWgjAyi1s4u6U9Cpf"
#define INSTANTDEX_MINPERC 50.
#define INSTANTDEX_DECKSIZE 1000
struct instantdex_event { char cmdstr[24],sendcmd[16]; int16_t nextstateind; };
struct instantdex_stateinfo *BTC_states; int32_t BTC_numstates;
struct instantdex_stateinfo
int64_t instantdex_BTCsatoshis(int64_t price,int64_t volume)
{
char name[24]; int16_t ind,initialstate;
cJSON *(*process)(struct supernet_info *myinfo,struct exchange_info *exchange,struct instantdex_accept *A,cJSON *argjson,cJSON *newjson,uint8_t **serdatap,int32_t *serdatalenp);
cJSON *(*timeout)(struct supernet_info *myinfo,struct exchange_info *exchange,struct instantdex_accept *A,cJSON *argjson,cJSON *newjson,uint8_t **serdatap,int32_t *serdatalenp);
int16_t timeoutind,errorind;
struct instantdex_event *events; int32_t numevents;
};
if ( volume > price )
return(price * dstr(volume));
else return(dstr(price) * volume);
}
struct bitcoin_swapinfo
int64_t instantdex_insurance(struct iguana_info *coin,int64_t amount)
{
bits256 privkeys[INSTANTDEX_DECKSIZE+2],mypubs[2],otherpubs[2],privAm,pubAm,privBn,pubBn;
bits256 orderhash,deposittxid,paymenttxid,altpaymenttxid,myfeetxid,otherfeetxid,othertrader;
uint64_t otherscut[INSTANTDEX_DECKSIZE][2],deck[INSTANTDEX_DECKSIZE][2],satoshis[2],insurance,bidid,askid,feetag64;
int32_t isbob,choosei,otherschoosei,cutverified,otherverifiedcut;
char altmsigaddr[64],expectedcmdstr[16],*deposit,*payment,*altpayment,*myfeetx,*otherfeetx;
double minperc,depositconfirms,paymentconfirms,altpaymentconfirms,myfeeconfirms,otherfeeconfirms;
struct instantdex_stateinfo *state; uint32_t expiration;
};
struct instantdex_stateinfo *BTC_states; int32_t BTC_numstates;
return(amount * INSTANTDEX_INSURANCERATE + coin->chain->txfee); // insurance prevents attack
}
void instantdex_swapfree(struct instantdex_accept *A,struct bitcoin_swapinfo *swap)
{
@ -64,14 +43,14 @@ void instantdex_swapfree(struct instantdex_accept *A,struct bitcoin_swapinfo *sw
free(swap->payment);
if ( swap->altpayment != 0 )
free(swap->altpayment);
if ( swap->myfeetx != 0 )
free(swap->myfeetx);
if ( swap->otherfeetx != 0 )
free(swap->otherfeetx);
if ( swap->myfee != 0 )
free(swap->myfee);
if ( swap->otherfee != 0 )
free(swap->otherfee);
}
}
cJSON *instantdex_defaultprocess(struct supernet_info *myinfo,struct exchange_info *exchange,struct instantdex_accept *A,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;
*serdatap = 0, *serdatalenp = 0;
@ -82,7 +61,7 @@ cJSON *instantdex_defaultprocess(struct supernet_info *myinfo,struct exchange_in
return(newjson);
}
//({"agent":"iguana","method":"addcoin","newcoin":"PPC","active":1,"maxpeers":128,"services":0,"poll":1,"RAM":4,"minoutput":100000,"minconfirms":3,"estblocktime":600,"path":"/data/ppcoin","conf":"/data/.ppcoin","txfee_satoshis":100000,"useaddmultisig":1,"hastimestamp":0,"userhome":"/data/SuperNET/iguana","pubval":"37","scriptval":"75","wiftype":"b7","netmagic":"e6e8e9e5","genesishash":"00000ffd590b1485b3caadc19b22e6379c733355108f107a430458cdf3407ab6","genesis":{"hashalgo":"sha256","version":1,"timestamp":1345084287,"nbits":"1d00ffff","nonce":2179302059,"merkleroot":"3c2d8f85fab4d17aac558cc648a1a58acff0de6deb890c29985690052c5993c2"},"p2p":9901,"rpc":9902})
cJSON *instantdex_defaulttimeout(struct supernet_info *myinfo,struct exchange_info *exchange,struct instantdex_accept *A,cJSON *argjson,cJSON *newjson,uint8_t **serdatap,int32_t *serdatalenp)
cJSON *instantdex_defaulttimeout(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;
*serdatap = 0, *serdatalenp = 0;
@ -128,7 +107,7 @@ void instantdex_stateinit(struct instantdex_stateinfo *states,int32_t numstates,
state->timeout = instantdex_defaulttimeout;
}
struct instantdex_stateinfo *instantdex_statecreate(struct instantdex_stateinfo *states,int32_t *numstatesp,char *name,cJSON *(*process_func)(struct supernet_info *myinfo,struct exchange_info *exchange,struct instantdex_accept *A,cJSON *argjson,cJSON *newjson,uint8_t **serdatap,int32_t *serdatalenp),cJSON *(*timeout_func)(struct supernet_info *myinfo,struct exchange_info *exchange,struct instantdex_accept *A,cJSON *argjson,cJSON *newjson,uint8_t **serdatap,int32_t *serdatalenp),char *timeoutstr,char *errorstr,int32_t initialstate)
struct instantdex_stateinfo *instantdex_statecreate(struct instantdex_stateinfo *states,int32_t *numstatesp,char *name,cJSON *(*process_func)(struct supernet_info *myinfo,struct exchange_info *exchange,struct bitcoin_swapinfo *swap,cJSON *argjson,cJSON *newjson,uint8_t **serdatap,int32_t *serdatalenp),cJSON *(*timeout_func)(struct supernet_info *myinfo,struct exchange_info *exchange,struct bitcoin_swapinfo *swap,cJSON *argjson,cJSON *newjson,uint8_t **serdatap,int32_t *serdatalenp),char *timeoutstr,char *errorstr,int32_t initialstate)
{
struct instantdex_stateinfo S,*state = 0;
if ( (state= instantdex_statefind(states,*numstatesp,name)) == 0 )
@ -524,6 +503,7 @@ cJSON *instantdex_offerjson(struct instantdex_offer *offer,uint64_t orderid)
jaddnum(item,"timestamp",offer->expiration);
jaddnum(item,"price",dstr(offer->price64));
jaddnum(item,"volume",dstr(offer->basevolume64));
jaddnum(item,"minperc",offer->minperc);
jaddnum(item,"nonce",offer->nonce);
jaddnum(item,"expiresin",offer->expiration - time(NULL));
return(item);
@ -537,28 +517,59 @@ cJSON *instantdex_acceptjson(struct instantdex_accept *ap)
if ( ap->dead != 0 )
jadd64bits(item,"dead",ap->dead);
jadd(item,"offer",instantdex_offerjson(&ap->offer,ap->orderid));
if ( ap->otherorderid != 0 )
return(item);
}
void instantdex_statetxjson(cJSON *array,char *name,struct bitcoin_statetx *tx)
{
cJSON *item;
if ( tx != 0 )
{
jadd64bits(item,"otherid",ap->otherorderid);
jadd(item,"otheroffer",instantdex_offerjson(&ap->otheroffer,ap->otherorderid));
item = cJSON_CreateObject();
jaddbits256(item,"txid",tx->txid);
jaddnum(item,"inputsum",dstr(tx->inputsum));
jaddnum(item,"amount",dstr(tx->amount));
jaddnum(item,"change",dstr(tx->change));
jaddnum(item,"txfee",dstr(tx->inputsum) - dstr(tx->amount) - dstr(tx->change));
jaddnum(item,"confirms",dstr(tx->numconfirms));
jaddstr(item,"destaddr",tx->destaddr);
jaddstr(item,"txbytes",tx->txbytes);
jadd(array,name,item);
}
return(item);
}
cJSON *instantdex_statemachinejson(struct instantdex_accept *ap)
cJSON *instantdex_statemachinejson(struct bitcoin_swapinfo *swap)
{
struct bitcoin_swapinfo *swap = ap->info; cJSON *confirms,*retjson,*txs;
cJSON *retjson,*txs; int32_t isbob,mydir,otherdir;
retjson = cJSON_CreateObject();
if ( swap != 0 )
{
jaddnum(retjson,"isbob",swap->isbob);
mydir = instantdex_bidaskdir(&swap->mine.offer);
otherdir = instantdex_bidaskdir(&swap->other.offer);
isbob = instantdex_isbob(swap);
jaddnum(retjson,"isbob",isbob);
jaddnum(retjson,"mydir",mydir);
jaddnum(retjson,"otherdir",otherdir);
jaddnum(retjson,"expiration",swap->expiration);
jaddnum(retjson,"insurance",dstr(swap->insurance));
jaddnum(retjson,"baseamount",dstr(swap->altsatoshis));
jaddnum(retjson,"BTCamount",dstr(swap->BTCsatoshis));
jaddnum(retjson,"expiration",swap->expiration);
if ( swap->dead != 0 )
jadd64bits(retjson,"dead",swap->dead);
jaddbits256(retjson,"privAm",swap->privAm);
jaddbits256(retjson,"pubAm",swap->pubAm);
jaddbits256(retjson,"privBn",swap->privBn);
jaddbits256(retjson,"pubBn",swap->pubBn);
jaddbits256(retjson,"myorderhash",swap->myorderhash);
jaddnum(retjson,"choosei",swap->choosei);
jaddnum(retjson,"cutverified",swap->cutverified);
jaddbits256(retjson,"othertrader",swap->othertrader);
jaddbits256(retjson,"orderhash",swap->orderhash);
if ( swap->isbob == 0 )
jaddbits256(retjson,"otherorderhash",swap->otherorderhash);
jaddnum(retjson,"otherchoosei",swap->otherchoosei);
jaddnum(retjson,"otherverifiedcut",swap->otherverifiedcut);
if ( isbob == 0 )
{
jaddbits256(retjson,"pubA0",swap->mypubs[0]);
jaddbits256(retjson,"pubA1",swap->mypubs[1]);
@ -572,97 +583,92 @@ cJSON *instantdex_statemachinejson(struct instantdex_accept *ap)
jaddbits256(retjson,"pubA0",swap->otherpubs[0]);
jaddbits256(retjson,"pubA1",swap->otherpubs[1]);
}
jaddnum(retjson,"choosei",swap->choosei);
jaddnum(retjson,"otherschoosei",swap->otherschoosei);
jaddnum(retjson,"otherschoosei",swap->otherschoosei);
jaddnum(retjson,"cutverified",swap->cutverified);
jaddnum(retjson,"otherverifiedcut",swap->otherverifiedcut);
jaddnum(retjson,"expiration",swap->expiration);
jaddnum(retjson,"minperc",swap->minperc * 100.);
jaddnum(retjson,"insurance",dstr(swap->insurance));
jaddnum(retjson,"baseamount",dstr(swap->satoshis[0]));
jaddnum(retjson,"BTCamount",dstr(swap->satoshis[1]));
jadd64bits(retjson,"bidid",swap->bidid);
jadd64bits(retjson,"askid",swap->askid);
jaddstr(retjson,"altmsigaddr",swap->altmsigaddr);
if ( mydir > 0 && otherdir < 0 )
{
jadd64bits(retjson,"bidid",swap->mine.orderid);
jadd64bits(retjson,"askid",swap->other.orderid);
}
else if ( mydir < 0 && otherdir > 0 )
{
jadd64bits(retjson,"askid",swap->mine.orderid);
jadd64bits(retjson,"bidid",swap->other.orderid);
}
if ( swap->matched64 == swap->mine.orderid )
{
jadd(retjson,"initiator",instantdex_acceptjson(&swap->other));
jadd(retjson,"matched",instantdex_acceptjson(&swap->mine));
}
else if ( swap->matched64 == swap->other.orderid )
{
jadd(retjson,"initiator",instantdex_acceptjson(&swap->mine));
jadd(retjson,"matched",instantdex_acceptjson(&swap->other));
}
else jaddstr(retjson,"initiator","illegal initiator missing");
if ( swap->state != 0 )
jaddstr(retjson,"state",swap->state->name);
jaddstr(retjson,"expected",swap->expectedcmdstr);
confirms = cJSON_CreateObject();
jaddnum(confirms,"deposit",swap->depositconfirms);
jaddnum(confirms,"payment",swap->paymentconfirms);
jaddnum(confirms,"altpayment",swap->altpaymentconfirms);
jaddnum(confirms,"myfee",swap->myfeeconfirms);
jaddnum(confirms,"otherfee",swap->otherfeeconfirms);
jadd(retjson,"confirms",confirms);
txs = cJSON_CreateObject();
if ( swap->deposit != 0 )
jaddstr(txs,"deposit",swap->deposit), jaddbits256(txs,"deposittxid",swap->deposittxid);
if ( swap->payment != 0 )
jaddstr(txs,"payment",swap->payment), jaddbits256(txs,"paymenttxid",swap->paymenttxid);
if ( swap->altpayment != 0 )
jaddstr(txs,"altpayment",swap->altpayment), jaddbits256(txs,"altpaymenttxid",swap->altpaymenttxid);
if ( swap->myfeetx != 0 )
jaddstr(txs,"myfee",swap->myfeetx), jaddbits256(txs,"myfeetxid",swap->myfeetxid);;
if ( swap->otherfeetx != 0 )
jaddstr(txs,"otherfee",swap->otherfeetx), jaddbits256(txs,"otherfeetxid",swap->otherfeetxid);
jadd(retjson,"txs",confirms);
jaddbits256(retjson,"othertrader",swap->othertrader);
instantdex_statetxjson(txs,"deposit",swap->deposit);
instantdex_statetxjson(txs,"payment",swap->payment);
instantdex_statetxjson(txs,"altpayment",swap->altpayment);
instantdex_statetxjson(txs,"myfee",swap->myfee);
instantdex_statetxjson(txs,"otherfee",swap->otherfee);
jadd(retjson,"txs",txs);
jaddstr(retjson,"status",swap->status);
}
jadd(retjson,"swap",instantdex_acceptjson(ap));
return(retjson);
}
cJSON *instantdex_historyjson(struct instantdex_accept *ap)
cJSON *instantdex_historyjson(struct bitcoin_swapinfo *swap)
{
// need to make sure accepts are put onto history queue when they are completed or deaded
// also to make permanent copy (somewhere)
return(instantdex_acceptjson(ap));
return(instantdex_statemachinejson(swap));
}
struct instantdex_accept *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 instantdex_accept PAD,*ap,*retap = 0; uint32_t now;
struct bitcoin_swapinfo PAD,*swap,*retswap = 0; uint32_t now;
now = (uint32_t)time(NULL);
memset(&PAD,0,sizeof(PAD));
queue_enqueue("historyQ",&exchange->historyQ,&PAD.DL,0);
while ( (ap= queue_dequeue(&exchange->historyQ,0)) != 0 && ap != &PAD )
while ( (swap= queue_dequeue(&exchange->historyQ,0)) != 0 && swap != &PAD )
{
if ( orderid == ap->orderid )
retap = ap;
queue_enqueue("historyQ",&exchange->historyQ,&ap->DL,0);
if ( orderid == swap->mine.orderid )
retswap = swap;
queue_enqueue("historyQ",&exchange->historyQ,&swap->DL,0);
}
return(retap);
return(retswap);
}
struct instantdex_accept *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,int32_t requeueflag)
{
struct instantdex_accept PAD,*ap,*retap = 0; uint32_t now;
struct bitcoin_swapinfo PAD,*swap,*retswap = 0; uint32_t now;
now = (uint32_t)time(NULL);
memset(&PAD,0,sizeof(PAD));
queue_enqueue("statemachineQ",&exchange->statemachineQ,&PAD.DL,0);
while ( (ap= queue_dequeue(&exchange->statemachineQ,0)) != 0 && ap != &PAD )
while ( (swap= queue_dequeue(&exchange->statemachineQ,0)) != 0 && swap != &PAD )
{
if ( now < ap->offer.expiration && ap->dead == 0 )
if ( now < swap->expiration && swap->mine.dead == 0 && swap->other.dead == 0 )
{
if ( orderid == ap->orderid )
if ( orderid == swap->mine.orderid )
{
if ( retap != 0 && requeueflag == 0 )
queue_enqueue("statemachineQ",&exchange->statemachineQ,&retap->DL,0);
retap = ap;
if ( retswap != 0 && requeueflag == 0 )
queue_enqueue("statemachineQ",&exchange->statemachineQ,&retswap->DL,0);
retswap = swap;
}
}
else
{
strcpy(swap->status,"expired");
printf("expired pending, need to take action, send timeout event\n");
free(ap);
queue_enqueue("historyQ",&exchange->historyQ,&swap->DL,0);
//bitcoin_freeswap(swap);
continue;
}
if ( ap != retap || requeueflag != 0 )
queue_enqueue("statemachineQ",&exchange->statemachineQ,&ap->DL,0);
if ( swap != retswap || requeueflag != 0 )
queue_enqueue("statemachineQ",&exchange->statemachineQ,&swap->DL,0);
}
return(retap);
return(retswap);
}
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)
@ -704,7 +710,7 @@ struct instantdex_accept *instantdex_offerfind(struct supernet_info *myinfo,stru
return(retap);
}
struct instantdex_accept *instantdex_acceptable(struct supernet_info *myinfo,struct exchange_info *exchange,struct instantdex_accept *A,uint64_t offerbits,double minperc)
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;
@ -716,9 +722,10 @@ struct instantdex_accept *instantdex_acceptable(struct supernet_info *myinfo,str
minvol = A->offer.basevolume64 * minperc * .01;
while ( (ap= queue_dequeue(&exchange->acceptableQ,0)) != 0 && ap != &PAD )
{
printf("check offerbits.%llu vs %llu: %d %d %d %d %d %d %d %d\n",(long long)offerbits,(long long)ap->offer.offer64,A->offer.basevolume64 > 0.,strcmp(A->offer.base,"*") == 0 ,strcmp(A->offer.base,ap->offer.base) == 0, strcmp(A->offer.rel,"*") == 0 ,strcmp(A->offer.rel,ap->offer.rel) == 0,A->offer.basevolume64 <= (ap->offer.basevolume64 - ap->pendingvolume64),offerdir,instantdex_bidaskdir(&ap->offer));
if ( now < ap->offer.expiration && ap->dead == 0 && (offerbits == 0 || offerbits != ap->offer.offer64) )
printf("check offerbits.%llu vs %llu: %d %d %d %d %d %d %d %d\n",(long long)myinfo->myaddr.nxt64bits,(long long)ap->offer.offer64,A->offer.basevolume64 > 0.,strcmp(A->offer.base,"*") == 0 ,strcmp(A->offer.base,ap->offer.base) == 0, strcmp(A->offer.rel,"*") == 0 ,strcmp(A->offer.rel,ap->offer.rel) == 0,A->offer.basevolume64 <= (ap->offer.basevolume64 - ap->pendingvolume64),offerdir,instantdex_bidaskdir(&ap->offer));
if ( now < ap->offer.expiration && ap->dead == 0 && myinfo->myaddr.nxt64bits != ap->offer.offer64 )
{
printf("aveprice %.8f %.8f offerdir.%d first cmp: %d %d %d\n",aveprice,dstr(ap->offer.price64),offerdir,A->offer.price64 == 0,(offerdir > 0 && ap->offer.price64 >= A->offer.price64),(offerdir < 0 && ap->offer.price64 <= A->offer.price64));
if ( A->offer.basevolume64 > 0. && (strcmp(A->offer.base,"*") == 0 || strcmp(A->offer.base,ap->offer.base) == 0) && (strcmp(A->offer.rel,"*") == 0 || strcmp(A->offer.rel,ap->offer.rel) == 0) && minvol <= (ap->offer.basevolume64 - ap->pendingvolume64) && offerdir*instantdex_bidaskdir(&ap->offer) < 0 )
{
printf("aveprice %.8f %.8f offerdir.%d first cmp: %d %d %d\n",aveprice,dstr(ap->offer.price64),offerdir,A->offer.price64 == 0,(offerdir > 0 && ap->offer.price64 >= A->offer.price64),(offerdir < 0 && ap->offer.price64 <= A->offer.price64));
@ -754,7 +761,7 @@ struct instantdex_accept *instantdex_acceptable(struct supernet_info *myinfo,str
// NXT node verifies bitcoin txbytes has proper payment and cashes in with onetimepubkey
// BTC* node approves phased tx with onetimepubkey
bits256 instantdex_acceptset(struct instantdex_accept *ap,char *base,char *rel,int32_t duration,int32_t myside,int32_t acceptdir,double price,double volume,uint64_t offerbits,uint32_t nonce)
bits256 instantdex_acceptset(struct instantdex_accept *ap,char *base,char *rel,int32_t duration,int32_t myside,int32_t acceptdir,double price,double volume,uint64_t offerbits,uint32_t nonce,uint8_t minperc)
{
bits256 hash;
memset(ap,0,sizeof(*ap));
@ -769,6 +776,7 @@ bits256 instantdex_acceptset(struct instantdex_accept *ap,char *base,char *rel,i
ap->offer.offer64 = offerbits;
ap->offer.myside = myside;
ap->offer.acceptdir = acceptdir;
ap->offer.minperc = minperc;
ap->offer.price64 = price * SATOSHIDEN;
ap->offer.basevolume64 = volume * SATOSHIDEN;
vcalc_sha256(0,hash.bytes,(void *)&ap->offer,sizeof(ap->offer));
@ -782,11 +790,15 @@ bits256 instantdex_acceptset(struct instantdex_accept *ap,char *base,char *rel,i
int32_t instantdex_acceptextract(struct instantdex_accept *ap,cJSON *argjson)
{
char *base,*rel; bits256 hash,traderpub; double price,volume; int32_t baserel,acceptdir;
char *base,*rel; bits256 hash,traderpub; double price,volume; int32_t baserel,acceptdir,minperc;
memset(ap,0,sizeof(*ap));
if ( (base= jstr(argjson,"base")) != 0 )
{
volume = jdouble(argjson,"volume");
if ( (minperc= juint(argjson,"minperc")) < INSTANTDEX_MINPERC )
minperc = INSTANTDEX_MINPERC;
else if ( minperc > 100 )
minperc = 100;
if ( (rel= jstr(argjson,"rel")) != 0 )
safecopy(ap->offer.rel,rel,sizeof(ap->offer.rel));
if ( (price= jdouble(argjson,"maxprice")) > SMALLVAL )
@ -801,7 +813,7 @@ int32_t instantdex_acceptextract(struct instantdex_accept *ap,cJSON *argjson)
} else return(-1);
//printf("price %f vol %f baserel.%d acceptdir.%d\n",price,volume,baserel,acceptdir);
traderpub = jbits256(argjson,"traderpub");
hash = instantdex_acceptset(ap,base,rel,INSTANTDEX_LOCKTIME*2,baserel,acceptdir,price,volume,traderpub.txid,0);
hash = instantdex_acceptset(ap,base,rel,INSTANTDEX_LOCKTIME*2,baserel,acceptdir,price,volume,traderpub.txid,0,minperc);
}
else
{
@ -816,6 +828,8 @@ int32_t instantdex_acceptextract(struct instantdex_accept *ap,cJSON *argjson)
ap->offer.offer64 = j64bits(argjson,"o");
ap->offer.price64 = j64bits(argjson,"p");
ap->offer.basevolume64 = j64bits(argjson,"v");
if ( (ap->offer.minperc= juint(argjson,"m")) < INSTANTDEX_MINPERC )
ap->offer.minperc = INSTANTDEX_MINPERC;
vcalc_sha256(0,hash.bytes,(void *)&ap->offer,sizeof(ap->offer));
ap->orderid = j64bits(argjson,"id");
}
@ -835,188 +849,113 @@ int32_t instantdex_acceptextract(struct instantdex_accept *ap,cJSON *argjson)
#include "swaps/iguana_NXTswap.c"
#include "swaps/iguana_PAXswap.c"
char *instantdex_swapset(struct supernet_info *myinfo,struct instantdex_accept *ap,cJSON *argjson)
struct bitcoin_swapinfo *bitcoin_swapinit(struct supernet_info *myinfo,struct exchange_info *exchange,struct instantdex_accept *myap,struct instantdex_accept *otherap,int32_t aminitiator,cJSON *argjson)
{
uint64_t satoshis[2]; int32_t offerdir = 0; double minperc; uint64_t insurance,relsatoshis;
struct bitcoin_swapinfo *swap; bits256 orderhash,traderpub; struct iguana_info *coinbtc;
if ( (swap= ap->info) == 0 )
return(clonestr("{\"error\":\"no swapinfo set\"}"));
relsatoshis = instantdex_BTCsatoshis(ap->offer.price64,ap->offer.basevolume64);
traderpub = jbits256(argjson,"traderpub");
if ( (minperc= jdouble(argjson,"p")) < INSTANTDEX_MINPERC )
minperc = INSTANTDEX_MINPERC;
if ( (coinbtc= iguana_coinfind("BTC")) == 0 )
return(clonestr("{\"error\":\"no BTC found\"}"));
insurance = (satoshis[1] * INSTANTDEX_INSURANCERATE + coinbtc->chain->txfee); // txfee prevents papercut attack
offerdir = instantdex_bidaskdir(&ap->offer);
vcalc_sha256(0,orderhash.bytes,(void *)&ap->offer,sizeof(ap->offer));
if ( 0 )
{
int32_t i;
for (i=0; i<sizeof(ap->offer); i++)
printf("%02x ",((uint8_t *)&ap->offer)[i]);
printf("swapset.%llu\n",(long long)ap->orderid);
}
if ( offerdir > 0 )
struct bitcoin_swapinfo *swap = 0; struct iguana_info *coinbtc,*altcoin;
swap = calloc(1,sizeof(struct bitcoin_swapinfo));
swap->mine = *myap, swap->other = *otherap;
if ( (swap->isinitiator= aminitiator) != 0 )
{
swap->bidid = ap->orderid;
swap->askid = ap->otherorderid;
swap->matched64 = otherap->orderid;
swap->expiration = otherap->offer.expiration;
}
else
{
swap->askid = ap->orderid;
swap->bidid = ap->otherorderid;
swap->matched64 = myap->orderid;
swap->expiration = myap->offer.expiration;
}
if ( bits256_nonz(swap->othertrader) == 0 )
swap->othertrader = traderpub;
else if ( bits256_cmp(traderpub,swap->othertrader) != 0 )
swap->choosei = swap->otherchoosei = -1;
strcpy(swap->status,"pending");
vcalc_sha256(0,swap->myorderhash.bytes,(void *)&swap->mine.offer,sizeof(swap->mine.offer));
vcalc_sha256(0,swap->otherorderhash.bytes,(void *)&swap->other.offer,sizeof(swap->other.offer));
swap->mypubkey = myinfo->myaddr.persistent;
swap->othertrader = jbits256(argjson,"traderpub");
swap->altsatoshis = myap->offer.basevolume64;
swap->BTCsatoshis = instantdex_BTCsatoshis(myap->offer.price64,myap->offer.basevolume64);
if ( (coinbtc= iguana_coinfind("BTC")) == 0 || (altcoin= iguana_coinfind(swap->mine.offer.base)) == 0 )
{
printf("competing offer received for (%s/%s) %.8f %.8f\n",ap->offer.base,ap->offer.rel,dstr(ap->offer.price64),dstr(ap->offer.basevolume64));
return(clonestr("{\"error\":\"no competing offers for now\"}"));
printf("cant find BTC or %s\n",swap->mine.offer.base);
return(0);
}
if ( bits256_nonz(swap->orderhash) == 0 )
swap->orderhash = orderhash;
else if ( bits256_cmp(orderhash,swap->orderhash) != 0 )
swap->insurance = (swap->BTCsatoshis * INSTANTDEX_INSURANCERATE + coinbtc->chain->txfee);
swap->altpremium = (swap->altsatoshis * INSTANTDEX_INSURANCERATE + altcoin->chain->txfee);
if ( myap->offer.myside != instantdex_isbob(swap) || otherap->offer.myside == instantdex_isbob(swap) )
{
printf("orderhash %llx mismatch %llx\n",(long long)swap->orderhash.txid,(long long)orderhash.txid);
return(clonestr("{\"error\":\"orderhash mismatch???\"}"));
printf("isbob error.(%d %d) %d\n",myap->offer.myside,otherap->offer.myside,instantdex_isbob(swap));
return(0);
}
swap->satoshis[0] = ap->offer.basevolume64;
swap->satoshis[1] = relsatoshis;
swap->insurance = (relsatoshis * INSTANTDEX_INSURANCERATE + coinbtc->chain->txfee); // txfee
if ( swap->minperc < minperc )
swap->minperc = minperc;
return(0);
return(swap);
}
char *instantdex_addfeetx(struct supernet_info *myinfo,cJSON *newjson,struct instantdex_accept *ap,struct bitcoin_swapinfo *swap,char *bobstate,char *alicestate)
char *instantdex_checkoffer(struct supernet_info *myinfo,uint64_t *txidp,struct exchange_info *exchange,struct instantdex_accept *myap,cJSON *argjson)
{
if ( (swap->myfeetx= instantdex_feetx(myinfo,&swap->myfeetxid,ap)) != 0 )
char *retstr = 0; struct instantdex_accept *otherap; struct bitcoin_swapinfo *swap; cJSON *newjson;
*txidp = myap->orderid;
if ( (otherap= instantdex_acceptable(myinfo,exchange,myap,myap->offer.minperc)) == 0 )
{
jaddstr(newjson,"feetx",swap->myfeetx);
jaddbits256(newjson,"feetxid",swap->myfeetxid);
swap->state = instantdex_statefind(BTC_states,BTC_numstates,swap->isbob != 0 ? bobstate : alicestate);
return(0);
printf("add.%llu to acceptableQ\n",(long long)myap->orderid);
if ( (retstr= instantdex_sendcmd(myinfo,&myap->offer,argjson,"BTCoffer",GENESIS_PUBKEY,INSTANTDEX_HOPS,0,0)) != 0 )
free(retstr);
queue_enqueue("acceptableQ",&exchange->acceptableQ,&myap->DL,0);
return(jprint(instantdex_offerjson(&myap->offer,myap->orderid),1));
}
return(clonestr("{\"error\":\"couldnt create feetx\"}"));
}
char *instantdex_sendoffer(struct supernet_info *myinfo,struct exchange_info *exchange,struct instantdex_accept *ap,cJSON *argjson) // Bob sending to network (Alice)
{
struct iguana_info *other; struct bitcoin_swapinfo *swap; int32_t isbob; cJSON *newjson; char *retstr;
if ( strcmp(ap->offer.rel,"BTC") != 0 )
return(clonestr("{\"error\":\"invalid othercoin\"}"));
else if ( (other= iguana_coinfind(ap->offer.base)) == 0 )
return(clonestr("{\"error\":\"invalid othercoin\"}"));
else if ( ap->offer.price64 <= 0 || ap->offer.basevolume64 <= 0 )
return(clonestr("{\"error\":\"illegal price or volume\"}"));
isbob = (ap->offer.myside == 1);
swap = calloc(1,sizeof(struct bitcoin_swapinfo));
swap->isbob = isbob;
swap->expiration = ap->offer.expiration;//(uint32_t)(time(NULL) + INSTANTDEX_LOCKTIME*isbob);
swap->choosei = swap->otherschoosei = -1;
swap->depositconfirms = swap->paymentconfirms = swap->altpaymentconfirms = swap->myfeeconfirms = swap->otherfeeconfirms = -1;
ap->info = swap;
printf("sendoffer SETSWAP for orderid.%llu ap.%p (%p)\n",(long long)ap->orderid,ap,swap);
if ( (retstr= instantdex_swapset(myinfo,ap,argjson)) != 0 )
return(retstr);
ap->orderid = swap->orderhash.txid;
if ( (newjson= instantdex_parseargjson(myinfo,exchange,ap,argjson,1)) == 0 )
return(clonestr("{\"error\":\"instantdex_BTCswap offer null newjson\"}"));
else
{
//instantdex_bobtx(myinfo,iguana_coinfind("BTCD"),&swap->deposittxid,swap->otherpubs[0],swap->mypubs[0],swap->privkeys[swap->choosei],ap->offer.expiration-INSTANTDEX_LOCKTIME*2,swap->satoshis[1],1);
//instantdex_alicetx(myinfo,iguana_coinfind("BTCD"),swap->altmsigaddr,&swap->altpaymenttxid,swap->pubAm,swap->pubBn,swap->satoshis[0]);
if ( 0 )
{
int32_t i;
for (i=0; i<sizeof(ap->offer); i++)
printf("%02x ",((uint8_t *)&ap->offer)[i]);
printf("BTCoffer.%llu\n",(long long)ap->orderid);
}
return(instantdex_sendcmd(myinfo,&ap->offer,newjson,"BTCoffer",GENESIS_PUBKEY,INSTANTDEX_HOPS,swap->deck,sizeof(swap->deck)));
swap = bitcoin_swapinit(myinfo,exchange,myap,otherap,1,argjson);
queue_enqueue("statemachineQ",&exchange->statemachineQ,&swap->DL,0);
if ( (newjson= instantdex_parseargjson(myinfo,exchange,swap,argjson,1)) == 0 )
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)));
}
return(retstr);
}
char *instantdex_gotoffer(struct supernet_info *myinfo,struct exchange_info *exchange,struct instantdex_accept *ap,struct instantdex_msghdr *msg,cJSON *argjson,char *remoteaddr,uint64_t signerbits,uint8_t *serdata,int32_t serdatalen) // receiving side
char *instantdex_gotoffer(struct supernet_info *myinfo,struct exchange_info *exchange,struct instantdex_accept *myap,struct instantdex_accept *otherap,struct instantdex_msghdr *msg,cJSON *argjson,char *remoteaddr,uint64_t signerbits,uint8_t *serdata,int32_t serdatalen) // receiving side
{
struct bitcoin_swapinfo *swap = 0; bits256 traderpub; struct iguana_info *coinbtc,*altcoin; cJSON *newjson=0; char *retstr=0;
swap = ap->info;
coinbtc = iguana_coinfind("BTC");
traderpub = jbits256(argjson,"traderpub");
if ( bits256_cmp(traderpub,myinfo->myaddr.persistent) == 0 )
{
printf("got my own gotoffer packet orderid.%llu\n",(long long)ap->orderid);
printf("got my own gotoffer packet orderid.%llu/%llu\n",(long long)myap->orderid,(long long)otherap->orderid);
return(clonestr("{\"result\":\"got my own packet\"}"));
}
if ( 0 )
{
int32_t i;
for (i=0; i<sizeof(ap->offer); i++)
printf("%02x ",((uint8_t *)&ap->offer)[i]);
printf("BTCoffer.%llu\n",(long long)ap->orderid);
for (i=0; i<sizeof(otherap->offer); i++)
printf("%02x ",((uint8_t *)&otherap->offer)[i]);
printf("gotoffer.%llu\n",(long long)otherap->orderid);
}
printf("T.%d got (%s/%s) %.8f vol %.8f %llu offerside.%d offerdir.%d swap.%p decksize.%ld/datalen.%d\n",bits256_cmp(traderpub,myinfo->myaddr.persistent),ap->offer.base,ap->offer.rel,dstr(ap->offer.price64),dstr(ap->offer.basevolume64),(long long)ap->orderid,ap->offer.myside,ap->offer.acceptdir,ap->info,sizeof(swap->deck),serdatalen);
//char str[65]; printf("GOT OFFER! orderid.%llu %p (%s/%s) other.%s myside.%d\n",(long long)ap->orderid,ap->info,ap->offer.base,ap->offer.rel,bits256_str(str,traderpub),swap->isbob);*/
printf("T.%d got (%s/%s) %.8f vol %.8f %llu offerside.%d offerdir.%d decksize.%ld/datalen.%d\n",bits256_cmp(traderpub,myinfo->myaddr.persistent),myap->offer.base,myap->offer.rel,dstr(myap->offer.price64),dstr(myap->offer.basevolume64),(long long)myap->orderid,myap->offer.myside,myap->offer.acceptdir,sizeof(swap->deck),serdatalen);
if ( exchange == 0 )
return(clonestr("{\"error\":\"instantdex_BTCswap null exchange ptr\"}"));
if ( (altcoin= iguana_coinfind(ap->offer.base)) == 0 || coinbtc == 0 )
if ( (altcoin= iguana_coinfind(myap->offer.base)) == 0 || coinbtc == 0 )
return(clonestr("{\"error\":\"instantdex_BTCswap cant find btc or other coin info\"}"));
if ( strcmp(ap->offer.rel,"BTC") != 0 )
if ( strcmp(myap->offer.rel,"BTC") != 0 )
return(clonestr("{\"error\":\"instantdex_BTCswap offer non BTC rel\"}"));
if ( ap->offer.expiration < (time(NULL) + INSTANTDEX_DURATION) )
if ( myap->offer.expiration < (time(NULL) + INSTANTDEX_DURATION) || otherap->offer.expiration < (time(NULL) + INSTANTDEX_DURATION) )
return(clonestr("{\"error\":\"instantdex_BTCswap offer too close to expiration\"}"));
if ( ap->info == 0 )
ap->info = swap = calloc(1,sizeof(struct bitcoin_swapinfo));
//printf("gotoffer SETSWAP for orderid.%llu (%s)\n",(long long)ap->orderid,jprint(argjson,0));
swap->choosei = swap->otherschoosei = -1;
swap->depositconfirms = swap->paymentconfirms = swap->altpaymentconfirms = swap->myfeeconfirms = swap->otherfeeconfirms = -1;
swap->isbob = (ap->offer.myside ^ 1);
if ( (retstr= instantdex_swapset(myinfo,ap,argjson)) != 0 )
return(retstr);
swap->feetag64 = ap->orderid;
if ( instantdex_pubkeyargs(swap,newjson,2+INSTANTDEX_DECKSIZE,myinfo->persistent_priv,swap->orderhash,0x02 + swap->isbob) != 2+INSTANTDEX_DECKSIZE )
return(clonestr("{\"error\":\"instantdex_BTCswap error creating pubkeyargs\"}"));
char str[65]; printf("GOT OFFER! orderid.%llu %p (%s/%s) other.%s myside.%d\n",(long long)ap->orderid,ap->info,ap->offer.base,ap->offer.rel,bits256_str(str,traderpub),swap->isbob);
if ( (newjson= instantdex_parseargjson(myinfo,exchange,ap,argjson,1)) == 0 )
swap = bitcoin_swapinit(myinfo,exchange,myap,otherap,0,argjson);
if ( (newjson= instantdex_parseargjson(myinfo,exchange,swap,argjson,1)) == 0 )
return(clonestr("{\"error\":\"instantdex_BTCswap offer null newjson\"}"));
else if ( (retstr= instantdex_addfeetx(myinfo,newjson,ap,swap,"BOB_gotoffer","ALICE_gotoffer")) == 0 )
else //if ( (retstr= instantdex_addfeetx(myinfo,newjson,ap,swap,"BOB_gotoffer","ALICE_gotoffer")) == 0 )
{
//instantdex_pendingnotice(myinfo,exchange,A,ap->offer.basevolume64);
queue_enqueue("statemachineQ",&exchange->statemachineQ,&swap->DL,0);
if ( (retstr= instantdex_choosei(swap,newjson,argjson,serdata,serdatalen)) != 0 )
return(retstr);
else
{
return(instantdex_sendcmd(myinfo,&ap->offer,newjson,"BTCdeckC",traderpub,INSTANTDEX_HOPS,swap->deck,sizeof(swap->deck)));
return(instantdex_sendcmd(myinfo,&swap->mine.offer,newjson,"BTCdeckC",traderpub,INSTANTDEX_HOPS,swap->deck,sizeof(swap->deck)));
}
} else return(retstr);
}
char *instantdex_selectqueue(struct exchange_info *exchange,struct instantdex_accept *ap,char *retstr)
{
cJSON *retjson; int32_t flag = 0;
if ( (retjson= cJSON_Parse(retstr)) != 0 )
{
if ( jobj(retjson,"error") != 0 )
{
printf("requeue acceptableQ gotoffer error.(%s)\n",jprint(retjson,0));
instantdex_swapfree(0,ap->info);
ap->info = 0;
flag++;
queue_enqueue("acceptableQ",&exchange->acceptableQ,&ap->DL,0);
}
free_json(retjson);
}
if ( flag == 0 )
{
printf("add orderid.%llu to statemachine\n",(long long)ap->orderid);
queue_enqueue("statemachineQ",&exchange->statemachineQ,&ap->DL,0);
}
return(retstr);
}
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; double minperc; struct instantdex_accept A,*ap = 0; bits256 traderpub; cJSON *newjson;
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");
@ -1033,51 +972,19 @@ char *instantdex_parse(struct supernet_info *myinfo,struct instantdex_msghdr *ms
A.offer = *offer;
A.orderid = orderhash.txid;
printf("got.(%s) for %llu\n",cmdstr,(long long)A.orderid);
if ( strcmp(cmdstr,"BTCoffer") == 0 || strcmp(cmdstr,"BTCdeckC") == 0 )
if ( (A.offer.minperc= jdouble(argjson,"p")) < INSTANTDEX_MINPERC )
A.offer.minperc = INSTANTDEX_MINPERC;
else if ( A.offer.minperc > 100 )
A.offer.minperc = 100;
if ( strcmp(cmdstr,"BTCoffer") == 0 ) // incoming
{
if ( (minperc= jdouble(argjson,"p")) < INSTANTDEX_MINPERC )
minperc = INSTANTDEX_MINPERC;
if ( (ap= instantdex_acceptable(myinfo,exchange,&A,myinfo->myaddr.nxt64bits,minperc)) != 0 )
if ( (ap= instantdex_acceptable(myinfo,exchange,&A,A.offer.minperc)) != 0 )
{
if ( strcmp(cmdstr,"BTCoffer") == 0 )
if ( (retstr= instantdex_gotoffer(myinfo,exchange,ap,&A,msg,argjson,remoteaddr,signerbits,serdata,serdatalen)) != 0 ) // adds to statemachine if no error
{
if ( ap->otherorderid == 0 )
{
ap->otherorderid = A.orderid;
ap->otheroffer = A.offer;
}
if ( (retstr= instantdex_gotoffer(myinfo,exchange,ap,msg,argjson,remoteaddr,signerbits,serdata,serdatalen)) != 0 ) // adds to statemachine if no error
{
//printf("from GOTOFFER\n");
return(instantdex_selectqueue(exchange,ap,retstr));
}
}
else
{
if ( ap->info == 0 )
{
printf("A (%s) null swap for orderid.%llu p.%p\n",cmdstr,(long long)ap->orderid,ap);
return(clonestr("{\"error\":\"no swap for orderid\"}"));
}
else
{
if ( ap->otherorderid == 0 )
{
ap->otherorderid = ap->orderid;
ap->otheroffer = ap->offer;
ap->offer = A.offer;
ap->orderid = A.orderid;
((struct bitcoin_swapinfo *)ap->info)->feetag64 = ap->orderid;
}
printf("add to statemachine\n");
queue_enqueue("statemachineQ",&exchange->statemachineQ,&ap->DL,0);
newjson = instantdex_parseargjson(myinfo,exchange,ap,argjson,0);
if ( (retstr= instantdex_addfeetx(myinfo,newjson,ap,ap->info,"BOB_sentoffer","ALICE_sentoffer")) == 0 )
{
return(instantdex_statemachine(BTC_states,BTC_numstates,myinfo,exchange,ap,cmdstr,argjson,newjson,serdata,serdatalen));
} else return(clonestr("{\"error\":\"couldnt add fee\"}"));
}
}
printf("from GOTOFFER.(%s)\n",retstr);
return(retstr);
} else return(clonestr("{\"error\":\"gotoffer error\"}"));
}
else
{
@ -1092,22 +999,10 @@ char *instantdex_parse(struct supernet_info *myinfo,struct instantdex_msghdr *ms
} else return(clonestr("{\"result\":\"order was already in orderbook\"}"));
}
}
else if ( (ap= instantdex_statemachinefind(myinfo,exchange,A.orderid,1)) != 0 || (ap= instantdex_offerfind(myinfo,exchange,0,0,A.orderid,"*","*",0)) != 0 )
else if ( (swap= instantdex_statemachinefind(myinfo,exchange,A.orderid,1)) != 0 )
{
if ( ap->info == 0 )
{
if ( strcmp(cmdstr,"BTCdeckC") != 0 )
{
printf("B (%s) null swap for orderid.%llu p.%p\n",cmdstr,(long long)ap->orderid,ap);
return(clonestr("{\"error\":\"no swap for orderid\"}"));
}
else
{
printf("BTCdeckC ap.%p null info\n",ap->info);
}
}
newjson = instantdex_parseargjson(myinfo,exchange,ap,argjson,0);
return(instantdex_statemachine(BTC_states,BTC_numstates,myinfo,exchange,ap,cmdstr,argjson,newjson,serdata,serdatalen));
newjson = instantdex_parseargjson(myinfo,exchange,swap,argjson,0);
return(instantdex_statemachine(BTC_states,BTC_numstates,myinfo,exchange,swap,cmdstr,argjson,newjson,serdata,serdatalen));
}
else
{
@ -1138,8 +1033,6 @@ char *InstantDEX_hexmsg(struct supernet_info *myinfo,void *ptr,int32_t len,char
free_json(argjson);
return(clonestr("{\"error\":\"string base packets deprecated\"}"));
}
//printf("msg.%p len.%d data.%p datalen.%d crc.%u %s\n",msg,len,data,datalen,calc_crc32(0,(void *)msg,len),bits256_str(str,msg->sig.pubkey));
//return(0);
else if ( (signerbits= acct777_validate(&msg->sig,acct777_msgprivkey(serdata,datalen),msg->sig.pubkey)) != 0 || 1 )
{
flag++;
@ -1197,7 +1090,7 @@ char *InstantDEX_hexmsg(struct supernet_info *myinfo,void *ptr,int32_t len,char
return(retstr);
}
char *instantdex_queueaccept(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)
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)
{
struct instantdex_accept *ap; int32_t myside; char *retstr;
*aptrp = 0;
@ -1213,7 +1106,7 @@ char *instantdex_queueaccept(struct supernet_info *myinfo,struct instantdex_acce
myside = -1;
printf("myside.(%s) != base.%s or rel.%s\n",mysidestr,base,rel);
}
instantdex_acceptset(ap,base,rel,duration,myside,acceptdir,price,basevolume,offerer,0);
instantdex_acceptset(ap,base,rel,duration,myside,acceptdir,price,basevolume,offerer,0,minperc);
if ( queueflag != 0 )
{
printf("acceptableQ <- %llu\n",(long long)ap->orderid);
@ -1233,7 +1126,7 @@ void instantdex_update(struct supernet_info *myinfo)
if ( (Q= category_Q(instantdexhash,myinfo->myaddr.persistent)) != 0 && queue_size(Q) > 0 && (item= Q->list) != 0 )
{
m = (void *)item;
m= queue_dequeue(Q,0);
m = queue_dequeue(Q,0);
pm = (struct instantdex_msghdr *)m->msg;
//printf("loop cmd.(%s)\n",pm->cmd);
//if ( m->remoteipbits == 0 && (m= queue_dequeue(Q,0)) )
@ -1250,41 +1143,31 @@ void instantdex_update(struct supernet_info *myinfo)
free(m);
}
}
/*
for (iter=0; iter<2; iter++)
{
while ( (m= category_gethexmsg(myinfo,instantdexhash,iter == 0 ? GENESIS_PUBKEY : myinfo->myaddr.persistent)) != 0 )
{
//printf("gothexmsg len.%d\n",m->len);
pm = (struct instantdex_msghdr *)m->msg;
if ( m->remoteipbits != 0 )
expand_ipbits(remote,m->remoteipbits);
else remote[0] = 0;
if ( (str= InstantDEX_hexmsg(myinfo,pm,m->len,remote)) != 0 )
free(str);
free(m);
}
}*/
}
#include "../includes/iguana_apidefs.h"
TWO_STRINGS_AND_TWO_DOUBLES(InstantDEX,maxaccept,base,rel,maxprice,basevolume)
{
struct instantdex_accept *ap;
struct instantdex_accept *ap; char *retstr; struct exchange_info *exchange; uint64_t txid;
myinfo = SuperNET_accountfind(json);
if ( remoteaddr == 0 )
return(instantdex_queueaccept(myinfo,&ap,exchanges777_find("bitcoin"),base,rel,maxprice,basevolume,-1,rel,INSTANTDEX_OFFERDURATION,myinfo->myaddr.nxt64bits,1));
else return(clonestr("{\"error\":\"InstantDEX API request only local usage!\"}"));
if ( remoteaddr == 0 && (exchange= exchanges777_find("bitcoin")) != 0 )
{
retstr = instantdex_createaccept(myinfo,&ap,exchange,base,rel,maxprice,basevolume,-1,rel,INSTANTDEX_OFFERDURATION,myinfo->myaddr.nxt64bits,1,juint(json,"minperc"));
return(instantdex_checkoffer(myinfo,&txid,exchange,ap,json));
} else return(clonestr("{\"error\":\"InstantDEX API request only local usage!\"}"));
}
TWO_STRINGS_AND_TWO_DOUBLES(InstantDEX,minaccept,base,rel,minprice,basevolume)
{
struct instantdex_accept *ap;
struct instantdex_accept *ap; char *retstr; struct exchange_info *exchange; uint64_t txid;
myinfo = SuperNET_accountfind(json);
if ( remoteaddr == 0 )
return(instantdex_queueaccept(myinfo,&ap,exchanges777_find("bitcoin"),base,rel,minprice,basevolume,1,base,INSTANTDEX_OFFERDURATION,myinfo->myaddr.nxt64bits,1));
else return(clonestr("{\"error\":\"InstantDEX API request only local usage!\"}"));
if ( remoteaddr == 0 && (exchange= exchanges777_find("bitcoin")) != 0 )
{
retstr = instantdex_createaccept(myinfo,&ap,exchanges777_find("bitcoin"),base,rel,minprice,basevolume,1,base,INSTANTDEX_OFFERDURATION,myinfo->myaddr.nxt64bits,1,juint(json,"minperc"));
return(instantdex_checkoffer(myinfo,&txid,exchange,ap,json));
} else return(clonestr("{\"error\":\"InstantDEX API request only local usage!\"}"));
}
THREE_STRINGS_AND_DOUBLE(atomic,offer,base,rel,orderid,basevolume)

BIN
iguana/pnacl/Release/iguana.pexe

Binary file not shown.

329
iguana/swaps/iguana_BTCswap.c

@ -25,18 +25,6 @@ Tier Nolan's approach is followed with the following changes:
e) BEFORE Bob broadcasts deposit, Alice broadcasts BTC denominated fee in cltv so if trade isnt done fee is reclaimed
*/
int64_t instantdex_BTCsatoshis(int64_t price,int64_t volume)
{
if ( volume > price )
return(price * dstr(volume));
else return(dstr(price) * volume);
}
int64_t instantdex_insurance(struct iguana_info *coin,int64_t amount)
{
return(amount * INSTANTDEX_INSURANCERATE + coin->chain->txfee); // insurance prevents attack
}
/*
both fees are standard payments: OP_DUP OP_HASH160 FEE_RMD160 OP_EQUALVERIFY OP_CHECKSIG
@ -104,9 +92,9 @@ void disp_tx(struct supernet_info *myinfo,struct iguana_info *coin,char *str,cha
printf("disp_tx (%s) -> %s.(%s)\n",txbytes,str,jprint(txobj,1));
}
char *instantdex_feetx(struct supernet_info *myinfo,bits256 *txidp,struct instantdex_accept *A)
struct bitcoin_statetx *instantdex_feetx(struct supernet_info *myinfo,bits256 *txidp,struct instantdex_accept *A)
{
int32_t n,len; char *feetx = 0; struct iguana_info *coin; cJSON *txobj; struct bitcoin_spend *spend; int64_t insurance; uint8_t paymentscript[128];
int32_t n,len; char *feetx = 0; struct iguana_info *coin; cJSON *txobj; struct bitcoin_spend *spend; int64_t insurance; uint8_t paymentscript[128]; struct bitcoin_statetx *ptr = 0;
if ( (coin= iguana_coinfind("BTCD")) != 0 )
{
insurance = IGUANA_BTCDMULT * instantdex_insurance(coin,instantdex_BTCsatoshis(A->offer.price64,A->offer.basevolume64));
@ -124,8 +112,11 @@ char *instantdex_feetx(struct supernet_info *myinfo,bits256 *txidp,struct instan
txobj = iguana_signtx(coin,txidp,&feetx,spend,txobj);
if ( feetx != 0 )
{
ptr = calloc(1,sizeof(*ptr) + strlen(feetx) + 1);
strcpy(ptr->txbytes,feetx);
printf("%s feetx.%s\n",A->offer.myside != 0 ? "BOB" : "ALICE",feetx);
//disp_tx(myinfo,coin,"feetx",feetx);
free(feetx);
}
else printf("error signing %s feetx numinputs.%d\n",A->offer.myside != 0 ? "BOB" : "ALICE",spend->numinputs);
free(spend);
@ -135,26 +126,28 @@ char *instantdex_feetx(struct supernet_info *myinfo,bits256 *txidp,struct instan
printf("no unspents to spend\n");
}
}
return(feetx);
return(ptr);
}
int32_t instantdex_feetxverify(struct supernet_info *myinfo,struct iguana_info *coin,struct bitcoin_swapinfo *swap,struct instantdex_accept *A,cJSON *argjson)
int32_t instantdex_feetxverify(struct supernet_info *myinfo,struct iguana_info *coin,struct bitcoin_swapinfo *swap,cJSON *argjson)
{
cJSON *txobj; bits256 txid; uint32_t n; int32_t i,retval = -1; int64_t insurance;
struct iguana_msgtx msgtx; uint8_t script[512];
if ( swap->otherfeetx != 0 && swap->otherfeeconfirms < 0 )
if ( swap->otherfee != 0 && swap->otherfee->numconfirms < 0 )
{
if ( (txobj= bitcoin_hex2json(coin,&txid,&msgtx,swap->otherfeetx)) != 0 )
if ( (txobj= bitcoin_hex2json(coin,&txid,&msgtx,swap->otherfee->txbytes)) != 0 )
{
insurance = IGUANA_BTCDMULT * instantdex_insurance(coin,instantdex_BTCsatoshis(A->offer.price64,A->offer.basevolume64));
n = instantdex_outputinsurance(script,0,insurance,A->orderid);
insurance = swap->insurance;//instantdex_insurance(coin,swap->BTCsatoshis);
if ( strcmp(coin->symbol,"BTCD") == 0 )
insurance *= IGUANA_BTCDMULT;
n = instantdex_outputinsurance(script,0,insurance,swap->matched64);
if ( n == msgtx.vouts[0].pk_scriptlen )
{
if ( memcmp(script,msgtx.vouts[0].pk_script,n) == 0 )
{
//printf("feetx script verified.(%s)\n",swap->otherfeetx);
retval = 0;
swap->otherfeeconfirms = 0;
swap->otherfee->numconfirms = 0.;
}
else
{
@ -167,17 +160,28 @@ int32_t instantdex_feetxverify(struct supernet_info *myinfo,struct iguana_info *
}
} 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->otherfeetx);
}
else if ( swap->otherfeeconfirms >= 0 )
} else printf("error converting (%s) txobj\n",swap->otherfee->txbytes);
} else if ( swap->otherfee != 0 && swap->otherfee->numconfirms >= 0 )
retval = 0;
else printf("no feetx to verify\n");
return(retval);
}
char *instantdex_bobtx(struct supernet_info *myinfo,struct iguana_info *coin,bits256 *txidp,bits256 pub1,bits256 pub2,bits256 priv,uint32_t reftime,int64_t amount,int32_t depositflag)
char *instantdex_addfeetx(struct supernet_info *myinfo,cJSON *newjson,struct instantdex_accept *ap,struct bitcoin_swapinfo *swap,char *bobstate,char *alicestate)
{
cJSON *txobj; int32_t n,secretstart; char *signedtx = 0;
if ( (swap->myfee= instantdex_feetx(myinfo,&swap->myfee->txid,ap)) != 0 )
{
jaddstr(newjson,"feetx",swap->myfee->txbytes);
jaddbits256(newjson,"feetxid",swap->myfee->txid);
swap->state = instantdex_statefind(BTC_states,BTC_numstates,instantdex_isbob(swap) != 0 ? bobstate : alicestate);
return(0);
}
return(clonestr("{\"error\":\"couldnt create feetx\"}"));
}
struct bitcoin_statetx *instantdex_bobtx(struct supernet_info *myinfo,struct iguana_info *coin,bits256 *txidp,bits256 pub1,bits256 pub2,bits256 priv,uint32_t reftime,int64_t amount,int32_t depositflag)
{
cJSON *txobj; int32_t n,secretstart; char *signedtx = 0; struct bitcoin_statetx *ptr = 0;
uint8_t script[1024],secret[20]; struct bitcoin_spend *spend; uint32_t locktime; int64_t insurance;
if ( coin == 0 )
return(0);
@ -193,28 +197,31 @@ char *instantdex_bobtx(struct supernet_info *myinfo,struct iguana_info *coin,bit
txobj = iguana_signtx(coin,txidp,&signedtx,spend,txobj);
if ( signedtx != 0 )
{
ptr = calloc(1,sizeof(*ptr) + strlen(signedtx) + 1);
strcpy(ptr->txbytes,signedtx);
printf("bob deposit.%s\n",signedtx);
//disp_tx(myinfo,coin,depositflag != 0 ? "deposit" : "payment",signedtx);
free(signedtx);
} else printf("error signing bobdeposit numinputs.%d\n",spend->numinputs);
free(spend);
}
free_json(txobj);
return(signedtx);
return(ptr);
}
int32_t instantdex_paymentverify(struct supernet_info *myinfo,struct iguana_info *coin,struct bitcoin_swapinfo *swap,struct instantdex_accept *A,cJSON *argjson,int32_t depositflag)
int32_t instantdex_paymentverify(struct supernet_info *myinfo,struct iguana_info *coin,struct bitcoin_swapinfo *swap,cJSON *argjson,int32_t depositflag)
{
cJSON *txobj; bits256 txid; uint32_t n,locktime; int32_t i,secretstart,retval = -1; uint64_t x;
struct iguana_msgtx msgtx; uint8_t script[512],rmd160[20]; int64_t relsatoshis,amount,insurance = 0;
if ( coin != 0 && jstr(argjson,depositflag != 0 ? "deposit" : "payment") != 0 )
{
relsatoshis = instantdex_BTCsatoshis(A->offer.price64,A->offer.basevolume64);
relsatoshis = swap->altsatoshis;
if ( depositflag != 0 )
insurance = 100 * (relsatoshis * INSTANTDEX_INSURANCERATE + coin->chain->txfee);
amount = relsatoshis + insurance;
if ( (txobj= bitcoin_hex2json(coin,&txid,&msgtx,swap->deposit)) != 0 )
if ( swap->deposit != 0 && (txobj= bitcoin_hex2json(coin,&txid,&msgtx,swap->deposit->txbytes)) != 0 )
{
locktime = A->offer.expiration;
locktime = swap->expiration;
if ( depositflag == 0 )
memset(rmd160,0,sizeof(rmd160));
else calc_rmd160_sha256(rmd160,swap->privkeys[0].bytes,sizeof(rmd160));
@ -225,10 +232,10 @@ int32_t instantdex_paymentverify(struct supernet_info *myinfo,struct iguana_info
if ( memcmp(script,msgtx.vouts[0].pk_script,n) == 0 )
{
iguana_rwnum(0,&script[secretstart],sizeof(x),&x);
printf("deposit script verified x.%llx vs otherscut %llx\n",(long long)x,(long long)swap->otherscut[swap->choosei][0]);
if ( x == swap->otherscut[swap->choosei][0] )
printf("deposit script verified x.%llx vs otherdeck %llx\n",(long long)x,(long long)swap->otherdeck[swap->choosei][0]);
if ( x == swap->otherdeck[swap->choosei][0] )
retval = 0;
else printf("deposit script verified but secret mismatch x.%llx vs otherscut %llx\n",(long long)x,(long long)swap->otherscut[swap->choosei][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
{
@ -246,13 +253,13 @@ int32_t instantdex_paymentverify(struct supernet_info *myinfo,struct iguana_info
return(retval);
}
int32_t instantdex_altpaymentverify(struct supernet_info *myinfo,struct iguana_info *coin,struct bitcoin_swapinfo *swap,struct instantdex_accept *A,cJSON *argjson)
int32_t instantdex_altpaymentverify(struct supernet_info *myinfo,struct iguana_info *coin,struct bitcoin_swapinfo *swap,cJSON *argjson)
{
cJSON *txobj; bits256 txid; uint32_t n; int32_t i,retval = -1;
struct iguana_msgtx msgtx; uint8_t script[512]; char *altmsigaddr,msigaddr[64];
if ( jstr(argjson,"altpayment") != 0 && (altmsigaddr= jstr(argjson,"altmsigaddr")) != 0 )
{
if ( (txobj= bitcoin_hex2json(coin,&txid,&msgtx,swap->altpayment)) != 0 )
if ( swap->altpayment != 0 && (txobj= bitcoin_hex2json(coin,&txid,&msgtx,swap->altpayment->txbytes)) != 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 )
@ -277,9 +284,9 @@ int32_t instantdex_altpaymentverify(struct supernet_info *myinfo,struct iguana_i
return(retval);
}
char *instantdex_alicetx(struct supernet_info *myinfo,struct iguana_info *altcoin,char *msigaddr,bits256 *txidp,bits256 pubAm,bits256 pubBn,int64_t amount)
struct bitcoin_statetx *instantdex_alicetx(struct supernet_info *myinfo,struct iguana_info *altcoin,char *msigaddr,bits256 *txidp,bits256 pubAm,bits256 pubBn,int64_t amount)
{
cJSON *txobj; int32_t n; char *signedtx = 0; uint8_t script[1024]; struct bitcoin_spend *spend;
cJSON *txobj; int32_t n; char *signedtx = 0; uint8_t script[1024]; struct bitcoin_spend *spend; struct bitcoin_statetx *ptr = 0;
if ( altcoin != 0 && (spend= iguana_spendset(myinfo,altcoin,amount,altcoin->chain->txfee,0)) != 0 )
{
txobj = bitcoin_createtx(altcoin,0);
@ -291,66 +298,76 @@ char *instantdex_alicetx(struct supernet_info *myinfo,struct iguana_info *altcoi
{
printf("alice payment.%s\n",signedtx);
//disp_tx(myinfo,altcoin,"altpayment",signedtx);
ptr = calloc(1,sizeof(*ptr) + strlen(signedtx) + 1);
strcpy(ptr->txbytes,signedtx);
free(signedtx);
}
else printf("error signing alicetx numinputs.%d\n",spend->numinputs);
free(spend);
free_json(txobj);
}
return(signedtx);
return(ptr);
}
cJSON *BOB_reclaimfunc(struct supernet_info *myinfo,struct exchange_info *exchange,struct instantdex_accept *ap,cJSON *argjson,cJSON *newjson,uint8_t **serdatap,int32_t *serdatalenp)
cJSON *BOB_reclaimfunc(struct supernet_info *myinfo,struct exchange_info *exchange,struct bitcoin_swapinfo *swap,cJSON *argjson,cJSON *newjson,uint8_t **serdatap,int32_t *serdatalenp)
{
*serdatap = 0, *serdatalenp = 0; struct bitcoin_swapinfo *swap = ap->info;
printf("reclaim deposit.(%s) to %s\n",swap->deposit,myinfo->myaddr.BTC);
*serdatap = 0, *serdatalenp = 0;
if ( swap->deposit != 0 )
printf("reclaim deposit.(%s) to %s\n",swap->deposit->txbytes,myinfo->myaddr.BTC);
// reclaim deposit
return(newjson);
}
cJSON *BOB_feereclaimfunc(struct supernet_info *myinfo,struct exchange_info *exchange,struct instantdex_accept *ap,cJSON *argjson,cJSON *newjson,uint8_t **serdatap,int32_t *serdatalenp)
cJSON *BOB_feereclaimfunc(struct supernet_info *myinfo,struct exchange_info *exchange,struct bitcoin_swapinfo *swap,cJSON *argjson,cJSON *newjson,uint8_t **serdatap,int32_t *serdatalenp)
{
*serdatap = 0, *serdatalenp = 0; struct bitcoin_swapinfo *swap = ap->info;
printf("reclaim fee.(%s)\n",swap->deposit);
*serdatap = 0, *serdatalenp = 0;
if ( swap->myfee != 0 )
printf("reclaim fee.(%s)\n",swap->myfee->txbytes);
// reclaim deposit
return(newjson);
}
cJSON *BOB_claimaltfunc(struct supernet_info *myinfo,struct exchange_info *exchange,struct instantdex_accept *ap,cJSON *argjson,cJSON *newjson,uint8_t **serdatap,int32_t *serdatalenp)
cJSON *BOB_claimaltfunc(struct supernet_info *myinfo,struct exchange_info *exchange,struct bitcoin_swapinfo *swap,cJSON *argjson,cJSON *newjson,uint8_t **serdatap,int32_t *serdatalenp)
{
*serdatap = 0, *serdatalenp = 0; struct bitcoin_swapinfo *swap = ap->info; char altcoinaddr[64];
printf("spend altpayment.(%s) -> %s\n",swap->altpayment,altcoinaddr);
*serdatap = 0, *serdatalenp = 0; char altcoinaddr[64];
if ( swap->altpayment != 0 )
printf("spend altpayment.(%s) -> %s\n",swap->altpayment->txbytes,altcoinaddr);
// spend altpayment
return(newjson);
}
cJSON *ALICE_reclaimfunc(struct supernet_info *myinfo,struct exchange_info *exchange,struct instantdex_accept *ap,cJSON *argjson,cJSON *newjson,uint8_t **serdatap,int32_t *serdatalenp)
cJSON *ALICE_reclaimfunc(struct supernet_info *myinfo,struct exchange_info *exchange,struct bitcoin_swapinfo *swap,cJSON *argjson,cJSON *newjson,uint8_t **serdatap,int32_t *serdatalenp)
{
*serdatap = 0, *serdatalenp = 0; struct bitcoin_swapinfo *swap = ap->info; char altcoinaddr[64];
*serdatap = 0, *serdatalenp = 0; char altcoinaddr[64];
// reclaim altpayment
printf("reclaim altpayment.(%s) -> %s\n",swap->altpayment,altcoinaddr);
if ( swap->altpayment != 0 )
printf("reclaim altpayment.(%s) -> %s\n",swap->altpayment->txbytes,altcoinaddr);
return(newjson);
}
cJSON *ALICE_feereclaimfunc(struct supernet_info *myinfo,struct exchange_info *exchange,struct instantdex_accept *ap,cJSON *argjson,cJSON *newjson,uint8_t **serdatap,int32_t *serdatalenp)
cJSON *ALICE_feereclaimfunc(struct supernet_info *myinfo,struct exchange_info *exchange,struct bitcoin_swapinfo *swap,cJSON *argjson,cJSON *newjson,uint8_t **serdatap,int32_t *serdatalenp)
{
*serdatap = 0, *serdatalenp = 0; struct bitcoin_swapinfo *swap = ap->info;
*serdatap = 0, *serdatalenp = 0;
// reclaim fee
printf("reclaim fee.(%s)\n",swap->myfeetx);
if ( swap->myfee != 0 )
printf("reclaim fee.(%s)\n",swap->myfee->txbytes);
return(newjson);
}
cJSON *ALICE_claimdepositfunc(struct supernet_info *myinfo,struct exchange_info *exchange,struct instantdex_accept *ap,cJSON *argjson,cJSON *newjson,uint8_t **serdatap,int32_t *serdatalenp)
cJSON *ALICE_claimdepositfunc(struct supernet_info *myinfo,struct exchange_info *exchange,struct bitcoin_swapinfo *swap,cJSON *argjson,cJSON *newjson,uint8_t **serdatap,int32_t *serdatalenp)
{
*serdatap = 0, *serdatalenp = 0; struct bitcoin_swapinfo *swap = ap->info;
printf("reclaim deposit.(%s)\n",swap->deposit);
*serdatap = 0, *serdatalenp = 0;
if ( swap->deposit != 0 )
printf("reclaim deposit.(%s)\n",swap->deposit->txbytes);
// reclaim deposit
return(newjson);
}
cJSON *ALICE_claimbtcfunc(struct supernet_info *myinfo,struct exchange_info *exchange,struct instantdex_accept *ap,cJSON *argjson,cJSON *newjson,uint8_t **serdatap,int32_t *serdatalenp)
cJSON *ALICE_claimbtcfunc(struct supernet_info *myinfo,struct exchange_info *exchange,struct bitcoin_swapinfo *swap,cJSON *argjson,cJSON *newjson,uint8_t **serdatap,int32_t *serdatalenp)
{
*serdatap = 0, *serdatalenp = 0; struct bitcoin_swapinfo *swap = ap->info;
printf("spend BTC payment.(%s) -> %s\n",swap->payment,myinfo->myaddr.BTC);
*serdatap = 0, *serdatalenp = 0;
if ( swap->payment != 0 )
printf("spend BTC payment.(%s) -> %s\n",swap->payment->txbytes,myinfo->myaddr.BTC);
// spend BTC
return(newjson);
}
@ -404,16 +421,16 @@ char *instantdex_choosei(struct bitcoin_swapinfo *swap,cJSON *newjson,cJSON *arg
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->otherscut) / sizeof(*swap->otherscut));
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->otherscut[i][j],sizeof(x),&serdata[len]);
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("%llu/%llu %s send mychoosei.%d of max.%d\n",(long long)swap->bidid,(long long)swap->askid,swap->isbob!=0?"BOB":"alice",swap->choosei,max);
printf("%llu/%llu %s send mychoosei.%d of max.%d\n",(long long)swap->mine.orderid,(long long)swap->other.orderid,instantdex_isbob(swap)!=0?"BOB":"alice",swap->choosei,max);
return(0);
}
else
@ -432,7 +449,7 @@ void instantdex_getpubs(struct bitcoin_swapinfo *swap,cJSON *argjson,cJSON *newj
for (i=0; i<2; i++)
for (j=0; j<2; j++)
fields[i][j][1] = '0' + j;
myind = swap->isbob;
myind = instantdex_isbob(swap);
otherind = (myind ^ 1);
for (j=0; j<2; j++)
{
@ -463,19 +480,19 @@ void instantdex_privkeyextract(struct supernet_info *myinfo,struct bitcoin_swapi
}
pubi = bitcoin_pubkey33(otherpubkey,otherpriv);
vcalc_sha256(0,hashpriv.bytes,otherpriv.bytes,sizeof(otherpriv));
if ( otherpubkey[0] != (swap->isbob ^ 1) + 0x02 )
if ( otherpubkey[0] != (instantdex_isbob(swap) ^ 1) + 0x02 )
{
wrongfirstbyte++;
printf("wrongfirstbyte[%d] %02x\n",i,otherpubkey[0]);
}
else if ( swap->otherscut[i][0] != hashpriv.txid )
else if ( swap->otherdeck[i][0] != hashpriv.txid )
{
printf("otherscut[%d] priv mismatch %llx != %llx\n",i,(long long)swap->otherscut[i][0],(long long)hashpriv.txid);
printf("otherdeck[%d] priv mismatch %llx != %llx\n",i,(long long)swap->otherdeck[i][0],(long long)hashpriv.txid);
errs++;
}
else if ( swap->otherscut[i][1] != pubi.txid )
else if ( swap->otherdeck[i][1] != pubi.txid )
{
printf("otherscut[%d] priv mismatch %llx != %llx\n",i,(long long)swap->otherscut[i][1],(long long)pubi.txid);
printf("otherdeck[%d] priv mismatch %llx != %llx\n",i,(long long)swap->otherdeck[i][1],(long long)pubi.txid);
errs++;
}
}
@ -485,7 +502,7 @@ void instantdex_privkeyextract(struct supernet_info *myinfo,struct bitcoin_swapi
}
}
void instantdex_swaptxupdate(char **ptrp,bits256 *txidp,cJSON *argjson,char *txname,char *txidfield)
void instantdex_swaptxupdate(struct bitcoin_statetx **ptrp,cJSON *argjson,char *txname,char *txidfield)
{
char *str;
if ( (str= jstr(argjson,txname)) != 0 )
@ -495,8 +512,9 @@ void instantdex_swaptxupdate(char **ptrp,bits256 *txidp,cJSON *argjson,char *txn
printf("got replacement %s? (%s)\n",txname,str);
free(*ptrp);
}
*txidp = jbits256(argjson,txidfield);
*ptrp = clonestr(str);
*ptrp = calloc(1,sizeof(**ptrp) + strlen(str) + 1);
strcpy((*ptrp)->txbytes,str);
(*ptrp)->txid = jbits256(argjson,txidfield);
}
}
@ -512,21 +530,21 @@ void instantdex_swapbits256update(bits256 *txidp,cJSON *argjson,char *fieldname)
}
}
cJSON *instantdex_parseargjson(struct supernet_info *myinfo,struct exchange_info *exchange,struct instantdex_accept *ap,cJSON *argjson,int32_t deckflag)
cJSON *instantdex_parseargjson(struct supernet_info *myinfo,struct exchange_info *exchange,struct bitcoin_swapinfo *swap,cJSON *argjson,int32_t deckflag)
{
cJSON *newjson; struct bitcoin_swapinfo *swap;
cJSON *newjson;
newjson = cJSON_CreateObject();
if ( (swap= ap->info) == 0 )
if ( swap == 0 )
jaddstr(newjson,"error","missing swap info");
else
{
if ( swap->isbob != 0 )
if ( instantdex_isbob(swap) != 0 )
{
instantdex_swapbits256update(&swap->otherpubs[0],argjson,"pubA0");
instantdex_swapbits256update(&swap->otherpubs[1],argjson,"pubA1");
instantdex_swapbits256update(&swap->pubAm,argjson,"pubAm");
instantdex_swapbits256update(&swap->privAm,argjson,"privAm");
instantdex_swaptxupdate(&swap->altpayment,&swap->altpaymenttxid,argjson,"altpayment","altpaymenttxid");
instantdex_swaptxupdate(&swap->altpayment,argjson,"altpayment","altpaymenttxid");
}
else
{
@ -534,20 +552,20 @@ cJSON *instantdex_parseargjson(struct supernet_info *myinfo,struct exchange_info
instantdex_swapbits256update(&swap->otherpubs[1],argjson,"pubB1");
instantdex_swapbits256update(&swap->pubBn,argjson,"pubBn");
instantdex_swapbits256update(&swap->privBn,argjson,"privBn");
instantdex_swaptxupdate(&swap->deposit,&swap->deposittxid,argjson,"deposit","deposittxid");
instantdex_swaptxupdate(&swap->payment,&swap->paymenttxid,argjson,"payment","paymenttxid");
instantdex_swaptxupdate(&swap->deposit,argjson,"deposit","deposittxid");
instantdex_swaptxupdate(&swap->payment,argjson,"payment","paymenttxid");
}
instantdex_swaptxupdate(&swap->otherfeetx,&swap->otherfeetxid,argjson,"feetx","feetxid");
if ( swap->otherschoosei < 0 && jobj(argjson,"mychoosei") != 0 )
instantdex_swaptxupdate(&swap->otherfee,argjson,"feetx","feetxid");
if ( swap->otherchoosei < 0 && jobj(argjson,"mychoosei") != 0 )
{
//printf("otherschoosei.%d\n",swap->otherschoosei);
if ( (swap->otherschoosei= juint(argjson,"mychoosei")) >= sizeof(swap->otherscut)/sizeof(*swap->otherscut) )
swap->otherschoosei = -1;
if ( (swap->otherchoosei= juint(argjson,"mychoosei")) >= sizeof(swap->otherdeck)/sizeof(*swap->otherdeck) )
swap->otherchoosei = -1;
}
if ( juint(argjson,"verified") != 0 )
swap->otherverifiedcut = 1;
jaddnum(newjson,"verified",swap->otherverifiedcut);
if ( instantdex_pubkeyargs(swap,newjson,2 + deckflag*INSTANTDEX_DECKSIZE,myinfo->persistent_priv,swap->orderhash,0x02+swap->isbob) == 2 + deckflag*INSTANTDEX_DECKSIZE )
if ( instantdex_pubkeyargs(swap,newjson,2 + deckflag*INSTANTDEX_DECKSIZE,myinfo->persistent_priv,swap->myorderhash,0x02+instantdex_isbob(swap)) == 2 + deckflag*INSTANTDEX_DECKSIZE )
instantdex_getpubs(swap,argjson,newjson);
else printf("ERROR: couldnt generate pubkeys\n");
}
@ -561,73 +579,70 @@ double iguana_numconfs(struct iguana_info *coin,bits256 txid,int32_t height)
else return(0.); // 0.5 if zeroconfs
}
char *BTC_txconfirmed(struct supernet_info *myinfo,struct iguana_info *coin,struct instantdex_accept *ap,cJSON *newjson,bits256 txid,double *numconfirmsp,char *virtualevent,double requiredconfs)
char *BTC_txconfirmed(struct supernet_info *myinfo,struct iguana_info *coin,struct bitcoin_swapinfo *swap,cJSON *newjson,bits256 txid,double *numconfirmsp,char *virtualevent,double requiredconfs)
{
struct iguana_txid *tx,T; struct bitcoin_swapinfo *swap; int32_t height; char *retstr; double confs;
swap = ap->info;
struct iguana_txid *tx,T; int32_t height; char *retstr; double confs;
*numconfirmsp = -1.;
if ( coin != 0 && *numconfirmsp < 0 )
{
if ( (tx= iguana_txidfind(coin,&height,&T,txid)) != 0 && (confs= iguana_numconfs(coin,txid,height)) >= requiredconfs )
{
*numconfirmsp = confs;
if ( (retstr= instantdex_sendcmd(myinfo,&ap->offer,newjson,virtualevent,myinfo->myaddr.persistent,0,0,0)) != 0 )
if ( (retstr= instantdex_sendcmd(myinfo,&swap->mine.offer,newjson,virtualevent,myinfo->myaddr.persistent,0,0,0)) != 0 )
return(retstr);
}
}
return(0);
}
cJSON *BTC_waitdeckCfunc(struct supernet_info *myinfo,struct exchange_info *exchange,struct instantdex_accept *ap,cJSON *argjson,cJSON *newjson,uint8_t **serdatap,int32_t *serdatalenp)
cJSON *BTC_waitdeckCfunc(struct supernet_info *myinfo,struct exchange_info *exchange,struct bitcoin_swapinfo *swap,cJSON *argjson,cJSON *newjson,uint8_t **serdatap,int32_t *serdatalenp)
{
*serdatap = 0, *serdatalenp = 0; struct bitcoin_swapinfo *swap = ap->info;
*serdatap = 0, *serdatalenp = 0;
strcmp(swap->expectedcmdstr,"BTCdeckC");
if ( instantdex_feetxverify(myinfo,iguana_coinfind("BTCD"),swap,ap,argjson) != 0 )
if ( instantdex_feetxverify(myinfo,iguana_coinfind("BTCD"),swap,argjson) != 0 )
return(cJSON_Parse("{\"error\":\"feetx didnt verify\"}"));
return(newjson);
}
cJSON *BTC_waitprivCfunc(struct supernet_info *myinfo,struct exchange_info *exchange,struct instantdex_accept *ap,cJSON *argjson,cJSON *newjson,uint8_t **serdatap,int32_t *serdatalenp)
cJSON *BTC_waitprivCfunc(struct supernet_info *myinfo,struct exchange_info *exchange,struct bitcoin_swapinfo *swap,cJSON *argjson,cJSON *newjson,uint8_t **serdatap,int32_t *serdatalenp)
{
struct bitcoin_swapinfo *swap = ap->info;
strcmp(swap->expectedcmdstr,"BTCprivC");
instantdex_privkeyextract(myinfo,swap,*serdatap,*serdatalenp);
if ( instantdex_feetxverify(myinfo,iguana_coinfind("BTCD"),swap,ap,argjson) != 0 )
if ( instantdex_feetxverify(myinfo,iguana_coinfind("BTCD"),swap,argjson) != 0 )
return(cJSON_Parse("{\"error\":\"feetx didnt verify\"}"));
*serdatap = 0, *serdatalenp = 0;
return(newjson);
}
cJSON *BOB_waitBTCalttxfunc(struct supernet_info *myinfo,struct exchange_info *exchange,struct instantdex_accept *ap,cJSON *argjson,cJSON *newjson,uint8_t **serdatap,int32_t *serdatalenp)
cJSON *BOB_waitBTCalttxfunc(struct supernet_info *myinfo,struct exchange_info *exchange,struct bitcoin_swapinfo *swap,cJSON *argjson,cJSON *newjson,uint8_t **serdatap,int32_t *serdatalenp)
{
*serdatap = 0, *serdatalenp = 0; struct bitcoin_swapinfo *swap = ap->info;
*serdatap = 0, *serdatalenp = 0;
strcmp(swap->expectedcmdstr,"BTCalttx");
if ( instantdex_altpaymentverify(myinfo,iguana_coinfind(ap->offer.base),swap,ap,argjson) != 0 )
if ( instantdex_altpaymentverify(myinfo,iguana_coinfind(swap->mine.offer.base),swap,argjson) != 0 )
return(cJSON_Parse("{\"error\":\"altpayment didnt verify\"}"));
return(newjson);
}
cJSON *ALICE_waitBTCpaytxfunc(struct supernet_info *myinfo,struct exchange_info *exchange,struct instantdex_accept *ap,cJSON *argjson,cJSON *newjson,uint8_t **serdatap,int32_t *serdatalenp)
cJSON *ALICE_waitBTCpaytxfunc(struct supernet_info *myinfo,struct exchange_info *exchange,struct bitcoin_swapinfo *swap,cJSON *argjson,cJSON *newjson,uint8_t **serdatap,int32_t *serdatalenp)
{
*serdatap = 0, *serdatalenp = 0; struct bitcoin_swapinfo *swap = ap->info;
*serdatap = 0, *serdatalenp = 0;
strcmp(swap->expectedcmdstr,"BTCpaytx");
return(newjson);
}
cJSON *BOB_waitfeefunc(struct supernet_info *myinfo,struct exchange_info *exchange,struct instantdex_accept *ap,cJSON *argjson,cJSON *newjson,uint8_t **serdatap,int32_t *serdatalenp)
cJSON *BOB_waitfeefunc(struct supernet_info *myinfo,struct exchange_info *exchange,struct bitcoin_swapinfo *swap,cJSON *argjson,cJSON *newjson,uint8_t **serdatap,int32_t *serdatalenp)
{
char *retstr; struct bitcoin_swapinfo *swap = ap->info; struct iguana_info *coinbtc; uint32_t reftime;
char *retstr; struct iguana_info *coinbtc;
coinbtc = iguana_coinfind("BTC");
*serdatap = 0, *serdatalenp = 0;
reftime = (uint32_t)(ap->offer.expiration - INSTANTDEX_LOCKTIME*2);
if ( coinbtc != 0 && swap->deposit == 0 && (retstr= BTC_txconfirmed(myinfo,coinbtc,ap,newjson,swap->otherfeetxid,&swap->otherfeeconfirms,"feefound",0)) != 0 )
if ( coinbtc != 0 && swap->deposit == 0 && (retstr= BTC_txconfirmed(myinfo,coinbtc,swap,newjson,swap->otherfee->txid,&swap->otherfee->numconfirms,"feefound",0)) != 0 )
{
jaddstr(newjson,"feefound",retstr);
if ( (swap->deposit= instantdex_bobtx(myinfo,coinbtc,&swap->deposittxid,swap->otherpubs[0],swap->mypubs[0],swap->privkeys[swap->choosei],reftime,swap->satoshis[1],1)) != 0 )
if ( (swap->deposit= instantdex_bobtx(myinfo,coinbtc,&swap->deposit->txid,swap->otherpubs[0],swap->mypubs[0],swap->privkeys[swap->choosei],swap->reftime,swap->BTCsatoshis,1)) != 0 )
{
// broadcast deposit
jaddstr(newjson,"deposit",swap->deposit);
jaddbits256(newjson,"deposittxid",swap->deposittxid);
jaddstr(newjson,"deposit",swap->deposit->txbytes);
jaddbits256(newjson,"deposittxid",swap->deposit->txid);
}
else jaddstr(newjson,"error","couldnt create paymenttx");
return(newjson);
@ -635,31 +650,31 @@ cJSON *BOB_waitfeefunc(struct supernet_info *myinfo,struct exchange_info *exchan
return(0);
}
cJSON *BOB_waitprivMfunc(struct supernet_info *myinfo,struct exchange_info *exchange,struct instantdex_accept *ap,cJSON *argjson,cJSON *newjson,uint8_t **serdatap,int32_t *serdatalenp)
cJSON *BOB_waitprivMfunc(struct supernet_info *myinfo,struct exchange_info *exchange,struct bitcoin_swapinfo *swap,cJSON *argjson,cJSON *newjson,uint8_t **serdatap,int32_t *serdatalenp)
{
char *retstr; struct bitcoin_swapinfo *swap = ap->info;
char *retstr;
strcmp(swap->expectedcmdstr,"BTCprivM");
if ( swap->payment != 0 && (retstr= BTC_txconfirmed(myinfo,iguana_coinfind("BTC"),ap,newjson,swap->paymenttxid,&swap->paymentconfirms,"btcfound",0)) != 0 )
if ( swap->payment != 0 && (retstr= BTC_txconfirmed(myinfo,iguana_coinfind("BTC"),swap,newjson,swap->payment->txid,&swap->payment->numconfirms,"btcfound",0)) != 0 )
jaddstr(newjson,"btcfound",retstr);
printf("search for payment spend in blockchain\n");
*serdatap = 0, *serdatalenp = 0;
return(newjson);
}
cJSON *BOB_waitaltconfirmfunc(struct supernet_info *myinfo,struct exchange_info *exchange,struct instantdex_accept *ap,cJSON *argjson,cJSON *newjson,uint8_t **serdatap,int32_t *serdatalenp)
cJSON *BOB_waitaltconfirmfunc(struct supernet_info *myinfo,struct exchange_info *exchange,struct bitcoin_swapinfo *swap,cJSON *argjson,cJSON *newjson,uint8_t **serdatap,int32_t *serdatalenp)
{
char *retstr; struct bitcoin_swapinfo *swap = ap->info; struct iguana_info *altcoin; uint32_t reftime;
altcoin = iguana_coinfind(ap->offer.base);
char *retstr; struct iguana_info *altcoin; //uint32_t reftime;
altcoin = iguana_coinfind(swap->mine.offer.base);
*serdatap = 0, *serdatalenp = 0;
reftime = (uint32_t)(ap->offer.expiration - INSTANTDEX_LOCKTIME*2);
if ( altcoin != 0 && swap->altpayment != 0 && (retstr= BTC_txconfirmed(myinfo,altcoin,ap,newjson,swap->altpaymenttxid,&swap->altpaymentconfirms,"altfound",altcoin->chain->minconfirms)) != 0 )
//reftime = (uint32_t)(ap->offer.expiration - INSTANTDEX_LOCKTIME*2);
if ( altcoin != 0 && swap->altpayment != 0 && (retstr= BTC_txconfirmed(myinfo,altcoin,swap,newjson,swap->altpayment->txid,&swap->altpayment->numconfirms,"altfound",altcoin->chain->minconfirms)) != 0 )
{
jaddstr(newjson,"altfound",retstr);
if ( (swap->payment= instantdex_bobtx(myinfo,altcoin,&swap->deposittxid,swap->mypubs[1],swap->otherpubs[0],swap->privkeys[swap->otherschoosei],reftime,swap->satoshis[1],0)) != 0 )
if ( (swap->payment= instantdex_bobtx(myinfo,altcoin,&swap->payment->txid,swap->mypubs[1],swap->otherpubs[0],swap->privkeys[swap->otherchoosei],swap->reftime,swap->BTCsatoshis,0)) != 0 )
{
// broadcast payment
jaddstr(newjson,"payment",swap->payment);
jaddbits256(newjson,"paymenttxid",swap->paymenttxid);
jaddstr(newjson,"payment",swap->payment->txbytes);
jaddbits256(newjson,"paymenttxid",swap->payment->txid);
}
else jaddstr(newjson,"error","couldnt create paymenttx");
return(newjson);
@ -667,56 +682,56 @@ cJSON *BOB_waitaltconfirmfunc(struct supernet_info *myinfo,struct exchange_info
return(0);
}
cJSON *BTC_waitprivsfunc(struct supernet_info *myinfo,struct exchange_info *exchange,struct instantdex_accept *ap,cJSON *argjson,cJSON *newjson,uint8_t **serdatap,int32_t *serdatalenp)
cJSON *BTC_waitprivsfunc(struct supernet_info *myinfo,struct exchange_info *exchange,struct bitcoin_swapinfo *swap,cJSON *argjson,cJSON *newjson,uint8_t **serdatap,int32_t *serdatalenp)
{
*serdatap = 0, *serdatalenp = 0; struct bitcoin_swapinfo *swap = ap->info;
*serdatap = 0, *serdatalenp = 0;
strcmp(swap->expectedcmdstr,"BTCprivs");
instantdex_privkeyextract(myinfo,swap,*serdatap,*serdatalenp);
return(newjson);
}
cJSON *ALICE_waitfeefunc(struct supernet_info *myinfo,struct exchange_info *exchange,struct instantdex_accept *ap,cJSON *argjson,cJSON *newjson,uint8_t **serdatap,int32_t *serdatalenp)
cJSON *ALICE_waitfeefunc(struct supernet_info *myinfo,struct exchange_info *exchange,struct bitcoin_swapinfo *swap,cJSON *argjson,cJSON *newjson,uint8_t **serdatap,int32_t *serdatalenp)
{
char *retstr; struct iguana_info *coinbtc; struct bitcoin_swapinfo *swap = ap->info;
char *retstr; struct iguana_info *coinbtc;
coinbtc = iguana_coinfind("BTC");
*serdatap = 0, *serdatalenp = 0;
if ( swap->otherfeetx != 0 && (retstr= BTC_txconfirmed(myinfo,coinbtc,ap,newjson,swap->otherfeetxid,&swap->otherfeeconfirms,"feefound",0)) != 0 )
if ( swap->otherfee != 0 && (retstr= BTC_txconfirmed(myinfo,coinbtc,swap,newjson,swap->otherfee->txid,&swap->otherfee->numconfirms,"feefound",0)) != 0 )
{
jaddstr(newjson,"feefound",retstr);
return(newjson);
} else return(0);
}
cJSON *ALICE_waitdepositfunc(struct supernet_info *myinfo,struct exchange_info *exchange,struct instantdex_accept *ap,cJSON *argjson,cJSON *newjson,uint8_t **serdatap,int32_t *serdatalenp)
cJSON *ALICE_waitdepositfunc(struct supernet_info *myinfo,struct exchange_info *exchange,struct bitcoin_swapinfo *swap,cJSON *argjson,cJSON *newjson,uint8_t **serdatap,int32_t *serdatalenp)
{
char *retstr; struct iguana_info *coinbtc,*altcoin; struct bitcoin_swapinfo *swap = ap->info;
char *retstr; struct iguana_info *coinbtc,*altcoin;
coinbtc = iguana_coinfind("BTC");
altcoin = iguana_coinfind(ap->offer.rel);
altcoin = iguana_coinfind(swap->mine.offer.rel);
*serdatap = 0, *serdatalenp = 0;
if ( swap->deposit != 0 && (retstr= BTC_txconfirmed(myinfo,coinbtc,ap,newjson,swap->deposittxid,&swap->depositconfirms,"depfound",0.5)) != 0 )
if ( swap->deposit != 0 && (retstr= BTC_txconfirmed(myinfo,coinbtc,swap,newjson,swap->deposit->txid,&swap->deposit->numconfirms,"depfound",0.5)) != 0 )
{
jaddstr(newjson,"depfound",retstr);
if ( instantdex_paymentverify(myinfo,iguana_coinfind("BTC"),swap,ap,argjson,1) != 0 )
if ( instantdex_paymentverify(myinfo,iguana_coinfind("BTC"),swap,argjson,1) != 0 )
return(cJSON_Parse("{\"error\":\"deposit didnt verify\"}"));
if ( (swap->altpayment= instantdex_alicetx(myinfo,altcoin,swap->altmsigaddr,&swap->altpaymenttxid,swap->pubAm,swap->pubBn,swap->satoshis[0])) != 0 )
if ( (swap->altpayment= instantdex_alicetx(myinfo,altcoin,swap->altpayment->destaddr,&swap->altpayment->txid,swap->pubAm,swap->pubBn,swap->altsatoshis)) != 0 )
{
// broadcast altpayment
jaddstr(newjson,"altpayment",swap->altpayment);
jaddbits256(newjson,"altpaymenttxid",swap->altpaymenttxid);
jaddstr(newjson,"altpayment",swap->altpayment->txbytes);
jaddbits256(newjson,"altpaymenttxid",swap->altpayment->txid);
} else return(cJSON_Parse("{\"error\":\"couldnt create altpayment\"}"));
}
return(newjson);
}
cJSON *ALICE_waitpayconf_or_bobreclaimfunc(struct supernet_info *myinfo,struct exchange_info *exchange,struct instantdex_accept *ap,cJSON *argjson,cJSON *newjson,uint8_t **serdatap,int32_t *serdatalenp)
cJSON *ALICE_waitpayconf_or_bobreclaimfunc(struct supernet_info *myinfo,struct exchange_info *exchange,struct bitcoin_swapinfo *swap,cJSON *argjson,cJSON *newjson,uint8_t **serdatap,int32_t *serdatalenp)
{
char *retstr; double btcconfirms; struct iguana_info *coinbtc; struct bitcoin_swapinfo *swap = ap->info;
char *retstr; double btcconfirms; struct iguana_info *coinbtc;
coinbtc = iguana_coinfind("BTC");
*serdatap = 0, *serdatalenp = 0;
if ( swap->satoshis[1] < SATOSHIDEN/10 )
if ( swap->BTCsatoshis < SATOSHIDEN/10 )
btcconfirms = 0;
else btcconfirms = 1. + sqrt((double)swap->satoshis[1] / SATOSHIDEN);
if ( swap->payment != 0 && (retstr= BTC_txconfirmed(myinfo,coinbtc,ap,newjson,swap->paymenttxid,&swap->paymentconfirms,"payfound",btcconfirms)) != 0 )
else btcconfirms = 1. + sqrt((double)swap->BTCsatoshis / SATOSHIDEN);
if ( swap->payment != 0 && (retstr= BTC_txconfirmed(myinfo,coinbtc,swap,newjson,swap->payment->txid,&swap->payment->numconfirms,"payfound",btcconfirms)) != 0 )
{
jaddstr(newjson,"payfound",retstr);
// if bobreclaimed is there, then reclaim altpayment
@ -725,11 +740,20 @@ cJSON *ALICE_waitpayconf_or_bobreclaimfunc(struct supernet_info *myinfo,struct e
} else return(0);
}
cJSON *BTC_cleanupfunc(struct supernet_info *myinfo,struct exchange_info *exchange,struct instantdex_accept *ap,cJSON *argjson,cJSON *newjson,uint8_t **serdatap,int32_t *serdatalenp)
cJSON *BTC_cleanupfunc(struct supernet_info *myinfo,struct exchange_info *exchange,struct bitcoin_swapinfo *swap,cJSON *argjson,cJSON *newjson,uint8_t **serdatap,int32_t *serdatalenp)
{
*serdatap = 0, *serdatalenp = 0;
jaddstr(newjson,"error","need to cleanup");
swap->dead = (uint32_t)time(NULL);
swap->mine.dead = (uint32_t)time(NULL);
swap->other.dead = (uint32_t)time(NULL);
return(newjson);
}
cJSON *BTC_idlerecvfunc(struct supernet_info *myinfo,struct exchange_info *exchange,struct bitcoin_swapinfo *swap,cJSON *argjson,cJSON *newjson,uint8_t **serdatap,int32_t *serdatalenp)
{
*serdatap = 0, *serdatalenp = 0;
jaddstr(newjson,"error","need to cleanup");
ap->dead = (uint32_t)time(NULL);
return(newjson);
}
@ -791,6 +815,8 @@ struct instantdex_stateinfo *BTC_initFSM(int32_t *n)
// end terminal [BLOCKING] states
// need to create states before they can be referred to, that way a one pass FSM compile is possible
s = instantdex_statecreate(s,n,"BOB_gotoffer",BTC_waitprivCfunc,0,"BTC_cleanup",0,1);
s = instantdex_statecreate(s,n,"ALICE_gotoffer",BTC_waitprivCfunc,0,"BTC_cleanup",0,1);
s = instantdex_statecreate(s,n,"BOB_sentprivs",BTC_waitprivsfunc,0,"BTC_cleanup",0,0);
s = instantdex_statecreate(s,n,"BOB_waitfee",BOB_waitfeefunc,0,"BTC_cleanup",0,0);
s = instantdex_statecreate(s,n,"BOB_sentdeposit",BOB_waitBTCalttxfunc,0,"BOB_reclaimed",0,0);
@ -804,13 +830,14 @@ struct instantdex_stateinfo *BTC_initFSM(int32_t *n)
if ( 0 ) // following are implicit states and events handled externally to setup datastructures
{
//s = instantdex_statecreate(s,n,"BOB_idle",BTC_idlefunc,0,0,0);
//s = instantdex_statecreate(s,n,"ALICE_idle",BTC_idlefunc,0,0,0);
instantdex_addevent(s,*n,"BOB_idle","usrorder","BTCoffer","BOB_sentoffer"); // send deck
instantdex_addevent(s,*n,"ALICE_idle","usrorder","BTCoffer","ALICE_sentoffer");
instantdex_addevent(s,*n,"BOB_idle","BTCoffer","BTCdeckC","BOB_gotoffer"); // send deck + Chose
instantdex_addevent(s,*n,"ALICE_idle","BTCoffer","BTCdeckC","ALICE_gotoffer");
}
s = instantdex_statecreate(s,n,"BOB_idle",BTC_idlerecvfunc,0,"BTC_cleanup",0,1);
instantdex_addevent(s,*n,"BOB_idle","BTCoffer","BTCdeckC","BOB_gotoffer"); // send deck + Chose
s = instantdex_statecreate(s,n,"ALICE_idle",BTC_idlerecvfunc,0,"BTC_cleanup",0,1);
instantdex_addevent(s,*n,"ALICE_idle","BTCoffer","BTCdeckC","ALICE_gotoffer");
// after offer is sent, wait for other side to choose and sent their deck, then send privs
s = instantdex_statecreate(s,n,"BOB_sentoffer",BTC_waitdeckCfunc,0,"BTC_cleanup",0,1);
s = instantdex_statecreate(s,n,"ALICE_sentoffer",BTC_waitdeckCfunc,0,"BTC_cleanup",0,1);
@ -874,16 +901,16 @@ struct instantdex_stateinfo *BTC_initFSM(int32_t *n)
return(s);
}
char *instantdex_statemachine(struct instantdex_stateinfo *states,int32_t numstates,struct supernet_info *myinfo,struct exchange_info *exchange,struct instantdex_accept *A,char *cmdstr,cJSON *argjson,cJSON *newjson,uint8_t *serdata,int32_t serdatalen)
char *instantdex_statemachine(struct instantdex_stateinfo *states,int32_t numstates,struct supernet_info *myinfo,struct exchange_info *exchange,struct bitcoin_swapinfo *swap,char *cmdstr,cJSON *argjson,cJSON *newjson,uint8_t *serdata,int32_t serdatalen)
{
uint32_t i; struct iguana_info *altcoin,*coinbtc; struct bitcoin_swapinfo *swap; struct instantdex_stateinfo *state; cJSON *origjson = newjson;
if ( (swap= A->info) == 0 || (state= swap->state) == 0 || (coinbtc= iguana_coinfind("BTC")) == 0 || (altcoin= iguana_coinfind(A->offer.base)) == 0 )
uint32_t i; struct iguana_info *altcoin,*coinbtc; struct instantdex_stateinfo *state; cJSON *origjson = newjson;
if ( swap == 0 || (state= swap->state) == 0 || (coinbtc= iguana_coinfind("BTC")) == 0 || (altcoin= iguana_coinfind(swap->mine.offer.base)) == 0 )
return(clonestr("{\"error\":\"instantdex_BTCswap missing coin info\"}"));
printf("%llu/%llu cmd.(%s) state.(%s)\n",(long long)swap->bidid,(long long)swap->askid,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);
if ( swap->expiration != 0 && time(NULL) > swap->expiration )
{
swap->state = &states[state->timeoutind];
if ( (newjson= (*state->timeout)(myinfo,exchange,A,argjson,newjson,&serdata,&serdatalen)) == 0 )
if ( (newjson= (*state->timeout)(myinfo,exchange,swap,argjson,newjson,&serdata,&serdatalen)) == 0 )
return(clonestr("{\"error\":\"instantdex_BTCswap null return from timeoutfunc\"}"));
return(jprint(newjson,1));
}
@ -891,13 +918,13 @@ char *instantdex_statemachine(struct instantdex_stateinfo *states,int32_t numsta
{
if ( strcmp(cmdstr,state->events[i].cmdstr) == 0 )
{
if ( (newjson= (*state->process)(myinfo,exchange,A,argjson,newjson,&serdata,&serdatalen)) == 0 )
if ( (newjson= (*state->process)(myinfo,exchange,swap,argjson,newjson,&serdata,&serdatalen)) == 0 )
{
free_json(origjson);
if ( strcmp("poll",state->events[i].sendcmd) == 0 )
{
printf("poll event\n");
return(instantdex_sendcmd(myinfo,&A->offer,newjson,state->events[i].sendcmd,myinfo->myaddr.persistent,0,serdata,serdatalen));
return(instantdex_sendcmd(myinfo,&swap->mine.offer,newjson,state->events[i].sendcmd,myinfo->myaddr.persistent,0,serdata,serdatalen));
}
else
{
@ -913,7 +940,7 @@ char *instantdex_statemachine(struct instantdex_stateinfo *states,int32_t numsta
if ( state->events[i].nextstateind > 1 )
{
swap->state = &states[state->events[i].nextstateind];
return(instantdex_sendcmd(myinfo,&A->offer,newjson,state->events[i].sendcmd,swap->othertrader,INSTANTDEX_HOPS,serdata,serdatalen));
return(instantdex_sendcmd(myinfo,&swap->mine.offer,newjson,state->events[i].sendcmd,swap->othertrader,INSTANTDEX_HOPS,serdata,serdatalen));
} else return(clonestr("{\"error\":\"instantdex_statemachine: illegal state\"}"));
} else return(clonestr("{\"result\":\"instantdex_statemachine: processed\"}"));
}
@ -1124,7 +1151,7 @@ char *instantdex_advance(struct supernet_info *myinfo,bits256 *sharedprivs,int32
} else return(clonestr("{\"error\":\"instantdex_BTCswap advance cant find statusjson\"}"));
}
void instantdex_pendingnotice(struct supernet_info *myinfo,struct exchange_info *exchange,struct instantdex_accept *ap,uint64_t basevolume64)
void instantdex_pendingnotice(struct supernet_info *myinfo,struct exchange_info *exchange,struct bitcoin_swapinfo *swap,uint64_t basevolume64)
{
// printf("need to start monitoring thread\n");
ap->pendingvolume64 -= basevolume64;
@ -1133,7 +1160,7 @@ void instantdex_pendingnotice(struct supernet_info *myinfo,struct exchange_info
char *instantdex_BTCswap(struct supernet_info *myinfo,struct exchange_info *exchange,struct instantdex_accept *A,char *cmdstr,struct instantdex_msghdr *msg,cJSON *argjson,char *remoteaddr,uint64_t signerbits,uint8_t *data,int32_t datalen) // receiving side
{
uint8_t secret160[20]; bits256 hash,traderpub,A0,B0,sharedprivs[4]; uint64_t satoshis[2];
cJSON *newjson; struct instantdex_accept *ap; char *retstr=0,*str;
cJSON *newjson; char *retstr=0,*str;
int32_t locktime,isbob=0,offerdir = 0; struct iguana_info *coinbtc,*other;
if ( exchange == 0 )
return(clonestr("{\"error\":\"instantdex_BTCswap null exchange ptr\"}"));

Loading…
Cancel
Save