diff --git a/iguana/coins/mshark_7776 b/iguana/coins/mshark_7776 old mode 100644 new mode 100755 diff --git a/iguana/exchanges/LP_RTmetrics.c b/iguana/exchanges/LP_RTmetrics.c index 7bbab1c38..3d37c8a2e 100644 --- a/iguana/exchanges/LP_RTmetrics.c +++ b/iguana/exchanges/LP_RTmetrics.c @@ -132,7 +132,7 @@ void LP_RTmetrics_swapsinfo(char *refbase,char *refrel,cJSON *swaps,int32_t nums quoteid = juint(item,"quoteid"); LP_RTmetrics_pendingswap(srcpub,LP_kmdvalue(base,basesatoshis)); LP_RTmetrics_pendingswap(destpub,LP_kmdvalue(rel,relsatoshis)); - if ( 0 && (retstr= basilisk_swapentry(requestid,quoteid)) != 0 ) // no need for this + if ( 0 && (retstr= basilisk_swapentry(requestid,quoteid,0)) != 0 ) // no need for this { if ( (swapjson= cJSON_Parse(retstr)) != 0 ) { diff --git a/iguana/exchanges/LP_bitcoin.c b/iguana/exchanges/LP_bitcoin.c index f9c212cd1..e4fb09e5d 100644 --- a/iguana/exchanges/LP_bitcoin.c +++ b/iguana/exchanges/LP_bitcoin.c @@ -2008,6 +2008,8 @@ int32_t bitcoin_p2shscript(uint8_t *script,int32_t n,const uint8_t *p2shscript,c char *bitcoind_passthru(char *coinstr,char *serverport,char *userpass,char *method,char *params) { + if ( userpass[0] == 0 ) + return(clonestr("{\"error\":\"no rpcusername rpcpassword in coin.conf\"}")); return(bitcoind_RPC(0,coinstr,serverport,userpass,method,params,4)); } diff --git a/iguana/exchanges/LP_cache.c b/iguana/exchanges/LP_cache.c index c27fb2ecd..194ab75c0 100644 --- a/iguana/exchanges/LP_cache.c +++ b/iguana/exchanges/LP_cache.c @@ -229,17 +229,24 @@ bits256 LP_merkleroot(struct iguana_info *coin,struct electrum_info *ep,int32_t int32_t LP_merkleproof(struct iguana_info *coin,char *coinaddr,struct electrum_info *ep,bits256 txid,int32_t height) { - struct LP_transaction *tx=0; cJSON *merkobj,*merkles,*retjson; bits256 roothash,merkleroot; int32_t m,SPV = 0; + struct LP_transaction *tx=0; cJSON *merkobj,*merkles,*retjson; bits256 roothash,merkleroot; int32_t m,ht=0,SPV = 0; if ( height <= 0 ) return(0); if ( (tx= LP_transactionfind(coin,txid)) == 0 && strcmp(coinaddr,coin->smartaddr) == 0 ) { - if ( (retjson= electrum_transaction(coin->symbol,ep,&retjson,txid,0)) != 0 ) + if ( (retjson= electrum_transaction(&ht,coin->symbol,ep,&retjson,txid,0)) != 0 ) free_json(retjson); } if ( tx != 0 ) { - tx->height = height; + if ( tx->height == 0 ) + { + if ( height != 0 ) + tx->height = height; + else if ( ht != 0 ) + tx->height = ht; + height = tx->height; + } if ( tx->SPV > 0 ) return(tx->SPV); } diff --git a/iguana/exchanges/LP_coins.c b/iguana/exchanges/LP_coins.c index 0bf61e969..67312eb51 100644 --- a/iguana/exchanges/LP_coins.c +++ b/iguana/exchanges/LP_coins.c @@ -214,7 +214,7 @@ uint16_t LP_userpass(char *userpass,char *symbol,char *assetname,char *confroot, cJSON *LP_coinjson(struct iguana_info *coin,int32_t showwif) { - struct electrum_info *ep; uint64_t balance; char wifstr[128],ipaddr[64]; uint8_t tmptype; bits256 checkkey; cJSON *item = cJSON_CreateObject(); + struct electrum_info *ep; int32_t notarized; uint64_t balance; char wifstr[128],ipaddr[64]; uint8_t tmptype; bits256 checkkey; cJSON *item = cJSON_CreateObject(); jaddstr(item,"coin",coin->symbol); if ( showwif != 0 ) { @@ -227,7 +227,9 @@ cJSON *LP_coinjson(struct iguana_info *coin,int32_t showwif) jadd(item,"installed",coin->userpass[0] == 0 ? jfalse() : jtrue()); if ( coin->userpass[0] != 0 ) { - jaddnum(item,"height",LP_getheight(coin)); + jaddnum(item,"height",LP_getheight(¬arized,coin)); + if ( notarized > 0 ) + jaddnum(item,"notarized",notarized); if ( coin->electrum != 0 ) balance = LP_unspents_load(coin->symbol,coin->smartaddr); else balance = LP_RTsmartbalance(coin); diff --git a/iguana/exchanges/LP_commands.c b/iguana/exchanges/LP_commands.c index b06a66e5d..af24bf929 100644 --- a/iguana/exchanges/LP_commands.c +++ b/iguana/exchanges/LP_commands.c @@ -124,6 +124,7 @@ swapstatus(coin, limit=10)\n\ swapstatus(base, rel, limit=10)\n\ swapstatus(requestid, quoteid)\n\ recentswaps(limit=3)\n\ +notarizations(coin)\n\ public API:\n \ getcoins()\n\ getcoin(coin)\n\ @@ -257,15 +258,13 @@ instantdex_claim()\n\ return(jprint(LP_coinsjson(0),1)); else if ( strcmp(method,"notarizations") == 0 ) { - int32_t height,bestheight; if ( (ptr= LP_coinsearch(coin)) != 0 ) { - height = LP_notarization_latest(&bestheight,ptr); retjson = cJSON_CreateObject(); jaddstr(retjson,"result","success"); jaddstr(retjson,"coin",coin); - jaddnum(retjson,"lastnotarization",height); - jaddnum(retjson,"bestheight",bestheight); + jaddnum(retjson,"lastnotarization",ptr->notarized); + jaddnum(retjson,"bestheight",ptr->height); return(jprint(retjson,1)); } else return(clonestr("{\"error\":\"cant find coin\"}")); } @@ -289,13 +288,13 @@ instantdex_claim()\n\ uint32_t requestid,quoteid; if ( (requestid= juint(argjson,"requestid")) != 0 && (quoteid= juint(argjson,"quoteid")) != 0 ) { - return(basilisk_swapentry(requestid,quoteid)); + return(basilisk_swapentry(requestid,quoteid,1)); } else if ( coin[0] != 0 ) return(basilisk_swapentries(coin,0,jint(argjson,"limit"))); else if ( base[0] != 0 && rel[0] != 0 ) return(basilisk_swapentries(base,rel,jint(argjson,"limit"))); - else return(basilisk_swaplist(0,0)); + else return(basilisk_swaplist(0,0,0)); } else if ( strcmp(method,"dynamictrust") == 0 ) { @@ -419,8 +418,8 @@ instantdex_claim()\n\ if ( LP_conflicts_find(ptr) == 0 ) { ptr->inactive = 0; - cJSON *array; - if ( LP_getheight(ptr) <= 0 ) + cJSON *array; int32_t notarized; + if ( LP_getheight(¬arized,ptr) <= 0 ) { ptr->inactive = (uint32_t)time(NULL); return(clonestr("{\"error\":\"coin cant be activated till synced\"}")); @@ -604,25 +603,33 @@ instantdex_claim()\n\ } argjson = reqjson; } - if ( strcmp(method,"gettradestatus") == 0 ) + if ( strcmp(method,"getdPoW") == 0 ) retstr = clonestr("{\"result\":\"success\"}"); } else { - if ( strcmp(method,"gettradestatus") == 0 ) - return(LP_gettradestatus(j64bits(argjson,"aliceid"))); - else if ( strcmp(method,"tradesarray") == 0 ) + if ( strcmp(method,"tradesarray") == 0 ) { return(jprint(LP_tradesarray(base,rel,juint(argjson,"starttime"),juint(argjson,"endtime"),jint(argjson,"timescale")),1)); } + else if ( strcmp(method,"getdPoW") == 0 ) + { + if ( (ptr= LP_coinfind(jstr(argjson,"coin"))) != 0 ) + LP_dPoW_broadcast(ptr); + retstr = clonestr("{\"result\":\"success\"}"); + } } // received response if ( strcmp(method,"swapstatus") == 0 ) return(LP_swapstatus_recv(argjson)); + else if ( strcmp(method,"gettradestatus") == 0 ) + return(LP_gettradestatus(j64bits(argjson,"aliceid"),juint(argjson,"requestid"),juint(argjson,"quoteid"))); else if ( strcmp(method,"postprice") == 0 ) return(LP_postprice_recv(argjson)); else if ( strcmp(method,"uitem") == 0 ) return(LP_uitem_recv(argjson)); + else if ( strcmp(method,"dPoW") == 0 ) + return(LP_dPoW_recv(argjson)); else if ( strcmp(method,"notify") == 0 ) return(LP_notify_recv(argjson)); else if ( strcmp(method,"getpeers") == 0 ) diff --git a/iguana/exchanges/LP_include.h b/iguana/exchanges/LP_include.h index bb7e77d73..218dc7867 100644 --- a/iguana/exchanges/LP_include.h +++ b/iguana/exchanges/LP_include.h @@ -27,7 +27,7 @@ #define LP_MAJOR_VERSION "0" #define LP_MINOR_VERSION "1" -#define LP_BUILD_NUMBER "17577" +#define LP_BUILD_NUMBER "17667" #define LP_BARTERDEX_VERSION 1 #define LP_MAGICBITS 1 @@ -64,7 +64,8 @@ void emscripten_usleep(int32_t x); // returns immediate, no sense for sleeping // RTmetrics #define LP_RTMETRICS_TOPGROUP 1.01 -#define LP_MAXPENDING_SWAPS 13 +//#define LP_MAXPENDING_SWAPS 13 +#define LP_CLIENT_STATSPARSE (90 * 1024 * 1024) #define LP_COMMAND_SENDSOCK NN_PUSH #define LP_COMMAND_RECVSOCK NN_PULL @@ -105,7 +106,8 @@ void emscripten_usleep(int32_t x); // returns immediate, no sense for sleeping #define INSTANTDEX_KMD "RThtXup6Zo7LZAi8kRWgjAyi1s4u6U9Cpf" #define BOTS_BONDADDRESS "RNdqHx26GWy9bk8MtmH1UiXjQcXE4RKK2P" #define BOTS_BONDPUBKEY33 "03e641d22e1ff5a7d45c8880537e0b0a114d7b9fee2c18a6b4a8a80b6285292990" -#define LP_WEEKMULT (7 * 24 * 2600) +#define LP_WEEKMULTBAD (7 * 24 * 2600) +#define LP_WEEKMULT (7 * 24 * 3600) #define LP_FIRSTWEEKTIME 1510790400 // must be 0 mod LP_WEEKMULT //#define BASILISK_DISABLEWAITTX @@ -289,8 +291,8 @@ struct iguana_info UT_hash_handle hh; portable_mutex_t txmutex,addrmutex; struct LP_transaction *transactions; struct LP_address *addresses; uint64_t txfee; - int32_t numutxos,longestchain,firstrefht,firstscanht,lastscanht,bussock,height; uint16_t busport; - uint32_t loadedcache,electrumlist,lastunspent,importedprivkey,lastpushtime,lastutxosync,addr_listunspent_requested,lastutxos,updaterate,counter,inactive,lastmempool,lastgetinfo,ratetime,heighttime,lastmonitor,obooktime; + int32_t numutxos,notarized,longestchain,firstrefht,firstscanht,lastscanht,bussock,height; uint16_t busport; + uint32_t dPoWtime,loadedcache,electrumlist,lastunspent,importedprivkey,lastpushtime,lastutxosync,addr_listunspent_requested,lastutxos,updaterate,counter,inactive,lastmempool,lastgetinfo,ratetime,heighttime,lastmonitor,obooktime; uint8_t pubtype,p2shtype,isPoS,wiftype,wiftaddr,taddr,noimportprivkey_flag,userconfirms,isassetchain,maxconfirms; char symbol[128],smartaddr[64],userpass[1024],serverport[128]; // portfolio @@ -299,8 +301,8 @@ struct iguana_info uint64_t maxamount,kmd_equiv,balanceA,balanceB,valuesumA,valuesumB; uint8_t pubkey33[33],zcash; int32_t privkeydepth; - bits256 cachedtxid; uint8_t *cachedtxiddata; int32_t cachedtxidlen; - bits256 cachedmerkle; int32_t cachedmerkleheight; + bits256 cachedtxid,notarizationtxid; uint8_t *cachedtxiddata; int32_t cachedtxidlen; + bits256 cachedmerkle,notarizedhash; int32_t cachedmerkleheight; }; struct _LP_utxoinfo { bits256 txid; uint64_t value; int32_t vout,height; }; @@ -401,9 +403,11 @@ struct LP_swapstats UT_hash_handle hh; struct LP_quoteinfo Q; bits256 bobdeposit,alicepayment,bobpayment,paymentspent,Apaymentspent,depositspent; + int32_t bobdeposit_ht,alicepayment_ht,bobpayment_ht,paymentspent_ht,Apaymentspent_ht,depositspent_ht; double qprice; uint64_t aliceid; - uint32_t ind,methodind,finished,expired,lasttime; + int32_t bobneeds_dPoW,aliceneeds_dPoW; + uint32_t ind,methodind,finished,expired,lasttime,dPoWfinished; char alicegui[32],bobgui[32]; }; @@ -482,13 +486,14 @@ void LP_aliceid(uint32_t tradeid,uint64_t aliceid,char *event,uint32_t requestid cJSON *LP_cache_transaction(struct iguana_info *coin,bits256 txid,uint8_t *serialized,int32_t len); cJSON *LP_transaction_fromdata(struct iguana_info *coin,bits256 txid,uint8_t *serialized,int32_t len); uint64_t LP_RTsmartbalance(struct iguana_info *coin); -int32_t LP_getheight(struct iguana_info *coin); +int32_t LP_getheight(int32_t *notarizedp,struct iguana_info *coin); int32_t LP_reserved_msg(int32_t priority,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); int32_t LP_merkleproof(struct iguana_info *coin,char *coinaddr,struct electrum_info *ep,bits256 txid,int32_t height); cJSON *electrum_address_gethistory(char *symbol,struct electrum_info *ep,cJSON **retjsonp,char *addr,bits256 reftxid); +cJSON *LP_myzdebits(); int32_t _LP_utxos_remove(bits256 txid,int32_t vout); int32_t LP_utxos_remove(bits256 txid,int32_t vout); struct LP_transaction *LP_transactionadd(struct iguana_info *coin,bits256 txid,int32_t height,int32_t numvouts,int32_t numvins); @@ -512,7 +517,7 @@ cJSON *LP_transactioninit(struct iguana_info *coin,bits256 txid,int32_t iter,cJS int32_t LP_mempoolscan(char *symbol,bits256 searchtxid); int32_t LP_txheight(struct iguana_info *coin,bits256 txid); int32_t LP_numpeers(); -char *basilisk_swapentry(uint32_t requestid,uint32_t quoteid); +char *basilisk_swapentry(uint32_t requestid,uint32_t quoteid,int32_t forceflag); int64_t LP_KMDvalue(struct iguana_info *coin,int64_t balance); int32_t LP_address_utxoadd(uint32_t timestamp,char *debug,struct iguana_info *coin,char *coinaddr,bits256 txid,int32_t vout,uint64_t value,int32_t height,int32_t spendheight); void LP_smartutxos_push(struct iguana_info *coin); diff --git a/iguana/exchanges/LP_instantdex.c b/iguana/exchanges/LP_instantdex.c index d2ee44382..cb01b37b8 100644 --- a/iguana/exchanges/LP_instantdex.c +++ b/iguana/exchanges/LP_instantdex.c @@ -178,8 +178,11 @@ char *LP_instantdex_deposit(struct iguana_info *coin,int32_t weeks,double amount int64_t LP_claimtx(void *ctx,struct iguana_info *coin,bits256 *claimtxidp,bits256 utxotxid,int32_t utxovout,uint64_t satoshis,char *vinaddr,uint32_t claimtime,uint8_t *redeemscript,int32_t redeemlen) { - uint8_t userdata[2]; char *signedtx; bits256 signedtxid,sendtxid; int32_t userdatalen; int64_t destamount,sum = 0; - userdata[0] = 0x51; + uint8_t userdata[2]; char *signedtx; bits256 signedtxid,sendtxid; int32_t isbots,userdatalen; int64_t destamount,sum = 0; + if ( strcmp(coin->smartaddr,BOTS_BONDADDRESS) == 0 ) + isbots = 1; + else isbots = 0; + userdata[0] = (isbots == 0) ? 0x51 : 0; userdatalen = 1; utxovout = 0; memset(claimtxidp,0,sizeof(*claimtxidp)); @@ -199,88 +202,88 @@ int64_t LP_claimtx(void *ctx,struct iguana_info *coin,bits256 *claimtxidp,bits25 return(sum); } +int32_t LP_claim_submit(void *ctx,cJSON *txids,int64_t *sump,struct iguana_info *coin,bits256 utxotxid) +{ + uint8_t redeemscript[512]; bits256 claimtxid; cJSON *txjson,*vout0,*vout1,*vout2,*vouts,*item; int32_t numvouts; char str[65],vinaddr[64],destaddr[64],checkaddr[64]; int32_t j,utxovout,flagi = 0,redeemlen,weeki; int64_t weeksatoshis,satoshis; uint32_t expiration,claimtime; + if ( (txjson= LP_gettx(coin->symbol,utxotxid,1)) != 0 ) + { + if ( (vouts= jarray(&numvouts,txjson,"vout")) != 0 && numvouts >= 3 ) + { + vout0 = jitem(vouts,0); + LP_destaddr(vinaddr,vout0); + satoshis = LP_value_extract(vout0,1); + vout2 = jitem(vouts,2); + LP_destaddr(destaddr,vout2); + if ( strcmp(destaddr,coin->smartaddr) == 0 ) + { + vout1 = jitem(vouts,1); + weeksatoshis = LP_value_extract(vout1,0); + weeki = (int32_t)(weeksatoshis % 10000); + for (j=0; j<2*168; j++) + { + if ( j >= 168 ) + expiration = ((weeki * LP_WEEKMULTBAD + (j-168)*3600) + LP_FIRSTWEEKTIME); + else expiration = ((weeki * LP_WEEKMULT + j*3600) + LP_FIRSTWEEKTIME); + redeemlen = LP_deposit_addr(checkaddr,redeemscript,coin->taddr,coin->p2shtype,expiration,G.LP_pubsecp); + if ( strcmp(checkaddr,vinaddr) == 0 ) + { + flagi = 1; + claimtime = (uint32_t)time(NULL)-777; + item = cJSON_CreateObject(); + jaddbits256(item,"txid",utxotxid); + jaddnum(item,"deposit",dstr(LP_value_extract(vout0,0))); + if ( coin->electrum == 0 ) + jaddnum(item,"interest",dstr(satoshis)-dstr(LP_value_extract(vout0,0))); + else jaddnum(item,"interest",dstr(LP_komodo_interest(utxotxid,satoshis))); + if ( claimtime <= expiration ) + { + printf("claimtime.%u vs %u, wait %d seconds to %s claim %.8f\n",claimtime,expiration,(int32_t)expiration-claimtime,bits256_str(str,utxotxid),dstr(satoshis)); + jaddnum(item,"waittime",(int32_t)expiration-claimtime); + jaddi(txids,item); + break; + } + else + { + utxovout = 0; + *sump += LP_claimtx(ctx,coin,&claimtxid,utxotxid,utxovout,satoshis,vinaddr,claimtime,redeemscript,redeemlen); + if ( bits256_nonz(claimtxid) != 0 ) + { + jaddbits256(item,"claimtxid",claimtxid); + jaddi(txids,item); + } + } + } //else printf("expiration.%u j.%d checkaddr.(%s) != vinaddr.%s\n",expiration,j,checkaddr,vinaddr); + if ( flagi != 0 ) + break; + } + } else printf("vout2 dest.(%s) != %s\n",destaddr,coin->smartaddr); + } else printf("numvouts %d != 3\n",numvouts); + free_json(txjson); + } else printf("cant get transaction\n"); + return(flagi); +} + char *LP_instantdex_claim(struct iguana_info *coin) { static void *ctx; - uint8_t redeemscript[512]; char vinaddr[64],checkaddr[64],destaddr[64],str[65]; uint32_t now,redeemlen,claimtime,expiration=0; int32_t i,j,n,flagi,flag,weeki,numvouts,utxovout; bits256 utxotxid,claimtxid; int64_t sum,satoshis,weeksatoshis; cJSON *array,*txids,*retjson,*newarray,*txjson,*vouts,*vout0,*vout1,*vout2,*item; - printf("inside instantdex claim\n"); + int32_t i,n; cJSON *array,*txids,*newarray,*retjson; int64_t sum; bits256 utxotxid; if ( ctx == 0 ) ctx = bitcoin_ctx(); if ( strcmp(coin->symbol,"KMD") != 0 ) return(clonestr("{\"error\":\"instantdex deposit must be in KMD\"}")); - now = (uint32_t)time(NULL); sum = 0; txids = cJSON_CreateArray(); newarray = cJSON_CreateArray(); if ( (array= LP_instantdex_txids()) != 0 ) { - //printf("claiming from.(%s)\n",jprint(array,0)); + printf("claiming from.(%s)\n",jprint(array,0)); if ( (n= cJSON_GetArraySize(array)) > 0 ) { - flag = 0; for (i=0; isymbol,utxotxid,1)) != 0 ) - { - if ( (vouts= jarray(&numvouts,txjson,"vout")) != 0 && numvouts == 3 ) - { - vout0 = jitem(vouts,0); - LP_destaddr(vinaddr,vout0); - satoshis = LP_value_extract(vout0,1); - vout2 = jitem(vouts,2); - LP_destaddr(destaddr,vout2); - if ( strcmp(destaddr,coin->smartaddr) == 0 ) - { - vout1 = jitem(vouts,1); - weeksatoshis = LP_value_extract(vout1,0); - weeki = (int32_t)(weeksatoshis % 10000); - for (j=28; j<=28; j++) - { - expiration = ((weeki * LP_WEEKMULT + j*3600) + LP_FIRSTWEEKTIME); - redeemlen = LP_deposit_addr(checkaddr,redeemscript,coin->taddr,coin->p2shtype,expiration,G.LP_pubsecp); - if ( strcmp(checkaddr,vinaddr) == 0 ) - { - claimtime = (uint32_t)time(NULL)-777; - item = cJSON_CreateObject(); - jaddbits256(item,"txid",utxotxid); - jaddnum(item,"deposit",dstr(LP_value_extract(vout0,0))); - if ( coin->electrum == 0 ) - jaddnum(item,"interest",dstr(satoshis)-dstr(LP_value_extract(vout0,0))); - else jaddnum(item,"interest",dstr(LP_komodo_interest(utxotxid,satoshis))); - if ( claimtime <= expiration ) - { - printf("claimtime.%u vs %u, wait %d seconds to %s claim %.8f\n",claimtime,expiration,(int32_t)expiration-claimtime,bits256_str(str,utxotxid),dstr(satoshis)); - jaddnum(item,"waittime",(int32_t)expiration-claimtime); - jaddi(txids,item); - break; - } - else - { - flagi = 1; - sum += LP_claimtx(ctx,coin,&claimtxid,utxotxid,utxovout,satoshis,vinaddr,claimtime,redeemscript,redeemlen); - jaddbits256(item,"claimtxid",claimtxid); - jaddi(txids,item); - } - } else printf("expiration.%u j.%d checkaddr.(%s) != vinaddr.%s\n",expiration,j,checkaddr,vinaddr); - if ( flagi != 0 ) - break; - } - } else printf("vout2 dest.(%s) != %s\n",destaddr,coin->smartaddr); - } else printf("numvouts %d != 3\n",numvouts); - free_json(txjson); - } else printf("cant get transaction\n"); - if ( flagi == 0 ) + if ( LP_claim_submit(ctx,txids,&sum,coin,utxotxid) == 0 ) jaddibits256(newarray,utxotxid); - else flag++; } } free_json(array); @@ -301,7 +304,7 @@ int64_t LP_instantdex_credit(int32_t dispflag,char *coinaddr,int64_t satoshis,in if ( coin != 0 ) { timestamp = LP_FIRSTWEEKTIME + weeki*LP_WEEKMULT; - if ( time(NULL) < timestamp-60*3600 && (ap= LP_address(coin,coinaddr)) != 0 ) + if ( (ap= LP_address(coin,coinaddr)) != 0 && time(NULL) < timestamp-60*3600 ) { ap->instantdex_credits += satoshis; ap->didinstantdex = 1; @@ -310,7 +313,7 @@ int64_t LP_instantdex_credit(int32_t dispflag,char *coinaddr,int64_t satoshis,in if ( dispflag != 0 ) printf("InstantDEX credit.(%s) %.8f weeki.%d (%s) -> sum %.8f\n",coinaddr,dstr(satoshis),weeki,p2shaddr,dstr(ap->instantdex_credits)); return(satoshis); - } + } //else printf("null ap.%p or expired %ld\n",ap,time(NULL) - (timestamp-60*3600)); } return(0); } @@ -333,15 +336,15 @@ int64_t LP_instantdex_creditcalc(struct iguana_info *coin,int32_t dispflag,bits2 weeki = (amount64 % 10000); item = jitem(vouts,0); satoshis = LP_value_extract(item,0); - //printf("%s funded %.8f weeki.%d\n",destaddr,dstr(satoshis),weeki); + //printf("%s %s funded %.8f weeki.%d (%s)\n",bits256_str(str,txid),destaddr,dstr(satoshis),weeki,jprint(item,0)); if ( LP_destaddr(p2shaddr,item) == 0 ) { if ( (txobj= LP_gettxout(coin->symbol,p2shaddr,txid,0)) != 0 ) { free_json(txobj); LP_instantdex_credit(dispflag,destaddr,satoshis,weeki,p2shaddr,txid); - } - } + } else printf("already spent\n"); + } else printf("error getting p2shaddr.(%s)\n",p2shaddr); } } free_json(txjson); @@ -391,15 +394,16 @@ int64_t LP_dynamictrust(bits256 pubkey,int64_t kmdvalue) { DL_FOREACH_SAFE(pubp->bobswaps,ptr,tmp) { - if ( (sp= ptr->swap) != 0 && sp->finished == 0 && sp->expired == 0 ) + if ( (sp= ptr->swap) != 0 && LP_swap_finished(sp,1) == 0 ) swaps_kmdvalue += LP_kmdvalue(sp->Q.srccoin,sp->Q.satoshis); } DL_FOREACH_SAFE(pubp->aliceswaps,ptr,tmp) { - if ( (sp= ptr->swap) != 0 && sp->finished == 0 && sp->expired == 0 ) + if ( (sp= ptr->swap) != 0 && LP_swap_finished(sp,1) == 0 ) swaps_kmdvalue += LP_kmdvalue(sp->Q.destcoin,sp->Q.destsatoshis); } - //printf("%s instantdex_credits %.8f vs (%.8f + current %.8f)\n",coinaddr,dstr(ap->instantdex_credits),dstr(swaps_kmdvalue),dstr(kmdvalue)); + if ( ap->instantdex_credits != 0 && (swaps_kmdvalue+kmdvalue) > ap->instantdex_credits ) + printf("%s instantdex_credits %.8f vs (%.8f + current %.8f)\n",coinaddr,dstr(ap->instantdex_credits),dstr(swaps_kmdvalue),dstr(kmdvalue)); //if ( ap->instantdex_credits > swaps_kmdvalue+kmdvalue ) return(ap->instantdex_credits - (swaps_kmdvalue+kmdvalue)); } @@ -414,7 +418,7 @@ int64_t LP_instantdex_proofcheck(char *coinaddr,cJSON *proof,int32_t num) { bitcoin_addr2rmd160(0,&addrtype,rmd160,coinaddr); bitcoin_address(othersmartaddr,0,60,rmd160,20); - if ((ap= LP_address(coin,othersmartaddr)) != 0 && (coin->electrum == 0 || ap->didinstantdex == 0) ) + if ((ap= LP_address(coin,othersmartaddr)) != 0 )//&& (coin->electrum == 0 || ap->didinstantdex == 0) ) { ap->instantdex_credits = 0; for (i=0; ididinstantdex = 1; //if ( ap->instantdex_credits > 0 ) printf("validated instantdex %s.[%d] proof.(%s) credits %.8f net %.8f\n",othersmartaddr,num,jprint(proof,0),dstr(ap->instantdex_credits),dstr(net)); - } else printf("cant find ap.%p or already did %d %.8f\n",ap,ap!=0?ap->didinstantdex:-1,ap!=0?dstr(ap->instantdex_credits):-1); + } //else printf("cant find ap.%p or already did %d %.8f\n",ap,ap!=0?ap->didinstantdex:-1,ap!=0?dstr(ap->instantdex_credits):-1); } return(ap->instantdex_credits); } @@ -441,3 +445,97 @@ int64_t LP_myzcredits() } return(0); } + +cJSON *LP_swapstats_item(struct LP_swapstats *sp,int32_t iambob) +{ + struct iguana_info *bob,*alice; int32_t flag = 0; char *retstr,*swapstr; bits256 zero; cJSON *item,*reqjson,*swapjson; + item = cJSON_CreateObject(); + jaddnum(item,"iambob",iambob); + jaddnum(item,"aliceid",sp->aliceid); + jaddnum(item,"requestid",sp->Q.R.requestid); + jaddnum(item,"quoteid",sp->Q.R.quoteid); + jaddstr(item,"base",sp->Q.srccoin); + jaddnum(item,"satoshis",sp->Q.satoshis); + jaddstr(item,"rel",sp->Q.destcoin); + jaddnum(item,"destsatoshis",sp->Q.destsatoshis); + jaddnum(item,"price",sp->Q.destsatoshis/((double)sp->Q.satoshis+1)); + if ( LP_swap_finished(sp,1) == 0 ) + { + jaddnum(item,"finished",sp->finished); + if ( sp->bobneeds_dPoW != 0 && (bob= LP_coinfind(sp->Q.srccoin)) != 0 ) + { + jaddnum(item,"bobneeds_dPoW",sp->bobneeds_dPoW); + jaddnum(item,"bob_dPoWheight",bob->notarized); + if ( sp->bobneeds_dPoW == 1 ) + flag = 1; + if ( bob->notarized == 0 ) + LP_dPoW_request(bob); + } + if ( sp->aliceneeds_dPoW != 0 && (alice= LP_coinfind(sp->Q.destcoin)) != 0 ) + { + jaddnum(item,"aliceneeds_dPoW",sp->aliceneeds_dPoW); + jaddnum(item,"alice_dPoWheight",alice->notarized); + if ( sp->aliceneeds_dPoW == 1 ) + flag = 1; + if ( alice->notarized == 0 ) + LP_dPoW_request(alice); + } + if ( flag != 0 ) + { + reqjson = cJSON_CreateObject(); + jaddstr(reqjson,"method","gettradestatus"); + jadd64bits(reqjson,"aliceid",sp->aliceid); + memset(zero.bytes,0,sizeof(zero)); + LP_reserved_msg(0,"","",zero,jprint(reqjson,1)); + if ( (swapstr= basilisk_swapentry(sp->Q.R.requestid,sp->Q.R.quoteid,0)) != 0 ) + { + if ( (swapjson= cJSON_Parse(swapstr)) != 0 ) + { + if ( (retstr= LP_swapstatus_recv(swapjson)) != 0 ) + free(retstr); + free_json(swapjson); + } + free(swapstr); + } + } + } + return(item); +} + +cJSON *LP_myzdebits() +{ + struct LP_pubswap *ptr,*tmp; struct LP_pubkey_info *pubp; struct LP_swapstats *sp; int64_t kmdvalue,swaps_kmdvalue = 0; struct iguana_info *coin; cJSON *retjson,*array,*item; + array = cJSON_CreateArray(); + if ( (coin= LP_coinfind("KMD")) != 0 ) + { + if ( (pubp= LP_pubkeyfind(G.LP_mypub25519)) != 0 ) + { + DL_FOREACH_SAFE(pubp->bobswaps,ptr,tmp) + { + if ( (sp= ptr->swap) != 0 && LP_swap_finished(sp,1) == 0 ) + { + kmdvalue = LP_kmdvalue(sp->Q.srccoin,sp->Q.satoshis); + item = LP_swapstats_item(sp,1); + jaddnum(item,"kmdvalue",dstr(kmdvalue)); + jaddi(array,item); + swaps_kmdvalue += kmdvalue; + } + } + DL_FOREACH_SAFE(pubp->aliceswaps,ptr,tmp) + { + if ( (sp= ptr->swap) != 0 && LP_swap_finished(sp,1) == 0 ) + { + kmdvalue = LP_kmdvalue(sp->Q.destcoin,sp->Q.destsatoshis); + item = LP_swapstats_item(sp,0); + jaddnum(item,"kmdvalue",dstr(kmdvalue)); + jaddi(array,item); + swaps_kmdvalue += kmdvalue; + } + } + } + } + retjson = cJSON_CreateObject(); + jadd(retjson,"swaps",array); + jaddnum(retjson,"pendingswaps",dstr(swaps_kmdvalue)); + return(retjson); +} diff --git a/iguana/exchanges/LP_nativeDEX.c b/iguana/exchanges/LP_nativeDEX.c index 4a853cd6d..19ee06ace 100644 --- a/iguana/exchanges/LP_nativeDEX.c +++ b/iguana/exchanges/LP_nativeDEX.c @@ -17,21 +17,18 @@ // LP_nativeDEX.c // marketmaker // -// verify claim works -// big BTC swaps // https://github.com/bitcoin/bips/blob/master/bip-0143.mediawiki for signing BCH/BTG +// big BTC swaps, assetchain markets // // compress packets // cancel bid/ask // portfolio to set prices from historical // portfolio value based on ask? -// USD paxprice based USDvalue in portfolio // -// improve critical section detection when parallel trades -// delay swap credit back until notarization +// else claim path // dPoW security -> 4: KMD notarized, 5: BTC notarized, after next notary elections // bigendian architectures need to use little endian for sighash calcs -// +// improve critical section detection when parallel trades #include @@ -484,7 +481,7 @@ void command_rpcloop(void *ctx) void LP_coinsloop(void *_coins) { - struct LP_address *ap=0,*atmp; struct LP_transaction *tx; cJSON *retjson; struct LP_address_utxo *up,*tmp; struct iguana_info *coin,*ctmp; char str[65]; struct electrum_info *ep,*backupep=0; bits256 zero; int32_t oldht,j,nonz; char *coins = _coins; + struct LP_address *ap=0,*atmp; struct LP_transaction *tx; cJSON *retjson; struct LP_address_utxo *up,*tmp; struct iguana_info *coin,*ctmp; char str[65]; struct electrum_info *ep,*backupep=0; bits256 zero; int32_t notarized,oldht,j,nonz; char *coins = _coins; if ( strcmp("BTC",coins) == 0 ) { strcpy(LP_coinsloopBTC_stats.name,"BTC coin loop"); @@ -529,7 +526,7 @@ void LP_coinsloop(void *_coins) if ( coin->inactive != 0 ) continue; if ( coin->longestchain == 1 ) // special init value - coin->longestchain = LP_getheight(coin); + coin->longestchain = LP_getheight(¬arized,coin); if ( (ep= coin->electrum) != 0 ) { /*if ( strcmp("KMD",coin->symbol) == 0 && coin->electrumzeroconf == 0 ) @@ -572,7 +569,7 @@ void LP_coinsloop(void *_coins) nonz++; printf("SPV failure for %s %s\n",coin->symbol,bits256_str(str,up->U.txid)); oldht = up->U.height; - LP_txheight_check(coin,ap->coinaddr,up); + LP_txheight_check(coin,ap->coinaddr,up->U.txid); if ( oldht != up->U.height ) up->SPV = LP_merkleproof(coin,coin->smartaddr,backupep,up->U.txid,up->U.height); if ( up->SPV <= 0 ) @@ -589,6 +586,7 @@ void LP_coinsloop(void *_coins) //printf("%s electrum.%p needs a keepalive: lag.%d\n",ep->symbol,ep,(int32_t)(time(NULL) - ep->keepalive)); if ( (retjson= electrum_banner(coin->symbol,ep,&retjson)) != 0 ) free_json(retjson); + ep->keepalive = (uint32_t)time(NULL); } ep = ep->prev; } @@ -645,7 +643,7 @@ void LP_coinsloop(void *_coins) int32_t LP_mainloop_iter(void *ctx,char *myipaddr,struct LP_peerinfo *mypeer,int32_t pubsock,char *pushaddr,uint16_t myport) { static uint32_t counter;//,didinstantdex; - struct iguana_info *coin,*ctmp; char *origipaddr; uint32_t now; int32_t height,nonz = 0; + struct iguana_info *coin,*ctmp; char *origipaddr; uint32_t now; int32_t notarized,height,nonz = 0; if ( (origipaddr= myipaddr) == 0 ) origipaddr = "127.0.0.1"; if ( mypeer == 0 ) @@ -660,19 +658,25 @@ int32_t LP_mainloop_iter(void *ctx,char *myipaddr,struct LP_peerinfo *mypeer,int didinstantdex = now; } #endif - if ( (coin->addr_listunspent_requested != 0 && now > coin->lastpushtime+LP_ORDERBOOK_DURATION*.5) || now > coin->lastpushtime+LP_ORDERBOOK_DURATION*5 ) + /*if ( (coin->addr_listunspent_requested != 0 && now > coin->lastpushtime+LP_ORDERBOOK_DURATION*.5) || now > coin->lastpushtime+LP_ORDERBOOK_DURATION*5 ) { //printf("PUSH addr_listunspent_requested %u\n",coin->addr_listunspent_requested); coin->lastpushtime = (uint32_t)now; LP_smartutxos_push(coin); coin->addr_listunspent_requested = 0; - } + }*/ if ( coin->electrum == 0 && coin->inactive == 0 && now > coin->lastgetinfo+LP_GETINFO_INCR ) { nonz++; - if ( (height= LP_getheight(coin)) > coin->longestchain ) + if ( (height= LP_getheight(¬arized,coin)) > coin->longestchain ) { coin->longestchain = height; + if ( notarized != 0 && notarized > coin->notarized ) + { + coin->notarized = notarized; + if ( IAMLP != 0 ) + LP_dPoW_broadcast(coin); + } if ( 0 && coin->firstrefht != 0 ) printf(">>>>>>>>>> set %s longestchain %d (ref.%d [%d, %d])\n",coin->symbol,height,coin->firstrefht,coin->firstscanht,coin->lastscanht); } //else LP_mempoolscan(coin->symbol,zero); @@ -685,7 +689,7 @@ int32_t LP_mainloop_iter(void *ctx,char *myipaddr,struct LP_peerinfo *mypeer,int void LP_initcoins(void *ctx,int32_t pubsock,cJSON *coins) { - int32_t i,n; cJSON *item; char *symbol; struct iguana_info *coin; + int32_t i,n,notarized; cJSON *item; char *symbol; struct iguana_info *coin; for (i=0; iinactive = (uint32_t)time(NULL); else { @@ -720,7 +724,7 @@ void LP_initcoins(void *ctx,int32_t pubsock,cJSON *coins) LP_priceinfoadd(jstr(item,"coin")); if ( (coin= LP_coinfind(symbol)) != 0 ) { - if ( LP_getheight(coin) <= 0 ) + if ( LP_getheight(¬arized,coin) <= 0 ) coin->inactive = (uint32_t)time(NULL); else LP_unspents_load(coin->symbol,coin->smartaddr); if ( coin->txfee == 0 && strcmp(coin->symbol,"BTC") != 0 ) @@ -802,7 +806,7 @@ void LP_swapsloop(void *ctx) while ( 1 ) { LP_millistats_update(&LP_swapsloop_stats); - if ( (retstr= basilisk_swapentry(0,0)) != 0 ) + if ( (retstr= basilisk_swapentry(0,0,0)) != 0 ) free(retstr); sleep(600); } @@ -1305,7 +1309,7 @@ void LP_fromjs_iter() { LP_notify_pubkeys(ctx,LP_mypubsock); LP_privkey_updates(ctx,LP_mypubsock,0); - if ( (retstr= basilisk_swapentry(0,0)) != 0 ) + if ( (retstr= basilisk_swapentry(0,0,0)) != 0 ) free(retstr); } } diff --git a/iguana/exchanges/LP_ordermatch.c b/iguana/exchanges/LP_ordermatch.c index 15d8f959d..85e4f5088 100644 --- a/iguana/exchanges/LP_ordermatch.c +++ b/iguana/exchanges/LP_ordermatch.c @@ -85,7 +85,7 @@ uint64_t LP_txfeecalc(struct iguana_info *coin,uint64_t txfee,int32_t txlen) return(txfee); } -double LP_qprice_calc(int64_t *destsatoshisp,int64_t *satoshisp,double price,uint64_t b_satoshis,uint64_t txfee,uint64_t a_value,uint64_t maxdestsatoshis,uint64_t desttxfee) +/*double LP_qprice_calc(int64_t *destsatoshisp,int64_t *satoshisp,double price,uint64_t b_satoshis,uint64_t txfee,uint64_t a_value,uint64_t maxdestsatoshis,uint64_t desttxfee) { uint64_t destsatoshis,satoshis; a_value -= (desttxfee + 1); @@ -100,7 +100,7 @@ double LP_qprice_calc(int64_t *destsatoshisp,int64_t *satoshisp,double price,uin if ( satoshis > 0 ) return((double)destsatoshis / satoshis); else return(0.); -} +}*/ int32_t LP_quote_checkmempool(struct LP_quoteinfo *qp,struct LP_utxoinfo *autxo,struct LP_utxoinfo *butxo) { @@ -421,34 +421,39 @@ struct LP_utxoinfo *LP_address_myutxopair(struct LP_utxoinfo *butxo,int32_t iamb printf("%.8f ",dstr(utxos[i]->U.value)); printf("targetval %.8f vol %.8f price %.8f txfee %.8f %s %s\n",dstr(targetval),relvolume,price,dstr(fee),coin->symbol,coinaddr); } - mini = -1; - if ( targetval != 0 && (mini= LP_nearest_utxovalue(coin,coinaddr,utxos,m,targetval+fee)) >= 0 ) + while ( 1 ) { - up = utxos[mini]; - utxos[mini] = 0; -//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 < ratio-1 ) - + mini = -1; + if ( targetval != 0 && (mini= LP_nearest_utxovalue(coin,coinaddr,utxos,m,targetval+fee)) >= 0 ) { - if ( 0 ) - { - int32_t i; - for (i=0; iU.value >= targetval2 ) - printf("%.8f ",dstr(utxos[i]->U.value)); - printf("targetval2 %.8f vol %.8f price %.8f txfee %.8f %s %s\n",dstr(targetval2),relvolume,price,dstr(fee),coin->symbol,coinaddr); - } - if ( (mini= LP_nearest_utxovalue(coin,coinaddr,utxos,m,(targetval2+2*fee) * 1.01)) >= 0 ) + up = utxos[mini]; + utxos[mini] = 0; + //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 < ratio-1 ) + { - if ( up != 0 && (up2= utxos[mini]) != 0 ) + if ( 0 ) { - LP_butxo_set(butxo,iambob,coin,up,up2,targetval); - return(butxo); - } else printf("cant find utxos[mini %d]\n",mini); - } 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); + int32_t i; + for (i=0; iU.value >= targetval2 ) + printf("%.8f ",dstr(utxos[i]->U.value)); + printf("targetval2 %.8f vol %.8f price %.8f txfee %.8f %s %s\n",dstr(targetval2),relvolume,price,dstr(fee),coin->symbol,coinaddr); + } + if ( (mini= LP_nearest_utxovalue(coin,coinaddr,utxos,m,(targetval2+2*fee) * 1.01)) >= 0 ) + { + if ( up != 0 && (up2= utxos[mini]) != 0 ) + { + LP_butxo_set(butxo,iambob,coin,up,up2,targetval); + return(butxo); + } else printf("cant find utxos[mini %d]\n",mini); + } 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); + if ( targetval == 0 || mini < 0 ) + break; + } } else printf("no %s utxos pass LP_address_utxo_ptrs filter\n",coinaddr); } else printf("address_myutxopair couldnt find %s %s\n",coin->symbol,coinaddr); return(0); @@ -696,13 +701,13 @@ int32_t LP_aliceonly(char *symbol) int32_t LP_validSPV(char *symbol,char *coinaddr,bits256 txid,int32_t vout) { - struct electrum_info *ep,*backupep; cJSON *txobj; struct LP_address_utxo *up; struct iguana_info *coin; struct LP_transaction *tx; + struct electrum_info *ep,*backupep; cJSON *txobj; struct LP_address_utxo *up; struct iguana_info *coin; int32_t height; struct LP_transaction *tx; coin = LP_coinfind(symbol); if ( coin != 0 && (ep= coin->electrum) != 0 ) { if ( (up= LP_address_utxofind(coin,coinaddr,txid,vout)) == 0 ) { - if ( (txobj= electrum_transaction(symbol,ep,&txobj,txid,coinaddr)) != 0 ) + if ( (txobj= electrum_transaction(&height,symbol,ep,&txobj,txid,coinaddr)) != 0 ) free_json(txobj); if ( (tx= LP_transactionfind(coin,txid)) != 0 ) { @@ -1308,7 +1313,6 @@ char *LP_autobuy(void *ctx,char *myipaddr,int32_t mypubsock,char *base,char *rel memset(&A,0,sizeof(A)); LP_address_utxo_reset(relcoin); if ( (autxo= LP_address_myutxopair(&A,0,utxos,max,relcoin,relcoin->smartaddr,txfee,dstr(destsatoshis),maxprice,desttxfee)) == 0 ) - //if ( (autxo= LP_utxo_bestfit(rel,destsatoshis + 2*desttxfee)) == 0 ) return(clonestr("{\"error\":\"cant find alice utxo that is close enough in size\"}")); //printf("bestfit selected alice (%.8f %.8f) for %.8f sats %.8f\n",dstr(autxo->payment.value),dstr(autxo->fee.value),dstr(destsatoshis),dstr(autxo->swap_satoshis)); if ( destsatoshis - desttxfee < autxo->swap_satoshis ) diff --git a/iguana/exchanges/LP_prices.c b/iguana/exchanges/LP_prices.c index 8c23d87fb..16efbe735 100644 --- a/iguana/exchanges/LP_prices.c +++ b/iguana/exchanges/LP_prices.c @@ -408,9 +408,9 @@ double LP_pricecache(struct LP_quoteinfo *qp,char *base,char *rel,bits256 txid,i { if ( qp != 0 ) (*qp) = ptr->Q; - if ( ptr->price == 0. && ptr->Q.satoshis != 0 ) + if ( ptr->price == 0. && ptr->Q.satoshis > ptr->Q.txfee ) { - ptr->price = (double)ptr->Q.destsatoshis / ptr->Q.satoshis; + ptr->price = (double)ptr->Q.destsatoshis / (ptr->Q.satoshis - ptr->Q.txfee); if ( LP_pricevalid(ptr->price) <= 0 ) ptr->price = 0.; printf("LP_pricecache: set %s/%s ptr->price %.8f\n",base,rel,ptr->price); diff --git a/iguana/exchanges/LP_privkey.c b/iguana/exchanges/LP_privkey.c index f9c533419..5c77b4c89 100644 --- a/iguana/exchanges/LP_privkey.c +++ b/iguana/exchanges/LP_privkey.c @@ -205,7 +205,7 @@ char *LP_secretaddresses(void *ctx,char *prefix,char *passphrase,int32_t n,uint8 bits256 LP_privkeycalc(void *ctx,uint8_t *pubkey33,bits256 *pubkeyp,struct iguana_info *coin,char *passphrase,char *wifstr) { //static uint32_t counter; - bits256 privkey,userpub,zero,userpass,checkkey; char tmpstr[128]; cJSON *retjson; uint8_t tmptype; + bits256 privkey,userpub,zero,userpass,checkkey; char tmpstr[128]; cJSON *retjson; uint8_t tmptype; int32_t notarized; if ( passphrase != 0 && passphrase[0] != 0 ) { calc_NXTaddr(G.LP_NXTaddr,userpub.bytes,(uint8_t *)passphrase,(int32_t)strlen(passphrase)); @@ -252,7 +252,7 @@ bits256 LP_privkeycalc(void *ctx,uint8_t *pubkey33,bits256 *pubkeyp,struct iguan printf("userpass.(%s)\n",bits256_str(G.USERPASS,userpub)); } } - if ( coin->importedprivkey == 0 && coin->electrum == 0 && coin->userpass[0] != 0 && LP_getheight(coin) > 0 ) + if ( coin->importedprivkey == 0 && coin->electrum == 0 && coin->userpass[0] != 0 && LP_getheight(¬arized,coin) > 0 ) { memset(zero.bytes,0,sizeof(zero)); LP_listunspent_issue(coin->symbol,coin->smartaddr,0,zero,zero); diff --git a/iguana/exchanges/LP_remember.c b/iguana/exchanges/LP_remember.c index 0b8264214..b054f9fdb 100644 --- a/iguana/exchanges/LP_remember.c +++ b/iguana/exchanges/LP_remember.c @@ -529,7 +529,7 @@ cJSON *LP_swap_json(struct LP_swap_remember *rswap) return(item); } -int32_t LP_rswap_init(struct LP_swap_remember *rswap,uint32_t requestid,uint32_t quoteid) +int32_t LP_rswap_init(struct LP_swap_remember *rswap,uint32_t requestid,uint32_t quoteid,int32_t forceflag) { 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)); @@ -664,6 +664,8 @@ int32_t LP_rswap_init(struct LP_swap_remember *rswap,uint32_t requestid,uint32_t } rswap->origfinishedflag = basilisk_swap_isfinished(rswap->iambob,rswap->txids,rswap->sentflags,rswap->paymentspent,rswap->Apaymentspent,rswap->depositspent); rswap->finishedflag = rswap->origfinishedflag; + if ( forceflag != 0 ) + rswap->finishedflag = rswap->origfinishedflag = 0; free(fstr); } return(rswap->iambob); @@ -694,7 +696,7 @@ int32_t LP_refht_update(char *symbol,bits256 txid) return(0); } -int32_t LP_swap_load(struct LP_swap_remember *rswap) +int32_t LP_swap_load(struct LP_swap_remember *rswap,int32_t forceflag) { int32_t i,needflag,addflag; long fsize; char fname[1024],*fstr,*symbol,*rstr; cJSON *txobj,*sentobj,*fileobj; bits256 txid,checktxid; uint64_t value; rswap->iambob = -1; @@ -704,7 +706,8 @@ int32_t LP_swap_load(struct LP_swap_remember *rswap) if ( (fileobj= cJSON_Parse(fstr)) != 0 ) { rswap->finishtime = juint(fileobj,"finishtime"); - rswap->origfinishedflag = rswap->finishedflag = 1; + if ( forceflag == 0 ) + rswap->origfinishedflag = rswap->finishedflag = 1; free_json(fileobj); } free(fstr); @@ -872,16 +875,16 @@ int32_t LP_spends_set(struct LP_swap_remember *rswap) return(numspent); } -cJSON *basilisk_remember(int64_t *KMDtotals,int64_t *BTCtotals,uint32_t requestid,uint32_t quoteid) +cJSON *basilisk_remember(int64_t *KMDtotals,int64_t *BTCtotals,uint32_t requestid,uint32_t quoteid,int32_t forceflag) { static void *ctx; struct LP_swap_remember rswap; int32_t i,j,flag,numspent,len,secretstart,redeemlen; char str[65],*srcAdest,*srcBdest,*destAdest,*destBdest,otheraddr[64]; cJSON *item,*txoutobj; bits256 rev,signedtxid,zero,deadtxid; 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 ) + if ( (rswap.iambob= LP_rswap_init(&rswap,requestid,quoteid,forceflag)) < 0 ) return(cJSON_Parse("{\"error\":\"couldnt initialize rswap, are all coins active?\"}")); decode_hex(deadtxid.bytes,32,"deadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeef"); - LP_swap_load(&rswap); + LP_swap_load(&rswap,forceflag); memset(zero.bytes,0,sizeof(zero)); otheraddr[0] = 0; srcAdest = srcBdest = destAdest = destBdest = 0; @@ -1185,7 +1188,7 @@ cJSON *basilisk_remember(int64_t *KMDtotals,int64_t *BTCtotals,uint32_t requesti return(item); } -char *basilisk_swaplist(uint32_t origrequestid,uint32_t origquoteid) +char *basilisk_swaplist(uint32_t origrequestid,uint32_t origquoteid,int32_t forceflag) { uint64_t ridqids[4096],ridqid; char fname[512]; FILE *fp; cJSON *item,*retjson,*array,*totalsobj; uint32_t r,q,quoteid,requestid; int64_t KMDtotals[LP_MAXPRICEINFOS],BTCtotals[LP_MAXPRICEINFOS],Btotal,Ktotal; int32_t i,j,count=0; portable_mutex_lock(&LP_swaplistmutex); @@ -1198,7 +1201,7 @@ char *basilisk_swaplist(uint32_t origrequestid,uint32_t origquoteid) if ( origrequestid != 0 && origquoteid != 0 ) { //printf("orig req.%u q.%u\n",origrequestid,origquoteid); - if ( (item= basilisk_remember(KMDtotals,BTCtotals,origrequestid,origquoteid)) != 0 ) + if ( (item= basilisk_remember(KMDtotals,BTCtotals,origrequestid,origquoteid,forceflag)) != 0 ) jaddi(array,item); //printf("got.(%s)\n",jprint(item,0)); } @@ -1237,7 +1240,7 @@ char *basilisk_swaplist(uint32_t origrequestid,uint32_t origquoteid) { if ( count < sizeof(ridqids)/sizeof(*ridqids) ) ridqids[count++] = ridqid; - if ( (item= basilisk_remember(KMDtotals,BTCtotals,requestid,quoteid)) != 0 ) + if ( (item= basilisk_remember(KMDtotals,BTCtotals,requestid,quoteid,0)) != 0 ) jaddi(array,item); } } @@ -1270,12 +1273,12 @@ char *basilisk_swaplist(uint32_t origrequestid,uint32_t origquoteid) return(jprint(retjson,1)); } -char *basilisk_swapentry(uint32_t requestid,uint32_t quoteid) +char *basilisk_swapentry(uint32_t requestid,uint32_t quoteid,int32_t forceflag) { cJSON *item; int64_t KMDtotals[LP_MAXPRICEINFOS],BTCtotals[LP_MAXPRICEINFOS]; memset(KMDtotals,0,sizeof(KMDtotals)); memset(BTCtotals,0,sizeof(BTCtotals)); - if ( (item= basilisk_remember(KMDtotals,BTCtotals,requestid,quoteid)) != 0 ) + if ( (item= basilisk_remember(KMDtotals,BTCtotals,requestid,quoteid,forceflag)) != 0 ) return(jprint(item,1)); else return(clonestr("{\"error\":\"cant find requestid-quoteid\"}")); } @@ -1365,7 +1368,7 @@ char *basilisk_swapentries(char *refbase,char *refrel,int32_t limit) limit = 10; memset(ridqids,0,sizeof(ridqids)); retarray = cJSON_CreateArray(); - if ( (liststr= basilisk_swaplist(0,0)) != 0 ) + if ( (liststr= basilisk_swaplist(0,0,0)) != 0 ) { //printf("swapentry.(%s)\n",liststr); if ( (retjson= cJSON_Parse(liststr)) != 0 ) @@ -1408,7 +1411,7 @@ char *basilisk_swapentries(char *refbase,char *refrel,int32_t limit) //printf("j.%d count.%d %u %u ridqid.%16llx\n",j,count,requestid,quoteid,(long long)ridqid); if ( j == count ) { - if ( (retstr2= basilisk_swapentry(requestid,quoteid)) != 0 ) + if ( (retstr2= basilisk_swapentry(requestid,quoteid,0)) != 0 ) { if ( (swapjson= cJSON_Parse(retstr2)) != 0 ) { diff --git a/iguana/exchanges/LP_rpc.c b/iguana/exchanges/LP_rpc.c index b39cdc9fa..a9dcfe1e3 100644 --- a/iguana/exchanges/LP_rpc.c +++ b/iguana/exchanges/LP_rpc.c @@ -52,7 +52,7 @@ cJSON *bitcoin_json(struct iguana_info *coin,char *method,char *params) //printf("issue.(%s, %s, %s, %s, %s)\n",coin->symbol,coin->serverport,coin->userpass,method,params); if ( coin->electrum != 0 && (strcmp(method,"getblock") == 0 || strcmp(method,"paxprice") == 0 || strcmp(method,"getrawmempool") == 0) ) return(cJSON_Parse("{\"error\":\"illegal electrum call\"}")); - if ( coin->inactive == 0 || strcmp(method,"importprivkey") == 0 || strcmp(method,"validateaddress") == 0 ) + if ( coin->inactive == 0 || strcmp(method,"importprivkey") == 0 || strcmp(method,"validateaddress") == 0 || strcmp(method,"getrawtransaction") == 0 || strcmp(method,"getblock") == 0 || strcmp(method,"getinfo") == 0 ) { if ( coin->electrum == 0 ) { @@ -86,13 +86,14 @@ void LP_unspents_mark(char *symbol,cJSON *vins) //printf("LOCK (%s)\n",jprint(vins,0)); } -int32_t LP_getheight(struct iguana_info *coin) +int32_t LP_getheight(int32_t *notarizedp,struct iguana_info *coin) { cJSON *retjson; char *retstr,*method = "getinfo"; int32_t height; + *notarizedp = 0; if ( coin == 0 ) return(-1); height = coin->height; - if ( coin->electrum == 0 && time(NULL) > coin->heighttime+60 ) + if ( coin->electrum == 0 && time(NULL) > coin->heighttime+60 && coin->userpass[0] != 0 ) { if ( strcmp(coin->symbol,"BTC") == 0 ) method = "getblockchaininfo"; @@ -101,6 +102,13 @@ int32_t LP_getheight(struct iguana_info *coin) { retjson = cJSON_Parse(retstr); coin->height = height = jint(retjson,"blocks"); + if ( (*notarizedp= jint(retjson,"notarized")) != 0 && *notarizedp != coin->notarized ) + { + printf("new notarized %s %d -> %d\n",coin->symbol,coin->notarized,*notarizedp); + coin->notarized = *notarizedp; + coin->notarizationtxid = jbits256(retjson,"notarizedtxid"); + coin->notarizedhash = jbits256(retjson,"notarizedhash"); + } free_json(retjson); if ( coin->height > 0 ) coin->heighttime = (uint32_t)time(NULL); @@ -157,7 +165,7 @@ cJSON *LP_paxprice(char *fiat) cJSON *LP_gettx(char *symbol,bits256 txid,int32_t suppress_errors) { - struct iguana_info *coin; char buf[512],str[65]; cJSON *retjson; + struct iguana_info *coin; char buf[512],str[65]; int32_t height; cJSON *retjson; //printf("LP_gettx %s %s\n",symbol,bits256_str(str,txid)); if ( symbol == 0 || symbol[0] == 0 ) return(cJSON_Parse("{\"error\":\"null symbol\"}")); @@ -174,7 +182,7 @@ cJSON *LP_gettx(char *symbol,bits256 txid,int32_t suppress_errors) } else { - if ( (retjson= electrum_transaction(symbol,coin->electrum,&retjson,txid,0)) != 0 ) + if ( (retjson= electrum_transaction(&height,symbol,coin->electrum,&retjson,txid,0)) != 0 ) return(retjson); else if ( suppress_errors == 0 ) printf("failed blockchain.transaction.get %s %s\n",coin->symbol,bits256_str(str,txid)); @@ -214,7 +222,7 @@ cJSON *LP_gettxout_json(bits256 txid,int32_t vout,int32_t height,char *coinaddr, cJSON *LP_gettxout(char *symbol,char *coinaddr,bits256 txid,int32_t vout) { - char buf[128],str[65]; cJSON *item,*array,*vouts,*txobj,*retjson=0; int32_t i,v,n; bits256 t,zero; struct iguana_info *coin; struct LP_transaction *tx; struct LP_address_utxo *up; + char buf[128],str[65]; cJSON *item,*array,*vouts,*txobj,*retjson=0; int32_t i,v,height,n; bits256 t,zero; struct iguana_info *coin; struct LP_transaction *tx; struct LP_address_utxo *up; if ( symbol == 0 || symbol[0] == 0 ) return(cJSON_Parse("{\"error\":\"null symbol\"}")); if ( (coin= LP_coinfind(symbol)) == 0 ) @@ -236,7 +244,7 @@ cJSON *LP_gettxout(char *symbol,char *coinaddr,bits256 txid,int32_t vout) } if ( coinaddr[0] == 0 ) { - if ( (txobj= electrum_transaction(symbol,coin->electrum,&txobj,txid,0)) != 0 ) + if ( (txobj= electrum_transaction(&height,symbol,coin->electrum,&txobj,txid,0)) != 0 ) { if ( (vouts= jarray(&n,txobj,"vout")) != 0 && n > 0 ) LP_destaddr(coinaddr,jitem(vouts,vout)); @@ -959,9 +967,10 @@ const char *Notaries_elected[][2] = { "xxspot2_XX", "03d85b221ea72ebcd25373e7961f4983d12add66a92f899deaf07bab1d8b6f5573" } }; -int32_t LP_txhasnotarization(struct iguana_info *coin,bits256 txid) +int32_t LP_txhasnotarization(bits256 *notarizedhashp,struct iguana_info *coin,bits256 txid) { - cJSON *txobj,*vins,*vin,*vouts,*vout,*spentobj,*sobj; char *hexstr; uint8_t script[35]; bits256 spenttxid; uint64_t notarymask; int32_t i,j,numnotaries,len,spentvout,numvins,numvouts,hasnotarization = 0; + cJSON *txobj,*vins,*vin,*vouts,*vout,*spentobj,*sobj; char *hexstr; uint8_t script[1024]; bits256 spenttxid; uint64_t notarymask; int32_t i,j,numnotaries,len,spentvout,numvins,numvouts,hasnotarization = 0; + memset(notarizedhashp,0,sizeof(*notarizedhashp)); if ( (txobj= LP_gettx(coin->symbol,txid,0)) != 0 ) { if ( (vins= jarray(&numvins,txobj,"vin")) != 0 ) @@ -981,7 +990,7 @@ int32_t LP_txhasnotarization(struct iguana_info *coin,bits256 txid) if ( spentvout < numvouts ) { vout = jitem(vouts,spentvout); - if ( (sobj= jobj(vout,"scriptPubKey")) != 0 && (hexstr= jstr(sobj,"hex")) != 0 && (len= is_hexstr(hexstr,0)) == sizeof(script)*2 ) + if ( (sobj= jobj(vout,"scriptPubKey")) != 0 && (hexstr= jstr(sobj,"hex")) != 0 && (len= is_hexstr(hexstr,0)) == 35*2 ) { len >>= 1; decode_hex(script,len,hexstr); @@ -1015,20 +1024,76 @@ int32_t LP_txhasnotarization(struct iguana_info *coin,bits256 txid) } } } + if ( (vouts= jarray(&numvouts,txobj,"vout")) != 0 ) + { + vout = jitem(vouts,1); + if ( (sobj= jobj(vout,"scriptPubKey")) != 0 && (hexstr= jstr(sobj,"hex")) != 0 && (len= is_hexstr(hexstr,0)) >= 35 ) + { + len >>= 1; + decode_hex(script,len,hexstr); + iguana_rwbignum(0,&script[2],32,(uint8_t *)notarizedhashp); + } + } free_json(txobj); } return(hasnotarization); } +int32_t LP_notarization_validate(char *symbol,int32_t notarized,bits256 notarizedhash,bits256 notarizationtxid) +{ + struct iguana_info *coin; int32_t valid = 0; cJSON *blockjson; bits256 notarizedhash2; char str[65],str2[65]; + if ( strcmp(symbol,"KMD") == 0 ) + coin = LP_coinfind("BTC"); + else coin = LP_coinfind("KMD"); + if ( coin != 0 ) + { + if (LP_txhasnotarization(¬arizedhash2,coin,notarizationtxid) == 0 ) + { + printf("missing %s notarization txid %s\n",symbol,bits256_str(str,notarizationtxid)); + return(-1); + } + else if ( bits256_cmp(notarizedhash,notarizedhash2) != 0 ) + { + printf("mismatched %s notarizedhash %s vs %s\n",symbol,bits256_str(str,notarizedhash),bits256_str(str2,notarizedhash2)); + return(-1); + } + } + if ( (coin= LP_coinfind(symbol)) != 0 ) + { + if ( coin->electrum == 0 ) + { + if ( (blockjson= LP_getblock(coin->symbol,notarizedhash)) != 0 ) + { + if ( jint(blockjson,"height") != notarized ) + valid = 1; + free_json(blockjson); + } + } + else + { + if ( (blockjson= electrum_getheader(symbol,coin->electrum,&blockjson,notarized+1)) != 0 ) + { + notarizedhash2 = jbits256(blockjson,"prev_block_hash"); + if ( bits256_cmp(notarizedhash,notarizedhash2) == 0 ) + valid = 1; + free_json(blockjson); + } + } + } + if ( valid == 1 ) + return(0); + else return(-1); +} + int32_t LP_hasnotarization(struct iguana_info *coin,cJSON *blockjson) { - int32_t i,n,hasnotarization = 0; bits256 txid; cJSON *txarray; + int32_t i,n,hasnotarization = 0; bits256 txid,notarizedhash; cJSON *txarray; if ( (txarray= jarray(&n,blockjson,"tx")) != 0 ) { for (i=0; iprev; //if ( ep != 0 ) // printf("using prev ep.%s\n",ep->symbol); @@ -558,12 +558,12 @@ cJSON *electrum_address_gethistory(char *symbol,struct electrum_info *ep,cJSON * return(retjson); } -int32_t LP_txheight_check(struct iguana_info *coin,char *coinaddr,struct LP_address_utxo *up) +int32_t LP_txheight_check(struct iguana_info *coin,char *coinaddr,bits256 txid) { cJSON *retjson; if ( coin->electrum != 0 ) { - if ( (retjson= electrum_address_gethistory(coin->symbol,coin->electrum,&retjson,coinaddr,up->U.txid)) != 0 ) + if ( (retjson= electrum_address_gethistory(coin->symbol,coin->electrum,&retjson,coinaddr,txid)) != 0 ) free_json(retjson); } return(0); @@ -744,14 +744,15 @@ cJSON *_electrum_transaction(char *symbol,struct electrum_info *ep,cJSON **retjs return(*retjsonp); } -cJSON *electrum_transaction(char *symbol,struct electrum_info *ep,cJSON **retjsonp,bits256 txid,char *SPVcheck) +cJSON *electrum_transaction(int32_t *heightp,char *symbol,struct electrum_info *ep,cJSON **retjsonp,bits256 txid,char *SPVcheck) { - cJSON *retjson,*array; bits256 zero; struct LP_transaction *tx; struct iguana_info *coin; + cJSON *retjson,*array; bits256 zero; struct LP_transaction *tx=0; struct iguana_info *coin; coin = LP_coinfind(symbol); + *heightp = 0; if ( ep != 0 ) portable_mutex_lock(&ep->txmutex); retjson = _electrum_transaction(symbol,ep,retjsonp,txid); - if ( ep != 0 && coin != 0 && SPVcheck != 0 && SPVcheck[0] != 0 && (tx= LP_transactionfind(coin,txid)) != 0 ) + if ( (tx= LP_transactionfind(coin,txid)) != 0 && ep != 0 && coin != 0 && SPVcheck != 0 && SPVcheck[0] != 0 ) { if ( tx->height <= 0 ) { @@ -763,9 +764,14 @@ cJSON *electrum_transaction(char *symbol,struct electrum_info *ep,cJSON **retjso } } if ( tx->height > 0 ) - tx->SPV = LP_merkleproof(coin,SPVcheck,ep,txid,tx->height); + { + if ( tx->SPV == 0 ) + tx->SPV = LP_merkleproof(coin,SPVcheck,ep,txid,tx->height); + *heightp = tx->height; + } char str[65]; printf("%s %s %s SPV height %d SPV %d\n",coin->symbol,SPVcheck,bits256_str(str,txid),tx->height,tx->SPV); - } + } else if ( tx != 0 ) + *heightp = tx->height; if ( ep != 0 ) portable_mutex_unlock(&ep->txmutex); return(retjson); @@ -782,7 +788,7 @@ cJSON *electrum_getmerkle(char *symbol,struct electrum_info *ep,cJSON **retjsonp void electrum_test() { - cJSON *retjson; bits256 hash,zero; struct electrum_info *ep = 0; char *addr,*script,*symbol = "BTC"; + cJSON *retjson; int32_t height; bits256 hash,zero; struct electrum_info *ep = 0; char *addr,*script,*symbol = "BTC"; while ( Num_electrums == 0 ) { sleep(1); @@ -808,7 +814,7 @@ void electrum_test() decode_hex(hash.bytes,sizeof(hash),"b967a7d55889fe11e993430921574ec6379bc8ce712a652c3fcb66c6be6e925c"); if ( (retjson= electrum_getmerkle(symbol,ep,0,hash,403000)) != 0 ) printf("electrum_getmerkle %s\n",jprint(retjson,1)); - if ( (retjson= electrum_transaction(symbol,ep,0,hash,0)) != 0 ) + if ( (retjson= electrum_transaction(&height,symbol,ep,0,hash,0)) != 0 ) printf("electrum_transaction %s\n",jprint(retjson,1)); addr = "14NeevLME8UAANiTCVNgvDrynUPk1VcQKb"; if ( (retjson= electrum_address_gethistory(symbol,ep,0,addr,zero)) != 0 ) diff --git a/iguana/exchanges/LP_stats.c b/iguana/exchanges/LP_stats.c index e460c1c6c..06d072285 100644 --- a/iguana/exchanges/LP_stats.c +++ b/iguana/exchanges/LP_stats.c @@ -24,9 +24,78 @@ struct LP_swapstats *LP_swapstats,*LP_RTstats; int32_t LP_statslog_parsequote(char *method,cJSON *lineobj); char *LP_stats_methods[] = { "unknown", "request", "reserved", "connect", "connected", "tradestatus" }; +#define LP_TRADESTATUS_METHODIND 5 static uint32_t LP_requests,LP_reserveds,LP_connects,LP_connecteds,LP_tradestatuses,LP_parse_errors,LP_unknowns,LP_duplicates,LP_aliceids; +void LP_dPoW_request(struct iguana_info *coin) +{ + bits256 zero; cJSON *reqjson; + reqjson = cJSON_CreateObject(); + jaddstr(reqjson,"method","getdPoW"); + jaddstr(reqjson,"coin",coin->symbol); + memset(zero.bytes,0,sizeof(zero)); + //printf("request %s\n",jprint(reqjson,0)); + LP_reserved_msg(0,coin->symbol,coin->symbol,zero,jprint(reqjson,1)); +} + +void LP_dPoW_broadcast(struct iguana_info *coin) +{ + bits256 zero; cJSON *reqjson; + if ( time(NULL) > coin->dPoWtime+60 && (coin->isassetchain != 0 || strcmp(coin->symbol,"KMD") == 0) ) + { + reqjson = cJSON_CreateObject(); + jaddstr(reqjson,"method","dPoW"); + jaddstr(reqjson,"coin",coin->symbol); + jaddnum(reqjson,"notarized",coin->notarized); + jaddbits256(reqjson,"notarizedhash",coin->notarizedhash); + jaddbits256(reqjson,"notarizationtxid",coin->notarizationtxid); + memset(zero.bytes,0,sizeof(zero)); + //printf("broadcast %s\n",jprint(reqjson,0)); + LP_reserved_msg(0,coin->symbol,coin->symbol,zero,jprint(reqjson,1)); + coin->dPoWtime = (uint32_t)time(NULL); + } +} + +char *LP_dPoW_recv(cJSON *argjson) +{ + int32_t notarized; bits256 notarizedhash,notarizationtxid; char *symbol; struct iguana_info *coin; + if ( (symbol= jstr(argjson,"coin")) != 0 && (coin= LP_coinfind(symbol)) != 0 && coin->electrum != 0 ) + { + notarized = jint(argjson,"notarized"); + notarizedhash = jbits256(argjson,"notarizedhash"); + notarizationtxid = jbits256(argjson,"notarizationtxid"); + //printf("dPoW %s\n",jprint(argjson,0)); + if ( notarized > coin->notarized && LP_notarization_validate(symbol,notarized,notarizedhash,notarizationtxid) == 0 ) + { + coin->notarized = notarized; + coin->notarizedhash = notarizedhash; + coin->notarizationtxid = notarizationtxid; + printf("VALIDATED dPoW %s\n",jprint(argjson,0)); + } + } + return(clonestr("{\"result\":\"success\"}")); +} + +/*int32_t LP_dPoWheight(struct iguana_info *coin) // get dPoW protected height +{ + int32_t notarized,oldnotarized; + if ( coin->electrum == 0 ) + { + coin->heighttime = (uint32_t)(time(NULL) - 61); + oldnotarized = coin->notarized; + LP_getheight(¬arized,coin); + if ( notarized != 0 && notarized != oldnotarized ) + { + printf("dPoWheight.%s %d <- %d\n",coin->symbol,oldnotarized,notarized); + coin->notarized = notarized; + } + } + else if ( coin->notarized == 0 ) + LP_dPoW_request(coin); + return(coin->notarized); +}*/ + void LP_tradecommand_log(cJSON *argjson) { static FILE *logfp; char *jsonstr; @@ -81,13 +150,14 @@ void LP_statslog_parseline(cJSON *lineobj) int32_t LP_statslog_parse() { - static long lastpos; FILE *fp; char line[8192]; cJSON *lineobj; int32_t n = 0; + static long lastpos; + FILE *fp; long fpos; char line[8192]; cJSON *lineobj; int32_t c,n = 0; if ( (fp= fopen(LP_STATSLOG_FNAME,"rb")) != 0 ) { if ( lastpos > 0 ) { fseek(fp,0,SEEK_END); - if ( ftell(fp) > lastpos ) + if ( ftell(fp) >= lastpos ) fseek(fp,lastpos,SEEK_SET); else { @@ -95,6 +165,20 @@ int32_t LP_statslog_parse() return(0); } } + else if ( 1 ) + { + if ( IAMLP == 0 ) + { + fseek(fp,0,SEEK_END); + if ( (fpos= ftell(fp)) > LP_CLIENT_STATSPARSE ) + { + fseek(fp,fpos-LP_CLIENT_STATSPARSE,SEEK_SET); + while ( (c= fgetc(fp)) >= 0 && c != '\n' ) + ; + printf("start scanning %s from %ld, found boundary %ld\n",LP_STATSLOG_FNAME,fpos-LP_CLIENT_STATSPARSE,ftell(fp)); + } else rewind(fp); + } + } while ( fgets(line,sizeof(line),fp) > 0 ) { lastpos = ftell(fp); @@ -197,7 +281,7 @@ int32_t LP_swapstats_update(struct LP_swapstats *sp,struct LP_quoteinfo *qp,cJSO } else { - if ( requestid == sp->Q.R.requestid && quoteid == sp->Q.R.quoteid ) + if ( 0 && requestid == sp->Q.R.requestid && quoteid == sp->Q.R.quoteid ) printf("mismatched tradestatus aliceid.%22llu b%s/%s r%s/%s r%u/%u q%u/%u %.8f/%.8f -> %.8f/%.8f\n",(long long)sp->aliceid,base,sp->Q.srccoin,rel,sp->Q.destcoin,requestid,sp->Q.R.requestid,quoteid,sp->Q.R.quoteid,dstr(satoshis+2*sp->Q.txfee),dstr(sp->Q.satoshis),dstr(destsatoshis+2*sp->Q.desttxfee),dstr(sp->Q.destsatoshis)); return(-1); } @@ -208,10 +292,136 @@ int32_t LP_swapstats_update(struct LP_swapstats *sp,struct LP_quoteinfo *qp,cJSO return(0); } +int32_t LP_finished_lastheight(struct LP_swapstats *sp) +{ + int32_t height = 1; struct iguana_info *bob,*alice; //char str[65]; + if ( (bob= LP_coinfind(sp->Q.srccoin)) != 0 && (alice= LP_coinfind(sp->Q.destcoin)) != 0 ) + { + if ( sp->bobneeds_dPoW != 0 ) + { + if ( bits256_nonz(sp->bobdeposit) != 0 && sp->bobdeposit_ht == 0 ) + { + if ( (sp->bobdeposit_ht= LP_txheight(bob,sp->bobdeposit)) > sp->bobneeds_dPoW ) + sp->bobneeds_dPoW = sp->bobdeposit_ht; + //printf("%s bobdeposit.%d height.%d\n",bits256_str(str,sp->bobdeposit),ht,sp->bobneeds_dPoW); + } + if ( bits256_nonz(sp->bobpayment) != 0 && sp->bobpayment_ht == 0 ) + { + if ( (sp->bobpayment_ht= LP_txheight(bob,sp->bobpayment)) > sp->bobneeds_dPoW ) + sp->bobneeds_dPoW = sp->bobpayment_ht; + //printf("%s bobpayment.%d height.%d\n",bits256_str(str,sp->bobpayment),ht,sp->bobneeds_dPoW); + } + if ( bits256_nonz(sp->paymentspent) != 0 && sp->paymentspent_ht == 0 ) + { + if ( (sp->paymentspent_ht= LP_txheight(bob,sp->paymentspent)) > sp->bobneeds_dPoW ) + sp->bobneeds_dPoW = sp->paymentspent_ht; + //printf("%s paymentspent.%d height.%d\n",bits256_str(str,sp->paymentspent),ht,sp->bobneeds_dPoW); + } + if ( bits256_nonz(sp->depositspent) != 0 && sp->depositspent_ht == 0 ) + { + if ( (sp->depositspent_ht= LP_txheight(bob,sp->depositspent)) > sp->bobneeds_dPoW ) + sp->bobneeds_dPoW = sp->depositspent_ht; + //printf("%s depositspent.%d height.%d\n",bits256_str(str,sp->depositspent),ht,sp->bobneeds_dPoW); + } + } + if ( sp->aliceneeds_dPoW != 0 ) + { + if ( bits256_nonz(sp->alicepayment) != 0 && sp->alicepayment_ht == 0 ) + { + if ( (sp->alicepayment_ht= LP_txheight(alice,sp->alicepayment)) > sp->aliceneeds_dPoW ) + sp->aliceneeds_dPoW = sp->alicepayment_ht; + //printf("%s alicepayment.%d height.%d\n",bits256_str(str,sp->alicepayment),ht,sp->aliceneeds_dPoW); + } + if ( bits256_nonz(sp->Apaymentspent) != 0 && sp->Apaymentspent_ht == 0 ) + { + if ( (sp->Apaymentspent_ht= LP_txheight(alice,sp->Apaymentspent)) > sp->aliceneeds_dPoW ) + sp->aliceneeds_dPoW = sp->Apaymentspent_ht; + //printf("%s Apaymentspent.%d height.%d\n",bits256_str(str,sp->Apaymentspent),ht,sp->aliceneeds_dPoW); + } + } + } + return(height); +} + +int32_t LP_swap_finished(struct LP_swapstats *sp,int32_t dPoWflag) +{ + struct iguana_info *bob,*alice; + if ( sp->dPoWfinished != 0 || sp->expired != 0 ) + return(1); + else if ( dPoWflag == 0 && sp->finished != 0 ) + return(1); + if ( (bob= LP_coinfind(sp->Q.srccoin)) == 0 ) + { + //printf("no bobcoin.%s\n",sp->Q.srccoin); + return(0); + } + if ( (alice= LP_coinfind(sp->Q.destcoin)) == 0 ) + { + //printf("no alicecoin.%s\n",sp->Q.destcoin); + return(0); + } + if ( dPoWflag != 0 ) + { + if ( sp->finished != 0 ) + { + LP_finished_lastheight(sp); + if ( 0 && IAMLP == 0 ) + printf("bob needs %d @ %d, alice needs %d @ %d\n",sp->bobneeds_dPoW,bob->notarized,sp->aliceneeds_dPoW,alice->notarized); + } + if ( (sp->bobneeds_dPoW == 0 || (sp->bobneeds_dPoW > 1 && bob->notarized >= sp->bobneeds_dPoW)) && (sp->aliceneeds_dPoW == 0 || (sp->aliceneeds_dPoW > 1 && alice->notarized >= sp->aliceneeds_dPoW)) ) + { + sp->dPoWfinished = (uint32_t)time(NULL); + return(1); + } + } + return(0); +} + +struct LP_swapstats *LP_swapstats_create(uint64_t aliceid,int32_t RTflag,struct LP_quoteinfo *qp,double qprice,int32_t methodind) +{ + struct LP_pubswap *ptr; struct iguana_info *alice,*bob; struct LP_pubkey_info *pubp; char *base,*rel; struct LP_swapstats *sp = 0; + base = qp->srccoin, rel = qp->destcoin; + if ( (sp= LP_swapstats_add(aliceid,RTflag)) != 0 ) + { + sp->Q = *qp; + sp->qprice = qprice; + sp->methodind = methodind; + sp->ind = LP_aliceids++; + sp->lasttime = (uint32_t)time(NULL); + if ( sp->lasttime > sp->Q.timestamp+LP_atomic_locktime(base,rel)*2 ) + sp->expired = sp->lasttime; + else + { + if ( (alice= LP_coinfind(rel)) != 0 && (alice->isassetchain != 0 || strcmp("KMD",alice->symbol) == 0) ) + sp->aliceneeds_dPoW = 1; + if ( (bob= LP_coinfind(rel)) != 0 && (bob->isassetchain != 0 || strcmp(bob->symbol,"KMD") == 0) ) + sp->bobneeds_dPoW = 1; + } + strcpy(sp->bobgui,"nogui"); + strcpy(sp->alicegui,"nogui"); + if ( LP_swap_finished(sp,1) == 0 ) //sp->finished == 0 && sp->expired == 0 ) + { + if ( (pubp= LP_pubkeyadd(qp->srchash)) != 0 ) + { + ptr = calloc(1,sizeof(*ptr)); + ptr->swap = sp; + DL_APPEND(pubp->bobswaps,ptr); + } + if ( (pubp= LP_pubkeyadd(qp->desthash)) != 0 ) + { + ptr = calloc(1,sizeof(*ptr)); + ptr->swap = sp; + DL_APPEND(pubp->aliceswaps,ptr); + } + } + } else printf("unexpected LP_swapstats_add failure\n"); + return(sp); +} + int32_t LP_statslog_parsequote(char *method,cJSON *lineobj) { static uint32_t unexpected; - struct LP_swapstats *sp,*tmp; struct LP_pubkey_info *pubp; struct LP_pubswap *ptr; double qprice; uint32_t requestid,quoteid,timestamp; int32_t i,RTflag,flag,numtrades[LP_MAXPRICEINFOS],methodind,destvout,feevout,duplicate=0; char *statusstr,*gui,*base,*rel; uint64_t aliceid,txfee,satoshis,destsatoshis; bits256 desttxid,feetxid; struct LP_quoteinfo Q; uint64_t basevols[LP_MAXPRICEINFOS],relvols[LP_MAXPRICEINFOS]; + struct LP_swapstats *sp,*tmp; double qprice; uint32_t requestid,quoteid,timestamp; int32_t i,RTflag,flag,numtrades[LP_MAXPRICEINFOS],methodind,destvout,feevout,duplicate=0; char *statusstr,*gui,*base,*rel; uint64_t aliceid,txfee,satoshis,destsatoshis; bits256 desttxid,feetxid; struct LP_quoteinfo Q; uint64_t basevols[LP_MAXPRICEINFOS],relvols[LP_MAXPRICEINFOS]; memset(numtrades,0,sizeof(numtrades)); memset(basevols,0,sizeof(basevols)); memset(relvols,0,sizeof(relvols)); @@ -306,32 +516,8 @@ int32_t LP_statslog_parsequote(char *method,cJSON *lineobj) } else { + sp = LP_swapstats_create(aliceid,RTflag,&Q,qprice,methodind); //printf("create aliceid.%llu\n",(long long)aliceid); - if ( (sp= LP_swapstats_add(aliceid,RTflag)) != 0 ) - { - sp->Q = Q; - sp->qprice = qprice; - sp->methodind = methodind; - sp->ind = LP_aliceids++; - sp->lasttime = (uint32_t)time(NULL); - strcpy(sp->bobgui,"nogui"); - strcpy(sp->alicegui,"nogui"); - if ( sp->finished == 0 && sp->expired == 0 ) - { - if ( (pubp= LP_pubkeyadd(sp->Q.srchash)) != 0 ) - { - ptr = calloc(1,sizeof(*ptr)); - ptr->swap = sp; - DL_APPEND(pubp->bobswaps,ptr); - } - if ( (pubp= LP_pubkeyadd(sp->Q.desthash)) != 0 ) - { - ptr = calloc(1,sizeof(*ptr)); - ptr->swap = sp; - DL_APPEND(pubp->aliceswaps,ptr); - } - } - } else printf("unexpected LP_swapstats_add failure\n"); } if ( sp != 0 ) { @@ -362,6 +548,20 @@ cJSON *LP_swapstats_json(struct LP_swapstats *sp) jaddnum(item,"quoteid",sp->Q.R.quoteid); jaddnum(item,"finished",sp->finished); jaddnum(item,"expired",sp->expired); + if ( bits256_nonz(sp->bobdeposit) != 0 ) + jaddbits256(item,"bobdeposit",sp->bobdeposit); + if ( bits256_nonz(sp->alicepayment) != 0 ) + jaddbits256(item,"alicepayment",sp->alicepayment); + if ( bits256_nonz(sp->bobpayment) != 0 ) + jaddbits256(item,"bobpayment",sp->bobpayment); + if ( bits256_nonz(sp->paymentspent) != 0 ) + jaddbits256(item,"paymentspent",sp->paymentspent); + if ( bits256_nonz(sp->Apaymentspent) != 0 ) + jaddbits256(item,"Apaymentspent",sp->Apaymentspent); + if ( bits256_nonz(sp->depositspent) != 0 ) + jaddbits256(item,"depositspent",sp->depositspent); + if ( sp->finished == 0 && sp->expired == 0 ) + jaddnum(item,"expires",sp->Q.timestamp + LP_atomic_locktime(sp->Q.srccoin,sp->Q.destcoin)*2 - time(NULL)); jaddnum(item,"ind",sp->methodind); //jaddstr(item,"line",line); return(item); @@ -369,10 +569,25 @@ cJSON *LP_swapstats_json(struct LP_swapstats *sp) char *LP_swapstatus_recv(cJSON *argjson) { - struct LP_swapstats *sp; int32_t methodind; - //printf("swapstatus.(%s)\n",jprint(argjson,0)); - if ( (sp= LP_swapstats_find(j64bits(argjson,"aliceid"))) != 0 ) + struct LP_swapstats *sp; char *statusstr; uint64_t aliceid; double qprice; struct LP_quoteinfo Q; int32_t methodind,RTflag; bits256 txid; //char str[65]; + if ( (aliceid= j64bits(argjson,"aliceid")) == 0 ) + return(clonestr("{\"error\":\"LP_swapstatus_recv null aliceid\"}")); + if ( (sp= LP_swapstats_find(aliceid)) == 0 ) { + LP_quoteparse(&Q,argjson); + if ( Q.satoshis > Q.txfee ) + return(clonestr("{\"error\":\"LP_swapstatus_recv null satoshis\"}")); + qprice = (double)Q.destsatoshis / (Q.satoshis - Q.txfee); + if ( (statusstr= jstr(argjson,"status")) != 0 && strcmp(statusstr,"finished") == 0 ) + RTflag = 0; + else RTflag = 1; + sp = LP_swapstats_create(aliceid,RTflag,&Q,qprice,LP_TRADESTATUS_METHODIND); + //printf("create swapstatus from recv\n"); + } + if ( sp != 0 ) + { + if ( 0 && IAMLP == 0 ) + printf("swapstatus.(%s)\n",jprint(argjson,0)); sp->lasttime = (uint32_t)time(NULL); if ( (methodind= jint(argjson,"ind")) > sp->methodind && methodind < sizeof(LP_stats_methods)/sizeof(*LP_stats_methods) ) { @@ -381,25 +596,87 @@ char *LP_swapstatus_recv(cJSON *argjson) sp->methodind = methodind; sp->finished = juint(argjson,"finished"); sp->expired = juint(argjson,"expired"); + txid = jbits256(argjson,"bobdeposit"); + if ( bits256_nonz(txid) != 0 && bits256_nonz(sp->bobdeposit) == 0 ) + { + sp->bobdeposit = txid; + //printf("set aliceid.%llu bobdeposit %s\n",(long long)sp->aliceid,bits256_str(str,txid)); + } + txid = jbits256(argjson,"alicepayment"); + if ( bits256_nonz(txid) != 0 && bits256_nonz(sp->alicepayment) == 0 ) + { + sp->alicepayment = txid; + //printf("set aliceid.%llu alicepayment %s\n",(long long)sp->aliceid,bits256_str(str,txid)); + } + txid = jbits256(argjson,"bobpayment"); + if ( bits256_nonz(txid) != 0 && bits256_nonz(sp->bobpayment) == 0 ) + { + sp->bobpayment = txid; + //printf("set aliceid.%llu bobpayment %s\n",(long long)sp->aliceid,bits256_str(str,txid)); + } + txid = jbits256(argjson,"paymentspent"); + if ( bits256_nonz(txid) != 0 && bits256_nonz(sp->paymentspent) == 0 ) + { + sp->paymentspent = txid; + //printf("set aliceid.%llu paymentspent %s\n",(long long)sp->aliceid,bits256_str(str,txid)); + } + txid = jbits256(argjson,"Apaymentspent"); + if ( bits256_nonz(txid) != 0 && bits256_nonz(sp->Apaymentspent) == 0 ) + { + sp->Apaymentspent = txid; + //printf("set aliceid.%llu Apaymentspent %s\n",(long long)sp->aliceid,bits256_str(str,txid)); + } + txid = jbits256(argjson,"depositspent"); + if ( bits256_nonz(txid) != 0 && bits256_nonz(sp->depositspent) == 0 ) + { + sp->depositspent = txid; + //printf("set aliceid.%llu depositspent %s\n",(long long)sp->aliceid,bits256_str(str,txid)); + } } } return(clonestr("{\"result\":\"success\"}")); } -char *LP_gettradestatus(uint64_t aliceid) +char *LP_gettradestatus(uint64_t aliceid,uint32_t requestid,uint32_t quoteid) { - struct LP_swapstats *sp; cJSON *reqjson; bits256 zero; + struct LP_swapstats *sp; struct iguana_info *bob,*alice; char *swapstr,*statusstr; cJSON *reqjson,*swapjson; bits256 zero; //printf("gettradestatus.(%llu)\n",(long long)aliceid); - if ( (sp= LP_swapstats_find(aliceid)) != 0 && time(NULL) > sp->lasttime+60 ) + if ( IAMLP != 0 ) + { + if ( (sp= LP_swapstats_find(aliceid)) != 0 ) + { + if ( time(NULL) > sp->lasttime+60 ) + { + if ( (reqjson= LP_swapstats_json(sp)) != 0 ) + { + jaddstr(reqjson,"method","swapstatus"); + memset(zero.bytes,0,sizeof(zero)); + LP_reserved_msg(0,"","",zero,jprint(reqjson,1)); + } + if ( (bob= LP_coinfind(sp->Q.srccoin)) != 0 ) + LP_dPoW_broadcast(bob); + if ( (alice= LP_coinfind(sp->Q.destcoin)) != 0 ) + LP_dPoW_broadcast(alice); + } + return(clonestr("{\"result\":\"success\"}")); + } + } + if ( (swapstr= basilisk_swapentry(requestid,quoteid,0)) != 0 ) { - if ( (reqjson= LP_swapstats_json(sp)) != 0 ) + if ( (swapjson= cJSON_Parse(swapstr)) != 0 ) { - jaddstr(reqjson,"method","swapstatus"); - memset(zero.bytes,0,sizeof(zero)); - LP_reserved_msg(0,"","",zero,jprint(reqjson,1)); + if ( (statusstr= jstr(swapjson,"status")) != 0 && strcmp(statusstr,"finished") == 0 ) + { + jaddstr(swapjson,"method","swapstatus"); + memset(zero.bytes,0,sizeof(zero)); + printf("send local swapstatus\n"); + LP_reserved_msg(0,"","",zero,jprint(swapjson,0)); + } + free_json(swapjson); } + free(swapstr); } - return(clonestr("{\"error\":\"cant find aliceid\"}")); + return(clonestr("{\"result\":\"success\"}")); } int32_t LP_stats_dispiter(cJSON *array,struct LP_swapstats *sp,uint32_t starttime,uint32_t endtime,char *refbase,char *refrel,char *refgui,bits256 refpubkey) @@ -407,7 +684,7 @@ int32_t LP_stats_dispiter(cJSON *array,struct LP_swapstats *sp,uint32_t starttim int32_t dispflag,retval = 0; if ( sp->finished == 0 && sp->expired == 0 && time(NULL) > sp->Q.timestamp+LP_atomic_locktime(sp->Q.srccoin,sp->Q.destcoin)*2 ) sp->expired = (uint32_t)time(NULL); - if ( sp->finished != 0 || sp->expired != 0 ) + if ( LP_swap_finished(sp,1) > 0 ) retval = 1; dispflag = 0; if ( starttime == 0 && endtime == 0 ) diff --git a/iguana/exchanges/LP_swap.c b/iguana/exchanges/LP_swap.c index fe905c424..d03cfa668 100644 --- a/iguana/exchanges/LP_swap.c +++ b/iguana/exchanges/LP_swap.c @@ -751,7 +751,7 @@ int32_t LP_swapwait(struct basilisk_swap *swap,uint32_t requestid,uint32_t quote // sleeptime = divisor * 60; while ( time(NULL) < expiration ) { - if ( (retstr= basilisk_swapentry(requestid,quoteid)) != 0 ) + if ( (retstr= basilisk_swapentry(requestid,quoteid,1)) != 0 ) { if ( (retjson= cJSON_Parse(retstr)) != 0 ) { @@ -775,7 +775,7 @@ int32_t LP_swapwait(struct basilisk_swap *swap,uint32_t requestid,uint32_t quote { printf("\n>>>>>>>>>>>>>>>>>>>>>>>>>\nSWAP completed! %u-%u %s\n",requestid,quoteid,jprint(retjson,0)); free_json(retjson); - if ( 0 && (retstr= basilisk_swapentry(requestid,quoteid)) != 0 ) + if ( 0 && (retstr= basilisk_swapentry(requestid,quoteid,1)) != 0 ) { printf("second call.(%s)\n",retstr); free(retstr); diff --git a/iguana/exchanges/LP_tradebots.c b/iguana/exchanges/LP_tradebots.c index 7f3742304..c5f0d7d6f 100644 --- a/iguana/exchanges/LP_tradebots.c +++ b/iguana/exchanges/LP_tradebots.c @@ -43,7 +43,7 @@ struct LP_tradebot void LP_tradebot_updatestats(struct LP_tradebot *bot,struct LP_tradebot_trade *tp) { char *swapstr,*status; int32_t flag; cJSON *swapjson; - if ( (swapstr= basilisk_swapentry(tp->requestid,tp->quoteid)) != 0 ) + if ( (swapstr= basilisk_swapentry(tp->requestid,tp->quoteid,1)) != 0 ) { flag = 0; if ( (swapjson= cJSON_Parse(swapstr)) != 0 ) diff --git a/iguana/exchanges/LP_utxo.c b/iguana/exchanges/LP_utxo.c index 9d48e6ba5..890577df0 100644 --- a/iguana/exchanges/LP_utxo.c +++ b/iguana/exchanges/LP_utxo.c @@ -495,13 +495,13 @@ struct LP_address *LP_address_utxo_reset(struct iguana_info *coin) cJSON *LP_address_item(struct iguana_info *coin,struct LP_address_utxo *up,int32_t electrumret) { - cJSON *item = cJSON_CreateObject(); + int32_t notarized; cJSON *item = cJSON_CreateObject(); if ( electrumret == 0 ) { jaddbits256(item,"txid",up->U.txid); jaddnum(item,"vout",up->U.vout); if ( up->U.height > 0 ) - jaddnum(item,"confirmations",LP_getheight(coin) - up->U.height + 1); + jaddnum(item,"confirmations",LP_getheight(¬arized,coin) - up->U.height + 1); jaddnum(item,"amount",dstr(up->U.value)); jaddstr(item,"scriptPubKey",""); } @@ -620,7 +620,10 @@ cJSON *LP_address_balance(struct iguana_info *coin,char *coinaddr,int32_t electr jaddstr(retjson,"address",coinaddr); jaddnum(retjson,"balance",dstr(balance)); if ( strcmp(coin->symbol,"KMD") == 0 && strcmp(coin->smartaddr,coinaddr) == 0 ) + { jaddnum(retjson,"zcredits",dstr(LP_myzcredits())); + jadd(retjson,"zdebits",LP_myzdebits()); + } return(retjson); } @@ -763,7 +766,7 @@ cJSON *LP_transactioninit(struct iguana_info *coin,bits256 txid,int32_t iter,cJS int32_t LP_txheight(struct iguana_info *coin,bits256 txid) { - bits256 blockhash; struct LP_transaction *tx; cJSON *blockobj,*txobj; int32_t height = 0; + bits256 blockhash; struct LP_transaction *tx; cJSON *blockobj,*retjson,*txobj; int32_t height = 0; if ( coin == 0 ) return(-1); if ( coin->electrum == 0 ) @@ -788,13 +791,23 @@ int32_t LP_txheight(struct iguana_info *coin,bits256 txid) { if ( (tx= LP_transactionfind(coin,txid)) != 0 ) height = tx->height; + if ( height == 0 ) + { + if ( (retjson= electrum_transaction(&height,coin->symbol,coin->electrum,&retjson,txid,0)) != 0 ) + { + //printf("process %s\n",jprint(retjson,0)); + free_json(retjson); + } + if ( (tx= LP_transactionfind(coin,txid)) != 0 ) + height = tx->height; + } } return(height); } int32_t LP_numconfirms(char *symbol,char *coinaddr,bits256 txid,int32_t vout,int32_t mempool) { - struct iguana_info *coin; bits256 zero; int32_t ht,numconfirms = 100; + struct iguana_info *coin; bits256 zero; int32_t ht,notarized,numconfirms = 100; cJSON *txobj; if ( (coin= LP_coinfind(symbol)) == 0 || coin->inactive != 0 ) return(-1); @@ -819,7 +832,7 @@ int32_t LP_numconfirms(char *symbol,char *coinaddr,bits256 txid,int32_t vout,int memset(zero.bytes,0,sizeof(zero)); LP_listunspent_issue(symbol,coinaddr,1,txid,zero); if ( (ht= LP_txheight(coin,txid)) > 0 && ht <= coin->height ) - numconfirms = (LP_getheight(coin) - ht + 1); + numconfirms = (LP_getheight(¬arized,coin) - ht + 1); else if ( mempool != 0 ) { if ( LP_waitmempool(symbol,coinaddr,txid,vout,30) >= 0 ) diff --git a/iguana/exchanges/mm.c b/iguana/exchanges/mm.c index f4d147131..ec3aba913 100644 --- a/iguana/exchanges/mm.c +++ b/iguana/exchanges/mm.c @@ -20,7 +20,6 @@ // - void PNACL_message(char *arg,...) { diff --git a/iguana/exchanges/stats.c b/iguana/exchanges/stats.c index 69d6435ab..abb7b785d 100644 --- a/iguana/exchanges/stats.c +++ b/iguana/exchanges/stats.c @@ -33,7 +33,7 @@ char *stats_JSON(void *ctx,char *myipaddr,int32_t mypubsock,cJSON *argjson,char char *stats_validmethods[] = { "psock", "getprices", "notify", "getpeers", // from issue_ "uitem", "listunspent", - "orderbook", "help", "getcoins", "pricearray", "balance", "tradesarray" + "orderbook", "statsdisp", "help", "getcoins", "pricearray", "balance", "tradesarray" }; int32_t LP_valid_remotemethod(cJSON *argjson) diff --git a/iguana/m_notary b/iguana/m_notary index c88989065..0d4d9a9c4 100755 --- a/iguana/m_notary +++ b/iguana/m_notary @@ -2,51 +2,4 @@ pkill -15 iguana rm -f ../agents/iguana *.o git pull -cd secp256k1; ./m_unix; cd .. -cd ../crypto777; ./m_LP; cd ../iguana -#gcc -g -fno-aggressive-loop-optimizations -Wno-deprecated -c -O2 -DISNOTARYNODE=1 -DLIQUIDITY_PROVIDER=1 *.c ../basilisk/basilisk.c ../gecko/gecko.c ../datachain/datachain.c -clang -g -Wno-deprecated -c -O2 -DISNOTARYNODE=1 -DLIQUIDITY_PROVIDER=1 *.c ../basilisk/basilisk.c ../gecko/gecko.c ../datachain/datachain.c -#gcc -g -fno-aggressive-loop-optimizations -Wno-deprecated -c -DISNOTARYNODE=1 -DLIQUIDITY_PROVIDER=1 main.c iguana777.c iguana_bundles.c ../basilisk/basilisk.c -clang -g -Wno-deprecated -c -DISNOTARYNODE=1 -DLIQUIDITY_PROVIDER=1 main.c iguana777.c iguana_bundles.c ../basilisk/basilisk.c -clang -g -o ../agents/iguana *.o ../agents/libcrypto777.a -lnanomsg -lcurl -lssl -lcrypto -lpthread -lz -lm - -../agents/iguana notary & #> iguana.log 2> error.log & - -myip=`curl -s4 checkip.amazonaws.com` -source pubkey.txt - -sleep 4 -curl --url "http://127.0.0.1:7776" --data "{\"agent\":\"SuperNET\",\"method\":\"myipaddr\",\"ipaddr\":\"$myip\"}" -sleep 3 -tests/addnotarys_7776 -coins/btc_7776 -coins/ltc_7776 -coins/kmd_7776 -coins/chips_7776 -./wp_7776 - -coins/revs_7776 -coins/supernet_7776 -coins/dex_7776 -coins/bet_7776 -coins/bots_7776 -coins/hodl_7776 -coins/shark_7776 -coins/mshark_7776 -coins/jumblr_7776 -coins/crypto_7776 -coins/pangea_7776 -coins/mgw_7776 -#coins/mvp_7776 -coins/coqui_7776 -coins/wlc_7776 -coins/kv_7776 -coins/ceal_7776 -coins/mesh_7776 -coins/mnz_7776 -curl --url "http://127.0.0.1:7776" --data "{\"agent\":\"passthru\",\"method\":\"paxfiats\",\"timeout\":900000}" - -#curl --url "http://127.0.0.1:7776" --data "{\"agent\":\"iguana\",\"method\":\"addnotary\",\"ipaddr\":\"$myip\"}" -curl --url "http://127.0.0.1:7776" --data "{\"agent\":\"iguana\",\"method\":\"dpow\",\"symbol\":\"KMD\",\"pubkey\":\"$pubkey\"}" - -sleep 17 +./m_notary_run diff --git a/iguana/m_notary_run b/iguana/m_notary_run new file mode 100755 index 000000000..4c64de6ff --- /dev/null +++ b/iguana/m_notary_run @@ -0,0 +1,47 @@ +#!/bin/bash + +cd secp256k1; ./m_unix; cd .. +cd ../crypto777; ./m_LP; cd ../iguana +#gcc -g -fno-aggressive-loop-optimizations -Wno-deprecated -c -O2 -DISNOTARYNODE=1 -DLIQUIDITY_PROVIDER=1 *.c ../basilisk/basilisk.c ../gecko/gecko.c ../datachain/datachain.c +clang -g -Wno-deprecated -c -O2 -DISNOTARYNODE=1 -DLIQUIDITY_PROVIDER=1 *.c ../basilisk/basilisk.c ../gecko/gecko.c ../datachain/datachain.c +#gcc -g -fno-aggressive-loop-optimizations -Wno-deprecated -c -DISNOTARYNODE=1 -DLIQUIDITY_PROVIDER=1 main.c iguana777.c iguana_bundles.c ../basilisk/basilisk.c +clang -g -Wno-deprecated -c -DISNOTARYNODE=1 -DLIQUIDITY_PROVIDER=1 main.c iguana777.c iguana_bundles.c ../basilisk/basilisk.c +clang -g -o ../agents/iguana *.o ../agents/libcrypto777.a -lnanomsg -lcurl -lssl -lcrypto -lpthread -lz -lm + +../agents/iguana notary & #> iguana.log 2> error.log & + +myip=`curl -s4 checkip.amazonaws.com` +source pubkey.txt + +sleep 4 +curl --url "http://127.0.0.1:7776" --data "{\"agent\":\"SuperNET\",\"method\":\"myipaddr\",\"ipaddr\":\"$myip\"}" +sleep 3 +tests/addnotarys_7776 +coins/btc_7776 +coins/ltc_7776 +coins/kmd_7776 +coins/chips_7776 +./wp_7776 + +coins/revs_7776 +coins/supernet_7776 +coins/dex_7776 +coins/bet_7776 +coins/bots_7776 +coins/hodl_7776 +coins/shark_7776 +coins/mshark_7776 +coins/jumblr_7776 +coins/crypto_7776 +coins/pangea_7776 +coins/mgw_7776 +coins/coqui_7776 +coins/wlc_7776 +coins/kv_7776 +coins/ceal_7776 +coins/mesh_7776 +coins/mnz_7776 +#curl --url "http://127.0.0.1:7776" --data "{\"agent\":\"passthru\",\"method\":\"paxfiats\",\"timeout\":900000}" + +#curl --url "http://127.0.0.1:7776" --data "{\"agent\":\"iguana\",\"method\":\"addnotary\",\"ipaddr\":\"$myip\"}" +curl --url "http://127.0.0.1:7776" --data "{\"agent\":\"iguana\",\"method\":\"dpow\",\"symbol\":\"KMD\",\"pubkey\":\"$pubkey\"}"