Browse Source

Test

etomic
jl777 8 years ago
parent
commit
3ee5c2f19a
  1. 2
      crypto777/OS_portable.h
  2. 51
      iguana/dpow/dpow_network.c
  3. 2357
      iguana/exchanges/LP_bitcoin.c
  4. 101
      iguana/exchanges/LP_commands.c
  5. 469
      iguana/exchanges/LP_include.h
  6. 97
      iguana/exchanges/LP_nativeDEX.c
  7. 307
      iguana/exchanges/LP_network.c
  8. 718
      iguana/exchanges/LP_remember.c
  9. 505
      iguana/exchanges/LP_rpc.c
  10. 186
      iguana/exchanges/LP_secp.c
  11. 558
      iguana/exchanges/LP_statemachine.c
  12. 2405
      iguana/exchanges/LP_swap.c
  13. 1657
      iguana/exchanges/LP_transaction.c
  14. 3
      iguana/m_mm

2
crypto777/OS_portable.h

@ -347,7 +347,7 @@ char *hmac_tiger_str(char *dest,char *key,int32_t key_size,char *message);
char *hmac_whirlpool_str(char *dest,char *key,int32_t key_size,char *message);
int nn_base64_encode(const uint8_t *in,size_t in_len,char *out,size_t out_len);
int nn_base64_decode(const char *in,size_t in_len,uint8_t *out,size_t out_len);
void calc_rmd160_sha256(uint8_t rmd160[20],uint8_t *data,int32_t datalen);
void sha256_sha256(char *hexstr,uint8_t *buf,uint8_t *msg,int32_t len);
void rmd160ofsha256(char *hexstr,uint8_t *buf,uint8_t *msg,int32_t len);
void calc_md5str(char *hexstr,uint8_t *buf,uint8_t *msg,int32_t len);

51
iguana/dpow/dpow_network.c

@ -145,10 +145,10 @@ int32_t signed_nn_send(struct supernet_info *myinfo,void *ctx,bits256 privkey,in
int32_t signed_nn_recv(void **freeptrp,struct supernet_info *myinfo,uint8_t notaries[64][33],int32_t n,int32_t sock,void *packetp)
{
int32_t i,recvbytes; uint8_t pubkey33[33],pubkey0[33]; bits256 packethash; struct signed_nnpacket *sigpacket=0;
int32_t i=0,recvbytes; uint8_t pubkey33[33],pubkey0[33]; bits256 packethash; struct signed_nnpacket *sigpacket=0;
*(void **)packetp = 0;
*freeptrp = 0;
for (i=0; i<100; i++)
/*for (i=0; i<100; i++)
{
struct nn_pollfd pfd;
pfd.fd = myinfo->reqsock;
@ -159,11 +159,11 @@ int32_t signed_nn_recv(void **freeptrp,struct supernet_info *myinfo,uint8_t nota
}
if ( i == 100 )
recvbytes = 0;
else if ( (recvbytes= nn_recv(sock,&sigpacket,NN_MSG,0)) > 0 )
else*/ if ( (recvbytes= nn_recv(sock,&sigpacket,NN_MSG,0)) > 0 )
{
//for (i=0; i<recvbytes; i++)
// printf("%02x",((uint8_t *)sigpacket)[i]);
//printf(" <- RECV.%d crc.%08x cmp.%d\n",recvbytes,calc_crc32(0,(void *)sigpacket,recvbytes),sigpacket->packetlen == recvbytes-sizeof(*sigpacket));
printf(" <- [%d] RECV.%d crc.%08x cmp.%d\n",i,recvbytes,calc_crc32(0,(void *)sigpacket,recvbytes),sigpacket->packetlen == recvbytes-sizeof(*sigpacket));
}
if ( sigpacket != 0 && recvbytes > sizeof(*sigpacket) && sigpacket->packetlen == recvbytes-sizeof(*sigpacket) )
{
@ -199,9 +199,9 @@ int32_t signed_nn_recv(void **freeptrp,struct supernet_info *myinfo,uint8_t nota
printf(" pubkey[%d]\n",i);
}
}
//for (i=0; i<33; i++)
// printf("%02x",pubkey33[i]);
//printf(" invalid pubkey33 n.%d\n",n);
for (i=0; i<33; i++)
printf("%02x",pubkey33[i]);
printf(" invalid pubkey33 n.%d\n",n);
} else printf("recoververify error nonce.%u packetlen.%d\n",sigpacket->nonce,sigpacket->packetlen);
} else printf("hash mismatch or bad nonce.%u packetlen.%d\n",sigpacket->nonce,sigpacket->packetlen);
} else if ( recvbytes > 0 )
@ -390,7 +390,7 @@ void dex_packet(struct supernet_info *myinfo,struct dex_nanomsghdr *dexp,int32_t
char *_dex_reqsend(struct supernet_info *myinfo,char *handler,uint8_t *key,int32_t keylen,uint8_t *data,int32_t datalen)
{
struct dex_nanomsghdr *dexp; cJSON *retjson; char ipaddr[64],str[128]; int32_t timeout,i,n,size,recvbytes,sentbytes = 0,reqsock,subsock; uint32_t *retptr,ipbits; void *freeptr; char *retstr = 0;
struct dex_nanomsghdr *dexp; cJSON *retjson; char ipaddr[64],str[128]; int32_t prio,timeout,i,n,size,recvbytes,sentbytes = 0,reqsock,subsock; uint32_t *retptr,ipbits; void *freeptr; char *retstr = 0;
portable_mutex_lock(&myinfo->dexmutex);
subsock = myinfo->subsock;
reqsock = myinfo->reqsock;
@ -400,15 +400,15 @@ char *_dex_reqsend(struct supernet_info *myinfo,char *handler,uint8_t *key,int32
{
timeout = 1000;
nn_setsockopt(reqsock,NN_SOL_SOCKET,NN_SNDTIMEO,&timeout,sizeof(timeout));
//timeout = 1500;
//nn_setsockopt(reqsock,NN_TCP,NN_RECONNECT_IVL,&timeout,sizeof(timeout));
timeout = 3000;
timeout = 1000;
nn_setsockopt(reqsock,NN_TCP,NN_RECONNECT_IVL,&timeout,sizeof(timeout));
timeout = 10000;
nn_setsockopt(reqsock,NN_SOL_SOCKET,NN_RCVTIMEO,&timeout,sizeof(timeout));
//prio = 1;
//nn_setsockopt(reqsock,NN_SOL_SOCKET,NN_SNDPRIO,&prio,sizeof(prio));
//nn_setsockopt(reqsock,NN_SOL_SOCKET,NN_RCVPRIO,&prio,sizeof(prio));
for (i=0; i<sizeof(myinfo->dexseed_ipaddrs)/sizeof(*myinfo->dexseed_ipaddrs); i++)
{
prio = (i/2) + 1;
nn_setsockopt(reqsock,NN_SOL_SOCKET,NN_SNDPRIO,&prio,sizeof(prio));
nn_setsockopt(reqsock,NN_SOL_SOCKET,NN_RCVPRIO,&prio,sizeof(prio));
if ( nn_connect(reqsock,nanomsg_tcpname(0,str,myinfo->dexseed_ipaddrs[i],REP_SOCK)) < 0 )
{
nn_close(reqsock);
@ -416,9 +416,6 @@ char *_dex_reqsend(struct supernet_info *myinfo,char *handler,uint8_t *key,int32
break;
}
}
//prio = 8;
//nn_setsockopt(reqsock,NN_SOL_SOCKET,NN_SNDPRIO,&prio,sizeof(prio));
//nn_setsockopt(reqsock,NN_SOL_SOCKET,NN_RCVPRIO,&prio,sizeof(prio));
}
if ( reqsock >= 0 )
{
@ -435,14 +432,14 @@ char *_dex_reqsend(struct supernet_info *myinfo,char *handler,uint8_t *key,int32
}
if ( reqsock >= 0 && subsock >= 0 )
{
timeout = 100;
timeout = 1;
nn_setsockopt(subsock,NN_SOL_SOCKET,NN_RCVTIMEO,&timeout,sizeof(timeout));
nn_setsockopt(subsock,NN_SUB,NN_SUB_SUBSCRIBE,"",0);
printf("CLIENT sockets req.%d sub.%d\n",reqsock,subsock);
//timeout = 5000;
//nn_setsockopt(reqsock,NN_TCP,NN_RECONNECT_IVL,&timeout,sizeof(timeout));
timeout = 10000;
nn_setsockopt(reqsock,NN_SOL_SOCKET,NN_RCVTIMEO,&timeout,sizeof(timeout));
//timeout = 10000;
//nn_setsockopt(reqsock,NN_SOL_SOCKET,NN_RCVTIMEO,&timeout,sizeof(timeout));
}
}
}
@ -481,7 +478,7 @@ char *_dex_reqsend(struct supernet_info *myinfo,char *handler,uint8_t *key,int32
if ( nn_poll(&pfd,1,100) > 0 )
{
sentbytes = nn_send(myinfo->reqsock,dexp,size,0);
//printf(" sent.%d:%d datalen.%d crc.%08x\n",sentbytes,size,datalen,calc_crc32(0,(void *)dexp,size));
printf(" [%d] sent.%d:%d datalen.%d crc.%08x\n",i,sentbytes,size,datalen,calc_crc32(0,(void *)dexp,size));
break;
}
usleep(1000);
@ -490,7 +487,7 @@ char *_dex_reqsend(struct supernet_info *myinfo,char *handler,uint8_t *key,int32
// printf("%02x",((uint8_t *)data)[i]);
if ( (recvbytes= signed_nn_recv(&freeptr,myinfo,myinfo->notaries,myinfo->numnotaries,myinfo->reqsock,&retptr)) >= 0 )
{
//printf("req returned.[%d]\n",recvbytes);
printf("req returned.[%d]\n",recvbytes);
portable_mutex_lock(&myinfo->dexmutex);
ipbits = 0;
if ( strcmp(handler,"DEX") == 0 )
@ -2163,11 +2160,11 @@ int32_t dpow_nanomsg_update(struct supernet_info *myinfo)
if ( (flags & 4) == 0 && (size= nn_recv(myinfo->repsock,&dexp,NN_MSG,0)) > 0 )
{
num2++;
//printf("REP got %d crc.%08x\n",size,calc_crc32(0,(void *)dexp,size));
printf("REP got %d crc.%08x\n",size,calc_crc32(0,(void *)dexp,size));
if ( (retstr= dex_response(&broadcastflag,myinfo,dexp)) != 0 )
{
signed_nn_send(myinfo,myinfo->ctx,myinfo->persistent_priv,myinfo->repsock,retstr,(int32_t)strlen(retstr)+1);
//printf("send back[%ld]\n",strlen(retstr)+1);
printf("send back[%ld]\n",strlen(retstr)+1);
free(retstr);
if ( broadcastflag != 0 )
{
@ -2182,11 +2179,11 @@ int32_t dpow_nanomsg_update(struct supernet_info *myinfo)
{
r = myinfo->dpowipbits[rand() % m];
signed_nn_send(myinfo,myinfo->ctx,myinfo->persistent_priv,myinfo->repsock,&r,sizeof(r));
//printf("REP.%08x <- rand ip m.%d %x\n",dexp->crc32,m,r);
printf("REP.%08x <- rand ip m.%d %x\n",dexp->crc32,m,r);
} else printf("illegal state without dpowipbits?\n");
if ( dex_packetcheck(myinfo,dexp,size) == 0 )
{
signed_nn_send(myinfo,myinfo->ctx,myinfo->persistent_priv,myinfo->dexsock,dexp,size);
//signed_nn_send(myinfo,myinfo->ctx,myinfo->persistent_priv,myinfo->dexsock,dexp,size);
//signed_nn_send(myinfo,myinfo->ctx,myinfo->persistent_priv,myinfo->pubsock,dexp,size);
//printf("REP.%08x -> dexbus and pub, t.%d lag.%d\n",dexp->crc32,dexp->timestamp,(int32_t)(time(NULL)-dexp->timestamp));
dex_packet(myinfo,dexp,size);
@ -2208,7 +2205,7 @@ int32_t dpow_nanomsg_update(struct supernet_info *myinfo)
} else break;
}
portable_mutex_unlock(&myinfo->dpowmutex);
return(num);
return(num+n+num2);
}
#else

2357
iguana/exchanges/LP_bitcoin.c

File diff suppressed because it is too large

101
iguana/exchanges/LP_commands.c

@ -18,18 +18,39 @@
// marketmaker
//
struct basilisk_request *LP_requestinit(struct basilisk_request *rp,bits256 srchash,bits256 desthash,char *src,uint64_t srcsatoshis,char *dest,uint64_t destsatoshis,uint32_t timestamp,uint32_t quotetime,int32_t DEXselector)
{
memset(rp,0,sizeof(*rp));
rp->srchash = srchash;
rp->desthash = desthash;
rp->srcamount = srcsatoshis;
rp->destamount = destsatoshis;
rp->timestamp = timestamp;
rp->quotetime = quotetime;
rp->DEXselector = DEXselector;
safecopy(rp->src,src,sizeof(rp->src));
safecopy(rp->dest,dest,sizeof(rp->dest));
rp->quoteid = basilisk_quoteid(rp);
rp->requestid = basilisk_requestid(rp);
return(rp);
}
void LP_command(struct LP_peerinfo *mypeer,int32_t pubsock,cJSON *argjson,uint8_t *data,int32_t datalen,double profitmargin)
{
char *method,*base,*rel,*retstr; cJSON *retjson; double price; bits256 txid; struct LP_utxoinfo *utxo;
char *method,*base,*rel,*retstr,*pairstr; cJSON *retjson; double price; bits256 srchash,desthash,pubkey,privkey,txid,desttxid; struct LP_utxoinfo *utxo; uint32_t timestamp,quotetime; int32_t destvout,DEXselector = 0; uint64_t txfee,satoshis,desttxfee,destsatoshis,value; struct basilisk_request R;
if ( (method= jstr(argjson,"method")) != 0 )
{
if ( strcmp(method,"price") == 0 || strcmp(method,"request") == 0 )
txid = jbits256(argjson,"txid");
if ( (utxo= LP_utxofind(txid,jint(argjson,"vout"))) != 0 && strcmp(utxo->ipaddr,mypeer->ipaddr) == 0 && utxo->port == mypeer->port && (base= jstr(argjson,"base")) != 0 && (rel= jstr(argjson,"rel")) != 0 && strcmp(base,utxo->coin) == 0 )
{
txid = jbits256(argjson,"txid");
if ( (utxo= LP_utxofind(txid)) != 0 && strcmp(utxo->ipaddr,mypeer->ipaddr) == 0 && utxo->port == mypeer->port && utxo->swappending == 0 )
if ( time(NULL) > utxo->swappending )
utxo->swappending = 0;
if ( strcmp(method,"price") == 0 || strcmp(method,"request") == 0 )
{
if ( (base= jstr(argjson,"base")) != 0 && (rel= jstr(argjson,"rel")) != 0 && strcmp(base,utxo->coin) == 0 )
if ( utxo->swappending == 0 && utxo->pair < 0 )
{
if ( utxo->pair >= 0 )
nn_close(utxo->pair), utxo->pair = -1;
if ( (price= LP_price(base,rel)) != 0. )
{
price *= (1. + profitmargin);
@ -39,11 +60,17 @@ void LP_command(struct LP_peerinfo *mypeer,int32_t pubsock,cJSON *argjson,uint8_
jaddnum(retjson,"timestamp",time(NULL));
jaddnum(retjson,"price",price);
jaddbits256(retjson,"txid",txid);
jadd64bits(retjson,"destsatoshis",price * utxo->satoshis);
pubkey = LP_pubkey(LP_privkey(utxo->coinaddr));
jaddbits256(retjson,"srchash",pubkey);
txfee = LP_txfee(base);
jadd64bits(retjson,"txfee",txfee);
jadd64bits(retjson,"satoshis",utxo->satoshis - txfee);
jadd64bits(retjson,"destsatoshis",price * (utxo->satoshis-txfee));
if ( strcmp(method,"request") == 0 )
{
utxo->swappending = (uint32_t)(time(NULL) + 60);
utxo->otherpubkey = jbits256(argjson,"pubkey");
jaddstr(retjson,"result","reserved");
jaddnum(retjson,"pending",utxo->swappending);
}
retstr = jprint(retjson,1);
@ -51,10 +78,64 @@ void LP_command(struct LP_peerinfo *mypeer,int32_t pubsock,cJSON *argjson,uint8_
}
}
}
}
else if ( )
{
else if ( strcmp(method,"connect") == 0 )
{
if ( utxo->pair < 0 )
{
if ( (price= LP_price(base,rel)) != 0. )
{
price *= (1. + profitmargin);
txfee = LP_txfee(base);
satoshis = j64bits(argjson,"satoshis");
desttxfee = LP_txfee(rel);
desttxid = jbits256(argjson,"desttxid");
destvout = jint(argjson,"destvout");
timestamp = juint(argjson,"timestamp");
quotetime = juint(argjson,"quotetime");
privkey = LP_privkey(utxo->coinaddr);
pubkey = LP_pubkey(privkey);
srchash = jbits256(argjson,"srchash");
value = j64bits(argjson,"destsatoshis");
if ( timestamp == utxo->swappending-60 && quotetime >= timestamp && quotetime < utxo->swappending && bits256_cmp(pubkey,srchash) == 0 && (destsatoshis= LP_txvalue(rel,desttxid,destvout)) > price*(utxo->satoshis-txfee)+desttxfee && value <= destsatoshis-desttxfee )
{
destsatoshis = value;
if ( (utxo->pair= nn_socket(AF_SP,NN_PAIR)) < 0 )
printf("error creating utxo->pair\n");
else if ( (pairstr= jstr(argjson,"pair")) != 0 && nn_connect(utxo->pair,pairstr) >= 0 )
{
desthash = jbits256(argjson,"desthash");
LP_requestinit(&R,srchash,desthash,base,satoshis,rel,destsatoshis,timestamp,quotetime,DEXselector);
if ( OS_thread_create(malloc(sizeof(pthread_t)),NULL,(void *)LP_bobloop,(void *)utxo) != 0 )
{
retjson = cJSON_CreateObject();
jaddstr(retjson,"result","connected");
jaddnum(retjson,"requestid",R.requestid);
jaddnum(retjson,"quoteid",R.quoteid);
retstr = jprint(retjson,1);
LP_send(pubsock,retstr,1);
utxo->swap = LP_swapinit(1,0,privkey,&R);
}
else
{
printf("error launching swaploop\n");
free(utxo->swap);
utxo->swap = 0;
nn_close(utxo->pair);
utxo->pair = -1;
}
}
else
{
if ( pairstr != 0 )
printf("printf error nn_connect to %s\n",pairstr);
else printf("(%s) missing pair\n",jprint(argjson,0));
nn_close(utxo->pair);
utxo->pair = -1;
}
} else printf("dest %.8f < required %.8f\n",dstr(value),dstr(price*(utxo->satoshis-txfee)));
} else printf("no price for %s/%s\n",base,rel);
} else printf("utxo->pair.%d when connect came in (%s)\n",utxo->pair,jprint(argjson,0));
}
}
}
}

469
iguana/exchanges/LP_include.h

@ -0,0 +1,469 @@
/******************************************************************************
* Copyright © 2014-2017 The SuperNET Developers. *
* *
* See the AUTHORS, DEVELOPER-AGREEMENT and LICENSE files at *
* the top-level directory of this distribution for the individual copyright *
* holder information and the developer policies on copyright and licensing. *
* *
* Unless otherwise agreed in a custom licensing agreement, no part of the *
* SuperNET software, including this file may be copied, modified, propagated *
* or distributed except according to the terms contained in the LICENSE file *
* *
* Removal or modification of this copyright notice is prohibited. *
* *
******************************************************************************/
//
// LP_include.h
// marketmaker
//
#ifndef LP_INCLUDE_H
#define LP_INCLUDE_H
#define BASILISK_DISABLEWAITTX
#define BASILISK_DISABLESENDTX
#define BASILISK_DEFAULT_NUMCONFIRMS 5
#define DEX_SLEEP 3
#define BASILISK_DEXDURATION 300
#define BASILISK_MSGDURATION 30
#define BASILISK_AUCTION_DURATION 5
#define BASILISK_MAXFUTUREBLOCK 60
#define BASILISK_KEYSIZE ((int32_t)(2*sizeof(bits256)+sizeof(uint32_t)*2))
extern char GLOBAL_DBDIR[];
void *bitcoin_ctx();
int32_t bitcoin_verify(void *ctx,uint8_t *sig,int32_t siglen,bits256 txhash2,uint8_t *pubkey,int32_t plen);
int32_t bitcoin_recoververify(void *ctx,char *symbol,uint8_t *sig,bits256 messagehash2,uint8_t *pubkey,size_t plen);
int32_t bitcoin_sign(void *ctx,char *symbol,uint8_t *sig,bits256 txhash2,bits256 privkey,int32_t recoverflag);
bits256 bitcoin_pubkey33(void *ctx,uint8_t *data,bits256 privkey);
bits256 bitcoin_pub256(void *ctx,bits256 *privkeyp,uint8_t odd_even);
char *bitcoin_base58encode(char *coinaddr,uint8_t *data,int32_t datalen);
int32_t bitcoin_base58decode(uint8_t *data,char *coinaddr);
#define IGUANA_MAXSCRIPTSIZE 10001
#define IGUANA_SEQUENCEID_FINAL 0xfffffffe
#define IGUANA_SCRIPT_NULL 0
#define IGUANA_SCRIPT_76AC 1
#define IGUANA_SCRIPT_76A988AC 2
#define IGUANA_SCRIPT_P2SH 3
#define IGUANA_SCRIPT_OPRETURN 4
#define IGUANA_SCRIPT_3of3 5
#define IGUANA_SCRIPT_2of3 6
#define IGUANA_SCRIPT_1of3 7
#define IGUANA_SCRIPT_2of2 8
#define IGUANA_SCRIPT_1of2 9
#define IGUANA_SCRIPT_MSIG 10
#define IGUANA_SCRIPT_DATA 11
#define IGUANA_SCRIPT_AC 12
#define IGUANA_SCRIPT_1of1 13
#define IGUANA_SCRIPT_STRANGE 15
#define BASILISK_TIMEOUT 3000
#define BASILISK_MINFANOUT 8
#define BASILISK_MAXFANOUT 64
#define BASILISK_DEFAULTDIFF 0x1effffff
#define BASILISK_HDROFFSET ((int32_t)(sizeof(bits256)+sizeof(struct iguana_msghdr)+sizeof(uint32_t)))
#define INSTANTDEX_DECKSIZE 1000
#define INSTANTDEX_LOCKTIME (3600*2 + 300*2)
#define INSTANTDEX_INSURANCEDIV 777
#define INSTANTDEX_PUBKEY "03bc2c7ba671bae4a6fc835244c9762b41647b9827d4780a89a949b984a8ddcc06"
#define INSTANTDEX_RMD160 "ca1e04745e8ca0c60d8c5881531d51bec470743f"
#define JUMBLR_RMD160 "5177f8b427e5f47342a4b8ab5dac770815d4389e"
#define TIERNOLAN_RMD160 "daedddd8dbe7a2439841ced40ba9c3d375f98146"
#define INSTANTDEX_BTC "1KRhTPvoxyJmVALwHFXZdeeWFbcJSbkFPu"
#define INSTANTDEX_BTCD "RThtXup6Zo7LZAi8kRWgjAyi1s4u6U9Cpf"
struct iguana_msgvin { bits256 prev_hash; uint8_t *vinscript,*userdata,*spendscript,*redeemscript; uint32_t prev_vout,sequence; uint16_t scriptlen,p2shlen,userdatalen,spendlen; };
struct iguana_msgvout { uint64_t value; uint32_t pk_scriptlen; uint8_t *pk_script; };
struct iguana_msgtx
{
uint32_t version,tx_in,tx_out,lock_time;
struct iguana_msgvin *vins;
struct iguana_msgvout *vouts;
bits256 txid;
int32_t allocsize,timestamp,numinputs,numoutputs;
int64_t inputsum,outputsum,txfee;
uint8_t *serialized;
};
struct vin_signer { bits256 privkey; char coinaddr[64]; uint8_t siglen,sig[80],rmd160[20],pubkey[66]; };
struct vin_info
{
struct iguana_msgvin vin; uint64_t amount; cJSON *extras; bits256 sigtxid;
int32_t M,N,validmask,spendlen,type,p2shlen,numpubkeys,numsigs,height,hashtype,userdatalen,suppress_pubkeys,ignore_cltverr;
uint32_t sequence,unspentind; struct vin_signer signers[16]; char coinaddr[65];
uint8_t rmd160[20],spendscript[IGUANA_MAXSCRIPTSIZE],p2shscript[IGUANA_MAXSCRIPTSIZE],userdata[IGUANA_MAXSCRIPTSIZE];
};
struct basilisk_swapmessage
{
bits256 srchash,desthash;
uint32_t crc32,msgbits,quoteid,datalen;
uint8_t *data;
};
struct basilisk_swap;
struct basilisk_rawtxinfo
{
char destaddr[64],coinstr[16];
bits256 txid,signedtxid,actualtxid;
uint64_t amount,change,inputsum;
int32_t redeemlen,datalen,completed,vintype,vouttype,numconfirms,spendlen,secretstart,suppress_pubkeys;
uint32_t locktime,crcs[2];
uint8_t addrtype,pubkey33[33],rmd160[20];
};
struct basilisk_request
{
uint32_t requestid,timestamp,quoteid,quotetime; // 0 to 15
uint64_t srcamount,unused; // 16 to 31
bits256 srchash; // 32 to 63
bits256 desthash;
char src[8],dest[8];
uint64_t destamount;
int32_t optionhours,DEXselector;
};
struct basilisk_rawtx
{
char name[32];
struct iguana_msgtx msgtx;
struct basilisk_rawtxinfo I;
struct iguana_info *coin;
char vinstr[8192],p2shaddr[64];
cJSON *vins;
bits256 utxotxid; int32_t utxovout;
uint8_t txbytes[16384],spendscript[512],redeemscript[1024],extraspace[4096],pubkey33[33];
};
struct basilisk_swapinfo
{
struct basilisk_request req;
char bobstr[64],alicestr[64];
bits256 myhash,otherhash,orderhash;
uint32_t statebits,otherstatebits,started,expiration,finished,dead,reftime,putduration,callduration;
int32_t bobconfirms,aliceconfirms,iambob,reclaimed,bobspent,alicespent,pad;
uint64_t alicesatoshis,bobsatoshis,bobinsurance,aliceinsurance;
bits256 myprivs[2],mypubs[2],otherpubs[2],pubA0,pubA1,pubB0,pubB1,privAm,pubAm,privBn,pubBn;
uint32_t crcs_mypub[2],crcs_mychoosei[2],crcs_myprivs[2],crcs_mypriv[2];
int32_t choosei,otherchoosei,cutverified,otherverifiedcut,numpubs,havestate,otherhavestate,pad2;
uint8_t secretAm[20],secretBn[20];
uint8_t secretAm256[32],secretBn256[32];
uint8_t userdata_aliceclaim[256],userdata_aliceclaimlen;
uint8_t userdata_alicereclaim[256],userdata_alicereclaimlen;
uint8_t userdata_alicespend[256],userdata_alicespendlen;
uint8_t userdata_bobspend[256],userdata_bobspendlen;
uint8_t userdata_bobreclaim[256],userdata_bobreclaimlen;
uint8_t userdata_bobrefund[256],userdata_bobrefundlen;
};
struct iguana_info
{
uint64_t txfee,estimatedfee;
int32_t longestchain;
uint8_t pubtype,p2shtype,isPoS,wiftype;
char symbol[16],changeaddr[64];
};
struct basilisk_swap
{
void *ctx; struct iguana_info bobcoin,alicecoin;
void (*balancingtrade)(struct basilisk_swap *swap,int32_t iambob);
int32_t subsock,pushsock,connected,aliceunconf,depositunconf,paymentunconf; uint32_t lasttime,aborted;
FILE *fp;
bits256 persistent_privkey,persistent_pubkey;
struct basilisk_swapinfo I;
struct basilisk_rawtx bobdeposit,bobpayment,alicepayment,myfee,otherfee,aliceclaim,alicespend,bobreclaim,bobspend,bobrefund,alicereclaim;
bits256 privkeys[INSTANTDEX_DECKSIZE];
struct basilisk_swapmessage *messages; int32_t nummessages;
char Bdeposit[64],Bpayment[64];
uint64_t otherdeck[INSTANTDEX_DECKSIZE][2],deck[INSTANTDEX_DECKSIZE][2];
uint8_t persistent_pubkey33[33],pad[15],verifybuf[65536];
};
static struct bitcoin_opcode { UT_hash_handle hh; uint8_t opcode,flags,stackitems; int8_t extralen; } *OPTABLE; static char *OPCODES[0x100]; static int32_t OPCODELENS[0x100];
#define SIGHASH_ALL 1
#define SIGHASH_NONE 2
#define SIGHASH_SINGLE 3
#define SIGHASH_ANYONECANPAY 0x80
#define SCRIPT_OP_NOP 0x00
#define SCRIPT_OP_TRUE 0x51
#define SCRIPT_OP_2 0x52
#define SCRIPT_OP_3 0x53
#define SCRIPT_OP_4 0x54
#define SCRIPT_OP_IF 0x63
#define SCRIPT_OP_ELSE 0x67
#define SCRIPT_OP_RETURN 0x6a
#define SCRIPT_OP_DUP 0x76
#define SCRIPT_OP_ENDIF 0x68
#define SCRIPT_OP_DROP 0x75
#define SCRIPT_OP_EQUALVERIFY 0x88
#define SCRIPT_OP_SHA256 0xa8
#define SCRIPT_OP_HASH160 0xa9
#define SCRIPT_OP_EQUAL 0x87
#define SCRIPT_OP_CHECKSIG 0xac
#define SCRIPT_OP_CHECKMULTISIG 0xae
#define SCRIPT_OP_CHECKSEQUENCEVERIFY 0xb2
#define SCRIPT_OP_CHECKLOCKTIMEVERIFY 0xb1
#define IGUANA_OP_0 0x00
#define IGUANA_OP_PUSHDATA1 0x4c
#define IGUANA_OP_PUSHDATA2 0x4d
#define IGUANA_OP_PUSHDATA4 0x4e
#define IGUANA_OP_1NEGATE 0x4f
#define IGUANA_OP_1 0x51
#define IGUANA_OP_16 0x60
#define IGUANA_OP_NOP 0x61
#define IGUANA_OP_IF 0x63
#define IGUANA_OP_NOTIF 0x64
#define IGUANA_OP_ELSE 0x67
#define IGUANA_OP_ENDIF 0x68
#define IGUANA_OP_VERIFY 0x69
#define IGUANA_OP_RETURN 0x6a
#define IGUANA_OP_TOALTSTACK 0x6b
#define IGUANA_OP_FROMALTSTACK 0x6c
#define IGUANA_OP_2DROP 0x6d
#define IGUANA_OP_2DUP 0x6e
#define IGUANA_OP_3DUP 0x6f
#define IGUANA_OP_2OVER 0x70
#define IGUANA_OP_2ROT 0x71
#define IGUANA_OP_2SWAP 0x72
#define IGUANA_OP_IFDUP 0x73
#define IGUANA_OP_DEPTH 0x74
#define IGUANA_OP_DROP 0x75
#define IGUANA_OP_DUP 0x76
#define IGUANA_OP_NIP 0x77
#define IGUANA_OP_OVER 0x78
#define IGUANA_OP_PICK 0x79
#define IGUANA_OP_ROLL 0x7a
#define IGUANA_OP_ROT 0x7b
#define IGUANA_OP_SWAP 0x7c
#define IGUANA_OP_TUCK 0x7d
#define IGUANA_OP_EQUAL 0x87
#define IGUANA_OP_EQUALVERIFY 0x88
#define IGUANA_OP_1ADD 0x8b
#define IGUANA_OP_1SUB 0x8c
#define IGUANA_OP_NEGATE 0x8f
#define IGUANA_OP_ABS 0x90
#define IGUANA_OP_NOT 0x91
#define IGUANA_OP_0NOTEQUAL 0x92
#define IGUANA_OP_ADD 0x93
#define IGUANA_OP_SUB 0x94
#define IGUANA_OP_BOOLAND 0x9a
#define IGUANA_OP_BOOLOR 0x9b
#define IGUANA_OP_NUMEQUAL 0x9c
#define IGUANA_OP_NUMEQUALVERIFY 0x9d
#define IGUANA_OP_NUMNOTEQUAL 0x9e
#define IGUANA_OP_LESSTHAN 0x9f
#define IGUANA_OP_GREATERTHAN 0xa0
#define IGUANA_OP_LESSTHANOREQUAL 0xa1
#define IGUANA_OP_GREATERTHANOREQUAL 0xa2
#define IGUANA_OP_MIN 0xa3
#define IGUANA_OP_MAX 0xa4
#define IGUANA_OP_WITHIN 0xa5
#define IGUANA_OP_RIPEMD160 0xa6
#define IGUANA_OP_SHA1 0xa7
#define IGUANA_OP_SHA256 0xa8
#define IGUANA_OP_HASH160 0xa9
#define IGUANA_OP_HASH256 0xaa
#define IGUANA_OP_CODESEPARATOR 0xab
#define IGUANA_OP_CHECKSIG 0xac
#define IGUANA_OP_CHECKSIGVERIFY 0xad
#define IGUANA_OP_CHECKMULTISIG 0xae
#define IGUANA_OP_CHECKMULTISIGVERIFY 0xaf
#define IGUANA_OP_NOP1 0xb0
#define IGUANA_OP_CHECKLOCKTIMEVERIFY 0xb1
#define IGUANA_OP_CHECKSEQUENCEVERIFY 0xb2
#define IGUANA_OP_NOP10 0xb9
#define IGUANA_OP_COMBINEPUBKEYS 0xc0
#define IGUANA_OP_CHECKSCHNORR 0xc1
#define IGUANA_OP_CHECKSCHNORRVERIFY 0xc2
// https://github.com/TierNolan/bips/blob/cpkv/bip-cprkv.mediawiki
#define IGUANA_OP_CHECKPRIVATEKEY 0xc3
#define IGUANA_OP_CHECKPRIVATEKEYVERIFY 0xc4
#define IGUANA_NOPFLAG 1
#define IGUANA_ALWAYSILLEGAL 2
#define IGUANA_EXECUTIONILLEGAL 4
#define IGUANA_POSTVERIFY 8
#define IGUANA_CRYPTOFLAG 16
#define IGUANA_MATHFLAG 32
#define IGUANA_CONTROLFLAG 64
#define IGUANA_STACKFLAG 128
enum opcodetype
{
// push value
OP_0 = 0x00,
OP_FALSE = OP_0,
OP_PUSHDATA1 = 0x4c,
OP_PUSHDATA2 = 0x4d,
OP_PUSHDATA4 = 0x4e,
OP_1NEGATE = 0x4f,
OP_RESERVED = 0x50,
OP_1 = 0x51,
OP_TRUE=OP_1,
OP_2 = 0x52,
OP_3 = 0x53,
OP_4 = 0x54,
OP_5 = 0x55,
OP_6 = 0x56,
OP_7 = 0x57,
OP_8 = 0x58,
OP_9 = 0x59,
OP_10 = 0x5a,
OP_11 = 0x5b,
OP_12 = 0x5c,
OP_13 = 0x5d,
OP_14 = 0x5e,
OP_15 = 0x5f,
OP_16 = 0x60,
// control
OP_NOP = 0x61,
OP_VER = 0x62,
OP_IF = 0x63,
OP_NOTIF = 0x64,
OP_VERIF = 0x65,
OP_VERNOTIF = 0x66,
OP_ELSE = 0x67,
OP_ENDIF = 0x68,
OP_VERIFY = 0x69,
OP_RETURN = 0x6a,
// stack ops
OP_TOALTSTACK = 0x6b,
OP_FROMALTSTACK = 0x6c,
OP_2DROP = 0x6d,
OP_2DUP = 0x6e,
OP_3DUP = 0x6f,
OP_2OVER = 0x70,
OP_2ROT = 0x71,
OP_2SWAP = 0x72,
OP_IFDUP = 0x73,
OP_DEPTH = 0x74,
OP_DROP = 0x75,
OP_DUP = 0x76,
OP_NIP = 0x77,
OP_OVER = 0x78,
OP_PICK = 0x79,
OP_ROLL = 0x7a,
OP_ROT = 0x7b,
OP_SWAP = 0x7c,
OP_TUCK = 0x7d,
// splice ops
OP_CAT = 0x7e,
OP_SUBSTR = 0x7f,
OP_LEFT = 0x80,
OP_RIGHT = 0x81,
OP_SIZE = 0x82,
// bit logic
OP_INVERT = 0x83,
OP_AND = 0x84,
OP_OR = 0x85,
OP_XOR = 0x86,
OP_EQUAL = 0x87,
OP_EQUALVERIFY = 0x88,
OP_RESERVED1 = 0x89,
OP_RESERVED2 = 0x8a,
// numeric
OP_1ADD = 0x8b,
OP_1SUB = 0x8c,
OP_2MUL = 0x8d,
OP_2DIV = 0x8e,
OP_NEGATE = 0x8f,
OP_ABS = 0x90,
OP_NOT = 0x91,
OP_0NOTEQUAL = 0x92,
OP_ADD = 0x93,
OP_SUB = 0x94,
OP_MUL = 0x95,
OP_DIV = 0x96,
OP_MOD = 0x97,
OP_LSHIFT = 0x98,
OP_RSHIFT = 0x99,
OP_BOOLAND = 0x9a,
OP_BOOLOR = 0x9b,
OP_NUMEQUAL = 0x9c,
OP_NUMEQUALVERIFY = 0x9d,
OP_NUMNOTEQUAL = 0x9e,
OP_LESSTHAN = 0x9f,
OP_GREATERTHAN = 0xa0,
OP_LESSTHANOREQUAL = 0xa1,
OP_GREATERTHANOREQUAL = 0xa2,
OP_MIN = 0xa3,
OP_MAX = 0xa4,
OP_WITHIN = 0xa5,
// crypto
OP_RIPEMD160 = 0xa6,
OP_SHA1 = 0xa7,
OP_SHA256 = 0xa8,
OP_HASH160 = 0xa9,
OP_HASH256 = 0xaa,
OP_CODESEPARATOR = 0xab,
OP_CHECKSIG = 0xac,
OP_CHECKSIGVERIFY = 0xad,
OP_CHECKMULTISIG = 0xae,
OP_CHECKMULTISIGVERIFY = 0xaf,
// expansion
OP_NOP1 = 0xb0,
OP_CHECKLOCKTIMEVERIFY = 0xb1,
OP_CHECKSEQUENCEVERIFY = 0xb2,
OP_NOP4 = 0xb3,
OP_NOP5 = 0xb4,
OP_NOP6 = 0xb5,
OP_NOP7 = 0xb6,
OP_NOP8 = 0xb7,
OP_NOP9 = 0xb8,
OP_NOP10 = 0xb9,
OP_COMBINEPUBKEYS = 0xc0,
OP_CHECKSCHNORR = 0xc1,
OP_CHECKSCHNORRVERIFY = 0xc2,
OP_CHECKPRIVATEKEY = 0xc3,
OP_CHECKPRIVATEKEYVERIFY = 0xc4,
// template matching params
//OP_SMALLINTEGER = 0xfa,
//OP_PUBKEYS = 0xfb,
//OP_PUBKEYHASH = 0xfd,
//OP_PUBKEY = 0xfe,
OP_INVALIDOPCODE = 0xff,
};
void basilisk_dontforget_update(struct basilisk_swap *swap,struct basilisk_rawtx *rawtx);
uint32_t basilisk_requestid(struct basilisk_request *rp);
uint32_t basilisk_quoteid(struct basilisk_request *rp);
#endif

97
iguana/exchanges/LP_nativeDEX.c

@ -14,11 +14,13 @@
* *
******************************************************************************/
//
// LP_unspents.c
// LP_nativeDEX.c
// marketmaker
//
#include <stdio.h>
#include "LP_include.h"
#include "LP_network.c"
#define LP_PROPAGATION_SLACK 10 // txid ordering is not enforced, so getting extra recent txid
@ -43,41 +45,13 @@ struct LP_utxoinfo
bits256 txid,deposittxid,otherpubkey;
void *swap;
uint64_t satoshis,depositsatoshis;
int32_t vout,depositvout; uint32_t lasttime,errors,swappending;
uint8_t key[sizeof(bits256) + sizeof(int32_t)];
int32_t vout,depositvout,pair; uint32_t lasttime,errors,swappending;
double profitmargin;
char ipaddr[64],coinaddr[64],spendscript[256],coin[16];
uint16_t port;
} *LP_utxoinfos;
char *nanomsg_tcpname(char *str,char *ipaddr,uint16_t port)
{
sprintf(str,"tcp://%s:%u",ipaddr,port);
return(str);
}
int32_t LP_send(int32_t sock,char *msg,int32_t freeflag)
{
int32_t sentbytes,len,i; struct nn_pollfd pfd;
for (i=0; i<100; i++)
{
pfd.fd = sock;
pfd.events = NN_POLLOUT;
if ( nn_poll(&pfd,1,100) > 0 )
{
len = (int32_t)strlen(msg) + 1;
if ( (sentbytes= nn_send(sock,msg,len,0)) != len )
printf("LP_send sent %d instead of %d\n",sentbytes,len);
else printf("SENT.(%s)\n",msg);
if ( freeflag != 0 )
free(msg);
return(sentbytes);
}
usleep(1000);
}
printf("error LP_send\n");
return(-1);
}
struct LP_peerinfo *LP_peerfind(uint32_t ipbits,uint16_t port)
{
struct LP_peerinfo *peer=0; uint64_t ip_port;
@ -88,11 +62,13 @@ struct LP_peerinfo *LP_peerfind(uint32_t ipbits,uint16_t port)
return(peer);
}
struct LP_utxoinfo *LP_utxofind(bits256 txid)
struct LP_utxoinfo *LP_utxofind(bits256 txid,int32_t vout)
{
struct LP_utxoinfo *utxo=0;
struct LP_utxoinfo *utxo=0; uint8_t key[sizeof(txid) + sizeof(vout)];
memcpy(key,txid.bytes,sizeof(txid));
memcpy(&key[sizeof(txid)],&vout,sizeof(vout));
portable_mutex_lock(&LP_utxomutex);
HASH_FIND(hh,LP_utxoinfos,&txid,sizeof(txid),utxo);
HASH_FIND(hh,LP_utxoinfos,key,sizeof(key),utxo);
portable_mutex_unlock(&LP_utxomutex);
return(utxo);
}
@ -214,13 +190,13 @@ struct LP_peerinfo *LP_addpeer(struct LP_peerinfo *mypeer,int32_t mypubsock,char
struct LP_utxoinfo *LP_addutxo(struct LP_peerinfo *mypeer,int32_t mypubsock,char *coin,bits256 txid,int32_t vout,int64_t satoshis,bits256 deposittxid,int32_t depositvout,int64_t depositsatoshis,char *spendscript,char *coinaddr,char *ipaddr,uint16_t port,double profitmargin)
{
struct LP_utxoinfo *utxo = 0;
struct LP_utxoinfo *utxo = 0; uint8_t key[sizeof(txid) + sizeof(vout)];
if ( coin == 0 || coin[0] == 0 || spendscript == 0 || spendscript[0] == 0 || coinaddr == 0 || coinaddr[0] == 0 || bits256_nonz(txid) == 0 || bits256_nonz(deposittxid) == 0 || vout < 0 || depositvout < 0 || satoshis <= 0 || depositsatoshis <= 0 )
{
printf("malformed addutxo %d %d %d %d %d %d %d %d %d %d %d %d\n", coin == 0,coin[0] == 0,spendscript == 0,spendscript[0] == 0,coinaddr == 0,coinaddr[0] == 0,bits256_nonz(txid) == 0,bits256_nonz(deposittxid) == 0,vout < 0,depositvout < 0,satoshis <= 0,depositsatoshis <= 0);
return(0);
}
if ( (utxo= LP_utxofind(txid)) != 0 )
if ( (utxo= LP_utxofind(txid,vout)) != 0 )
{
if ( bits256_cmp(txid,utxo->txid) != 0 || bits256_cmp(deposittxid,utxo->deposittxid) != 0 || vout != utxo->vout || satoshis != utxo->satoshis || depositvout != utxo->depositvout || depositsatoshis != utxo->depositsatoshis || strcmp(coin,utxo->coin) != 0 || strcmp(spendscript,utxo->spendscript) != 0 || strcmp(coinaddr,utxo->coinaddr) != 0 || strcmp(ipaddr,utxo->ipaddr) != 0 || port != utxo->port )
{
@ -233,6 +209,7 @@ struct LP_utxoinfo *LP_addutxo(struct LP_peerinfo *mypeer,int32_t mypubsock,char
else
{
utxo = calloc(1,sizeof(*utxo));
utxo->pair = -1;
utxo->profitmargin = profitmargin;
strcpy(utxo->ipaddr,ipaddr);
utxo->port = port;
@ -245,8 +222,11 @@ struct LP_utxoinfo *LP_addutxo(struct LP_peerinfo *mypeer,int32_t mypubsock,char
utxo->deposittxid = deposittxid;
utxo->depositvout = depositvout;
utxo->depositsatoshis = depositsatoshis;
memcpy(key,txid.bytes,sizeof(txid));
memcpy(&key[sizeof(txid)],&vout,sizeof(vout));
memcpy(utxo->key,key,sizeof(key));
portable_mutex_lock(&LP_utxomutex);
HASH_ADD(hh,LP_utxoinfos,txid,sizeof(txid),utxo);
HASH_ADD(hh,LP_utxoinfos,key,sizeof(key),utxo);
if ( mypeer != 0 )
{
mypeer->numutxos++;
@ -525,9 +505,50 @@ uint64_t LP_privkey_init(struct LP_peerinfo *mypeer,int32_t mypubsock,char *coin
return(total);
}
int32_t basilisk_istrustedbob(struct basilisk_swap *swap)
{
// for BTC and if trusted LP
return(0);
}
struct iguana_info KMDcoin,BTCcoin,LTCcoin;
struct iguana_info *LP_coinfind(char *symbol)
{
struct iguana_info *coin;
if ( strcmp(symbol,"BTC") == 0 )
return(&BTCcoin);
else if ( strcmp(symbol,"LTC") == 0 )
return(&LTCcoin);
else //if ( strcmp(symbol,"KMD") == 0 )
{
coin = calloc(1,sizeof(*coin));
*coin = KMDcoin;
strcpy(coin->symbol,symbol);
return(coin);
}
}
void tradebot_swap_balancingtrade(struct basilisk_swap *swap,int32_t iambob)
{
}
void tradebot_pendingadd(cJSON *tradejson,char *base,double basevolume,char *rel,double relvolume)
{
// add to trades
}
char GLOBAL_DBDIR[] = ".";
#include "LP_secp.c"
#include "LP_rpc.c"
#include "LP_bitcoin.c"
#include "LP_swap.c"
#include "LP_transaction.c"
#include "LP_remember.c"
#include "LP_statemachine.c"
#include "LP_swap.c"
#include "LP_commands.c"
void LPinit(uint16_t myport,uint16_t mypull,uint16_t mypub,double profitmargin)

307
iguana/exchanges/LP_network.c

@ -0,0 +1,307 @@
/******************************************************************************
* Copyright © 2014-2017 The SuperNET Developers. *
* *
* See the AUTHORS, DEVELOPER-AGREEMENT and LICENSE files at *
* the top-level directory of this distribution for the individual copyright *
* holder information and the developer policies on copyright and licensing. *
* *
* Unless otherwise agreed in a custom licensing agreement, no part of the *
* SuperNET software, including this file may be copied, modified, propagated *
* or distributed except according to the terms contained in the LICENSE file *
* *
* Removal or modification of this copyright notice is prohibited. *
* *
******************************************************************************/
//
// LP_network.c
// marketmaker
//
void basilisk_psockinit(struct basilisk_swap *swap,int32_t amlp)
{
/* char keystr[64],databuf[1024],pubkeystr[128],*retstr,*retstr2,*datastr,*pushaddr=0,*subaddr=0; cJSON *retjson,*addrjson; uint8_t data[512]; int32_t datalen,timeout,pushsock = -1,subsock = -1;
if ( swap->connected == 1 )
return;
if ( swap->pushsock < 0 && swap->subsock < 0 && (pushsock= nn_socket(AF_SP,NN_PUSH)) >= 0 && (subsock= nn_socket(AF_SP,NN_SUB)) >= 0 )
{
timeout = 1000;
nn_setsockopt(pushsock,NN_SOL_SOCKET,NN_SNDTIMEO,&timeout,sizeof(timeout));
timeout = 1;
nn_setsockopt(subsock,NN_SOL_SOCKET,NN_RCVTIMEO,&timeout,sizeof(timeout));
nn_setsockopt(subsock,NN_SUB,NN_SUB_SUBSCRIBE,"",0);
swap->pushsock = pushsock;
swap->subsock = subsock;
}
if ( (subsock= swap->subsock) < 0 || (pushsock= swap->pushsock) < 0 )
{
printf("error getting nn_sockets\n");
return;
}
sprintf(keystr,"%08x-%08x",swap->I.req.requestid,swap->I.req.quoteid);
if ( swap->connected == 0 && (retstr= _dex_kvsearch("KV",keystr)) != 0 )
{
if ( (retjson= cJSON_Parse(retstr)) != 0 )
{
if ( (datastr= jstr(retjson,"value")) != 0 )
{
datalen = (int32_t)strlen(datastr) >> 1;
decode_hex((uint8_t *)databuf,datalen,datastr);
if ( (addrjson= cJSON_Parse(databuf)) != 0 )
{
pushaddr = jstr(addrjson,"push");
subaddr = jstr(addrjson,"sub");
if ( pushaddr != 0 && subaddr != 0 )
{
printf("KV decoded (%s and %s) %d %d\n",pushaddr,subaddr,swap->pushsock,swap->subsock);
if ( nn_connect(swap->pushsock,pushaddr) >= 0 && nn_connect(swap->subsock,subaddr) >= 0 )
swap->connected = 1;
}
free_json(addrjson);
}
}
free_json(retjson);
}
printf("KVsearch.(%s) -> (%s) connected.%d socks.(%d %d) amlp.%d\n",keystr,retstr,swap->connected,swap->pushsock,swap->subsock,amlp);
free(retstr);
}
printf("connected.%d amlp.%d subsock.%d pushsock.%d\n",swap->connected,amlp,subsock,pushsock);
if ( swap->connected <= 0 && amlp != 0 && subsock >= 0 && pushsock >= 0 )
{
if ( (retstr= _dex_psock("{}")) != 0 )
{
printf("psock returns.(%s)\n",retstr);
// {"result":"success","pushaddr":"tcp://5.9.102.210:30002","subaddr":"tcp://5.9.102.210:30003","randipbits":3606291758,"coin":"KMD","tag":"6952562460568228137"}
if ( (retjson= cJSON_Parse(retstr)) != 0 )
{
pushaddr = jstr(retjson,"pushaddr");
subaddr = jstr(retjson,"subaddr");
if ( pushaddr != 0 && subaddr != 0 )
{
if ( nn_connect(pushsock,pushaddr) >= 0 )
{
printf("connected to %d pushaddr.(%s)\n",pushsock,pushaddr);
if ( nn_connect(subsock,subaddr) >= 0 )
{
swap->connected = 1;
init_hexbytes_noT(pubkeystr,myinfo->persistent_pubkey33,33);
sprintf((char *)data,"{\"push\":\"%s\",\"sub\":\"%s\",\"trade\":[\"%s\", %.8f, \"%s\", %.8f],\"pub\":\"%s\"}",pushaddr,subaddr,swap->I.req.src,dstr(swap->I.req.srcamount),swap->I.req.dest,dstr(swap->I.req.destamount),pubkeystr);
datalen = (int32_t)strlen((char *)data) + 1;
printf("datalen.%d (%s)\n",datalen,(char *)data);
init_hexbytes_noT(databuf,data,datalen);
printf("%s -> %s\n",keystr,databuf);
if ( (retstr2= _dex_kvupdate("KV",keystr,databuf,1)) != 0 )
{
printf("KVupdate.(%s)\n",retstr2);
free(retstr2);
}
} else printf("nn_connect error to %d subaddr.(%s)\n",subsock,subaddr);
} else printf("nn_connect error to %d pushaddr.(%s)\n",pushsock,pushaddr);
}
else printf("missing addr (%p) (%p) (%s)\n",pushaddr,subaddr,jprint(retjson,0));
free_json(retjson);
} else printf("Error parsing psock.(%s)\n",retstr);
free(retstr);
} else printf("error issuing _dex_psock\n");
}*/
}
char *nanomsg_tcpname(char *str,char *ipaddr,uint16_t port)
{
sprintf(str,"tcp://%s:%u",ipaddr,port);
return(str);
}
int32_t LP_send(int32_t sock,char *msg,int32_t freeflag)
{
int32_t sentbytes,len,i; struct nn_pollfd pfd;
for (i=0; i<100; i++)
{
pfd.fd = sock;
pfd.events = NN_POLLOUT;
if ( nn_poll(&pfd,1,100) > 0 )
{
len = (int32_t)strlen(msg) + 1;
if ( (sentbytes= nn_send(sock,msg,len,0)) != len )
printf("LP_send sent %d instead of %d\n",sentbytes,len);
else printf("SENT.(%s)\n",msg);
if ( freeflag != 0 )
free(msg);
return(sentbytes);
}
usleep(1000);
}
printf("error LP_send\n");
return(-1);
}
uint32_t LP_swapsend(struct basilisk_swap *swap,uint32_t msgbits,uint8_t *data,int32_t datalen,uint32_t nextbits,uint32_t crcs[2])
{
uint8_t *buf; int32_t sentbytes,offset=0,i;
buf = malloc(datalen + sizeof(msgbits) + sizeof(swap->I.req.quoteid) + sizeof(bits256)*2);
for (i=0; i<32; i++)
buf[offset++] = swap->I.myhash.bytes[i];
for (i=0; i<32; i++)
buf[offset++] = swap->I.otherhash.bytes[i];
offset += iguana_rwnum(1,&buf[offset],sizeof(swap->I.req.quoteid),&swap->I.req.quoteid);
offset += iguana_rwnum(1,&buf[offset],sizeof(msgbits),&msgbits);
if ( datalen > 0 )
memcpy(&buf[offset],data,datalen), offset += datalen;
if ( (sentbytes= nn_send(swap->pushsock,buf,offset,0)) != offset )
{
printf("sentbytes.%d vs offset.%d\n",sentbytes,offset);
if ( sentbytes < 0 )
{
if ( swap->pushsock >= 0 )
nn_close(swap->pushsock), swap->pushsock = -1; //,
if ( swap->subsock >= 0 ) //
nn_close(swap->subsock), swap->subsock = -1;
swap->connected = swap->I.iambob != 0 ? -1 : 0;
swap->aborted = (uint32_t)time(NULL);
}
}
//else printf("send.[%d] %x offset.%d datalen.%d [%llx]\n",sentbytes,msgbits,offset,datalen,*(long long *)data);
free(buf);
return(nextbits);
}
void basilisk_swap_sendabort(struct basilisk_swap *swap)
{
uint32_t msgbits = 0; uint8_t buf[sizeof(msgbits) + sizeof(swap->I.req.quoteid) + sizeof(bits256)*2]; int32_t sentbytes,offset=0;
memset(buf,0,sizeof(buf));
offset += iguana_rwnum(1,&buf[offset],sizeof(swap->I.req.quoteid),&swap->I.req.quoteid);
offset += iguana_rwnum(1,&buf[offset],sizeof(msgbits),&msgbits);
if ( (sentbytes= nn_send(swap->pushsock,buf,offset,0)) != offset )
{
if ( sentbytes < 0 )
{
if ( swap->pushsock >= 0 ) //
nn_close(swap->pushsock), swap->pushsock = -1;
if ( swap->subsock >= 0 ) //
nn_close(swap->subsock), swap->subsock = -1;
swap->connected = 0;
}
} else printf("basilisk_swap_sendabort\n");
}
void basilisk_psockinit(struct basilisk_swap *swap,int32_t amlp);
void basilisk_swapgotdata(struct basilisk_swap *swap,uint32_t crc32,bits256 srchash,bits256 desthash,uint32_t quoteid,uint32_t msgbits,uint8_t *data,int32_t datalen,int32_t reinit)
{
int32_t i; struct basilisk_swapmessage *mp;
for (i=0; i<swap->nummessages; i++)
if ( crc32 == swap->messages[i].crc32 && msgbits == swap->messages[i].msgbits && bits256_cmp(srchash,swap->messages[i].srchash) == 0 && bits256_cmp(desthash,swap->messages[i].desthash) == 0 )
return;
//printf(" new message.[%d] datalen.%d Q.%x msg.%x [%llx]\n",swap->nummessages,datalen,quoteid,msgbits,*(long long *)data);
swap->messages = realloc(swap->messages,sizeof(*swap->messages) * (swap->nummessages + 1));
mp = &swap->messages[swap->nummessages++];
mp->crc32 = crc32;
mp->srchash = srchash;
mp->desthash = desthash;
mp->msgbits = msgbits;
mp->quoteid = quoteid;
mp->data = malloc(datalen);
mp->datalen = datalen;
memcpy(mp->data,data,datalen);
if ( reinit == 0 && swap->fp != 0 )
{
fwrite(mp,1,sizeof(*mp),swap->fp);
fwrite(data,1,datalen,swap->fp);
fflush(swap->fp);
}
}
int32_t basilisk_swapget(struct basilisk_swap *swap,uint32_t msgbits,uint8_t *data,int32_t maxlen,int32_t (*basilisk_verify_func)(void *ptr,uint8_t *data,int32_t datalen))
{
uint8_t *ptr; bits256 srchash,desthash; uint32_t crc32,_msgbits,quoteid; int32_t i,size,offset,retval = -1; struct basilisk_swapmessage *mp = 0;
while ( (size= nn_recv(swap->subsock,&ptr,NN_MSG,0)) >= 0 )
{
swap->lasttime = (uint32_t)time(NULL);
memset(srchash.bytes,0,sizeof(srchash));
memset(desthash.bytes,0,sizeof(desthash));
//printf("gotmsg.[%d] crc.%x\n",size,crc32);
offset = 0;
for (i=0; i<32; i++)
srchash.bytes[i] = ptr[offset++];
for (i=0; i<32; i++)
desthash.bytes[i] = ptr[offset++];
offset += iguana_rwnum(0,&ptr[offset],sizeof(uint32_t),&quoteid);
offset += iguana_rwnum(0,&ptr[offset],sizeof(uint32_t),&_msgbits);
if ( size > offset )
{
crc32 = calc_crc32(0,&ptr[offset],size-offset);
if ( size > offset )
{
//printf("size.%d offset.%d datalen.%d\n",size,offset,size-offset);
basilisk_swapgotdata(swap,crc32,srchash,desthash,quoteid,_msgbits,&ptr[offset],size-offset,0);
}
}
else if ( bits256_nonz(srchash) == 0 && bits256_nonz(desthash) == 0 )
{
if ( swap->aborted == 0 )
{
swap->aborted = (uint32_t)time(NULL);
printf("got abort signal from other side\n");
}
} else printf("basilisk_swapget: got strange packet\n");
if ( ptr != 0 )
nn_freemsg(ptr), ptr = 0;
}
//char str[65],str2[65];
for (i=0; i<swap->nummessages; i++)
{
//printf("%d: %s vs %s\n",i,bits256_str(str,swap->messages[i].srchash),bits256_str(str2,swap->messages[i].desthash));
if ( bits256_cmp(swap->messages[i].desthash,swap->I.myhash) == 0 )
{
if ( swap->messages[i].msgbits == msgbits )
{
if ( swap->I.iambob == 0 && swap->lasttime != 0 && time(NULL) > swap->lasttime+360 )
{
printf("nothing received for a while from Bob, try new sockets\n");
if ( swap->pushsock >= 0 ) //
nn_close(swap->pushsock), swap->pushsock = -1;
if ( swap->subsock >= 0 ) //
nn_close(swap->subsock), swap->subsock = -1;
swap->connected = 0;
basilisk_psockinit(swap,swap->I.iambob != 0);
}
mp = &swap->messages[i];
if ( msgbits != 0x80000000 )
break;
}
}
}
if ( mp != 0 )
retval = (*basilisk_verify_func)(swap,mp->data,mp->datalen);
//printf("mine/other %s vs %s\n",bits256_str(str,swap->I.myhash),bits256_str(str2,swap->I.otherhash));
return(retval);
}
int32_t basilisk_messagekeyread(uint8_t *key,uint32_t *channelp,uint32_t *msgidp,bits256 *srchashp,bits256 *desthashp)
{
int32_t keylen = 0;
keylen += iguana_rwnum(0,&key[keylen],sizeof(uint32_t),channelp);
keylen += iguana_rwnum(0,&key[keylen],sizeof(uint32_t),msgidp);
keylen += iguana_rwbignum(0,&key[keylen],sizeof(*srchashp),srchashp->bytes);
keylen += iguana_rwbignum(0,&key[keylen],sizeof(*desthashp),desthashp->bytes);
return(keylen);
}
int32_t basilisk_messagekey(uint8_t *key,uint32_t channel,uint32_t msgid,bits256 srchash,bits256 desthash)
{
int32_t keylen = 0;
keylen += iguana_rwnum(1,&key[keylen],sizeof(uint32_t),&channel);
keylen += iguana_rwnum(1,&key[keylen],sizeof(uint32_t),&msgid);
keylen += iguana_rwbignum(1,&key[keylen],sizeof(srchash),srchash.bytes);
keylen += iguana_rwbignum(1,&key[keylen],sizeof(desthash),desthash.bytes);
return(keylen);
}
void LP_channelsend(bits256 srchash,bits256 desthash,uint32_t channel,uint32_t msgid,uint8_t *data,int32_t datalen)
{
int32_t keylen; uint8_t key[BASILISK_KEYSIZE]; //char *retstr;
keylen = basilisk_messagekey(key,channel,msgid,srchash,desthash);
//if ( (retstr= _dex_reqsend(myinfo,"DEX",key,keylen,data,datalen)) != 0 )
// free(retstr);
}

718
iguana/exchanges/LP_remember.c

@ -18,439 +18,341 @@
// marketmaker
//
cJSON *basilisk_nullretjson(cJSON *retjson)
{
char *outstr;
if ( retjson != 0 )
{
outstr = jprint(retjson,0);
if ( strcmp(outstr,"{}") == 0 )
{
free_json(retjson);
retjson = 0;
}
free(outstr);
}
return(retjson);
}
cJSON *basilisk_swapgettxout(struct supernet_info *myinfo,char *symbol,bits256 trigger,int32_t vout)
/*void basilisk_swaps_init(struct supernet_info *myinfo)
{
char *retstr; cJSON *retjson=0; struct iguana_info *coin;
if ( ((coin= iguana_coinfind(symbol)) == 0 || coin->FULLNODE == 0) && iguana_isnotarychain(symbol) >= 0 )
char fname[512]; uint32_t iter,swapcompleted,requestid,quoteid,optionduration,statebits; FILE *fp; bits256 privkey;struct basilisk_request R; struct basilisk_swapmessage M; struct basilisk_swap *swap = 0;
sprintf(fname,"%s/SWAPS/list",GLOBAL_DBDIR), OS_compatible_path(fname);
if ( (myinfo->swapsfp= fopen(fname,"rb+")) != 0 )
{
if ( (retstr= dex_gettxout(myinfo,0,0,0,trigger,symbol,vout)) != 0 )
while ( fread(&requestid,1,sizeof(requestid),myinfo->swapsfp) == sizeof(requestid) && fread(&quoteid,1,sizeof(quoteid),myinfo->swapsfp) == sizeof(quoteid) )
{
//printf("dexgettxout.(%s)\n",retstr);
retjson = cJSON_Parse(retstr);
free(retstr);
sprintf(fname,"%s/SWAPS/%u-%u",GLOBAL_DBDIR,requestid,quoteid), OS_compatible_path(fname);
printf("%s\n",fname);
if ( (fp= fopen(fname,"rb+")) != 0 ) // check to see if completed
{
memset(&M,0,sizeof(M));
swapcompleted = 1;
for (iter=0; iter<2; iter++)
{
if ( fread(privkey.bytes,1,sizeof(privkey),fp) == sizeof(privkey) &&
fread(&R,1,sizeof(R),fp) == sizeof(R) &&
fread(&statebits,1,sizeof(statebits),fp) == sizeof(statebits) &&
fread(&optionduration,1,sizeof(optionduration),fp) == sizeof(optionduration) )
{
while ( 0 && fread(&M,1,sizeof(M),fp) == sizeof(M) )
{
M.data = 0;
//printf("entry iter.%d crc32.%x datalen.%d\n",iter,M.crc32,M.datalen);
if ( M.datalen < 100000 )
{
M.data = malloc(M.datalen);
if ( fread(M.data,1,M.datalen,fp) == M.datalen )
{
if ( calc_crc32(0,M.data,M.datalen) == M.crc32 )
{
if ( iter == 1 )
{
if ( swap == 0 )
{
swap = basilisk_thread_start(privkey,&R,statebits,optionduration,1);
swap->I.choosei = swap->I.otherchoosei = -1;
}
if ( swap != 0 )
basilisk_swapgotdata(swap,M.crc32,M.srchash,M.desthash,M.quoteid,M.msgbits,M.data,M.datalen,1);
}
} else printf("crc mismatch %x vs %x\n",calc_crc32(0,M.data,M.datalen),M.crc32);
} else printf("error reading M.datalen %d\n",M.datalen);
free(M.data), M.data = 0;
}
}
}
if ( swapcompleted != 0 )
break;
rewind(fp);
}
}
}
if ( 0 && strcmp("BTC",symbol) == 0 )
printf("%s gettxout.(%s)\n",symbol,jprint(retjson,0));
}
else
{
retjson = dpow_gettxout(myinfo,coin,trigger,vout);
//printf("need to verify passthru has this info\n");
//printf("dpowgettxout.(%s)\n",jprint(retjson,0));
}
return(basilisk_nullretjson(retjson));
}
} else myinfo->swapsfp = fopen(fname,"wb+");
}*/
cJSON *basilisk_swapgettx(struct supernet_info *myinfo,char *symbol,bits256 txid)
FILE *basilisk_swap_save(struct basilisk_swap *swap,bits256 privkey,struct basilisk_request *rp,uint32_t statebits,int32_t optionduration,int32_t reinit)
{
char *retstr; cJSON *retjson=0; struct iguana_info *coin;
if ( ((coin= iguana_coinfind(symbol)) == 0 || coin->FULLNODE == 0) && iguana_isnotarychain(symbol) >= 0 )
{
if ( (retstr= dex_gettransaction(myinfo,0,0,0,txid,symbol)) != 0 )
{
retjson = cJSON_Parse(retstr);
free(retstr);
}
//if ( strcmp("BTC",symbol) == 0 )
// printf("%s gettx.(%s)\n",symbol,jprint(retjson,0));
} else retjson = dpow_gettransaction(myinfo,coin,txid);
return(basilisk_nullretjson(retjson));
FILE *fp=0; /*char fname[512];
sprintf(fname,"%s/SWAPS/%u-%u",GLOBAL_DBDIR,rp->requestid,rp->quoteid), OS_compatible_path(fname);
if ( (fp= fopen(fname,"rb+")) == 0 )
{
if ( (fp= fopen(fname,"wb+")) != 0 )
{
fwrite(privkey.bytes,1,sizeof(privkey),fp);
fwrite(rp,1,sizeof(*rp),fp);
fwrite(&statebits,1,sizeof(statebits),fp);
fwrite(&optionduration,1,sizeof(optionduration),fp);
fflush(fp);
}
}
else if ( reinit != 0 )
{
}*/
return(fp);
}
int32_t basilisk_swap_txdestaddr(char *destaddr,bits256 txid,int32_t vout,cJSON *txobj)
int32_t basilisk_swap_load(uint32_t requestid,uint32_t quoteid,bits256 *privkeyp,struct basilisk_request *rp,uint32_t *statebitsp,int32_t *optiondurationp)
{
int32_t n,m,retval = -1; cJSON *vouts,*item,*addresses,*skey; char *addr;
if ( (vouts= jarray(&n,txobj,"vout")) != 0 && vout < n )
FILE *fp=0; char fname[512]; int32_t retval = -1;
sprintf(fname,"%s/SWAPS/%u-%u",GLOBAL_DBDIR,requestid,quoteid), OS_compatible_path(fname);
if ( (fp= fopen(fname,"rb+")) != 0 )
{
item = jitem(vouts,vout);
if ( (skey= jobj(item,"scriptPubKey")) != 0 && (addresses= jarray(&m,skey,"addresses")) != 0 )
{
item = jitem(addresses,0);
if ( (addr= jstr(item,0)) != 0 )
{
safecopy(destaddr,addr,64);
retval = 0;
}
//printf("item.(%s) -> dest.(%s)\n",jprint(item,0),destaddr);
}
if ( fread(privkeyp,1,sizeof(*privkeyp),fp) == sizeof(*privkeyp) &&
fread(rp,1,sizeof(*rp),fp) == sizeof(*rp) &&
fread(statebitsp,1,sizeof(*statebitsp),fp) == sizeof(*statebitsp) &&
fread(optiondurationp,1,sizeof(*optiondurationp),fp) == sizeof(*optiondurationp) )
retval = 0;
fclose(fp);
}
return(retval);
}
int32_t basilisk_swap_getcoinaddr(struct supernet_info *myinfo,char *symbol,char *coinaddr,bits256 txid,int32_t vout)
void basilisk_swap_saveupdate(struct basilisk_swap *swap)
{
cJSON *retjson;
coinaddr[0] = 0;
if ( (retjson= basilisk_swapgettx(myinfo,symbol,txid)) != 0 )
FILE *fp; char fname[512];
sprintf(fname,"%s/SWAPS/%u-%u.swap",GLOBAL_DBDIR,swap->I.req.requestid,swap->I.req.quoteid), OS_compatible_path(fname);
if ( (fp= fopen(fname,"wb")) != 0 )
{
basilisk_swap_txdestaddr(coinaddr,txid,vout,retjson);
free_json(retjson);
fwrite(&swap->I,1,sizeof(swap->I),fp);
/*fwrite(&swap->bobdeposit,1,sizeof(swap->bobdeposit),fp);
fwrite(&swap->bobpayment,1,sizeof(swap->bobpayment),fp);
fwrite(&swap->alicepayment,1,sizeof(swap->alicepayment),fp);
fwrite(&swap->myfee,1,sizeof(swap->myfee),fp);
fwrite(&swap->otherfee,1,sizeof(swap->otherfee),fp);
fwrite(&swap->aliceclaim,1,sizeof(swap->aliceclaim),fp);
fwrite(&swap->alicespend,1,sizeof(swap->alicespend),fp);
fwrite(&swap->bobreclaim,1,sizeof(swap->bobreclaim),fp);
fwrite(&swap->bobspend,1,sizeof(swap->bobspend),fp);
fwrite(&swap->bobrefund,1,sizeof(swap->bobrefund),fp);
fwrite(&swap->alicereclaim,1,sizeof(swap->alicereclaim),fp);*/
fwrite(swap->privkeys,1,sizeof(swap->privkeys),fp);
fwrite(swap->otherdeck,1,sizeof(swap->otherdeck),fp);
fwrite(swap->deck,1,sizeof(swap->deck),fp);
fclose(fp);
}
return(coinaddr[0] != 0);
}
int32_t basilisk_swap_getsigscript(struct supernet_info *myinfo,char *symbol,uint8_t *script,int32_t maxlen,bits256 txid,int32_t vini)
/*int32_t basilisk_swap_loadtx(struct basilisk_rawtx *rawtx,FILE *fp,char *bobcoinstr,char *alicecoinstr)
{
cJSON *retjson,*vins,*item,*skey; int32_t n,scriptlen = 0; char *hexstr;
if ( (retjson= basilisk_swapgettx(myinfo,symbol,txid)) != 0 )
if ( fread(rawtx,1,sizeof(*rawtx),fp) == sizeof(*rawtx) )
{
if ( (vins= jarray(&n,retjson,"vin")) != 0 && vini < n )
rawtx->coin = 0;
rawtx->vins = 0;
if ( strcmp(rawtx->I.coinstr,bobcoinstr) == 0 || strcmp(rawtx->I.coinstr,alicecoinstr) == 0 )
{
item = jitem(vins,vini);
if ( (skey= jobj(item,"scriptSig")) != 0 && (hexstr= jstr(skey,"hex")) != 0 && (scriptlen= (int32_t)strlen(hexstr)) < maxlen*2 )
{
scriptlen >>= 1;
decode_hex(script,scriptlen,hexstr);
//char str[65]; printf("%s/v%d sigscript.(%s)\n",bits256_str(str,txid),vini,hexstr);
}
rawtx->coin = LP_coinfind(rawtx->I.coinstr);
if ( rawtx->vinstr[0] != 0 )
rawtx->vins = cJSON_Parse(rawtx->vinstr);
printf("loaded.%s len.%d\n",rawtx->name,rawtx->I.datalen);
return(0);
}
free_json(retjson);
}
return(scriptlen);
}
return(-1);
}*/
int64_t basilisk_txvalue(struct supernet_info *myinfo,char *symbol,bits256 txid,int32_t vout)
void basilisk_dontforget_userdata(char *userdataname,FILE *fp,uint8_t *script,int32_t scriptlen)
{
cJSON *txobj,*vouts,*item; int32_t n; int64_t value = 0;
//char str[65]; printf("%s txvalue.(%s)\n",symbol,bits256_str(str,txid));
if ( (txobj= basilisk_swapgettx(myinfo,symbol,txid)) != 0 )
int32_t i; char scriptstr[513];
if ( scriptlen != 0 )
{
//printf("txobj.(%s)\n",jprint(txobj,0));
if ( (vouts= jarray(&n,txobj,"vout")) != 0 )
{
item = jitem(vouts,vout);
if ( (value= jdouble(item,"amount") * SATOSHIDEN) == 0 )
value = jdouble(item,"value") * SATOSHIDEN;
}
free_json(txobj);
for (i=0; i<scriptlen; i++)
sprintf(&scriptstr[i << 1],"%02x",script[i]);
scriptstr[i << 1] = 0;
fprintf(fp,"\",\"%s\":\"%s\"",userdataname,scriptstr);
}
return(value);
}
bits256 dex_swap_spendtxid(struct supernet_info *myinfo,char *symbol,char *destaddr,char *coinaddr,bits256 utxotxid,int32_t vout)
void basilisk_dontforget(struct basilisk_swap *swap,struct basilisk_rawtx *rawtx,int32_t locktime,bits256 triggertxid)
{
char *retstr,*addr; cJSON *array,*item,*array2; int32_t i,n,m; bits256 spendtxid,txid;
memset(&spendtxid,0,sizeof(spendtxid));
if ( (retstr= dex_listtransactions(myinfo,0,0,0,symbol,coinaddr,100,0)) != 0 )
char zeroes[32],fname[512],str[65],coinaddr[64],secretAmstr[41],secretAm256str[65],secretBnstr[41],secretBn256str[65],*tmp; FILE *fp; int32_t i,len; uint8_t redeemscript[256],script[256];
sprintf(fname,"%s/SWAPS/%u-%u.%s",GLOBAL_DBDIR,swap->I.req.requestid,swap->I.req.quoteid,rawtx->name), OS_compatible_path(fname);
coinaddr[0] = secretAmstr[0] = secretAm256str[0] = secretBnstr[0] = secretBn256str[0] = 0;
memset(zeroes,0,sizeof(zeroes));
if ( rawtx != 0 && (fp= fopen(fname,"wb")) != 0 )
{
if ( (array= cJSON_Parse(retstr)) != 0 )
fprintf(fp,"{\"name\":\"%s\",\"coin\":\"%s\"",rawtx->name,rawtx->coin->symbol);
if ( rawtx->I.datalen > 0 )
{
if ( (n= cJSON_GetArraySize(array)) > 0 )
fprintf(fp,",\"tx\":\"");
for (i=0; i<rawtx->I.datalen; i++)
fprintf(fp,"%02x",rawtx->txbytes[i]);
fprintf(fp,"\",\"txid\":\"%s\"",bits256_str(str,bits256_doublesha256(0,rawtx->txbytes,rawtx->I.datalen)));
if ( rawtx == &swap->bobdeposit || rawtx == &swap->bobpayment )
{
for (i=0; i<n; i++)
basilisk_swap_coinaddr(swap,&swap->bobcoin,coinaddr,rawtx->txbytes,rawtx->I.datalen);
if ( coinaddr[0] != 0 )
{
if ( (item= jitem(array,i)) == 0 )
continue;
txid = jbits256(item,"txid");
if ( bits256_nonz(txid) == 0 )
{
if ( (array2= jarray(&m,item,"inputs")) != 0 && m == 1 )
{
//printf("found inputs with %s\n",bits256_str(str,spendtxid));
txid = jbits256(jitem(array2,0),"output_hash");
if ( bits256_cmp(txid,utxotxid) == 0 )
{
//printf("matched %s\n",bits256_str(str,txid));
if ( (array2= jarray(&m,item,"outputs")) != 0 && m == 1 && (addr= jstr(jitem(array2,0),"address")) != 0 )
{
spendtxid = jbits256(item,"hash");
strcpy(destaddr,addr);
//printf("set spend addr.(%s) <- %s\n",addr,jprint(item,0));
break;
}
}
}
}
else if ( bits256_cmp(txid,utxotxid) == 0 )
{
spendtxid = jbits256(item,"spendtxid");
if ( bits256_nonz(spendtxid) != 0 )
{
basilisk_swap_getcoinaddr(myinfo,symbol,destaddr,spendtxid,0);
//char str[65]; printf("found spendtxid.(%s) -> %s\n",bits256_str(str,spendtxid),destaddr);
break;
}
}
if ( (tmp= LP_importaddress(swap->bobcoin.symbol,coinaddr)) != 0 )
free(tmp);
if ( rawtx == &swap->bobdeposit )
safecopy(swap->Bdeposit,coinaddr,sizeof(swap->Bdeposit));
else safecopy(swap->Bpayment,coinaddr,sizeof(swap->Bpayment));
}
}
free_json(array);
}
free(retstr);
}
return(spendtxid);
}
bits256 basilisk_swap_spendtxid(struct supernet_info *myinfo,char *symbol,char *destaddr,bits256 utxotxid,int32_t vout)
{
bits256 spendtxid,txid; char *catstr,*addr; cJSON *array,*item,*item2,*txobj,*vins; int32_t i,n,m; char coinaddr[64],str[65]; struct iguana_info *coin = iguana_coinfind(symbol);
// listtransactions or listspents
destaddr[0] = 0;
coinaddr[0] = 0;
memset(&spendtxid,0,sizeof(spendtxid));
//char str[65]; printf("swap %s spendtxid.(%s)\n",symbol,bits256_str(str,utxotxid));
if ( (coin == 0 || coin->FULLNODE >= 0) && iguana_isnotarychain(symbol) >= 0 )
{
//[{"type":"sent","confirmations":379,"height":275311,"timestamp":1492084664,"txid":"8703c5517bc57db38134058370a14e99b8e662b99ccefa2061dea311bbd02b8b","vout":0,"amount":117.50945263,"spendtxid":"cf2509e076fbb9b22514923df916b7aacb1391dce9c7e1460b74947077b12510","vin":0,"paid":{"type":"paid","txid":"cf2509e076fbb9b22514923df916b7aacb1391dce9c7e1460b74947077b12510","height":275663,"timestamp":1492106024,"vouts":[{"RUDpN6PEBsE7ZFbGjUxk1W3QVsxnjBLYw6":117.50935263}]}}]
basilisk_swap_getcoinaddr(myinfo,symbol,coinaddr,utxotxid,vout);
if ( coinaddr[0] != 0 )
spendtxid = dex_swap_spendtxid(myinfo,symbol,destaddr,coinaddr,utxotxid,vout);
if ( swap->Bdeposit[0] != 0 )
fprintf(fp,",\"%s\":\"%s\"","Bdeposit",swap->Bdeposit);
if ( swap->Bpayment[0] != 0 )
fprintf(fp,",\"%s\":\"%s\"","Bpayment",swap->Bpayment);
fprintf(fp,",\"expiration\":%u",swap->I.expiration);
fprintf(fp,",\"iambob\":%d",swap->I.iambob);
fprintf(fp,",\"bobcoin\":\"%s\"",swap->bobcoin.symbol);
fprintf(fp,",\"alicecoin\":\"%s\"",swap->alicecoin.symbol);
fprintf(fp,",\"lock\":%u",locktime);
fprintf(fp,",\"amount\":%.8f",dstr(rawtx->I.amount));
if ( bits256_nonz(triggertxid) != 0 )
fprintf(fp,",\"trigger\":\"%s\"",bits256_str(str,triggertxid));
if ( bits256_nonz(swap->I.pubAm) != 0 && bits256_nonz(swap->I.pubBn) != 0 )
{
basilisk_alicescript(redeemscript,&len,script,0,coinaddr,swap->alicecoin.p2shtype,swap->I.pubAm,swap->I.pubBn);
if ( (tmp= LP_importaddress(swap->alicecoin.symbol,coinaddr)) != 0 )
free(tmp);
fprintf(fp,",\"Apayment\":\"%s\"",coinaddr);
}
/*basilisk_dontforget_userdata("Aclaim",fp,swap->I.userdata_aliceclaim,swap->I.userdata_aliceclaimlen);
basilisk_dontforget_userdata("Areclaim",fp,swap->I.userdata_alicereclaim,swap->I.userdata_alicereclaimlen);
basilisk_dontforget_userdata("Aspend",fp,swap->I.userdata_alicespend,swap->I.userdata_alicespendlen);
basilisk_dontforget_userdata("Bspend",fp,swap->I.userdata_bobspend,swap->I.userdata_bobspendlen);
basilisk_dontforget_userdata("Breclaim",fp,swap->I.userdata_bobreclaim,swap->I.userdata_bobreclaimlen);
basilisk_dontforget_userdata("Brefund",fp,swap->I.userdata_bobrefund,swap->I.userdata_bobrefundlen);*/
fprintf(fp,"}\n");
fclose(fp);
}
else if ( coin != 0 )
sprintf(fname,"%s/SWAPS/%u-%u",GLOBAL_DBDIR,swap->I.req.requestid,swap->I.req.quoteid), OS_compatible_path(fname);
if ( (fp= fopen(fname,"wb")) != 0 )
{
if ( (array= dpow_listtransactions(myinfo,coin,destaddr,1000,0)) != 0 )
fprintf(fp,"{\"src\":\"%s\",\"srcamount\":%.8f,\"dest\":\"%s\",\"destamount\":%.8f,\"requestid\":%u,\"quoteid\":%u,\"iambob\":%d,\"state\":%u,\"otherstate\":%u,\"expiration\":%u,\"dlocktime\":%u,\"plocktime\":%u",swap->I.req.src,dstr(swap->I.req.srcamount),swap->I.req.dest,dstr(swap->I.req.destamount),swap->I.req.requestid,swap->I.req.quoteid,swap->I.iambob,swap->I.statebits,swap->I.otherstatebits,swap->I.expiration,swap->bobdeposit.I.locktime,swap->bobpayment.I.locktime);
if ( memcmp(zeroes,swap->I.secretAm,20) != 0 )
{
if ( (n= cJSON_GetArraySize(array)) > 0 )
{
for (i=0; i<n; i++)
{
if ( (item= jitem(array,i)) == 0 )
continue;
txid = jbits256(item,"txid");
if ( vout == juint(item,"vout") && bits256_cmp(txid,utxotxid) == 0 && (addr= jstr(item,"address")) != 0 )
{
if ( (catstr= jstr(item,"category")) != 0 )
{
if (strcmp(catstr,"send") == 0 )
{
strncpy(destaddr,addr,63);
//printf("(%s) <- (%s) item.%d.[%s]\n",destaddr,coinaddr,i,jprint(item,0));
if ( coinaddr[0] != 0 )
break;
}
if (strcmp(catstr,"receive") == 0 )
{
strncpy(coinaddr,addr,63);
//printf("receive dest.(%s) <- (%s)\n",destaddr,coinaddr);
if ( destaddr[0] != 0 )
break;
}
}
}
}
}
free_json(array);
init_hexbytes_noT(secretAmstr,swap->I.secretAm,20);
fprintf(fp,",\"secretAm\":\"%s\"",secretAmstr);
}
if ( destaddr[0] != 0 )
if ( memcmp(zeroes,swap->I.secretAm256,32) != 0 )
{
if ( (array= dpow_listtransactions(myinfo,coin,destaddr,1000,0)) != 0 )
{
if ( (n= cJSON_GetArraySize(array)) > 0 )
{
for (i=0; i<n; i++)
{
if ( (item= jitem(array,i)) == 0 )
continue;
if ( (catstr= jstr(item,"category")) != 0 && strcmp(catstr,"send") == 0 )
{
txid = jbits256(item,"txid");
if ( (txobj= dpow_gettransaction(myinfo,coin,txid)) != 0 )
{
if ( (vins= jarray(&m,txobj,"vin")) != 0 && m > jint(item,"vout") )
{
item2 = jitem(vins,jint(item,"vout"));
if ( bits256_cmp(utxotxid,jbits256(item2,"txid")) == 0 && vout == jint(item2,"vout") )
{
spendtxid = txid;
break;
}
}
}
}
}
if ( i == n )
printf("dpowlist: native couldnt find spendtxid for %s\n",bits256_str(str,utxotxid));
}
free_json(array);
}
if ( bits256_nonz(spendtxid) != 0 )
return(spendtxid);
init_hexbytes_noT(secretAm256str,swap->I.secretAm256,32);
fprintf(fp,",\"secretAm256\":\"%s\"",secretAm256str);
}
if ( iguana_isnotarychain(symbol) >= 0 )
if ( memcmp(zeroes,swap->I.secretBn,20) != 0 )
{
basilisk_swap_getcoinaddr(myinfo,symbol,coinaddr,utxotxid,vout);
printf("fallback use DEX for native (%s) (%s)\n",coinaddr,bits256_str(str,utxotxid));
if ( coinaddr[0] != 0 )
{
spendtxid = dex_swap_spendtxid(myinfo,symbol,destaddr,coinaddr,utxotxid,vout);
printf("spendtxid.(%s)\n",bits256_str(str,spendtxid));
}
init_hexbytes_noT(secretBnstr,swap->I.secretBn,20);
fprintf(fp,",\"secretBn\":\"%s\"",secretBnstr);
}
}
return(spendtxid);
}
bits256 basilisk_swap_sendrawtransaction(struct supernet_info *myinfo,char *txname,char *symbol,char *txbytes)
{
char *retstr; bits256 txid; int32_t i,sentflag = 0;
memset(&txid,0,sizeof(txid));
for (i=0; i<3; i++)
{
if ( (retstr= _dex_sendrawtransaction(myinfo,symbol,txbytes)) != 0 )
if ( memcmp(zeroes,swap->I.secretBn256,32) != 0 )
{
if ( is_hexstr(retstr,0) == 64 )
{
decode_hex(txid.bytes,32,retstr);
sentflag = 1;
}
char str[65]; printf("[%s] %s RETSTR.(%s) %s.%s\n",txname,txbytes,retstr,symbol,bits256_str(str,txid));
free(retstr);
init_hexbytes_noT(secretBn256str,swap->I.secretBn256,32);
fprintf(fp,",\"secretBn256\":\"%s\"",secretBn256str);
}
if ( sentflag != 0 )
break;
for (i=0; i<2; i++)
if ( bits256_nonz(swap->I.myprivs[i]) != 0 )
fprintf(fp,",\"myprivs%d\":\"%s\"",i,bits256_str(str,swap->I.myprivs[i]));
if ( bits256_nonz(swap->I.privAm) != 0 )
fprintf(fp,",\"privAm\":\"%s\"",bits256_str(str,swap->I.privAm));
if ( bits256_nonz(swap->I.privBn) != 0 )
fprintf(fp,",\"privBn\":\"%s\"",bits256_str(str,swap->I.privBn));
if ( bits256_nonz(swap->I.pubA0) != 0 )
fprintf(fp,",\"pubA0\":\"%s\"",bits256_str(str,swap->I.pubA0));
if ( bits256_nonz(swap->I.pubB0) != 0 )
fprintf(fp,",\"pubB0\":\"%s\"",bits256_str(str,swap->I.pubB0));
if ( bits256_nonz(swap->I.pubB1) != 0 )
fprintf(fp,",\"pubB1\":\"%s\"",bits256_str(str,swap->I.pubB1));
if ( bits256_nonz(swap->bobdeposit.I.actualtxid) != 0 )
fprintf(fp,",\"Bdeposit\":\"%s\"",bits256_str(str,swap->bobdeposit.I.actualtxid));
if ( bits256_nonz(swap->bobrefund.I.actualtxid) != 0 )
fprintf(fp,",\"Brefund\":\"%s\"",bits256_str(str,swap->bobrefund.I.actualtxid));
if ( bits256_nonz(swap->aliceclaim.I.actualtxid) != 0 )
fprintf(fp,",\"Aclaim\":\"%s\"",bits256_str(str,swap->aliceclaim.I.actualtxid));
if ( bits256_nonz(swap->bobpayment.I.actualtxid) != 0 )
fprintf(fp,",\"Bpayment\":\"%s\"",bits256_str(str,swap->bobpayment.I.actualtxid));
if ( bits256_nonz(swap->alicespend.I.actualtxid) != 0 )
fprintf(fp,",\"Aspend\":\"%s\"",bits256_str(str,swap->alicespend.I.actualtxid));
if ( bits256_nonz(swap->bobreclaim.I.actualtxid) != 0 )
fprintf(fp,",\"Breclaim\":\"%s\"",bits256_str(str,swap->bobreclaim.I.actualtxid));
if ( bits256_nonz(swap->alicepayment.I.actualtxid) != 0 )
fprintf(fp,",\"Apayment\":\"%s\"",bits256_str(str,swap->alicepayment.I.actualtxid));
if ( bits256_nonz(swap->bobspend.I.actualtxid) != 0 )
fprintf(fp,",\"Bspend\":\"%s\"",bits256_str(str,swap->bobspend.I.actualtxid));
if ( bits256_nonz(swap->alicereclaim.I.actualtxid) != 0 )
fprintf(fp,",\"Areclaim\":\"%s\"",bits256_str(str,swap->alicereclaim.I.actualtxid));
if ( bits256_nonz(swap->otherfee.I.actualtxid) != 0 )
fprintf(fp,",\"otherfee\":\"%s\"",bits256_str(str,swap->otherfee.I.actualtxid));
if ( bits256_nonz(swap->myfee.I.actualtxid) != 0 )
fprintf(fp,",\"myfee\":\"%s\"",bits256_str(str,swap->myfee.I.actualtxid));
fprintf(fp,",\"dest33\":\"");
for (i=0; i<33; i++)
fprintf(fp,"%02x",swap->persistent_pubkey33[i]);
fprintf(fp,"\"}\n");
fclose(fp);
}
return(txid);
}
char *basilisk_swap_bobtxspend(char *name,struct supernet_info *myinfo,char *symbol,bits256 privkey,bits256 *privkey2p,uint8_t *redeemscript,int32_t redeemlen,uint8_t *userdata,int32_t userdatalen,bits256 utxotxid,int32_t vout,uint8_t *pubkey33,int32_t finalseqid,uint32_t expiration,int64_t *destamountp)
void basilisk_dontforget_update(struct basilisk_swap *swap,struct basilisk_rawtx *rawtx)
{
char *rawtxbytes=0,*signedtx=0,str[65],hexstr[999],wifstr[128],destaddr[64]; uint8_t spendscript[512],addrtype,rmd160[20]; cJSON *utxoobj,*txobj,*vins,*item,*sobj,*privkeys; int32_t height,completed,spendlen,ignore_cltverr=1,suppress_pubkeys=1; struct vin_info *V; uint32_t timestamp,locktime = 0,sequenceid = 0xffffffff * finalseqid; struct iguana_info *coin; bits256 txid,signedtxid; uint64_t destamount;
*destamountp = 0;
if ( finalseqid == 0 )
locktime = expiration;
//printf("bobtxspend.%s redeem.[%d]\n",symbol,redeemlen);
if ( redeemlen < 0 || (coin= iguana_coinfind(symbol)) == 0 )
return(0);
if ( (utxoobj= basilisk_swapgettxout(myinfo,symbol,utxotxid,vout)) == 0 )
bits256 triggertxid;
memset(triggertxid.bytes,0,sizeof(triggertxid));
if ( rawtx == 0 )
{
printf("basilisk_swap_bobtxspend.%s utxo already spent or doesnt exist\n",name);
return(0);
basilisk_dontforget(swap,0,0,triggertxid);
return;
}
if ( (destamount= jdouble(utxoobj,"amount")*SATOSHIDEN) == 0 && (destamount= jdouble(utxoobj,"value")*SATOSHIDEN) == 0 )
if ( rawtx == &swap->myfee )
basilisk_dontforget(swap,&swap->myfee,0,triggertxid);
else if ( rawtx == &swap->otherfee )
basilisk_dontforget(swap,&swap->otherfee,0,triggertxid);
else if ( rawtx == &swap->bobdeposit )
{
printf("%s %s basilisk_swap_bobtxspend.%s strange utxo.(%s)\n",symbol,bits256_str(str,utxotxid),name,jprint(utxoobj,0));
free_json(utxoobj);
return(0);
} else free_json(utxoobj);
*destamountp = destamount;
if ( destamount > 10000 )
destamount -= 10000;
if ( strcmp(symbol,"BTC") == 0 )
basilisk_dontforget(swap,&swap->bobdeposit,0,triggertxid);
basilisk_dontforget(swap,&swap->bobrefund,swap->bobdeposit.I.locktime,triggertxid);
}
else if ( rawtx == &swap->bobrefund )
basilisk_dontforget(swap,&swap->bobrefund,swap->bobdeposit.I.locktime,triggertxid);
else if ( rawtx == &swap->aliceclaim )
{
if ( destamount > 40000 )
destamount -= 40000;
basilisk_dontforget(swap,&swap->bobrefund,0,triggertxid);
basilisk_dontforget(swap,&swap->aliceclaim,0,swap->bobrefund.I.actualtxid);
}
height = coin->longestchain;
timestamp = (uint32_t)time(NULL);
V = calloc(256,sizeof(*V));
privkeys = cJSON_CreateArray();
if ( privkey2p != 0 )
else if ( rawtx == &swap->alicepayment )
{
V[0].signers[1].privkey = *privkey2p;
bitcoin_pubkey33(myinfo->ctx,V[0].signers[1].pubkey,*privkey2p);
bitcoin_priv2wif(wifstr,*privkey2p,coin->chain->wiftype);
jaddistr(privkeys,wifstr);
V[0].N = V[0].M = 2;
} else V[0].N = V[0].M = 1;
V[0].signers[0].privkey = privkey;
bitcoin_pubkey33(myinfo->ctx,V[0].signers[0].pubkey,privkey);
bitcoin_priv2wif(wifstr,privkey,coin->chain->wiftype);
jaddistr(privkeys,wifstr);
V[0].suppress_pubkeys = suppress_pubkeys;
V[0].ignore_cltverr = ignore_cltverr;
if ( redeemlen != 0 )
memcpy(V[0].p2shscript,redeemscript,redeemlen), V[0].p2shlen = redeemlen;
txobj = bitcoin_txcreate(coin->symbol,coin->chain->isPoS,locktime,1,timestamp);
vins = cJSON_CreateArray();
item = cJSON_CreateObject();
if ( userdata != 0 && userdatalen > 0 )
basilisk_dontforget(swap,&swap->alicepayment,0,swap->bobdeposit.I.actualtxid);
}
else if ( rawtx == &swap->bobspend )
{
memcpy(V[0].userdata,userdata,userdatalen);
V[0].userdatalen = userdatalen;
init_hexbytes_noT(hexstr,userdata,userdatalen);
jaddstr(item,"userdata",hexstr);
basilisk_dontforget(swap,&swap->alicepayment,0,swap->bobdeposit.I.actualtxid);
basilisk_dontforget(swap,&swap->bobspend,0,swap->alicepayment.I.actualtxid);
}
jaddbits256(item,"txid",utxotxid);
jaddnum(item,"vout",vout);
sobj = cJSON_CreateObject();
bitcoin_address(destaddr,coin->chain->pubtype,pubkey33,33);
bitcoin_addr2rmd160(&addrtype,rmd160,destaddr);
/*int32_t i;
for (i=0; i<33; i++)
printf("%02x",pubkey33[i]);
printf(" pubkey33 ->\n");
for (i=0; i<20; i++)
printf("%02x",rmd160[i]);
printf(" destaddr.(%s)\n",destaddr);
calc_rmd160_sha256(rmd160,pubkey33,33);
for (i=0; i<20; i++)
printf("%02x",rmd160[i]);
printf(" <- vs direct calc\n");*/
spendlen = bitcoin_standardspend(spendscript,0,rmd160);
init_hexbytes_noT(hexstr,spendscript,spendlen);
jaddstr(sobj,"hex",hexstr);
jadd(item,"scriptPubKey",sobj);
jaddnum(item,"suppress",suppress_pubkeys);
jaddnum(item,"sequence",sequenceid);
if ( redeemlen != 0 )
else if ( rawtx == &swap->alicereclaim )
{
init_hexbytes_noT(hexstr,redeemscript,redeemlen);
jaddstr(item,"redeemScript",hexstr);
basilisk_dontforget(swap,&swap->alicepayment,0,swap->bobdeposit.I.actualtxid);
basilisk_dontforget(swap,&swap->alicereclaim,0,swap->bobrefund.I.actualtxid);
}
jaddi(vins,item);
jdelete(txobj,"vin");
jadd(txobj,"vin",vins);
txobj = bitcoin_txoutput(txobj,spendscript,spendlen,destamount);
if ( (rawtxbytes= bitcoin_json2hex(myinfo,coin,&txid,txobj,V)) != 0 )
else if ( rawtx == &swap->bobpayment )
{
//printf("locktime.%u sequenceid.%x rawtx.(%s) vins.(%s)\n",locktime,sequenceid,rawtxbytes,jprint(vins,0));
if ( (signedtx= iguana_signrawtx(myinfo,coin,height,&signedtxid,&completed,vins,rawtxbytes,privkeys,V)) == 0 )
printf("couldnt sign transaction\n");
else if ( completed == 0 )
printf("incomplete signing\n");
else printf("%s -> %s\n",name,bits256_str(str,signedtxid));
free(rawtxbytes);
} else printf("error making rawtx\n");
free_json(privkeys);
free_json(txobj);
free(V);
return(signedtx);
}
char *basilisk_swap_Aspend(char *name,struct supernet_info *myinfo,char *symbol,bits256 privAm,bits256 privBn,bits256 utxotxid,int32_t vout,uint8_t pubkey33[33],uint32_t expiration,int64_t *destamountp)
{
char msigaddr[64],*signedtx = 0; int32_t spendlen,redeemlen; uint8_t tmp33[33],redeemscript[512],spendscript[128]; bits256 pubAm,pubBn; struct iguana_info *coin = iguana_coinfind(symbol);
if ( coin != 0 && bits256_nonz(privAm) != 0 && bits256_nonz(privBn) != 0 )
basilisk_dontforget(swap,&swap->bobpayment,0,triggertxid);
basilisk_dontforget(swap,&swap->bobreclaim,swap->bobpayment.I.locktime,triggertxid);
}
else if ( rawtx == &swap->alicespend )
{
pubAm = bitcoin_pubkey33(myinfo->ctx,tmp33,privAm);
pubBn = bitcoin_pubkey33(myinfo->ctx,tmp33,privBn);
//char str[65];
//printf("pubAm.(%s)\n",bits256_str(str,pubAm));
//printf("pubBn.(%s)\n",bits256_str(str,pubBn));
spendlen = basilisk_alicescript(redeemscript,&redeemlen,spendscript,0,msigaddr,coin->chain->p2shtype,pubAm,pubBn);
//char str[65]; printf("%s utxo.(%s) redeemlen.%d spendlen.%d\n",msigaddr,bits256_str(str,utxotxid),redeemlen,spendlen);
/*rev = privAm;
for (i=0; i<32; i++)
privAm.bytes[i] = rev.bytes[31 - i];
rev = privBn;
for (i=0; i<32; i++)
privBn.bytes[i] = rev.bytes[31 - i];*/
signedtx = basilisk_swap_bobtxspend(name,myinfo,symbol,privAm,&privBn,redeemscript,redeemlen,0,0,utxotxid,vout,pubkey33,1,expiration,destamountp);
basilisk_dontforget(swap,&swap->bobpayment,0,triggertxid);
basilisk_dontforget(swap,&swap->alicespend,0,triggertxid);
}
return(signedtx);
else if ( rawtx == &swap->bobreclaim )
basilisk_dontforget(swap,&swap->bobreclaim,swap->bobpayment.I.locktime,triggertxid);
}
bits256 basilisk_swap_privbob_extract(struct supernet_info *myinfo,char *symbol,bits256 spendtxid,int32_t vini,int32_t revflag)
bits256 basilisk_swap_privbob_extract(char *symbol,bits256 spendtxid,int32_t vini,int32_t revflag)
{
bits256 privkey; int32_t i,scriptlen,siglen; uint8_t script[1024]; // from Bob refund of Bob deposit
memset(&privkey,0,sizeof(privkey));
if ( (scriptlen= basilisk_swap_getsigscript(myinfo,symbol,script,(int32_t)sizeof(script),spendtxid,vini)) > 0 )
if ( (scriptlen= basilisk_swap_getsigscript(symbol,script,(int32_t)sizeof(script),spendtxid,vini)) > 0 )
{
siglen = script[0];
for (i=0; i<32; i++)
@ -464,20 +366,20 @@ bits256 basilisk_swap_privbob_extract(struct supernet_info *myinfo,char *symbol,
return(privkey);
}
bits256 basilisk_swap_privBn_extract(struct supernet_info *myinfo,bits256 *bobrefundp,char *bobcoin,bits256 bobdeposit,bits256 privBn)
bits256 basilisk_swap_privBn_extract(bits256 *bobrefundp,char *bobcoin,bits256 bobdeposit,bits256 privBn)
{
char destaddr[64];
if ( bits256_nonz(privBn) == 0 )
{
if ( bits256_nonz(bobdeposit) != 0 )
*bobrefundp = basilisk_swap_spendtxid(myinfo,bobcoin,destaddr,bobdeposit,0);
*bobrefundp = LP_swap_spendtxid(bobcoin,destaddr,bobdeposit,0);
if ( bits256_nonz(*bobrefundp) != 0 )
privBn = basilisk_swap_privbob_extract(myinfo,bobcoin,*bobrefundp,0,0);
privBn = basilisk_swap_privbob_extract(bobcoin,*bobrefundp,0,0);
}
return(privBn);
}
bits256 basilisk_swap_spendupdate(struct supernet_info *myinfo,char *symbol,int32_t *sentflags,bits256 *txids,int32_t utxoind,int32_t alicespent,int32_t bobspent,int32_t vout,char *aliceaddr,char *bobaddr)
bits256 basilisk_swap_spendupdate(char *symbol,int32_t *sentflags,bits256 *txids,int32_t utxoind,int32_t alicespent,int32_t bobspent,int32_t vout,char *aliceaddr,char *bobaddr)
{
bits256 spendtxid,txid; char destaddr[64];
txid = txids[utxoind];
@ -489,7 +391,7 @@ bits256 basilisk_swap_spendupdate(struct supernet_info *myinfo,char *symbol,int3
if ( bits256_nonz(txid) != 0 )
{
//char str[65];
spendtxid = basilisk_swap_spendtxid(myinfo,symbol,destaddr,txid,vout);
spendtxid = LP_swap_spendtxid(symbol,destaddr,txid,vout);
if ( bits256_nonz(spendtxid) != 0 )
{
sentflags[utxoind] = 1;
@ -598,9 +500,12 @@ int32_t basilisk_swap_isfinished(int32_t iambob,bits256 *txids,int32_t *sentflag
return(0);
}
cJSON *basilisk_remember(struct supernet_info *myinfo,int64_t *KMDtotals,int64_t *BTCtotals,uint32_t requestid,uint32_t quoteid)
cJSON *basilisk_remember(int64_t *KMDtotals,int64_t *BTCtotals,uint32_t requestid,uint32_t quoteid)
{
FILE *fp; struct iguana_info *coin; int32_t sentflags[sizeof(txnames)/sizeof(*txnames)],i,n,j,len,needflag,secretstart,redeemlen,addflag,origfinishedflag = 0,finishedflag = 0,iambob = -1; int64_t srcamount,destamount=0,value,values[sizeof(txnames)/sizeof(*txnames)]; uint8_t secretAm[20],secretAm256[32],secretBn[20],secretBn256[32],pubkey33[33],redeemscript[1024],userdata[1024]; uint32_t plocktime,dlocktime,expiration=0,r,q,state,otherstate; char *secretstr,*srcstr,*deststr,str[65],src[64],dest[64],fname[512],*fstr,*dest33,*symbol,*txname,*Adest,*Bdest,*AAdest,*ABdest,destaddr[64],Adestaddr[64],alicecoin[64],bobcoin[64],*txbytes[sizeof(txnames)/sizeof(*txnames)]; long fsize; cJSON *txobj,*item,*sentobj,*array; bits256 checktxid,txid,pubA0,pubB0,pubB1,privAm,privBn,paymentspent,Apaymentspent,depositspent,zero,privkey,rev,myprivs[2],txids[sizeof(txnames)/sizeof(*txnames)];
static void *ctx;
FILE *fp; int32_t sentflags[sizeof(txnames)/sizeof(*txnames)],i,n,j,len,needflag,secretstart,redeemlen,addflag,origfinishedflag = 0,finishedflag = 0,iambob = -1; int64_t srcamount,destamount=0,value,values[sizeof(txnames)/sizeof(*txnames)]; uint8_t secretAm[20],secretAm256[32],secretBn[20],secretBn256[32],pubkey33[33],redeemscript[1024],userdata[1024]; uint32_t plocktime,dlocktime,expiration=0,r,q,state,otherstate; char *secretstr,*srcstr,*deststr,str[65],src[64],dest[64],fname[512],*fstr,*dest33,*symbol,*txname,*Adest,*Bdest,*AAdest,*ABdest,destaddr[64],Adestaddr[64],alicecoin[64],bobcoin[64],*txbytes[sizeof(txnames)/sizeof(*txnames)]; long fsize; cJSON *txobj,*item,*sentobj,*array; bits256 checktxid,txid,pubA0,pubB0,pubB1,privAm,privBn,paymentspent,Apaymentspent,depositspent,zero,privkey,rev,myprivs[2],txids[sizeof(txnames)/sizeof(*txnames)],signedtxid; struct iguana_info *bob=0,*alice=0; uint64_t txfee = 10000;
if ( ctx == 0 )
ctx = bitcoin_ctx();
memset(values,0,sizeof(values));
memset(txids,0,sizeof(txids));
memset(secretAm,0,sizeof(secretAm));
@ -753,7 +658,7 @@ cJSON *basilisk_remember(struct supernet_info *myinfo,int64_t *KMDtotals,int64_t
safecopy(alicecoin,symbol,sizeof(alicecoin));
if ( finishedflag == 0 )
{
if ( (sentobj= basilisk_swapgettx(myinfo,symbol,txid)) == 0 )
if ( (sentobj= LP_swapgettx(symbol,txid)) == 0 )
{
//printf("%s %s ready to broadcast\n",symbol,bits256_str(str2,txid));
}
@ -788,27 +693,27 @@ cJSON *basilisk_remember(struct supernet_info *myinfo,int64_t *KMDtotals,int64_t
{
if ( iambob == 0 )
{
if ( (coin= iguana_coinfind(alicecoin)) != 0 )
if ( (alice= LP_coinfind(alicecoin)) != 0 )
{
bitcoin_address(Adestaddr,coin->chain->pubtype,pubkey33,33);
bitcoin_address(Adestaddr,alice->pubtype,pubkey33,33);
AAdest = Adestaddr;
}
if ( (coin= iguana_coinfind(bobcoin)) != 0 )
if ( (bob= LP_coinfind(bobcoin)) != 0 )
{
bitcoin_address(destaddr,coin->chain->pubtype,pubkey33,33);
bitcoin_address(destaddr,bob->pubtype,pubkey33,33);
Adest = destaddr;
}
}
else
{
if ( (coin= iguana_coinfind(bobcoin)) != 0 )
if ( (bob= LP_coinfind(bobcoin)) != 0 )
{
bitcoin_address(destaddr,coin->chain->pubtype,pubkey33,33);
bitcoin_address(destaddr,bob->pubtype,pubkey33,33);
Bdest = destaddr;
}
if ( (coin= iguana_coinfind(alicecoin)) != 0 )
if ( (alice= LP_coinfind(alicecoin)) != 0 )
{
bitcoin_address(Adestaddr,coin->chain->pubtype,pubkey33,33);
bitcoin_address(Adestaddr,alice->pubtype,pubkey33,33);
ABdest = Adestaddr;
}
}
@ -817,15 +722,15 @@ cJSON *basilisk_remember(struct supernet_info *myinfo,int64_t *KMDtotals,int64_t
printf("txbytes.%p Apayment.%s\n",txbytes[BASILISK_ALICEPAYMENT],bits256_str(str,txids[BASILISK_ALICEPAYMENT]));
if ( txbytes[BASILISK_ALICEPAYMENT] != 0 )
sentflags[BASILISK_ALICEPAYMENT] = 1;
else if ( (sentobj= basilisk_swapgettx(myinfo,alicecoin,txids[BASILISK_ALICEPAYMENT])) != 0 )
else if ( (sentobj= LP_swapgettx(alicecoin,txids[BASILISK_ALICEPAYMENT])) != 0 )
{
sentflags[BASILISK_ALICEPAYMENT] = 1;
free_json(sentobj);
}
}
paymentspent = basilisk_swap_spendupdate(myinfo,bobcoin,sentflags,txids,BASILISK_BOBPAYMENT,BASILISK_ALICESPEND,BASILISK_BOBRECLAIM,0,Adest,Bdest);
Apaymentspent = basilisk_swap_spendupdate(myinfo,alicecoin,sentflags,txids,BASILISK_ALICEPAYMENT,BASILISK_ALICERECLAIM,BASILISK_BOBSPEND,0,AAdest,ABdest);
depositspent = basilisk_swap_spendupdate(myinfo,bobcoin,sentflags,txids,BASILISK_BOBDEPOSIT,BASILISK_ALICECLAIM,BASILISK_BOBREFUND,0,Adest,Bdest);
paymentspent = basilisk_swap_spendupdate(bobcoin,sentflags,txids,BASILISK_BOBPAYMENT,BASILISK_ALICESPEND,BASILISK_BOBRECLAIM,0,Adest,Bdest);
Apaymentspent = basilisk_swap_spendupdate(alicecoin,sentflags,txids,BASILISK_ALICEPAYMENT,BASILISK_ALICERECLAIM,BASILISK_BOBSPEND,0,AAdest,ABdest);
depositspent = basilisk_swap_spendupdate(bobcoin,sentflags,txids,BASILISK_BOBDEPOSIT,BASILISK_ALICECLAIM,BASILISK_BOBREFUND,0,Adest,Bdest);
finishedflag = basilisk_swap_isfinished(iambob,txids,sentflags,paymentspent,Apaymentspent,depositspent);
if ( iambob == 0 )
{
@ -845,13 +750,13 @@ cJSON *basilisk_remember(struct supernet_info *myinfo,int64_t *KMDtotals,int64_t
redeemlen = basilisk_swap_bobredeemscript(0,&secretstart,redeemscript,plocktime,pubA0,pubB0,pubB1,rev,privBn,secretAm,secretAm256,secretBn,secretBn256);
len = basilisk_swapuserdata(userdata,rev,0,myprivs[0],redeemscript,redeemlen);
printf("alicespend len.%d redeemlen.%d\n",len,redeemlen);
if ( (txbytes[BASILISK_ALICESPEND]= basilisk_swap_bobtxspend("alicespend",myinfo,bobcoin,myprivs[0],0,redeemscript,redeemlen,userdata,len,txids[BASILISK_BOBPAYMENT],0,pubkey33,1,expiration,&values[BASILISK_ALICESPEND])) != 0 )
if ( (txbytes[BASILISK_ALICESPEND]= basilisk_swap_bobtxspend(&signedtxid,txfee,"alicespend",bobcoin,bob->pubtype,bob->p2shtype,bob->isPoS,bob->wiftype,ctx,myprivs[0],0,redeemscript,redeemlen,userdata,len,txids[BASILISK_BOBPAYMENT],0,pubkey33,1,expiration,&values[BASILISK_ALICESPEND])) != 0 )
printf("alicespend.(%s)\n",txbytes[BASILISK_ALICESPEND]);
}
}
if ( txbytes[BASILISK_ALICESPEND] != 0 )
{
txids[BASILISK_ALICESPEND] = basilisk_swap_sendrawtransaction(myinfo,"alicespend",bobcoin,txbytes[BASILISK_ALICESPEND]);
txids[BASILISK_ALICESPEND] = basilisk_swap_sendrawtransaction("alicespend",bobcoin,txbytes[BASILISK_ALICESPEND]);
if ( bits256_nonz(txids[BASILISK_ALICESPEND]) != 0 ) // tested
{
sentflags[BASILISK_ALICESPEND] = 1;
@ -870,13 +775,13 @@ cJSON *basilisk_remember(struct supernet_info *myinfo,int64_t *KMDtotals,int64_t
if ( redeemlen > 0 )
{
len = basilisk_swapuserdata(userdata,zero,1,myprivs[0],redeemscript,redeemlen);
if ( (txbytes[BASILISK_ALICECLAIM]= basilisk_swap_bobtxspend("aliceclaim",myinfo,bobcoin,myprivs[0],0,redeemscript,redeemlen,userdata,len,txids[BASILISK_BOBDEPOSIT],0,pubkey33,0,expiration,&values[BASILISK_ALICECLAIM])) != 0 )
if ( (txbytes[BASILISK_ALICECLAIM]= basilisk_swap_bobtxspend(&signedtxid,txfee,"aliceclaim",bobcoin,bob->pubtype,bob->p2shtype,bob->isPoS,bob->wiftype,ctx,myprivs[0],0,redeemscript,redeemlen,userdata,len,txids[BASILISK_BOBDEPOSIT],0,pubkey33,0,expiration,&values[BASILISK_ALICECLAIM])) != 0 )
printf("privBn.(%s) aliceclaim.(%s)\n",bits256_str(str,privBn),txbytes[BASILISK_ALICECLAIM]);
}
}
if ( txbytes[BASILISK_ALICECLAIM] != 0 )
{
txids[BASILISK_ALICECLAIM] = basilisk_swap_sendrawtransaction(myinfo,"aliceclaim",bobcoin,txbytes[BASILISK_ALICECLAIM]);
txids[BASILISK_ALICECLAIM] = basilisk_swap_sendrawtransaction("aliceclaim",bobcoin,txbytes[BASILISK_ALICECLAIM]);
if ( bits256_nonz(txids[BASILISK_ALICECLAIM]) != 0 ) // tested
{
sentflags[BASILISK_ALICECLAIM] = 1;
@ -889,16 +794,16 @@ cJSON *basilisk_remember(struct supernet_info *myinfo,int64_t *KMDtotals,int64_t
{
//if ( txbytes[BASILISK_ALICERECLAIM] == 0 )
{
privBn = basilisk_swap_privBn_extract(myinfo,&txids[BASILISK_BOBREFUND],bobcoin,txids[BASILISK_BOBDEPOSIT],privBn);
privBn = basilisk_swap_privBn_extract(&txids[BASILISK_BOBREFUND],bobcoin,txids[BASILISK_BOBDEPOSIT],privBn);
if ( bits256_nonz(txids[BASILISK_ALICEPAYMENT]) != 0 && bits256_nonz(privAm) != 0 && bits256_nonz(privBn) != 0 )
{
if ( (txbytes[BASILISK_ALICERECLAIM]= basilisk_swap_Aspend("alicereclaim",myinfo,alicecoin,privAm,privBn,txids[BASILISK_ALICEPAYMENT],0,pubkey33,expiration,&values[BASILISK_ALICERECLAIM])) != 0 )
if ( (txbytes[BASILISK_ALICERECLAIM]= basilisk_swap_Aspend("alicereclaim",alicecoin,alice->pubtype,alice->p2shtype,alice->isPoS,alice->wiftype,ctx,privAm,privBn,txids[BASILISK_ALICEPAYMENT],0,pubkey33,expiration,&values[BASILISK_ALICERECLAIM])) != 0 )
printf("privBn.(%s) alicereclaim.(%s)\n",bits256_str(str,privBn),txbytes[BASILISK_ALICERECLAIM]);
}
}
if ( txbytes[BASILISK_ALICERECLAIM] != 0 )
{
txids[BASILISK_ALICERECLAIM] = basilisk_swap_sendrawtransaction(myinfo,"alicereclaim",alicecoin,txbytes[BASILISK_ALICERECLAIM]);
txids[BASILISK_ALICERECLAIM] = basilisk_swap_sendrawtransaction("alicereclaim",alicecoin,txbytes[BASILISK_ALICERECLAIM]);
if ( bits256_nonz(txids[BASILISK_ALICERECLAIM]) != 0 ) // tested
{
sentflags[BASILISK_ALICERECLAIM] = 1;
@ -918,17 +823,17 @@ cJSON *basilisk_remember(struct supernet_info *myinfo,int64_t *KMDtotals,int64_t
{
if ( bits256_nonz(privAm) == 0 )
{
privAm = basilisk_swap_privbob_extract(myinfo,bobcoin,txids[BASILISK_ALICESPEND],0,1);
privAm = basilisk_swap_privbob_extract(bobcoin,txids[BASILISK_ALICESPEND],0,1);
}
if ( bits256_nonz(privAm) != 0 && bits256_nonz(privBn) != 0 )
{
if ( (txbytes[BASILISK_BOBSPEND]= basilisk_swap_Aspend("bobspend",myinfo,alicecoin,privAm,privBn,txids[BASILISK_ALICEPAYMENT],0,pubkey33,expiration,&values[BASILISK_BOBSPEND])) != 0 )
if ( (txbytes[BASILISK_BOBSPEND]= basilisk_swap_Aspend("bobspend",alicecoin,alice->pubtype,alice->p2shtype,alice->isPoS,alice->wiftype,ctx,privAm,privBn,txids[BASILISK_ALICEPAYMENT],0,pubkey33,expiration,&values[BASILISK_BOBSPEND])) != 0 )
printf("bobspend.(%s)\n",txbytes[BASILISK_BOBSPEND]);
}
}
if ( txbytes[BASILISK_BOBSPEND] != 0 )
{
txids[BASILISK_BOBSPEND] = basilisk_swap_sendrawtransaction(myinfo,"bobspend",alicecoin,txbytes[BASILISK_BOBSPEND]);
txids[BASILISK_BOBSPEND] = basilisk_swap_sendrawtransaction("bobspend",alicecoin,txbytes[BASILISK_BOBSPEND]);
if ( bits256_nonz(txids[BASILISK_BOBSPEND]) != 0 ) // tested
{
sentflags[BASILISK_BOBSPEND] = 1;
@ -946,7 +851,7 @@ cJSON *basilisk_remember(struct supernet_info *myinfo,int64_t *KMDtotals,int64_t
if ( redeemlen > 0 )
{
len = basilisk_swapuserdata(userdata,zero,1,myprivs[1],redeemscript,redeemlen);
if ( (txbytes[BASILISK_BOBRECLAIM]= basilisk_swap_bobtxspend("bobrefund",myinfo,bobcoin,myprivs[1],0,redeemscript,redeemlen,userdata,len,txids[BASILISK_BOBPAYMENT],0,pubkey33,0,expiration,&values[BASILISK_BOBRECLAIM])) != 0 )
if ( (txbytes[BASILISK_BOBRECLAIM]= basilisk_swap_bobtxspend(&signedtxid,txfee,"bobrefund",bobcoin,bob->pubtype,bob->p2shtype,bob->isPoS,bob->wiftype,ctx,myprivs[1],0,redeemscript,redeemlen,userdata,len,txids[BASILISK_BOBPAYMENT],0,pubkey33,0,expiration,&values[BASILISK_BOBRECLAIM])) != 0 )
{
int32_t z;
for (z=0; z<20; z++)
@ -957,7 +862,7 @@ cJSON *basilisk_remember(struct supernet_info *myinfo,int64_t *KMDtotals,int64_t
}
if ( txbytes[BASILISK_BOBRECLAIM] != 0 )
{
txids[BASILISK_BOBRECLAIM] = basilisk_swap_sendrawtransaction(myinfo,"bobreclaim",bobcoin,txbytes[BASILISK_BOBRECLAIM]);
txids[BASILISK_BOBRECLAIM] = basilisk_swap_sendrawtransaction("bobreclaim",bobcoin,txbytes[BASILISK_BOBRECLAIM]);
if ( bits256_nonz(txids[BASILISK_BOBRECLAIM]) != 0 ) // tested
{
sentflags[BASILISK_BOBRECLAIM] = 1;
@ -976,12 +881,12 @@ cJSON *basilisk_remember(struct supernet_info *myinfo,int64_t *KMDtotals,int64_t
vcalc_sha256(0,secretBn256,privBn.bytes,sizeof(privBn));
redeemlen = basilisk_swap_bobredeemscript(1,&secretstart,redeemscript,dlocktime,pubA0,pubB0,pubB1,privAm,privBn,secretAm,secretAm256,secretBn,secretBn256);
len = basilisk_swapuserdata(userdata,privBn,0,myprivs[0],redeemscript,redeemlen);
if ( (txbytes[BASILISK_BOBREFUND]= basilisk_swap_bobtxspend("bobrefund",myinfo,bobcoin,myprivs[0],0,redeemscript,redeemlen,userdata,len,txids[BASILISK_BOBDEPOSIT],0,pubkey33,1,expiration,&values[BASILISK_BOBREFUND])) != 0 )
if ( (txbytes[BASILISK_BOBREFUND]= basilisk_swap_bobtxspend(&signedtxid,txfee,"bobrefund",bobcoin,bob->pubtype,bob->p2shtype,bob->isPoS,bob->wiftype,ctx,myprivs[0],0,redeemscript,redeemlen,userdata,len,txids[BASILISK_BOBDEPOSIT],0,pubkey33,1,expiration,&values[BASILISK_BOBREFUND])) != 0 )
printf("pubB1.(%s) bobrefund.(%s)\n",bits256_str(str,pubB1),txbytes[BASILISK_BOBREFUND]);
}
if ( txbytes[BASILISK_BOBREFUND] != 0 )
{
txids[BASILISK_BOBREFUND] = basilisk_swap_sendrawtransaction(myinfo,"bobrefund",bobcoin,txbytes[BASILISK_BOBREFUND]);
txids[BASILISK_BOBREFUND] = basilisk_swap_sendrawtransaction("bobrefund",bobcoin,txbytes[BASILISK_BOBREFUND]);
if ( bits256_nonz(txids[BASILISK_BOBREFUND]) != 0 ) // tested
{
sentflags[BASILISK_BOBREFUND] = 1;
@ -1001,7 +906,7 @@ cJSON *basilisk_remember(struct supernet_info *myinfo,int64_t *KMDtotals,int64_t
sentflags[BASILISK_BOBDEPOSIT] = 1;
for (i=0; i<sizeof(txnames)/sizeof(*txnames); i++)
if ( bits256_nonz(txids[i]) != 0 && values[i] == 0 )
values[i] = basilisk_txvalue(myinfo,basilisk_isbobcoin(iambob,i) ? bobcoin : alicecoin,txids[i],0);
values[i] = basilisk_txvalue(basilisk_isbobcoin(iambob,i) ? bobcoin : alicecoin,txids[i],0);
if ( origfinishedflag == 0 )
{
printf("iambob.%d Apaymentspent.(%s) alice.%d bob.%d %s %.8f\n",iambob,bits256_str(str,Apaymentspent),sentflags[BASILISK_ALICERECLAIM],sentflags[BASILISK_BOBSPEND],alicecoin,dstr(values[BASILISK_ALICEPAYMENT]));
@ -1101,7 +1006,7 @@ cJSON *basilisk_remember(struct supernet_info *myinfo,int64_t *KMDtotals,int64_t
return(item);
}
char *basilisk_swaplist(struct supernet_info *myinfo)
char *basilisk_swaplist()
{
char fname[512],*status; FILE *fp; cJSON *item,*retjson,*array,*totalsobj; uint32_t quoteid,requestid; int64_t KMDtotals[16],BTCtotals[16],Btotal,Ktotal; int32_t i;
memset(KMDtotals,0,sizeof(KMDtotals));
@ -1112,20 +1017,21 @@ char *basilisk_swaplist(struct supernet_info *myinfo)
sprintf(fname,"%s/SWAPS/list",GLOBAL_DBDIR), OS_compatible_path(fname);
if ( (fp= fopen(fname,"rb")) != 0 )
{
struct basilisk_swap *swap; int32_t flag = 0;
//struct basilisk_swap *swap;
int32_t flag = 0;
while ( fread(&requestid,1,sizeof(requestid),fp) == sizeof(requestid) && fread(&quoteid,1,sizeof(quoteid),fp) == sizeof(quoteid) )
{
flag = 0;
for (i=0; i<myinfo->numswaps; i++)
/*for (i=0; i<myinfo->numswaps; i++)
if ( (swap= myinfo->swaps[i]) != 0 && swap->I.req.requestid == requestid && swap->I.req.quoteid == quoteid )
{
jaddi(array,basilisk_swapjson(myinfo,swap));
jaddi(array,basilisk_swapjson(swap));
flag = 1;
break;
}
}*/
if ( flag == 0 )
{
if ( (item= basilisk_remember(myinfo,KMDtotals,BTCtotals,requestid,quoteid)) != 0 )
if ( (item= basilisk_remember(KMDtotals,BTCtotals,requestid,quoteid)) != 0 )
{
jaddi(array,item);
if ( 1 && (status= jstr(item,"status")) != 0 && strcmp(status,"pending") == 0 )
@ -1157,12 +1063,12 @@ char *basilisk_swaplist(struct supernet_info *myinfo)
jaddnum(retjson,"avesell",(double)-Btotal/Ktotal);
}
array = cJSON_CreateArray();
for (i=0; i<sizeof(myinfo->linfos)/sizeof(*myinfo->linfos); i++)
/*for (i=0; i<sizeof(myinfo->linfos)/sizeof(*myinfo->linfos); i++)
{
if ( myinfo->linfos[i].base[0] != 0 && myinfo->linfos[i].rel[0] != 0 )
jaddi(array,linfo_json(&myinfo->linfos[i]));
}
jadd(retjson,"quotes",array);
jadd(retjson,"quotes",array);*/
return(jprint(retjson,1));
}

505
iguana/exchanges/LP_rpc.c

@ -0,0 +1,505 @@
/******************************************************************************
* Copyright © 2014-2017 The SuperNET Developers. *
* *
* See the AUTHORS, DEVELOPER-AGREEMENT and LICENSE files at *
* the top-level directory of this distribution for the individual copyright *
* holder information and the developer policies on copyright and licensing. *
* *
* Unless otherwise agreed in a custom licensing agreement, no part of the *
* SuperNET software, including this file may be copied, modified, propagated *
* or distributed except according to the terms contained in the LICENSE file *
* *
* Removal or modification of this copyright notice is prohibited. *
* *
******************************************************************************/
//
// LP_rpc.c
// marketmaker
//
cJSON *basilisk_nullretjson(cJSON *retjson)
{
char *outstr;
if ( retjson != 0 )
{
outstr = jprint(retjson,0);
if ( strcmp(outstr,"{}") == 0 )
{
free_json(retjson);
retjson = 0;
}
free(outstr);
}
return(retjson);
}
void LP_unspentslock(char *symbol,cJSON *vins)
{
}
void LP_unspents_mark(char *symbol,cJSON *vins)
{
}
uint64_t LP_getestimatedfee(char *symbol)
{
return(200);
}
uint64_t LP_txfee(char *symbol)
{
return(10000);
}
char *dpow_validateaddress(struct supernet_info *myinfo,struct iguana_info *coin,char *address)
{
char buf[128],*retstr=0;
if ( coin->FULLNODE < 0 )
{
sprintf(buf,"\"%s\"",address);
retstr = bitcoind_passthru(coin->symbol,coin->chain->serverport,coin->chain->userpass,"validateaddress",buf);
usleep(10000);
}
else if ( coin->FULLNODE > 0 || coin->VALIDATENODE > 0 )
{
retstr = bitcoinrpc_validateaddress(myinfo,coin,0,0,address);
}
else
{
return(0);
}
return(retstr);
}
cJSON *dpow_gettxout(struct supernet_info *myinfo,struct iguana_info *coin,bits256 txid,int32_t vout)
{
char buf[128],str[65],*retstr=0; cJSON *json = 0;
sprintf(buf,"\"%s\", %d",bits256_str(str,txid),vout);
if ( coin->FULLNODE < 0 )
{
retstr = bitcoind_passthru(coin->symbol,coin->chain->serverport,coin->chain->userpass,"gettxout",buf);
usleep(10000);
}
else if ( coin->FULLNODE > 0 || coin->VALIDATENODE > 0 )
{
printf("need to test following call\n");
retstr = bitcoinrpc_gettxout(myinfo,coin,0,buf,txid,1,0); // untested
}
else
{
return(0);
}
if ( retstr != 0 )
{
json = cJSON_Parse(retstr);
free(retstr);
}
//printf("dpow_gettxout.(%s)\n",retstr);
return(json);
}
char *dpow_decoderawtransaction(struct supernet_info *myinfo,struct iguana_info *coin,char *rawtx)
{
char *retstr,*paramstr; cJSON *array;
if ( coin->FULLNODE < 0 )
{
array = cJSON_CreateArray();
jaddistr(array,rawtx);
paramstr = jprint(array,1);
retstr = bitcoind_passthru(coin->symbol,coin->chain->serverport,coin->chain->userpass,"decoderawtransaction",paramstr);
//printf("%s decoderawtransaction.(%s) <- (%s)\n",coin->symbol,retstr,paramstr);
free(paramstr);
usleep(10000);
}
else if ( coin->FULLNODE > 0 || coin->VALIDATENODE > 0 )
{
retstr = bitcoinrpc_decoderawtransaction(myinfo,coin,0,0,rawtx,1);
}
else
{
return(0);
}
return(retstr);
}
cJSON *dpow_gettransaction(struct supernet_info *myinfo,struct iguana_info *coin,bits256 txid)
{
char buf[128],str[65],*retstr=0; cJSON *json = 0;
if ( coin->FULLNODE < 0 )
{
sprintf(buf,"[\"%s\", 1]",bits256_str(str,txid));
if ( (retstr= bitcoind_passthru(coin->symbol,coin->chain->serverport,coin->chain->userpass,"getrawtransaction",buf)) != 0 )
{
}
usleep(10000);
}
else if ( coin->FULLNODE > 0 || coin->VALIDATENODE > 0 )
{
retstr = bitcoinrpc_getrawtransaction(myinfo,coin,0,0,txid,1);
}
else
{
return(0);
}
if ( retstr != 0 )
{
json = cJSON_Parse(retstr);
free(retstr);
}
return(json);
}
cJSON *dpow_listunspent(struct supernet_info *myinfo,struct iguana_info *coin,char *coinaddr)
{
char buf[128],*retstr; cJSON *array,*json = 0;
if ( coin->FULLNODE < 0 )
{
sprintf(buf,"0, 99999999, [\"%s\"]",coinaddr);
if ( (retstr= bitcoind_passthru(coin->symbol,coin->chain->serverport,coin->chain->userpass,"listunspent",buf)) != 0 )
{
json = cJSON_Parse(retstr);
//printf("%s (%s) listunspent.(%s)\n",coin->symbol,buf,retstr);
free(retstr);
} else printf("%s null retstr from (%s)n",coin->symbol,buf);
}
else if ( coin->FULLNODE > 0 || coin->VALIDATENODE > 0 )
{
array = cJSON_CreateArray();
jaddistr(array,coinaddr);
json = iguana_listunspents(myinfo,coin,array,1,coin->longestchain,"");
free_json(array);
}
else
{
return(0);
}
return(json);
}
cJSON *dpow_listtransactions(struct supernet_info *myinfo,struct iguana_info *coin,char *coinaddr,int32_t count,int32_t skip)
{
char buf[128],*retstr; cJSON *json = 0;
if ( coin->FULLNODE < 0 )
{
if ( count == 0 )
count = 100;
sprintf(buf,"[\"%s\", %d, %d, true]",coinaddr,count,skip);
if ( (retstr= bitcoind_passthru(coin->symbol,coin->chain->serverport,coin->chain->userpass,"listtransactions",buf)) != 0 )
{
//printf("LIST.(%s)\n",retstr);
json = cJSON_Parse(retstr);
free(retstr);
return(json);
} else printf("%s null retstr from (%s)n",coin->symbol,buf);
}
return(0);
}
char *dpow_signrawtransaction(struct supernet_info *myinfo,struct iguana_info *coin,char *rawtx,cJSON *vins)
{
cJSON *array,*privkeys,*item; char *wifstr,*str,*paramstr,*retstr; uint8_t script[256]; int32_t i,n,len,hashtype; struct vin_info V; struct iguana_waddress *waddr; struct iguana_waccount *wacct;
if ( coin->FULLNODE < 0 )
{
array = cJSON_CreateArray();
jaddistr(array,rawtx);
jaddi(array,jduplicate(vins));
paramstr = jprint(array,1);
//printf("signrawtransaction\n");
retstr = bitcoind_passthru(coin->symbol,coin->chain->serverport,coin->chain->userpass,"signrawtransaction",paramstr);
//printf("%s signrawtransaction.(%s) params.(%s)\n",coin->symbol,retstr,paramstr);
free(paramstr);
usleep(10000);
return(retstr);
}
else if ( coin->FULLNODE > 0 || coin->VALIDATENODE > 0 )
{
privkeys = cJSON_CreateArray();
if ( (n= cJSON_GetArraySize(vins)) > 0 )
{
for (i=0; i<n; i++)
{
wifstr = "";
item = jitem(vins,i);
if ( (str= jstr(item,"scriptPubkey")) != 0 && is_hexstr(str,0) > 0 && strlen(str) < sizeof(script)*2 )
{
len = (int32_t)strlen(str) >> 1;
decode_hex(script,len,str);
V.spendlen = len;
memcpy(V.spendscript,script,len);
if ( (hashtype= _iguana_calcrmd160(coin,&V)) >= 0 && V.coinaddr[0] != 0 )
{
if ( (waddr= iguana_waddresssearch(myinfo,&wacct,V.coinaddr)) != 0 )
{
if ( bits256_nonz(waddr->privkey) != 0 )
{
if ( bitcoin_priv2wif(waddr->wifstr,waddr->privkey,coin->chain->wiftype) > 0 )
{
wifstr = waddr->wifstr;
}
}
}
}
}
jaddistr(privkeys,wifstr);
}
}
retstr = bitcoinrpc_signrawtransaction(myinfo,coin,0,0,rawtx,vins,privkeys,"ALL");
printf("call sign.(%s) vins.(%s) privs.(%s) -> (%s)\n",rawtx,jprint(vins,0),jprint(privkeys,0),retstr);
free_json(privkeys);
return(retstr);
}
else
{
return(0);
}
}
char *dpow_sendrawtransaction(struct supernet_info *myinfo,struct iguana_info *coin,char *signedtx)
{
bits256 txid; cJSON *json,*array; char *paramstr,*retstr;
if ( coin->FULLNODE < 0 )
{
array = cJSON_CreateArray();
jaddistr(array,signedtx);
paramstr = jprint(array,1);
retstr = bitcoind_passthru(coin->symbol,coin->chain->serverport,coin->chain->userpass,"sendrawtransaction",paramstr);
printf(">>>>>>>>>>> %s dpow_sendrawtransaction.(%s) -> (%s)\n",coin->symbol,paramstr,retstr);
free(paramstr);
return(retstr);
}
else if ( coin->FULLNODE > 0 || coin->VALIDATENODE > 0 )
{
txid = iguana_sendrawtransaction(myinfo,coin,signedtx);
json = cJSON_CreateObject();
jaddbits256(json,"result",txid);
return(jprint(json,1));
}
else
{
return(0);
}
}
char *LP_importaddress(char *symbol,char *address)
{
char buf[1024],*retstr; cJSON *validatejson; int32_t isvalid=0,doneflag = 0;
if ( (retstr= LP_validateaddress(symbol,address)) != 0 )
{
if ( (validatejson= cJSON_Parse(retstr)) != 0 )
{
if ( (isvalid= is_cJSON_True(jobj(validatejson,"isvalid")) != 0) != 0 )
{
if ( is_cJSON_True(jobj(validatejson,"iswatchonly")) != 0 || is_cJSON_True(jobj(validatejson,"ismine")) != 0 )
doneflag = 1;
}
free_json(validatejson);
}
free(retstr);
retstr = 0;
}
if ( isvalid == 0 )
return(clonestr("{\"isvalid\":false}"));
update_alladdresses(myinfo,coin,address);
if ( doneflag != 0 )
return(0); // success
if ( coin->FULLNODE < 0 )
{
sprintf(buf,"[\"%s\", \"%s\", false]",address,address);
retstr = bitcoind_passthru(coin->symbol,coin->chain->serverport,coin->chain->userpass,"importaddress",buf);
printf("%s importaddress.(%s) -> (%s)\n",coin->symbol,address,retstr);
return(retstr);
}
else return(0);
}
char *LP_importaddress(char *symbol,char *coinaddr)
{
return(0);
}
char *LP_sendrawtransaction(char *symbol,char *signedtx)
{
return(0);
}
char *LP_signrawtx(char *symbol,bits256 *signedtxidp,int32_t *completedp,cJSON *vins,char *rawtxbytes,cJSON *privkeys,struct vin_info *V)
{
return(0);
}
cJSON *LP_listtransactions(char *symbol,char *coinaddr,int32_t num,int32_t skip)
{
return(0);
}
char *dex_listtransactions(char *symbol,char *coinaddr,int32_t num,int32_t skip)
{
return(0);
}
bits256 LP_privkey(char *coinaddr)
{
bits256 privkey;
return(privkey);
}
bits256 LP_pubkey(bits256 privkey)
{
bits256 pubkey;
pubkey = curve25519(privkey,curve25519_basepoint9());
return(pubkey);
}
cJSON *LP_swapgettxout(char *symbol,bits256 trigger,int32_t vout)
{
cJSON *retjson=0; //char *retstr; struct iguana_info *coin;
/*if ( ((coin= iguana_coinfind(symbol)) == 0 || coin->FULLNODE == 0) && iguana_isnotarychain(symbol) >= 0 )
{
if ( (retstr= dex_gettxout(0,0,0,trigger,symbol,vout)) != 0 )
{
//printf("dexgettxout.(%s)\n",retstr);
retjson = cJSON_Parse(retstr);
free(retstr);
}
if ( 0 && strcmp("BTC",symbol) == 0 )
printf("%s gettxout.(%s)\n",symbol,jprint(retjson,0));
}
else
{
retjson = dpow_gettxout(coin,trigger,vout);
//printf("need to verify passthru has this info\n");
//printf("dpowgettxout.(%s)\n",jprint(retjson,0));
}*/
return(basilisk_nullretjson(retjson));
}
uint64_t LP_txvalue(char *symbol,bits256 txid,int32_t vout)
{
uint64_t value = 0;
return(value);
}
cJSON *LP_swapgettx(char *symbol,bits256 txid)
{
cJSON *retjson=0; //char *retstr; struct iguana_info *coin;
/*if ( ((coin= iguana_coinfind(symbol)) == 0 || coin->FULLNODE == 0) && iguana_isnotarychain(symbol) >= 0 )
{
if ( (retstr= dex_gettransaction(0,0,0,txid,symbol)) != 0 )
{
retjson = cJSON_Parse(retstr);
free(retstr);
}
//if ( strcmp("BTC",symbol) == 0 )
// printf("%s gettx.(%s)\n",symbol,jprint(retjson,0));
} else retjson = dpow_gettransaction(coin,txid);*/
return(basilisk_nullretjson(retjson));
}
bits256 basilisk_swap_sendrawtransaction(char *txname,char *symbol,char *txbytes)
{
char *retstr; bits256 txid; int32_t i,sentflag = 0;
memset(&txid,0,sizeof(txid));
for (i=0; i<3; i++)
{
if ( (retstr= LP_sendrawtransaction(symbol,txbytes)) != 0 )
{
if ( is_hexstr(retstr,0) == 64 )
{
decode_hex(txid.bytes,32,retstr);
sentflag = 1;
}
char str[65]; printf("[%s] %s RETSTR.(%s) %s.%s\n",txname,txbytes,retstr,symbol,bits256_str(str,txid));
free(retstr);
}
if ( sentflag != 0 )
break;
}
return(txid);
}
bits256 LP_broadcast(char *name,char *symbol,uint8_t *data,int32_t datalen)
{
bits256 txid; char *signedtx,*retstr; int32_t i;
memset(txid.bytes,0,sizeof(txid));
if ( data != 0 && datalen != 0 )
{
char str[65];
#ifdef BASILISK_DISABLESENDTX
txid = bits256_doublesha256(0,data,datalen);
printf("%s <- dont sendrawtransaction (%s)\n",name,bits256_str(str,txid));
return(txid);
#endif
signedtx = malloc(datalen*2 + 1);
init_hexbytes_noT(signedtx,data,datalen);
for (i=0; i<3; i++)
{
if ( (retstr= LP_sendrawtransaction(symbol,signedtx)) != 0 )
{
if ( is_hexstr(retstr,0) == 64 )
{
decode_hex(txid.bytes,32,retstr);
free(retstr);
printf("sendrawtransaction.%s %s.(%s)\n",name,symbol,bits256_str(str,txid));
break;
}
else
{
printf("sendrawtransaction.%s %s error.(%s)\n",name,symbol,retstr);
free(retstr);
}
} else printf("sendrawtransaction.%s %s got null return\n",name,symbol);
}
free(signedtx);
}
return(txid);
}
int32_t basilisk_confirmsobj(cJSON *item)
{
int32_t height,numconfirms;
height = jint(item,"height");
numconfirms = jint(item,"numconfirms");
if ( height > 0 && numconfirms >= 0 )
return(numconfirms);
printf("basilisk_confirmsobj height.%d numconfirms.%d (%s)\n",height,numconfirms,jprint(item,0));
return(-1);
}
int32_t LP_numconfirms(struct basilisk_swap *swap,struct basilisk_rawtx *rawtx)
{
#ifdef BASILISK_DISABLEWAITTX
return(100);
#endif
/*cJSON *argjson,*valuearray=0; char *valstr; int32_t i,n,retval = -1;
argjson = cJSON_CreateObject();
jaddbits256(argjson,"txid",rawtx->I.actualtxid);
jaddnum(argjson,"vout",0);
jaddstr(argjson,"coin",rawtx->coin->symbol);
if ( (valstr= basilisk_value(rawtx->coin,0,0,swap->persistent_pubkey,argjson,0)) != 0 )
{
char str[65]; printf("basilisk_numconfirms required.%d %s %s valstr.(%s)\n",rawtx->I.numconfirms,rawtx->name,bits256_str(str,rawtx->I.actualtxid),valstr);
//basilisk_numconfirms required.0 alicespend 29a2a6b4a61b1da82096d533c71b6762d61a82ca771a633269d97c0ccb94fe85 valstr.({"result":"success","numconfirms":0,"address":"1JGvZ67oTdM7kCya4J8kj1uErbSRAoq3wH","satoshis":"1413818","value":0.01413818,"height":462440,"txid":"29a2a6b4a61b1da82096d533c71b6762d61a82ca771a633269d97c0ccb94fe85","vout":0,"coin":"BTC"})
if ( (valuearray= cJSON_Parse(valstr)) != 0 )
{
if ( valstr[0] == '[' && is_cJSON_Array(valuearray) != 0 )
{
n = cJSON_GetArraySize(valuearray);
for (i=0; i<n; i++)
{
printf("i.%d of n.%d\n",i,n);
if ( (retval= basilisk_confirmsobj(jitem(valuearray,i))) >= 0 )
break;
}
} else retval = basilisk_confirmsobj(valuearray);
free_json(valuearray);
} else printf("parse error\n");
free(valstr);
}
free_json(argjson);
printf("numconfirms.%d returned\n",retval);
return(retval);*/
}

186
iguana/exchanges/LP_secp.c

@ -0,0 +1,186 @@
/******************************************************************************
* Copyright © 2014-2017 The SuperNET Developers. *
* *
* See the AUTHORS, DEVELOPER-AGREEMENT and LICENSE files at *
* the top-level directory of this distribution for the individual copyright *
* holder information and the developer policies on copyright and licensing. *
* *
* Unless otherwise agreed in a custom licensing agreement, no part of the *
* SuperNET software, including this file may be copied, modified, propagated *
* or distributed except according to the terms contained in the LICENSE file *
* *
* Removal or modification of this copyright notice is prohibited. *
* *
******************************************************************************/
//
// LP_secp.c
// marketmaker
//
#include <ctype.h>
#include <string.h>
#include <stdio.h>
#include <stdlib.h>
#include "../../includes/curve25519.h"
#include "../secp256k1/include/secp256k1.h"
#include "../secp256k1/include/secp256k1_ecdh.h"
#include "../secp256k1/include/secp256k1_schnorr.h"
#include "../secp256k1/include/secp256k1_rangeproof.h"
#include "../secp256k1/include/secp256k1_recovery.h"
SECP256K1_API extern const secp256k1_nonce_function secp256k1_nonce_function_rfc6979;
#define bits256_nonz(a) (((a).ulongs[0] | (a).ulongs[1] | (a).ulongs[2] | (a).ulongs[3]) != 0)
#define SECP_ENSURE_CTX int32_t flag = 0; if ( ctx == 0 ) { ctx = secp256k1_context_create(SECP256K1_CONTEXT_SIGN | SECP256K1_CONTEXT_VERIFY); secp256k1_pedersen_context_initialize(ctx); secp256k1_rangeproof_context_initialize(ctx); flag++; } else flag = 0; if ( ctx != 0 )
#define ENDSECP_ENSURE_CTX if ( flag != 0 ) secp256k1_context_destroy(ctx);
void *bitcoin_ctx()
{
void *ctx = secp256k1_context_create(SECP256K1_CONTEXT_SIGN | SECP256K1_CONTEXT_VERIFY);
secp256k1_pedersen_context_initialize(ctx);
secp256k1_rangeproof_context_initialize(ctx);
return(ctx);
}
bits256 bitcoin_pubkey33(void *ctx,uint8_t *data,bits256 privkey)
{
size_t plen; bits256 pubkey; secp256k1_pubkey secppub;
memset(pubkey.bytes,0,sizeof(pubkey));
SECP_ENSURE_CTX
{
if ( secp256k1_ec_seckey_verify(ctx,privkey.bytes) == 0 )
{
//printf("bitcoin_sign illegal privkey\n");
return(pubkey);
}
if ( secp256k1_ec_pubkey_create(ctx,&secppub,privkey.bytes) != 0 )
{
plen = 33;
secp256k1_ec_pubkey_serialize(ctx,data,&plen,&secppub,SECP256K1_EC_COMPRESSED);
if ( plen == 33 )
memcpy(pubkey.bytes,data+1,sizeof(pubkey));
}
ENDSECP_ENSURE_CTX
}
return(pubkey);
}
bits256 bitcoin_pub256(void *ctx,bits256 *privkeyp,uint8_t odd_even)
{
bits256 pub256; uint8_t pubkey[33]; int32_t i;
for (i=0; i<100; i++)
{
*privkeyp = rand256(0);
pub256 = bitcoin_pubkey33(ctx,pubkey,*privkeyp);
if ( pubkey[0] == odd_even+2 )
return(pub256);
}
printf("bitcoin_pub256 couldnt generate pubkey.%d\n",odd_even+2);
memset(pub256.bytes,0,sizeof(pub256));
return(pub256);
}
int32_t bitcoin_sign(void *ctx,char *symbol,uint8_t *sig,bits256 txhash2,bits256 privkey,int32_t recoverflag)
{
int32_t fCompressed = 1;
secp256k1_ecdsa_signature SIG; secp256k1_ecdsa_recoverable_signature rSIG; bits256 extra_entropy,seed; int32_t recid,retval = -1; size_t siglen = 72; secp256k1_pubkey SECPUB,CHECKPUB;
seed = rand256(0);
extra_entropy = rand256(0);
SECP_ENSURE_CTX
{
if ( secp256k1_ec_seckey_verify(ctx,privkey.bytes) == 0 )
{
//printf("bitcoin_sign illegal privkey\n");
return(-1);
}
if ( secp256k1_context_randomize(ctx,seed.bytes) != 0 )
{
if ( recoverflag != 0 )
{
if ( secp256k1_ecdsa_sign_recoverable(ctx,&rSIG,txhash2.bytes,privkey.bytes,secp256k1_nonce_function_rfc6979,extra_entropy.bytes) != 0 )
{
recid = -1;
secp256k1_ecdsa_recoverable_signature_serialize_compact(ctx,sig+1,&recid,&rSIG);
if ( secp256k1_ecdsa_recover(ctx,&SECPUB,&rSIG,txhash2.bytes) != 0 )
{
if ( secp256k1_ec_pubkey_create(ctx,&CHECKPUB,privkey.bytes) != 0 )
{
if ( memcmp(&SECPUB,&CHECKPUB,sizeof(SECPUB)) == 0 )
{
sig[0] = 27 + recid + (fCompressed != 0 ? 4 : 0);
retval = 64 + 1;
//size_t i,plen = 33; uint8_t pubkey[33];
//secp256k1_ec_pubkey_serialize(ctx,pubkey,&plen,&CHECKPUB,SECP256K1_EC_COMPRESSED);
//for (i=0; i<33; i++)
// printf("%02x",pubkey[i]);
//printf(" bitcoin_sign's pubkey\n");
} //else printf("secpub mismatch\n");
} else printf("pubkey create error\n");
} //else printf("recover error\n");
} else printf("secp256k1_ecdsa_sign_recoverable error\n");
}
else
{
if ( secp256k1_ecdsa_sign(ctx,&SIG,txhash2.bytes,privkey.bytes,secp256k1_nonce_function_rfc6979,extra_entropy.bytes) != 0 )
{
if ( secp256k1_ecdsa_signature_serialize_der(ctx,sig,&siglen,&SIG) != 0 )
retval = (int32_t)siglen;
}
}
}
ENDSECP_ENSURE_CTX
}
return(retval);
}
int32_t bitcoin_recoververify(void *ctx,char *symbol,uint8_t *sig,bits256 messagehash2,uint8_t *pubkey,size_t plen)
{
int32_t retval = -1; secp256k1_pubkey PUB; secp256k1_ecdsa_signature SIG; secp256k1_ecdsa_recoverable_signature rSIG;
pubkey[0] = 0;
SECP_ENSURE_CTX
{
if ( plen == 0 )
{
plen = (sig[0] <= 31) ? 65 : 33;
sig++;
}
secp256k1_ecdsa_recoverable_signature_parse_compact(ctx,&rSIG,sig,0);
secp256k1_ecdsa_recoverable_signature_convert(ctx,&SIG,&rSIG);
if ( secp256k1_ecdsa_recover(ctx,&PUB,&rSIG,messagehash2.bytes) != 0 )
{
plen = 33;
memset(pubkey,0,33);
secp256k1_ec_pubkey_serialize(ctx,pubkey,&plen,&PUB,SECP256K1_EC_COMPRESSED);//plen == 65 ? SECP256K1_EC_UNCOMPRESSED : SECP256K1_EC_COMPRESSED);
if ( secp256k1_ecdsa_verify(ctx,&SIG,messagehash2.bytes,&PUB) != 0 )
{
retval = 0;
/*if ( pubkey[0] == 4 ) // experimentally looks like 04 is set
pubkey[0] = 2;
else if ( pubkey[0] != 2 )
pubkey[0] = 3;*/
} else printf("secp256k1_ecdsa_verify error\n");
} else printf("secp256k1_ecdsa_recover error\n");
ENDSECP_ENSURE_CTX
}
return(retval);
}
int32_t bitcoin_verify(void *ctx,uint8_t *sig,int32_t siglen,bits256 txhash2,uint8_t *pubkey,int32_t plen)
{
int32_t retval = -1; secp256k1_pubkey PUB; secp256k1_ecdsa_signature SIG;
SECP_ENSURE_CTX
{
if ( secp256k1_ec_pubkey_parse(ctx,&PUB,pubkey,plen) != 0 )
{
secp256k1_ecdsa_signature_parse_der(ctx,&SIG,sig,siglen);
if ( secp256k1_ecdsa_verify(ctx,&SIG,txhash2.bytes,&PUB) != 0 )
retval = 0;
}
ENDSECP_ENSURE_CTX
}
return(retval);
}

558
iguana/exchanges/LP_statemachine.c

@ -0,0 +1,558 @@
/******************************************************************************
* Copyright © 2014-2017 The SuperNET Developers. *
* *
* See the AUTHORS, DEVELOPER-AGREEMENT and LICENSE files at *
* the top-level directory of this distribution for the individual copyright *
* holder information and the developer policies on copyright and licensing. *
* *
* Unless otherwise agreed in a custom licensing agreement, no part of the *
* SuperNET software, including this file may be copied, modified, propagated *
* or distributed except according to the terms contained in the LICENSE file *
* *
* Removal or modification of this copyright notice is prohibited. *
* *
******************************************************************************/
//
// LP_statemachine.c
// marketmaker
//
int32_t basilisk_process_swapverify(void *ptr,int32_t (*internal_func)(void *ptr,uint8_t *data,int32_t datalen),uint32_t channel,uint32_t msgid,uint8_t *data,int32_t datalen,uint32_t expiration,uint32_t duration)
{
struct basilisk_swap *swap = ptr;
if ( internal_func != 0 )
return((*internal_func)(swap,data,datalen));
else return(0);
}
int32_t basilisk_priviextract(struct iguana_info *coin,char *name,bits256 *destp,uint8_t secret160[20],bits256 srctxid,int32_t srcvout)
{
/*bits256 txid; char str[65]; int32_t i,vini,scriptlen; uint8_t rmd160[20],scriptsig[IGUANA_MAXSCRIPTSIZE];
memset(privkey.bytes,0,sizeof(privkey));
// use dex_listtransactions!
if ( (vini= iguana_vinifind(coin,&txid,srctxid,srcvout)) >= 0 )
{
if ( (scriptlen= iguana_scriptsigextract(coin,scriptsig,sizeof(scriptsig),txid,vini)) > 32 )
{
for (i=0; i<32; i++)
privkey.bytes[i] = scriptsig[scriptlen - 33 + i];
revcalc_rmd160_sha256(rmd160,privkey);//.bytes,sizeof(privkey));
if ( memcmp(secret160,rmd160,sizeof(rmd160)) == sizeof(rmd160) )
{
*destp = privkey;
printf("basilisk_priviextract found privi %s (%s)\n",name,bits256_str(str,privkey));
return(0);
}
}
}*/
return(-1);
}
int32_t basilisk_verify_privi(void *ptr,uint8_t *data,int32_t datalen);
int32_t basilisk_privBn_extract(struct basilisk_swap *swap,uint8_t *data,int32_t maxlen)
{
if ( basilisk_priviextract(&swap->bobcoin,"privBn",&swap->I.privBn,swap->I.secretBn,swap->bobrefund.I.actualtxid,0) == 0 )
{
printf("extracted privBn from blockchain\n");
}
else if ( basilisk_swapget(swap,0x40000000,data,maxlen,basilisk_verify_privi) == 0 )
{
}
if ( bits256_nonz(swap->I.privBn) != 0 && swap->alicereclaim.I.datalen == 0 )
{
char str[65]; printf("got privBn.%s\n",bits256_str(str,swap->I.privBn));
return(basilisk_alicepayment_spend(swap,&swap->alicereclaim));
}
return(-1);
}
int32_t basilisk_privAm_extract(struct basilisk_swap *swap)
{
if ( basilisk_priviextract(&swap->bobcoin,"privAm",&swap->I.privAm,swap->I.secretAm,swap->bobpayment.I.actualtxid,0) == 0 )
{
printf("extracted privAm from blockchain\n");
}
if ( bits256_nonz(swap->I.privAm) != 0 && swap->bobspend.I.datalen == 0 )
{
char str[65]; printf("got privAm.%s\n",bits256_str(str,swap->I.privAm));
return(basilisk_alicepayment_spend(swap,&swap->bobspend));
}
return(-1);
}
int32_t basilisk_verify_otherstatebits(void *ptr,uint8_t *data,int32_t datalen)
{
int32_t retval; struct basilisk_swap *swap = ptr;
if ( datalen == sizeof(swap->I.otherstatebits) )
{
retval = iguana_rwnum(0,data,sizeof(swap->I.otherstatebits),&swap->I.otherstatebits);
return(retval);
} else return(-1);
}
int32_t basilisk_verify_statebits(void *ptr,uint8_t *data,int32_t datalen)
{
int32_t retval = -1; uint32_t statebits; struct basilisk_swap *swap = ptr;
if ( datalen == sizeof(swap->I.statebits) )
{
retval = iguana_rwnum(0,data,sizeof(swap->I.statebits),&statebits);
if ( statebits != swap->I.statebits )
{
printf("statebits.%x != %x\n",statebits,swap->I.statebits);
return(-1);
}
}
return(retval);
}
void basilisk_sendstate(struct basilisk_swap *swap,uint8_t *data,int32_t maxlen)
{
int32_t datalen=0;
datalen = iguana_rwnum(1,data,sizeof(swap->I.statebits),&swap->I.statebits);
LP_swapsend(swap,0x80000000,data,datalen,0,0);
}
int32_t basilisk_swapiteration(struct basilisk_swap *swap,uint8_t *data,int32_t maxlen)
{
int32_t j,datalen,retval = 0; uint32_t savestatebits=0,saveotherbits=0;
if ( swap->I.iambob != 0 )
swap->I.statebits |= 0x80;
while ( swap->aborted == 0 && ((swap->I.otherstatebits & 0x80) == 0 || (swap->I.statebits & 0x80) == 0) && retval == 0 && time(NULL) < swap->I.expiration )
{
if ( swap->connected == 0 )
basilisk_psockinit(swap,swap->I.iambob != 0);
printf("D r%u/q%u swapstate.%x otherstate.%x remaining %d\n",swap->I.req.requestid,swap->I.req.quoteid,swap->I.statebits,swap->I.otherstatebits,(int32_t)(swap->I.expiration-time(NULL)));
if ( swap->I.iambob != 0 && (swap->I.statebits & 0x80) == 0 ) // wait for fee
{
if ( basilisk_swapget(swap,0x80,data,maxlen,basilisk_verify_otherfee) == 0 )
{
// verify and submit otherfee
swap->I.statebits |= 0x80;
basilisk_sendstate(swap,data,maxlen);
}
}
else if ( swap->I.iambob == 0 )
swap->I.statebits |= 0x80;
basilisk_sendstate(swap,data,maxlen);
basilisk_swapget(swap,0x80000000,data,maxlen,basilisk_verify_otherstatebits);
if ( (swap->I.otherstatebits & 0x80) != 0 && (swap->I.statebits & 0x80) != 0 )
break;
if ( swap->I.statebits == savestatebits && swap->I.otherstatebits == saveotherbits )
sleep(DEX_SLEEP + (swap->I.iambob == 0)*1);
savestatebits = swap->I.statebits;
saveotherbits = swap->I.otherstatebits;
basilisk_swapget(swap,0x80000000,data,maxlen,basilisk_verify_otherstatebits);
basilisk_sendstate(swap,data,maxlen);
if ( (swap->I.otherstatebits & 0x80) == 0 )
LP_swapdata_rawtxsend(swap,0x80,data,maxlen,&swap->myfee,0x40,0);
}
basilisk_swap_saveupdate(swap);
while ( swap->aborted == 0 && retval == 0 && time(NULL) < swap->I.expiration ) // both sides have setup required data and paid txfee
{
basilisk_swap_saveupdate(swap);
if ( swap->connected == 0 )
basilisk_psockinit(swap,swap->I.iambob != 0);
//if ( (rand() % 30) == 0 )
printf("E r%u/q%u swapstate.%x otherstate.%x remaining %d\n",swap->I.req.requestid,swap->I.req.quoteid,swap->I.statebits,swap->I.otherstatebits,(int32_t)(swap->I.expiration-time(NULL)));
if ( swap->I.iambob != 0 )
{
//printf("BOB\n");
if ( (swap->I.statebits & 0x100) == 0 )
{
printf("send bobdeposit\n");
swap->I.statebits |= LP_swapdata_rawtxsend(swap,0x200,data,maxlen,&swap->bobdeposit,0x100,0);
}
// [BLOCKING: altfound] make sure altpayment is confirmed and send payment
else if ( (swap->I.statebits & 0x1000) == 0 )
{
printf("check alicepayment\n");
if ( basilisk_swapget(swap,0x1000,data,maxlen,basilisk_verify_alicepaid) == 0 )
{
swap->I.statebits |= 0x1000;
printf("got alicepayment aliceconfirms.%d\n",swap->I.aliceconfirms);
}
}
else if ( (swap->I.statebits & 0x2000) == 0 )
{
if ( (swap->I.aliceconfirms == 0 && swap->aliceunconf != 0) || LP_numconfirms(swap,&swap->alicepayment) >= swap->I.aliceconfirms )
{
swap->I.statebits |= 0x2000;
printf("alicepayment confirmed\n");
}
}
else if ( (swap->I.statebits & 0x4000) == 0 )
{
basilisk_bobscripts_set(swap,0,1);
printf("send bobpayment\n");
swap->I.statebits |= LP_swapdata_rawtxsend(swap,0x8000,data,maxlen,&swap->bobpayment,0x4000,0);
}
// [BLOCKING: privM] Bob waits for privAm either from Alice or alice blockchain
else if ( (swap->I.statebits & 0xc0000) != 0xc0000 )
{
if ( basilisk_swapget(swap,0x40000,data,maxlen,basilisk_verify_privi) == 0 || basilisk_privAm_extract(swap) == 0 ) // divulges privAm
{
//printf("got privi spend alicepayment, dont divulge privBn until bobspend propagated\n");
basilisk_alicepayment_spend(swap,&swap->bobspend);
if ( LP_swapdata_rawtxsend(swap,0,data,maxlen,&swap->bobspend,0x40000,1) == 0 )
printf("Bob error spending alice payment\n");
else
{
tradebot_swap_balancingtrade(swap,1);
printf("Bob spends alicepayment aliceconfirms.%d\n",swap->I.aliceconfirms);
swap->I.statebits |= 0x40000;
if ( LP_numconfirms(swap,&swap->bobspend) >= swap->I.aliceconfirms )
{
printf("bobspend confirmed\n");
swap->I.statebits |= 0x80000;
printf("Bob confirming spend of Alice's payment\n");
sleep(DEX_SLEEP);
}
retval = 1;
}
}
}
if ( swap->bobpayment.I.locktime != 0 && time(NULL) > swap->bobpayment.I.locktime )
{
// submit reclaim of payment
printf("bob reclaims bobpayment\n");
swap->I.statebits |= (0x40000 | 0x80000);
if ( LP_swapdata_rawtxsend(swap,0,data,maxlen,&swap->bobreclaim,0,0) == 0 )
printf("Bob error reclaiming own payment after alice timed out\n");
else
{
printf("Bob reclaimed own payment\n");
while ( 0 && (swap->I.statebits & 0x100000) == 0 ) // why wait for own tx?
{
if ( LP_numconfirms(swap,&swap->bobreclaim) >= 1 )
{
printf("bobreclaim confirmed\n");
swap->I.statebits |= 0x100000;
printf("Bob confirms reclain of payment\n");
break;
}
}
retval = 1;
}
}
}
else
{
//printf("ALICE\n");
// [BLOCKING: depfound] Alice waits for deposit to confirm and sends altpayment
if ( (swap->I.statebits & 0x200) == 0 )
{
printf("checkfor deposit\n");
if ( basilisk_swapget(swap,0x200,data,maxlen,basilisk_verify_bobdeposit) == 0 )
{
// verify deposit and submit, set confirmed height
printf("got bobdeposit\n");
swap->I.statebits |= 0x200;
} else printf("no valid deposit\n");
}
else if ( (swap->I.statebits & 0x400) == 0 )
{
if ( basilisk_istrustedbob(swap) != 0 || (swap->I.bobconfirms == 0 && swap->depositunconf != 0) || LP_numconfirms(swap,&swap->bobdeposit) >= swap->I.bobconfirms )
{
printf("bobdeposit confirmed\n");
swap->I.statebits |= 0x400;
}
}
else if ( (swap->I.statebits & 0x800) == 0 )
{
printf("send alicepayment\n");
swap->I.statebits |= LP_swapdata_rawtxsend(swap,0x1000,data,maxlen,&swap->alicepayment,0x800,0);
}
// [BLOCKING: payfound] make sure payment is confrmed and send in spend or see bob's reclaim and claim
else if ( (swap->I.statebits & 0x8000) == 0 )
{
if ( basilisk_swapget(swap,0x8000,data,maxlen,basilisk_verify_bobpaid) == 0 )
{
printf("got bobpayment\n");
tradebot_swap_balancingtrade(swap,0);
// verify payment and submit, set confirmed height
swap->I.statebits |= 0x8000;
}
}
else if ( (swap->I.statebits & 0x10000) == 0 )
{
if ( basilisk_istrustedbob(swap) != 0 || (swap->I.bobconfirms == 0 && swap->paymentunconf != 0) || LP_numconfirms(swap,&swap->bobpayment) >= swap->I.bobconfirms )
{
printf("bobpayment confirmed\n");
swap->I.statebits |= 0x10000;
}
}
else if ( (swap->I.statebits & 0x20000) == 0 )
{
printf("alicespend bobpayment\n");
if ( LP_swapdata_rawtxsend(swap,0,data,maxlen,&swap->alicespend,0x20000,0) != 0 )//&& (swap->aliceunconf != 0 || basilisk_numconfirms(swap,&swap->alicespend) > 0) )
{
swap->I.statebits |= 0x20000;
}
}
else if ( (swap->I.statebits & 0x40000) == 0 )
{
int32_t numconfs;
if ( (numconfs= LP_numconfirms(swap,&swap->alicespend)) >= swap->I.bobconfirms )
{
for (j=datalen=0; j<32; j++)
data[datalen++] = swap->I.privAm.bytes[j];
printf("send privAm %x\n",swap->I.statebits);
swap->I.statebits |= LP_swapsend(swap,0x40000,data,datalen,0x20000,swap->I.crcs_mypriv);
printf("Alice confirms spend of Bob's payment\n");
retval = 1;
} else printf("alicespend numconfs.%d < %d\n",numconfs,swap->I.bobconfirms);
}
if ( swap->bobdeposit.I.locktime != 0 && time(NULL) > swap->bobdeposit.I.locktime )
{
printf("Alice claims deposit\n");
if ( LP_swapdata_rawtxsend(swap,0,data,maxlen,&swap->aliceclaim,0,0) == 0 )
printf("Alice couldnt claim deposit\n");
else
{
printf("Alice claimed deposit\n");
retval = 1;
}
}
else if ( swap->aborted != 0 || basilisk_privBn_extract(swap,data,maxlen) == 0 )
{
printf("Alice reclaims her payment\n");
swap->I.statebits |= 0x40000000;
if ( LP_swapdata_rawtxsend(swap,0,data,maxlen,&swap->alicereclaim,0x40000000,0) == 0 )
printf("Alice error sending alicereclaim\n");
else
{
printf("Alice reclaimed her payment\n");
retval = 1;
}
}
}
if ( (rand() % 30) == 0 )
printf("finished swapstate.%x other.%x\n",swap->I.statebits,swap->I.otherstatebits);
if ( swap->I.statebits == savestatebits && swap->I.otherstatebits == saveotherbits )
sleep(DEX_SLEEP + (swap->I.iambob == 0)*1);
savestatebits = swap->I.statebits;
saveotherbits = swap->I.otherstatebits;
basilisk_sendstate(swap,data,maxlen);
basilisk_swapget(swap,0x80000000,data,maxlen,basilisk_verify_otherstatebits);
}
return(retval);
}
int32_t swapcompleted(struct basilisk_swap *swap)
{
if ( swap->I.iambob != 0 )
return(swap->I.bobspent);
else return(swap->I.alicespent);
}
cJSON *swapjson(struct basilisk_swap *swap)
{
cJSON *retjson = cJSON_CreateObject();
return(retjson);
}
int32_t basilisk_rwDEXquote(int32_t rwflag,uint8_t *serialized,struct basilisk_request *rp)
{
int32_t len = 0;
len += iguana_rwnum(rwflag,&serialized[len],sizeof(rp->requestid),&rp->requestid);
len += iguana_rwnum(rwflag,&serialized[len],sizeof(rp->timestamp),&rp->timestamp); // must be 2nd
len += iguana_rwnum(rwflag,&serialized[len],sizeof(rp->quoteid),&rp->quoteid);
len += iguana_rwnum(rwflag,&serialized[len],sizeof(rp->quotetime),&rp->quotetime);
len += iguana_rwnum(rwflag,&serialized[len],sizeof(rp->optionhours),&rp->optionhours);
len += iguana_rwnum(rwflag,&serialized[len],sizeof(rp->srcamount),&rp->srcamount);
len += iguana_rwnum(rwflag,&serialized[len],sizeof(rp->unused),&rp->unused);
len += iguana_rwbignum(rwflag,&serialized[len],sizeof(rp->srchash),rp->srchash.bytes);
len += iguana_rwbignum(rwflag,&serialized[len],sizeof(rp->desthash),rp->desthash.bytes);
len += iguana_rwnum(rwflag,&serialized[len],sizeof(rp->destamount),&rp->destamount);
if ( rwflag != 0 )
{
memcpy(&serialized[len],rp->src,sizeof(rp->src)), len += sizeof(rp->src);
memcpy(&serialized[len],rp->dest,sizeof(rp->dest)), len += sizeof(rp->dest);
}
else
{
memcpy(rp->src,&serialized[len],sizeof(rp->src)), len += sizeof(rp->src);
memcpy(rp->dest,&serialized[len],sizeof(rp->dest)), len += sizeof(rp->dest);
}
//len += iguana_rwnum(rwflag,&serialized[len],sizeof(rp->DEXselector),&rp->DEXselector);
//len += iguana_rwnum(rwflag,&serialized[len],sizeof(rp->extraspace),&rp->extraspace);
if ( rp->quoteid != 0 && basilisk_quoteid(rp) != rp->quoteid )
printf(" basilisk_rwDEXquote.%d: quoteid.%u mismatch calc %u rp.%p\n",rwflag,rp->quoteid,basilisk_quoteid(rp),rp);
if ( basilisk_requestid(rp) != rp->requestid )
printf(" basilisk_rwDEXquote.%d: requestid.%u mismatch calc %u rp.%p\n",rwflag,rp->requestid,basilisk_requestid(rp),rp);
return(len);
}
struct basilisk_request *basilisk_parsejson(struct basilisk_request *rp,cJSON *reqjson)
{
uint32_t requestid,quoteid;
memset(rp,0,sizeof(*rp));
rp->srchash = jbits256(reqjson,"srchash");
rp->desthash = jbits256(reqjson,"desthash");
rp->srcamount = j64bits(reqjson,"srcamount");
//rp->minamount = j64bits(reqjson,"minamount");
//rp->destamount = j64bits(reqjson,"destamount");
rp->destamount = j64bits(reqjson,"destsatoshis");
//printf("parse DESTSATOSHIS.%llu (%s)\n",(long long)rp->destamount,jprint(reqjson,0));
requestid = juint(reqjson,"requestid");
quoteid = juint(reqjson,"quoteid");
//if ( jstr(reqjson,"relay") != 0 )
// rp->relaybits = (uint32_t)calc_ipbits(jstr(reqjson,"relay"));
rp->timestamp = juint(reqjson,"timestamp");
rp->quotetime = juint(reqjson,"quotetime");
safecopy(rp->src,jstr(reqjson,"src"),sizeof(rp->src));
safecopy(rp->dest,jstr(reqjson,"dest"),sizeof(rp->dest));
if ( quoteid != 0 )
{
rp->quoteid = basilisk_quoteid(rp);
if ( quoteid != rp->quoteid )
printf("basilisk_parsejson quoteid.%u != %u error\n",quoteid,rp->quoteid);
}
rp->requestid = basilisk_requestid(rp);
if ( requestid != rp->requestid )
{
int32_t i; for (i=0; i<sizeof(*rp); i++)
printf("%02x",((uint8_t *)rp)[i]);
printf(" basilisk_parsejson.(%s) requestid.%u != %u error\n",jprint(reqjson,0),requestid,rp->requestid);
}
return(rp);
}
cJSON *basilisk_requestjson(struct basilisk_request *rp)
{
cJSON *item = cJSON_CreateObject();
/*if ( rp->relaybits != 0 )
{
expand_ipbits(ipaddr,rp->relaybits);
jaddstr(item,"relay",ipaddr);
}*/
jaddbits256(item,"srchash",rp->srchash);
if ( bits256_nonz(rp->desthash) != 0 )
jaddbits256(item,"desthash",rp->desthash);
jaddstr(item,"src",rp->src);
if ( rp->srcamount != 0 )
jadd64bits(item,"srcamount",rp->srcamount);
//if ( rp->minamount != 0 )
// jadd64bits(item,"minamount",rp->minamount);
jaddstr(item,"dest",rp->dest);
if ( rp->destamount != 0 )
{
//jadd64bits(item,"destamount",rp->destamount);
jadd64bits(item,"destsatoshis",rp->destamount);
//printf("DESTSATOSHIS.%llu\n",(long long)rp->destamount);
}
jaddnum(item,"quotetime",rp->quotetime);
jaddnum(item,"timestamp",rp->timestamp);
jaddnum(item,"requestid",rp->requestid);
jaddnum(item,"quoteid",rp->quoteid);
//jaddnum(item,"DEXselector",rp->DEXselector);
jaddnum(item,"optionhours",rp->optionhours);
//jaddnum(item,"profit",(double)rp->profitmargin / 1000000.);
if ( rp->quoteid != 0 && basilisk_quoteid(rp) != rp->quoteid )
printf("quoteid mismatch %u vs %u\n",basilisk_quoteid(rp),rp->quoteid);
if ( basilisk_requestid(rp) != rp->requestid )
printf("requestid mismatch %u vs calc %u\n",rp->requestid,basilisk_requestid(rp));
{
int32_t i; struct basilisk_request R;
if ( basilisk_parsejson(&R,item) != 0 )
{
if ( memcmp(&R,rp,sizeof(*rp)-sizeof(uint32_t)) != 0 )
{
for (i=0; i<sizeof(*rp); i++)
printf("%02x",((uint8_t *)rp)[i]);
printf(" <- rp.%p\n",rp);
for (i=0; i<sizeof(R); i++)
printf("%02x",((uint8_t *)&R)[i]);
printf(" <- R mismatch\n");
for (i=0; i<sizeof(R); i++)
if ( ((uint8_t *)rp)[i] != ((uint8_t *)&R)[i] )
printf("(%02x %02x).%d ",((uint8_t *)rp)[i],((uint8_t *)&R)[i],i);
printf("mismatches\n");
} //else printf("matched JSON conv %u %u\n",basilisk_requestid(&R),basilisk_requestid(rp));
}
}
return(item);
}
cJSON *basilisk_swapjson(struct basilisk_swap *swap)
{
cJSON *item = cJSON_CreateObject();
jaddnum(item,"requestid",swap->I.req.requestid);
jaddnum(item,"quoteid",swap->I.req.quoteid);
jaddnum(item,"state",swap->I.statebits);
jaddnum(item,"otherstate",swap->I.otherstatebits);
jadd(item,"request",basilisk_requestjson(&swap->I.req));
return(item);
}
#ifdef later
cJSON *basilisk_privkeyarray(struct iguana_info *coin,cJSON *vins)
{
cJSON *privkeyarray,*item,*sobj; struct iguana_waddress *waddr; struct iguana_waccount *wacct; char coinaddr[64],account[128],wifstr[64],str[65],typestr[64],*hexstr; uint8_t script[1024]; int32_t i,n,len,vout; bits256 txid,privkey; double bidasks[2];
privkeyarray = cJSON_CreateArray();
//printf("%s persistent.(%s) (%s) change.(%s) scriptstr.(%s)\n",coin->symbol,myinfo->myaddr.BTC,coinaddr,coin->changeaddr,scriptstr);
if ( (n= cJSON_GetArraySize(vins)) > 0 )
{
for (i=0; i<n; i++)
{
item = jitem(vins,i);
txid = jbits256(item,"txid");
vout = jint(item,"vout");
if ( bits256_nonz(txid) != 0 && vout >= 0 )
{
iguana_txidcategory(coin,account,coinaddr,txid,vout);
if ( coinaddr[0] == 0 && (sobj= jobj(item,"scriptPubKey")) != 0 && (hexstr= jstr(sobj,"hex")) != 0 && is_hexstr(hexstr,0) > 0 )
{
len = (int32_t)strlen(hexstr) >> 1;
if ( len < (sizeof(script) << 1) )
{
decode_hex(script,len,hexstr);
if ( len == 25 && script[0] == 0x76 && script[1] == 0xa9 && script[2] == 0x14 )
bitcoin_address(coinaddr,coin->chain->pubtype,script+3,20);
}
}
if ( coinaddr[0] != 0 )
{
if ( (waddr= iguana_waddresssearch(&wacct,coinaddr)) != 0 )
{
bitcoin_priv2wif(wifstr,waddr->privkey,coin->chain->wiftype);
jaddistr(privkeyarray,waddr->wifstr);
}
else if ( smartaddress(typestr,bidasks,&privkey,coin->symbol,coinaddr) >= 0 )
{
bitcoin_priv2wif(wifstr,privkey,coin->chain->wiftype);
jaddistr(privkeyarray,wifstr);
}
else printf("cant find (%s) in wallet\n",coinaddr);
} else printf("cant coinaddr from (%s).v%d\n",bits256_str(str,txid),vout);
} else printf("invalid txid/vout %d of %d\n",i,n);
}
}
return(privkeyarray);
}
#endif
/*void basilisk_swap_purge(struct basilisk_swap *swap)
{
int32_t i,n;
// while still in orderbook, wait
//return;
portable_mutex_lock(&myinfo->DEX_swapmutex);
n = myinfo->numswaps;
for (i=0; i<n; i++)
if ( myinfo->swaps[i] == swap )
{
myinfo->swaps[i] = myinfo->swaps[--myinfo->numswaps];
myinfo->swaps[myinfo->numswaps] = 0;
basilisk_swap_finished(swap);
break;
}
portable_mutex_unlock(&myinfo->DEX_swapmutex);
}*/

2405
iguana/exchanges/LP_swap.c

File diff suppressed because it is too large

1657
iguana/exchanges/LP_transaction.c

File diff suppressed because it is too large

3
iguana/m_mm

@ -1 +1,2 @@
gcc -o marketmaker -I../crypto777 exchanges/mm.c ../crypto777/cJSON.c ../agents/libcrypto777.a -lnanomsg -lcurl -lpthread -lm
cd secp256k1; ./m_unix; cd ..
gcc -o marketmaker -I../crypto777 exchanges/mm.c mini-gmp.c secp256k1.o ../agents/libcrypto777.a -lnanomsg -lcurl -lpthread -lm

Loading…
Cancel
Save