Browse Source

Merge branch 'spvdex' of https://github.com/jl777/SuperNET into dev-decker-spvdex

etomic
DeckerSU 7 years ago
parent
commit
89f671918c
  1. 2
      crypto777/OS_portable.h
  2. 7
      crypto777/bitcoind_RPC.c
  3. 4
      crypto777/iguana_OS.c
  4. 2
      crypto777/jpeg/unix/jmemname.c
  5. 11
      iguana/exchanges/LP_coins.c
  6. 145
      iguana/exchanges/LP_commands.c
  7. 18
      iguana/exchanges/LP_include.h
  8. 139
      iguana/exchanges/LP_nativeDEX.c
  9. 5
      iguana/exchanges/LP_network.c
  10. 312
      iguana/exchanges/LP_ordermatch.c
  11. 5
      iguana/exchanges/LP_peers.c
  12. 2
      iguana/exchanges/LP_portfolio.c
  13. 29
      iguana/exchanges/LP_prices.c
  14. 168
      iguana/exchanges/LP_remember.c
  15. 51
      iguana/exchanges/LP_rpc.c
  16. 11
      iguana/exchanges/LP_scan.c
  17. 16
      iguana/exchanges/LP_socket.c
  18. 58
      iguana/exchanges/LP_statemachine.c
  19. 93
      iguana/exchanges/LP_swap.c
  20. 311
      iguana/exchanges/LP_transaction.c
  21. 32
      iguana/exchanges/LP_utxo.c
  22. 12
      iguana/exchanges/LP_utxos.c
  23. 2
      iguana/exchanges/coins
  24. 2
      iguana/exchanges/install
  25. 1
      iguana/exchanges/listunspent
  26. 3
      iguana/exchanges/register
  27. 3
      iguana/exchanges/sendrawtransaction
  28. 3
      iguana/exchanges/setconfirms
  29. 6
      iguana/exchanges/stats.c
  30. 4
      iguana/exchanges/trust
  31. 2
      iguana/exchanges/trusted
  32. 3
      iguana/exchanges/withdraw

2
crypto777/OS_portable.h

@ -40,7 +40,7 @@
#include <sys/types.h>
#include <time.h>
#ifdef WIN32
#ifdef _WIN32
#define sleep(x) Sleep(1000*(x))
#include "../OSlibs/win/mingw.h"
#include "../OSlibs/win/mman.h"

7
crypto777/bitcoind_RPC.c

@ -55,17 +55,18 @@ char *post_process_bitcoind_RPC(char *debugstr,char *command,char *rpcstr,char *
long i,j,len;
char *retstr = 0;
cJSON *json,*result,*error;
usleep(2500);
//printf("<<<<<<<<<<< bitcoind_RPC: %s post_process_bitcoind_RPC.%s.[%s]\n",debugstr,command,rpcstr);
if ( command == 0 || rpcstr == 0 || rpcstr[0] == 0 )
{
if ( strcmp(command,"signrawtransaction") != 0 && strcmp(command,"getrawtransaction") != 0 )
printf("<<<<<<<<<<< bitcoind_RPC: %s post_process_bitcoind_RPC.%s.[%s]\n",debugstr,command,rpcstr);
printf("<<<<<<<<<<< A bitcoind_RPC: %s post_process_bitcoind_RPC.%s.[%s]\n",debugstr,command,params);
return(rpcstr);
}
json = cJSON_Parse(rpcstr);
if ( json == 0 )
{
printf("<<<<<<<<<<< bitcoind_RPC: %s post_process_bitcoind_RPC.%s can't parse.(%s) params.(%s)\n",debugstr,command,rpcstr,params);
printf("<<<<<<<<<<< B bitcoind_RPC: %s post_process_bitcoind_RPC.%s can't parse.(%s) params.(%s)\n",debugstr,command,rpcstr,params);
free(rpcstr);
return(0);
}
@ -227,7 +228,7 @@ try_again:
{
count++;
elapsedsum += (OS_milliseconds() - starttime);
if ( (count % 10000) == 0)
if ( (count % 100000) == 0)
printf("%d: ave %9.6f | elapsed %.3f millis | bitcoind_RPC.(%s) url.(%s)\n",count,elapsedsum/count,(OS_milliseconds() - starttime),command,url);
if ( retstrp != 0 )
{

4
crypto777/iguana_OS.c

@ -30,7 +30,7 @@
char *OS_mvstr()
{
#ifdef __WIN32
#ifdef _WIN32
return("rename");
#else
return("mv");
@ -659,7 +659,7 @@ int64_t OS_copyfile(char *src,char *dest,int32_t cmpflag)
{
if ( (destfp= fopen(OS_compatible_path(dest),"wb")) != 0 )
{
#ifdef WIN32
#ifdef _WIN32
allocsize = 1024 * 1024 * 8L;
#else
allocsize = 1024 * 1024 * 128L;

2
crypto777/jpeg/unix/jmemname.c

@ -11,7 +11,7 @@
* Also, the problem of determining the amount of memory available
* is shoved onto the user.
*/
#ifndef WIN32
#ifndef _WIN32
#include <unistd.h>
#endif

11
iguana/exchanges/LP_coins.c

@ -100,7 +100,7 @@ void LP_statefname(char *fname,char *symbol,char *assetname,char *str,char *name
return;
}
sprintf(fname,"%s",LP_getdatadir());
#ifdef WIN32
#ifdef _WIN32
strcat(fname,"\\");
#else
strcat(fname,"/");
@ -138,7 +138,7 @@ void LP_statefname(char *fname,char *symbol,char *assetname,char *str,char *name
#endif
if ( strcmp(symbol,"KMD") != 0 )
{
#ifdef WIN32
#ifdef _WIN32
strcat(fname,"\\");
#else
strcat(fname,"/");
@ -146,7 +146,7 @@ void LP_statefname(char *fname,char *symbol,char *assetname,char *str,char *name
strcat(fname,assetname);
}
}
#ifdef WIN32
#ifdef _WIN32
strcat(fname,"\\");
#else
strcat(fname,"/");
@ -299,6 +299,11 @@ uint16_t LP_coininit(struct iguana_info *coin,char *symbol,char *name,char *asse
coin->inactive = (uint32_t)time(NULL);
coin->bussock = LP_coinbus(busport);
coin->ctx = bitcoin_ctx();
if ( assetname != 0 && strcmp(name,assetname) == 0 )
{
printf("%s is assetchain\n",symbol);
coin->isassetchain = 1;
}
if ( strcmp(symbol,"KMD") == 0 || (assetname != 0 && assetname[0] != 0) )
name2 = 0;
else name2 = name;

145
iguana/exchanges/LP_commands.c

@ -94,19 +94,23 @@ char *stats_JSON(void *ctx,char *myipaddr,int32_t pubsock,cJSON *argjson,char *r
// return(clonestr("{\"result\":\"success\"}"));
else if ( strcmp(method,"help") == 0 )
return(clonestr("{\"result\":\" \
available localhost RPC commands:\n \
available localhost RPC commands: * means it needs to be a signed request\n \
pricearray(base, rel, firsttime=0, lasttime=-1, timescale=60) -> [timestamp, avebid, aveask, highbid, lowask]\n\
setprice(base, rel, price)\n\
autoprice(base, rel, price, margin, type)\n\
goal(coin=*, val=<autocalc>)\n\
setprice(base, rel, price)*\n\
autoprice(base, rel, price, margin, type)*\n\
goal(coin=*, val=<autocalc>)*\n\
myprice(base, rel)\n\
enable(coin)\n\
disable(coin)\n\
enable(coin)*\n\
disable(coin)*\n\
inventory(coin)\n\
bestfit(rel, relvolume)\n\
buy(base, rel, price, relvolume, timeout=10, duration=3600)\n\
swapstatus()\n\
swapstatus(requestid, quoteid)\n\
lastnonce()\n\
buy(base, rel, price, relvolume, timeout=10, duration=3600, nonce)*\n\
sell(base, rel, price, basevolume, timeout=10, duration=3600, nonce)*\n\
withdraw(coin, outputs[])*\n\
sendrawtransaction(coin, signedtx)\n\
swapstatus()*\n\
swapstatus(requestid, quoteid)*\n\
public API:\n \
getcoins()\n\
getcoin(coin)\n\
@ -114,14 +118,16 @@ portfolio()\n\
getpeers()\n\
passphrase(passphrase, gui)\n\
listunspent(coin, address)\n\
setconfirms(coin, numconfirms, maxconfirms=6)*\n\
trust(pubkey, trust)*\n\
balance(coin, address)\n\
orderbook(base, rel, duration=3600)\n\
getprices(base, rel)\n\
sendmessage(base=coin, rel="", pubkey=zero, <argjson method2>)\n\
getmessages(firsti=0, num=100)\n\
clearmessages(firsti=0, num=100)\n\
sendmessage(base=coin, rel="", pubkey=zero, <argjson method2>)*\n\
getmessages(firsti=0, num=100)*\n\
deletemessages(firsti=0, num=100)*\n\
secretaddresses(prefix='secretaddress', passphrase, num=10, pubtype=60, taddr=0)\n\
electrum(coin, ipaddr, port)\n\
electrum(coin, ipaddr, port)*\n\
snapshot(coin, height)\n\
snapshot_balance(coin, height, addresses[])\n\
dividends(coin, height, <args>)\n\
@ -147,6 +153,7 @@ dividends(coin, height, <args>)\n\
jdelete(argjson,"userpass");
if ( strcmp(method,"sendmessage") == 0 )
{
//*
if ( jobj(argjson,"method2") == 0 )
{
printf("broadcast message\n");
@ -156,12 +163,14 @@ dividends(coin, height, <args>)\n\
}
else if ( strcmp(method,"getmessages") == 0 )
{
//*
if ( (retjson= LP_getmessages(jint(argjson,"firsti"),jint(argjson,"num"))) != 0 )
return(jprint(retjson,1));
else return(clonestr("{\"error\":\"null messages\"}"));
}
else if ( strcmp(method,"deletemessages") == 0 )
{
//*
LP_deletemessages(jint(argjson,"firsti"),jint(argjson,"num"));
return(clonestr("{\"result\":\"success\"}"));
}
@ -196,6 +205,7 @@ dividends(coin, height, <args>)\n\
price = jdouble(argjson,"price");
if ( strcmp(method,"setprice") == 0 )
{
//*
if ( price > SMALLVAL )
{
if ( LP_mypriceset(&changed,base,rel,price) < 0 )
@ -207,6 +217,7 @@ dividends(coin, height, <args>)\n\
}
else if ( strcmp(method,"autoprice") == 0 )
{
//*
if ( LP_autoprice(base,rel,price,jdouble(argjson,"margin"),jstr(argjson,"type")) < 0 )
return(clonestr("{\"error\":\"couldnt set autoprice\"}"));
else return(clonestr("{\"result\":\"success\"}"));
@ -229,16 +240,18 @@ dividends(coin, height, <args>)\n\
}
else if ( strcmp(method,"buy") == 0 )
{
//*
if ( price > SMALLVAL )
{
return(LP_autobuy(ctx,myipaddr,pubsock,base,rel,price,jdouble(argjson,"relvolume"),jint(argjson,"timeout"),jint(argjson,"duration"),jstr(argjson,"gui")));
return(LP_autobuy(ctx,myipaddr,pubsock,base,rel,price,jdouble(argjson,"relvolume"),jint(argjson,"timeout"),jint(argjson,"duration"),jstr(argjson,"gui"),juint(argjson,"nonce")));
} else return(clonestr("{\"error\":\"no price set\"}"));
}
else if ( strcmp(method,"sell") == 0 )
{
//*
if ( price > SMALLVAL )
{
return(LP_autobuy(ctx,myipaddr,pubsock,rel,base,1./price,jdouble(argjson,"basevolume"),jint(argjson,"timeout"),jint(argjson,"duration"),jstr(argjson,"gui")));
return(LP_autobuy(ctx,myipaddr,pubsock,rel,base,1./price,jdouble(argjson,"basevolume"),jint(argjson,"timeout"),jint(argjson,"duration"),jstr(argjson,"gui"),juint(argjson,"nonce")));
} else return(clonestr("{\"error\":\"no price set\"}"));
}
}
@ -253,6 +266,7 @@ dividends(coin, height, <args>)\n\
{
if ( strcmp(method,"enable") == 0 )
{
//*
if ( (ptr= LP_coinsearch(coin)) != 0 )
{
if ( LP_conflicts_find(ptr) == 0 )
@ -263,18 +277,52 @@ dividends(coin, height, <args>)\n\
}
else if ( strcmp(method,"disable") == 0 )
{
//*
if ( (ptr= LP_coinsearch(coin)) != 0 )
ptr->inactive = (uint32_t)time(NULL);
return(jprint(LP_coinsjson(0),1));
}
else if ( strcmp(method,"electrum") == 0 )
{
//*
if ( (ptr= LP_coinsearch(coin)) != 0 )
{
ptr->inactive = 0;
return(jprint(LP_electrumserver(ptr,jstr(argjson,"ipaddr"),juint(argjson,"port")),1));
} else return(clonestr("{\"error\":\"cant find coind\"}"));
}
else if ( strcmp(method,"sendrawtransaction") == 0 )
{
return(LP_sendrawtransaction(coin,jstr(argjson,"signedtx")));
}
else if ( strcmp(method,"withdraw") == 0 )
{
///*
if ( (ptr= LP_coinsearch(coin)) != 0 )
{
if ( jobj(argjson,"outputs") == 0 )
return(clonestr("{\"error\":\"withdraw needs to have outputs\"}"));
else return(LP_withdraw(ptr,argjson));
}
return(clonestr("{\"error\":\"cant find coind\"}"));
}
else if ( strcmp(method,"setconfirms") == 0 )
{
int32_t n;
//*
n = jint(argjson,"numconfirms");
if ( n < 0 )
return(clonestr("{\"error\":\"illegal numconfirms\"}"));
if ( (ptr= LP_coinsearch(coin)) != 0 )
{
ptr->userconfirms = n;
if ( (n= jint(argjson,"maxconfirms")) > 0 )
ptr->maxconfirms = n;
if ( ptr->maxconfirms > 0 && ptr->userconfirms > ptr->maxconfirms )
ptr->userconfirms = ptr->maxconfirms;
return(clonestr("{\"result\":\"success\"}"));
} else return(clonestr("{\"error\":\"cant find coind\"}"));
}
else if ( strcmp(method,"snapshot") == 0 )
{
if ( (ptr= LP_coinsearch(coin)) != 0 )
@ -316,23 +364,42 @@ dividends(coin, height, <args>)\n\
}
}
else if ( strcmp(method,"goal") == 0 )
{
//*
return(LP_portfolio_goal(coin,jdouble(argjson,"val")));
}
else if ( strcmp(method,"getcoin") == 0 )
return(LP_getcoin(coin));
}
else if ( strcmp(method,"goal") == 0 )
{
//*
return(LP_portfolio_goal("*",100.));
}
else if ( strcmp(method,"swapstatus") == 0 )
{
uint32_t requestid,quoteid;
//*
if ( (requestid= juint(argjson,"requestid")) != 0 && (quoteid= juint(argjson,"quoteid")) != 0 )
return(basilisk_swapentry(requestid,quoteid));
else return(basilisk_swaplist(0,0));
}
else if ( strcmp(method,"lastnonce") == 0 )
{
cJSON *retjson = cJSON_CreateObject();
jaddstr(retjson,"result","success");
jaddnum(retjson,"lastnonce",LP_lastnonce);
return(jprint(retjson,1));
}
else if ( strcmp(method,"myprices") == 0 )
return(LP_myprices());
else if ( strcmp(method,"trust") == 0 )
{
//*
return(LP_pubkey_trustset(jbits256(argjson,"pubkey"),jint(argjson,"trust")));
}
else if ( strcmp(method,"trusted") == 0 )
return(LP_pubkey_trusted());
}
if ( IAMLP == 0 )
{
@ -379,7 +446,7 @@ dividends(coin, height, <args>)\n\
{
if ( coinaddr[0] != 0 )
{
LP_listunspent_issue(coin,coinaddr);
LP_listunspent_issue(coin,coinaddr,1);
if ( strcmp(coinaddr,ptr->smartaddr) == 0 && bits256_nonz(G.LP_mypriv25519) != 0 )
{
LP_privkey_init(-1,ptr,G.LP_mypriv25519,G.LP_mypub25519);
@ -404,16 +471,6 @@ dividends(coin, height, <args>)\n\
return(clonestr("{\"result\":\"at least one of coins disabled\"}"));
else if ( IAMLP == 0 && LP_isdisabled(jstr(argjson,"coin"),0) != 0 )
retstr = clonestr("{\"result\":\"coin is disabled\"}");
else if ( strcmp(method,"reserved") == 0 )
{
//printf("RESERVED.(%s)\n",jprint(argjson,0));
retstr = LP_quotereceived(argjson);
}
else if ( strcmp(method,"connected") == 0 )
{
//printf("CONNECTED.(%s)\n",jprint(argjson,0));
retstr = LP_connectedalice(argjson);
}
else if ( strcmp(method,"checktxid") == 0 )
retstr = LP_spentcheck(argjson);
else if ( strcmp(method,"addr_unspents") == 0 )
@ -438,38 +495,10 @@ dividends(coin, height, <args>)\n\
}
else if ( strcmp(method,"getcoins") == 0 )
return(jprint(LP_coinsjson(0),1));
else if ( strcmp(method,"numutxos") == 0 )
{
printf("deprecated numutxos received\n");
retstr = clonestr("{\"result\":\"couldnt add utxo\"}");
//return(LP_numutxos());
}
else if ( strcmp(method,"encrypted") == 0 )
retstr = clonestr("{\"result\":\"success\"}");
else if ( strcmp(method,"registerall") == 0 )
return(clonestr("{\"error\":\"you are running an obsolete version, update\"}"));
else if ( strcmp(method,"forward") == 0 )
return(clonestr("{\"error\":\"you are running an obsolete version, update\"}"));
else if ( strcmp(method,"keepalive") == 0 )
return(clonestr("{\"error\":\"you are running an obsolete version, update\"}"));
else if ( strcmp(method,"getpeers") == 0 )
return(LP_peers());
else if ( strcmp(method,"getutxos") == 0 )
{
printf("deprecated getutxos received\n");
retstr = clonestr("{\"result\":\"couldnt add utxo\"}");
//return(LP_utxos(1,LP_mypeer,jstr(argjson,"coin"),jint(argjson,"lastn")));
}
else if ( strcmp(method,"utxo") == 0 )
{
static uint32_t counter;
if ( counter++ < 3 )
printf("deprecated utxo received\n");
//if ( LP_utxoaddjson(1,LP_mypubsock,argjson) != 0 )
// retstr = clonestr("{\"result\":\"success\",\"utxo\":\"received\"}");
//else
retstr = clonestr("{\"result\":\"couldnt add utxo\"}");
}
else
{
if ( base != 0 && rel != 0 && strcmp(method,"pricearray") == 0 )
@ -500,10 +529,6 @@ dividends(coin, height, <args>)\n\
}
if ( IAMLP != 0 )
{
if ( strcmp(method,"register") == 0 )
return(clonestr("{\"error\":\"you are running an obsolete version, update\"}"));
else if ( strcmp(method,"lookup") == 0 )
return(clonestr("{\"error\":\"you are running an obsolete version, update\"}"));
if ( strcmp(method,"broadcast") == 0 )
{
bits256 zero; char *cipherstr; int32_t cipherlen; uint8_t cipher[LP_ENCRYPTED_MAXSIZE];
@ -521,11 +546,9 @@ dividends(coin, height, <args>)\n\
}
else
{
char *msg;
memset(zero.bytes,0,sizeof(zero));
msg = jprint(reqjson,0);
//printf("broadcast.(%s)\n",msg);
LP_broadcast_message(LP_mypubsock,base!=0?base:jstr(argjson,"coin"),rel,zero,msg);
LP_reserved_msg(base!=0?base:jstr(argjson,"coin"),rel,zero,jprint(reqjson,0));
}
retstr = clonestr("{\"result\":\"success\"}");
} else retstr = clonestr("{\"error\":\"couldnt dereference sendmessage\"}");

18
iguana/exchanges/LP_include.h

@ -43,7 +43,7 @@
#define LP_PEERGOOD_ERRORDECAY 0.9
#define LP_SWAPSTEP_TIMEOUT 30
#define LP_AUTOTRADE_TIMEOUT 60
#define LP_AUTOTRADE_TIMEOUT 10
#define LP_MIN_TXFEE 10000
#define LP_MINVOL 20
#define LP_MINCLIENTVOL 50
@ -71,7 +71,8 @@
#define LP_RESERVETIME 60
#define LP_AVETXSIZE 256
#define LP_CACHEDURATION 60
#define BASILISK_DEFAULT_NUMCONFIRMS 1
#define BASILISK_DEFAULT_NUMCONFIRMS 3
#define BASILISK_DEFAULT_MAXCONFIRMS 6
#define DEX_SLEEP 3
#define BASILISK_KEYSIZE ((int32_t)(2*sizeof(bits256)+sizeof(uint32_t)*2))
@ -151,7 +152,7 @@ struct basilisk_swapinfo
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;
int32_t bobconfirms,aliceconfirms,iambob,reclaimed,bobspent,alicespent,pad,aliceistrusted,bobistrusted,otheristrusted,otherstrust,alicemaxconfirms,bobmaxconfirms;
uint64_t alicesatoshis,bobsatoshis,bobinsurance,aliceinsurance,Atxfee,Btxfee;
bits256 myprivs[2],mypubs[2],otherpubs[2],pubA0,pubA1,pubB0,pubB1,privAm,pubAm,privBn,pubBn;
@ -184,7 +185,7 @@ struct iguana_info
uint64_t txfee;
int32_t longestchain,firstrefht,firstscanht,lastscanht,bussock,height; uint16_t busport;
uint32_t addr_listunspent_requested,lastutxos,updaterate,counter,inactive,lastmempool,lastgetinfo,ratetime,heighttime,lastmonitor,unspenttime,obooktime;
uint8_t pubtype,p2shtype,isPoS,wiftype,wiftaddr,taddr,noimportprivkey_flag;
uint8_t pubtype,p2shtype,isPoS,wiftype,wiftaddr,taddr,noimportprivkey_flag,userconfirms,isassetchain,maxconfirms;
char symbol[16],smartaddr[64],userpass[1024],serverport[128],lastunspent[64];
// portfolio
double price_kmd,force,perc,goal,goalperc,relvolume,rate;
@ -288,6 +289,7 @@ int32_t LP_ismine(struct LP_utxoinfo *utxo);
int32_t LP_isavailable(struct LP_utxoinfo *utxo);
struct LP_peerinfo *LP_peerfind(uint32_t ipbits,uint16_t port);
uint64_t LP_value_extract(cJSON *obj,int32_t addinterest);
int32_t LP_swap_getcoinaddr(char *symbol,char *coinaddr,bits256 txid,int32_t vout);
char *LP_command_process(void *ctx,char *myipaddr,int32_t pubsock,cJSON *argjson,uint8_t *data,int32_t datalen);
void LP_availableset(struct LP_utxoinfo *utxo);
int32_t LP_iseligible(uint64_t *valp,uint64_t *val2p,int32_t iambob,char *symbol,bits256 txid,int32_t vout,uint64_t satoshis,bits256 txid2,int32_t vout2);
@ -295,10 +297,13 @@ int32_t LP_pullsock_check(void *ctx,char **retstrp,char *myipaddr,int32_t pubsoc
uint16_t LP_psock_get(char *connectaddr,char *publicaddr,int32_t ispaired);
//void LP_utxo_clientpublish(struct LP_utxoinfo *utxo);
int32_t LP_coinbus(uint16_t coin_busport);
int32_t LP_nanomsg_recvs(void *ctx);
int32_t LP_reserved_msgs();
int32_t LP_reserved_msg(char *base,char *rel,bits256 pubkey,char *msg);
struct iguana_info *LP_coinfind(char *symbol);
int32_t LP_crc32find(int32_t *duplicatep,int32_t ind,uint32_t crc32);
char *LP_pricepings(void *ctx,char *myipaddr,int32_t pubsock,char *base,char *rel,double price);
uint64_t LP_txfeecalc(struct iguana_info *coin,uint64_t txfee);
uint64_t LP_txfeecalc(struct iguana_info *coin,uint64_t txfee,int32_t txlen);
struct LP_address *_LP_address(struct iguana_info *coin,char *coinaddr);
struct LP_address *_LP_addressfind(struct iguana_info *coin,char *coinaddr);
struct LP_address *_LP_addressadd(struct iguana_info *coin,char *coinaddr);
@ -316,7 +321,7 @@ void LP_smartutxos_push(struct iguana_info *coin);
cJSON *LP_address_utxos(struct iguana_info *coin,char *coinaddr,int32_t electrumret);
cJSON *LP_gettxout(char *symbol,char *coinaddr,bits256 txid,int32_t vout);
void LP_postutxos(char *symbol,char *coinaddr);
int32_t LP_listunspent_both(char *symbol,char *coinaddr);
int32_t LP_listunspent_both(char *symbol,char *coinaddr,int32_t fullflag);
uint16_t LP_randpeer(char *destip);
cJSON *bitcoin_data2json(uint8_t taddr,uint8_t pubtype,uint8_t p2shtype,uint8_t isPoS,int32_t height,bits256 *txidp,struct iguana_msgtx *msgtx,uint8_t *extraspace,int32_t extralen,uint8_t *serialized,int32_t len,cJSON *vins,int32_t suppress_pubkeys);
//int32_t LP_butxo_findeither(bits256 txid,int32_t vout);
@ -327,5 +332,6 @@ struct LP_utxoinfo *_LP_utxofind(int32_t iambob,bits256 txid,int32_t vout);
struct LP_utxoinfo *_LP_utxo2find(int32_t iambob,bits256 txid,int32_t vout);
void LP_listunspent_query(char *symbol,char *coinaddr);
int32_t bitcoin_priv2wif(uint8_t wiftaddr,char *wifstr,bits256 privkey,uint8_t addrtype);
#endif

139
iguana/exchanges/LP_nativeDEX.c

@ -13,29 +13,25 @@
* Removal or modification of this copyright notice is prohibited. *
* *
******************************************************************************/
//alice only coins GAME UNO BTM ANC: GAME BTCD PPC RDD XZC POT EAC FTC BASH SPR WDC UNO XPM XCN BELA CHC DIME MEC NAUT MED AUR MAX DGC RIC EB3 DOT BTM GEO ANC CANN ICASH WBB SRC PTC ADZ TIPS EQT START EFL FST FJC NYC GCN
//
// LP_nativeDEX.c
// marketmaker
//
// SPV at tx level and limit SPV proofing
// coins file
// stats, fix pricearray
// sign packets
// dPoW security
// electrum peers
// withdraw
// verify portfolio
// bittrex balancing
// sign critical api calls
// stats
// dPoW security -> 2: KMD notarized, 3: BTC notarized
// add interest to KMD withdraw
// verify portfolio, pricearray, withdraw
// alice only coins GAME UNO BTM ANC: GAME BTCD PPC RDD XZC POT EAC FTC BASH SPR WDC UNO XPM XCN BELA CHC DIME MEC NAUT MED AUR MAX DGC RIC EB3 DOT BTM GEO ANC CANN ICASH WBB SRC PTC ADZ TIPS EQT START EFL FST FJC NYC GCN
#include <stdio.h>
#include "LP_include.h"
portable_mutex_t LP_peermutex,LP_UTXOmutex,LP_utxomutex,LP_commandmutex,LP_cachemutex,LP_swaplistmutex,LP_forwardmutex,LP_pubkeymutex,LP_networkmutex,LP_psockmutex,LP_coinmutex,LP_messagemutex,LP_portfoliomutex,LP_electrummutex,LP_butxomutex;
portable_mutex_t LP_peermutex,LP_UTXOmutex,LP_utxomutex,LP_commandmutex,LP_cachemutex,LP_swaplistmutex,LP_forwardmutex,LP_pubkeymutex,LP_networkmutex,LP_psockmutex,LP_coinmutex,LP_messagemutex,LP_portfoliomutex,LP_electrummutex,LP_butxomutex,LP_reservedmutex,LP_nanorecvsmutex;
int32_t LP_canbind;
char *Broadcaststr;
char *Broadcaststr,*Reserved_msgs[1000];
int32_t num_Reserved_msgs,max_Reserved_msgs;
struct LP_peerinfo *LP_peerinfos,*LP_mypeer;
struct LP_forwardinfo *LP_forwardinfos;
struct iguana_info *LP_coins;
@ -50,6 +46,7 @@ char *default_LPnodes[] = { "5.9.253.195", "5.9.253.196", "5.9.253.197", "5.9.25
//uint32_t LP_deadman_switch;
uint16_t LP_fixed_pairport,LP_publicport;
uint32_t LP_lastnonce;
int32_t LP_mybussock = -1;
int32_t LP_mypubsock = -1;
int32_t LP_mypullsock = -1;
@ -163,7 +160,7 @@ char *LP_process_message(void *ctx,char *typestr,char *myipaddr,int32_t pubsock,
if ( duplicate != 0 )
dup++;
else uniq++;
if ( (rand() % 1000) == 0 )
if ( (rand() % 10000) == 0 )
printf("%s dup.%d (%u / %u) %.1f%% encrypted.%d recv.%u [%02x %02x] vs %02x %02x\n",typestr,duplicate,dup,dup+uniq,(double)100*dup/(dup+uniq),encrypted,crc32,ptr[0],ptr[1],crc32&0xff,(crc32>>8)&0xff);
if ( duplicate == 0 )
{
@ -257,14 +254,14 @@ int32_t LP_sock_check(char *typestr,void *ctx,char *myipaddr,int32_t pubsock,int
{
if ( jobj(argjson,"method") != 0 && strcmp("connect",jstr(argjson,"method")) == 0 )
printf("self.(%s)\n",str);
portable_mutex_lock(&LP_commandmutex);
if ( LP_tradecommand(ctx,myipaddr,pubsock,argjson,0,0) <= 0 )
{
portable_mutex_lock(&LP_commandmutex);
if ( (retstr= stats_JSON(ctx,myipaddr,pubsock,argjson,remoteaddr,0)) != 0 )
free(retstr);
portable_mutex_unlock(&LP_commandmutex);
}
free_json(argjson);
portable_mutex_unlock(&LP_commandmutex);
}
free(str);
}
@ -274,39 +271,52 @@ int32_t LP_sock_check(char *typestr,void *ctx,char *myipaddr,int32_t pubsock,int
return(nonz);
}
void command_rpcloop(void *myipaddr)
int32_t LP_nanomsg_recvs(void *ctx)
{
int32_t nonz = 0; char *origipaddr; struct LP_peerinfo *peer,*tmp; void *ctx;
ctx = bitcoin_ctx();
if ( (origipaddr= myipaddr) == 0 )
static double lastmilli;
int32_t nonz = 0; char *origipaddr; struct LP_peerinfo *peer,*tmp; double milli;
if ( (origipaddr= LP_myipaddr) == 0 )
origipaddr = "127.0.0.1";
while ( 1 )
milli = OS_milliseconds();
if ( lastmilli > 0. && milli > lastmilli+1000 )
fprintf(stderr,">>>>>>>>>>>>>>>>> BIG latency lag %.3f milliseconds\n",milli-lastmilli);
lastmilli = milli;
//portable_mutex_lock(&LP_nanorecvsmutex);
HASH_ITER(hh,LP_peerinfos,peer,tmp)
{
nonz = 0;
HASH_ITER(hh,LP_peerinfos,peer,tmp)
if ( peer->errors >= LP_MAXPEER_ERRORS )
{
if ( peer->errors >= LP_MAXPEER_ERRORS )
if ( (rand() % 10000) == 0 )
peer->errors--;
else
{
if ( (rand() % 10000) == 0 )
peer->errors--;
else
{
//printf("skip %s\n",peer->ipaddr);
continue;
}
//printf("skip %s\n",peer->ipaddr);
continue;
}
//printf("check %s pubsock.%d\n",peer->ipaddr,peer->subsock);
nonz += LP_sock_check("PULL",ctx,origipaddr,LP_mypubsock,peer->subsock,peer->ipaddr);
}
/*HASH_ITER(hh,LP_coins,coin,ctmp) // firstrefht,firstscanht,lastscanht
{
if ( coin->inactive != 0 )
continue;
if ( coin->bussock >= 0 )
nonz += LP_sock_check(coin->symbol,ctx,origipaddr,-1,coin->bussock,LP_profitratio - 1.);
}*/
if ( LP_mypullsock >= 0 )
nonz += LP_sock_check("SUB",ctx,origipaddr,-1,LP_mypullsock,"127.0.0.1");
//printf("check %s pubsock.%d\n",peer->ipaddr,peer->subsock);
nonz += LP_sock_check("PULL",ctx,origipaddr,LP_mypubsock,peer->subsock,peer->ipaddr);
}
/*HASH_ITER(hh,LP_coins,coin,ctmp) // firstrefht,firstscanht,lastscanht
{
if ( coin->inactive != 0 )
continue;
if ( coin->bussock >= 0 )
nonz += LP_sock_check(coin->symbol,ctx,origipaddr,-1,coin->bussock,LP_profitratio - 1.);
}*/
if ( LP_mypullsock >= 0 )
nonz += LP_sock_check("SUB",ctx,origipaddr,-1,LP_mypullsock,"127.0.0.1");
//portable_mutex_unlock(&LP_nanorecvsmutex);
return(nonz);
}
void command_rpcloop(void *myipaddr)
{
int32_t nonz = 0; void *ctx;
ctx = bitcoin_ctx();
while ( 1 )
{
nonz = LP_nanomsg_recvs(ctx);
//if ( LP_mybussock >= 0 )
// nonz += LP_sock_check("BUS",ctx,origipaddr,-1,LP_mybussock);
if ( nonz == 0 )
@ -328,7 +338,7 @@ void LP_smartutxos_push(struct iguana_info *coin)
memset(zero.bytes,0,sizeof(zero));
if ( (n= cJSON_GetArraySize(array)) > 0 )
{
printf("PUSH %s %s\n",coin->symbol,coin->smartaddr);
//printf("PUSH %s %s\n",coin->symbol,coin->smartaddr);
for (i=0; i<n; i++)
{
item = jitem(array,i);
@ -355,7 +365,7 @@ void LP_smartutxos_push(struct iguana_info *coin)
jaddnum(req,"ht",height);
jadd64bits(req,"value",value);
//printf("ADDR_UNSPENTS[] <- %s\n",jprint(req,0));
LP_broadcast_message(LP_mypubsock,"","",zero,jprint(req,1));
LP_reserved_msg("","",zero,jprint(req,1));
}
}
}
@ -375,7 +385,7 @@ int32_t LP_utxos_sync(struct LP_peerinfo *peer)
if ( coin->smartaddr[0] == 0 )
continue;
total = 0;
if ( (j= LP_listunspent_both(coin->symbol,coin->smartaddr)) == 0 )
if ( (j= LP_listunspent_both(coin->symbol,coin->smartaddr,0)) == 0 )
continue;
if ( (array= LP_address_utxos(coin,coin->smartaddr,1)) != 0 )
{
@ -551,7 +561,7 @@ int32_t LP_mainloop_iter(void *ctx,char *myipaddr,struct LP_peerinfo *mypeer,int
memset(&zero,0,sizeof(zero));
if ( coin->addr_listunspent_requested != 0 )
{
printf("addr_listunspent_requested %u\n",coin->addr_listunspent_requested);
//printf("addr_listunspent_requested %u\n",coin->addr_listunspent_requested);
LP_smartutxos_push(coin);
coin->addr_listunspent_requested = 0;
}
@ -687,6 +697,41 @@ void LP_initpeers(int32_t pubsock,struct LP_peerinfo *mypeer,char *myipaddr,uint
}
}
int32_t LP_reserved_msgs()
{
bits256 zero; int32_t n = 0;
memset(zero.bytes,0,sizeof(zero));
portable_mutex_lock(&LP_reservedmutex);
while ( num_Reserved_msgs > 0 )
{
num_Reserved_msgs--;
//printf("BROADCASTING RESERVED.(%s)\n",Reserved_msgs[num_Reserved_msgs]);
LP_broadcast_message(LP_mypubsock,"","",zero,Reserved_msgs[num_Reserved_msgs]);
Reserved_msgs[num_Reserved_msgs] = 0;
n++;
}
portable_mutex_unlock(&LP_reservedmutex);
return(n);
}
int32_t LP_reserved_msg(char *base,char *rel,bits256 pubkey,char *msg)
{
int32_t n = 0;
portable_mutex_lock(&LP_reservedmutex);
if ( num_Reserved_msgs < sizeof(Reserved_msgs)/sizeof(*Reserved_msgs) )
{
Reserved_msgs[num_Reserved_msgs++] = msg;
n = num_Reserved_msgs;
} else LP_broadcast_message(LP_mypubsock,base,rel,pubkey,msg);
portable_mutex_unlock(&LP_reservedmutex);
if ( num_Reserved_msgs > max_Reserved_msgs )
{
max_Reserved_msgs = num_Reserved_msgs;
printf("New max_Reserved_msgs.%d\n",max_Reserved_msgs);
}
return(n);
}
void LPinit(uint16_t myport,uint16_t mypullport,uint16_t mypubport,uint16_t mybusport,char *passphrase,int32_t amclient,char *userhome,cJSON *argjson)
{
char *myipaddr=0; long filesize,n; int32_t timeout,pubsock=-1; struct LP_peerinfo *mypeer=0; char pushaddr[128],subaddr[128],bindaddr[128],*coins_str=0; cJSON *coinsjson=0; void *ctx = bitcoin_ctx();
@ -747,6 +792,8 @@ void LPinit(uint16_t myport,uint16_t mypullport,uint16_t mypubport,uint16_t mybu
portable_mutex_init(&LP_messagemutex);
portable_mutex_init(&LP_portfoliomutex);
portable_mutex_init(&LP_butxomutex);
portable_mutex_init(&LP_reservedmutex);
portable_mutex_init(&LP_nanorecvsmutex);
#ifndef _WIN32
if ( system("curl -s4 checkip.amazonaws.com > DB/myipaddr") == 0 )
{

5
iguana/exchanges/LP_network.c

@ -144,6 +144,7 @@ void queue_loop(void *ignore)
struct LP_queue *ptr,*tmp; int32_t sentbytes,nonz,flag,duplicate,n=0;
while ( 1 )
{
LP_reserved_msgs();
nonz = 0;
//printf("LP_Q.%p next.%p prev.%p\n",LP_Q,LP_Q!=0?LP_Q->next:0,LP_Q!=0?LP_Q->prev:0);
n = 0;
@ -170,7 +171,7 @@ void queue_loop(void *ignore)
if ( duplicate > 0 )
{
LP_Qfound++;
if ( (LP_Qfound % 10) == 0 )
if ( (LP_Qfound % 100) == 0 )
printf("found.%u Q.%d err.%d match.%d\n",ptr->crc32,LP_Qenqueued,LP_Qerrors,LP_Qfound);
flag = 1;
}
@ -199,7 +200,7 @@ void queue_loop(void *ignore)
//if ( n != 0 )
// printf("LP_Q.[%d]\n",n);
if ( nonz == 0 )
usleep(50000);
usleep(5000);
}
}

312
iguana/exchanges/LP_ordermatch.c

@ -19,18 +19,20 @@
// marketmaker
//
uint64_t LP_txfeecalc(struct iguana_info *coin,uint64_t txfee)
uint64_t LP_txfeecalc(struct iguana_info *coin,uint64_t txfee,int32_t txlen)
{
if ( coin != 0 )
{
if ( strcmp(coin->symbol,"BTC") == 0 )
{
if ( txlen == 0 )
txlen = LP_AVETXSIZE;
coin->rate = LP_getestimatedrate(coin);
if ( (txfee= SATOSHIDEN * coin->rate * LP_AVETXSIZE) <= LP_MIN_TXFEE )
if ( (txfee= SATOSHIDEN * coin->rate * txlen) <= LP_MIN_TXFEE )
{
coin->rate = -1.;
coin->rate = _LP_getestimatedrate(coin);
if ( (txfee= SATOSHIDEN * coin->rate * LP_AVETXSIZE) <= LP_MIN_TXFEE )
if ( (txfee= SATOSHIDEN * coin->rate * txlen) <= LP_MIN_TXFEE )
txfee = LP_MIN_TXFEE;
}
} else txfee = coin->txfee;
@ -42,8 +44,8 @@ uint64_t LP_txfeecalc(struct iguana_info *coin,uint64_t txfee)
void LP_txfees(uint64_t *txfeep,uint64_t *desttxfeep,char *base,char *rel)
{
*txfeep = LP_txfeecalc(LP_coinfind(base),0);
*desttxfeep = LP_txfeecalc(LP_coinfind(rel),0);
*txfeep = LP_txfeecalc(LP_coinfind(base),0,0);
*desttxfeep = LP_txfeecalc(LP_coinfind(rel),0,0);
printf("LP_txfees(%.8f %.8f)\n",dstr(*txfeep),dstr(*desttxfeep));
}
@ -219,41 +221,37 @@ char *LP_quotereceived(cJSON *argjson)
char *LP_pricepings(void *ctx,char *myipaddr,int32_t pubsock,char *base,char *rel,double price)
{
bits256 zero; char *msg; cJSON *reqjson = cJSON_CreateObject();
bits256 zero; cJSON *reqjson = cJSON_CreateObject();
memset(zero.bytes,0,sizeof(zero));
jaddbits256(reqjson,"pubkey",G.LP_mypub25519);
jaddstr(reqjson,"base",base);
jaddstr(reqjson,"rel",rel);
jaddnum(reqjson,"price",price);
jaddstr(reqjson,"method","postprice");
msg = jprint(reqjson,1);
LP_broadcast_message(pubsock,base,rel,zero,msg);
LP_reserved_msg(base,rel,zero,jprint(reqjson,1));
return(clonestr("{\"result\":\"success\"}"));
}
void LP_notify_pubkeys(void *ctx,int32_t pubsock)
{
bits256 zero; char *msg,secpstr[67]; cJSON *reqjson = cJSON_CreateObject();
bits256 zero; char secpstr[67]; cJSON *reqjson = cJSON_CreateObject();
memset(zero.bytes,0,sizeof(zero));
jaddstr(reqjson,"method","notify");
jaddstr(reqjson,"rmd160",G.LP_myrmd160str);
jaddbits256(reqjson,"pub",G.LP_mypub25519);
init_hexbytes_noT(secpstr,G.LP_pubsecp,33);
jaddstr(reqjson,"pubsecp",secpstr);
msg = jprint(reqjson,1);
LP_broadcast_message(pubsock,"","",zero,msg);
LP_reserved_msg("","",zero,jprint(reqjson,1));
}
void LP_listunspent_query(char *symbol,char *coinaddr)
{
bits256 zero; char *msg; cJSON *reqjson = cJSON_CreateObject();
bits256 zero; cJSON *reqjson = cJSON_CreateObject();
memset(zero.bytes,0,sizeof(zero));
jaddstr(reqjson,"method","addr_unspents");
jaddstr(reqjson,"coin",symbol);
jaddstr(reqjson,"address",coinaddr);
msg = jprint(reqjson,1);
printf("BROADCAST.(%s)\n",msg);
LP_broadcast_message(LP_mypubsock,"","",zero,msg);
LP_reserved_msg("","",zero,jprint(reqjson,1));
}
char *LP_postedprice(cJSON *argjson)
@ -291,7 +289,7 @@ int32_t LP_quote_checkmempool(struct LP_quoteinfo *qp,struct LP_utxoinfo *autxo,
double LP_quote_validate(struct LP_utxoinfo *autxo,struct LP_utxoinfo *butxo,struct LP_quoteinfo *qp,int32_t iambob)
{
double qprice=0.; uint64_t txfee,desttxfee,srcvalue=0,srcvalue2=0,destvalue=0,destvalue2=0;
printf("quote %s %.8f -> %s %.8f\n",qp->srccoin,dstr(qp->satoshis),qp->destcoin,dstr(qp->destsatoshis));
printf(">>>>>>> quote satoshis.(%.8f %.8f) %s %.8f -> %s %.8f\n",dstr(qp->satoshis),dstr(qp->destsatoshis),qp->srccoin,dstr(qp->satoshis),qp->destcoin,dstr(qp->destsatoshis));
if ( butxo != 0 )
{
if (LP_iseligible(&srcvalue,&srcvalue2,1,qp->srccoin,qp->txid,qp->vout,qp->satoshis,qp->txid2,qp->vout2) == 0 )
@ -380,9 +378,9 @@ int32_t LP_arrayfind(cJSON *array,bits256 txid,int32_t vout)
return(-1);
}
double LP_query(void *ctx,char *myipaddr,int32_t mypubsock,char *method,struct LP_quoteinfo *qp)
void LP_query(void *ctx,char *myipaddr,int32_t mypubsock,char *method,struct LP_quoteinfo *qp)
{
cJSON *reqjson; bits256 zero; char *msg; int32_t i,flag = 0; double price = 0.; struct LP_utxoinfo *utxo;
cJSON *reqjson; bits256 zero; char *msg; int32_t flag = 0; struct LP_utxoinfo *utxo;
if ( strcmp(method,"request") == 0 )
{
if ( (utxo= LP_utxofind(0,qp->desttxid,qp->destvout)) != 0 && LP_ismine(utxo) > 0 && LP_isavailable(utxo) > 0 )
@ -390,7 +388,7 @@ double LP_query(void *ctx,char *myipaddr,int32_t mypubsock,char *method,struct L
else
{
printf("couldnt find my txid to make request\n");
return(0.);
return;
}
}
reqjson = LP_quotejson(qp);
@ -401,24 +399,16 @@ double LP_query(void *ctx,char *myipaddr,int32_t mypubsock,char *method,struct L
msg = jprint(reqjson,1);
printf("QUERY.(%s)\n",msg);
memset(&zero,0,sizeof(zero));
if ( 1 && strcmp(method,"request") == 0 )
{
sleep(3);
LP_broadcast_message(LP_mypubsock,qp->srccoin,qp->destcoin,zero,msg);
} else LP_broadcast_message(LP_mypubsock,qp->srccoin,qp->destcoin,qp->srchash,msg);
for (i=0; i<20; i++)
portable_mutex_lock(&LP_reservedmutex);
if ( num_Reserved_msgs < sizeof(Reserved_msgs)/sizeof(*Reserved_msgs) )
Reserved_msgs[num_Reserved_msgs++] = msg;
else
{
if ( (price= LP_pricecache(qp,qp->srccoin,qp->destcoin,qp->txid,qp->vout)) > SMALLVAL )
{
if ( flag == 0 || bits256_nonz(qp->desthash) != 0 )
{
printf("break out of loop.%d price %.8f %s/%s\n",i,price,qp->srccoin,qp->destcoin);
break;
}
}
sleep(1);
//if ( 1 && strcmp(method,"request") == 0 )
LP_broadcast_message(LP_mypubsock,qp->srccoin,qp->destcoin,zero,msg);
//else LP_broadcast_message(LP_mypubsock,qp->srccoin,qp->destcoin,qp->srchash,msg);
}
return(price);
portable_mutex_unlock(&LP_reservedmutex);
}
int32_t LP_nanobind(void *ctx,char *pairstr)
@ -461,42 +451,41 @@ int32_t LP_nearest_utxovalue(struct iguana_info *coin,struct LP_address_utxo **u
if ( (backupep= ep->prev) == 0 )
backupep = ep;
}
printf("LP_nearest_utxovalue %s utxos[%d] target %.8f\n",coin->symbol,n,dstr(targetval));
//printf("LP_nearest_utxovalue %s utxos[%d] target %.8f\n",coin->symbol,n,dstr(targetval));
for (i=0; i<n; i++)
{
if ( (up= utxos[i]) != 0 )
{
dist = (up->U.value - targetval);
printf("nearest i.%d target %.8f val %.8f dist %.8f mindist %.8f mini.%d spent.%d\n",i,dstr(targetval),dstr(up->U.value),dstr(dist),dstr(mindist),mini,up->spendheight);
//printf("nearest i.%d target %.8f val %.8f dist %.8f mindist %.8f mini.%d spent.%d\n",i,dstr(targetval),dstr(up->U.value),dstr(dist),dstr(mindist),mini,up->spendheight);
if ( up->spendheight <= 0 )
{
if ( coin->electrum != 0 )
{
if (up->SPV == 0 )
if (up->SPV <= 0 )
up->SPV = LP_merkleproof(coin,backupep,up->U.txid,up->U.height);
printf("%s %s: SPV.%d\n",coin->symbol,bits256_str(str,up->U.txid),up->SPV);
if ( up->SPV < 0 )
{
printf("SPV failure for %s %s\n",coin->symbol,bits256_str(str,up->U.txid));
continue;
}
} else printf("%s %s: SPV.%d\n",coin->symbol,bits256_str(str,up->U.txid),up->SPV);
}
if ( dist >= 0 && dist < mindist )
{
printf("(%.8f %.8f %.8f).%d ",dstr(up->U.value),dstr(dist),dstr(mindist),mini);
//printf("(%.8f %.8f %.8f).%d ",dstr(up->U.value),dstr(dist),dstr(mindist),mini);
mini = i;
mindist = dist;
}
}
}
}
printf("return mini.%d\n",mini);
//printf("return mini.%d\n",mini);
return(mini);
}
uint64_t LP_basesatoshis(double relvolume,double price,uint64_t txfee,uint64_t desttxfee)
{
printf("basesatoshis %.8f (rel %.8f / price %.8f)\n",dstr(SATOSHIDEN * ((relvolume) / price) + 2*txfee),relvolume,price);
//printf("basesatoshis %.8f (rel %.8f / price %.8f)\n",dstr(SATOSHIDEN * ((relvolume) / price) + 2*txfee),relvolume,price);
if ( relvolume > dstr(desttxfee) && price > SMALLVAL )
return(SATOSHIDEN * (relvolume / price) + 2*txfee);
else return(0);
@ -510,7 +499,7 @@ struct LP_utxoinfo *LP_address_utxopair(int32_t iambob,struct LP_address_utxo **
if ( (m= LP_address_utxo_ptrs(iambob,utxos,max,ap)) > 1 )
{
targetval = LP_basesatoshis(relvolume,price,txfee,desttxfee);
if ( 1 )
if ( 0 )
{
int32_t i;
for (i=0; i<m; i++)
@ -523,8 +512,9 @@ struct LP_utxoinfo *LP_address_utxopair(int32_t iambob,struct LP_address_utxo **
up = utxos[mini];
utxos[mini] = 0;
targetval2 = (targetval / 8) * 9 + 2*txfee;
printf("found mini.%d %.8f for targetval %.8f -> targetval2 %.8f, ratio %.2f\n",mini,dstr(up->U.value),dstr(targetval),dstr(targetval2),(double)up->U.value/targetval);
//printf("found mini.%d %.8f for targetval %.8f -> targetval2 %.8f, ratio %.2f\n",mini,dstr(up->U.value),dstr(targetval),dstr(targetval2),(double)up->U.value/targetval);
if ( (double)up->U.value/targetval < LP_MINVOL-1 )
{
if ( (mini= LP_nearest_utxovalue(coin,utxos,m,targetval2 * 1.01)) >= 0 )
{
@ -537,7 +527,7 @@ struct LP_utxoinfo *LP_address_utxopair(int32_t iambob,struct LP_address_utxo **
return(utxo);
}
}
} else printf("cant find targetval2 %.8f\n",dstr(targetval2));
} //else printf("cant find targetval2 %.8f\n",dstr(targetval2));
} else printf("failed ratio test %.8f\n",(double)up->U.value/targetval);
} else if ( targetval != 0 && mini >= 0 )
printf("targetval %.8f mini.%d\n",dstr(targetval),mini);
@ -582,7 +572,7 @@ void LP_abutxo_set(struct LP_utxoinfo *autxo,struct LP_utxoinfo *butxo,struct LP
int32_t LP_connectstartbob(void *ctx,int32_t pubsock,struct LP_utxoinfo *utxo,cJSON *argjson,char *base,char *rel,double price,struct LP_quoteinfo *qp)
{
char pairstr[512],*msg; cJSON *retjson; bits256 privkey; int32_t pair=-1,retval = -1,DEXselector = 0; struct basilisk_swap *swap; struct iguana_info *coin;
char pairstr[512]; cJSON *retjson; bits256 privkey; int32_t pair=-1,retval = -1,DEXselector = 0; struct basilisk_swap *swap; struct iguana_info *coin;
printf("LP_connectstartbob.(%s) with.(%s) %s\n",LP_myipaddr,jprint(argjson,0),LP_myipaddr);
qp->quotetime = (uint32_t)time(NULL);
if ( (coin= LP_coinfind(utxo->coin)) == 0 )
@ -596,9 +586,7 @@ int32_t LP_connectstartbob(void *ctx,int32_t pubsock,struct LP_utxoinfo *utxo,cJ
if ( (pair= LP_nanobind(ctx,pairstr)) >= 0 )
{
LP_requestinit(&qp->R,qp->srchash,qp->desthash,base,qp->satoshis-2*qp->txfee,rel,qp->destsatoshis-2*qp->desttxfee,qp->timestamp,qp->quotetime,DEXselector);
printf("call swapinit\n");
swap = LP_swapinit(1,0,privkey,&qp->R,qp);
printf("swapinit.%p\n",swap);
swap->N.pair = pair;
utxo->S.swap = swap;
swap->utxo = utxo;
@ -610,8 +598,7 @@ int32_t LP_connectstartbob(void *ctx,int32_t pubsock,struct LP_utxoinfo *utxo,cJ
jaddnum(retjson,"requestid",qp->R.requestid);
jaddnum(retjson,"quoteid",qp->R.quoteid);
char str[65]; printf("BOB pubsock.%d binds to %d (%s)\n",pubsock,pair,bits256_str(str,utxo->S.otherpubkey));
msg = jprint(retjson,1);
LP_broadcast_message(pubsock,base,rel,utxo->S.otherpubkey,msg);
LP_reserved_msg(base,rel,utxo->S.otherpubkey,jprint(retjson,1));
retval = 0;
} else printf("error launching swaploop\n");
} else printf("couldnt bind to any port %s\n",pairstr);
@ -695,7 +682,7 @@ char *LP_connectedalice(cJSON *argjson) // alice
return(clonestr("{\"error\":\"cant get alicecoin\"}"));
}
Q.privkey = LP_privkey(Q.destaddr,coin->taddr);
if ( bits256_nonz(Q.privkey) != 0 && Q.quotetime >= Q.timestamp-3 )
if ( bits256_nonz(Q.privkey) != 0 )//&& Q.quotetime >= Q.timestamp-3 )
{
retjson = cJSON_CreateObject();
if ( (pairstr= jstr(argjson,"pair")) == 0 || (pairsock= nn_socket(AF_SP,NN_PAIR)) < 0 )
@ -728,12 +715,12 @@ char *LP_connectedalice(cJSON *argjson) // alice
else
{
LP_availableset(autxo);
printf("no privkey found\n");
printf("no privkey found coin.%s %s taddr.%u\n",Q.destcoin,Q.destaddr,coin->taddr);
return(clonestr("{\"error\",\"no privkey\"}"));
}
}
int32_t LP_listunspent_both(char *symbol,char *coinaddr)
int32_t LP_listunspent_both(char *symbol,char *coinaddr,int32_t fullflag)
{
int32_t i,v,height,n=0; uint64_t value; bits256 txid; char buf[512]; cJSON *array,*item; struct iguana_info *coin = LP_coinfind(symbol);
if ( coin != 0 )//&& (IAMLP != 0 || coin->inactive == 0) )
@ -743,7 +730,7 @@ int32_t LP_listunspent_both(char *symbol,char *coinaddr)
//printf("issue path electrum.%p\n",coin->electrum);
//if ( coin->electrum != 0 && (array= electrum_address_gethistory(symbol,coin->electrum,&array,coinaddr)) != 0 )
// free_json(array);
n = LP_listunspent_issue(symbol,coinaddr);
n = LP_listunspent_issue(symbol,coinaddr,fullflag);
}
else
{
@ -770,19 +757,90 @@ int32_t LP_listunspent_both(char *symbol,char *coinaddr)
return(n);
}
char *LP_bestfit(char *rel,double relvolume)
{
struct LP_utxoinfo *autxo;
if ( relvolume <= 0. || LP_priceinfofind(rel) == 0 )
return(clonestr("{\"error\":\"invalid parameter\"}"));
if ( (autxo= LP_utxo_bestfit(rel,SATOSHIDEN * relvolume)) == 0 )
return(clonestr("{\"error\":\"cant find utxo that is big enough\"}"));
return(jprint(LP_utxojson(autxo),1));
}
struct LP_quoteinfo LP_Alicequery;
double LP_Alicemaxprice;
char *LP_trade(void *ctx,char *myipaddr,int32_t mypubsock,struct LP_quoteinfo *qp,double maxprice,int32_t timeout,int32_t duration)
{
struct LP_utxoinfo *aliceutxo; double price; //cJSON *bestitem=0; int32_t DEXselector=0; uint32_t expiration; double price; struct LP_pubkeyinfo *pubp; struct basilisk_swap *swap;
if ( (aliceutxo= LP_utxopairfind(0,qp->desttxid,qp->destvout,qp->feetxid,qp->feevout)) == 0 )
{
char str[65],str2[65]; printf("dest.(%s)/v%d fee.(%s)/v%d\n",bits256_str(str,qp->desttxid),qp->destvout,bits256_str(str2,qp->feetxid),qp->feevout);
return(clonestr("{\"error\":\"cant find alice utxopair\"}"));
}
price = 0.;
LP_query(ctx,myipaddr,mypubsock,"request",qp);
LP_Alicequery = *qp, LP_Alicemaxprice = maxprice;
return(clonestr("{\"result\":\"success\"}"));
}
int32_t LP_quotecmp(struct LP_quoteinfo *qp,struct LP_quoteinfo *qp2)
{
if ( bits256_cmp(qp->srchash,qp2->srchash) == 0 && bits256_cmp(qp->desthash,qp2->desthash) == 0 && strcmp(qp->srccoin,qp2->srccoin) == 0 && strcmp(qp->destcoin,qp2->destcoin) == 0 && bits256_cmp(qp->desttxid,qp2->desttxid) == 0 && qp->destvout == qp2->destvout && bits256_cmp(qp->feetxid,qp2->feetxid) == 0 && qp->feevout == qp2->feevout && qp->destsatoshis == qp2->destsatoshis && qp->txfee >= qp2->txfee && qp->desttxfee == qp2->desttxfee )
return(0);
else return(-1);
}
void LP_reserved(void *ctx,char *myipaddr,int32_t mypubsock,struct LP_quoteinfo *qp)
{
double price,maxprice = LP_Alicemaxprice;
if ( LP_quotecmp(qp,&LP_Alicequery) == 0 )
{
price = LP_pricecache(qp,qp->srccoin,qp->destcoin,qp->txid,qp->vout);
if ( LP_pricevalid(price) > 0 && maxprice > SMALLVAL && price <= maxprice )
{
memset(&LP_Alicequery,0,sizeof(LP_Alicequery));
LP_Alicemaxprice = 0.;
LP_query(ctx,myipaddr,mypubsock,"connect",qp);
}
}
}
int32_t LP_tradecommand(void *ctx,char *myipaddr,int32_t pubsock,cJSON *argjson,uint8_t *data,int32_t datalen)
{
char *method,*msg; uint64_t value,value2; cJSON *retjson; double qprice,price,bid,ask; struct LP_utxoinfo A,B,*autxo,*butxo; struct iguana_info *coin; struct LP_address_utxo *utxos[1000]; struct LP_quoteinfo Q; int32_t retval = -1,max=(int32_t)(sizeof(utxos)/sizeof(*utxos));
if ( (method= jstr(argjson,"method")) != 0 && (strcmp(method,"request") == 0 ||strcmp(method,"connect") == 0) )
char *method,*msg,*retstr,str[65]; int32_t DEXselector = 0; uint64_t value,value2; cJSON *retjson; double qprice,price,bid,ask; struct LP_utxoinfo A,B,*autxo,*butxo; struct iguana_info *coin; struct LP_address_utxo *utxos[1000]; struct LP_quoteinfo Q; int32_t retval = -1,max=(int32_t)(sizeof(utxos)/sizeof(*utxos));
if ( (method= jstr(argjson,"method")) != 0 && (strcmp(method,"reserved") == 0 ||strcmp(method,"connected") == 0 || strcmp(method,"request") == 0 || strcmp(method,"connect") == 0) )
{
printf("LP_tradecommand: check received %s\n",method);
LP_quoteparse(&Q,argjson);
LP_requestinit(&Q.R,Q.srchash,Q.desthash,Q.srccoin,Q.satoshis-2*Q.txfee,Q.destcoin,Q.destsatoshis-2*Q.desttxfee,Q.timestamp,Q.quotetime,DEXselector);
printf("LP_tradecommand: check received method %s\n",method);
retval = 1;
if ( LP_quoteparse(&Q,argjson) == 0 && bits256_cmp(G.LP_mypub25519,Q.srchash) == 0 && bits256_cmp(G.LP_mypub25519,Q.desthash) != 0 )
if ( strcmp(method,"reserved") == 0 )
{
if ( bits256_cmp(G.LP_mypub25519,Q.desthash) == 0 && bits256_cmp(G.LP_mypub25519,Q.srchash) != 0 )
{
printf("alice %s received RESERVED.(%s)\n",bits256_str(str,G.LP_mypub25519),jprint(argjson,0));
if ( (retstr= LP_quotereceived(argjson)) != 0 )
free(retstr);
LP_reserved(ctx,myipaddr,pubsock,&Q);
}
return(retval);
}
else if ( strcmp(method,"connected") == 0 )
{
if ( bits256_cmp(G.LP_mypub25519,Q.desthash) == 0 && bits256_cmp(G.LP_mypub25519,Q.srchash) != 0 )
{
printf("alice %s received CONNECTED.(%s)\n",bits256_str(str,G.LP_mypub25519),jprint(argjson,0));
if ( (retstr= LP_connectedalice(argjson)) != 0 )
free(retstr);
}
return(retval);
}
if ( bits256_cmp(G.LP_mypub25519,Q.srchash) == 0 && bits256_cmp(G.LP_mypub25519,Q.desthash) != 0 )
{
if ( (coin= LP_coinfind(Q.srccoin)) == 0 || (price= LP_myprice(&bid,&ask,Q.srccoin,Q.destcoin)) <= SMALLVAL || ask <= SMALLVAL )
{
printf("this node has no price for %s/%s\n",Q.srccoin,Q.destcoin);
return(-3);
return(retval);
}
price = ask;
autxo = &A;
@ -799,7 +857,7 @@ int32_t LP_tradecommand(void *ctx,char *myipaddr,int32_t pubsock,cJSON *argjson,
if ( LP_allocated(butxo->payment.txid,butxo->payment.vout) != 0 || LP_allocated(butxo->deposit.txid,butxo->deposit.vout) != 0 || (qprice= LP_quote_validate(autxo,butxo,&Q,1)) <= SMALLVAL )
{
printf("butxo.%p replace path %p %s, %p %s, %.8f\n",butxo,LP_allocated(butxo->payment.txid,butxo->payment.vout),bits256_str(str,butxo->payment.txid),LP_allocated(butxo->deposit.txid,butxo->deposit.vout),bits256_str(str2,butxo->deposit.txid),LP_quote_validate(autxo,butxo,&Q,1));
LP_listunspent_both(Q.srccoin,Q.coinaddr);
LP_listunspent_both(Q.srccoin,Q.coinaddr,0);
if ( (butxo= LP_address_utxopair(1,utxos,max,LP_coinfind(Q.srccoin),Q.coinaddr,Q.txfee,dstr(Q.destsatoshis),price,Q.desttxfee)) != 0 )
{
Q.txid = butxo->payment.txid;
@ -828,17 +886,17 @@ int32_t LP_tradecommand(void *ctx,char *myipaddr,int32_t pubsock,cJSON *argjson,
if ( butxo == 0 || bits256_nonz(butxo->payment.txid) == 0 || bits256_nonz(butxo->deposit.txid) == 0 || butxo->payment.vout < 0 || butxo->deposit.vout < 0 )
{
char str[65],str2[65]; printf("couldnt find bob utxos for autxo %s/v%d %s/v%d %.8f -> %.8f\n",bits256_str(str,Q.txid),Q.vout,bits256_str(str2,Q.txid2),Q.vout2,dstr(Q.satoshis),dstr(Q.destsatoshis));
return(1);
return(retval);
}
if ( (qprice= LP_quote_validate(autxo,butxo,&Q,1)) <= SMALLVAL )
{
printf("quote validate error %.0f\n",qprice);
return(-4);
return(-3);
}
if ( qprice < (price - 0.00000001) * 0.9999 )
{
printf("(%.8f %.8f) quote price %.8f too low vs %.8f for %s/%s\n",bid,ask,qprice,price,Q.srccoin,Q.destcoin);
return(-5);
return(-4);
}
if ( butxo->S.swap == 0 && time(NULL) > butxo->T.swappending )
butxo->T.swappending = 0;
@ -846,7 +904,7 @@ int32_t LP_tradecommand(void *ctx,char *myipaddr,int32_t pubsock,cJSON *argjson,
{
if ( LP_isavailable(butxo) > 0 )
{
butxo->T.swappending = Q.timestamp + LP_RESERVETIME;
autxo->T.swappending = butxo->T.swappending = Q.timestamp + LP_RESERVETIME;
retjson = LP_quotejson(&Q);
butxo->S.otherpubkey = jbits256(argjson,"desthash");
LP_unavailableset(butxo,butxo->S.otherpubkey);
@ -857,17 +915,9 @@ int32_t LP_tradecommand(void *ctx,char *myipaddr,int32_t pubsock,cJSON *argjson,
jaddstr(retjson,"method","reserved");
msg = jprint(retjson,1);
butxo->T.lasttime = (uint32_t)time(NULL);
printf("set swappending.%u accept qprice %.8f, min %.8f\n(%s)\n",butxo->T.swappending,qprice,price,msg);
{
bits256 zero; char *msg2;
memset(&zero,0,sizeof(zero));
msg2 = clonestr(msg);
LP_broadcast_message(pubsock,Q.srccoin,Q.destcoin,zero,msg);
//LP_broadcast_message(pubsock,Q.srccoin,Q.destcoin,butxo->S.otherpubkey,msg2);
//LP_butxo_swapfields_set(butxo);
printf("return after RESERVED\n");
return(2);
}
printf("return after queued RESERVED: set swappending.%u accept qprice %.8f, min %.8f\n(%s)\n",butxo->T.swappending,qprice,price,msg);
LP_reserved_msg(Q.srccoin,Q.destcoin,butxo->S.otherpubkey,msg);
return(retval);
} else printf("warning swappending.%u swap.%p\n",butxo->T.swappending,butxo->S.swap);
}
else if ( strcmp(method,"connect") == 0 ) // bob
@ -878,7 +928,7 @@ int32_t LP_tradecommand(void *ctx,char *myipaddr,int32_t pubsock,cJSON *argjson,
// validate SPV alice
LP_connectstartbob(ctx,pubsock,butxo,argjson,Q.srccoin,Q.destcoin,qprice,&Q);
//LP_butxo_swapfields_set(butxo);
return(3);
return(retval);
}
else printf("pend.%u swap %p when connect came in (%s)\n",butxo->T.swappending,butxo->S.swap,jprint(argjson,0));
}
@ -888,73 +938,6 @@ int32_t LP_tradecommand(void *ctx,char *myipaddr,int32_t pubsock,cJSON *argjson,
return(retval);
}
char *LP_bestfit(char *rel,double relvolume)
{
struct LP_utxoinfo *autxo;
if ( relvolume <= 0. || LP_priceinfofind(rel) == 0 )
return(clonestr("{\"error\":\"invalid parameter\"}"));
if ( (autxo= LP_utxo_bestfit(rel,SATOSHIDEN * relvolume)) == 0 )
return(clonestr("{\"error\":\"cant find utxo that is big enough\"}"));
return(jprint(LP_utxojson(autxo),1));
}
char *LP_trade(void *ctx,char *myipaddr,int32_t mypubsock,struct LP_quoteinfo *qp,double maxprice,int32_t timeout,int32_t duration)
{
struct LP_utxoinfo *aliceutxo; cJSON *bestitem=0; int32_t DEXselector=0; uint32_t expiration; double price; struct LP_pubkeyinfo *pubp; struct basilisk_swap *swap;
if ( (aliceutxo= LP_utxopairfind(0,qp->desttxid,qp->destvout,qp->feetxid,qp->feevout)) == 0 )
{
char str[65],str2[65]; printf("dest.(%s)/v%d fee.(%s)/v%d\n",bits256_str(str,qp->desttxid),qp->destvout,bits256_str(str2,qp->feetxid),qp->feevout);
return(clonestr("{\"error\":\"cant find alice utxopair\"}"));
}
price = LP_query(ctx,myipaddr,mypubsock,"request",qp);
bestitem = LP_quotejson(qp);
if ( LP_pricevalid(price) > 0 )
{
if ( price <= maxprice )
{
price = LP_query(ctx,myipaddr,mypubsock,"connect",qp);
LP_requestinit(&qp->R,qp->srchash,qp->desthash,qp->srccoin,qp->satoshis-2*qp->txfee,qp->destcoin,qp->destsatoshis-2*qp->desttxfee,qp->timestamp,qp->quotetime,DEXselector);
expiration = (uint32_t)time(NULL) + timeout;
while ( time(NULL) < expiration )
{
if ( aliceutxo->S.swap != 0 )
break;
sleep(3);
}
jaddnum(bestitem,"quotedprice",price);
jaddnum(bestitem,"maxprice",maxprice);
if ( (swap= aliceutxo->S.swap) == 0 )
{
if ( (pubp= LP_pubkeyadd(qp->srchash)) != 0 )
pubp->numerrors++;
jaddstr(bestitem,"status","couldnt establish connection");
}
else
{
jaddstr(bestitem,"status","connected");
jaddnum(bestitem,"requestid",swap->I.req.requestid);
jaddnum(bestitem,"quoteid",swap->I.req.quoteid);
printf("Alice r.%u qp->%u\n",swap->I.req.requestid,swap->I.req.quoteid);
}
}
else
{
jaddnum(bestitem,"quotedprice",price);
jaddnum(bestitem,"maxprice",maxprice);
jaddstr(bestitem,"status","too expensive");
}
}
else
{
printf("invalid price %.8f\n",price);
jaddnum(bestitem,"maxprice",maxprice);
jaddstr(bestitem,"status","no response to request");
}
if ( aliceutxo->S.swap == 0 )
LP_availableset(aliceutxo);
return(jprint(bestitem,0));
}
struct LP_utxoinfo *LP_ordermatch_iter(struct LP_address_utxo **utxos,int32_t max,double *ordermatchpricep,int64_t *bestsatoshisp,int64_t *bestdestsatoshisp,struct iguana_info *basecoin,char *coinaddr,uint64_t asatoshis,double price,uint64_t txfee,uint64_t desttxfee,bits256 pubkey,char *gui)
{
uint64_t basesatoshis; struct LP_utxoinfo *bestutxo;
@ -996,7 +979,7 @@ struct LP_utxoinfo *LP_buyutxo(double *ordermatchpricep,int64_t *bestsatoshisp,i
item = jitem(asks,i);
price = jdouble(item,"price");
pubkey = jbits256(item,"pubkey");
printf("[%d/%d] %s pubcmp %d price %.8f vs maxprice %.8f\n",i,numasks,jprint(item,0),bits256_cmp(pubkey,G.LP_mypub25519),price,maxprice);
//printf("[%d/%d] %s pubcmp %d price %.8f vs maxprice %.8f\n",i,numasks,jprint(item,0),bits256_cmp(pubkey,G.LP_mypub25519),price,maxprice);
if ( LP_pricevalid(price) > 0 && price <= maxprice )
{
for (j=0; j<numavoids; j++)
@ -1008,7 +991,7 @@ struct LP_utxoinfo *LP_buyutxo(double *ordermatchpricep,int64_t *bestsatoshisp,i
{
bitcoin_address(coinaddr,basecoin->taddr,basecoin->pubtype,pubp->rmd160,sizeof(pubp->rmd160));
LP_listunspent_query(base,coinaddr);
LP_listunspent_both(base,coinaddr);
LP_listunspent_both(base,coinaddr,1);
asatoshis = autxo->S.satoshis;
for (j=0; j<maxiters; j++)
{
@ -1043,19 +1026,25 @@ struct LP_utxoinfo *LP_buyutxo(double *ordermatchpricep,int64_t *bestsatoshisp,i
return(bestutxo);
}
char *LP_autobuy(void *ctx,char *myipaddr,int32_t mypubsock,char *base,char *rel,double maxprice,double relvolume,int32_t timeout,int32_t duration,char *gui)
char *LP_autobuy(void *ctx,char *myipaddr,int32_t mypubsock,char *base,char *rel,double maxprice,double relvolume,int32_t timeout,int32_t duration,char *gui,uint32_t nonce)
{
uint64_t desttxfee,txfee; int32_t numpubs = 0; int64_t bestsatoshis=0,destsatoshis,bestdestsatoshis=0; struct LP_utxoinfo *autxo,*bestutxo = 0; double qprice,ordermatchprice=0.; struct LP_quoteinfo Q; bits256 pubkeys[100];
printf("LP_autobuy %s/%s price %.8f vol %.8f\n",base,rel,maxprice,relvolume);
uint64_t desttxfee,txfee; uint32_t lastnonce; int32_t i,maxiters,numpubs = 0; int64_t bestsatoshis=0,destsatoshis,bestdestsatoshis=0; struct LP_utxoinfo *autxo,*bestutxo = 0; double qprice,ordermatchprice=0.; struct LP_quoteinfo Q; bits256 pubkeys[100];
printf("LP_autobuy %s/%s price %.8f vol %.8f nonce %u\n",base,rel,maxprice,relvolume,nonce);
if ( (lastnonce= LP_lastnonce) != 0 && nonce <= lastnonce )
{
printf("nonce.%u not bigger than lastnonce.%u\n",nonce,lastnonce);
return(clonestr("{\"error\":\"invalid nonce\"}"));
}
LP_lastnonce = nonce;
if ( duration <= 0 )
duration = LP_ORDERBOOK_DURATION;
if ( timeout <= 0 )
timeout = LP_AUTOTRADE_TIMEOUT;
if ( maxprice <= 0. || relvolume <= 0. || LP_priceinfofind(base) == 0 || LP_priceinfofind(rel) == 0 )
return(clonestr("{\"error\":\"invalid parameter\"}"));
if ( strcmp("BTC",rel) == 0 )
maxprice *= 1.01;
else maxprice *= 1.001;
//if ( strcmp("BTC",rel) == 0 )
// maxprice *= 1.01;
//else maxprice *= 1.001;
memset(pubkeys,0,sizeof(pubkeys));
LP_txfees(&txfee,&desttxfee,base,rel);
destsatoshis = SATOSHIDEN * relvolume + 2*desttxfee;
@ -1075,9 +1064,24 @@ char *LP_autobuy(void *ctx,char *myipaddr,int32_t mypubsock,char *base,char *rel
return(clonestr("{\"error\":\"cant set ordermatch quote\"}"));
if ( LP_quotedestinfo(&Q,autxo->payment.txid,autxo->payment.vout,autxo->fee.txid,autxo->fee.vout,G.LP_mypub25519,autxo->coinaddr) < 0 )
return(clonestr("{\"error\":\"cant set ordermatch quote info\"}"));
if ( (qprice= LP_quote_validate(autxo,0,&Q,0)) <= SMALLVAL )
maxiters = 100;
qprice = 1. / SMALLVAL;
for (i=0; i<maxiters; i++)
{
if ( (qprice= LP_quote_validate(autxo,0,&Q,0)) <= SMALLVAL )
{
printf("quote validate error %.0f\n",qprice);
return(clonestr("{\"error\":\"quote validate error\"}"));
}
if ( qprice/ordermatchprice < 1.+SMALLVAL )
{
printf("i.%d/%d qprice %.8f < ordermatchprice %.8f\n",i,maxiters,qprice,ordermatchprice);
Q.satoshis *= 0.9999;
} else break;
}
if ( i == maxiters || qprice > maxprice )
{
printf("continue searching, quote validate error %.0f\n",qprice);
printf("i.%d maxiters.%d qprice %.8f vs maxprice %.8f, no acceptable quote for this pubkey\n",i,maxiters,dstr(qprice),dstr(maxprice));
continue;
}
break;

5
iguana/exchanges/LP_peers.c

@ -128,11 +128,10 @@ struct LP_peerinfo *LP_addpeer(struct LP_peerinfo *mypeer,int32_t mypubsock,char
portable_mutex_unlock(&LP_peermutex);
if ( IAMLP != 0 && mypubsock >= 0 )
{
struct iguana_info *coin,*ctmp; bits256 zero; char *msg,busaddr[64];
msg = jprint(LP_peerjson(peer),1);
struct iguana_info *coin,*ctmp; bits256 zero; char busaddr[64];
memset(zero.bytes,0,sizeof(zero));
//LP_send(mypubsock,msg,(int32_t)strlen(msg)+1,1);
LP_broadcast_message(mypubsock,"","",zero,msg);
LP_reserved_msg("","",zero,jprint(LP_peerjson(peer),1));
if ( 0 )
{
HASH_ITER(hh,LP_coins,coin,ctmp)

2
iguana/exchanges/LP_portfolio.c

@ -441,7 +441,7 @@ int32_t LP_portfolio_trade(void *ctx,uint32_t *requestidp,uint32_t *quoteidp,str
break;
if ( LP_utxo_bestfit(sell->symbol,SATOSHIDEN * relvolume) != 0 )
{
if ( (retstr2= LP_autobuy(ctx,"127.0.0.1",-1,buy->symbol,sell->symbol,maxprice,relvolume,60,24*3600,gui)) != 0 )
if ( (retstr2= LP_autobuy(ctx,"127.0.0.1",-1,buy->symbol,sell->symbol,maxprice,relvolume,60,24*3600,gui,LP_lastnonce+1)) != 0 )
{
if ( (retjson2= cJSON_Parse(retstr2)) != 0 )
{

29
iguana/exchanges/LP_prices.c

@ -221,10 +221,21 @@ char *LP_pubkey_trustset(bits256 pubkey,uint32_t trustval)
return(clonestr("{\"error\":\"pubkey not found\"}"));
}
char *LP_pubkey_trusted()
{
struct LP_pubkeyinfo *pubp,*tmp; cJSON *array = cJSON_CreateArray();
HASH_ITER(hh,LP_pubkeyinfos,pubp,tmp)
{
if ( pubp->istrusted != 0 )
jaddibits256(array,pubp->pubkey);
}
return(jprint(array,1));
}
uint64_t LP_unspents_metric(struct iguana_info *coin,char *coinaddr)
{
cJSON *array,*item; int32_t i,n; uint64_t metric=0,total;
LP_listunspent_both(coin->symbol,coinaddr);
LP_listunspent_both(coin->symbol,coinaddr,0);
if ( (array= LP_address_utxos(coin,coinaddr,1)) != 0 )
{
total = 0;
@ -666,8 +677,8 @@ cJSON *LP_orderbookjson(char *symbol,struct LP_orderbookentry *op)
jaddstr(item,"address",op->coinaddr);
jaddnum(item,"price",op->price);
jaddnum(item,"numutxos",op->numutxos);
jaddnum(item,"minvolume",dstr(op->minsatoshis));
jaddnum(item,"maxvolume",dstr(op->maxsatoshis));
jaddnum(item,"minvolume",dstr(op->minsatoshis)*0.8);
jaddnum(item,"maxvolume",dstr(op->maxsatoshis)*0.8);
jaddbits256(item,"pubkey",op->pubkey);
jaddnum(item,"age",time(NULL)-op->timestamp);
}
@ -771,11 +782,11 @@ char *LP_orderbook(char *base,char *rel,int32_t duration)
for (i=n=0; i<numbids; i++)
{
jaddi(array,LP_orderbookjson(rel,bids[i]));
if ( bids[i]->numutxos == 0 )//|| relcoin->electrum == 0 )
if ( n < 10 && bids[i]->numutxos == 0 )//|| relcoin->electrum == 0 )
{
LP_address(relcoin,bids[i]->coinaddr);
if ( relcoin->electrum == 0 )
LP_listunspent_issue(rel,bids[i]->coinaddr);
LP_listunspent_issue(rel,bids[i]->coinaddr,0);
LP_listunspent_query(rel,bids[i]->coinaddr);
n++;
}
@ -790,11 +801,11 @@ char *LP_orderbook(char *base,char *rel,int32_t duration)
for (i=n=0; i<numasks; i++)
{
jaddi(array,LP_orderbookjson(base,asks[i]));
if ( asks[i]->numutxos == 0 )//|| basecoin->electrum == 0 )
if ( n < 10 && asks[i]->numutxos == 0 )//|| basecoin->electrum == 0 )
{
LP_address(basecoin,asks[i]->coinaddr);
if ( basecoin->electrum == 0 )
LP_listunspent_issue(base,asks[i]->coinaddr);
LP_listunspent_issue(base,asks[i]->coinaddr,0);
LP_listunspent_query(base,asks[i]->coinaddr);
n++;
}
@ -1017,7 +1028,7 @@ void LP_pricefeedupdate(bits256 pubkey,char *base,char *rel,double price)
pubp->timestamp = (uint32_t)time(NULL);
} else printf("error creating pubkey entry\n");
}
else if ( (rand() % 100) == 0 )
printf("error finding %s/%s %.8f\n",base,rel,price);
//else if ( (rand() % 100) == 0 )
// printf("error finding %s/%s %.8f\n",base,rel,price);
}

168
iguana/exchanges/LP_remember.c

@ -267,7 +267,7 @@ bits256 basilisk_swap_spendupdate(char *symbol,char *spentaddr,int32_t *sentflag
if ( bits256_nonz(spendtxid) != 0 )
{
sentflags[utxoind] = 1;
printf("utxoind.%d Alice.(%s) Bob.(%s)\n",utxoind,aliceaddr,bobaddr);
printf("utxoind.%d Alice.(%s %s) Bob.(%s %s) vs destaddr.(%s)\n",utxoind,aliceaddr,Adest,bobaddr,dest,destaddr);
if ( aliceaddr != 0 && (strcmp(destaddr,aliceaddr) == 0 || strcmp(Adest,destaddr) == 0) )
{
printf("ALICE spent.(%s) -> %s\n",bits256_str(str,txid),destaddr);
@ -287,13 +287,13 @@ bits256 basilisk_swap_spendupdate(char *symbol,char *spentaddr,int32_t *sentflag
printf("OTHER dest spent.(%s) -> %s\n",bits256_str(str,txid),destaddr);
if ( aliceaddr != 0 )
{
sentflags[bobspent] = 0;
sentflags[bobspent] = 1;
sentflags[alicespent] = 0;
txids[bobspent] = spendtxid;
}
else if ( bobaddr != 0 )
{
sentflags[alicespent] = 0;
sentflags[alicespent] = 1;
sentflags[bobspent] = 0;
txids[alicespent] = spendtxid;
}
@ -358,7 +358,7 @@ int32_t basilisk_swap_isfinished(int32_t iambob,bits256 *txids,int32_t *sentflag
if ( bits256_nonz(depositspent) != 0 )
return(1);
}
else if ( bits256_nonz(paymentspent) != 0 )
else if ( bits256_nonz(Apaymentspent) != 0 )
return(1);
}
else
@ -467,7 +467,7 @@ struct LP_swap_remember
uint32_t requestid,quoteid,plocktime,dlocktime,expiration,state,otherstate;
int32_t iambob,finishedflag,origfinishedflag,Predeemlen,Dredeemlen,sentflags[sizeof(txnames)/sizeof(*txnames)];
uint8_t secretAm[20],secretAm256[32],secretBn[20],secretBn256[32],Predeemscript[1024],Dredeemscript[1024],pubkey33[33],other33[33];
char src[64],dest[64],destaddr[64],Adestaddr[64],alicepaymentaddr[64],bobpaymentaddr[64],bobdepositaddr[64],alicecoin[64],bobcoin[64],*txbytes[sizeof(txnames)/sizeof(*txnames)];
char src[64],dest[64],destaddr[64],Adestaddr[64],Sdestaddr[64],alicepaymentaddr[64],bobpaymentaddr[64],bobdepositaddr[64],alicecoin[64],bobcoin[64],*txbytes[sizeof(txnames)/sizeof(*txnames)];
};
cJSON *LP_swap_json(struct LP_swap_remember *rswap)
@ -511,7 +511,7 @@ cJSON *LP_swap_json(struct LP_swap_remember *rswap)
int32_t LP_rswap_init(struct LP_swap_remember *rswap,uint32_t requestid,uint32_t quoteid)
{
char fname[1024],*fstr,*secretstr,*srcstr,*deststr,*dest33,*txname; long fsize; cJSON *item,*txobj,*array; bits256 privkey; uint32_t r,q; int32_t i,j,n; uint8_t other33[33];
char fname[1024],*fstr,*secretstr,*srcstr,*deststr,*dest33,*txname; long fsize; cJSON *item,*txobj,*array; bits256 privkey; struct iguana_info *coin; uint32_t r,q; int32_t i,j,n; uint8_t other33[33];
memset(rswap,0,sizeof(*rswap));
rswap->requestid = requestid;
rswap->quoteid = quoteid;
@ -536,6 +536,10 @@ int32_t LP_rswap_init(struct LP_swap_remember *rswap,uint32_t requestid,uint32_t
if ( (dest33= jstr(item,"dest33")) != 0 && strlen(dest33) == 66 )
{
decode_hex(rswap->pubkey33,33,dest33);
if ( rswap->iambob != 0 && (coin= LP_coinfind(rswap->src)) != 0 )
bitcoin_address(rswap->destaddr,coin->taddr,coin->pubtype,rswap->pubkey33,33);
else if ( rswap->iambob == 0 && (coin= LP_coinfind(rswap->dest)) != 0 )
bitcoin_address(rswap->Adestaddr,coin->taddr,coin->pubtype,rswap->pubkey33,33);
//for (i=0; i<33; i++)
// printf("%02x",pubkey33[i]);
//printf(" <- %s dest33\n",dest33);
@ -548,7 +552,11 @@ int32_t LP_rswap_init(struct LP_swap_remember *rswap,uint32_t requestid,uint32_t
break;
if ( i < 33 )
memcpy(rswap->other33,other33,33);
//printf(" <- %s dest33\n",dest33);
if ( rswap->iambob != 0 && (coin= LP_coinfind(rswap->dest)) != 0 )
bitcoin_address(rswap->Adestaddr,coin->taddr,coin->pubtype,rswap->other33,33);
else if ( rswap->iambob == 0 && (coin= LP_coinfind(rswap->src)) != 0 )
bitcoin_address(rswap->destaddr,coin->taddr,coin->pubtype,rswap->other33,33);
//printf("(%s, %s) <- %s other33\n",rswap->destaddr,rswap->Adestaddr,dest33);
}
if ( (rswap->plocktime= juint(item,"plocktime")) == 0 )
rswap->plocktime = LP_extract(requestid,quoteid,fname,"plocktime");
@ -637,7 +645,8 @@ int32_t LP_rswap_init(struct LP_swap_remember *rswap,uint32_t requestid,uint32_t
int32_t _LP_refht_update(struct iguana_info *coin,bits256 txid,int32_t refht)
{
if ( refht > 0 && (coin->firstrefht == 0 || refht < coin->firstrefht) )
refht -= 9;
if ( refht > 10 && (coin->firstrefht == 0 || refht < coin->firstrefht) )
{
char str[65]; printf(">>>>>>>>. 1st refht %s %s <- %d, scan %d %d\n",coin->symbol,bits256_str(str,txid),refht,coin->firstscanht,coin->lastscanht);
if ( coin->firstscanht == 0 || refht < coin->firstscanht )
@ -809,57 +818,87 @@ int32_t LP_rswap_checktx(struct LP_swap_remember *rswap,char *symbol,int32_t txi
return(0);
}
int32_t LP_spends_set(struct LP_swap_remember *rswap)
{
int32_t numspent = 0;
if ( bits256_nonz(rswap->paymentspent) == 0 )
{
if ( bits256_nonz(rswap->txids[BASILISK_ALICESPEND]) != 0 )
rswap->paymentspent = rswap->txids[BASILISK_ALICESPEND];
else rswap->paymentspent = rswap->txids[BASILISK_BOBRECLAIM];
} else numspent++;
if ( bits256_nonz(rswap->depositspent) == 0 )
{
if ( bits256_nonz(rswap->txids[BASILISK_BOBREFUND]) != 0 )
rswap->depositspent = rswap->txids[BASILISK_BOBREFUND];
else rswap->depositspent = rswap->txids[BASILISK_ALICECLAIM];
} else numspent++;
if ( bits256_nonz(rswap->Apaymentspent) == 0 )
{
if ( bits256_nonz(rswap->txids[BASILISK_BOBSPEND]) != 0 )
rswap->Apaymentspent = rswap->txids[BASILISK_BOBSPEND];
else rswap->Apaymentspent = rswap->txids[BASILISK_ALICERECLAIM];
} else numspent++;
return(numspent);
}
cJSON *basilisk_remember(int64_t *KMDtotals,int64_t *BTCtotals,uint32_t requestid,uint32_t quoteid)
{
static void *ctx;
struct LP_swap_remember rswap; int32_t i,j,len,secretstart,redeemlen; char str[65],*Adest,*Bdest,*AAdest,*ABdest; cJSON *item; bits256 rev,signedtxid,zero; struct iguana_info *bob=0,*alice=0; uint8_t redeemscript[1024],userdata[1024];
struct LP_swap_remember rswap; int32_t i,j,numspent,len,secretstart,redeemlen; char str[65],*srcAdest,*srcBdest,*destAdest,*destBdest,otheraddr[64]; cJSON *item; bits256 rev,signedtxid,zero; struct iguana_info *bob=0,*alice=0; uint8_t redeemscript[1024],userdata[1024];
if ( ctx == 0 )
ctx = bitcoin_ctx();
if ( (rswap.iambob= LP_rswap_init(&rswap,requestid,quoteid)) < 0 )
return(cJSON_Parse("{\"error\":\"couldnt initialize rswap, are all coins active?\"}"));
LP_swap_load(&rswap);
memset(zero.bytes,0,sizeof(zero));
Adest = Bdest = AAdest = ABdest = 0;
otheraddr[0] = 0;
srcAdest = srcBdest = destAdest = destBdest = 0;
if ( rswap.bobcoin[0] == 0 || rswap.alicecoin[0] == 0 || strcmp(rswap.bobcoin,rswap.src) != 0 || strcmp(rswap.alicecoin,rswap.dest) != 0 )
{
printf("BOB.(%s) Alice.(%s) src.(%s) dest.(%s)\n",rswap.bobcoin,rswap.alicecoin,rswap.src,rswap.dest);
printf("legacy DB SWAPS files BOB.(%s) Alice.(%s) src.(%s) dest.(%s)\n",rswap.bobcoin,rswap.alicecoin,rswap.src,rswap.dest);
return(cJSON_Parse("{\"error\":\"mismatched bob/alice vs src/dest coins??\"}"));
}
alice = LP_coinfind(rswap.alicecoin);
bob = LP_coinfind(rswap.bobcoin);
rswap.Atxfee = LP_txfeecalc(alice,rswap.Atxfee);
rswap.Btxfee = LP_txfeecalc(bob,rswap.Btxfee);
rswap.Atxfee = LP_txfeecalc(alice,rswap.Atxfee,0);
rswap.Btxfee = LP_txfeecalc(bob,rswap.Btxfee,0);
if ( rswap.iambob == 0 )
{
if ( alice != 0 )
{
bitcoin_address(rswap.Adestaddr,alice->taddr,alice->pubtype,rswap.pubkey33,33);
AAdest = rswap.Adestaddr;
bitcoin_address(otheraddr,alice->taddr,alice->pubtype,rswap.other33,33);
destBdest = otheraddr;
destAdest = rswap.Adestaddr;
}
if ( (bob= LP_coinfind(rswap.bobcoin)) != 0 )
{
bitcoin_address(rswap.destaddr,bob->taddr,bob->pubtype,rswap.pubkey33,33);
Adest = rswap.destaddr;
bitcoin_address(rswap.Sdestaddr,bob->taddr,bob->pubtype,rswap.pubkey33,33);
srcAdest = rswap.Sdestaddr;
}
srcBdest = rswap.destaddr;
}
else
{
if ( bob != 0 )
{
bitcoin_address(rswap.destaddr,bob->taddr,bob->pubtype,rswap.pubkey33,33);
Bdest = rswap.destaddr;
bitcoin_address(otheraddr,bob->taddr,bob->pubtype,rswap.other33,33);
srcAdest = otheraddr;
srcBdest = rswap.destaddr;
}
if ( (alice= LP_coinfind(rswap.alicecoin)) != 0 )
{
bitcoin_address(rswap.Adestaddr,alice->taddr,alice->pubtype,rswap.pubkey33,33);
ABdest = rswap.Adestaddr;
bitcoin_address(rswap.Sdestaddr,alice->taddr,alice->pubtype,rswap.pubkey33,33);
destBdest = rswap.Sdestaddr;
}
destAdest = rswap.Adestaddr;
}
if ( bob == 0 || alice == 0 )
{
printf("Bob.%p is null or Alice.%p is null\n",bob,alice);
return(cJSON_Parse("{\"error\":\"null bob or alice coin\"}"));
}
//printf("src.(Adest %s, Bdest %s), dest.(Adest %s, Bdest %s)\n",srcAdest,srcBdest,destAdest,destBdest);
//printf("iambob.%d finishedflag.%d %s %.8f txfee, %s %.8f txfee\n",rswap.iambob,rswap.finishedflag,rswap.alicecoin,dstr(rswap.Atxfee),rswap.bobcoin,dstr(rswap.Btxfee));
//printf("privAm.(%s) %p/%p\n",bits256_str(str,rswap.privAm),Adest,AAdest);
//printf("privBn.(%s) %p/%p\n",bits256_str(str,rswap.privBn),Bdest,ABdest);
@ -875,10 +914,11 @@ cJSON *basilisk_remember(int64_t *KMDtotals,int64_t *BTCtotals,uint32_t requesti
LP_rswap_checktx(&rswap,rswap.alicecoin,BASILISK_ALICEPAYMENT);
LP_rswap_checktx(&rswap,rswap.bobcoin,BASILISK_BOBPAYMENT);
LP_rswap_checktx(&rswap,rswap.bobcoin,BASILISK_BOBDEPOSIT);
rswap.paymentspent = basilisk_swap_spendupdate(rswap.bobcoin,rswap.bobpaymentaddr,rswap.sentflags,rswap.txids,BASILISK_BOBPAYMENT,BASILISK_ALICESPEND,BASILISK_BOBRECLAIM,0,Adest,Bdest,rswap.Adestaddr,rswap.destaddr);
rswap.Apaymentspent = basilisk_swap_spendupdate(rswap.alicecoin,rswap.alicepaymentaddr,rswap.sentflags,rswap.txids,BASILISK_ALICEPAYMENT,BASILISK_ALICERECLAIM,BASILISK_BOBSPEND,0,AAdest,ABdest,rswap.Adestaddr,rswap.destaddr);
rswap.depositspent = basilisk_swap_spendupdate(rswap.bobcoin,rswap.bobdepositaddr,rswap.sentflags,rswap.txids,BASILISK_BOBDEPOSIT,BASILISK_ALICECLAIM,BASILISK_BOBREFUND,0,Adest,Bdest,rswap.Adestaddr,rswap.destaddr);
rswap.paymentspent = basilisk_swap_spendupdate(rswap.bobcoin,rswap.bobpaymentaddr,rswap.sentflags,rswap.txids,BASILISK_BOBPAYMENT,BASILISK_ALICESPEND,BASILISK_BOBRECLAIM,0,srcAdest,srcBdest,rswap.Adestaddr,rswap.destaddr);
rswap.Apaymentspent = basilisk_swap_spendupdate(rswap.alicecoin,rswap.alicepaymentaddr,rswap.sentflags,rswap.txids,BASILISK_ALICEPAYMENT,BASILISK_ALICERECLAIM,BASILISK_BOBSPEND,0,destAdest,destBdest,rswap.Adestaddr,rswap.destaddr);
rswap.depositspent = basilisk_swap_spendupdate(rswap.bobcoin,rswap.bobdepositaddr,rswap.sentflags,rswap.txids,BASILISK_BOBDEPOSIT,BASILISK_ALICECLAIM,BASILISK_BOBREFUND,0,srcAdest,srcBdest,rswap.Adestaddr,rswap.destaddr);
rswap.finishedflag = basilisk_swap_isfinished(rswap.iambob,rswap.txids,rswap.sentflags,rswap.paymentspent,rswap.Apaymentspent,rswap.depositspent);
LP_spends_set(&rswap);
if ( rswap.iambob == 0 )
{
if ( rswap.sentflags[BASILISK_ALICESPEND] == 0 )
@ -912,15 +952,6 @@ cJSON *basilisk_remember(int64_t *KMDtotals,int64_t *BTCtotals,uint32_t requesti
}
}
LP_txbytes_update("alicespend",rswap.bobcoin,rswap.txbytes[BASILISK_ALICESPEND],&rswap.txids[BASILISK_ALICESPEND],&rswap.paymentspent,&rswap.sentflags[BASILISK_ALICESPEND]);
/*if ( rswap.txbytes[BASILISK_ALICESPEND] != 0 )
{
rswap.txids[BASILISK_ALICESPEND] = LP_broadcast("alicespend",rswap.bobcoin,rswap.txbytes[BASILISK_ALICESPEND],zero);
if ( bits256_nonz(rswap.txids[BASILISK_ALICESPEND]) != 0 ) // tested
{
rswap.sentflags[BASILISK_ALICESPEND] = 1;
rswap.paymentspent = rswap.txids[BASILISK_ALICESPEND];
}
}*/
}
}
if ( rswap.sentflags[BASILISK_ALICECLAIM] == 0 && rswap.sentflags[BASILISK_BOBDEPOSIT] != 0 && bits256_nonz(rswap.txids[BASILISK_BOBDEPOSIT]) != 0 && bits256_nonz(rswap.depositspent) == 0 )
@ -945,15 +976,6 @@ cJSON *basilisk_remember(int64_t *KMDtotals,int64_t *BTCtotals,uint32_t requesti
}
}
LP_txbytes_update("aliceclaim",rswap.bobcoin,rswap.txbytes[BASILISK_ALICECLAIM],&rswap.txids[BASILISK_ALICECLAIM],&rswap.depositspent,&rswap.sentflags[BASILISK_ALICECLAIM]);
/*if ( rswap.txbytes[BASILISK_ALICECLAIM] != 0 )
{
rswap.txids[BASILISK_ALICECLAIM] = LP_broadcast("aliceclaim",rswap.bobcoin,rswap.txbytes[BASILISK_ALICECLAIM],zero);
if ( bits256_nonz(rswap.txids[BASILISK_ALICECLAIM]) != 0 ) // tested
{
rswap.sentflags[BASILISK_ALICECLAIM] = 1;
rswap.depositspent = rswap.txids[BASILISK_ALICECLAIM];
}
}*/
} else printf("now %u before expiration %u\n",(uint32_t)time(NULL),rswap.expiration);
}
if ( rswap.sentflags[BASILISK_ALICEPAYMENT] != 0 && bits256_nonz(rswap.Apaymentspent) == 0 && rswap.sentflags[BASILISK_ALICECLAIM] == 0 )
@ -968,15 +990,6 @@ cJSON *basilisk_remember(int64_t *KMDtotals,int64_t *BTCtotals,uint32_t requesti
}
}
LP_txbytes_update("alicereclaim",rswap.alicecoin,rswap.txbytes[BASILISK_ALICERECLAIM],&rswap.txids[BASILISK_ALICERECLAIM],&rswap.Apaymentspent,&rswap.sentflags[BASILISK_ALICERECLAIM]);
/*if ( rswap.txbytes[BASILISK_ALICERECLAIM] != 0 )
{
rswap.txids[BASILISK_ALICERECLAIM] = LP_broadcast("alicereclaim",rswap.alicecoin,rswap.txbytes[BASILISK_ALICERECLAIM],zero);
if ( bits256_nonz(rswap.txids[BASILISK_ALICERECLAIM]) != 0 ) // tested
{
rswap.sentflags[BASILISK_ALICERECLAIM] = 1;
rswap.Apaymentspent = rswap.txids[BASILISK_ALICERECLAIM];
}
}*/
}
}
else if ( rswap.iambob == 1 )
@ -991,6 +1004,7 @@ cJSON *basilisk_remember(int64_t *KMDtotals,int64_t *BTCtotals,uint32_t requesti
if ( bits256_nonz(rswap.privAm) == 0 )
{
rswap.privAm = basilisk_swap_privbob_extract(rswap.bobcoin,rswap.txids[BASILISK_ALICESPEND],0,1);
printf("try to bobspend aspend.%s have privAm.%d\n",bits256_str(str,rswap.txids[BASILISK_ALICESPEND]),bits256_nonz(rswap.privAm));
}
if ( bits256_nonz(rswap.privAm) != 0 && bits256_nonz(rswap.privBn) != 0 )
{
@ -999,15 +1013,6 @@ cJSON *basilisk_remember(int64_t *KMDtotals,int64_t *BTCtotals,uint32_t requesti
}
}
LP_txbytes_update("bobspend",rswap.alicecoin,rswap.txbytes[BASILISK_BOBSPEND],&rswap.txids[BASILISK_BOBSPEND],&rswap.Apaymentspent,&rswap.sentflags[BASILISK_BOBSPEND]);
/*if ( rswap.txbytes[BASILISK_BOBSPEND] != 0 )
{
rswap.txids[BASILISK_BOBSPEND] = LP_broadcast("bobspend",rswap.alicecoin,rswap.txbytes[BASILISK_BOBSPEND],zero);
if ( bits256_nonz(rswap.txids[BASILISK_BOBSPEND]) != 0 ) // tested
{
rswap.sentflags[BASILISK_BOBSPEND] = 1;
rswap.Apaymentspent = rswap.txids[BASILISK_BOBSPEND];
}
}*/
}
}
if ( rswap.sentflags[BASILISK_BOBRECLAIM] == 0 && rswap.sentflags[BASILISK_BOBPAYMENT] != 0 && bits256_nonz(rswap.txids[BASILISK_BOBPAYMENT]) != 0 && time(NULL) > rswap.expiration && bits256_nonz(rswap.paymentspent) == 0 )
@ -1029,21 +1034,12 @@ cJSON *basilisk_remember(int64_t *KMDtotals,int64_t *BTCtotals,uint32_t requesti
}
}
LP_txbytes_update("bobreclaim",rswap.bobcoin,rswap.txbytes[BASILISK_BOBRECLAIM],&rswap.txids[BASILISK_BOBRECLAIM],&rswap.paymentspent,&rswap.sentflags[BASILISK_BOBRECLAIM]);
/*if ( rswap.txbytes[BASILISK_BOBRECLAIM] != 0 )
{
rswap.txids[BASILISK_BOBRECLAIM] = LP_broadcast("bobreclaim",rswap.bobcoin,rswap.txbytes[BASILISK_BOBRECLAIM],zero);
if ( bits256_nonz(rswap.txids[BASILISK_BOBRECLAIM]) != 0 ) // tested
{
rswap.sentflags[BASILISK_BOBRECLAIM] = 1;
rswap.paymentspent = rswap.txids[BASILISK_BOBRECLAIM];
}
}*/
}
if ( rswap.sentflags[BASILISK_BOBREFUND] == 0 && rswap.sentflags[BASILISK_BOBDEPOSIT] != 0 && bits256_nonz(rswap.txids[BASILISK_BOBDEPOSIT]) != 0 && bits256_nonz(rswap.depositspent) == 0 )
{
if ( bits256_nonz(rswap.paymentspent) != 0 || time(NULL) > rswap.expiration )
if ( bits256_nonz(rswap.Apaymentspent) != 0 || time(NULL) > rswap.expiration )
{
printf("do the refund!\n");
printf("do the refund! paymentspent.%s now.%u vs expiration.%u\n",bits256_str(str,rswap.paymentspent),(uint32_t)time(NULL),rswap.expiration);
//if ( txbytes[BASILISK_BOBREFUND] == 0 )
{
revcalc_rmd160_sha256(rswap.secretBn,rswap.privBn);
@ -1054,15 +1050,6 @@ cJSON *basilisk_remember(int64_t *KMDtotals,int64_t *BTCtotals,uint32_t requesti
printf("pubB1.(%s) bobrefund.(%s)\n",bits256_str(str,rswap.pubB1),rswap.txbytes[BASILISK_BOBREFUND]);
}
LP_txbytes_update("bobrefund",rswap.bobcoin,rswap.txbytes[BASILISK_BOBREFUND],&rswap.txids[BASILISK_BOBREFUND],&rswap.depositspent,&rswap.sentflags[BASILISK_BOBREFUND]);
/*if ( rswap.txbytes[BASILISK_BOBREFUND] != 0 )
{
rswap.txids[BASILISK_BOBREFUND] = LP_broadcast("bobrefund",rswap.bobcoin,rswap.txbytes[BASILISK_BOBREFUND],zero);
if ( bits256_nonz(rswap.txids[BASILISK_BOBREFUND]) != 0 ) // tested
{
rswap.sentflags[BASILISK_BOBREFUND] = 1;
rswap.depositspent = rswap.txids[BASILISK_BOBREFUND];
}
}*/
} else printf("bobrefund's time %u vs expiration %u\n",(uint32_t)time(NULL),rswap.expiration);
}
}
@ -1084,26 +1071,7 @@ cJSON *basilisk_remember(int64_t *KMDtotals,int64_t *BTCtotals,uint32_t requesti
printf("depositspent.(%s) alice.%d bob.%d %s %.8f\n",bits256_str(str,rswap.depositspent),rswap.sentflags[BASILISK_ALICECLAIM],rswap.sentflags[BASILISK_BOBREFUND],rswap.bobcoin,dstr(rswap.values[BASILISK_BOBDEPOSIT]));
}
LP_totals_update(rswap.iambob,rswap.alicecoin,rswap.bobcoin,KMDtotals,BTCtotals,rswap.sentflags,rswap.values);
int32_t numspent = 0;
if ( bits256_nonz(rswap.paymentspent) == 0 )
{
if ( bits256_nonz(rswap.txids[BASILISK_ALICESPEND]) != 0 )
rswap.paymentspent = rswap.txids[BASILISK_ALICESPEND];
else rswap.paymentspent = rswap.txids[BASILISK_BOBRECLAIM];
} else numspent++;
if ( bits256_nonz(rswap.depositspent) == 0 )
{
if ( bits256_nonz(rswap.txids[BASILISK_BOBREFUND]) != 0 )
rswap.depositspent = rswap.txids[BASILISK_BOBREFUND];
else rswap.depositspent = rswap.txids[BASILISK_ALICECLAIM];
} else numspent++;
if ( bits256_nonz(rswap.Apaymentspent) == 0 )
{
if ( bits256_nonz(rswap.txids[BASILISK_BOBSPEND]) != 0 )
rswap.Apaymentspent = rswap.txids[BASILISK_BOBSPEND];
else rswap.Apaymentspent = rswap.txids[BASILISK_ALICERECLAIM];
} else numspent++;
if ( numspent == 3 )
if ( (numspent= LP_spends_set(&rswap)) == 3 )
rswap.finishedflag = 1;
else rswap.finishedflag = basilisk_swap_isfinished(rswap.iambob,rswap.txids,rswap.sentflags,rswap.paymentspent,rswap.Apaymentspent,rswap.depositspent);
item = LP_swap_json(&rswap);

51
iguana/exchanges/LP_rpc.c

@ -326,7 +326,7 @@ cJSON *LP_gettxout(char *symbol,char *coinaddr,bits256 txid,int32_t vout)
return(0);
return(LP_gettxout_json(txid,vout,up->U.height,coinaddr,up->U.value));
}
if ( (array= electrum_address_listunspent(coin->symbol,0,&array,coinaddr)) != 0 )
if ( (array= electrum_address_listunspent(coin->symbol,0,&array,coinaddr,1)) != 0 )
{
//printf("array.(%s)\n",jprint(array,0));
if ( array != 0 && (n= cJSON_GetArraySize(array)) > 0 )
@ -419,6 +419,24 @@ int32_t LP_address_ismine(char *symbol,char *address)
return(doneflag);
}
int32_t LP_address_isvalid(char *symbol,char *address)
{
int32_t isvalid = 0; cJSON *retjson;
if ( symbol == 0 || symbol[0] == 0 )
return(0);
if ( (retjson= LP_validateaddress(symbol,address)) != 0 )
{
if ( jobj(retjson,"isvalid") != 0 && is_cJSON_True(jobj(retjson,"isvalid")) != 0 )
{
isvalid = 1;
//printf("%s ismine (%s)\n",address,jprint(retjson,0));
}
//printf("%s\n",jprint(retjson,0));
free_json(retjson);
}
return(isvalid);
}
cJSON *LP_listunspent(char *symbol,char *coinaddr)
{
char buf[128]; cJSON *retjson; struct iguana_info *coin;
@ -435,19 +453,19 @@ cJSON *LP_listunspent(char *symbol,char *coinaddr)
sprintf(buf,"[0, 99999999, [\"%s\"]]",coinaddr);
return(bitcoin_json(coin,"listunspent",buf));
} else return(LP_address_utxos(coin,coinaddr,0));
} else return(electrum_address_listunspent(symbol,coin->electrum,&retjson,coinaddr));
} else return(electrum_address_listunspent(symbol,coin->electrum,&retjson,coinaddr,1));
}
int32_t LP_listunspent_issue(char *symbol,char *coinaddr)
int32_t LP_listunspent_issue(char *symbol,char *coinaddr,int32_t fullflag)
{
struct iguana_info *coin; int32_t n = 0; cJSON *retjson=0; char *retstr=0;// uint16_t destport;
struct iguana_info *coin; int32_t n = 0; cJSON *retjson=0; char *retstr=0,destip[64]; uint16_t destport;
if ( symbol == 0 || symbol[0] == 0 )
return(0);
if ( (coin= LP_coinfind(symbol)) != 0 )
{
if ( coin->electrum != 0 )
{
if ( (retjson= electrum_address_listunspent(symbol,coin->electrum,&retjson,coinaddr)) != 0 )
if ( (retjson= electrum_address_listunspent(symbol,coin->electrum,&retjson,coinaddr,1)) != 0 )
{
n = cJSON_GetArraySize(retjson);
//printf("LP_listunspent_issue.%s %s.%d %s\n",symbol,coinaddr,n,jprint(retjson,0));
@ -461,17 +479,22 @@ int32_t LP_listunspent_issue(char *symbol,char *coinaddr)
//printf("SELF_LISTUNSPENT.(%s %s)\n",symbol,coinaddr);
}
else if ( IAMLP == 0 )
LP_listunspent_query(coin->symbol,coin->smartaddr);
/*else if ( (destport= LP_randpeer(destip)) > 0 )
{
retstr = issue_LP_listunspent(destip,destport,symbol,coinaddr);
printf("issue %s %s %s -> (%s)\n",coin->symbol,coinaddr,destip,retstr);
retjson = cJSON_Parse(retstr);
} else printf("LP_listunspent_issue couldnt get a random peer?\n");*/
LP_listunspent_query(coin->symbol,coin->smartaddr);
if ( fullflag != 0 )
{
if ( (destport= LP_randpeer(destip)) > 0 )
{
retstr = issue_LP_listunspent(destip,destport,symbol,coinaddr);
printf("issue %s %s %s -> (%s)\n",coin->symbol,coinaddr,destip,retstr);
retjson = cJSON_Parse(retstr);
} else printf("LP_listunspent_issue couldnt get a random peer?\n");
}
}
if ( retjson != 0 )
{
n = cJSON_GetArraySize(retjson);
if ( electrum_process_array(coin,0,coinaddr,retjson) != 0 )
if ( electrum_process_array(coin,0,coinaddr,retjson,1) != 0 )
{
//LP_postutxos(symbol,coinaddr); // might be good to not saturate
}
@ -607,9 +630,9 @@ double LP_getestimatedrate(struct iguana_info *coin)
char *LP_sendrawtransaction(char *symbol,char *signedtx)
{
cJSON *array,*errobj; char *paramstr,*tmpstr,*retstr=0; int32_t n,alreadyflag = 0; cJSON *retjson; struct iguana_info *coin;
if ( symbol == 0 || symbol[0] == 0 )
if ( symbol == 0 || symbol[0] == 0 || signedtx == 0 || signedtx[0] == 0 )
{
printf("LP_sendrawtransaction null symbol\n");
printf("LP_sendrawtransaction null symbol %p or signedtx.%p\n",symbol,signedtx);
return(0);
}
coin = LP_coinfind(symbol);

11
iguana/exchanges/LP_scan.c

@ -391,7 +391,7 @@ char *LP_dividends(struct iguana_info *coin,int32_t height,cJSON *argjson)
return(clonestr("{\"error\":\"symbol not found\"}"));
}
int32_t LP_spendsearch(bits256 *spendtxidp,int32_t *indp,char *symbol,bits256 searchtxid,int32_t searchvout)
int32_t LP_spendsearch(char *coinaddr,bits256 *spendtxidp,int32_t *indp,char *symbol,bits256 searchtxid,int32_t searchvout)
{
struct LP_transaction *tx; struct iguana_info *coin;
*indp = -1;
@ -404,6 +404,7 @@ int32_t LP_spendsearch(bits256 *spendtxidp,int32_t *indp,char *symbol,bits256 se
{
*spendtxidp = tx->outpoints[searchvout].spendtxid;
*indp = tx->outpoints[searchvout].spendvini;
LP_swap_getcoinaddr(symbol,coinaddr,*spendtxidp,*indp);
return(tx->outpoints[searchvout].spendheight);
}
}
@ -481,7 +482,7 @@ int32_t LP_waitmempool(char *symbol,char *coinaddr,bits256 txid,int32_t vout,int
}
free(array);
}
LP_listunspent_issue(coin->symbol,coinaddr);
LP_listunspent_issue(coin->symbol,coinaddr,1);
struct LP_address_utxo *up;
if ( (up= LP_address_utxofind(coin,coinaddr,txid,vout)) != 0 )
{
@ -504,7 +505,7 @@ int32_t LP_waitmempool(char *symbol,char *coinaddr,bits256 txid,int32_t vout,int
int32_t LP_mempool_vinscan(bits256 *spendtxidp,int32_t *spendvinp,char *symbol,char *coinaddr,bits256 searchtxid,int32_t searchvout,bits256 searchtxid2,int32_t searchvout2)
{
struct iguana_info *coin; int32_t selector; cJSON *array;
struct iguana_info *coin; int32_t selector; cJSON *array; char addr[64];
if ( symbol == 0 || symbol[0] == 0 || bits256_nonz(searchtxid) == 0 || bits256_nonz(searchtxid2) == 0 )
return(-1);
if ( (coin= LP_coinfind(symbol)) == 0 || coin->inactive != 0 )
@ -517,9 +518,9 @@ int32_t LP_mempool_vinscan(bits256 *spendtxidp,int32_t *spendvinp,char *symbol,c
coin->lastmempool = (uint32_t)time(NULL);
}
}
if ( (selector= LP_spendsearch(spendtxidp,spendvinp,symbol,searchtxid,searchvout)) >= 0 )
if ( (selector= LP_spendsearch(addr,spendtxidp,spendvinp,symbol,searchtxid,searchvout)) >= 0 )
return(selector);
else if ( (selector= LP_spendsearch(spendtxidp,spendvinp,symbol,searchtxid2,searchvout2)) >= 0 )
else if ( (selector= LP_spendsearch(addr,spendtxidp,spendvinp,symbol,searchtxid2,searchvout2)) >= 0 )
return(selector);
return(-1);
}

16
iguana/exchanges/LP_socket.c

@ -86,7 +86,7 @@ int32_t LP_socket(int32_t bindflag,char *hostname,uint16_t port)
#endif
saddr.sin_family = AF_INET;
saddr.sin_port = htons(port);
//#ifdef WIN32
//#ifdef _WIN32
// saddr.sin_addr.s_addr = (uint32_t)calc_ipbits("127.0.0.1");
//#else
@ -111,7 +111,7 @@ int32_t LP_socket(int32_t bindflag,char *hostname,uint16_t port)
opt = 1;
slen = sizeof(opt);
//printf("set keepalive.%d\n",setsockopt(sock,SOL_SOCKET,SO_KEEPALIVE,(void *)&opt,slen));
#ifndef WIN32
#ifndef _WIN32
if ( 1 )//&& bindflag != 0 )
{
opt = 0;
@ -295,7 +295,7 @@ struct electrum_info *electrum_server(char *symbol,struct electrum_info *ep)
return(ep);
}
int32_t electrum_process_array(struct iguana_info *coin,struct electrum_info *ep,char *coinaddr,cJSON *array)
int32_t electrum_process_array(struct iguana_info *coin,struct electrum_info *ep,char *coinaddr,cJSON *array,int32_t electrumflag)
{
int32_t i,v,n,ht,flag = 0; char str[65]; uint64_t value; bits256 txid; cJSON *item,*retjson,*txobj; struct LP_transaction *tx;
if ( array != 0 && coin != 0 && (n= cJSON_GetArraySize(array)) > 0 )
@ -304,7 +304,7 @@ int32_t electrum_process_array(struct iguana_info *coin,struct electrum_info *ep
for (i=0; i<n; i++)
{
item = jitem(array,i);
if ( coin->electrum == 0 )
if ( electrumflag == 0 )
{
txid = jbits256(item,"txid");
v = jint(item,"vout");
@ -493,11 +493,11 @@ cJSON *electrum_address_getmempool(char *symbol,struct electrum_info *ep,cJSON *
cJSON *retjson; struct iguana_info *coin = LP_coinfind(symbol);
retjson = electrum_strarg(symbol,ep,retjsonp,"blockchain.address.get_mempool",addr,ELECTRUM_TIMEOUT);
//printf("MEMPOOL.(%s)\n",jprint(retjson,0));
electrum_process_array(coin,ep,addr,retjson);
electrum_process_array(coin,ep,addr,retjson,1);
return(retjson);
}
cJSON *electrum_address_listunspent(char *symbol,struct electrum_info *ep,cJSON **retjsonp,char *addr)
cJSON *electrum_address_listunspent(char *symbol,struct electrum_info *ep,cJSON **retjsonp,char *addr,int32_t electrumflag)
{
cJSON *retjson=0; struct iguana_info *coin = LP_coinfind(symbol);
//printf("electrum.%s/%s listunspent last.(%s lag %d)\n",ep->symbol,coin->symbol,coin->lastunspent,(int32_t)(time(NULL) - coin->unspenttime));
@ -506,7 +506,7 @@ cJSON *electrum_address_listunspent(char *symbol,struct electrum_info *ep,cJSON
if ( (retjson= electrum_strarg(symbol,ep,retjsonp,"blockchain.address.listunspent",addr,ELECTRUM_TIMEOUT)) != 0 )
{
//printf("LISTUNSPENT.(%s)\n",jprint(retjson,0));
if ( electrum_process_array(coin,ep,addr,retjson) != 0 )
if ( electrum_process_array(coin,ep,addr,retjson,electrumflag) != 0 )
LP_postutxos(coin->symbol,addr);
safecopy(coin->lastunspent,addr,sizeof(coin->lastunspent));
coin->unspenttime = (uint32_t)time(NULL);
@ -654,7 +654,7 @@ void electrum_test()
printf("electrum_address_getmempool %s\n",jprint(retjson,1));
if ( (retjson= electrum_address_getbalance(symbol,ep,0,addr)) != 0 )
printf("electrum_address_getbalance %s\n",jprint(retjson,1));
if ( (retjson= electrum_address_listunspent(symbol,ep,0,addr)) != 0 )
if ( (retjson= electrum_address_listunspent(symbol,ep,0,addr,1)) != 0 )
printf("electrum_address_listunspent %s\n",jprint(retjson,1));
if ( (retjson= electrum_addpeer(symbol,ep,0,"electrum.be:50001")) != 0 )
printf("electrum_addpeer %s\n",jprint(retjson,1));

58
iguana/exchanges/LP_statemachine.c

@ -1871,6 +1871,64 @@ int32_t LP_peer_utxosquery(struct LP_peerinfo *mypeer,uint16_t myport,int32_t pu
} //else printf("LP_peer_utxosquery skip.(%s) %u\n",peer->ipaddr,peer->lastutxos);
return(n);
}
bestitem = LP_quotejson(qp);
if ( LP_pricevalid(price) > 0 )
{
if ( price <= maxprice )
{
LP_query(ctx,myipaddr,mypubsock,"connect",qp);
//price = LP_pricecache(qp,qp->srccoin,qp->destcoin,qp->txid,qp->vout);
LP_requestinit(&qp->R,qp->srchash,qp->desthash,qp->srccoin,qp->satoshis-2*qp->txfee,qp->destcoin,qp->destsatoshis-2*qp->desttxfee,qp->timestamp,qp->quotetime,DEXselector);
while ( time(NULL) < expiration )
{
if ( aliceutxo->S.swap != 0 )
break;
sleep(3);
}
jaddnum(bestitem,"quotedprice",price);
jaddnum(bestitem,"maxprice",maxprice);
if ( (swap= aliceutxo->S.swap) == 0 )
{
if ( (pubp= LP_pubkeyadd(qp->srchash)) != 0 )
pubp->numerrors++;
jaddstr(bestitem,"status","couldnt establish connection");
}
else
{
jaddstr(bestitem,"status","connected");
jaddnum(bestitem,"requestid",swap->I.req.requestid);
jaddnum(bestitem,"quoteid",swap->I.req.quoteid);
printf("Alice r.%u qp->%u\n",swap->I.req.requestid,swap->I.req.quoteid);
}
}
else
{
jaddnum(bestitem,"quotedprice",price);
jaddnum(bestitem,"maxprice",maxprice);
jaddstr(bestitem,"status","too expensive");
}
}
else
{
printf("invalid price %.8f\n",price);
jaddnum(bestitem,"maxprice",maxprice);
jaddstr(bestitem,"status","no response to request");
}
/*while ( time(NULL) < expiration )
{
if ( (price= LP_pricecache(qp,qp->srccoin,qp->destcoin,qp->txid,qp->vout)) > SMALLVAL )
{
printf("break out of price %.8f %s/%s\n",price,qp->srccoin,qp->destcoin);
break;
}
sleep(1);
}*/
if ( aliceutxo->S.swap == 0 )
LP_availableset(aliceutxo);
return(jprint(bestitem,0));
}
/*if ( time(NULL) > coin->lastmonitor+60 )
{
//portable_mutex_lock(&coin->addrmutex);

93
iguana/exchanges/LP_swap.c

@ -177,6 +177,11 @@ uint32_t basilisk_requestid(struct basilisk_request *rp)
int32_t LP_pubkeys_data(struct basilisk_swap *swap,uint8_t *data,int32_t maxlen)
{
int32_t i,datalen = 0;
data[datalen++] = swap->I.aliceconfirms;
data[datalen++] = swap->I.bobconfirms;
data[datalen++] = swap->I.alicemaxconfirms;
data[datalen++] = swap->I.bobmaxconfirms;
data[datalen++] = swap->I.otheristrusted;
for (i=0; i<33; i++)
data[datalen++] = swap->persistent_pubkey33[i];
for (i=0; i<sizeof(swap->deck)/sizeof(swap->deck[0][0]); i++)
@ -186,9 +191,39 @@ int32_t LP_pubkeys_data(struct basilisk_swap *swap,uint8_t *data,int32_t maxlen)
int32_t LP_pubkeys_verify(struct basilisk_swap *swap,uint8_t *data,int32_t datalen)
{
int32_t i,nonz=0,len = 0; uint8_t other33[33];
if ( datalen == sizeof(swap->otherdeck)+33 )
int32_t i,nonz=0,alicemaxconfirms,bobmaxconfirms,aliceconfirms,bobconfirms,len = 0; uint8_t other33[33];
if ( datalen == sizeof(swap->otherdeck)+38 )
{
aliceconfirms = data[len++];
bobconfirms = data[len++];
alicemaxconfirms = data[len++];
bobmaxconfirms = data[len++];
if ( aliceconfirms != swap->I.aliceconfirms || bobconfirms != swap->I.bobconfirms )
{
printf("MISMATCHED required confirms me.(%d %d) vs (%d %d) max.(%d %d) othermax.(%d %d)\n",swap->I.aliceconfirms,swap->I.bobconfirms,aliceconfirms,bobconfirms,swap->I.alicemaxconfirms,swap->I.bobmaxconfirms,alicemaxconfirms,bobmaxconfirms);
if ( alicemaxconfirms > swap->I.alicemaxconfirms )
alicemaxconfirms = swap->I.alicemaxconfirms;
if ( bobmaxconfirms > swap->I.bobmaxconfirms )
bobmaxconfirms = swap->I.bobmaxconfirms;
if ( swap->I.aliceconfirms < aliceconfirms )
swap->I.aliceconfirms = aliceconfirms;
if ( swap->I.bobconfirms < bobconfirms )
swap->I.bobconfirms = bobconfirms;
if ( swap->I.aliceconfirms > swap->I.alicemaxconfirms || swap->I.bobconfirms > swap->I.bobmaxconfirms )
{
printf("numconfirms (%d %d) exceeds max (%d %d)\n",swap->I.aliceconfirms,swap->I.bobconfirms,swap->I.alicemaxconfirms,swap->I.bobmaxconfirms);
return(-1);
}
}
if ( (swap->I.otherstrust= data[len++]) != 0 )
{
if ( swap->I.otheristrusted != 0 )
{
swap->I.aliceconfirms = swap->I.bobconfirms = 0;
printf("Otherside trusts us, adjust required confirms to: alice.%d bob.%d\n",swap->I.aliceconfirms,swap->I.bobconfirms);
}
}
printf("NUMCONFIRMS for SWAP alice.%d bob.%d, otheristrusted.%d othertrusts.%d\n",swap->I.aliceconfirms,swap->I.bobconfirms,swap->I.otheristrusted,swap->I.otherstrust);
for (i=0; i<33; i++)
if ( (other33[i]= data[len++]) != 0 )
nonz++;
@ -198,7 +233,7 @@ int32_t LP_pubkeys_verify(struct basilisk_swap *swap,uint8_t *data,int32_t datal
len += iguana_rwnum(0,&data[len],sizeof(swap->otherdeck[i>>1][i&1]),&swap->otherdeck[i>>1][i&1]);
return(0);
}
printf("pubkeys verify size mismatch %d != %d\n",datalen,(int32_t)sizeof(swap->otherdeck));
printf("pubkeys verify size mismatch %d != %d\n",datalen,(int32_t)sizeof(swap->otherdeck)+36);
return(-1);
}
@ -419,10 +454,10 @@ int32_t LP_waitfor(int32_t pairsock,struct basilisk_swap *swap,int32_t timeout,i
pfd.events = NN_POLLIN;
if ( nn_poll(&pfd,1,1) > 0 )
{
printf("start wait\n");
//printf("start wait\n");
if ( (datalen= nn_recv(pairsock,&data,NN_MSG,0)) >= 0 )
{
printf("wait for got.%d\n",datalen);
//printf("wait for got.%d\n",datalen);
retval = (*verify)(swap,data,datalen);
nn_freemsg(data);
//printf("retval.%d\n",retval);
@ -746,14 +781,16 @@ void LP_bobloop(void *_swap)
{
if ( strcmp(swap->alicecoin.symbol,"BTC") == 0 )
m = 0;
else m = 1;
else m = swap->I.aliceconfirms;
while ( (n= LP_numconfirms(swap->alicecoin.symbol,swap->alicepayment.I.destaddr,swap->alicepayment.I.signedtxid,0,1)) < m ) // sync with alice
{
char str[65];printf("%d waiting for alicepayment %s to be confirmed.%d %s %s\n",n,swap->alicepayment.I.destaddr,1,swap->alicecoin.symbol,bits256_str(str,swap->alicepayment.I.signedtxid));
char str[65];printf("%d waiting for alicepayment %s to be confirmed.%d %s %s\n",n,swap->alicepayment.I.destaddr,m,swap->alicecoin.symbol,bits256_str(str,swap->alicepayment.I.signedtxid));
sleep(3);
}
if ( LP_swapdata_rawtxsend(swap->N.pair,swap,0x8000,data,maxlen,&swap->bobpayment,0x4000,0) == 0 )
printf("error sending bobpayment\n");
//if ( LP_waitfor(swap->N.pair,swap,10,LP_verify_alicespend) < 0 )
// printf("error waiting for alicespend\n");
swap->sentflag = 1;
swap->bobreclaim.utxovout = 0;
swap->bobreclaim.utxotxid = swap->bobpayment.I.signedtxid;
@ -799,10 +836,10 @@ void LP_aliceloop(void *_swap)
{
if ( strcmp(swap->alicecoin.symbol,"BTC") == 0 )
m = 0;
else m = 1;
else m = swap->I.aliceconfirms;
while ( (n= LP_numconfirms(swap->alicecoin.symbol,swap->alicepayment.I.destaddr,swap->alicepayment.I.signedtxid,0,1)) < m )
{
char str[65];printf("%d waiting for alicepayment %s to be confirmed.%d %s %s\n",n,swap->alicepayment.I.destaddr,1,swap->alicecoin.symbol,bits256_str(str,swap->alicepayment.I.signedtxid));
char str[65];printf("%d waiting for alicepayment %s to be confirmed.%d %s %s\n",n,swap->alicepayment.I.destaddr,m,swap->alicecoin.symbol,bits256_str(str,swap->alicepayment.I.signedtxid));
sleep(10);
}
swap->sentflag = 1;
@ -815,13 +852,13 @@ void LP_aliceloop(void *_swap)
char str[65];printf("%d waiting for bobpayment %s to be confirmed.%d %s %s\n",n,swap->bobpayment.I.destaddr,swap->I.bobconfirms,swap->bobcoin.symbol,bits256_str(str,swap->bobpayment.I.signedtxid));
sleep(LP_SWAPSTEP_TIMEOUT);
}
if ( LP_swapdata_rawtxsend(swap->N.pair,swap,0x20000,data,maxlen,&swap->alicespend,0x40000,0) == 0 )
/*if ( LP_swapdata_rawtxsend(swap->N.pair,swap,0x20000,data,maxlen,&swap->alicespend,0x40000,0) == 0 )
printf("error sending alicespend\n");
while ( (n= LP_numconfirms(swap->alicecoin.symbol,swap->alicespend.I.destaddr,swap->alicespend.I.signedtxid,0,1)) < swap->I.aliceconfirms )
{
char str[65];printf("%d waiting for alicespend %s to be confirmed.%d %s %s\n",n,swap->alicespend.I.destaddr,swap->I.aliceconfirms,swap->bobcoin.symbol,bits256_str(str,swap->alicespend.I.signedtxid));
sleep(LP_SWAPSTEP_TIMEOUT);
}
}*/
if ( swap->N.pair >= 0 )
nn_close(swap->N.pair), swap->N.pair = -1;
LP_swapwait(swap->I.req.requestid,swap->I.req.quoteid,4*3600,30);
@ -955,7 +992,7 @@ void basilisk_rawtx_setparms(char *name,uint32_t quoteid,struct basilisk_rawtx *
struct basilisk_swap *bitcoin_swapinit(bits256 privkey,uint8_t *pubkey33,bits256 pubkey25519,struct basilisk_swap *swap,int32_t optionduration,uint32_t statebits,struct LP_quoteinfo *qp)
{
//FILE *fp; char fname[512];
uint8_t *alicepub33=0,*bobpub33=0; int32_t bobistrusted,aliceistrusted,jumblrflag=-2,x = -1; struct iguana_info *coin;
uint8_t *alicepub33=0,*bobpub33=0; int32_t jumblrflag=-2,x = -1; struct iguana_info *coin;
swap->I.Atxfee = qp->desttxfee;
swap->I.Btxfee = qp->txfee;
swap->I.putduration = swap->I.callduration = INSTANTDEX_LOCKTIME;
@ -983,15 +1020,15 @@ struct basilisk_swap *bitcoin_swapinit(bits256 privkey,uint8_t *pubkey33,bits256
{
swap->I.iambob = 0;
swap->I.otherhash = swap->I.req.desthash;
aliceistrusted = 1;
bobistrusted = LP_pubkey_istrusted(swap->I.req.desthash);
swap->I.aliceistrusted = 1;
swap->I.otheristrusted = swap->I.bobistrusted = LP_pubkey_istrusted(swap->I.req.srchash);
}
else
{
swap->I.iambob = 1;
swap->I.otherhash = swap->I.req.srchash;
bobistrusted = 1;
aliceistrusted = LP_pubkey_istrusted(swap->I.req.desthash);
swap->I.bobistrusted = 1;
swap->I.otheristrusted = swap->I.aliceistrusted = LP_pubkey_istrusted(swap->I.req.desthash);
}
if ( bits256_nonz(privkey) == 0 || (x= instantdex_pubkeyargs(swap,2 + INSTANTDEX_DECKSIZE,privkey,swap->I.orderhash,0x02+swap->I.iambob)) != 2 + INSTANTDEX_DECKSIZE )
{
@ -1017,20 +1054,36 @@ struct basilisk_swap *bitcoin_swapinit(bits256 privkey,uint8_t *pubkey33,bits256
if ( strcmp("BTC",swap->bobcoin.symbol) == 0 )
{
swap->I.bobconfirms = (1 + sqrt(dstr(swap->I.bobsatoshis) * .1));
swap->I.aliceconfirms = MIN(BASILISK_DEFAULT_NUMCONFIRMS,swap->I.bobconfirms);
swap->I.aliceconfirms = BASILISK_DEFAULT_NUMCONFIRMS;
}
else if ( strcmp("BTC",swap->alicecoin.symbol) == 0 )
{
swap->I.aliceconfirms = (1 + sqrt(dstr(swap->I.alicesatoshis) * .1));
swap->I.bobconfirms = MIN(BASILISK_DEFAULT_NUMCONFIRMS,swap->I.aliceconfirms);
swap->I.bobconfirms = BASILISK_DEFAULT_NUMCONFIRMS;
}
else
{
swap->I.bobconfirms = BASILISK_DEFAULT_NUMCONFIRMS;
swap->I.aliceconfirms = BASILISK_DEFAULT_NUMCONFIRMS;
}
swap->I.bobconfirms *= !bobistrusted;
swap->I.aliceconfirms *= !aliceistrusted;
if ( swap->bobcoin.isassetchain != 0 )
swap->I.bobconfirms = 1;
if ( swap->alicecoin.isassetchain != 0 )
swap->I.aliceconfirms = 1;
if ( swap->bobcoin.userconfirms > 0 )
swap->I.bobconfirms = swap->bobcoin.userconfirms;
if ( swap->alicecoin.userconfirms > 0 )
swap->I.aliceconfirms = swap->alicecoin.userconfirms;
if ( (swap->I.bobmaxconfirms= swap->bobcoin.maxconfirms) == 0 )
swap->I.bobmaxconfirms = BASILISK_DEFAULT_MAXCONFIRMS;
if ( (swap->I.alicemaxconfirms= swap->alicecoin.maxconfirms) == 0 )
swap->I.alicemaxconfirms = BASILISK_DEFAULT_MAXCONFIRMS;
if ( swap->I.bobconfirms > swap->I.bobmaxconfirms )
swap->I.bobconfirms = swap->I.bobmaxconfirms;
if ( swap->I.aliceconfirms > swap->I.alicemaxconfirms )
swap->I.aliceconfirms = swap->I.alicemaxconfirms;
swap->I.bobconfirms *= !swap->I.bobistrusted;
swap->I.aliceconfirms *= !swap->I.aliceistrusted;
printf(">>>>>>>>>> jumblrflag.%d <<<<<<<<< use smart address, %.8f bobconfs.%d, %.8f aliceconfs.%d taddr.%d %d\n",jumblrflag,dstr(swap->I.bobsatoshis),swap->I.bobconfirms,dstr(swap->I.alicesatoshis),swap->I.aliceconfirms,swap->bobcoin.taddr,swap->alicecoin.taddr);
if ( swap->I.iambob != 0 )
{

311
iguana/exchanges/LP_transaction.c

@ -444,14 +444,14 @@ int32_t iguana_signrawtransaction(void *ctx,char *symbol,uint8_t wiftaddr,uint8_
extraspace = malloc(extralen);
memset(msgtx,0,sizeof(*msgtx));
decode_hex(serialized,len,rawtx);
// printf("call hex2json.(%s) vins.(%s)\n",rawtx,jprint(vins,0));
if ( (txobj= bitcoin_hex2json(taddr,pubtype,p2shtype,isPoS,height,&txid,msgtx,rawtx,extraspace,extralen,serialized4,vins,V->suppress_pubkeys)) != 0 )
{
//printf("back from bitcoin_hex2json (%s)\n",jprint(vins,0));
} else fprintf(stderr,"no txobj from bitcoin_hex2json\n");
//printf("call hex2json.(%s) vins.(%s)\n",rawtx,jprint(vins,0));
if ( (numinputs= cJSON_GetArraySize(vins)) > 0 )
{
//printf("numinputs.%d msgtx.%d\n",numinputs,msgtx->tx_in);
//printf("numinputs.%d (%s) msgtx.%d\n",numinputs,jprint(vins,0),msgtx->tx_in);
memset(msgtx,0,sizeof(*msgtx));
if ( iguana_rwmsgtx(taddr,pubtype,p2shtype,isPoS,height,0,0,serialized,maxsize,msgtx,&txid,"",extraspace,extralen,vins,V->suppress_pubkeys) > 0 && numinputs == msgtx->tx_in )
{
@ -724,9 +724,285 @@ char *basilisk_swap_bobtxspend(bits256 *signedtxidp,uint64_t txfee,char *name,ch
return(signedtx);
}
int32_t LP_vin_select(int32_t *aboveip,int64_t *abovep,int32_t *belowip,int64_t *belowp,struct LP_address_utxo **utxos,int32_t numunspents,uint64_t value,int32_t maxmode)
{
int32_t i,abovei,belowi; int64_t above,below,gap,atx_value;
abovei = belowi = -1;
for (above=below=i=0; i<numunspents; i++)
{
if ( utxos[i] == 0 )
continue;
if ( (atx_value= utxos[i]->U.value) <= 0 )
{
//printf("illegal value.%d\n",i);
continue;
}
if ( atx_value == value )
{
*aboveip = *belowip = i;
*abovep = *belowp = 0;
return(i);
}
else if ( atx_value > value )
{
gap = (atx_value - value);
if ( above == 0 || gap < above )
{
above = gap;
abovei = i;
}
} else gap = (value - atx_value);
if ( below == 0 || gap < below )
{
below = gap;
belowi = i;
}
}
*aboveip = abovei;
*abovep = above;
*belowip = belowi;
*belowp = below;
//printf("above.%d below.%d\n",abovei,belowi);
return(abovei >= 0 && above < (below>>1) ? abovei : belowi);
}
cJSON *LP_inputjson(bits256 txid,int32_t vout,char *spendscriptstr)
{
cJSON *sobj,*item = cJSON_CreateObject();
jaddbits256(item,"txid",txid);
jaddnum(item,"vout",vout);
sobj = cJSON_CreateObject();
jaddstr(sobj,"hex",spendscriptstr);
jadd(item,"scriptPubKey",sobj);
//printf("vin.%s\n",jprint(item,0));
return(item);
}
int32_t LP_vins_select(void *ctx,struct iguana_info *coin,int64_t *totalp,int64_t amount,struct vin_info *V,struct LP_address_utxo **utxos,int32_t numunspents,int32_t suppress_pubkeys,int32_t ignore_cltverr,bits256 privkey,cJSON *privkeys,cJSON *vins,uint8_t *script,int32_t scriptlen)
{
char wifstr[128],spendscriptstr[128]; int32_t i,n,ind,abovei,belowi,maxmode=0; struct vin_info *vp; struct LP_address_utxo *up; int64_t above,below,remains = amount,total = 0;
*totalp = 0;
init_hexbytes_noT(spendscriptstr,script,scriptlen);
bitcoin_priv2wif(coin->wiftaddr,wifstr,privkey,coin->wiftype);
for (i=n=0; i<numunspents; i++)
{
//printf("vinselect.%d of %d: remain %.8f amount %.8f\n",i,numunspents,dstr(remains),dstr(amount));
below = above = 0;
abovei = belowi = -1;
if ( LP_vin_select(&abovei,&above,&belowi,&below,utxos,numunspents,remains,maxmode) < 0 )
{
printf("error finding unspent i.%d of %d, %.8f vs %.8f\n",i,numunspents,dstr(remains),dstr(amount));
return(0);
}
if ( belowi < 0 || abovei >= 0 )
ind = abovei;
else ind = belowi;
if ( ind < 0 )
{
printf("error finding unspent i.%d of %d, %.8f vs %.8f, abovei.%d belowi.%d ind.%d\n",i,numunspents,dstr(remains),dstr(amount),abovei,belowi,ind);
return(0);
}
up = utxos[ind];
utxos[ind] = utxos[--numunspents];
utxos[numunspents] = 0;
total += up->U.value;
remains -= up->U.value;
vp = &V[n++];
vp->N = vp->M = 1;
vp->signers[0].privkey = privkey;
jaddistr(privkeys,wifstr);
bitcoin_pubkey33(ctx,vp->signers[0].pubkey,privkey);
vp->suppress_pubkeys = suppress_pubkeys;
vp->ignore_cltverr = ignore_cltverr;
jaddi(vins,LP_inputjson(up->U.txid,up->U.vout,spendscriptstr));
//printf("wif.%s i.%d privkeys.%s vins.%s %p %p\n",wifstr,i,jprint(privkeys,0),jprint(vins,0),privkeys,vins);
//printf("%s value %.8f -> remains %.8f\n",coinaddr,dstr(value),dstr(remains));
if ( remains <= 0 )
break;
if ( numunspents == 0 )
{
printf("total %.8f not enough for amount %.8f\n",dstr(total),dstr(amount));
return(0);
}
}
*totalp = total;
return(n);
}
char *LP_createrawtransaction(cJSON **txobjp,int32_t *numvinsp,struct iguana_info *coin,struct vin_info *V,int32_t max,bits256 privkey,cJSON *outputs,cJSON *vins,cJSON *privkeys,int64_t txfee)
{
static void *ctx;
cJSON *txobj,*item; uint8_t addrtype,rmd160[20],script[64],spendscript[64]; char *coinaddr,*rawtxbytes; bits256 txid; uint32_t timestamp,locktime; int64_t change=0,adjust=0,total,value,amount = 0; int32_t i,scriptlen,spendlen,suppress_pubkeys,ignore_cltverr,numvouts=0,numvins=0,numutxos=0; struct LP_address_utxo *utxos[256]; struct LP_address *ap;
if ( ctx == 0 )
ctx = bitcoin_ctx();
*numvinsp = 0;
*txobjp = 0;
if ( sizeof(utxos)/sizeof(*utxos) != max )
{
printf("LP_createrawtransaction: internal error %ld != max.%d\n",sizeof(utxos)/sizeof(*utxos),max);
return(0);
}
if ( coin == 0 || outputs == 0 || (numvouts= cJSON_GetArraySize(outputs)) <= 0 )
{
printf("LP_createrawtransaction: illegal coin.%p outputs.%p or arraysize.%d, error\n",coin,outputs,numvouts);
return(0);
}
amount = txfee;
for (i=0; i<numvouts; i++)
{
item = jitem(outputs,i);
if ( (coinaddr= jfieldname(item)) != 0 )
{
if ( LP_address_isvalid(coin->symbol,coinaddr) <= 0 )
{
printf("LP_createrawtransaction %s i.%d of %d is invalid\n",coinaddr,i,numvouts);
return(0);
}
if ( (value= SATOSHIDEN * jdouble(item,coinaddr)) <= 0 )
{
printf("cant get value %s i.%d of %d %s\n",coinaddr,i,numvouts,jprint(outputs,0));
return(0);
}
amount += value;
}
else
{
printf("cant get fieldname.%d of %d %s\n",i,numvouts,jprint(outputs,0));
return(0);
}
}
LP_listunspent_issue(coin->symbol,coin->smartaddr,1);
if ( (ap= LP_addressfind(coin,coin->smartaddr)) == 0 )
{
printf("LP_createrawtransaction: cant find address data\n");
return(0);
}
memset(utxos,0,sizeof(utxos));
if ( (numutxos= LP_address_utxo_ptrs(0,utxos,max,ap)) <= 0 )
{
printf("LP_createrawtransaction: address_utxo_ptrs %d, error\n",numutxos);
return(0);
}
ignore_cltverr = 0;
suppress_pubkeys = 1;
scriptlen = bitcoin_standardspend(script,0,G.LP_myrmd160);
numvins = LP_vins_select(ctx,coin,&total,amount,V,utxos,numutxos,suppress_pubkeys,ignore_cltverr,privkey,privkeys,vins,script,scriptlen);
change = (total - amount);
timestamp = (uint32_t)time(NULL);
if ( strcmp("KMD",coin->symbol) == 0 )
locktime = timestamp - 777;
else locktime = 0;
txobj = bitcoin_txcreate(coin->symbol,coin->isPoS,locktime,1,timestamp);
jdelete(txobj,"vin");
jadd(txobj,"vin",jduplicate(vins));
if ( change < 6000 )
{
adjust = change / numvouts;
change = 0;
}
for (i=0; i<numvouts; i++)
{
item = jitem(outputs,i);
if ( (coinaddr= jfieldname(item)) != 0 )
{
if ( (value= SATOSHIDEN * jdouble(item,coinaddr)) <= 0 )
{
printf("cant get value i.%d of %d %s\n",i,numvouts,jprint(outputs,0));
return(0);
}
bitcoin_addr2rmd160(coin->taddr,&addrtype,rmd160,coinaddr);
spendlen = bitcoin_standardspend(spendscript,0,rmd160);
txobj = bitcoin_txoutput(txobj,spendscript,spendlen,value + adjust);
}
else
{
printf("cant get fieldname.%d of %d %s\n",i,numvouts,jprint(outputs,0));
return(0);
}
}
if ( change != 0 )
txobj = bitcoin_txoutput(txobj,script,scriptlen,change);
if ( (rawtxbytes= bitcoin_json2hex(coin->isPoS,&txid,txobj,V)) != 0 )
{
} else printf("error making rawtx suppress.%d\n",suppress_pubkeys);
*txobjp = txobj;
return(rawtxbytes);
}
char *LP_withdraw(struct iguana_info *coin,cJSON *argjson)
{
static void *ctx;
int32_t iter,completed=0,maxV,numvins,numvouts,datalen,suppress_pubkeys; bits256 privkey; char changeaddr[64],vinaddr[64],str[65],*signedtx=0,*rawtx=0; struct vin_info *V; cJSON *retjson,*outputs,*vins=0,*txobj=0,*privkeys=0; struct iguana_msgtx msgtx; bits256 signedtxid; uint64_t txfee,newtxfee=10000;
if ( (outputs= jarray(&numvouts,argjson,"outputs")) == 0 )
{
printf("no outputs in argjson (%s)\n",jprint(argjson,0));
return(clonestr("{\"error\":\"no outputs specified\"}"));
}
txfee = coin->txfee;
if ( ctx == 0 )
ctx = bitcoin_ctx();
if ( txfee > 0 && txfee < 10000 )
txfee = 10000;
suppress_pubkeys = 0;
memset(signedtxid.bytes,0,sizeof(signedtxid));
safecopy(changeaddr,coin->smartaddr,sizeof(changeaddr));
safecopy(vinaddr,coin->smartaddr,sizeof(vinaddr));
privkey = LP_privkey(vinaddr,coin->taddr);
maxV = 256;
V = malloc(maxV * sizeof(*V));
for (iter=0; iter<2; iter++)
{
privkeys = cJSON_CreateArray();
vins = cJSON_CreateArray();
memset(V,0,sizeof(*V) * maxV);
if ( (rawtx= LP_createrawtransaction(&txobj,&numvins,coin,V,maxV,privkey,outputs,vins,privkeys,iter == 0 ? txfee : newtxfee)) != 0 )
{
completed = 0;
memset(&msgtx,0,sizeof(msgtx));
memset(signedtxid.bytes,0,sizeof(signedtxid));
if ( (completed= iguana_signrawtransaction(ctx,coin->symbol,coin->wiftaddr,coin->taddr,coin->pubtype,coin->p2shtype,coin->isPoS,coin->longestchain,&msgtx,&signedtx,&signedtxid,V,numvins,rawtx,vins,privkeys)) < 0 )
printf("couldnt sign withdraw %s\n",bits256_str(str,signedtxid));
else if ( completed == 0 )
{
printf("incomplete signing withdraw (%s)\n",jprint(vins,0));
if ( signedtx != 0 )
free(signedtx), signedtx = 0;
} else printf("LP_withdraw %s -> %s\n",jprint(argjson,0),bits256_str(str,signedtxid));
if ( signedtx == 0 )
break;
datalen = (int32_t)strlen(signedtx) / 2;
if ( strcmp(coin->symbol,"BTC") == 0 )
{
newtxfee = LP_txfeecalc(coin,0,datalen);
printf("txfee %.8f -> newtxfee %.8f\n",dstr(txfee),dstr(newtxfee));
} else break;
} else break;
free_json(vins), vins = 0;
free_json(txobj), txobj = 0;
free_json(privkeys), privkeys = 0;
if ( rawtx != 0 )
free(rawtx), rawtx = 0;
}
free(V);
if ( vins != 0 )
free_json(vins);
if ( privkeys != 0 )
free_json(privkeys);
retjson = cJSON_CreateObject();
if ( rawtx != 0 )
jaddstr(retjson,"rawtx",rawtx);
if ( signedtx != 0 )
jaddstr(retjson,"hex",signedtx);
if ( txobj != 0 )
jadd(retjson,"tx",txobj);
jaddbits256(retjson,"txid",signedtxid);
jadd(retjson,"complete",completed!=0?jtrue():jfalse());
return(jprint(retjson,1));
}
int32_t basilisk_rawtx_gen(void *ctx,char *str,uint32_t swapstarted,uint8_t *pubkey33,int32_t iambob,int32_t lockinputs,struct basilisk_rawtx *rawtx,uint32_t locktime,uint8_t *script,int32_t scriptlen,int64_t txfee,int32_t minconf,int32_t delay,bits256 privkey,uint8_t *changermd160,char *vinaddr)
{
int32_t retval=-1,len,iter; char *signedtx,*changeaddr = 0,_changeaddr[64]; struct iguana_info *coin; int64_t newtxfee=0,destamount;
int32_t retval=-1,iter; char *signedtx,*changeaddr = 0,_changeaddr[64]; struct iguana_info *coin; int64_t newtxfee=0,destamount;
char str2[65]; printf("%s rawtxgen.(%s/v%d)\n",rawtx->name,bits256_str(str2,rawtx->utxotxid),rawtx->utxovout);
if ( (coin= rawtx->coin) == 0 )
return(-1);
@ -753,8 +1029,7 @@ int32_t basilisk_rawtx_gen(void *ctx,char *str,uint32_t swapstarted,uint8_t *pub
free(signedtx);
if ( strcmp(coin->symbol,"BTC") != 0 )
return(retval);
len = rawtx->I.datalen;
newtxfee = LP_txfeecalc(coin,0);
newtxfee = LP_txfeecalc(coin,0,rawtx->I.datalen);
printf("txfee %.8f -> newtxfee %.8f\n",dstr(txfee),dstr(newtxfee));
} else break;
if ( strcmp(str,"myfee") == 0 )
@ -940,9 +1215,9 @@ bits256 LP_swap_spendtxid(char *symbol,char *destaddr,bits256 utxotxid,int32_t v
destaddr[0] = 0;
coinaddr[0] = 0;
memset(&spendtxid,0,sizeof(spendtxid));
if ( LP_spendsearch(&spendtxid,&spendvin,symbol,utxotxid,vout) > 0 )
if ( LP_spendsearch(destaddr,&spendtxid,&spendvin,symbol,utxotxid,vout) > 0 )
printf("spend of %s/v%d detected\n",bits256_str(str,utxotxid),vout);
else if ( (coin= LP_coinfind(symbol)) != 0 && coin->electrum == 0 )
else if ( 0 && (coin= LP_coinfind(symbol)) != 0 && coin->electrum == 0 )
{
if ( (retjson= LP_gettxout(symbol,coinaddr,utxotxid,vout)) == 0 )
{
@ -1077,16 +1352,16 @@ int32_t basilisk_swapuserdata(uint8_t *userdata,bits256 privkey,int32_t ifpath,b
int32_t basilisk_bobpayment_reclaim(struct basilisk_swap *swap,int32_t delay)
{
uint8_t userdata[512]; int32_t retval,len = 0; static bits256 zero;
uint8_t userdata[512]; int32_t retval,i,len = 0; static bits256 zero;
//printf("basilisk_bobpayment_reclaim\n");
len = basilisk_swapuserdata(userdata,zero,1,swap->I.myprivs[1],swap->bobpayment.redeemscript,swap->bobpayment.I.redeemlen);
memcpy(swap->I.userdata_bobreclaim,userdata,len);
swap->I.userdata_bobreclaimlen = len;
if ( (retval= basilisk_rawtx_sign(swap->bobcoin.symbol,swap->bobcoin.wiftaddr,swap->bobcoin.taddr,swap->bobcoin.pubtype,swap->bobcoin.p2shtype,swap->bobcoin.isPoS,swap->bobcoin.wiftype,swap,&swap->bobreclaim,&swap->bobpayment,swap->I.myprivs[1],0,userdata,len,1,swap->changermd160,swap->bobpayment.I.destaddr)) == 0 )
{
//for (i=0; i<swap->bobreclaim.I.datalen; i++)
// printf("%02x",swap->bobreclaim.txbytes[i]);
//printf(" <- bobreclaim\n");
for (i=0; i<swap->bobreclaim.I.datalen; i++)
printf("%02x",swap->bobreclaim.txbytes[i]);
printf(" <- bobreclaim\n");
//basilisk_txlog(swap,&swap->bobreclaim,delay);
return(retval);
}
@ -1329,6 +1604,20 @@ int32_t LP_verify_otherfee(struct basilisk_swap *swap,uint8_t *data,int32_t data
return(-1);
}
int32_t LP_verify_alicespend(struct basilisk_swap *swap,uint8_t *data,int32_t datalen)
{
if ( LP_rawtx_spendscript(swap,swap->bobcoin.longestchain,&swap->alicespend,0,data,datalen,0) == 0 )
{
printf("alicespend amount %.8f -> %s vs %s\n",dstr(swap->alicespend.I.amount),swap->alicespend.p2shaddr,swap->alicespend.I.destaddr);
if ( strcmp(swap->alicespend.I.destaddr,swap->alicespend.p2shaddr) == 0 )
{
printf("alicespend verified\n");
return(0);
}
}
return(-1);
}
/* Bob deposit:
OP_IF
<now + INSTANTDEX_LOCKTIME*2> OP_CLTV OP_DROP <alice_pubA0> OP_CHECKSIG

32
iguana/exchanges/LP_utxo.c

@ -324,16 +324,21 @@ int32_t LP_merkleproof(struct iguana_info *coin,struct electrum_info *ep,bits256
roothash = validate_merkle(jint(merkobj,"pos"),txid,merkles,m);
if ( (hdrobj= electrum_getheader(coin->symbol,ep,&hdrobj,height)) != 0 )
{
merkleroot = jbits256(hdrobj,"merkle_root");
if ( bits256_cmp(merkleroot,roothash) == 0 )
if ( jobj(hdrobj,"merkle_root") != 0 )
{
SPV = height;
//printf("validated MERK %s ht.%d -> %s root.(%s)\n",bits256_str(str,up->U.txid),up->U.height,jprint(merkobj,0),bits256_str(str2,roothash));
}
else printf("ERROR MERK %s ht.%d -> %s root.(%s) vs %s\n",bits256_str(str,txid),height,jprint(merkobj,0),bits256_str(str2,roothash),bits256_str(str3,merkleroot));
merkleroot = jbits256(hdrobj,"merkle_root");
if ( bits256_cmp(merkleroot,roothash) == 0 )
{
SPV = height;
//printf("validated MERK %s ht.%d -> %s root.(%s)\n",bits256_str(str,up->U.txid),up->U.height,jprint(merkobj,0),bits256_str(str2,roothash));
}
else printf("ERROR MERK %s ht.%d -> %s root.(%s) vs %s (%s)\n",bits256_str(str,txid),height,jprint(merkobj,0),bits256_str(str2,roothash),bits256_str(str3,merkleroot),jprint(hdrobj,0));
} else SPV = 0;
free_json(hdrobj);
}
} else printf("couldnt get header for ht.%d\n",height);
}
if ( SPV < 0 )
printf("MERKLE DIDNT VERIFY.(%s)\n",jprint(merkobj,0));
free_json(merkobj);
}
return(SPV);
@ -366,7 +371,7 @@ cJSON *LP_address_utxos(struct iguana_info *coin,char *coinaddr,int32_t electrum
}
if ( up->spendheight <= 0 )
{
if ( backupep != 0 && up->SPV == 0 )
if ( backupep != 0 && up->SPV <= 0 )
up->SPV = LP_merkleproof(coin,backupep,up->U.txid,up->U.height);
jaddi(array,LP_address_item(coin,up,electrumret));
n++;
@ -417,7 +422,7 @@ cJSON *LP_address_balance(struct iguana_info *coin,char *coinaddr,int32_t electr
void LP_postutxos(char *symbol,char *coinaddr)
{
bits256 zero; char *msg; struct iguana_info *coin; cJSON *array,*reqjson = cJSON_CreateObject();
bits256 zero; struct iguana_info *coin; cJSON *array,*reqjson = cJSON_CreateObject();
if ( (coin= LP_coinfind(symbol)) != 0 && (array= LP_address_utxos(coin,coinaddr,1)) != 0 )
{
//printf("LP_postutxos pubsock.%d %s %s\n",pubsock,symbol,coin->smartaddr);
@ -430,9 +435,8 @@ void LP_postutxos(char *symbol,char *coinaddr)
jaddstr(reqjson,"coin",symbol);
jaddstr(reqjson,"coinaddr",coinaddr);
jadd(reqjson,"utxos",array);
msg = jprint(reqjson,1);
//printf("post (%s) -> %d\n",msg,LP_mypubsock);
LP_broadcast_message(LP_mypubsock,symbol,symbol,zero,msg);
LP_reserved_msg(symbol,symbol,zero,jprint(reqjson,1));
}
}
}
@ -489,7 +493,7 @@ char *LP_postedutxos(cJSON *argjson)
if ( (array= jarray(&n,argjson,"utxos")) != 0 )
LP_unspents_array(coin,coinaddr,array);
}
else if ( (array= electrum_address_listunspent(symbol,coin->electrum,&array,coinaddr)) != 0 )
else if ( (array= electrum_address_listunspent(symbol,coin->electrum,&array,coinaddr,1)) != 0 )
free_json(array);
}
return(clonestr("{\"result\":\"success\"}"));
@ -722,7 +726,7 @@ int32_t LP_numconfirms(char *symbol,char *coinaddr,bits256 txid,int32_t vout,int
}
else
{
LP_listunspent_issue(symbol,coinaddr);
LP_listunspent_issue(symbol,coinaddr,1);
if ( (ht= LP_txheight(coin,txid)) > 0 && ht <= coin->height )
numconfirms = (LP_getheight(coin) - ht + 1);
else if ( mempool != 0 )
@ -824,7 +828,7 @@ int32_t LP_iseligible(uint64_t *valp,uint64_t *val2p,int32_t iambob,char *symbol
return(-2);
if ( (up= LP_address_utxofind(coin,destaddr,txid2,vout2)) != 0 && up->spendheight > 0 )
return(-3);
txfee = LP_txfeecalc(LP_coinfind(symbol),0);
txfee = LP_txfeecalc(LP_coinfind(symbol),0,0);
if ( val >= satoshis && val > (1+LP_MINSIZE_TXFEEMULT)*txfee )
{
threshold = (iambob != 0) ? LP_DEPOSITSATOSHIS(satoshis) : (LP_DEXFEE(satoshis) + txfee);

12
iguana/exchanges/LP_utxos.c

@ -309,10 +309,10 @@ struct LP_utxoinfo *LP_utxoadd(int32_t iambob,char *symbol,bits256 txid,int32_t
}*/
if ( (coin= LP_coinfind(symbol)) == 0 || (IAMLP == 0 && coin->inactive != 0) )
{
printf("LP_utxoadd reject inactive %s\n",symbol);
//printf("LP_utxoadd reject inactive %s\n",symbol);
return(0);
}
txfee = LP_txfeecalc(coin,0);
txfee = LP_txfeecalc(coin,0,0);
if ( iambob != 0 && value2 < 9 * (value >> 3) + 2*txfee ) // big txfee padding
{
if ( value2 > 2*txfee )
@ -452,7 +452,7 @@ cJSON *LP_inventory(char *symbol)
if ( (coin= LP_coinfind(symbol)) != 0 )
{
coin->unspenttime = (uint32_t)time(NULL) - 777;
LP_listunspent_both(symbol,coin->smartaddr);
LP_listunspent_both(symbol,coin->smartaddr,0);
}
HASH_ITER(hh,G.LP_utxoinfos[iambob],utxo,tmp)
{
@ -519,10 +519,10 @@ int32_t LP_privkey_init(int32_t mypubsock,struct iguana_info *coin,bits256 mypri
}
//printf("privkey init.(%s) %s\n",coin->symbol,coin->smartaddr);
if ( coin->inactive == 0 )
LP_listunspent_issue(coin->symbol,coin->smartaddr);
LP_listunspent_issue(coin->symbol,coin->smartaddr,0);
if ( coin->inactive == 0 && (array= LP_listunspent(coin->symbol,coin->smartaddr)) != 0 )
{
txfee = LP_txfeecalc(coin,0);
txfee = LP_txfeecalc(coin,0,0);
if ( is_cJSON_Array(array) != 0 && (n= cJSON_GetArraySize(array)) > 0 )
{
//printf("LP_privkey_init %s %s\n",coin->symbol,jprint(array,0));
@ -746,7 +746,7 @@ bits256 LP_privkeycalc(void *ctx,uint8_t *pubkey33,bits256 *pubkeyp,struct iguan
}
if ( coin->electrum == 0 && coin->userpass[0] != 0 )
{
LP_listunspent_issue(coin->symbol,coin->smartaddr);
LP_listunspent_issue(coin->symbol,coin->smartaddr,0);
if ( (retjson= LP_importprivkey(coin->symbol,tmpstr,coin->smartaddr,-1)) != 0 )
{
if ( jobj(retjson,"error") != 0 )

2
iguana/exchanges/coins

File diff suppressed because one or more lines are too long

2
iguana/exchanges/install

@ -1,5 +1,5 @@
#!/bin/bash
cp balance listunspent electrum snapshot_balance snapshot_loop secretaddresses dividends snapshot goals goal portfolio autoprice deletemessages getmessages debug register registerall buy sell bestfit orderbook client run_osx client_osx run coins disable enable myprice myprices getcoins getpeers getpeersIP getprices getutxos help inv setprice status utxos ../dexscripts
cp trust trusted setconfirms balance listunspent electrum snapshot_balance snapshot_loop secretaddresses dividends snapshot goals goal portfolio autoprice deletemessages getmessages debug buy sell bestfit orderbook client run_osx client_osx run coins disable enable myprice myprices getcoins getpeers getpeersIP getprices help inv setprice status ../dexscripts
cp coins.json ..
cd ../dexscripts
#cp ../exchanges/passphrase ../exchanges/userpass .

1
iguana/exchanges/listunspent

@ -1,2 +1,3 @@
#!/bin/bash
source userpass
curl --url "http://127.0.0.1:7783" --data "{\"userpass\":\"$userpass\",\"method\":\"listunspent\",\"coin\":\"CHIPS\",\"address\":\"RMfQwu5ey23eWJ4as2ckd8dqsQJwo836ny\"}"

3
iguana/exchanges/register

@ -1,3 +0,0 @@
#!/bin/bash
source userpass
curl --url "http://5.9.253.195:7783" --data "{\"userpass\":\"9bb4846d24136fc7c33515e45bccbab5c8fb7b57b411aa20057b371da9358255\",\"agent\":\"stats\",\"method\":\"register\",\"client\":\"6d3332be4904feafd326609bd76b66528dc7b2e2d75a7bd110c6bf8d19c4cf58\",\"pushaddr\":\"5.9.253.195\",\"pushport\":\"10000\"}"

3
iguana/exchanges/sendrawtransaction

@ -0,0 +1,3 @@
#!/bin/bash
source userpass
curl --url "http://127.0.0.1:7783" --data "{\"userpass\":\"$userpass\",\"method\":\"sendrawtransaction\",\"coin\":\"KMD\",\"signedtx\":\"$1\"}"

3
iguana/exchanges/registerall → iguana/exchanges/setconfirms

@ -1,4 +1,3 @@
#!/bin/bash
source userpass
curl --url "http://127.0.0.1:7783" --data "{\"userpass\":\"$userpass\",\"method\":\"registerall\",\"numnodes\":10}"
curl --url "http://127.0.0.1:7783" --data "{\"userpass\":\"$userpass\",\"method\":\"setconfirms\",\"coin\":\"REVS\",\"numconfirms\":1}"

6
iguana/exchanges/stats.c

@ -30,7 +30,7 @@
#include "DEXstats.h"
char *stats_JSON(void *ctx,char *myipaddr,int32_t mypubsock,cJSON *argjson,char *remoteaddr,uint16_t port);
#ifndef WIN32
#ifndef _WIN32
#ifndef MSG_NOSIGNAL
#define MSG_NOSIGNAL 0x4000 // Do not generate SIGPIPE
#endif
@ -118,7 +118,7 @@ int32_t iguana_socket(int32_t bindflag,char *hostname,uint16_t port)
#endif
saddr.sin_family = AF_INET;
saddr.sin_port = htons(port);
//#ifdef WIN32
//#ifdef _WIN32
// saddr.sin_addr.s_addr = (uint32_t)calc_ipbits("127.0.0.1");
//#else
@ -143,7 +143,7 @@ int32_t iguana_socket(int32_t bindflag,char *hostname,uint16_t port)
opt = 1;
slen = sizeof(opt);
//printf("set keepalive.%d\n",setsockopt(sock,SOL_SOCKET,SO_KEEPALIVE,(void *)&opt,slen));
#ifndef WIN32
#ifndef _WIN32
if ( 1 )//&& bindflag != 0 )
{
opt = 0;

4
iguana/exchanges/trust

@ -0,0 +1,4 @@
#!/bin/bash
echo "usage: ./trust <pubkey>"
source userpass
curl --url "http://127.0.0.1:7783" --data "{\"userpass\":\"$userpass\",\"pubkey\":\"$1\",\"method\":\"trust\",\"trust\":1}"

2
iguana/exchanges/utxos → iguana/exchanges/trusted

@ -1,3 +1,3 @@
#!/bin/bash
source userpass
curl --url "http://127.0.0.1:7783" --data "{\"userpass\":\"$userpass\",\"method\":\"getutxos\",\"coin\":\"REVS\"}"
curl --url "http://127.0.0.1:7783" --data "{\"userpass\":\"$userpass\",\"method\":\"trusted\"}"

3
iguana/exchanges/withdraw

@ -0,0 +1,3 @@
#!/bin/bash
source userpass
curl --url "http://127.0.0.1:7783" --data "{\"userpass\":\"$userpass\",\"method\":\"withdraw\",\"coin\":\"KMD\",\"outputs\":[{\"RUgW6fLfVsLJ87Ng4zJTqNedJSKYQ9ToAf\":0.001}, {\"RUgW6fLfVsLJ87Ng4zJTqNedJSKYQ9ToAf\":0.002}]}"
Loading…
Cancel
Save