From 5941868628a5d7bdfeb9be5ccc1913e218f3227c Mon Sep 17 00:00:00 2001 From: jl777 Date: Tue, 31 Oct 2017 11:58:52 +0200 Subject: [PATCH 0001/1664] Test --- iguana/exchanges/DB/PRICES/.tmpmarker | 0 iguana/exchanges/LP_nativeDEX.c | 3 ++- iguana/exchanges/LP_rpc.c | 34 +++++++++++++++++++++++++-- 3 files changed, 34 insertions(+), 3 deletions(-) create mode 100644 iguana/exchanges/DB/PRICES/.tmpmarker diff --git a/iguana/exchanges/DB/PRICES/.tmpmarker b/iguana/exchanges/DB/PRICES/.tmpmarker new file mode 100644 index 000000000..e69de29bb diff --git a/iguana/exchanges/LP_nativeDEX.c b/iguana/exchanges/LP_nativeDEX.c index 395866af8..e82caf3a4 100644 --- a/iguana/exchanges/LP_nativeDEX.c +++ b/iguana/exchanges/LP_nativeDEX.c @@ -18,9 +18,10 @@ // LP_nativeDEX.c // marketmaker // -// verify portfolio, interest to KMD withdraw, pricebroadcast loop +// verify portfolio, interest to KMD withdraw // dPoW security -> 4: KMD notarized, 5: BTC notarized, after next notary elections // bigendian architectures need to use little endian for sighash calcs +// BCH signing #include #include "LP_include.h" diff --git a/iguana/exchanges/LP_rpc.c b/iguana/exchanges/LP_rpc.c index eb0dab1e2..2ac79a5c5 100644 --- a/iguana/exchanges/LP_rpc.c +++ b/iguana/exchanges/LP_rpc.c @@ -220,11 +220,32 @@ cJSON *LP_NXT_message(char *method,uint64_t txnum,char *passphrase) return(retjson); } +cJSON *LP_NXT_decrypt(char *account,char *data,char *nonce,char *passphrase) +{ + char url[1024],*retstr; cJSON *retjson = 0; + if ( account != 0 && data != 0 && nonce != 0 && passphrase != 0 ) + { + sprintf(url,"http://127.0.0.1:7876/nxt?requestType=decryptFrom&account=%s&secretPhrase=%s&data=%s&nonce=%s",account,passphrase,data,nonce); + //printf("issue.(%s)\n",url); + if ( (retstr= issue_curlt(url,LP_HTTP_TIMEOUT)) != 0 ) + { + if ( (retjson= cJSON_Parse(retstr)) != 0 ) + { + + } + free(retstr); + } + } + return(retjson); +} + cJSON *LP_NXT_redeems() { - char url[1024],*retstr,*recv,*method,*msgstr,assetname[16]; uint64_t totals[20],mult,txnum,assetid,qty; int32_t i,ind,numtx; cJSON *item,*attach,*array,*msgjson,*encjson,*retjson=0; + char url[1024],*retstr,*recv,*method,*msgstr,assetname[16]; uint64_t totals[20],mult,txnum,assetid,qty; int32_t i,ind,numtx; cJSON *item,*attach,*decjson,*array,*msgjson,*encjson,*retjson=0; +char *passphrase = ""; +char *account = "NXT-MRBN-8DFH-PFMK-A4DBM"; memset(totals,0,sizeof(totals)); - sprintf(url,"http://127.0.0.1:7876/nxt?requestType=getBlockchainTransactions&account=NXT-MRBN-8DFH-PFMK-A4DBM");//,NXTnodes[rand() % (sizeof(NXTnodes)/sizeof(*NXTnodes))]); + sprintf(url,"http://127.0.0.1:7876/nxt?requestType=getBlockchainTransactions&account=%s",account); //printf("calling (%s)\n",url); if ( (retstr= issue_curlt(url,LP_HTTP_TIMEOUT)) != 0 ) { @@ -260,8 +281,17 @@ cJSON *LP_NXT_redeems() msgstr = jstr(attach,"message"); if ( msgstr == 0 || msgstr[0] == 0 ) { + if ( (encjson= jobj(attach,"encryptedMessage")) != 0 ) + { msgstr = "encryptedMessage";//jstr(encjson,"data"); + if ( (decjson= LP_NXT_decrypt(account,jstr(encjson,"data"),jstr(encjson,"nonce"),passphrase)) != 0 ) + { + printf("%s\n",jprint(decjson,0)); + free_json(decjson); + } + + } } } mult = LP_assetid_mult(&ind,assetname,assetid); From cd2766143dbad2001867cffa284a8bf9cc9575c6 Mon Sep 17 00:00:00 2001 From: jl777 Date: Tue, 31 Oct 2017 12:26:24 +0200 Subject: [PATCH 0002/1664] Test --- iguana/exchanges/LP_rpc.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/iguana/exchanges/LP_rpc.c b/iguana/exchanges/LP_rpc.c index 2ac79a5c5..0e71e62be 100644 --- a/iguana/exchanges/LP_rpc.c +++ b/iguana/exchanges/LP_rpc.c @@ -225,6 +225,9 @@ cJSON *LP_NXT_decrypt(char *account,char *data,char *nonce,char *passphrase) char url[1024],*retstr; cJSON *retjson = 0; if ( account != 0 && data != 0 && nonce != 0 && passphrase != 0 ) { + sprintf(url,"http://127.0.0.1:7876/nxt?requestType=getAccountId&secretPhrase=%s",passphrase); + if ( (retstr= issue_curlt(url,LP_HTTP_TIMEOUT)) != 0 ) + printf("%s\n",retstr); sprintf(url,"http://127.0.0.1:7876/nxt?requestType=decryptFrom&account=%s&secretPhrase=%s&data=%s&nonce=%s",account,passphrase,data,nonce); //printf("issue.(%s)\n",url); if ( (retstr= issue_curlt(url,LP_HTTP_TIMEOUT)) != 0 ) From 122170f3042a1b8c7d3bd30506ad1b7876a812e9 Mon Sep 17 00:00:00 2001 From: jl777 Date: Tue, 31 Oct 2017 12:30:20 +0200 Subject: [PATCH 0003/1664] Test --- iguana/exchanges/LP_rpc.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/iguana/exchanges/LP_rpc.c b/iguana/exchanges/LP_rpc.c index 0e71e62be..5194b40f6 100644 --- a/iguana/exchanges/LP_rpc.c +++ b/iguana/exchanges/LP_rpc.c @@ -220,12 +220,13 @@ cJSON *LP_NXT_message(char *method,uint64_t txnum,char *passphrase) return(retjson); } -cJSON *LP_NXT_decrypt(char *account,char *data,char *nonce,char *passphrase) +cJSON *LP_NXT_decrypt(uint64_t txnum,char *account,char *data,char *nonce,char *passphrase) { char url[1024],*retstr; cJSON *retjson = 0; if ( account != 0 && data != 0 && nonce != 0 && passphrase != 0 ) { sprintf(url,"http://127.0.0.1:7876/nxt?requestType=getAccountId&secretPhrase=%s",passphrase); + sprintf(url,"http://127.0.0.1:7876/nxt?requestType=readMessage&transaction=%llu&secretPhrase=%s",(long long)txnum,passphrase); if ( (retstr= issue_curlt(url,LP_HTTP_TIMEOUT)) != 0 ) printf("%s\n",retstr); sprintf(url,"http://127.0.0.1:7876/nxt?requestType=decryptFrom&account=%s&secretPhrase=%s&data=%s&nonce=%s",account,passphrase,data,nonce); @@ -288,7 +289,7 @@ char *account = "NXT-MRBN-8DFH-PFMK-A4DBM"; if ( (encjson= jobj(attach,"encryptedMessage")) != 0 ) { msgstr = "encryptedMessage";//jstr(encjson,"data"); - if ( (decjson= LP_NXT_decrypt(account,jstr(encjson,"data"),jstr(encjson,"nonce"),passphrase)) != 0 ) + if ( (decjson= LP_NXT_decrypt(txnum,account,jstr(encjson,"data"),jstr(encjson,"nonce"),passphrase)) != 0 ) { printf("%s\n",jprint(decjson,0)); free_json(decjson); From 1ca484597af9422b42ec27bf7b1c82b19365a6aa Mon Sep 17 00:00:00 2001 From: jl777 Date: Tue, 31 Oct 2017 12:33:44 +0200 Subject: [PATCH 0004/1664] Test --- iguana/exchanges/LP_rpc.c | 18 +++++++++++------- 1 file changed, 11 insertions(+), 7 deletions(-) diff --git a/iguana/exchanges/LP_rpc.c b/iguana/exchanges/LP_rpc.c index 5194b40f6..528675f75 100644 --- a/iguana/exchanges/LP_rpc.c +++ b/iguana/exchanges/LP_rpc.c @@ -225,11 +225,11 @@ cJSON *LP_NXT_decrypt(uint64_t txnum,char *account,char *data,char *nonce,char * char url[1024],*retstr; cJSON *retjson = 0; if ( account != 0 && data != 0 && nonce != 0 && passphrase != 0 ) { - sprintf(url,"http://127.0.0.1:7876/nxt?requestType=getAccountId&secretPhrase=%s",passphrase); + //sprintf(url,"http://127.0.0.1:7876/nxt?requestType=getAccountId&secretPhrase=%s",passphrase); sprintf(url,"http://127.0.0.1:7876/nxt?requestType=readMessage&transaction=%llu&secretPhrase=%s",(long long)txnum,passphrase); - if ( (retstr= issue_curlt(url,LP_HTTP_TIMEOUT)) != 0 ) + //if ( (retstr= issue_curlt(url,LP_HTTP_TIMEOUT)) != 0 ) printf("%s\n",retstr); - sprintf(url,"http://127.0.0.1:7876/nxt?requestType=decryptFrom&account=%s&secretPhrase=%s&data=%s&nonce=%s",account,passphrase,data,nonce); + //sprintf(url,"http://127.0.0.1:7876/nxt?requestType=decryptFrom&account=%s&secretPhrase=%s&data=%s&nonce=%s",account,passphrase,data,nonce); //printf("issue.(%s)\n",url); if ( (retstr= issue_curlt(url,LP_HTTP_TIMEOUT)) != 0 ) { @@ -259,7 +259,7 @@ char *account = "NXT-MRBN-8DFH-PFMK-A4DBM"; { for (i=0; i= 0 ) totals[ind] += qty * mult; if ( msgstr != 0 && assetname[0] != 0 && qty != 0 ) - printf("%-4d: (%35s) <- %13.5f %10s tx.%llu\n",i,msgstr!=0?msgstr:jprint(item,0),dstr(qty * mult),assetname,(long long)txnum); + printf("%-4d: (%34s) <- %13.5f %10s tx.%llu\n",i,msgstr!=0?msgstr:jprint(item,0),dstr(qty * mult),assetname,(long long)txnum); if ( msgjson != 0 ) free_json(msgjson); + if ( encjson != 0 ) + free_json(encjson); + if ( decjson != 0 ) + free_json(decjson); } if ( txnum == calc_nxt64bits("7256847492742571143") ) break; From f9c0d9b89788c92a76cc23880f930bdc65dcb4ed Mon Sep 17 00:00:00 2001 From: jl777 Date: Tue, 31 Oct 2017 13:22:38 +0200 Subject: [PATCH 0005/1664] Test --- iguana/exchanges/LP_rpc.c | 14 +++++--------- 1 file changed, 5 insertions(+), 9 deletions(-) diff --git a/iguana/exchanges/LP_rpc.c b/iguana/exchanges/LP_rpc.c index 528675f75..67c347c6a 100644 --- a/iguana/exchanges/LP_rpc.c +++ b/iguana/exchanges/LP_rpc.c @@ -225,12 +225,7 @@ cJSON *LP_NXT_decrypt(uint64_t txnum,char *account,char *data,char *nonce,char * char url[1024],*retstr; cJSON *retjson = 0; if ( account != 0 && data != 0 && nonce != 0 && passphrase != 0 ) { - //sprintf(url,"http://127.0.0.1:7876/nxt?requestType=getAccountId&secretPhrase=%s",passphrase); sprintf(url,"http://127.0.0.1:7876/nxt?requestType=readMessage&transaction=%llu&secretPhrase=%s",(long long)txnum,passphrase); - //if ( (retstr= issue_curlt(url,LP_HTTP_TIMEOUT)) != 0 ) - printf("%s\n",retstr); - //sprintf(url,"http://127.0.0.1:7876/nxt?requestType=decryptFrom&account=%s&secretPhrase=%s&data=%s&nonce=%s",account,passphrase,data,nonce); - //printf("issue.(%s)\n",url); if ( (retstr= issue_curlt(url,LP_HTTP_TIMEOUT)) != 0 ) { if ( (retjson= cJSON_Parse(retstr)) != 0 ) @@ -302,11 +297,12 @@ char *account = "NXT-MRBN-8DFH-PFMK-A4DBM"; if ( ind >= 0 ) totals[ind] += qty * mult; if ( msgstr != 0 && assetname[0] != 0 && qty != 0 ) - printf("%-4d: (%34s) <- %13.5f %10s tx.%llu\n",i,msgstr!=0?msgstr:jprint(item,0),dstr(qty * mult),assetname,(long long)txnum); + { + // extract valid address + printf("%-4d: (%34s) <- %13.5f %10s tx.%llu\n",i,msgstr!=0?msgstr:jprint(item,0),dstr(qty * mult),assetname,(long long)txnum); + } if ( msgjson != 0 ) free_json(msgjson); - if ( encjson != 0 ) - free_json(encjson); if ( decjson != 0 ) free_json(decjson); } @@ -314,7 +310,7 @@ char *account = "NXT-MRBN-8DFH-PFMK-A4DBM"; break; } } - free_json(retjson); + //free_json(retjson); } free(retstr); } From 7160bd0b1caef999f18b77c0e71564cc2d739707 Mon Sep 17 00:00:00 2001 From: jl777 Date: Tue, 31 Oct 2017 13:29:01 +0200 Subject: [PATCH 0006/1664] Test --- iguana/exchanges/LP_rpc.c | 28 ++++++++++++++++++++++++---- 1 file changed, 24 insertions(+), 4 deletions(-) diff --git a/iguana/exchanges/LP_rpc.c b/iguana/exchanges/LP_rpc.c index 67c347c6a..24d2cb5f2 100644 --- a/iguana/exchanges/LP_rpc.c +++ b/iguana/exchanges/LP_rpc.c @@ -240,7 +240,9 @@ cJSON *LP_NXT_decrypt(uint64_t txnum,char *account,char *data,char *nonce,char * cJSON *LP_NXT_redeems() { - char url[1024],*retstr,*recv,*method,*msgstr,assetname[16]; uint64_t totals[20],mult,txnum,assetid,qty; int32_t i,ind,numtx; cJSON *item,*attach,*decjson,*array,*msgjson,*encjson,*retjson=0; + char url[1024],*retstr,*recv,*method,*msgstr,assetname[16]; uint64_t totals[20],mult,txnum,assetid,qty; int32_t i,ind,numtx,past_marker=0; cJSON *item,*attach,*decjson,*array,*msgjson,*encjson,*retjson=0; + uint64_t txnum_marker = calc_nxt64bits("0"); + uint64_t txnum_marker2 = calc_nxt64bits("7256847492742571143"); char *passphrase = ""; char *account = "NXT-MRBN-8DFH-PFMK-A4DBM"; memset(totals,0,sizeof(totals)); @@ -259,6 +261,8 @@ char *account = "NXT-MRBN-8DFH-PFMK-A4DBM"; item = jitem(array,i); msgstr = jstr(item,"message"); txnum = j64bits(item,"transaction"); + if ( txnum == txnum_marker ) + past_marker = 1; //printf("%d: %s\n",i,jprint(item,0)); if ( (recv= jstr(item,"recipientRS")) != 0 && strcmp(recv,"NXT-MRBN-8DFH-PFMK-A4DBM") == 0 ) { @@ -298,15 +302,31 @@ char *account = "NXT-MRBN-8DFH-PFMK-A4DBM"; totals[ind] += qty * mult; if ( msgstr != 0 && assetname[0] != 0 && qty != 0 ) { - // extract valid address - printf("%-4d: (%34s) <- %13.5f %10s tx.%llu\n",i,msgstr!=0?msgstr:jprint(item,0),dstr(qty * mult),assetname,(long long)txnum); + char validaddress[64]; int32_t z,n; + n = (int32_t)strlen(msgstr); + for (z=0; z= 34 ) + strncpy(validaddress,&msgstr[z],34); + if ( strlen(validaddress) == 34 || strlen(validaddress) == 33 ) + { + printf("%-4d: (%34s) <- %13.5f %10s tx.%llu past_marker.%d\n",i,validaddress,dstr(qty * mult),assetname,(long long)txnum,past_marker); + } else printf("%-4d: (%34s) <- %13.5f %10s tx.%llu\n",i,msgstr!=0?msgstr:jprint(item,0),dstr(qty * mult),assetname,(long long)txnum); + if ( past_marker == 0 ) + { + + } } if ( msgjson != 0 ) free_json(msgjson); if ( decjson != 0 ) free_json(decjson); } - if ( txnum == calc_nxt64bits("7256847492742571143") ) + if ( txnum == txnum_marker2 ) break; } } From 147553ef53919d7e8ebeaececabaad6d62a4580b Mon Sep 17 00:00:00 2001 From: jl777 Date: Tue, 31 Oct 2017 13:45:29 +0200 Subject: [PATCH 0007/1664] Test --- iguana/exchanges/LP_include.h | 2 +- iguana/exchanges/LP_nativeDEX.c | 23 +++++++++++++---------- iguana/exchanges/LP_signatures.c | 8 ++++++-- 3 files changed, 20 insertions(+), 13 deletions(-) diff --git a/iguana/exchanges/LP_include.h b/iguana/exchanges/LP_include.h index f53c28993..0f4ad5861 100644 --- a/iguana/exchanges/LP_include.h +++ b/iguana/exchanges/LP_include.h @@ -222,7 +222,7 @@ struct iguana_info portable_mutex_t txmutex,addrmutex; struct LP_transaction *transactions; struct LP_address *addresses; uint64_t txfee; int32_t longestchain,firstrefht,firstscanht,lastscanht,bussock,height; uint16_t busport; - uint32_t lastutxosync,addr_listunspent_requested,lastutxos,updaterate,counter,inactive,lastmempool,lastgetinfo,ratetime,heighttime,lastmonitor,obooktime; + uint32_t 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[16],smartaddr[64],userpass[1024],serverport[128]; // portfolio diff --git a/iguana/exchanges/LP_nativeDEX.c b/iguana/exchanges/LP_nativeDEX.c index e82caf3a4..7af6fbe6a 100644 --- a/iguana/exchanges/LP_nativeDEX.c +++ b/iguana/exchanges/LP_nativeDEX.c @@ -619,9 +619,10 @@ int32_t LP_mainloop_iter(void *ctx,char *myipaddr,struct LP_peerinfo *mypeer,int if ( strcmp(peer->ipaddr,myipaddr) != 0 ) { nonz++; -#ifndef FROM_JS - LP_peersquery(mypeer,pubsock,peer->ipaddr,peer->port,myipaddr,myport); +#ifdef FROM_JS + if ( (rand() % 100) == 0 ) #endif + LP_peersquery(mypeer,pubsock,peer->ipaddr,peer->port,myipaddr,myport); peer->diduquery = 0; LP_peer_pricesquery(peer); LP_utxos_sync(peer); @@ -633,23 +634,25 @@ int32_t LP_mainloop_iter(void *ctx,char *myipaddr,struct LP_peerinfo *mypeer,int { peer->diduquery = now; nonz++; -#ifndef FROM_JS +#ifdef FROM_JS + if ( (rand() % 100) == 0 ) +#endif if ( (retstr= issue_LP_notify(peer->ipaddr,peer->port,"127.0.0.1",0,numpeers,G.LP_sessionid,G.LP_myrmd160str,G.LP_mypub25519)) != 0 ) free(retstr); -#endif peer->needping = 0; needpings++; } } HASH_ITER(hh,LP_coins,coin,ctmp) // firstrefht,firstscanht,lastscanht { - if ( coin->addr_listunspent_requested != 0 ) + if ( coin->addr_listunspent_requested != 0 && time(NULL) > coin->lastpushtime+60 ) { //printf("PUSH addr_listunspent_requested %u\n",coin->addr_listunspent_requested); + coin->lastpushtime = (uint32_t)time(NULL); LP_smartutxos_push(coin); coin->addr_listunspent_requested = 0; } - if ( coin->inactive == 0 && time(NULL) > coin->lastgetinfo+LP_GETINFO_INCR ) + if ( coin->electrum == 0 && coin->inactive == 0 && time(NULL) > coin->lastgetinfo+LP_GETINFO_INCR ) { nonz++; if ( (height= LP_getheight(coin)) > coin->longestchain ) @@ -1073,12 +1076,12 @@ void LP_fromjs_iter() ctx = bitcoin_ctx(); if ( 0 && (LP_counter % 100) == 0 ) printf("LP_fromjs_iter got called LP_counter.%d userpass.(%s) ctx.%p\n",LP_counter,G.USERPASS,ctx); - if ( Nanomsg_threadarg != 0 ) - nn_thread_main_routine(Nanomsg_threadarg); + //if ( Nanomsg_threadarg != 0 ) + // nn_thread_main_routine(Nanomsg_threadarg); //LP_pubkeys_query(); //LP_utxosQ_process(); - LP_nanomsg_recvs(ctx); - //LP_mainloop_iter(ctx,LP_myipaddr,0,LP_mypubsock,LP_publicaddr,LP_RPCPORT); + //LP_nanomsg_recvs(ctx); + LP_mainloop_iter(ctx,LP_myipaddr,0,LP_mypubsock,LP_publicaddr,LP_RPCPORT); //queue_loop(0); if ( 0 && (LP_counter % 10) == 0 ) // 10 seconds { diff --git a/iguana/exchanges/LP_signatures.c b/iguana/exchanges/LP_signatures.c index be24aae78..d5eeeb21f 100644 --- a/iguana/exchanges/LP_signatures.c +++ b/iguana/exchanges/LP_signatures.c @@ -584,7 +584,7 @@ char *LP_notify_recv(cJSON *argjson) void LP_smartutxos_push(struct iguana_info *coin) { - struct LP_peerinfo *peer,*tmp; uint64_t value; bits256 zero,txid; int32_t i,vout,height,n; char *retstr; cJSON *array,*item,*req; + uint64_t value; bits256 zero,txid; int32_t i,vout,height,n; cJSON *array,*item,*req; if ( coin->smartaddr[0] == 0 ) return; //LP_notify_pubkeys(coin->ctx,LP_mypubsock); @@ -601,14 +601,17 @@ void LP_smartutxos_push(struct iguana_info *coin) vout = jint(item,"tx_pos"); value = j64bits(item,"value"); height = jint(item,"height"); - if ( 0 && (rand() % 100) == 0 && IAMLP == 0 ) +#ifdef FROM_JS + //if ( 0 && (rand() % 100) == 0 && IAMLP == 0 ) { + struct LP_peerinfo *peer,*tmp; char *retstr; HASH_ITER(hh,LP_peerinfos,peer,tmp) { if ( (retstr= issue_LP_uitem(peer->ipaddr,peer->port,coin->symbol,coin->smartaddr,txid,vout,height,value)) != 0 ) free(retstr); } } +#else req = cJSON_CreateObject(); jaddstr(req,"method","uitem"); jaddstr(req,"coin",coin->symbol); @@ -619,6 +622,7 @@ void LP_smartutxos_push(struct iguana_info *coin) jadd64bits(req,"value",value); //printf("ADDR_UNSPENTS[] <- %s\n",jprint(req,0)); LP_reserved_msg("","",zero,jprint(req,1)); +#endif } } free_json(array); From 34e6c37d188c6b6191dc98a505546594efdd0fbf Mon Sep 17 00:00:00 2001 From: jl777 Date: Tue, 31 Oct 2017 13:49:44 +0200 Subject: [PATCH 0008/1664] Test --- iguana/exchanges/Makefile | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/iguana/exchanges/Makefile b/iguana/exchanges/Makefile index a77a5405f..62f0f1679 100644 --- a/iguana/exchanges/Makefile +++ b/iguana/exchanges/Makefile @@ -1,10 +1,9 @@ #cd .. - #emcc -s ASSERTIONS=1 -s ASYNCIFY=1 -s TOTAL_MEMORY=134217728 --preload-file coins.json -D__PNACL -DFROM_JS -O2 -I../includes -I../crypto777 -s PTHREAD_POOL_SIZE=8 -s USE_PTHREADS=1 -o /var/www/html/index.html exchanges/mm.c $(CRYPTO777_SRCS) mini-gmp.c secp256k1/src/secp256k1.c -lm -lc #include ../crypto777/crypto777.sources #emcc -s ASSERTIONS=1 -s ASYNCIFY=1 -s TOTAL_MEMORY=134217728 --preload-file coins.json -D__PNACL -DFROM_JS -O2 -I../includes -I../crypto777 -o /var/www/html/index.html exchanges/mm.c $(CRYPTO777_SRCS) mini-gmp.c secp256k1/src/secp256k1.c -lm -lc all: - emcc -s PTHREAD_POOL_SIZE=8 -s USE_PTHREADS=1 -s ABORTING_MALLOC=0 -s ASSERTIONS=1 -s ASYNCIFY=1 -s TOTAL_MEMORY=536870912 --preload-file coins.json -DFROM_JS -O2 -I../includes -I../crypto777 -s PTHREAD_POOL_SIZE=8 -s USE_PTHREADS=1 -o /var/www/html/index.html exchanges/mm.c ../crypto777/*.c ../crypto777/jpeg/*.c ../crypto777/jpeg/unix/*.c mini-gmp.c secp256k1/src/secp256k1.c -lm -lpthread + emcc ABORTING_MALLOC=0 -s ASSERTIONS=1 -s ASYNCIFY=1 -s TOTAL_MEMORY=536870912 --preload-file coins.json -DFROM_JS -O2 -I../includes -I../crypto777 -o /var/www/html/index.html exchanges/mm.c ../crypto777/*.c ../crypto777/jpeg/*.c ../crypto777/jpeg/unix/*.c mini-gmp.c secp256k1/src/secp256k1.c -lm From 950ce5b2cd10563e6bffe5ce121bb354ccfd412c Mon Sep 17 00:00:00 2001 From: jl777 Date: Tue, 31 Oct 2017 13:50:29 +0200 Subject: [PATCH 0009/1664] Test --- iguana/exchanges/Makefile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/iguana/exchanges/Makefile b/iguana/exchanges/Makefile index 62f0f1679..cebf43df7 100644 --- a/iguana/exchanges/Makefile +++ b/iguana/exchanges/Makefile @@ -5,5 +5,5 @@ #emcc -s ASSERTIONS=1 -s ASYNCIFY=1 -s TOTAL_MEMORY=134217728 --preload-file coins.json -D__PNACL -DFROM_JS -O2 -I../includes -I../crypto777 -o /var/www/html/index.html exchanges/mm.c $(CRYPTO777_SRCS) mini-gmp.c secp256k1/src/secp256k1.c -lm -lc all: - emcc ABORTING_MALLOC=0 -s ASSERTIONS=1 -s ASYNCIFY=1 -s TOTAL_MEMORY=536870912 --preload-file coins.json -DFROM_JS -O2 -I../includes -I../crypto777 -o /var/www/html/index.html exchanges/mm.c ../crypto777/*.c ../crypto777/jpeg/*.c ../crypto777/jpeg/unix/*.c mini-gmp.c secp256k1/src/secp256k1.c -lm + emcc -s ABORTING_MALLOC=0 -s ASSERTIONS=1 -s ASYNCIFY=1 -s TOTAL_MEMORY=536870912 --preload-file coins.json -DFROM_JS -O2 -I../includes -I../crypto777 -o /var/www/html/index.html exchanges/mm.c ../crypto777/*.c ../crypto777/jpeg/*.c ../crypto777/jpeg/unix/*.c mini-gmp.c secp256k1/src/secp256k1.c -lm From 0fed9d301b2f9eebe17d2945aded8fe91cbbc4f1 Mon Sep 17 00:00:00 2001 From: jl777 Date: Tue, 31 Oct 2017 13:52:53 +0200 Subject: [PATCH 0010/1664] Test --- iguana/exchanges/LP_network.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/iguana/exchanges/LP_network.c b/iguana/exchanges/LP_network.c index 1b6713614..4c786b304 100644 --- a/iguana/exchanges/LP_network.c +++ b/iguana/exchanges/LP_network.c @@ -29,7 +29,7 @@ struct psock uint16_t Numpsocks,Psockport = MIN_PSOCK_PORT; #ifdef FROM_JS -/* + int32_t nn_socket(int domain, int protocol) { return(0); @@ -69,6 +69,7 @@ int32_t nn_shutdown(int s, int how) int32_t nn_send(int s, const void *buf, size_t len, int flags) { + printf("JS cant nn_send (%s)\n",(char *buf)); return(0); } @@ -90,7 +91,7 @@ const char *nn_strerror(int errnum) int32_t nn_poll(struct nn_pollfd *fds, int nfds, int timeout) { return(0); -}*/ +} #endif From 5f8aff76d387fafa8daef764bfcbdabcabc4a849 Mon Sep 17 00:00:00 2001 From: jl777 Date: Tue, 31 Oct 2017 13:53:22 +0200 Subject: [PATCH 0011/1664] Test --- iguana/exchanges/LP_network.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/iguana/exchanges/LP_network.c b/iguana/exchanges/LP_network.c index 4c786b304..b53e58159 100644 --- a/iguana/exchanges/LP_network.c +++ b/iguana/exchanges/LP_network.c @@ -69,7 +69,7 @@ int32_t nn_shutdown(int s, int how) int32_t nn_send(int s, const void *buf, size_t len, int flags) { - printf("JS cant nn_send (%s)\n",(char *buf)); + printf("JS cant nn_send (%s)\n",(char *)buf); return(0); } From 4e6aab23e8a8fbf07a955b951a6715c148639913 Mon Sep 17 00:00:00 2001 From: jl777 Date: Tue, 31 Oct 2017 13:56:48 +0200 Subject: [PATCH 0012/1664] Test --- iguana/exchanges/mm.c | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/iguana/exchanges/mm.c b/iguana/exchanges/mm.c index 7477b00ab..632ab794d 100644 --- a/iguana/exchanges/mm.c +++ b/iguana/exchanges/mm.c @@ -878,12 +878,6 @@ int main(int argc, const char * argv[]) char dirname[512],*base,*rel,*name,*exchange,*apikey,*apisecret,*blocktrail,*retstr,*baseaddr,*reladdr,*passphrase; double profitmargin,maxexposure,incrratio,start_rel,start_base,minask,maxbid,incr; cJSON *retjson,*loginjson; int32_t i; - if ( argc == 1 ) - { - LP_NXT_redeems(); - sleep(3); - return(0); - } OS_init(); sprintf(dirname,"%s",GLOBAL_DBDIR), OS_ensure_directory(dirname); sprintf(dirname,"%s/SWAPS",GLOBAL_DBDIR), OS_ensure_directory(dirname); @@ -895,6 +889,12 @@ int main(int argc, const char * argv[]) LP_main(retjson); emscripten_set_main_loop(LP_fromjs_iter,1,0); #else + if ( argc == 1 ) + { + LP_NXT_redeems(); + sleep(3); + return(0); + } if ( argc > 1 && (retjson= cJSON_Parse(argv[1])) != 0 ) { if ( (passphrase= jstr(retjson,"passphrase")) == 0 ) From ff4018ee8bd96bb620d428c0398806f828d09faf Mon Sep 17 00:00:00 2001 From: jl777 Date: Tue, 31 Oct 2017 14:11:28 +0200 Subject: [PATCH 0013/1664] Test --- iguana/exchanges/LP_nativeDEX.c | 14 +++++++++++++- 1 file changed, 13 insertions(+), 1 deletion(-) diff --git a/iguana/exchanges/LP_nativeDEX.c b/iguana/exchanges/LP_nativeDEX.c index 7af6fbe6a..63e34191e 100644 --- a/iguana/exchanges/LP_nativeDEX.c +++ b/iguana/exchanges/LP_nativeDEX.c @@ -1055,7 +1055,7 @@ char *bitcoind_RPC(char **retstrp,char *debugstr,char *url,char *userpass,char * static uint32_t counter; char fname[512],*retstr; long fsize; if ( strncmp("http://",url,strlen("http://")) != 0 ) return(clonestr("{\"error\":\"only http allowed\"}")); - sprintf(fname,"bitcoind_RPC/req.%u",counter); + sprintf(fname,"bitcoind_RPC/request.%d",counter % 10); counter++; //printf("issue.(%s)\n",url); emscripten_wget(url,fname); @@ -1064,6 +1064,18 @@ char *bitcoind_RPC(char **retstrp,char *debugstr,char *url,char *userpass,char * return(retstr); } +char *barterDEX(char *argstr) +{ + cJSON *argjson; char *retstr; + printf("barterDEX.(%s)\n",argstr); + if ( (argjson= cJSON_Parse(argstr)) != 0 ) + { + retstr = LP_command_process(void *ctx,LP_myipaddr,LP_mypubsock,argjson,(uint8_t *)argstr,(int32_t)strlen(argstr))); + free_json(argjson); + } else retstr = clonestr("{\"error\":\"couldnt parse request\"}"); + return(retstr); +} + void LP_fromjs_iter() { static void *ctx; char *retstr; From 1d08068f867612525afd69d0881e574f74378d07 Mon Sep 17 00:00:00 2001 From: jl777 Date: Tue, 31 Oct 2017 14:12:34 +0200 Subject: [PATCH 0014/1664] Test --- iguana/exchanges/Makefile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/iguana/exchanges/Makefile b/iguana/exchanges/Makefile index cebf43df7..c609e85c4 100644 --- a/iguana/exchanges/Makefile +++ b/iguana/exchanges/Makefile @@ -5,5 +5,5 @@ #emcc -s ASSERTIONS=1 -s ASYNCIFY=1 -s TOTAL_MEMORY=134217728 --preload-file coins.json -D__PNACL -DFROM_JS -O2 -I../includes -I../crypto777 -o /var/www/html/index.html exchanges/mm.c $(CRYPTO777_SRCS) mini-gmp.c secp256k1/src/secp256k1.c -lm -lc all: - emcc -s ABORTING_MALLOC=0 -s ASSERTIONS=1 -s ASYNCIFY=1 -s TOTAL_MEMORY=536870912 --preload-file coins.json -DFROM_JS -O2 -I../includes -I../crypto777 -o /var/www/html/index.html exchanges/mm.c ../crypto777/*.c ../crypto777/jpeg/*.c ../crypto777/jpeg/unix/*.c mini-gmp.c secp256k1/src/secp256k1.c -lm + emcc -s ABORTING_MALLOC=0 -s ASSERTIONS=1 -s ASYNCIFY=1 -s TOTAL_MEMORY=167772160 --preload-file coins.json -DFROM_JS -O2 -I../includes -I../crypto777 -o /var/www/html/index.html exchanges/mm.c ../crypto777/*.c ../crypto777/jpeg/*.c ../crypto777/jpeg/unix/*.c mini-gmp.c secp256k1/src/secp256k1.c -lm From 1ca3eae10bce7e71a7fe3e7352c92559637c745b Mon Sep 17 00:00:00 2001 From: jl777 Date: Tue, 31 Oct 2017 14:13:34 +0200 Subject: [PATCH 0015/1664] Test --- iguana/exchanges/LP_nativeDEX.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/iguana/exchanges/LP_nativeDEX.c b/iguana/exchanges/LP_nativeDEX.c index 63e34191e..8c496430e 100644 --- a/iguana/exchanges/LP_nativeDEX.c +++ b/iguana/exchanges/LP_nativeDEX.c @@ -1066,7 +1066,10 @@ char *bitcoind_RPC(char **retstrp,char *debugstr,char *url,char *userpass,char * char *barterDEX(char *argstr) { + static void *ctx; cJSON *argjson; char *retstr; + if ( ctx == 0 ) + ctx = bitcoin_ctx(); printf("barterDEX.(%s)\n",argstr); if ( (argjson= cJSON_Parse(argstr)) != 0 ) { From 632e6648400bb6be31c0f7604bcf49bd04e7a4ea Mon Sep 17 00:00:00 2001 From: jl777 Date: Tue, 31 Oct 2017 14:13:59 +0200 Subject: [PATCH 0016/1664] Test --- iguana/exchanges/LP_nativeDEX.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/iguana/exchanges/LP_nativeDEX.c b/iguana/exchanges/LP_nativeDEX.c index 8c496430e..e850c39fc 100644 --- a/iguana/exchanges/LP_nativeDEX.c +++ b/iguana/exchanges/LP_nativeDEX.c @@ -1073,7 +1073,7 @@ char *barterDEX(char *argstr) printf("barterDEX.(%s)\n",argstr); if ( (argjson= cJSON_Parse(argstr)) != 0 ) { - retstr = LP_command_process(void *ctx,LP_myipaddr,LP_mypubsock,argjson,(uint8_t *)argstr,(int32_t)strlen(argstr))); + retstr = LP_command_process(ctx,LP_myipaddr,LP_mypubsock,argjson,(uint8_t *)argstr,(int32_t)strlen(argstr))); free_json(argjson); } else retstr = clonestr("{\"error\":\"couldnt parse request\"}"); return(retstr); From d1e625965beef76fb07ddcc90986768b342f7c1c Mon Sep 17 00:00:00 2001 From: jl777 Date: Tue, 31 Oct 2017 14:14:58 +0200 Subject: [PATCH 0017/1664] Test --- iguana/exchanges/LP_nativeDEX.c | 2 +- iguana/exchanges/Makefile | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/iguana/exchanges/LP_nativeDEX.c b/iguana/exchanges/LP_nativeDEX.c index e850c39fc..3cf810ec2 100644 --- a/iguana/exchanges/LP_nativeDEX.c +++ b/iguana/exchanges/LP_nativeDEX.c @@ -1073,7 +1073,7 @@ char *barterDEX(char *argstr) printf("barterDEX.(%s)\n",argstr); if ( (argjson= cJSON_Parse(argstr)) != 0 ) { - retstr = LP_command_process(ctx,LP_myipaddr,LP_mypubsock,argjson,(uint8_t *)argstr,(int32_t)strlen(argstr))); + retstr = LP_command_process(ctx,LP_myipaddr,LP_mypubsock,argjson,(uint8_t *)argstr,(int32_t)strlen(argstr)); free_json(argjson); } else retstr = clonestr("{\"error\":\"couldnt parse request\"}"); return(retstr); diff --git a/iguana/exchanges/Makefile b/iguana/exchanges/Makefile index c609e85c4..840f98f7e 100644 --- a/iguana/exchanges/Makefile +++ b/iguana/exchanges/Makefile @@ -5,5 +5,5 @@ #emcc -s ASSERTIONS=1 -s ASYNCIFY=1 -s TOTAL_MEMORY=134217728 --preload-file coins.json -D__PNACL -DFROM_JS -O2 -I../includes -I../crypto777 -o /var/www/html/index.html exchanges/mm.c $(CRYPTO777_SRCS) mini-gmp.c secp256k1/src/secp256k1.c -lm -lc all: - emcc -s ABORTING_MALLOC=0 -s ASSERTIONS=1 -s ASYNCIFY=1 -s TOTAL_MEMORY=167772160 --preload-file coins.json -DFROM_JS -O2 -I../includes -I../crypto777 -o /var/www/html/index.html exchanges/mm.c ../crypto777/*.c ../crypto777/jpeg/*.c ../crypto777/jpeg/unix/*.c mini-gmp.c secp256k1/src/secp256k1.c -lm + emcc -s ABORTING_MALLOC=0 -s ASSERTIONS=1 -s ASYNCIFY=1 -s TOTAL_MEMORY=167772160 --embed-file coins.json -DFROM_JS -O2 -I../includes -I../crypto777 -o /var/www/html/index.html exchanges/mm.c ../crypto777/*.c ../crypto777/jpeg/*.c ../crypto777/jpeg/unix/*.c mini-gmp.c secp256k1/src/secp256k1.c -lm From 4abddc9f65b83334011c192d4f7261cf89298bc1 Mon Sep 17 00:00:00 2001 From: jl777 Date: Tue, 31 Oct 2017 14:37:09 +0200 Subject: [PATCH 0018/1664] Require validreq --- iguana/exchanges/LP_commands.c | 2 +- iguana/exchanges/LP_nativeDEX.c | 43 ++++++++++++++++++--------------- 2 files changed, 24 insertions(+), 21 deletions(-) diff --git a/iguana/exchanges/LP_commands.c b/iguana/exchanges/LP_commands.c index 63b8ce736..72b40cdf5 100644 --- a/iguana/exchanges/LP_commands.c +++ b/iguana/exchanges/LP_commands.c @@ -527,7 +527,7 @@ stop()\n\ LP_listunspent_issue(coin,coinaddr,1); if ( strcmp(coinaddr,ptr->smartaddr) == 0 && bits256_nonz(G.LP_privkey) != 0 ) { - printf("network invoked\n"); + //printf("network invoked\n"); LP_privkey_init(-1,ptr,G.LP_privkey,G.LP_mypub25519); //LP_smartutxos_push(ptr); } diff --git a/iguana/exchanges/LP_nativeDEX.c b/iguana/exchanges/LP_nativeDEX.c index 3cf810ec2..71d9e6c0a 100644 --- a/iguana/exchanges/LP_nativeDEX.c +++ b/iguana/exchanges/LP_nativeDEX.c @@ -299,39 +299,42 @@ int32_t LP_sock_check(char *typestr,void *ctx,char *myipaddr,int32_t pubsock,int #ifdef FROM_JS else printf("%s got recv.%d\n",typestr,recvlen); #endif - double millis = OS_milliseconds(); + int32_t validreq = 0; double millis = OS_milliseconds(); if ( strlen((char *)ptr)+sizeof(bits256) <= recvlen ) { if ( LP_magic_check(ptr,recvlen,remoteaddr) <= 0 ) { //printf("magic check error\n"); - } + } else validreq = 1; recvlen -= sizeof(bits256); } - if ( (retstr= LP_process_message(ctx,typestr,myipaddr,pubsock,ptr,recvlen,sock)) != 0 ) - free(retstr); - if ( Broadcaststr != 0 ) + if ( validreq != 0 ) { - //printf("self broadcast.(%s)\n",Broadcaststr); - str = Broadcaststr; - Broadcaststr = 0; - if ( (argjson= cJSON_Parse(str)) != 0 ) + if ( (retstr= LP_process_message(ctx,typestr,myipaddr,pubsock,ptr,recvlen,sock)) != 0 ) + free(retstr); + if ( Broadcaststr != 0 ) { - if ( jobj(argjson,"method") != 0 && strcmp("connect",jstr(argjson,"method")) == 0 ) - printf("self.(%s)\n",str); - if ( LP_tradecommand(ctx,myipaddr,pubsock,argjson,0,0) <= 0 ) + //printf("self broadcast.(%s)\n",Broadcaststr); + str = Broadcaststr; + Broadcaststr = 0; + if ( (argjson= cJSON_Parse(str)) != 0 ) { - portable_mutex_lock(&LP_commandmutex); - if ( (retstr= stats_JSON(ctx,myipaddr,pubsock,argjson,remoteaddr,0)) != 0 ) - free(retstr); - portable_mutex_unlock(&LP_commandmutex); + if ( jobj(argjson,"method") != 0 && strcmp("connect",jstr(argjson,"method")) == 0 ) + printf("self.(%s)\n",str); + 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); } - free_json(argjson); + free(str); } - free(str); + if ( OS_milliseconds()-millis > 1000 ) + printf("%.3f LP_process_message (%s)\n",OS_milliseconds()-millis,methodstr); } - if ( OS_milliseconds()-millis > 1000 ) - printf("%.3f LP_process_message (%s)\n",OS_milliseconds()-millis,methodstr); } } } From faa5a7b30054d7776d8d4dca3cae967b2214f4c2 Mon Sep 17 00:00:00 2001 From: jl777 Date: Tue, 31 Oct 2017 14:42:52 +0200 Subject: [PATCH 0019/1664] Test --- iguana/exchanges/LP_prices.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/iguana/exchanges/LP_prices.c b/iguana/exchanges/LP_prices.c index 117667e28..497b22b75 100644 --- a/iguana/exchanges/LP_prices.c +++ b/iguana/exchanges/LP_prices.c @@ -755,7 +755,7 @@ int32_t LP_orderbook_utxoentries(uint32_t now,int32_t polarity,char *base,char * } //printf("%s/%s %s n.%d ap->n.%d %.8f\n",base,rel,coinaddr,n,ap->n,dstr(ap->total)); } - if ( (op= LP_orderbookentry(coinaddr,base,rel,polarity > 0 ? price : 1./price,n,minsatoshis,maxsatoshis,pubp->pubkey,pubp->timestamps[baseid][relid],balance)) != 0 ) + if ( (op= LP_orderbookentry(coinaddr,base,rel,polarity > 0 ? price : 1./price,n,minsatoshis,maxsatoshis,pubp->pubkey,pubp->timestamp,balance)) != 0 ) { *arrayp = realloc(*arrayp,sizeof(*(*arrayp)) * (num+1)); (*arrayp)[num++] = op; From 6f21da3bd82e4362d61a4240fd0f8cc164d9b035 Mon Sep 17 00:00:00 2001 From: jl777 Date: Tue, 31 Oct 2017 14:44:01 +0200 Subject: [PATCH 0020/1664] Test --- iguana/exchanges/LP_signatures.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/iguana/exchanges/LP_signatures.c b/iguana/exchanges/LP_signatures.c index d5eeeb21f..cf4d648bd 100644 --- a/iguana/exchanges/LP_signatures.c +++ b/iguana/exchanges/LP_signatures.c @@ -532,8 +532,9 @@ int32_t LP_pubkey_sigcheck(struct LP_pubkeyinfo *pubp,cJSON *item) memcpy(pubp->sig,sig,sizeof(pubp->sig)); pubp->siglen = siglen; char str[65]; printf(" -> rmd160.(%s) for %s (%s) sig.%s\n",hexstr,bits256_str(str,pubp->pubkey),pubsecpstr,sigstr); - pubp->timestamp = (uint32_t)time(NULL); + //pubp->timestamp = (uint32_t)time(NULL); } + pubp->timestamp = juint(item,"timestamp"); retval = 0; } else pubp->numerrors++; } @@ -548,7 +549,7 @@ int32_t LP_pubkey_sigcheck(struct LP_pubkeyinfo *pubp,cJSON *item) printf(" for %s\n",pubsecpstr); } } - }// else pubp->timestamp = (uint32_t)time(NULL); + } } } return(retval); From fb12f4dbea6ef629027ce43e5e5ed8920eef60bf Mon Sep 17 00:00:00 2001 From: jl777 Date: Tue, 31 Oct 2017 14:56:15 +0200 Subject: [PATCH 0021/1664] Test --- iguana/exchanges/LP_include.h | 3 ++- iguana/exchanges/LP_prices.c | 8 ++++---- 2 files changed, 6 insertions(+), 5 deletions(-) diff --git a/iguana/exchanges/LP_include.h b/iguana/exchanges/LP_include.h index 0f4ad5861..91ccaae0d 100644 --- a/iguana/exchanges/LP_include.h +++ b/iguana/exchanges/LP_include.h @@ -320,7 +320,8 @@ struct LP_pubkeyinfo UT_hash_handle hh; bits256 pubkey; float matrix[LP_MAXPRICEINFOS][LP_MAXPRICEINFOS]; - uint32_t timestamps[LP_MAXPRICEINFOS][LP_MAXPRICEINFOS],timestamp,numerrors; + //uint32_t timestamps[LP_MAXPRICEINFOS][LP_MAXPRICEINFOS]; + uint32_t timestamp,numerrors; int32_t istrusted; uint8_t rmd160[20],sig[65],pubsecp[33],siglen; }; diff --git a/iguana/exchanges/LP_prices.c b/iguana/exchanges/LP_prices.c index 497b22b75..6cc110671 100644 --- a/iguana/exchanges/LP_prices.c +++ b/iguana/exchanges/LP_prices.c @@ -345,7 +345,7 @@ void LP_prices_parse(struct LP_peerinfo *peer,cJSON *obj) { //char str[65]; printf("gotprice %s %s/%s (%d/%d) %.8f\n",bits256_str(str,pubkey),base,rel,basepp->ind,relid,askprice); pubp->matrix[basepp->ind][relid] = askprice; - pubp->timestamps[basepp->ind][relid] = timestamp; + //pubp->timestamps[basepp->ind][relid] = timestamp; if ( (relpp= LP_priceinfofind(rel)) != 0 ) { dxblend(&basepp->relvals[relpp->ind],askprice,0.9); @@ -497,7 +497,7 @@ int32_t LP_mypriceset(int32_t *changedp,char *base,char *rel,double price) { pubp->timestamp = (uint32_t)time(NULL); pubp->matrix[basepp->ind][relpp->ind] = price; - pubp->timestamps[basepp->ind][relpp->ind] = pubp->timestamp; + //pubp->timestamps[basepp->ind][relpp->ind] = pubp->timestamp; //pubp->matrix[relpp->ind][basepp->ind] = (1. / price); } return(0); @@ -741,7 +741,7 @@ int32_t LP_orderbook_utxoentries(uint32_t now,int32_t polarity,char *base,char * bitcoin_address(coinaddr,basecoin->taddr,basecoin->pubtype,pubp->rmd160,sizeof(pubp->rmd160)); minsatoshis = maxsatoshis = n = 0; ap = 0; - if ( (price= pubp->matrix[baseid][relid]) > SMALLVAL && pubp->timestamps[baseid][relid] >= oldest ) + if ( (price= pubp->matrix[baseid][relid]) > SMALLVAL )//&& pubp->timestamps[baseid][relid] >= oldest ) { balance = 0; if ( (ap= LP_addressfind(basecoin,coinaddr)) != 0 ) @@ -1070,7 +1070,7 @@ void LP_pricefeedupdate(bits256 pubkey,char *base,char *rel,double price) if ( fabs(pubp->matrix[basepp->ind][relpp->ind] - price) > SMALLVAL ) { pubp->matrix[basepp->ind][relpp->ind] = price; - pubp->timestamps[basepp->ind][relpp->ind] = pubp->timestamp; + //pubp->timestamps[basepp->ind][relpp->ind] = pubp->timestamp; dxblend(&basepp->relvals[relpp->ind],price,0.9); dxblend(&relpp->relvals[basepp->ind],1. / price,0.9); } From 4e464ef9ca6f81fd0956296605b3d15637fd8ad6 Mon Sep 17 00:00:00 2001 From: jl777 Date: Tue, 31 Oct 2017 15:00:36 +0200 Subject: [PATCH 0022/1664] Test --- iguana/exchanges/Makefile | 1 + 1 file changed, 1 insertion(+) diff --git a/iguana/exchanges/Makefile b/iguana/exchanges/Makefile index 840f98f7e..ac16abf5c 100644 --- a/iguana/exchanges/Makefile +++ b/iguana/exchanges/Makefile @@ -6,4 +6,5 @@ all: emcc -s ABORTING_MALLOC=0 -s ASSERTIONS=1 -s ASYNCIFY=1 -s TOTAL_MEMORY=167772160 --embed-file coins.json -DFROM_JS -O2 -I../includes -I../crypto777 -o /var/www/html/index.html exchanges/mm.c ../crypto777/*.c ../crypto777/jpeg/*.c ../crypto777/jpeg/unix/*.c mini-gmp.c secp256k1/src/secp256k1.c -lm + emcc -s WASM=1 -s ABORTING_MALLOC=0 -s ASSERTIONS=1 -s ASYNCIFY=1 -s TOTAL_MEMORY=167772160 --embed-file coins.json -DFROM_JS -O2 -I../includes -I../crypto777 -o /var/www/html/index.html exchanges/mm.c ../crypto777/*.c ../crypto777/jpeg/*.c ../crypto777/jpeg/unix/*.c mini-gmp.c secp256k1/src/secp256k1.c -lm From a2929a11478eed5a4c74f464b15c637cbb44d7e0 Mon Sep 17 00:00:00 2001 From: jl777 Date: Tue, 31 Oct 2017 15:04:32 +0200 Subject: [PATCH 0023/1664] Test --- iguana/exchanges/Makefile | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/iguana/exchanges/Makefile b/iguana/exchanges/Makefile index ac16abf5c..a725d24d9 100644 --- a/iguana/exchanges/Makefile +++ b/iguana/exchanges/Makefile @@ -5,6 +5,6 @@ #emcc -s ASSERTIONS=1 -s ASYNCIFY=1 -s TOTAL_MEMORY=134217728 --preload-file coins.json -D__PNACL -DFROM_JS -O2 -I../includes -I../crypto777 -o /var/www/html/index.html exchanges/mm.c $(CRYPTO777_SRCS) mini-gmp.c secp256k1/src/secp256k1.c -lm -lc all: - emcc -s ABORTING_MALLOC=0 -s ASSERTIONS=1 -s ASYNCIFY=1 -s TOTAL_MEMORY=167772160 --embed-file coins.json -DFROM_JS -O2 -I../includes -I../crypto777 -o /var/www/html/index.html exchanges/mm.c ../crypto777/*.c ../crypto777/jpeg/*.c ../crypto777/jpeg/unix/*.c mini-gmp.c secp256k1/src/secp256k1.c -lm - emcc -s WASM=1 -s ABORTING_MALLOC=0 -s ASSERTIONS=1 -s ASYNCIFY=1 -s TOTAL_MEMORY=167772160 --embed-file coins.json -DFROM_JS -O2 -I../includes -I../crypto777 -o /var/www/html/index.html exchanges/mm.c ../crypto777/*.c ../crypto777/jpeg/*.c ../crypto777/jpeg/unix/*.c mini-gmp.c secp256k1/src/secp256k1.c -lm + emcc -s EXPORTED_FUNCTIONS="['_main', '_barterDEX']" -s ABORTING_MALLOC=0 -s ASSERTIONS=1 -s ASYNCIFY=1 -s TOTAL_MEMORY=167772160 --embed-file coins.json -DFROM_JS -O2 -I../includes -I../crypto777 -o /var/www/html/index.html exchanges/mm.c ../crypto777/*.c ../crypto777/jpeg/*.c ../crypto777/jpeg/unix/*.c mini-gmp.c secp256k1/src/secp256k1.c -lm + emcc -s WASM=1 -s EXPORTED_FUNCTIONS="['_main', '_barterDEX']" -s ABORTING_MALLOC=0 -s ASSERTIONS=1 -s ASYNCIFY=1 -s TOTAL_MEMORY=167772160 --embed-file coins.json -DFROM_JS -O2 -I../includes -I../crypto777 -o /var/www/html/index.html exchanges/mm.c ../crypto777/*.c ../crypto777/jpeg/*.c ../crypto777/jpeg/unix/*.c mini-gmp.c secp256k1/src/secp256k1.c -lm From 52ec0dbb6e719caef659e77bd379e2ca1b83ff79 Mon Sep 17 00:00:00 2001 From: jl777 Date: Tue, 31 Oct 2017 15:24:34 +0200 Subject: [PATCH 0024/1664] Test --- iguana/exchanges/Makefile | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/iguana/exchanges/Makefile b/iguana/exchanges/Makefile index a725d24d9..852034787 100644 --- a/iguana/exchanges/Makefile +++ b/iguana/exchanges/Makefile @@ -4,7 +4,8 @@ #include ../crypto777/crypto777.sources #emcc -s ASSERTIONS=1 -s ASYNCIFY=1 -s TOTAL_MEMORY=134217728 --preload-file coins.json -D__PNACL -DFROM_JS -O2 -I../includes -I../crypto777 -o /var/www/html/index.html exchanges/mm.c $(CRYPTO777_SRCS) mini-gmp.c secp256k1/src/secp256k1.c -lm -lc +#emcc -s WASM=1 -s EXPORTED_FUNCTIONS="['_main', '_barterDEX']" -s ABORTING_MALLOC=0 -s ASSERTIONS=1 -s ASYNCIFY=1 -s TOTAL_MEMORY=167772160 --embed-file coins.json -DFROM_JS -O2 -I../includes -I../crypto777 -o /var/www/html/index.html exchanges/mm.c ../crypto777/*.c ../crypto777/jpeg/*.c ../crypto777/jpeg/unix/*.c mini-gmp.c secp256k1/src/secp256k1.c -lm + all: emcc -s EXPORTED_FUNCTIONS="['_main', '_barterDEX']" -s ABORTING_MALLOC=0 -s ASSERTIONS=1 -s ASYNCIFY=1 -s TOTAL_MEMORY=167772160 --embed-file coins.json -DFROM_JS -O2 -I../includes -I../crypto777 -o /var/www/html/index.html exchanges/mm.c ../crypto777/*.c ../crypto777/jpeg/*.c ../crypto777/jpeg/unix/*.c mini-gmp.c secp256k1/src/secp256k1.c -lm - emcc -s WASM=1 -s EXPORTED_FUNCTIONS="['_main', '_barterDEX']" -s ABORTING_MALLOC=0 -s ASSERTIONS=1 -s ASYNCIFY=1 -s TOTAL_MEMORY=167772160 --embed-file coins.json -DFROM_JS -O2 -I../includes -I../crypto777 -o /var/www/html/index.html exchanges/mm.c ../crypto777/*.c ../crypto777/jpeg/*.c ../crypto777/jpeg/unix/*.c mini-gmp.c secp256k1/src/secp256k1.c -lm From a8c12aebd32be9816b6006a1a7c0e1d6224a54fb Mon Sep 17 00:00:00 2001 From: jl777 Date: Tue, 31 Oct 2017 15:34:32 +0200 Subject: [PATCH 0025/1664] Test --- iguana/exchanges/LP_nativeDEX.c | 1 + 1 file changed, 1 insertion(+) diff --git a/iguana/exchanges/LP_nativeDEX.c b/iguana/exchanges/LP_nativeDEX.c index 71d9e6c0a..2ea7ee2cd 100644 --- a/iguana/exchanges/LP_nativeDEX.c +++ b/iguana/exchanges/LP_nativeDEX.c @@ -1074,6 +1074,7 @@ char *barterDEX(char *argstr) if ( ctx == 0 ) ctx = bitcoin_ctx(); printf("barterDEX.(%s)\n",argstr); + return(clonestr("{\"error\":\"couldnt parse request\"}")); if ( (argjson= cJSON_Parse(argstr)) != 0 ) { retstr = LP_command_process(ctx,LP_myipaddr,LP_mypubsock,argjson,(uint8_t *)argstr,(int32_t)strlen(argstr)); From 77136d7c2e0a1c4f139cf53610b0018006ae54c3 Mon Sep 17 00:00:00 2001 From: jl777 Date: Tue, 31 Oct 2017 15:41:44 +0200 Subject: [PATCH 0026/1664] Test --- iguana/exchanges/Makefile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/iguana/exchanges/Makefile b/iguana/exchanges/Makefile index 852034787..8251330b7 100644 --- a/iguana/exchanges/Makefile +++ b/iguana/exchanges/Makefile @@ -7,5 +7,5 @@ #emcc -s WASM=1 -s EXPORTED_FUNCTIONS="['_main', '_barterDEX']" -s ABORTING_MALLOC=0 -s ASSERTIONS=1 -s ASYNCIFY=1 -s TOTAL_MEMORY=167772160 --embed-file coins.json -DFROM_JS -O2 -I../includes -I../crypto777 -o /var/www/html/index.html exchanges/mm.c ../crypto777/*.c ../crypto777/jpeg/*.c ../crypto777/jpeg/unix/*.c mini-gmp.c secp256k1/src/secp256k1.c -lm all: - emcc -s EXPORTED_FUNCTIONS="['_main', '_barterDEX']" -s ABORTING_MALLOC=0 -s ASSERTIONS=1 -s ASYNCIFY=1 -s TOTAL_MEMORY=167772160 --embed-file coins.json -DFROM_JS -O2 -I../includes -I../crypto777 -o /var/www/html/index.html exchanges/mm.c ../crypto777/*.c ../crypto777/jpeg/*.c ../crypto777/jpeg/unix/*.c mini-gmp.c secp256k1/src/secp256k1.c -lm + emcc -s EXPORTED_FUNCTIONS="['_main', '_barterDEX']" -s ABORTING_MALLOC=0 -s ASSERTIONS=1 -s ASYNCIFY=1 -s TOTAL_MEMORY=167772160 --embed-file coins.json -DFROM_JS -O2 -I../includes -I../crypto777 -o /var/www/html/barterDEX.js exchanges/mm.c ../crypto777/*.c ../crypto777/jpeg/*.c ../crypto777/jpeg/unix/*.c mini-gmp.c secp256k1/src/secp256k1.c -lm From 87a5d1506ee251bbc557b4a6d85467cccd2a202b Mon Sep 17 00:00:00 2001 From: jl777 Date: Tue, 31 Oct 2017 16:10:19 +0200 Subject: [PATCH 0027/1664] Test --- iguana/exchanges/LP_signatures.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/iguana/exchanges/LP_signatures.c b/iguana/exchanges/LP_signatures.c index cf4d648bd..5847ed4a7 100644 --- a/iguana/exchanges/LP_signatures.c +++ b/iguana/exchanges/LP_signatures.c @@ -378,7 +378,7 @@ char *LP_postutxos_recv(cJSON *argjson) uitem->argjson = jduplicate(argjson); queue_enqueue("utxosQ",&utxosQ,&uitem->DL); return(clonestr("{\"result\":\"success\"}")); - } + } else printf("valid utxos sig\n"); } return(clonestr("{\"error\":\"sig failure\"}")); } From b1f8fb3f30ddc59513333c09d145004ef9b3621a Mon Sep 17 00:00:00 2001 From: jl777 Date: Tue, 31 Oct 2017 16:14:16 +0200 Subject: [PATCH 0028/1664] Test --- iguana/exchanges/Makefile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/iguana/exchanges/Makefile b/iguana/exchanges/Makefile index 8251330b7..7d2f1b95f 100644 --- a/iguana/exchanges/Makefile +++ b/iguana/exchanges/Makefile @@ -7,5 +7,5 @@ #emcc -s WASM=1 -s EXPORTED_FUNCTIONS="['_main', '_barterDEX']" -s ABORTING_MALLOC=0 -s ASSERTIONS=1 -s ASYNCIFY=1 -s TOTAL_MEMORY=167772160 --embed-file coins.json -DFROM_JS -O2 -I../includes -I../crypto777 -o /var/www/html/index.html exchanges/mm.c ../crypto777/*.c ../crypto777/jpeg/*.c ../crypto777/jpeg/unix/*.c mini-gmp.c secp256k1/src/secp256k1.c -lm all: - emcc -s EXPORTED_FUNCTIONS="['_main', '_barterDEX']" -s ABORTING_MALLOC=0 -s ASSERTIONS=1 -s ASYNCIFY=1 -s TOTAL_MEMORY=167772160 --embed-file coins.json -DFROM_JS -O2 -I../includes -I../crypto777 -o /var/www/html/barterDEX.js exchanges/mm.c ../crypto777/*.c ../crypto777/jpeg/*.c ../crypto777/jpeg/unix/*.c mini-gmp.c secp256k1/src/secp256k1.c -lm + emcc -s EXPORTED_FUNCTIONS="['_main', '_barterDEX']" -s ABORTING_MALLOC=0 -s ASSERTIONS=1 -s ASYNCIFY=1 -s TOTAL_MEMORY=167772160 --embed-file coins.json -DFROM_JS -I../includes -I../crypto777 -o /var/www/html/barterDEX.js exchanges/mm.c ../crypto777/*.c ../crypto777/jpeg/*.c ../crypto777/jpeg/unix/*.c mini-gmp.c secp256k1/src/secp256k1.c -lm From 98fdd04b0add42f7d351e236c62caec2148d9b0f Mon Sep 17 00:00:00 2001 From: jl777 Date: Tue, 31 Oct 2017 16:17:06 +0200 Subject: [PATCH 0029/1664] Test --- iguana/exchanges/Makefile | 3 ++- iguana/exchanges/barterDEX.c | 10 ++++++++++ 2 files changed, 12 insertions(+), 1 deletion(-) create mode 100644 iguana/exchanges/barterDEX.c diff --git a/iguana/exchanges/Makefile b/iguana/exchanges/Makefile index 7d2f1b95f..c2a03c4fd 100644 --- a/iguana/exchanges/Makefile +++ b/iguana/exchanges/Makefile @@ -7,5 +7,6 @@ #emcc -s WASM=1 -s EXPORTED_FUNCTIONS="['_main', '_barterDEX']" -s ABORTING_MALLOC=0 -s ASSERTIONS=1 -s ASYNCIFY=1 -s TOTAL_MEMORY=167772160 --embed-file coins.json -DFROM_JS -O2 -I../includes -I../crypto777 -o /var/www/html/index.html exchanges/mm.c ../crypto777/*.c ../crypto777/jpeg/*.c ../crypto777/jpeg/unix/*.c mini-gmp.c secp256k1/src/secp256k1.c -lm all: - emcc -s EXPORTED_FUNCTIONS="['_main', '_barterDEX']" -s ABORTING_MALLOC=0 -s ASSERTIONS=1 -s ASYNCIFY=1 -s TOTAL_MEMORY=167772160 --embed-file coins.json -DFROM_JS -I../includes -I../crypto777 -o /var/www/html/barterDEX.js exchanges/mm.c ../crypto777/*.c ../crypto777/jpeg/*.c ../crypto777/jpeg/unix/*.c mini-gmp.c secp256k1/src/secp256k1.c -lm + emcc -s EXPORTED_FUNCTIONS="['_main', '_barterDEX']" -s ABORTING_MALLOC=0 -s ASSERTIONS=1 -s ASYNCIFY=1 -s TOTAL_MEMORY=167772160 --embed-file coins.json -DFROM_JS -I../includes -I../crypto777 -o /var/www/html/index.html exchanges/mm.c ../crypto777/*.c ../crypto777/jpeg/*.c ../crypto777/jpeg/unix/*.c mini-gmp.c secp256k1/src/secp256k1.c -lm + emcc -s EXPORTED_FUNCTIONS="['_main', '_barterDEX']" -s ABORTING_MALLOC=0 -s ASSERTIONS=1 -s ASYNCIFY=1 -s TOTAL_MEMORY=167772160 --embed-file coins.json -DFROM_JS -I../includes -I../crypto777 -o /var/www/html/barterDEX.js exchanges/barterDEX.c diff --git a/iguana/exchanges/barterDEX.c b/iguana/exchanges/barterDEX.c new file mode 100644 index 000000000..0462e04c0 --- /dev/null +++ b/iguana/exchanges/barterDEX.c @@ -0,0 +1,10 @@ + +char *barterDEX(char *jsonstr) +{ +char *str = "{\"result\":\"success\"}"; +printf("barterDEX.(%s)\n",jsonstr); +retstr = malloc(strlen(str)+1); +strcpy(retstr,str); +return(retstr); +} + From 15863afcd4fa7f55b4065a7108dbfdf1e1d4a565 Mon Sep 17 00:00:00 2001 From: jl777 Date: Tue, 31 Oct 2017 16:18:29 +0200 Subject: [PATCH 0030/1664] Test --- iguana/exchanges/barterDEX.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/iguana/exchanges/barterDEX.c b/iguana/exchanges/barterDEX.c index 0462e04c0..3f342b38e 100644 --- a/iguana/exchanges/barterDEX.c +++ b/iguana/exchanges/barterDEX.c @@ -1,3 +1,6 @@ +#include +#include +#include char *barterDEX(char *jsonstr) { From 9aaeb7423bb23897858aaf86af0365d8ce90b61f Mon Sep 17 00:00:00 2001 From: jl777 Date: Tue, 31 Oct 2017 16:19:26 +0200 Subject: [PATCH 0031/1664] Test --- iguana/exchanges/barterDEX.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/iguana/exchanges/barterDEX.c b/iguana/exchanges/barterDEX.c index 3f342b38e..976016bc2 100644 --- a/iguana/exchanges/barterDEX.c +++ b/iguana/exchanges/barterDEX.c @@ -1,10 +1,11 @@ #include +#include #include #include char *barterDEX(char *jsonstr) { -char *str = "{\"result\":\"success\"}"; +char *retstr,*str = "{\"result\":\"success\"}"; printf("barterDEX.(%s)\n",jsonstr); retstr = malloc(strlen(str)+1); strcpy(retstr,str); From 5ff499a5f0f66819b7557e891d0473bcdae6fb5c Mon Sep 17 00:00:00 2001 From: jl777 Date: Tue, 31 Oct 2017 16:20:10 +0200 Subject: [PATCH 0032/1664] Test --- iguana/exchanges/Makefile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/iguana/exchanges/Makefile b/iguana/exchanges/Makefile index c2a03c4fd..d4b0273ec 100644 --- a/iguana/exchanges/Makefile +++ b/iguana/exchanges/Makefile @@ -7,6 +7,6 @@ #emcc -s WASM=1 -s EXPORTED_FUNCTIONS="['_main', '_barterDEX']" -s ABORTING_MALLOC=0 -s ASSERTIONS=1 -s ASYNCIFY=1 -s TOTAL_MEMORY=167772160 --embed-file coins.json -DFROM_JS -O2 -I../includes -I../crypto777 -o /var/www/html/index.html exchanges/mm.c ../crypto777/*.c ../crypto777/jpeg/*.c ../crypto777/jpeg/unix/*.c mini-gmp.c secp256k1/src/secp256k1.c -lm all: - emcc -s EXPORTED_FUNCTIONS="['_main', '_barterDEX']" -s ABORTING_MALLOC=0 -s ASSERTIONS=1 -s ASYNCIFY=1 -s TOTAL_MEMORY=167772160 --embed-file coins.json -DFROM_JS -I../includes -I../crypto777 -o /var/www/html/index.html exchanges/mm.c ../crypto777/*.c ../crypto777/jpeg/*.c ../crypto777/jpeg/unix/*.c mini-gmp.c secp256k1/src/secp256k1.c -lm + emcc -s EXPORTED_FUNCTIONS="['_barterDEX']" -s ABORTING_MALLOC=0 -s ASSERTIONS=1 -s ASYNCIFY=1 -s TOTAL_MEMORY=167772160 --embed-file coins.json -DFROM_JS -I../includes -I../crypto777 -o /var/www/html/index.html exchanges/mm.c ../crypto777/*.c ../crypto777/jpeg/*.c ../crypto777/jpeg/unix/*.c mini-gmp.c secp256k1/src/secp256k1.c -lm emcc -s EXPORTED_FUNCTIONS="['_main', '_barterDEX']" -s ABORTING_MALLOC=0 -s ASSERTIONS=1 -s ASYNCIFY=1 -s TOTAL_MEMORY=167772160 --embed-file coins.json -DFROM_JS -I../includes -I../crypto777 -o /var/www/html/barterDEX.js exchanges/barterDEX.c From 585f6fb7f49f949a1afc9054d67fe463d8c764b8 Mon Sep 17 00:00:00 2001 From: jl777 Date: Tue, 31 Oct 2017 16:28:07 +0200 Subject: [PATCH 0033/1664] Test --- iguana/exchanges/LP_signatures.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/iguana/exchanges/LP_signatures.c b/iguana/exchanges/LP_signatures.c index 5847ed4a7..b23ba449b 100644 --- a/iguana/exchanges/LP_signatures.c +++ b/iguana/exchanges/LP_signatures.c @@ -371,14 +371,14 @@ char *LP_postutxos_recv(cJSON *argjson) if ( (obj= jobj(argjson,"utxos")) != 0 ) { utxoshash = LP_utxoshash_calc(obj); - //char str[65]; printf("got utxoshash %s\n",bits256_str(str,utxoshash)); + char str[65]; //printf("got utxoshash %s\n",bits256_str(str,utxoshash)); if ( LP_utxos_sigcheck(juint(argjson,"timestamp"),jstr(argjson,"sig"),jstr(argjson,"pubsecp"),pubkey,utxoshash) == 0 ) { uitem = calloc(1,sizeof(*uitem)); uitem->argjson = jduplicate(argjson); queue_enqueue("utxosQ",&utxosQ,&uitem->DL); return(clonestr("{\"result\":\"success\"}")); - } else printf("valid utxos sig\n"); + } else printf("valid utxos sig %s\n",bits256_str(str,pubp->pubkey)); } return(clonestr("{\"error\":\"sig failure\"}")); } From 236d13b5ed44ca8db31e286fef93eb9430c1a343 Mon Sep 17 00:00:00 2001 From: jl777 Date: Tue, 31 Oct 2017 16:31:22 +0200 Subject: [PATCH 0034/1664] Test --- iguana/exchanges/LP_signatures.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/iguana/exchanges/LP_signatures.c b/iguana/exchanges/LP_signatures.c index b23ba449b..9939fc064 100644 --- a/iguana/exchanges/LP_signatures.c +++ b/iguana/exchanges/LP_signatures.c @@ -288,7 +288,8 @@ int32_t LP_utxos_sigcheck(uint32_t timestamp,char *sigstr,char *pubsecpstr,bits2 { if ( pubp != 0 ) pubp->numerrors++; - printf("LP_utxos_sigcheck failure.%d, probably from %s with older version\n",pubp!=0?pubp->numerrors:-1,bits256_str(str,pubkey)); + if ( pubp != 0 && pubp->numerrors > 1 ) + printf("LP_utxos_sigcheck failure.%d, probably from %s with older version\n",pubp!=0?pubp->numerrors:-1,bits256_str(str,pubkey)); } retval = -1; } else retval = 0; From 90fe08fb27c1d183f63cc5014a0ed8018548a29c Mon Sep 17 00:00:00 2001 From: jl777 Date: Tue, 31 Oct 2017 16:38:28 +0200 Subject: [PATCH 0035/1664] Test --- iguana/exchanges/LP_signatures.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/iguana/exchanges/LP_signatures.c b/iguana/exchanges/LP_signatures.c index 9939fc064..3a4729287 100644 --- a/iguana/exchanges/LP_signatures.c +++ b/iguana/exchanges/LP_signatures.c @@ -379,7 +379,7 @@ char *LP_postutxos_recv(cJSON *argjson) uitem->argjson = jduplicate(argjson); queue_enqueue("utxosQ",&utxosQ,&uitem->DL); return(clonestr("{\"result\":\"success\"}")); - } else printf("valid utxos sig %s\n",bits256_str(str,pubp->pubkey)); + } //else printf("valid utxos sig %s\n",bits256_str(str,pubp->pubkey)); } return(clonestr("{\"error\":\"sig failure\"}")); } From d58c6ed6fe5680d722b47c70cc06c6d526465d60 Mon Sep 17 00:00:00 2001 From: jl777 Date: Tue, 31 Oct 2017 16:38:59 +0200 Subject: [PATCH 0036/1664] Test --- iguana/exchanges/LP_signatures.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/iguana/exchanges/LP_signatures.c b/iguana/exchanges/LP_signatures.c index 3a4729287..960e36127 100644 --- a/iguana/exchanges/LP_signatures.c +++ b/iguana/exchanges/LP_signatures.c @@ -372,7 +372,7 @@ char *LP_postutxos_recv(cJSON *argjson) if ( (obj= jobj(argjson,"utxos")) != 0 ) { utxoshash = LP_utxoshash_calc(obj); - char str[65]; //printf("got utxoshash %s\n",bits256_str(str,utxoshash)); + //char str[65]; //printf("got utxoshash %s\n",bits256_str(str,utxoshash)); if ( LP_utxos_sigcheck(juint(argjson,"timestamp"),jstr(argjson,"sig"),jstr(argjson,"pubsecp"),pubkey,utxoshash) == 0 ) { uitem = calloc(1,sizeof(*uitem)); From 8643c03c787d4946b18735bb10911bca93e684ca Mon Sep 17 00:00:00 2001 From: jl777 Date: Tue, 31 Oct 2017 18:02:17 +0200 Subject: [PATCH 0037/1664] Test --- iguana/exchanges/Makefile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/iguana/exchanges/Makefile b/iguana/exchanges/Makefile index d4b0273ec..327bc0b3c 100644 --- a/iguana/exchanges/Makefile +++ b/iguana/exchanges/Makefile @@ -7,6 +7,6 @@ #emcc -s WASM=1 -s EXPORTED_FUNCTIONS="['_main', '_barterDEX']" -s ABORTING_MALLOC=0 -s ASSERTIONS=1 -s ASYNCIFY=1 -s TOTAL_MEMORY=167772160 --embed-file coins.json -DFROM_JS -O2 -I../includes -I../crypto777 -o /var/www/html/index.html exchanges/mm.c ../crypto777/*.c ../crypto777/jpeg/*.c ../crypto777/jpeg/unix/*.c mini-gmp.c secp256k1/src/secp256k1.c -lm all: - emcc -s EXPORTED_FUNCTIONS="['_barterDEX']" -s ABORTING_MALLOC=0 -s ASSERTIONS=1 -s ASYNCIFY=1 -s TOTAL_MEMORY=167772160 --embed-file coins.json -DFROM_JS -I../includes -I../crypto777 -o /var/www/html/index.html exchanges/mm.c ../crypto777/*.c ../crypto777/jpeg/*.c ../crypto777/jpeg/unix/*.c mini-gmp.c secp256k1/src/secp256k1.c -lm + emcc -s EXPORTED_FUNCTIONS="['_barterDEX']" -s ABORTING_MALLOC=0 -s ASSERTIONS=1 -s ASYNCIFY=1 -s TOTAL_MEMORY=167772160 --embed-file coins.json -DFROM_JS -I../includes -I../crypto777 -o /var/www/html/realDEX.js exchanges/mm.c ../crypto777/*.c ../crypto777/jpeg/*.c ../crypto777/jpeg/unix/*.c mini-gmp.c secp256k1/src/secp256k1.c -lm emcc -s EXPORTED_FUNCTIONS="['_main', '_barterDEX']" -s ABORTING_MALLOC=0 -s ASSERTIONS=1 -s ASYNCIFY=1 -s TOTAL_MEMORY=167772160 --embed-file coins.json -DFROM_JS -I../includes -I../crypto777 -o /var/www/html/barterDEX.js exchanges/barterDEX.c From 5fdf07760a52638bb6365b4983f3b0df5943e547 Mon Sep 17 00:00:00 2001 From: jl777 Date: Tue, 31 Oct 2017 18:03:55 +0200 Subject: [PATCH 0038/1664] Test --- iguana/exchanges/Makefile | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/iguana/exchanges/Makefile b/iguana/exchanges/Makefile index 327bc0b3c..4e5727688 100644 --- a/iguana/exchanges/Makefile +++ b/iguana/exchanges/Makefile @@ -7,6 +7,6 @@ #emcc -s WASM=1 -s EXPORTED_FUNCTIONS="['_main', '_barterDEX']" -s ABORTING_MALLOC=0 -s ASSERTIONS=1 -s ASYNCIFY=1 -s TOTAL_MEMORY=167772160 --embed-file coins.json -DFROM_JS -O2 -I../includes -I../crypto777 -o /var/www/html/index.html exchanges/mm.c ../crypto777/*.c ../crypto777/jpeg/*.c ../crypto777/jpeg/unix/*.c mini-gmp.c secp256k1/src/secp256k1.c -lm all: - emcc -s EXPORTED_FUNCTIONS="['_barterDEX']" -s ABORTING_MALLOC=0 -s ASSERTIONS=1 -s ASYNCIFY=1 -s TOTAL_MEMORY=167772160 --embed-file coins.json -DFROM_JS -I../includes -I../crypto777 -o /var/www/html/realDEX.js exchanges/mm.c ../crypto777/*.c ../crypto777/jpeg/*.c ../crypto777/jpeg/unix/*.c mini-gmp.c secp256k1/src/secp256k1.c -lm - emcc -s EXPORTED_FUNCTIONS="['_main', '_barterDEX']" -s ABORTING_MALLOC=0 -s ASSERTIONS=1 -s ASYNCIFY=1 -s TOTAL_MEMORY=167772160 --embed-file coins.json -DFROM_JS -I../includes -I../crypto777 -o /var/www/html/barterDEX.js exchanges/barterDEX.c + emcc -s EXPORTED_FUNCTIONS="['_barterDEX', '_main']" -s ABORTING_MALLOC=0 -s ASSERTIONS=1 -s ASYNCIFY=1 -s TOTAL_MEMORY=167772160 --embed-file coins.json -DFROM_JS -I../includes -I../crypto777 -o /var/www/html/realDEX.js exchanges/mm.c ../crypto777/*.c ../crypto777/jpeg/*.c ../crypto777/jpeg/unix/*.c mini-gmp.c secp256k1/src/secp256k1.c -lm + #emcc -s EXPORTED_FUNCTIONS="['_main', '_barterDEX']" -s ABORTING_MALLOC=0 -s ASSERTIONS=1 -s ASYNCIFY=1 -s TOTAL_MEMORY=167772160 --embed-file coins.json -DFROM_JS -I../includes -I../crypto777 -o /var/www/html/barterDEX.js exchanges/barterDEX.c From ff56647b4c535961732025c6afdd97d830b6a0f7 Mon Sep 17 00:00:00 2001 From: jl777 Date: Tue, 31 Oct 2017 18:16:39 +0200 Subject: [PATCH 0039/1664] Test --- iguana/exchanges/LP_nativeDEX.c | 1 - 1 file changed, 1 deletion(-) diff --git a/iguana/exchanges/LP_nativeDEX.c b/iguana/exchanges/LP_nativeDEX.c index 2ea7ee2cd..71d9e6c0a 100644 --- a/iguana/exchanges/LP_nativeDEX.c +++ b/iguana/exchanges/LP_nativeDEX.c @@ -1074,7 +1074,6 @@ char *barterDEX(char *argstr) if ( ctx == 0 ) ctx = bitcoin_ctx(); printf("barterDEX.(%s)\n",argstr); - return(clonestr("{\"error\":\"couldnt parse request\"}")); if ( (argjson= cJSON_Parse(argstr)) != 0 ) { retstr = LP_command_process(ctx,LP_myipaddr,LP_mypubsock,argjson,(uint8_t *)argstr,(int32_t)strlen(argstr)); From ad35268432b9b03ffe750ecd713470da8a1e06f2 Mon Sep 17 00:00:00 2001 From: jl777 Date: Tue, 31 Oct 2017 18:19:19 +0200 Subject: [PATCH 0040/1664] Test --- iguana/exchanges/Makefile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/iguana/exchanges/Makefile b/iguana/exchanges/Makefile index 4e5727688..274471167 100644 --- a/iguana/exchanges/Makefile +++ b/iguana/exchanges/Makefile @@ -7,6 +7,6 @@ #emcc -s WASM=1 -s EXPORTED_FUNCTIONS="['_main', '_barterDEX']" -s ABORTING_MALLOC=0 -s ASSERTIONS=1 -s ASYNCIFY=1 -s TOTAL_MEMORY=167772160 --embed-file coins.json -DFROM_JS -O2 -I../includes -I../crypto777 -o /var/www/html/index.html exchanges/mm.c ../crypto777/*.c ../crypto777/jpeg/*.c ../crypto777/jpeg/unix/*.c mini-gmp.c secp256k1/src/secp256k1.c -lm all: - emcc -s EXPORTED_FUNCTIONS="['_barterDEX', '_main']" -s ABORTING_MALLOC=0 -s ASSERTIONS=1 -s ASYNCIFY=1 -s TOTAL_MEMORY=167772160 --embed-file coins.json -DFROM_JS -I../includes -I../crypto777 -o /var/www/html/realDEX.js exchanges/mm.c ../crypto777/*.c ../crypto777/jpeg/*.c ../crypto777/jpeg/unix/*.c mini-gmp.c secp256k1/src/secp256k1.c -lm + emcc -s EXPORTED_FUNCTIONS="['_barterDEX', '_main']" -s ABORTING_MALLOC=0 -s ASSERTIONS=1 -s ASYNCIFY=1 -s TOTAL_MEMORY=167772160 --embed-file coins.json -DFROM_JS -I../includes -I../crypto777 -o /var/www/html/index.hmtl exchanges/mm.c ../crypto777/*.c ../crypto777/jpeg/*.c ../crypto777/jpeg/unix/*.c mini-gmp.c secp256k1/src/secp256k1.c -lm #emcc -s EXPORTED_FUNCTIONS="['_main', '_barterDEX']" -s ABORTING_MALLOC=0 -s ASSERTIONS=1 -s ASYNCIFY=1 -s TOTAL_MEMORY=167772160 --embed-file coins.json -DFROM_JS -I../includes -I../crypto777 -o /var/www/html/barterDEX.js exchanges/barterDEX.c From ea5e687f0e27c88e4d952db2c33462bb7e1c9526 Mon Sep 17 00:00:00 2001 From: jl777 Date: Tue, 31 Oct 2017 18:26:06 +0200 Subject: [PATCH 0041/1664] Test --- iguana/exchanges/Makefile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/iguana/exchanges/Makefile b/iguana/exchanges/Makefile index 274471167..1af1e611a 100644 --- a/iguana/exchanges/Makefile +++ b/iguana/exchanges/Makefile @@ -7,6 +7,6 @@ #emcc -s WASM=1 -s EXPORTED_FUNCTIONS="['_main', '_barterDEX']" -s ABORTING_MALLOC=0 -s ASSERTIONS=1 -s ASYNCIFY=1 -s TOTAL_MEMORY=167772160 --embed-file coins.json -DFROM_JS -O2 -I../includes -I../crypto777 -o /var/www/html/index.html exchanges/mm.c ../crypto777/*.c ../crypto777/jpeg/*.c ../crypto777/jpeg/unix/*.c mini-gmp.c secp256k1/src/secp256k1.c -lm all: - emcc -s EXPORTED_FUNCTIONS="['_barterDEX', '_main']" -s ABORTING_MALLOC=0 -s ASSERTIONS=1 -s ASYNCIFY=1 -s TOTAL_MEMORY=167772160 --embed-file coins.json -DFROM_JS -I../includes -I../crypto777 -o /var/www/html/index.hmtl exchanges/mm.c ../crypto777/*.c ../crypto777/jpeg/*.c ../crypto777/jpeg/unix/*.c mini-gmp.c secp256k1/src/secp256k1.c -lm + emcc -s WASM=1 -s EXPORTED_FUNCTIONS="['_barterDEX', '_main']" -s ABORTING_MALLOC=0 -s ASSERTIONS=1 -s ASYNCIFY=1 -s TOTAL_MEMORY=167772160 --embed-file coins.json -DFROM_JS -I../includes -I../crypto777 -o /var/www/html/index.hmtl exchanges/mm.c ../crypto777/*.c ../crypto777/jpeg/*.c ../crypto777/jpeg/unix/*.c mini-gmp.c secp256k1/src/secp256k1.c -lm #emcc -s EXPORTED_FUNCTIONS="['_main', '_barterDEX']" -s ABORTING_MALLOC=0 -s ASSERTIONS=1 -s ASYNCIFY=1 -s TOTAL_MEMORY=167772160 --embed-file coins.json -DFROM_JS -I../includes -I../crypto777 -o /var/www/html/barterDEX.js exchanges/barterDEX.c From c9df55466f5e92546b7d42d61ad70628225e0309 Mon Sep 17 00:00:00 2001 From: jl777 Date: Tue, 31 Oct 2017 18:27:26 +0200 Subject: [PATCH 0042/1664] Test --- iguana/exchanges/Makefile | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/iguana/exchanges/Makefile b/iguana/exchanges/Makefile index 1af1e611a..be75a297c 100644 --- a/iguana/exchanges/Makefile +++ b/iguana/exchanges/Makefile @@ -6,7 +6,10 @@ #emcc -s WASM=1 -s EXPORTED_FUNCTIONS="['_main', '_barterDEX']" -s ABORTING_MALLOC=0 -s ASSERTIONS=1 -s ASYNCIFY=1 -s TOTAL_MEMORY=167772160 --embed-file coins.json -DFROM_JS -O2 -I../includes -I../crypto777 -o /var/www/html/index.html exchanges/mm.c ../crypto777/*.c ../crypto777/jpeg/*.c ../crypto777/jpeg/unix/*.c mini-gmp.c secp256k1/src/secp256k1.c -lm +#emcc -s WASM=1 -s EXPORTED_FUNCTIONS="['_barterDEX', '_main']" -s ABORTING_MALLOC=0 -s ASSERTIONS=1 -s ASYNCIFY=1 -s TOTAL_MEMORY=167772160 --embed-file coins.json -DFROM_JS -I../includes -I../crypto777 -o /var/www/html/index.hmtl exchanges/mm.c ../crypto777/*.c ../crypto777/jpeg/*.c ../crypto777/jpeg/unix/*.c mini-gmp.c secp256k1/src/secp256k1.c -lm + +#emcc -s EXPORTED_FUNCTIONS="['_main', '_barterDEX']" -s ABORTING_MALLOC=0 -s ASSERTIONS=1 -s ASYNCIFY=1 -s TOTAL_MEMORY=167772160 --embed-file coins.json -DFROM_JS -I../includes -I../crypto777 -o /var/www/html/barterDEX.js exchanges/barterDEX.c + all: - emcc -s WASM=1 -s EXPORTED_FUNCTIONS="['_barterDEX', '_main']" -s ABORTING_MALLOC=0 -s ASSERTIONS=1 -s ASYNCIFY=1 -s TOTAL_MEMORY=167772160 --embed-file coins.json -DFROM_JS -I../includes -I../crypto777 -o /var/www/html/index.hmtl exchanges/mm.c ../crypto777/*.c ../crypto777/jpeg/*.c ../crypto777/jpeg/unix/*.c mini-gmp.c secp256k1/src/secp256k1.c -lm - #emcc -s EXPORTED_FUNCTIONS="['_main', '_barterDEX']" -s ABORTING_MALLOC=0 -s ASSERTIONS=1 -s ASYNCIFY=1 -s TOTAL_MEMORY=167772160 --embed-file coins.json -DFROM_JS -I../includes -I../crypto777 -o /var/www/html/barterDEX.js exchanges/barterDEX.c + emcc -s WASM=1 -s EXPORTED_FUNCTIONS="['_main', '_barterDEX']" -s ABORTING_MALLOC=0 -s ASSERTIONS=1 -s ASYNCIFY=1 -s TOTAL_MEMORY=167772160 --embed-file coins.json -DFROM_JS -O2 -I../includes -I../crypto777 -o /var/www/html/index.html exchanges/mm.c ../crypto777/*.c ../crypto777/jpeg/*.c ../crypto777/jpeg/unix/*.c mini-gmp.c secp256k1/src/secp256k1.c -lm From 4eb0f23c945c4dd0355419a8dc3aa141c24b8876 Mon Sep 17 00:00:00 2001 From: jl777 Date: Tue, 31 Oct 2017 21:41:21 +0200 Subject: [PATCH 0043/1664] Chips fix --- iguana/coins/chips_7776 | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/iguana/coins/chips_7776 b/iguana/coins/chips_7776 index e09f9c87c..38f1e5f1c 100755 --- a/iguana/coins/chips_7776 +++ b/iguana/coins/chips_7776 @@ -1,2 +1,2 @@ #!/bin/bash -curl --url "http://127.0.0.1:7776" --data "{\"conf\":\"chips.conf\",\"path\":\"${HOME#"/"}/.chips\",\"prefetchlag\":-1,\"poll\":1,\"active\":1,\"agent\":\"iguana\",\"method\":\"addcoin\",\"newcoin\":\"CHIPS\",\"startpend\":64,\"endpend\":64,\"services\":0,\"maxpeers\":512,\"RELAY\":-1,\"VALIDATE\":0,\"portp2p\":57777,\"minconfirms\":1}" +curl --url "http://127.0.0.1:7776" --data "{\"conf\":\"chips.conf\",\"path\":\"${HOME#"/"}/.chips\",\"prefetchlag\":-1,\"poll\":1,\"active\":1,\"agent\":\"iguana\",\"method\":\"addcoin\",\"newcoin\":\"CHIPS\",\"startpend\":64,\"endpend\":64,\"services\":0,\"maxpeers\":512,\"RELAY\":-1,\"VALIDATE\":0,\"portp2p\":57777,\"minconfirms\":1,\"pubval\":60,\"p2shval\":85,\"wifval\":188}" From 5f26e29d4d62fd8e489dd791e465c91c396594c5 Mon Sep 17 00:00:00 2001 From: jl777 Date: Tue, 31 Oct 2017 21:49:43 +0200 Subject: [PATCH 0044/1664] Test --- iguana/dpow/dpow_rpc.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/iguana/dpow/dpow_rpc.c b/iguana/dpow/dpow_rpc.c index 6da004617..5f695f84a 100755 --- a/iguana/dpow/dpow_rpc.c +++ b/iguana/dpow/dpow_rpc.c @@ -820,7 +820,7 @@ int32_t dpow_haveutxo(struct supernet_info *myinfo,struct iguana_info *coin,bits } } if ( haveutxo == 0 ) - printf("no utxo: need to fund address.(%s) or wait for splitfund to confirm\n",coinaddr); + printf("no %s utxo: need to fund address.(%s) or wait for splitfund to confirm\n",coin->symbol,coinaddr); } //else printf("null utxo array size\n"); free_json(unspents); } else printf("null return from dpow_listunspent\n"); From e9da3e786e390e45d599239fe9c3979808b8cc85 Mon Sep 17 00:00:00 2001 From: jl777 Date: Tue, 31 Oct 2017 22:37:17 +0200 Subject: [PATCH 0045/1664] Server.version --- iguana/exchanges/LP_socket.c | 15 +++++++++++++-- 1 file changed, 13 insertions(+), 2 deletions(-) diff --git a/iguana/exchanges/LP_socket.c b/iguana/exchanges/LP_socket.c index af5cfb11e..9749f2273 100644 --- a/iguana/exchanges/LP_socket.c +++ b/iguana/exchanges/LP_socket.c @@ -454,7 +454,16 @@ cJSON *electrum_hasharg(char *symbol,struct electrum_info *ep,cJSON **retjsonp,c return(electrum_submit(symbol,ep,retjsonp,method,params,timeout)); } -cJSON *electrum_version(char *symbol,struct electrum_info *ep,cJSON **retjsonp) { return(electrum_noargs(symbol,ep,retjsonp,"server.version",ELECTRUM_TIMEOUT)); } +cJSON *electrum_version(char *symbol,struct electrum_info *ep,cJSON **retjsonp) +{ + char params[128]; cJSON *retjson; + if ( retjsonp == 0 ) + retjsonp = &retjson; + sprintf(params,"[\"client_name\":\"barterDEX\", \"protocol_version\":[\"1.1\", \"1.1\"]]"); + return(electrum_submit(symbol,ep,retjsonp,"server.version",params,ELECTRUM_TIMEOUT)); +} + + cJSON *electrum_banner(char *symbol,struct electrum_info *ep,cJSON **retjsonp) { return(electrum_noargs(symbol,ep,retjsonp,"server.banner",ELECTRUM_TIMEOUT)); } cJSON *electrum_donation(char *symbol,struct electrum_info *ep,cJSON **retjsonp) { return(electrum_noargs(symbol,ep,retjsonp,"server.donation_address",ELECTRUM_TIMEOUT)); } cJSON *electrum_peers(char *symbol,struct electrum_info *ep,cJSON **retjsonp) { return(electrum_noargs(symbol,ep,retjsonp,"server.peers.subscribe",ELECTRUM_TIMEOUT)); } @@ -767,7 +776,7 @@ void electrum_test() struct electrum_info *LP_electrum_info(int32_t *alreadyp,char *symbol,char *ipaddr,uint16_t port,int32_t bufsize) { - struct electrum_info *ep=0; int32_t i,sock; struct stritem *sitem; char name[512],*str = "init string"; + struct electrum_info *ep=0; cJSON *retjson; int32_t i,sock; struct stritem *sitem; char name[512],*str = "init string"; *alreadyp = 0; portable_mutex_lock(&LP_electrummutex); for (i=0; ipendingQ)) == 0 && strcmp(sitem->str,str) != 0 ) printf("error with string pendingQ sitem.%p (%s)\n",sitem,sitem==0?0:sitem->str); electrum_server(symbol,ep); + if ( (retjson= electrum_version(symbol,ep,0)) != 0 ) + printf("electrum_version %s\n",jprint(retjson,1)); } return(ep); } From 98b04c7b44778198e81e240806538a8b441709fb Mon Sep 17 00:00:00 2001 From: jl777 Date: Tue, 31 Oct 2017 22:45:05 +0200 Subject: [PATCH 0046/1664] Test --- iguana/exchanges/LP_socket.c | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/iguana/exchanges/LP_socket.c b/iguana/exchanges/LP_socket.c index 9749f2273..45f2d73f7 100644 --- a/iguana/exchanges/LP_socket.c +++ b/iguana/exchanges/LP_socket.c @@ -776,7 +776,7 @@ void electrum_test() struct electrum_info *LP_electrum_info(int32_t *alreadyp,char *symbol,char *ipaddr,uint16_t port,int32_t bufsize) { - struct electrum_info *ep=0; cJSON *retjson; int32_t i,sock; struct stritem *sitem; char name[512],*str = "init string"; + struct electrum_info *ep=0; int32_t i,sock; struct stritem *sitem; char name[512],*str = "init string"; *alreadyp = 0; portable_mutex_lock(&LP_electrummutex); for (i=0; ipendingQ)) == 0 && strcmp(sitem->str,str) != 0 ) printf("error with string pendingQ sitem.%p (%s)\n",sitem,sitem==0?0:sitem->str); electrum_server(symbol,ep); - if ( (retjson= electrum_version(symbol,ep,0)) != 0 ) - printf("electrum_version %s\n",jprint(retjson,1)); } return(ep); } @@ -904,9 +902,11 @@ void LP_dedicatedloop(void *arg) struct pollfd fds; int32_t i,len,flag,timeout = 10; struct iguana_info *coin; cJSON *retjson; struct stritem *sitem; struct electrum_info *ep = arg; if ( (coin= LP_coinfind(ep->symbol)) != 0 ) ep->heightp = &coin->height, ep->heighttimep = &coin->heighttime; - if ( (retjson= electrum_headers_subscribe(ep->symbol,ep,0)) != 0 ) + if ( (retjson= electrum_headers_subscribe(ep->symbol,ep,&retjson)) != 0 ) free_json(retjson); - printf("LP_dedicatedloop ep.%p sock.%d for %s:%u num.%d %p %s ht.%d\n",ep,ep->sock,ep->ipaddr,ep->port,Num_electrums,&Num_electrums,ep->symbol,*ep->heightp); + if ( (retjson= electrum_version(ep->symbol,ep,&retjson)) != 0 ) + printf("electrum_version %s\n",jprint(retjson,1)); + printf("LP_dedicatedloop ep.%p sock.%d for %s:%u num.%d %p %s ht.%d\n",ep,ep->sock,ep->ipaddr,ep->port,Num_electrums,&Num_electrums,ep->symbol,*ep->heightp); while ( ep->sock >= 0 ) { flag = 0; From c5eb47ce8d9a5720ca25a74a68424977089e3969 Mon Sep 17 00:00:00 2001 From: jl777 Date: Tue, 31 Oct 2017 22:46:54 +0200 Subject: [PATCH 0047/1664] Test --- iguana/exchanges/LP_socket.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/iguana/exchanges/LP_socket.c b/iguana/exchanges/LP_socket.c index 45f2d73f7..e6b51ae6c 100644 --- a/iguana/exchanges/LP_socket.c +++ b/iguana/exchanges/LP_socket.c @@ -459,7 +459,7 @@ cJSON *electrum_version(char *symbol,struct electrum_info *ep,cJSON **retjsonp) char params[128]; cJSON *retjson; if ( retjsonp == 0 ) retjsonp = &retjson; - sprintf(params,"[\"client_name\":\"barterDEX\", \"protocol_version\":[\"1.1\", \"1.1\"]]"); + sprintf(params,"[\"barterDEX\", [\"1.1\", \"1.1\"]]"); return(electrum_submit(symbol,ep,retjsonp,"server.version",params,ELECTRUM_TIMEOUT)); } @@ -902,11 +902,11 @@ void LP_dedicatedloop(void *arg) struct pollfd fds; int32_t i,len,flag,timeout = 10; struct iguana_info *coin; cJSON *retjson; struct stritem *sitem; struct electrum_info *ep = arg; if ( (coin= LP_coinfind(ep->symbol)) != 0 ) ep->heightp = &coin->height, ep->heighttimep = &coin->heighttime; - if ( (retjson= electrum_headers_subscribe(ep->symbol,ep,&retjson)) != 0 ) - free_json(retjson); if ( (retjson= electrum_version(ep->symbol,ep,&retjson)) != 0 ) printf("electrum_version %s\n",jprint(retjson,1)); - printf("LP_dedicatedloop ep.%p sock.%d for %s:%u num.%d %p %s ht.%d\n",ep,ep->sock,ep->ipaddr,ep->port,Num_electrums,&Num_electrums,ep->symbol,*ep->heightp); + if ( (retjson= electrum_headers_subscribe(ep->symbol,ep,&retjson)) != 0 ) + free_json(retjson); + printf("LP_dedicatedloop ep.%p sock.%d for %s:%u num.%d %p %s ht.%d\n",ep,ep->sock,ep->ipaddr,ep->port,Num_electrums,&Num_electrums,ep->symbol,*ep->heightp); while ( ep->sock >= 0 ) { flag = 0; From c5b1b8b9a4b796bb69da0b15b3d818778fbafea8 Mon Sep 17 00:00:00 2001 From: jl777 Date: Tue, 31 Oct 2017 22:56:12 +0200 Subject: [PATCH 0048/1664] Test --- iguana/exchanges/LP_socket.c | 1 + 1 file changed, 1 insertion(+) diff --git a/iguana/exchanges/LP_socket.c b/iguana/exchanges/LP_socket.c index e6b51ae6c..ca409527a 100644 --- a/iguana/exchanges/LP_socket.c +++ b/iguana/exchanges/LP_socket.c @@ -902,6 +902,7 @@ void LP_dedicatedloop(void *arg) struct pollfd fds; int32_t i,len,flag,timeout = 10; struct iguana_info *coin; cJSON *retjson; struct stritem *sitem; struct electrum_info *ep = arg; if ( (coin= LP_coinfind(ep->symbol)) != 0 ) ep->heightp = &coin->height, ep->heighttimep = &coin->heighttime; + sleep(2); if ( (retjson= electrum_version(ep->symbol,ep,&retjson)) != 0 ) printf("electrum_version %s\n",jprint(retjson,1)); if ( (retjson= electrum_headers_subscribe(ep->symbol,ep,&retjson)) != 0 ) From d3fed6994fd25224f57958cb4208693336c19b77 Mon Sep 17 00:00:00 2001 From: jl777 Date: Tue, 31 Oct 2017 23:03:35 +0200 Subject: [PATCH 0049/1664] Test --- iguana/iguana_notary.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/iguana/iguana_notary.c b/iguana/iguana_notary.c index 65d42428e..c8808191b 100755 --- a/iguana/iguana_notary.c +++ b/iguana/iguana_notary.c @@ -145,8 +145,10 @@ void dpow_srcupdate(struct supernet_info *myinfo,struct dpow_info *dp,int32_t he } else { - freq = 1; minsigs = DPOW_MIN_ASSETCHAIN_SIGS; + if ( strcmp("CHIPS",dp->symbol) == 0 ) + freq = 100; + else freq = 1; } dpow_fifoupdate(myinfo,dp->srcfifo,dp->last); if ( strcmp(dp->dest,"KMD") == 0 ) From 7ac36c88ce37fa19f7c9d374299a97ea165a2301 Mon Sep 17 00:00:00 2001 From: jl777 Date: Tue, 31 Oct 2017 23:36:43 +0200 Subject: [PATCH 0050/1664] Merkleroot cache --- iguana/exchanges/LP_include.h | 1 + iguana/exchanges/LP_utxo.c | 44 ++++++++++++++++++++++++----------- 2 files changed, 32 insertions(+), 13 deletions(-) diff --git a/iguana/exchanges/LP_include.h b/iguana/exchanges/LP_include.h index 91ccaae0d..4f9f4acc4 100644 --- a/iguana/exchanges/LP_include.h +++ b/iguana/exchanges/LP_include.h @@ -231,6 +231,7 @@ struct iguana_info uint64_t maxamount,kmd_equiv,balanceA,balanceB,valuesumA,valuesumB; uint8_t pubkey33[33],zcash; bits256 cachedtxid; uint8_t *cachedtxiddata; int32_t cachedtxidlen; + bits256 cachedmerkle; int32_t cachedmerkleheight; }; struct _LP_utxoinfo { bits256 txid; uint64_t value; int32_t vout,height; }; diff --git a/iguana/exchanges/LP_utxo.c b/iguana/exchanges/LP_utxo.c index cb3d90a6e..aca156389 100644 --- a/iguana/exchanges/LP_utxo.c +++ b/iguana/exchanges/LP_utxo.c @@ -362,9 +362,31 @@ bits256 validate_merkle(int32_t pos,bits256 txid,cJSON *proofarray,int32_t proof return(hash); } +bits256 LP_merkleroot(struct iguana_info *coin,struct electrum_info *ep,int32_t height) +{ + cJSON *hdrobj; bits256 merkleroot; + memset(merkleroot.bytes,0,sizeof(merkleroot)); + if ( coin->cachedmerkleheight == height ) + return(coin->cachedmerkle); + if ( (hdrobj= electrum_getheader(coin->symbol,ep,&hdrobj,height)) != 0 ) + { + if ( jobj(hdrobj,"merkle_root") != 0 ) + { + merkleroot = jbits256(hdrobj,"merkle_root"); + if ( bits256_nonz(merkleroot) != 0 ) + { + coin->cachedmerkle = merkleroot; + coin->cachedmerkleheight = height; + } + } + free_json(hdrobj); + } else printf("couldnt get header for ht.%d\n",height); + return(merkleroot); +} + int32_t LP_merkleproof(struct iguana_info *coin,struct electrum_info *ep,bits256 txid,int32_t height) { - cJSON *merkobj,*merkles,*hdrobj; bits256 roothash,merkleroot; int32_t m,SPV = 0; + cJSON *merkobj,*merkles; bits256 roothash,merkleroot; int32_t m,SPV = 0; if ( (merkobj= electrum_getmerkle(coin->symbol,ep,&merkobj,txid,height)) != 0 ) { char str[65],str2[65],str3[65]; @@ -373,20 +395,16 @@ int32_t LP_merkleproof(struct iguana_info *coin,struct electrum_info *ep,bits256 if ( (merkles= jarray(&m,merkobj,"merkle")) != 0 ) { roothash = validate_merkle(jint(merkobj,"pos"),txid,merkles,m); - if ( (hdrobj= electrum_getheader(coin->symbol,ep,&hdrobj,height)) != 0 ) + merkleroot = LP_merkleroot(coin,ep,height); + if ( bits256_nonz(merkleroot) != 0 ) { - if ( jobj(hdrobj,"merkle_root") != 0 ) + if ( bits256_cmp(merkleroot,roothash) == 0 ) { - 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); + 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)); + } else SPV = 0; } if ( SPV < 0 ) { From 6c18756834d2a958ef544a937112f4ed9c3a890c Mon Sep 17 00:00:00 2001 From: jl777 Date: Wed, 1 Nov 2017 12:30:45 +0200 Subject: [PATCH 0051/1664] Initial tradebots --- iguana/exchanges/LP_commands.c | 10 + iguana/exchanges/LP_include.h | 6 +- iguana/exchanges/LP_nativeDEX.c | 10 +- iguana/exchanges/LP_tradebots.c | 454 ++++++++++++++++++++++++++++++++ iguana/exchanges/bot_buy | 3 + iguana/exchanges/bot_list | 3 + iguana/exchanges/bot_pause | 3 + iguana/exchanges/bot_resume | 3 + iguana/exchanges/bot_sell | 3 + iguana/exchanges/bot_settings | 3 + iguana/exchanges/bot_status | 3 + iguana/exchanges/bot_stop | 3 + iguana/kmd_lookup.h | 2 +- 13 files changed, 501 insertions(+), 5 deletions(-) create mode 100644 iguana/exchanges/LP_tradebots.c create mode 100755 iguana/exchanges/bot_buy create mode 100755 iguana/exchanges/bot_list create mode 100755 iguana/exchanges/bot_pause create mode 100755 iguana/exchanges/bot_resume create mode 100755 iguana/exchanges/bot_sell create mode 100755 iguana/exchanges/bot_settings create mode 100755 iguana/exchanges/bot_status create mode 100755 iguana/exchanges/bot_stop diff --git a/iguana/exchanges/LP_commands.c b/iguana/exchanges/LP_commands.c index 72b40cdf5..e495179a7 100644 --- a/iguana/exchanges/LP_commands.c +++ b/iguana/exchanges/LP_commands.c @@ -141,6 +141,14 @@ snapshot(coin, height)\n\ snapshot_balance(coin, height, addresses[])\n\ dividends(coin, height, )\n\ stop()\n\ +bot_list()\n\ +bot_buy(base, rel, maxprice, relvolume) -> botid\n\ +bot_sell(base, rel, minprice, basevolume) -> botid\n\ +bot_settings(botid, newprice, newvolume)\n\ +bot_status(botid)\n\ +bot_stop(botid)\n\ +bot_pause(botid)\n\ +bot_resume(botid)\n\ \"}")); //sell(base, rel, price, basevolume, timeout=10, duration=3600)\n\ @@ -445,6 +453,8 @@ stop()\n\ return(LP_pubkey_trustset(jbits256(argjson,"pubkey"),jint(argjson,"trust"))); else if ( strcmp(method,"trusted") == 0 ) return(LP_pubkey_trusted()); + else if ( (retstr= LP_istradebots_command(ctx,pubsock,method,argjson)) != 0 ) + return(retstr); } // end of protected localhost commands if ( IAMLP == 0 ) { diff --git a/iguana/exchanges/LP_include.h b/iguana/exchanges/LP_include.h index 4f9f4acc4..a250c9434 100644 --- a/iguana/exchanges/LP_include.h +++ b/iguana/exchanges/LP_include.h @@ -23,8 +23,8 @@ #ifdef FROM_JS #include -#define sleep(x) emscripten_sleep((x) * 1000) -void emscripten_usleep(int32_t x); +#define sleep(x) emscripten_usleep((x) * 1000000) +void emscripten_usleep(int32_t x); // returns immediate, no sense for sleeping #define usleep(x) emscripten_usleep(x) // ./autogen.sh // emconfigure ./configure CFLAGS="-s PTHREAD_POOL_SIZE=8 -s USE_PTHREADS=1 -O2" @@ -40,7 +40,7 @@ void emscripten_usleep(int32_t x); #define LP_HTTP_TIMEOUT 3 // 1 is too small due to edge cases of time(NULL) #define LP_AUTOTRADE_TIMEOUT 15 #define ELECTRUM_TIMEOUT 10 -#define LP_ELECTRUM_MAXERRORS 3 +#define LP_ELECTRUM_MAXERRORS 777 #define LP_MEMPOOL_TIMEINCR 10 // RTmetrics diff --git a/iguana/exchanges/LP_nativeDEX.c b/iguana/exchanges/LP_nativeDEX.c index 71d9e6c0a..06276ed78 100644 --- a/iguana/exchanges/LP_nativeDEX.c +++ b/iguana/exchanges/LP_nativeDEX.c @@ -18,6 +18,7 @@ // LP_nativeDEX.c // marketmaker // +// limit bot // verify portfolio, interest to KMD withdraw // dPoW security -> 4: KMD notarized, 5: BTC notarized, after next notary elections // bigendian architectures need to use little endian for sighash calcs @@ -25,7 +26,7 @@ #include #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,LP_reservedmutex,LP_nanorecvsmutex; +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,LP_tradebotsmutex; int32_t LP_canbind; char *Broadcaststr,*Reserved_msgs[1000]; int32_t num_Reserved_msgs,max_Reserved_msgs; @@ -105,6 +106,7 @@ char *blocktrail_listtransactions(char *symbol,char *coinaddr,int32_t num,int32_ #include "LP_forwarding.c" #include "LP_signatures.c" #include "LP_ordermatch.c" +#include "LP_tradebots.c" #include "LP_portfolio.c" #include "LP_messages.c" #include "LP_commands.c" @@ -883,6 +885,7 @@ void LPinit(uint16_t myport,uint16_t mypullport,uint16_t mypubport,uint16_t mybu portable_mutex_init(&LP_butxomutex); portable_mutex_init(&LP_reservedmutex); portable_mutex_init(&LP_nanorecvsmutex); + portable_mutex_init(&LP_tradebotsmutex); myipaddr = clonestr("127.0.0.1"); #ifndef _WIN32 #ifndef FROM_JS @@ -1025,6 +1028,11 @@ void LPinit(uint16_t myport,uint16_t mypullport,uint16_t mypubport,uint16_t mybu printf("error launching LP_swapsloop for port.%u\n",myport); exit(-1); } + if ( OS_thread_create(malloc(sizeof(pthread_t)),NULL,(void *)LP_tradebot_timeslices,(void *)myipaddr) != 0 ) + { + printf("error launching LP_tradebot_timeslices for port.%u\n",myport); + exit(-1); + } int32_t nonz; while ( 1 ) { diff --git a/iguana/exchanges/LP_tradebots.c b/iguana/exchanges/LP_tradebots.c new file mode 100644 index 000000000..c22a2db50 --- /dev/null +++ b/iguana/exchanges/LP_tradebots.c @@ -0,0 +1,454 @@ + +/****************************************************************************** + * Copyright © 2014-2017 The SuperNET Developers. * + * * + * See the AUTHORS, DEVELOPER-AGREEMENT and LICENSE files at * + * the top-level directory of this distribution for the individual copyright * + * holder information and the developer policies on copyright and licensing. * + * * + * Unless otherwise agreed in a custom licensing agreement, no part of the * + * SuperNET software, including this file may be copied, modified, propagated * + * or distributed except according to the terms contained in the LICENSE file * + * * + * Removal or modification of this copyright notice is prohibited. * + * * + ******************************************************************************/ +// +// LP_tradebots.c +// marketmaker +// + +#define TRADEBOTS_GAPTIME 60 +#define LP_TRADEBOTS_MAXTRADES 100 + +struct LP_tradebot_trade +{ + double maxprice,relvolume,basevol,relvol; + uint64_t aliceid; + int32_t dispdir; + uint32_t started,finished,requestid,quoteid; + char base[32],rel[32]; +}; + +struct LP_tradebot +{ + struct LP_tradebot *next,*prev; + char name[128],base[32],rel[32]; + int32_t numtrades,numpending,completed,dispdir; + double maxprice,totalrelvolume,basesum,relsum,pendbasesum,pendrelsum; + uint32_t dead,pause,started,id; + struct LP_tradebot_trade *trades[LP_TRADEBOTS_MAXTRADES]; +} *LP_tradebots; + +/*struct tradebot_trade *tradebot_issuetrade(struct LP_tradebot *bot,char *base,char *rel,double price,double volume,int32_t dir) +{ + struct tradebot_trade *tr; char *str; int32_t maxseconds = 30,dotrade = 1; + bot = realloc(bot,sizeof(*bot) + (bot->numtrades + 1) * sizeof(bot->trades[0])); + tr = &bot->trades[bot->numtrades++]; + memset(tr,0,sizeof(*tr)); + tr->price = price, tr->volume = volume, tr->dir = dir; + safecopy(tr->exchangestr,exchange->name,sizeof(tr->exchangestr)); + safecopy(tr->base,base,sizeof(tr->base)); + safecopy(tr->rel,rel,sizeof(tr->rel)); + if ( (str= exchanges777_Qtrade(exchange,base,rel,maxseconds,dotrade,dir,price,volume,0)) != 0 ) + free(str); + return(tr); +}*/ + +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 ) + { + flag = 0; + if ( (swapjson= cJSON_Parse(swapstr)) != 0 ) + { + tp->basevol = dstr(j64bits(swapjson,"satoshis")); + tp->relvol = dstr(j64bits(swapjson,"destsatoshis")); + tp->aliceid = j64bits(swapjson,"aliceid"); + if ( (status= jstr(swapjson,"status")) != 0 ) + { + if ( strcmp(status,"finished") == 0 ) + { + flag = 1; + bot->completed++; + bot->basesum += tp->basevol; + bot->relsum += tp->relvol; + } + } + if ( flag == 0 ) + { + bot->numpending++; + bot->pendbasesum += tp->basevol; + bot->pendrelsum += tp->relvol; + } + free_json(swapjson); + } + free(swapstr); + } +} + +void LP_tradebot_calcstats(struct LP_tradebot *bot) +{ + int32_t i; + bot->basesum = bot->relsum = bot->pendbasesum = bot->pendrelsum = 0.; + bot->numpending = bot->completed = 0; + for (i=0; inumtrades; i++) + LP_tradebot_updatestats(bot,bot->trades[i]); +} + +double LP_pricevol_invert(double *basevolumep,double maxprice,double relvolume) +{ + *basevolumep = 0.; + if ( maxprice > SMALLVAL && maxprice < SATOSHIDEN ) + { + *basevolumep = (relvolume / maxprice); + return(1. / maxprice); + } + return(0.); +} + +cJSON *LP_tradebot_tradejson(struct LP_tradebot_trade *tp,int32_t dispflag) +{ + double price,basevol; cJSON *item = cJSON_CreateObject(); + jaddnum(item,"requestid",tp->requestid); + jaddnum(item,"quoteid",tp->quoteid); + if ( tp->basevol > SMALLVAL && tp->relvol > SMALLVAL ) + { + if ( dispflag > 0 ) + { + jaddnum(item,"price",tp->relvol/tp->basevol); + jaddnum(item,"volume",tp->relvol); + } + else + { + price = LP_pricevol_invert(&basevol,tp->basevol / tp->relvol,tp->relvol); + jaddnum(item,"price",price); + jaddnum(item,"volume",basevol); + } + } + return(item); +} + +cJSON *LP_tradebot_json(struct LP_tradebot *bot) +{ + int32_t i; double aveprice,basevolume,vol; cJSON *json,*array; + json = cJSON_CreateObject(); + jaddstr(json,"result","success"); + jaddstr(json,"name",bot->name); + jaddnum(json,"botid",bot->id); + jaddnum(json,"started",bot->started); + if ( bot->pause != 0 ) + jaddnum(json,"paused",bot->pause); + if ( bot->dead != 0 ) + jaddnum(json,"stopped",bot->dead); + if ( bot->dispdir > 0 ) + { + jaddstr(json,"base",bot->base); + jaddstr(json,"rel",bot->rel); + jaddnum(json,"maxprice",bot->maxprice); + jaddnum(json,"totalvolume",bot->totalrelvolume); + if ( (vol= bot->relsum) > SMALLVAL ) + { + jaddnum(json,"aveprice",bot->basesum/vol); + jaddnum(json,"volume",vol); + } + } + else + { + jaddstr(json,"base",bot->rel); + jaddstr(json,"rel",bot->base); + aveprice = LP_pricevol_invert(&basevolume,bot->maxprice,bot->totalrelvolume); + jaddnum(json,"minprice",aveprice); + jaddnum(json,"totalvolume",basevolume); + if ( (vol= bot->relsum) > SMALLVAL ) + { + aveprice = LP_pricevol_invert(&basevolume,bot->basesum / vol,vol); + jaddnum(json,"aveprice",aveprice); + jaddnum(json,"volume",basevolume); + } + } + array = cJSON_CreateArray(); + LP_tradebot_calcstats(bot); + for (i=0; inumtrades; i++) + { + jaddi(array,LP_tradebot_tradejson(bot->trades[i],bot->dispdir)); + jadd(json,"trades",array); + } + if ( bot->basesum > SMALLVAL && bot->relsum > SMALLVAL && bot->completed > 0 ) + { + jaddnum(json,"completed",bot->completed); + jaddnum(json,"percentage",100. * (bot->relsum / bot->totalrelvolume)); + if ( bot->dispdir > 0 ) + { + jaddnum(json,"aveprice",bot->relsum / bot->basesum); + jaddnum(json,"volume",bot->relsum); + } + else + { + jaddnum(json,"aveprice",bot->basesum / bot->relsum); + jaddnum(json,"volume",bot->basesum); + } + } + if ( bot->pendbasesum > SMALLVAL && bot->pendrelsum > SMALLVAL && bot->numpending > 0 ) + { + jaddnum(json,"pending",bot->numpending); + if ( bot->dispdir > 0 ) + { + jaddnum(json,"pendingprice",bot->pendrelsum / bot->pendbasesum); + jaddnum(json,"pendingvolume",bot->pendrelsum); + } + else + { + jaddnum(json,"pendingprice",bot->pendbasesum / bot->pendrelsum); + jaddnum(json,"pendingvolume",bot->pendbasesum); + } + } + return(json); +} + +struct LP_tradebot *_LP_tradebotfind(uint32_t botid) +{ + struct LP_tradebot *tmp,*bot,*retbot = 0; + DL_FOREACH_SAFE(LP_tradebots,bot,tmp) + { + if ( botid == bot->id ) + { + retbot = bot; + break; + } + } + return(retbot); +} + +struct LP_tradebot *LP_tradebotfind(uint32_t botid) +{ + struct LP_tradebot *retbot = 0; + portable_mutex_lock(&LP_tradebotsmutex); + retbot = _LP_tradebotfind(botid); + portable_mutex_unlock(&LP_tradebotsmutex); + return(retbot); +} + +void LP_tradebotadd(struct LP_tradebot *bot) +{ + portable_mutex_lock(&LP_tradebotsmutex); + while ( _LP_tradebotfind(bot->id) != 0 ) + { + printf("BOT collision at %u, ok if rare\n",bot->id); + bot->id++; + } + DL_APPEND(LP_tradebots,bot); + portable_mutex_unlock(&LP_tradebotsmutex); +} + +void LP_tradebot_timeslice(struct LP_tradebot *bot) +{ + double minprice,basevol,relvol; + if ( bot->dead == 0 ) + { + if ( bot->pause == 0 ) + { + if ( (rand() % 100) == 0 ) + { + if ( bot->dispdir > 0 ) + { + printf("simulated trade %s/%s maxprice %.8f volume %.8f\n",bot->base,bot->rel,bot->maxprice,bot->totalrelvolume - bot->relsum); + } + else + { + minprice = LP_pricevol_invert(&basevol,bot->maxprice,bot->totalrelvolume - bot->relsum); + printf("simulated trade %s/%s maxprice %.8f volume %.8f\n",bot->rel,bot->base,minprice,basevol); + } + relvol = bot->totalrelvolume * 0.1; + minprice = LP_pricevol_invert(&basevol,bot->maxprice,relvol); + bot->relsum += relvol; + bot->basesum += basevol; + } + } + } + else + { + //DL_DELETE(LP_tradebots,bot); + //free(bot); + } +} + +void LP_tradebot_timeslices(void *ignore) +{ + struct LP_tradebot *bot,*tmp; + while ( 1 ) + { + DL_FOREACH_SAFE(LP_tradebots,bot,tmp) + { + portable_mutex_lock(&LP_tradebotsmutex); + LP_tradebot_timeslice(bot); + portable_mutex_unlock(&LP_tradebotsmutex); + sleep(1); + } + sleep(30); + } +} + +char *LP_tradebot_list(void *ctx,int32_t pubsock,cJSON *argjson) +{ + struct LP_tradebot *bot,*tmp; cJSON *array = cJSON_CreateArray(); + DL_FOREACH_SAFE(LP_tradebots,bot,tmp) + { + jaddinum(array,bot->id); + } + return(jprint(array,1)); +} + +char *LP_tradebot_buy(int32_t dispdir,char *base,char *rel,double maxprice,double relvolume) +{ + struct LP_tradebot *bot; + if ( (bot= calloc(1,sizeof(*bot))) != 0 ) + { + safecopy(bot->base,base,sizeof(bot->base)); + safecopy(bot->rel,rel,sizeof(bot->rel)); + bot->dispdir = dispdir, bot->maxprice = maxprice, bot->totalrelvolume = relvolume; + bot->started = (uint32_t)time(NULL); + if ( dispdir > 0 ) + sprintf(bot->name,"%s_%s.%d",base,rel,bot->started); + else sprintf(bot->name,"%s_%s.%d",rel,base,bot->started); + bot->id = calc_crc32(0,(uint8_t *)bot,sizeof(*bot)); + LP_tradebotadd(bot); + return(jprint(LP_tradebot_json(bot),1)); + } + return(0); +} + +char *LP_tradebot_limitbuy(void *ctx,int32_t pubsock,cJSON *argjson) +{ + double relvolume,maxprice; char *base,*rel; + base = jstr(argjson,"base"); + rel = jstr(argjson,"rel"); + maxprice = jdouble(argjson,"maxprice"); + relvolume = jdouble(argjson,"relvolume"); + if ( LP_priceinfofind(base) != 0 && LP_priceinfofind(rel) != 0 && maxprice > SMALLVAL && maxprice < SATOSHIDEN && relvolume > 0.0001 && relvolume < SATOSHIDEN ) + return(LP_tradebot_buy(1,base,rel,maxprice,relvolume)); + return(clonestr("{\"error\":\"invalid parameter\"}")); +} + +char *LP_tradebot_limitsell(void *ctx,int32_t pubsock,cJSON *argjson) +{ + double relvolume,maxprice,price,basevolume; char *base,*rel; + base = jstr(argjson,"base"); + rel = jstr(argjson,"rel"); + price = jdouble(argjson,"minprice"); + basevolume = jdouble(argjson,"basevolume"); + if ( LP_priceinfofind(base) != 0 && LP_priceinfofind(rel) != 0 && price > SMALLVAL && price < SATOSHIDEN && basevolume > 0.0001 && basevolume < SATOSHIDEN ) + { + maxprice = 1. / price; + relvolume = (price * basevolume); + return(LP_tradebot_buy(-1,rel,base,maxprice,relvolume)); + } + return(clonestr("{\"error\":\"invalid parameter\"}")); +} + +char *LP_tradebot_settings(void *ctx,int32_t pubsock,cJSON *argjson,uint32_t botid) +{ + struct LP_tradebot *bot; double newprice,newvolume; + if ( (bot= LP_tradebotfind(botid)) != 0 ) + { + if ( bot->dead != 0 ) + return(clonestr("{\"error\":\"botid aleady stopped\"}")); + newprice = jdouble(argjson,"newprice"); + newvolume = jdouble(argjson,"newvolume"); + if ( (newprice > SMALLVAL && newprice < SATOSHIDEN) || (newvolume > 0.0001 && newvolume < SATOSHIDEN) ) + { + if ( bot->dispdir < 0 ) + { + if ( newprice > SMALLVAL ) + bot->maxprice = 1. / newprice; + if ( newvolume > SMALLVAL ) + bot->totalrelvolume = (bot->maxprice * newvolume); + } + else + { + if ( newprice > SMALLVAL ) + bot->maxprice = newprice; + if ( newvolume > SMALLVAL ) + bot->totalrelvolume = newvolume; + } + } + return(jprint(LP_tradebot_json(bot),1)); + } + return(clonestr("{\"error\":\"couldnt find botid\"}")); +} + +char *LP_tradebot_status(void *ctx,int32_t pubsock,cJSON *argjson,uint32_t botid) +{ + struct LP_tradebot *bot; + if ( (bot= LP_tradebotfind(botid)) != 0 ) + return(jprint(LP_tradebot_json(bot),1)); + return(clonestr("{\"error\":\"couldnt find botid\"}")); +} + +char *LP_tradebot_stop(void *ctx,int32_t pubsock,cJSON *argjson,uint32_t botid) +{ + struct LP_tradebot *bot; + if ( (bot= LP_tradebotfind(botid)) != 0 ) + { + bot->dead = (uint32_t)time(NULL); + return(clonestr("{\"result\":\"success\"}")); + } + return(clonestr("{\"error\":\"couldnt find botid\"}")); +} + +char *LP_tradebot_pause(void *ctx,int32_t pubsock,cJSON *argjson,uint32_t botid) +{ + struct LP_tradebot *bot; + if ( (bot= LP_tradebotfind(botid)) != 0 ) + { + if ( bot->dead != 0 ) + return(clonestr("{\"error\":\"botid aleady stopped\"}")); + bot->pause = (uint32_t)time(NULL); + return(clonestr("{\"result\":\"success\"}")); + } + return(clonestr("{\"error\":\"couldnt find botid\"}")); +} + +char *LP_tradebot_resume(void *ctx,int32_t pubsock,cJSON *argjson,uint32_t botid) +{ + struct LP_tradebot *bot; + if ( (bot= LP_tradebotfind(botid)) != 0 ) + { + if ( bot->dead != 0 ) + return(clonestr("{\"error\":\"botid aleady stopped\"}")); + if ( bot->pause == 0 ) + return(clonestr("{\"result\":\"success\",\"status\":\"botid not paused\"}")); + bot->pause = 0; + return(clonestr("{\"result\":\"success\"}")); + } + return(clonestr("{\"error\":\"couldnt find botid\"}")); +} + +char *LP_istradebots_command(void *ctx,int32_t pubsock,char *method,cJSON *argjson) +{ + uint32_t botid; + if ( strcmp(method,"bot_list") == 0 ) + return(LP_tradebot_list(ctx,pubsock,argjson)); + else if ( strcmp(method,"bot_buy") == 0 ) + return(LP_tradebot_limitbuy(ctx,pubsock,argjson)); + else if ( strcmp(method,"bot_sell") == 0 ) + return(LP_tradebot_limitsell(ctx,pubsock,argjson)); + if ( (botid= juint(argjson,"botid")) == 0 ) + return(clonestr("{\"error\":\"no botid specified\"}")); + else + { + if ( strcmp(method,"bot_status") == 0 ) + return(LP_tradebot_status(ctx,pubsock,argjson,botid)); + else if ( strcmp(method,"bot_settings") == 0 ) + return(LP_tradebot_settings(ctx,pubsock,argjson,botid)); + else if ( strcmp(method,"bot_stop") == 0 ) + return(LP_tradebot_stop(ctx,pubsock,argjson,botid)); + else if ( strcmp(method,"bot_pause") == 0 ) + return(LP_tradebot_pause(ctx,pubsock,argjson,botid)); + else if ( strcmp(method,"bot_resume") == 0 ) + return(LP_tradebot_resume(ctx,pubsock,argjson,botid)); + } + return(0); +} + diff --git a/iguana/exchanges/bot_buy b/iguana/exchanges/bot_buy new file mode 100755 index 000000000..d26f5a8f7 --- /dev/null +++ b/iguana/exchanges/bot_buy @@ -0,0 +1,3 @@ +#!/bin/bash +source userpass +curl --url "http://127.0.0.1:7783" --data "{\"userpass\":\"$userpass\",\"method\":\"bot_buy\",\"base\":\"REVS\",\"rel\":\"KMD\",\"maxprice\":3,\"relvolume\":10.0}" diff --git a/iguana/exchanges/bot_list b/iguana/exchanges/bot_list new file mode 100755 index 000000000..40cb49145 --- /dev/null +++ b/iguana/exchanges/bot_list @@ -0,0 +1,3 @@ +#!/bin/bash +source userpass +curl --url "http://127.0.0.1:7783" --data "{\"userpass\":\"$userpass\",\"method\":\"bot_list\"}" diff --git a/iguana/exchanges/bot_pause b/iguana/exchanges/bot_pause new file mode 100755 index 000000000..ed9323e71 --- /dev/null +++ b/iguana/exchanges/bot_pause @@ -0,0 +1,3 @@ +#!/bin/bash +source userpass +curl --url "http://127.0.0.1:7783" --data "{\"userpass\":\"$userpass\",\"method\":\"bot_pause\",\"botid\":$1}" diff --git a/iguana/exchanges/bot_resume b/iguana/exchanges/bot_resume new file mode 100755 index 000000000..6d161b155 --- /dev/null +++ b/iguana/exchanges/bot_resume @@ -0,0 +1,3 @@ +#!/bin/bash +source userpass +curl --url "http://127.0.0.1:7783" --data "{\"userpass\":\"$userpass\",\"method\":\"bot_resume\",\"botid\":$1}" diff --git a/iguana/exchanges/bot_sell b/iguana/exchanges/bot_sell new file mode 100755 index 000000000..3613db3cb --- /dev/null +++ b/iguana/exchanges/bot_sell @@ -0,0 +1,3 @@ +#!/bin/bash +source userpass +curl --url "http://127.0.0.1:7783" --data "{\"userpass\":\"$userpass\",\"method\":\"bot_sell\",\"base\":\"REVS\",\"rel\":\"KMD\",\"minprice\":2,\"basevolume\":5.0}" diff --git a/iguana/exchanges/bot_settings b/iguana/exchanges/bot_settings new file mode 100755 index 000000000..f619f92e3 --- /dev/null +++ b/iguana/exchanges/bot_settings @@ -0,0 +1,3 @@ +#!/bin/bash +source userpass +curl --url "http://127.0.0.1:7783" --data "{\"userpass\":\"$userpass\",\"method\":\"bot_settings\",\"botid\":$1,\"newprice\":$1,\"newvolume\":$2}" diff --git a/iguana/exchanges/bot_status b/iguana/exchanges/bot_status new file mode 100755 index 000000000..e64bc5ae7 --- /dev/null +++ b/iguana/exchanges/bot_status @@ -0,0 +1,3 @@ +#!/bin/bash +source userpass +curl --url "http://127.0.0.1:7783" --data "{\"userpass\":\"$userpass\",\"method\":\"bot_status\",\"botid\":$1}" diff --git a/iguana/exchanges/bot_stop b/iguana/exchanges/bot_stop new file mode 100755 index 000000000..665e2ac9e --- /dev/null +++ b/iguana/exchanges/bot_stop @@ -0,0 +1,3 @@ +#!/bin/bash +source userpass +curl --url "http://127.0.0.1:7783" --data "{\"userpass\":\"$userpass\",\"method\":\"bot_stop\",\"botid\":$1}" diff --git a/iguana/kmd_lookup.h b/iguana/kmd_lookup.h index 61f7f60b0..05cb91ad4 100755 --- a/iguana/kmd_lookup.h +++ b/iguana/kmd_lookup.h @@ -668,7 +668,7 @@ int32_t _kmd_bitcoinscan(struct iguana_info *coin) { if ( bits256_cmp(txid,jbits256(txjson,"txid")) != 0 ) { - printf("txid mismatch error ht.%d i.%d\n",loadheight,i); + printf("%s txid mismatch error ht.%d i.%d\n",coin->symbol,loadheight,i); continue; } vouts = jarray(&numvouts,txjson,"vout"); From 5b0cc4eef81ddded860718afdac7c674ccd18687 Mon Sep 17 00:00:00 2001 From: jl777 Date: Wed, 1 Nov 2017 12:35:56 +0200 Subject: [PATCH 0052/1664] Test --- iguana/exchanges/install | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/iguana/exchanges/install b/iguana/exchanges/install index 4ec27cffc..ef6617a55 100755 --- a/iguana/exchanges/install +++ b/iguana/exchanges/install @@ -1,5 +1,5 @@ #!/bin/bash -cp guistats pubkeystats pendings coinswaps baserelswaps setpassphrase notarizations getrawtransaction parselog statsdisp m_js 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 bot_buy bot_list bot_pause bot_resume bot_sell bot_settings bot_status bot_stop guistats pubkeystats pendings coinswaps baserelswaps setpassphrase notarizations getrawtransaction parselog statsdisp m_js 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 . From 075b55bf6383432989bd6e755bd0c71704eabe6e Mon Sep 17 00:00:00 2001 From: jl777 Date: Wed, 1 Nov 2017 12:38:53 +0200 Subject: [PATCH 0053/1664] Test --- iguana/exchanges/LP_tradebots.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/iguana/exchanges/LP_tradebots.c b/iguana/exchanges/LP_tradebots.c index c22a2db50..7b6b6d442 100644 --- a/iguana/exchanges/LP_tradebots.c +++ b/iguana/exchanges/LP_tradebots.c @@ -303,6 +303,7 @@ char *LP_tradebot_list(void *ctx,int32_t pubsock,cJSON *argjson) char *LP_tradebot_buy(int32_t dispdir,char *base,char *rel,double maxprice,double relvolume) { struct LP_tradebot *bot; + printf("disp.%d tradebot_buy(%s / %s) maxprice %.8f relvolume %.8f\n",dispdir,base,rel,maxprice,relvolume); if ( (bot= calloc(1,sizeof(*bot))) != 0 ) { safecopy(bot->base,base,sizeof(bot->base)); @@ -428,6 +429,7 @@ char *LP_tradebot_resume(void *ctx,int32_t pubsock,cJSON *argjson,uint32_t botid char *LP_istradebots_command(void *ctx,int32_t pubsock,char *method,cJSON *argjson) { uint32_t botid; + printf("istradebots.(%s)\n",method); if ( strcmp(method,"bot_list") == 0 ) return(LP_tradebot_list(ctx,pubsock,argjson)); else if ( strcmp(method,"bot_buy") == 0 ) @@ -449,6 +451,7 @@ char *LP_istradebots_command(void *ctx,int32_t pubsock,char *method,cJSON *argjs else if ( strcmp(method,"bot_resume") == 0 ) return(LP_tradebot_resume(ctx,pubsock,argjson,botid)); } + printf("not tradebots\n"); return(0); } From 8d3d8f791c24e473ade3889ec280d8565fc5b8f5 Mon Sep 17 00:00:00 2001 From: jl777 Date: Wed, 1 Nov 2017 12:42:07 +0200 Subject: [PATCH 0054/1664] Test --- iguana/exchanges/LP_tradebots.c | 1 + 1 file changed, 1 insertion(+) diff --git a/iguana/exchanges/LP_tradebots.c b/iguana/exchanges/LP_tradebots.c index 7b6b6d442..ac9f8a157 100644 --- a/iguana/exchanges/LP_tradebots.c +++ b/iguana/exchanges/LP_tradebots.c @@ -327,6 +327,7 @@ char *LP_tradebot_limitbuy(void *ctx,int32_t pubsock,cJSON *argjson) rel = jstr(argjson,"rel"); maxprice = jdouble(argjson,"maxprice"); relvolume = jdouble(argjson,"relvolume"); + printf("limit buy %s/%s %.8f %.8f\n",base,rel,maxprice,relvolume); if ( LP_priceinfofind(base) != 0 && LP_priceinfofind(rel) != 0 && maxprice > SMALLVAL && maxprice < SATOSHIDEN && relvolume > 0.0001 && relvolume < SATOSHIDEN ) return(LP_tradebot_buy(1,base,rel,maxprice,relvolume)); return(clonestr("{\"error\":\"invalid parameter\"}")); From d966805c379b59bc49b21d95e230ceed6fb5023a Mon Sep 17 00:00:00 2001 From: jl777 Date: Wed, 1 Nov 2017 12:43:54 +0200 Subject: [PATCH 0055/1664] Test --- iguana/exchanges/LP_commands.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/iguana/exchanges/LP_commands.c b/iguana/exchanges/LP_commands.c index e495179a7..2c147dc00 100644 --- a/iguana/exchanges/LP_commands.c +++ b/iguana/exchanges/LP_commands.c @@ -257,6 +257,8 @@ bot_resume(botid)\n\ return(basilisk_swapentries(base,rel,jint(argjson,"limit"))); else return(basilisk_swaplist(0,0)); } + else if ( (retstr= LP_istradebots_command(ctx,pubsock,method,argjson)) != 0 ) + return(retstr); if ( base != 0 && rel != 0 ) { double price,bid,ask; @@ -453,8 +455,6 @@ bot_resume(botid)\n\ return(LP_pubkey_trustset(jbits256(argjson,"pubkey"),jint(argjson,"trust"))); else if ( strcmp(method,"trusted") == 0 ) return(LP_pubkey_trusted()); - else if ( (retstr= LP_istradebots_command(ctx,pubsock,method,argjson)) != 0 ) - return(retstr); } // end of protected localhost commands if ( IAMLP == 0 ) { From 0ea6e850de82cc9047b5e168e7539d246d727fd0 Mon Sep 17 00:00:00 2001 From: jl777 Date: Wed, 1 Nov 2017 12:45:56 +0200 Subject: [PATCH 0056/1664] Test --- iguana/exchanges/LP_tradebots.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/iguana/exchanges/LP_tradebots.c b/iguana/exchanges/LP_tradebots.c index ac9f8a157..7f2d92939 100644 --- a/iguana/exchanges/LP_tradebots.c +++ b/iguana/exchanges/LP_tradebots.c @@ -430,6 +430,8 @@ char *LP_tradebot_resume(void *ctx,int32_t pubsock,cJSON *argjson,uint32_t botid char *LP_istradebots_command(void *ctx,int32_t pubsock,char *method,cJSON *argjson) { uint32_t botid; + if ( strncmp("bot_",method,strlen("bot_")) != 0 ) + return(0); printf("istradebots.(%s)\n",method); if ( strcmp(method,"bot_list") == 0 ) return(LP_tradebot_list(ctx,pubsock,argjson)); From 7fef554728828f6d7eba76f233b128c9f81fe141 Mon Sep 17 00:00:00 2001 From: jl777 Date: Wed, 1 Nov 2017 12:50:41 +0200 Subject: [PATCH 0057/1664] Test --- iguana/exchanges/LP_tradebots.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/iguana/exchanges/LP_tradebots.c b/iguana/exchanges/LP_tradebots.c index 7f2d92939..87e74e32f 100644 --- a/iguana/exchanges/LP_tradebots.c +++ b/iguana/exchanges/LP_tradebots.c @@ -102,7 +102,7 @@ double LP_pricevol_invert(double *basevolumep,double maxprice,double relvolume) *basevolumep = 0.; if ( maxprice > SMALLVAL && maxprice < SATOSHIDEN ) { - *basevolumep = (relvolume / maxprice); + *basevolumep = (relvolume * maxprice); return(1. / maxprice); } return(0.); @@ -147,7 +147,7 @@ cJSON *LP_tradebot_json(struct LP_tradebot *bot) jaddstr(json,"base",bot->base); jaddstr(json,"rel",bot->rel); jaddnum(json,"maxprice",bot->maxprice); - jaddnum(json,"totalvolume",bot->totalrelvolume); + jaddnum(json,"totalrelvolume",bot->totalrelvolume); if ( (vol= bot->relsum) > SMALLVAL ) { jaddnum(json,"aveprice",bot->basesum/vol); @@ -160,7 +160,7 @@ cJSON *LP_tradebot_json(struct LP_tradebot *bot) jaddstr(json,"rel",bot->base); aveprice = LP_pricevol_invert(&basevolume,bot->maxprice,bot->totalrelvolume); jaddnum(json,"minprice",aveprice); - jaddnum(json,"totalvolume",basevolume); + jaddnum(json,"totalbasevolume",basevolume); if ( (vol= bot->relsum) > SMALLVAL ) { aveprice = LP_pricevol_invert(&basevolume,bot->basesum / vol,vol); From 4fa7c97733749f2c623a77b99af1b1a092b63a8d Mon Sep 17 00:00:00 2001 From: jl777 Date: Wed, 1 Nov 2017 12:55:50 +0200 Subject: [PATCH 0058/1664] Test --- iguana/exchanges/LP_tradebots.c | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/iguana/exchanges/LP_tradebots.c b/iguana/exchanges/LP_tradebots.c index 87e74e32f..79c0dcc2c 100644 --- a/iguana/exchanges/LP_tradebots.c +++ b/iguana/exchanges/LP_tradebots.c @@ -144,10 +144,13 @@ cJSON *LP_tradebot_json(struct LP_tradebot *bot) jaddnum(json,"stopped",bot->dead); if ( bot->dispdir > 0 ) { + jaddstr(json,"action","buy"); jaddstr(json,"base",bot->base); jaddstr(json,"rel",bot->rel); jaddnum(json,"maxprice",bot->maxprice); jaddnum(json,"totalrelvolume",bot->totalrelvolume); + LP_pricevol_invert(&basevolume,bot->maxprice,bot->totalrelvolume); + jaddnum(json,"totalbasevolume",basevolume); if ( (vol= bot->relsum) > SMALLVAL ) { jaddnum(json,"aveprice",bot->basesum/vol); @@ -156,11 +159,13 @@ cJSON *LP_tradebot_json(struct LP_tradebot *bot) } else { + jaddstr(json,"action","sell"); jaddstr(json,"base",bot->rel); jaddstr(json,"rel",bot->base); aveprice = LP_pricevol_invert(&basevolume,bot->maxprice,bot->totalrelvolume); jaddnum(json,"minprice",aveprice); jaddnum(json,"totalbasevolume",basevolume); + jaddnum(json,"totalrelvolume",bot->totalrelvolume); if ( (vol= bot->relsum) > SMALLVAL ) { aveprice = LP_pricevol_invert(&basevolume,bot->basesum / vol,vol); @@ -432,7 +437,6 @@ char *LP_istradebots_command(void *ctx,int32_t pubsock,char *method,cJSON *argjs uint32_t botid; if ( strncmp("bot_",method,strlen("bot_")) != 0 ) return(0); - printf("istradebots.(%s)\n",method); if ( strcmp(method,"bot_list") == 0 ) return(LP_tradebot_list(ctx,pubsock,argjson)); else if ( strcmp(method,"bot_buy") == 0 ) @@ -454,7 +458,6 @@ char *LP_istradebots_command(void *ctx,int32_t pubsock,char *method,cJSON *argjs else if ( strcmp(method,"bot_resume") == 0 ) return(LP_tradebot_resume(ctx,pubsock,argjson,botid)); } - printf("not tradebots\n"); return(0); } From c311720c1d1b5f3298fb38195f0be1765643550d Mon Sep 17 00:00:00 2001 From: jl777 Date: Wed, 1 Nov 2017 13:00:39 +0200 Subject: [PATCH 0059/1664] Test --- iguana/exchanges/LP_tradebots.c | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/iguana/exchanges/LP_tradebots.c b/iguana/exchanges/LP_tradebots.c index 79c0dcc2c..e8bace080 100644 --- a/iguana/exchanges/LP_tradebots.c +++ b/iguana/exchanges/LP_tradebots.c @@ -102,7 +102,7 @@ double LP_pricevol_invert(double *basevolumep,double maxprice,double relvolume) *basevolumep = 0.; if ( maxprice > SMALLVAL && maxprice < SATOSHIDEN ) { - *basevolumep = (relvolume * maxprice); + *basevolumep = (relvolume / maxprice); return(1. / maxprice); } return(0.); @@ -122,7 +122,7 @@ cJSON *LP_tradebot_tradejson(struct LP_tradebot_trade *tp,int32_t dispflag) } else { - price = LP_pricevol_invert(&basevol,tp->basevol / tp->relvol,tp->relvol); + price = LP_pricevol_invert(&basevol,tp->relvol / tp->basevol,tp->relvol); jaddnum(item,"price",price); jaddnum(item,"volume",basevol); } @@ -316,8 +316,8 @@ char *LP_tradebot_buy(int32_t dispdir,char *base,char *rel,double maxprice,doubl bot->dispdir = dispdir, bot->maxprice = maxprice, bot->totalrelvolume = relvolume; bot->started = (uint32_t)time(NULL); if ( dispdir > 0 ) - sprintf(bot->name,"%s_%s.%d",base,rel,bot->started); - else sprintf(bot->name,"%s_%s.%d",rel,base,bot->started); + sprintf(bot->name,"buy_%s_%s.%d",base,rel,bot->started); + else sprintf(bot->name,"sell_%s_%s.%d",rel,base,bot->started); bot->id = calc_crc32(0,(uint8_t *)bot,sizeof(*bot)); LP_tradebotadd(bot); return(jprint(LP_tradebot_json(bot),1)); @@ -348,7 +348,7 @@ char *LP_tradebot_limitsell(void *ctx,int32_t pubsock,cJSON *argjson) if ( LP_priceinfofind(base) != 0 && LP_priceinfofind(rel) != 0 && price > SMALLVAL && price < SATOSHIDEN && basevolume > 0.0001 && basevolume < SATOSHIDEN ) { maxprice = 1. / price; - relvolume = (price * basevolume); + relvolume = (maxprice * basevolume); return(LP_tradebot_buy(-1,rel,base,maxprice,relvolume)); } return(clonestr("{\"error\":\"invalid parameter\"}")); From 1d99f9d69ebf00eae6968dbfc92aa16fb43ec586 Mon Sep 17 00:00:00 2001 From: jl777 Date: Wed, 1 Nov 2017 13:04:45 +0200 Subject: [PATCH 0060/1664] Test --- iguana/exchanges/LP_tradebots.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/iguana/exchanges/LP_tradebots.c b/iguana/exchanges/LP_tradebots.c index e8bace080..7805f2db9 100644 --- a/iguana/exchanges/LP_tradebots.c +++ b/iguana/exchanges/LP_tradebots.c @@ -340,7 +340,7 @@ char *LP_tradebot_limitbuy(void *ctx,int32_t pubsock,cJSON *argjson) char *LP_tradebot_limitsell(void *ctx,int32_t pubsock,cJSON *argjson) { - double relvolume,maxprice,price,basevolume; char *base,*rel; + double relvolume,maxprice,price,basevolume,p,v; char *base,*rel; base = jstr(argjson,"base"); rel = jstr(argjson,"rel"); price = jdouble(argjson,"minprice"); @@ -348,7 +348,9 @@ char *LP_tradebot_limitsell(void *ctx,int32_t pubsock,cJSON *argjson) if ( LP_priceinfofind(base) != 0 && LP_priceinfofind(rel) != 0 && price > SMALLVAL && price < SATOSHIDEN && basevolume > 0.0001 && basevolume < SATOSHIDEN ) { maxprice = 1. / price; - relvolume = (maxprice * basevolume); + relvolume = (price * basevolume); + p = LP_pricevol_invert(&v,maxprice,relvolume); + printf("minprice %.8f basevolume %.8f -> (%.8f %.8f) -> (%.8f %.8f)\n",price,basevolume,maxprice,relvolume,p,v); return(LP_tradebot_buy(-1,rel,base,maxprice,relvolume)); } return(clonestr("{\"error\":\"invalid parameter\"}")); From 648ba26b3324638e5727a285757fb912356821c9 Mon Sep 17 00:00:00 2001 From: jl777 Date: Wed, 1 Nov 2017 13:09:48 +0200 Subject: [PATCH 0061/1664] Test --- iguana/exchanges/LP_tradebots.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/iguana/exchanges/LP_tradebots.c b/iguana/exchanges/LP_tradebots.c index 7805f2db9..db082b8b5 100644 --- a/iguana/exchanges/LP_tradebots.c +++ b/iguana/exchanges/LP_tradebots.c @@ -102,7 +102,7 @@ double LP_pricevol_invert(double *basevolumep,double maxprice,double relvolume) *basevolumep = 0.; if ( maxprice > SMALLVAL && maxprice < SATOSHIDEN ) { - *basevolumep = (relvolume / maxprice); + *basevolumep = (relvolume * maxprice); return(1. / maxprice); } return(0.); @@ -284,6 +284,7 @@ void LP_tradebot_timeslices(void *ignore) struct LP_tradebot *bot,*tmp; while ( 1 ) { + printf("LP_tradebot_timeslices\n"); DL_FOREACH_SAFE(LP_tradebots,bot,tmp) { portable_mutex_lock(&LP_tradebotsmutex); From cd49afc49b8e022b0fc5d3907a2c28c0fa504c8b Mon Sep 17 00:00:00 2001 From: jl777 Date: Wed, 1 Nov 2017 13:18:32 +0200 Subject: [PATCH 0062/1664] Test --- iguana/exchanges/LP_tradebots.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/iguana/exchanges/LP_tradebots.c b/iguana/exchanges/LP_tradebots.c index db082b8b5..1dc4cebec 100644 --- a/iguana/exchanges/LP_tradebots.c +++ b/iguana/exchanges/LP_tradebots.c @@ -149,7 +149,7 @@ cJSON *LP_tradebot_json(struct LP_tradebot *bot) jaddstr(json,"rel",bot->rel); jaddnum(json,"maxprice",bot->maxprice); jaddnum(json,"totalrelvolume",bot->totalrelvolume); - LP_pricevol_invert(&basevolume,bot->maxprice,bot->totalrelvolume); + LP_pricevol_invert(&basevolume,1./bot->maxprice,bot->totalrelvolume); jaddnum(json,"totalbasevolume",basevolume); if ( (vol= bot->relsum) > SMALLVAL ) { @@ -254,7 +254,7 @@ void LP_tradebot_timeslice(struct LP_tradebot *bot) { if ( bot->pause == 0 ) { - if ( (rand() % 100) == 0 ) + //if ( (rand() % 100) == 0 ) { if ( bot->dispdir > 0 ) { @@ -292,7 +292,7 @@ void LP_tradebot_timeslices(void *ignore) portable_mutex_unlock(&LP_tradebotsmutex); sleep(1); } - sleep(30); + sleep(10); } } From 407d2573cc635dd06d75496533de2479a9c70b76 Mon Sep 17 00:00:00 2001 From: jl777 Date: Wed, 1 Nov 2017 13:26:55 +0200 Subject: [PATCH 0063/1664] Test --- iguana/exchanges/LP_tradebots.c | 18 ++++++++++++------ 1 file changed, 12 insertions(+), 6 deletions(-) diff --git a/iguana/exchanges/LP_tradebots.c b/iguana/exchanges/LP_tradebots.c index 1dc4cebec..d286f13a1 100644 --- a/iguana/exchanges/LP_tradebots.c +++ b/iguana/exchanges/LP_tradebots.c @@ -35,7 +35,7 @@ struct LP_tradebot struct LP_tradebot *next,*prev; char name[128],base[32],rel[32]; int32_t numtrades,numpending,completed,dispdir; - double maxprice,totalrelvolume,basesum,relsum,pendbasesum,pendrelsum; + double maxprice,totalrelvolume,totalbasevolume,basesum,relsum,pendbasesum,pendrelsum; uint32_t dead,pause,started,id; struct LP_tradebot_trade *trades[LP_TRADEBOTS_MAXTRADES]; } *LP_tradebots; @@ -99,11 +99,13 @@ void LP_tradebot_calcstats(struct LP_tradebot *bot) double LP_pricevol_invert(double *basevolumep,double maxprice,double relvolume) { + double price; *basevolumep = 0.; if ( maxprice > SMALLVAL && maxprice < SATOSHIDEN ) { - *basevolumep = (relvolume * maxprice); - return(1. / maxprice); + price = (1. / maxprice); + *basevolumep = (relvolume * price); + return(price); } return(0.); } @@ -149,8 +151,9 @@ cJSON *LP_tradebot_json(struct LP_tradebot *bot) jaddstr(json,"rel",bot->rel); jaddnum(json,"maxprice",bot->maxprice); jaddnum(json,"totalrelvolume",bot->totalrelvolume); - LP_pricevol_invert(&basevolume,1./bot->maxprice,bot->totalrelvolume); - jaddnum(json,"totalbasevolume",basevolume); + LP_pricevol_invert(&basevolume,bot->maxprice,bot->totalrelvolume); + jaddnum(json,"totalbasevolume2",basevolume); + jaddnum(json,"totalbasevolume",bot->totalbasevolume); if ( (vol= bot->relsum) > SMALLVAL ) { jaddnum(json,"aveprice",bot->basesum/vol); @@ -314,7 +317,10 @@ char *LP_tradebot_buy(int32_t dispdir,char *base,char *rel,double maxprice,doubl { safecopy(bot->base,base,sizeof(bot->base)); safecopy(bot->rel,rel,sizeof(bot->rel)); - bot->dispdir = dispdir, bot->maxprice = maxprice, bot->totalrelvolume = relvolume; + bot->dispdir = dispdir; + bot->maxprice = maxprice; + bot->totalrelvolume = relvolume; + LP_pricevol_invert(&bot->totalbasevolume,maxprice,relvolume); bot->started = (uint32_t)time(NULL); if ( dispdir > 0 ) sprintf(bot->name,"buy_%s_%s.%d",base,rel,bot->started); From e0224484501870013b05d9dc6fe8336d9e64e787 Mon Sep 17 00:00:00 2001 From: jl777 Date: Wed, 1 Nov 2017 13:32:05 +0200 Subject: [PATCH 0064/1664] Test --- iguana/exchanges/LP_tradebots.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/iguana/exchanges/LP_tradebots.c b/iguana/exchanges/LP_tradebots.c index d286f13a1..dd1684234 100644 --- a/iguana/exchanges/LP_tradebots.c +++ b/iguana/exchanges/LP_tradebots.c @@ -104,7 +104,7 @@ double LP_pricevol_invert(double *basevolumep,double maxprice,double relvolume) if ( maxprice > SMALLVAL && maxprice < SATOSHIDEN ) { price = (1. / maxprice); - *basevolumep = (relvolume * price); + *basevolumep = (relvolume * maxprice); return(price); } return(0.); From eb7ef221a7d578be827d0a01b3751a9aba5b3e83 Mon Sep 17 00:00:00 2001 From: jl777 Date: Wed, 1 Nov 2017 13:35:16 +0200 Subject: [PATCH 0065/1664] Test --- iguana/exchanges/LP_tradebots.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/iguana/exchanges/LP_tradebots.c b/iguana/exchanges/LP_tradebots.c index dd1684234..d10022dc5 100644 --- a/iguana/exchanges/LP_tradebots.c +++ b/iguana/exchanges/LP_tradebots.c @@ -104,7 +104,7 @@ double LP_pricevol_invert(double *basevolumep,double maxprice,double relvolume) if ( maxprice > SMALLVAL && maxprice < SATOSHIDEN ) { price = (1. / maxprice); - *basevolumep = (relvolume * maxprice); + *basevolumep = (relvolume * price); return(price); } return(0.); @@ -354,7 +354,7 @@ char *LP_tradebot_limitsell(void *ctx,int32_t pubsock,cJSON *argjson) basevolume = jdouble(argjson,"basevolume"); if ( LP_priceinfofind(base) != 0 && LP_priceinfofind(rel) != 0 && price > SMALLVAL && price < SATOSHIDEN && basevolume > 0.0001 && basevolume < SATOSHIDEN ) { - maxprice = 1. / price; + maxprice = price; relvolume = (price * basevolume); p = LP_pricevol_invert(&v,maxprice,relvolume); printf("minprice %.8f basevolume %.8f -> (%.8f %.8f) -> (%.8f %.8f)\n",price,basevolume,maxprice,relvolume,p,v); From 9e9db4254801ffd65ffbf4603b4c46eec0cf37db Mon Sep 17 00:00:00 2001 From: jl777 Date: Wed, 1 Nov 2017 13:40:36 +0200 Subject: [PATCH 0066/1664] Test --- iguana/exchanges/LP_tradebots.c | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) diff --git a/iguana/exchanges/LP_tradebots.c b/iguana/exchanges/LP_tradebots.c index d10022dc5..98f84cf61 100644 --- a/iguana/exchanges/LP_tradebots.c +++ b/iguana/exchanges/LP_tradebots.c @@ -261,17 +261,21 @@ void LP_tradebot_timeslice(struct LP_tradebot *bot) { if ( bot->dispdir > 0 ) { - printf("simulated trade %s/%s maxprice %.8f volume %.8f\n",bot->base,bot->rel,bot->maxprice,bot->totalrelvolume - bot->relsum); + printf("simulated trade buy %s/%s maxprice %.8f volume %.8f\n",bot->base,bot->rel,bot->maxprice,bot->totalrelvolume - bot->relsum); } else { minprice = LP_pricevol_invert(&basevol,bot->maxprice,bot->totalrelvolume - bot->relsum); - printf("simulated trade %s/%s maxprice %.8f volume %.8f\n",bot->rel,bot->base,minprice,basevol); + printf("simulated trade sell %s/%s maxprice %.8f volume %.8f\n",bot->rel,bot->base,minprice,basevol); } relvol = bot->totalrelvolume * 0.1; minprice = LP_pricevol_invert(&basevol,bot->maxprice,relvol); bot->relsum += relvol; bot->basesum += basevol; + if ( bot->relsum >= bot->totalrelvolume-SMALLVAL || bot->basesum >= bot->totalbasevolume-SMALLVAL ) + bot->dead = (uint32_t)time(NULL); + else if ( (bot->pendrelsum+bot->relsum) >= bot->totalrelvolume-SMALLVAL || (bot->basesum+bot->pendbasesum) >= bot->totalbasevolume-SMALLVAL ) + bot->pause = (uint32_t)time(NULL); } } } @@ -287,7 +291,6 @@ void LP_tradebot_timeslices(void *ignore) struct LP_tradebot *bot,*tmp; while ( 1 ) { - printf("LP_tradebot_timeslices\n"); DL_FOREACH_SAFE(LP_tradebots,bot,tmp) { portable_mutex_lock(&LP_tradebotsmutex); @@ -357,7 +360,7 @@ char *LP_tradebot_limitsell(void *ctx,int32_t pubsock,cJSON *argjson) maxprice = price; relvolume = (price * basevolume); p = LP_pricevol_invert(&v,maxprice,relvolume); - printf("minprice %.8f basevolume %.8f -> (%.8f %.8f) -> (%.8f %.8f)\n",price,basevolume,maxprice,relvolume,p,v); + printf("minprice %.8f basevolume %.8f -> (%.8f %.8f) -> (%.8f %.8f)\n",price,basevolume,maxprice,relvolume,1./p,v); return(LP_tradebot_buy(-1,rel,base,maxprice,relvolume)); } return(clonestr("{\"error\":\"invalid parameter\"}")); From e99d385dfe4752edea73b1161f2c22f424f63b1c Mon Sep 17 00:00:00 2001 From: jl777 Date: Wed, 1 Nov 2017 13:43:52 +0200 Subject: [PATCH 0067/1664] Test --- iguana/exchanges/LP_tradebots.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/iguana/exchanges/LP_tradebots.c b/iguana/exchanges/LP_tradebots.c index 98f84cf61..7aa0eeb61 100644 --- a/iguana/exchanges/LP_tradebots.c +++ b/iguana/exchanges/LP_tradebots.c @@ -361,7 +361,7 @@ char *LP_tradebot_limitsell(void *ctx,int32_t pubsock,cJSON *argjson) relvolume = (price * basevolume); p = LP_pricevol_invert(&v,maxprice,relvolume); printf("minprice %.8f basevolume %.8f -> (%.8f %.8f) -> (%.8f %.8f)\n",price,basevolume,maxprice,relvolume,1./p,v); - return(LP_tradebot_buy(-1,rel,base,maxprice,relvolume)); + return(LP_tradebot_buy(-1,rel,base,p,relvolume)); } return(clonestr("{\"error\":\"invalid parameter\"}")); } From 6b6290cbf6e6ae4965ace5ea09839245e5fcbd67 Mon Sep 17 00:00:00 2001 From: jl777 Date: Wed, 1 Nov 2017 13:47:05 +0200 Subject: [PATCH 0068/1664] Test --- iguana/exchanges/LP_tradebots.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/iguana/exchanges/LP_tradebots.c b/iguana/exchanges/LP_tradebots.c index 7aa0eeb61..9c2c6bf94 100644 --- a/iguana/exchanges/LP_tradebots.c +++ b/iguana/exchanges/LP_tradebots.c @@ -361,7 +361,7 @@ char *LP_tradebot_limitsell(void *ctx,int32_t pubsock,cJSON *argjson) relvolume = (price * basevolume); p = LP_pricevol_invert(&v,maxprice,relvolume); printf("minprice %.8f basevolume %.8f -> (%.8f %.8f) -> (%.8f %.8f)\n",price,basevolume,maxprice,relvolume,1./p,v); - return(LP_tradebot_buy(-1,rel,base,p,relvolume)); + return(LP_tradebot_buy(-1,rel,base,p,v)); } return(clonestr("{\"error\":\"invalid parameter\"}")); } From 2e8498ec5012bd800a975960d5f938f39ab578df Mon Sep 17 00:00:00 2001 From: jl777 Date: Wed, 1 Nov 2017 13:54:48 +0200 Subject: [PATCH 0069/1664] Test --- iguana/exchanges/LP_tradebots.c | 14 ++++++-------- 1 file changed, 6 insertions(+), 8 deletions(-) diff --git a/iguana/exchanges/LP_tradebots.c b/iguana/exchanges/LP_tradebots.c index 9c2c6bf94..5919cf21d 100644 --- a/iguana/exchanges/LP_tradebots.c +++ b/iguana/exchanges/LP_tradebots.c @@ -151,8 +151,6 @@ cJSON *LP_tradebot_json(struct LP_tradebot *bot) jaddstr(json,"rel",bot->rel); jaddnum(json,"maxprice",bot->maxprice); jaddnum(json,"totalrelvolume",bot->totalrelvolume); - LP_pricevol_invert(&basevolume,bot->maxprice,bot->totalrelvolume); - jaddnum(json,"totalbasevolume2",basevolume); jaddnum(json,"totalbasevolume",bot->totalbasevolume); if ( (vol= bot->relsum) > SMALLVAL ) { @@ -252,26 +250,26 @@ void LP_tradebotadd(struct LP_tradebot *bot) void LP_tradebot_timeslice(struct LP_tradebot *bot) { - double minprice,basevol,relvol; + double minprice,basevol,relvol,p,v; if ( bot->dead == 0 ) { if ( bot->pause == 0 ) { //if ( (rand() % 100) == 0 ) { + relvol = bot->totalrelvolume * 0.1; + p = LP_pricevol_invert(&v,bot->maxprice,relvol); if ( bot->dispdir > 0 ) { - printf("simulated trade buy %s/%s maxprice %.8f volume %.8f\n",bot->base,bot->rel,bot->maxprice,bot->totalrelvolume - bot->relsum); + printf("simulated trade buy %s/%s maxprice %.8f volume %.8f, %.8f %s -> %s\n",bot->base,bot->rel,bot->maxprice,bot->totalrelvolume - bot->relsum,relvol,bot->rel,bot->base); } else { minprice = LP_pricevol_invert(&basevol,bot->maxprice,bot->totalrelvolume - bot->relsum); - printf("simulated trade sell %s/%s maxprice %.8f volume %.8f\n",bot->rel,bot->base,minprice,basevol); + printf("simulated trade sell %s/%s maxprice %.8f volume %.8f, %.8f %s -> %s min %.8f\n",bot->rel,bot->base,minprice,basevol,v,bot->base,bot->rel,p); } - relvol = bot->totalrelvolume * 0.1; - minprice = LP_pricevol_invert(&basevol,bot->maxprice,relvol); bot->relsum += relvol; - bot->basesum += basevol; + bot->basesum += v; if ( bot->relsum >= bot->totalrelvolume-SMALLVAL || bot->basesum >= bot->totalbasevolume-SMALLVAL ) bot->dead = (uint32_t)time(NULL); else if ( (bot->pendrelsum+bot->relsum) >= bot->totalrelvolume-SMALLVAL || (bot->basesum+bot->pendbasesum) >= bot->totalbasevolume-SMALLVAL ) From 624cc50088e8a0fcf2882ef57221ea37bf65fe59 Mon Sep 17 00:00:00 2001 From: jl777 Date: Wed, 1 Nov 2017 14:00:53 +0200 Subject: [PATCH 0070/1664] Test --- iguana/exchanges/LP_tradebots.c | 21 +++++++++++++++------ 1 file changed, 15 insertions(+), 6 deletions(-) diff --git a/iguana/exchanges/LP_tradebots.c b/iguana/exchanges/LP_tradebots.c index 5919cf21d..f5111f6ac 100644 --- a/iguana/exchanges/LP_tradebots.c +++ b/iguana/exchanges/LP_tradebots.c @@ -165,8 +165,8 @@ cJSON *LP_tradebot_json(struct LP_tradebot *bot) jaddstr(json,"rel",bot->base); aveprice = LP_pricevol_invert(&basevolume,bot->maxprice,bot->totalrelvolume); jaddnum(json,"minprice",aveprice); - jaddnum(json,"totalbasevolume",basevolume); - jaddnum(json,"totalrelvolume",bot->totalrelvolume); + jaddnum(json,"totalbasevolume",bot->totalrelvolume); + jaddnum(json,"totalrelvolume",basevolume); if ( (vol= bot->relsum) > SMALLVAL ) { aveprice = LP_pricevol_invert(&basevolume,bot->basesum / vol,vol); @@ -175,7 +175,7 @@ cJSON *LP_tradebot_json(struct LP_tradebot *bot) } } array = cJSON_CreateArray(); - LP_tradebot_calcstats(bot); + //LP_tradebot_calcstats(bot); for (i=0; inumtrades; i++) { jaddi(array,LP_tradebot_tradejson(bot->trades[i],bot->dispdir)); @@ -266,14 +266,23 @@ void LP_tradebot_timeslice(struct LP_tradebot *bot) else { minprice = LP_pricevol_invert(&basevol,bot->maxprice,bot->totalrelvolume - bot->relsum); - printf("simulated trade sell %s/%s maxprice %.8f volume %.8f, %.8f %s -> %s min %.8f\n",bot->rel,bot->base,minprice,basevol,v,bot->base,bot->rel,p); + printf("simulated trade sell %s/%s minprice %.8f volume %.8f, %.8f %s -> %s min %.8f\n",bot->rel,bot->base,minprice,basevol,v,bot->base,bot->rel,p); + } + if ( (rand() % 2) == 0 ) + { + bot->relsum += relvol; + bot->basesum += v; + } + else + { + bot->pendrelsum += relvol; + bot->pendbasesum += v; } - bot->relsum += relvol; - bot->basesum += v; if ( bot->relsum >= bot->totalrelvolume-SMALLVAL || bot->basesum >= bot->totalbasevolume-SMALLVAL ) bot->dead = (uint32_t)time(NULL); else if ( (bot->pendrelsum+bot->relsum) >= bot->totalrelvolume-SMALLVAL || (bot->basesum+bot->pendbasesum) >= bot->totalbasevolume-SMALLVAL ) bot->pause = (uint32_t)time(NULL); + printf("%s\n",jprint(LP_tradebot_json(bot),1)); } } } From bcdbb31c274f11492252a794f32f9883331d7697 Mon Sep 17 00:00:00 2001 From: jl777 Date: Wed, 1 Nov 2017 14:04:27 +0200 Subject: [PATCH 0071/1664] Test --- iguana/exchanges/LP_tradebots.c | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/iguana/exchanges/LP_tradebots.c b/iguana/exchanges/LP_tradebots.c index f5111f6ac..1eab5a419 100644 --- a/iguana/exchanges/LP_tradebots.c +++ b/iguana/exchanges/LP_tradebots.c @@ -113,6 +113,8 @@ double LP_pricevol_invert(double *basevolumep,double maxprice,double relvolume) cJSON *LP_tradebot_tradejson(struct LP_tradebot_trade *tp,int32_t dispflag) { double price,basevol; cJSON *item = cJSON_CreateObject(); + if ( tp == 0 ) + return(cJSON_Parse("{}")); jaddnum(item,"requestid",tp->requestid); jaddnum(item,"quoteid",tp->quoteid); if ( tp->basevol > SMALLVAL && tp->relvol > SMALLVAL ) @@ -272,12 +274,15 @@ void LP_tradebot_timeslice(struct LP_tradebot *bot) { bot->relsum += relvol; bot->basesum += v; + bot->completed++; } else { bot->pendrelsum += relvol; bot->pendbasesum += v; + bot->numpending++; } + bot->numtrades++; if ( bot->relsum >= bot->totalrelvolume-SMALLVAL || bot->basesum >= bot->totalbasevolume-SMALLVAL ) bot->dead = (uint32_t)time(NULL); else if ( (bot->pendrelsum+bot->relsum) >= bot->totalrelvolume-SMALLVAL || (bot->basesum+bot->pendbasesum) >= bot->totalbasevolume-SMALLVAL ) From 62a272713a75cd00872f98db693ea9eee3bb1751 Mon Sep 17 00:00:00 2001 From: jl777 Date: Wed, 1 Nov 2017 14:15:43 +0200 Subject: [PATCH 0072/1664] Test --- iguana/exchanges/LP_tradebots.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/iguana/exchanges/LP_tradebots.c b/iguana/exchanges/LP_tradebots.c index 1eab5a419..5afa04414 100644 --- a/iguana/exchanges/LP_tradebots.c +++ b/iguana/exchanges/LP_tradebots.c @@ -270,7 +270,7 @@ void LP_tradebot_timeslice(struct LP_tradebot *bot) minprice = LP_pricevol_invert(&basevol,bot->maxprice,bot->totalrelvolume - bot->relsum); printf("simulated trade sell %s/%s minprice %.8f volume %.8f, %.8f %s -> %s min %.8f\n",bot->rel,bot->base,minprice,basevol,v,bot->base,bot->rel,p); } - if ( (rand() % 2) == 0 ) + if ( 1 || (rand() % 2) == 0 ) { bot->relsum += relvol; bot->basesum += v; From 766feb92bfda24baa95bea0eb9343efeef8439c7 Mon Sep 17 00:00:00 2001 From: jl777 Date: Wed, 1 Nov 2017 14:18:32 +0200 Subject: [PATCH 0073/1664] Test --- iguana/exchanges/LP_tradebots.c | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/iguana/exchanges/LP_tradebots.c b/iguana/exchanges/LP_tradebots.c index 5afa04414..9c841829e 100644 --- a/iguana/exchanges/LP_tradebots.c +++ b/iguana/exchanges/LP_tradebots.c @@ -179,10 +179,8 @@ cJSON *LP_tradebot_json(struct LP_tradebot *bot) array = cJSON_CreateArray(); //LP_tradebot_calcstats(bot); for (i=0; inumtrades; i++) - { jaddi(array,LP_tradebot_tradejson(bot->trades[i],bot->dispdir)); - jadd(json,"trades",array); - } + jadd(json,"trades",array); if ( bot->basesum > SMALLVAL && bot->relsum > SMALLVAL && bot->completed > 0 ) { jaddnum(json,"completed",bot->completed); From 2b1f5e288b5240599f4d04dddeca9382825803ad Mon Sep 17 00:00:00 2001 From: jl777 Date: Wed, 1 Nov 2017 14:21:30 +0200 Subject: [PATCH 0074/1664] Test --- iguana/exchanges/LP_tradebots.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/iguana/exchanges/LP_tradebots.c b/iguana/exchanges/LP_tradebots.c index 9c841829e..e96c1d459 100644 --- a/iguana/exchanges/LP_tradebots.c +++ b/iguana/exchanges/LP_tradebots.c @@ -268,7 +268,7 @@ void LP_tradebot_timeslice(struct LP_tradebot *bot) minprice = LP_pricevol_invert(&basevol,bot->maxprice,bot->totalrelvolume - bot->relsum); printf("simulated trade sell %s/%s minprice %.8f volume %.8f, %.8f %s -> %s min %.8f\n",bot->rel,bot->base,minprice,basevol,v,bot->base,bot->rel,p); } - if ( 1 || (rand() % 2) == 0 ) + if ( (rand() % 2) == 0 ) { bot->relsum += relvol; bot->basesum += v; From 4f14a69c59c1180a7ecb93beb96908c817c048f8 Mon Sep 17 00:00:00 2001 From: jl777 Date: Wed, 1 Nov 2017 14:25:25 +0200 Subject: [PATCH 0075/1664] Test --- iguana/exchanges/LP_tradebots.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/iguana/exchanges/LP_tradebots.c b/iguana/exchanges/LP_tradebots.c index e96c1d459..f3378045c 100644 --- a/iguana/exchanges/LP_tradebots.c +++ b/iguana/exchanges/LP_tradebots.c @@ -258,7 +258,7 @@ void LP_tradebot_timeslice(struct LP_tradebot *bot) //if ( (rand() % 100) == 0 ) { relvol = bot->totalrelvolume * 0.1; - p = LP_pricevol_invert(&v,bot->maxprice,relvol); + p = LP_pricevol_invert(&v,bot->maxprice,relvol) * (double)(91 + (rand()%10)/100.); if ( bot->dispdir > 0 ) { printf("simulated trade buy %s/%s maxprice %.8f volume %.8f, %.8f %s -> %s\n",bot->base,bot->rel,bot->maxprice,bot->totalrelvolume - bot->relsum,relvol,bot->rel,bot->base); From 5196c2d5ccd050492def9620c7fe924fac1c33d0 Mon Sep 17 00:00:00 2001 From: jl777 Date: Wed, 1 Nov 2017 14:28:14 +0200 Subject: [PATCH 0076/1664] Test --- iguana/exchanges/LP_tradebots.c | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/iguana/exchanges/LP_tradebots.c b/iguana/exchanges/LP_tradebots.c index f3378045c..78c8d453e 100644 --- a/iguana/exchanges/LP_tradebots.c +++ b/iguana/exchanges/LP_tradebots.c @@ -250,15 +250,16 @@ void LP_tradebotadd(struct LP_tradebot *bot) void LP_tradebot_timeslice(struct LP_tradebot *bot) { - double minprice,basevol,relvol,p,v; + double minprice,basevol,relvol,p,v,r; if ( bot->dead == 0 ) { if ( bot->pause == 0 ) { //if ( (rand() % 100) == 0 ) { - relvol = bot->totalrelvolume * 0.1; - p = LP_pricevol_invert(&v,bot->maxprice,relvol) * (double)(91 + (rand()%10)/100.); + r = (double)(91 + (rand()%10)/100.); + relvol = bot->totalrelvolume * 0.1 * r; + p = LP_pricevol_invert(&v,bot->maxprice,relvol); if ( bot->dispdir > 0 ) { printf("simulated trade buy %s/%s maxprice %.8f volume %.8f, %.8f %s -> %s\n",bot->base,bot->rel,bot->maxprice,bot->totalrelvolume - bot->relsum,relvol,bot->rel,bot->base); From 3162ee0a69662cf9c43eb2ecfa6aa2c619f9b4e7 Mon Sep 17 00:00:00 2001 From: jl777 Date: Wed, 1 Nov 2017 14:30:54 +0200 Subject: [PATCH 0077/1664] Test --- iguana/exchanges/LP_tradebots.c | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/iguana/exchanges/LP_tradebots.c b/iguana/exchanges/LP_tradebots.c index 78c8d453e..e2f2cc8b7 100644 --- a/iguana/exchanges/LP_tradebots.c +++ b/iguana/exchanges/LP_tradebots.c @@ -257,17 +257,18 @@ void LP_tradebot_timeslice(struct LP_tradebot *bot) { //if ( (rand() % 100) == 0 ) { - r = (double)(91 + (rand()%10)/100.); + r = (double)(91 + (rand()%10))/100.; relvol = bot->totalrelvolume * 0.1 * r; - p = LP_pricevol_invert(&v,bot->maxprice,relvol); + r = (double)(96 + (rand()%5))/100.; + p = LP_pricevol_invert(&v,bot->maxprice * r,relvol); if ( bot->dispdir > 0 ) { - printf("simulated trade buy %s/%s maxprice %.8f volume %.8f, %.8f %s -> %s\n",bot->base,bot->rel,bot->maxprice,bot->totalrelvolume - bot->relsum,relvol,bot->rel,bot->base); + printf("simulated trade buy %s/%s maxprice %.8f volume %.8f, %.8f %s -> %s, price %.8f\n",bot->base,bot->rel,bot->maxprice,bot->totalrelvolume - bot->relsum,relvol,bot->rel,bot->base,bot->maxprice*r); } else { minprice = LP_pricevol_invert(&basevol,bot->maxprice,bot->totalrelvolume - bot->relsum); - printf("simulated trade sell %s/%s minprice %.8f volume %.8f, %.8f %s -> %s min %.8f\n",bot->rel,bot->base,minprice,basevol,v,bot->base,bot->rel,p); + printf("simulated trade sell %s/%s minprice %.8f volume %.8f, %.8f %s -> %s price %.8f\n",bot->rel,bot->base,minprice,basevol,v,bot->base,bot->rel,p); } if ( (rand() % 2) == 0 ) { From 71b96cf9259371e00579bfd12780484abaac06c0 Mon Sep 17 00:00:00 2001 From: jl777 Date: Wed, 1 Nov 2017 14:37:15 +0200 Subject: [PATCH 0078/1664] Test --- iguana/exchanges/LP_tradebots.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/iguana/exchanges/LP_tradebots.c b/iguana/exchanges/LP_tradebots.c index e2f2cc8b7..0b53b44e1 100644 --- a/iguana/exchanges/LP_tradebots.c +++ b/iguana/exchanges/LP_tradebots.c @@ -257,8 +257,10 @@ void LP_tradebot_timeslice(struct LP_tradebot *bot) { //if ( (rand() % 100) == 0 ) { - r = (double)(91 + (rand()%10))/100.; - relvol = bot->totalrelvolume * 0.1 * r; + r = (double)(51 + (rand()%50))/100.; + relvol = (bot->totalrelvolume - bot->relsum); + if ( relvol > (bot->totalrelvolume * .1) ) + relvol *= r; r = (double)(96 + (rand()%5))/100.; p = LP_pricevol_invert(&v,bot->maxprice * r,relvol); if ( bot->dispdir > 0 ) From a266e14c1523b1692cf3ac03832dbac76562710e Mon Sep 17 00:00:00 2001 From: jl777 Date: Wed, 1 Nov 2017 14:43:53 +0200 Subject: [PATCH 0079/1664] Test --- iguana/exchanges/LP_nativeDEX.c | 2 +- iguana/exchanges/LP_tradebots.c | 12 ++++++++---- 2 files changed, 9 insertions(+), 5 deletions(-) diff --git a/iguana/exchanges/LP_nativeDEX.c b/iguana/exchanges/LP_nativeDEX.c index 06276ed78..1139a0ea7 100644 --- a/iguana/exchanges/LP_nativeDEX.c +++ b/iguana/exchanges/LP_nativeDEX.c @@ -18,7 +18,7 @@ // LP_nativeDEX.c // marketmaker // -// limit bot +// electrum keepalive // verify portfolio, interest to KMD withdraw // dPoW security -> 4: KMD notarized, 5: BTC notarized, after next notary elections // bigendian architectures need to use little endian for sighash calcs diff --git a/iguana/exchanges/LP_tradebots.c b/iguana/exchanges/LP_tradebots.c index 0b53b44e1..fd195cdcc 100644 --- a/iguana/exchanges/LP_tradebots.c +++ b/iguana/exchanges/LP_tradebots.c @@ -257,7 +257,7 @@ void LP_tradebot_timeslice(struct LP_tradebot *bot) { //if ( (rand() % 100) == 0 ) { - r = (double)(51 + (rand()%50))/100.; + r = (double)(51 + (rand()%25))/100.; relvol = (bot->totalrelvolume - bot->relsum); if ( relvol > (bot->totalrelvolume * .1) ) relvol *= r; @@ -265,12 +265,12 @@ void LP_tradebot_timeslice(struct LP_tradebot *bot) p = LP_pricevol_invert(&v,bot->maxprice * r,relvol); if ( bot->dispdir > 0 ) { - printf("simulated trade buy %s/%s maxprice %.8f volume %.8f, %.8f %s -> %s, price %.8f\n",bot->base,bot->rel,bot->maxprice,bot->totalrelvolume - bot->relsum,relvol,bot->rel,bot->base,bot->maxprice*r); + printf("simulated trade buy %s/%s maxprice %.8f volume %.8f, %.8f %s -> %s, price %.8f relvol %.8f\n",bot->base,bot->rel,bot->maxprice,bot->totalrelvolume - bot->relsum,relvol,bot->rel,bot->base,bot->maxprice*r,relvol); } else { minprice = LP_pricevol_invert(&basevol,bot->maxprice,bot->totalrelvolume - bot->relsum); - printf("simulated trade sell %s/%s minprice %.8f volume %.8f, %.8f %s -> %s price %.8f\n",bot->rel,bot->base,minprice,basevol,v,bot->base,bot->rel,p); + printf("simulated trade sell %s/%s minprice %.8f volume %.8f, %.8f %s -> %s price %.8f relvol %.8f\n",bot->rel,bot->base,minprice,basevol,v,bot->base,bot->rel,p,relvol); } if ( (rand() % 2) == 0 ) { @@ -328,7 +328,11 @@ char *LP_tradebot_list(void *ctx,int32_t pubsock,cJSON *argjson) char *LP_tradebot_buy(int32_t dispdir,char *base,char *rel,double maxprice,double relvolume) { - struct LP_tradebot *bot; + struct LP_tradebot *bot; struct iguana_info *basecoin,*relcoin; + basecoin = LP_coinfind(base); + relcoin = LP_coinfind(rel); + if ( basecoin == 0 || relcoin == 0 || basecoin->inactive != 0 || relcoin->inactive != 0 ) + return(clonestr("{\"error\":\"one or more coins inactive\"}")); printf("disp.%d tradebot_buy(%s / %s) maxprice %.8f relvolume %.8f\n",dispdir,base,rel,maxprice,relvolume); if ( (bot= calloc(1,sizeof(*bot))) != 0 ) { From 223d0f64d62b3bbb08d52741add36b72bff74c6c Mon Sep 17 00:00:00 2001 From: jl777 Date: Wed, 1 Nov 2017 14:47:09 +0200 Subject: [PATCH 0080/1664] Test --- iguana/exchanges/LP_tradebots.c | 12 ++++-------- 1 file changed, 4 insertions(+), 8 deletions(-) diff --git a/iguana/exchanges/LP_tradebots.c b/iguana/exchanges/LP_tradebots.c index fd195cdcc..dc7b7cfbc 100644 --- a/iguana/exchanges/LP_tradebots.c +++ b/iguana/exchanges/LP_tradebots.c @@ -250,22 +250,18 @@ void LP_tradebotadd(struct LP_tradebot *bot) void LP_tradebot_timeslice(struct LP_tradebot *bot) { - double minprice,basevol,relvol,p,v,r; + double minprice,basevol,relvol,p,v; if ( bot->dead == 0 ) { if ( bot->pause == 0 ) { //if ( (rand() % 100) == 0 ) { - r = (double)(51 + (rand()%25))/100.; - relvol = (bot->totalrelvolume - bot->relsum); - if ( relvol > (bot->totalrelvolume * .1) ) - relvol *= r; - r = (double)(96 + (rand()%5))/100.; - p = LP_pricevol_invert(&v,bot->maxprice * r,relvol); + relvol = bot->totalrelvolume * .1; + p = LP_pricevol_invert(&v,bot->maxprice,relvol); if ( bot->dispdir > 0 ) { - printf("simulated trade buy %s/%s maxprice %.8f volume %.8f, %.8f %s -> %s, price %.8f relvol %.8f\n",bot->base,bot->rel,bot->maxprice,bot->totalrelvolume - bot->relsum,relvol,bot->rel,bot->base,bot->maxprice*r,relvol); + printf("simulated trade buy %s/%s maxprice %.8f volume %.8f, %.8f %s -> %s, price %.8f relvol %.8f\n",bot->base,bot->rel,bot->maxprice,bot->totalrelvolume - bot->relsum,relvol,bot->rel,bot->base,bot->maxprice,relvol); } else { From 0cfa8f8a6c0687546211aa20deff872d67f2e4af Mon Sep 17 00:00:00 2001 From: jl777 Date: Wed, 1 Nov 2017 18:43:26 +0200 Subject: [PATCH 0081/1664] Enable bots trading --- iguana/exchanges/LP_nativeDEX.c | 6 +- iguana/exchanges/LP_ordermatch.c | 8 +- iguana/exchanges/LP_remember.c | 4 +- iguana/exchanges/LP_statemachine.c | 29 ++++- iguana/exchanges/LP_swap.c | 4 +- iguana/exchanges/LP_tradebots.c | 189 ++++++++++++++++++++--------- 6 files changed, 172 insertions(+), 68 deletions(-) diff --git a/iguana/exchanges/LP_nativeDEX.c b/iguana/exchanges/LP_nativeDEX.c index 1139a0ea7..a4bf251b1 100644 --- a/iguana/exchanges/LP_nativeDEX.c +++ b/iguana/exchanges/LP_nativeDEX.c @@ -49,7 +49,7 @@ uint32_t LP_lastnonce,LP_counter; int32_t LP_mybussock = -1; int32_t LP_mypubsock = -1; int32_t LP_mypullsock = -1; -int32_t LP_showwif,IAMLP = 0; +int32_t LP_numfinished,LP_showwif,IAMLP = 0; double LP_profitratio = 1.; struct LP_privkey { bits256 privkey; uint8_t rmd160[20]; }; @@ -1028,9 +1028,9 @@ void LPinit(uint16_t myport,uint16_t mypullport,uint16_t mypubport,uint16_t mybu printf("error launching LP_swapsloop for port.%u\n",myport); exit(-1); } - if ( OS_thread_create(malloc(sizeof(pthread_t)),NULL,(void *)LP_tradebot_timeslices,(void *)myipaddr) != 0 ) + if ( OS_thread_create(malloc(sizeof(pthread_t)),NULL,(void *)LP_tradebot_timeslices,ctx) != 0 ) { - printf("error launching LP_tradebot_timeslices for port.%u\n",myport); + printf("error launching LP_tradebot_timeslices\n"); exit(-1); } int32_t nonz; diff --git a/iguana/exchanges/LP_ordermatch.c b/iguana/exchanges/LP_ordermatch.c index aba389945..0f0451750 100644 --- a/iguana/exchanges/LP_ordermatch.c +++ b/iguana/exchanges/LP_ordermatch.c @@ -411,7 +411,7 @@ char *LP_trade(void *ctx,char *myipaddr,int32_t mypubsock,struct LP_quoteinfo *q qp->aliceid = LP_aliceid_calc(qp->desttxid,qp->destvout,qp->feetxid,qp->feevout); LP_query(ctx,myipaddr,mypubsock,"request",qp); LP_Alicequery = *qp, LP_Alicemaxprice = maxprice, Alice_expiration = qp->timestamp + timeout; - return(clonestr("{\"result\":\"success\"}")); + return(LP_recent_swaps(0)); } int32_t LP_quotecmp(struct LP_quoteinfo *qp,struct LP_quoteinfo *qp2) @@ -625,11 +625,11 @@ int32_t LP_tradecommand(void *ctx,char *myipaddr,int32_t pubsock,cJSON *argjson, printf("this node has no price for %s/%s\n",Q.srccoin,Q.destcoin); return(retval); } - if ( coin->electrum != 0 ) + /*if ( coin->electrum != 0 ) { printf("electrum can only be for alice\n"); return(retval); - } + }*/ if ( LP_aliceonly(Q.srccoin) > 0 ) { printf("{\"error\":\"GAME can only be alice coin\"}\n"); @@ -783,7 +783,7 @@ struct LP_utxoinfo *LP_buyutxo(double *ordermatchpricep,int64_t *bestsatoshisp,i return(0); if ( basecoin->electrum == 0 ) max = 1000; - else max = 20; + else max = 40; utxos = calloc(max,sizeof(*utxos)); LP_txfees(&txfee,&desttxfee,base,autxo->coin); printf("LP_buyutxo maxprice %.8f relvol %.8f %s/%s %.8f %.8f\n",maxprice,dstr(autxo->S.satoshis),base,autxo->coin,dstr(txfee),dstr(desttxfee)); diff --git a/iguana/exchanges/LP_remember.c b/iguana/exchanges/LP_remember.c index 8f5272f20..953910c42 100644 --- a/iguana/exchanges/LP_remember.c +++ b/iguana/exchanges/LP_remember.c @@ -1130,7 +1130,8 @@ cJSON *basilisk_remember(int64_t *KMDtotals,int64_t *BTCtotals,uint32_t requesti if ( rswap.origfinishedflag == 0 && rswap.finishedflag != 0 ) { char fname[1024],*itemstr; FILE *fp; - printf("SWAP %u-%u finished!\n",requestid,quoteid); + LP_numfinished++; + printf("SWAP %u-%u finished LP_numfinished.%d !\n",requestid,quoteid,LP_numfinished); sprintf(fname,"%s/SWAPS/%u-%u.finished",GLOBAL_DBDIR,rswap.requestid,rswap.quoteid), OS_compatible_path(fname); if ( (fp= fopen(fname,"wb")) != 0 ) { @@ -1315,6 +1316,7 @@ char *LP_recent_swaps(int32_t limit) jaddstr(item,"alice",LP_Alicequery.destcoin); jaddstr(item,"rel",LP_Alicequery.destcoin); jaddnum(item,"relvalue",dstr(LP_Alicequery.destsatoshis)); + jaddnum(item,"aliceid",LP_aliceid_calc(LP_Alicequery.desttxid,LP_Alicequery.destvout,LP_Alicequery.feetxid,LP_Alicequery.feevout)); jadd(retjson,"pending",item); } else Alice_expiration = 0; return(jprint(retjson,1)); diff --git a/iguana/exchanges/LP_statemachine.c b/iguana/exchanges/LP_statemachine.c index c14c557ee..a3b824d36 100644 --- a/iguana/exchanges/LP_statemachine.c +++ b/iguana/exchanges/LP_statemachine.c @@ -2275,7 +2275,34 @@ void LP_price_broadcastloop(void *ctx) retstr = clonestr("{\"result\":\"success\"}"); } else retstr = clonestr("{\"error\":\"couldnt dereference sendmessage\"}"); } - else*/ #ifdef FROM_JS + else*/ + +/*relvol = bot->totalrelvolume * .1; + p = LP_pricevol_invert(&v,bot->maxprice,relvol); + if ( bot->dispdir > 0 ) + { + printf("simulated trade buy %s/%s maxprice %.8f volume %.8f, %.8f %s -> %s, price %.8f relvol %.8f\n",bot->base,bot->rel,bot->maxprice,bot->totalrelvolume - bot->relsum,relvol,bot->rel,bot->base,bot->maxprice,relvol); + } + else + { + minprice = LP_pricevol_invert(&basevol,bot->maxprice,bot->totalrelvolume - bot->relsum); + printf("simulated trade sell %s/%s minprice %.8f volume %.8f, %.8f %s -> %s price %.8f relvol %.8f\n",bot->rel,bot->base,minprice,basevol,v,bot->base,bot->rel,p,relvol); + } + if ( (rand() % 2) == 0 ) + { + bot->relsum += relvol; + bot->basesum += v; + bot->completed++; + } + else + { + bot->pendrelsum += relvol; + bot->pendbasesum += v; + bot->numpending++; + } + bot->numtrades++; + */ +#ifdef FROM_JS int32_t sentbytes,sock,peerind,maxind; if ( (maxind= LP_numpeers()) > 0 ) peerind = (rand() % maxind) + 1; diff --git a/iguana/exchanges/LP_swap.c b/iguana/exchanges/LP_swap.c index 0238e398b..72860cc80 100644 --- a/iguana/exchanges/LP_swap.c +++ b/iguana/exchanges/LP_swap.c @@ -798,7 +798,7 @@ void LP_bobloop(void *_swap) basilisk_bobpayment_reclaim(swap,swap->I.callduration); 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); + LP_swapwait(swap->I.req.requestid,swap->I.req.quoteid,INSTANTDEX_LOCKTIME*2,30); } } } @@ -864,7 +864,7 @@ void LP_aliceloop(void *_swap) }*/ 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); + LP_swapwait(swap->I.req.requestid,swap->I.req.quoteid,INSTANTDEX_LOCKTIME*2,30); } } } diff --git a/iguana/exchanges/LP_tradebots.c b/iguana/exchanges/LP_tradebots.c index dc7b7cfbc..f6ede98e5 100644 --- a/iguana/exchanges/LP_tradebots.c +++ b/iguana/exchanges/LP_tradebots.c @@ -23,7 +23,7 @@ struct LP_tradebot_trade { - double maxprice,relvolume,basevol,relvol; + double maxprice,totalrelvolume,basevol,relvol; uint64_t aliceid; int32_t dispdir; uint32_t started,finished,requestid,quoteid; @@ -40,21 +40,6 @@ struct LP_tradebot struct LP_tradebot_trade *trades[LP_TRADEBOTS_MAXTRADES]; } *LP_tradebots; -/*struct tradebot_trade *tradebot_issuetrade(struct LP_tradebot *bot,char *base,char *rel,double price,double volume,int32_t dir) -{ - struct tradebot_trade *tr; char *str; int32_t maxseconds = 30,dotrade = 1; - bot = realloc(bot,sizeof(*bot) + (bot->numtrades + 1) * sizeof(bot->trades[0])); - tr = &bot->trades[bot->numtrades++]; - memset(tr,0,sizeof(*tr)); - tr->price = price, tr->volume = volume, tr->dir = dir; - safecopy(tr->exchangestr,exchange->name,sizeof(tr->exchangestr)); - safecopy(tr->base,base,sizeof(tr->base)); - safecopy(tr->rel,rel,sizeof(tr->rel)); - if ( (str= exchanges777_Qtrade(exchange,base,rel,maxseconds,dotrade,dir,price,volume,0)) != 0 ) - free(str); - return(tr); -}*/ - void LP_tradebot_updatestats(struct LP_tradebot *bot,struct LP_tradebot_trade *tp) { char *swapstr,*status; int32_t flag; cJSON *swapjson; @@ -177,7 +162,7 @@ cJSON *LP_tradebot_json(struct LP_tradebot *bot) } } array = cJSON_CreateArray(); - //LP_tradebot_calcstats(bot); + LP_tradebot_calcstats(bot); for (i=0; inumtrades; i++) jaddi(array,LP_tradebot_tradejson(bot->trades[i],bot->dispdir)); jadd(json,"trades",array); @@ -248,66 +233,156 @@ void LP_tradebotadd(struct LP_tradebot *bot) portable_mutex_unlock(&LP_tradebotsmutex); } -void LP_tradebot_timeslice(struct LP_tradebot *bot) +struct LP_tradebot_trade *LP_tradebot_pending(struct LP_tradebot *bot,cJSON *pending) { - double minprice,basevol,relvol,p,v; - if ( bot->dead == 0 ) + struct LP_tradebot_trade *tp; + tp = calloc(1,sizeof(*tp)); + tp->maxprice = bot->maxprice; + tp->totalrelvolume = bot->totalrelvolume; + tp->started = (uint32_t)time(NULL); + tp->dispdir = bot->dispdir; + strcpy(tp->base,bot->base); + strcpy(tp->rel,bot->rel); + tp->aliceid = j64bits(pending,"aliceid"); + tp->basevol = jdouble(pending,"basevalue"); + tp->relvol = jdouble(pending,"relvalue"); + bot->pendrelsum += tp->relvol; + bot->pendbasesum += tp->basevol; + bot->numpending++; + return(tp); +} + +void LP_tradebot_timeslice(void *ctx,struct LP_tradebot *bot) +{ + double remaining; bits256 destpubkey; char *retstr,*liststr; cJSON *retjson,*pending; + memset(destpubkey.bytes,0,sizeof(destpubkey)); + if ( bot->dead == 0 && bot->pause == 0 && bot->numtrades < sizeof(bot->trades)/sizeof(*bot->trades) ) { - if ( bot->pause == 0 ) + if ( (liststr= LP_recent_swaps(0)) != 0 ) { - //if ( (rand() % 100) == 0 ) + if ( (retjson= cJSON_Parse(liststr)) != 0 ) { - relvol = bot->totalrelvolume * .1; - p = LP_pricevol_invert(&v,bot->maxprice,relvol); - if ( bot->dispdir > 0 ) - { - printf("simulated trade buy %s/%s maxprice %.8f volume %.8f, %.8f %s -> %s, price %.8f relvol %.8f\n",bot->base,bot->rel,bot->maxprice,bot->totalrelvolume - bot->relsum,relvol,bot->rel,bot->base,bot->maxprice,relvol); - } - else - { - minprice = LP_pricevol_invert(&basevol,bot->maxprice,bot->totalrelvolume - bot->relsum); - printf("simulated trade sell %s/%s minprice %.8f volume %.8f, %.8f %s -> %s price %.8f relvol %.8f\n",bot->rel,bot->base,minprice,basevol,v,bot->base,bot->rel,p,relvol); - } - if ( (rand() % 2) == 0 ) - { - bot->relsum += relvol; - bot->basesum += v; - bot->completed++; - } - else + if ( jobj(retjson,"pending") == 0 ) { - bot->pendrelsum += relvol; - bot->pendbasesum += v; - bot->numpending++; + remaining = bot->totalrelvolume - (bot->relsum + bot->pendrelsum); + printf("try autobuy %s/%s remaining %.8f maxprice %.8f\n",bot->base,bot->rel,remaining,bot->maxprice); + if ( (retstr= LP_autobuy(ctx,LP_myipaddr,LP_mypubsock,bot->base,bot->rel,bot->maxprice,remaining,0,0,G.gui,0,destpubkey)) != 0 ) + { + if ( (pending= cJSON_Parse(retstr)) != 0 ) + { + if ( jobj(pending,"pending") != 0 ) + { + bot->trades[bot->numtrades++] = LP_tradebot_pending(bot,pending); + if ( bot->relsum >= bot->totalrelvolume-SMALLVAL || bot->basesum >= bot->totalbasevolume-SMALLVAL ) + bot->dead = (uint32_t)time(NULL); + else if ( (bot->pendrelsum+bot->relsum) >= bot->totalrelvolume-SMALLVAL || (bot->basesum+bot->pendbasesum) >= bot->totalbasevolume-SMALLVAL ) + bot->pause = (uint32_t)time(NULL); + printf("%s\n",jprint(LP_tradebot_json(bot),1)); + } else printf("didnt get any trade pending %s\n",bot->name); + free_json(pending); + } + free(retstr); + } } - bot->numtrades++; - if ( bot->relsum >= bot->totalrelvolume-SMALLVAL || bot->basesum >= bot->totalbasevolume-SMALLVAL ) - bot->dead = (uint32_t)time(NULL); - else if ( (bot->pendrelsum+bot->relsum) >= bot->totalrelvolume-SMALLVAL || (bot->basesum+bot->pendbasesum) >= bot->totalbasevolume-SMALLVAL ) - bot->pause = (uint32_t)time(NULL); - printf("%s\n",jprint(LP_tradebot_json(bot),1)); + free_json(retjson); } + free(liststr); } } - else - { - //DL_DELETE(LP_tradebots,bot); - //free(bot); - } + else if ( bot->pause == 0 ) + bot->pause = (uint32_t)time(NULL); } -void LP_tradebot_timeslices(void *ignore) +void LP_tradebot_timeslices(void *ctx) { - struct LP_tradebot *bot,*tmp; + struct LP_tradebot_trade *tp; struct LP_tradebot *bot,*tmp; char *retstr,*status; cJSON *retjson,*item; uint64_t aliceid; int32_t i,j,n,flag,lastnumfinished = 0; while ( 1 ) { DL_FOREACH_SAFE(LP_tradebots,bot,tmp) { portable_mutex_lock(&LP_tradebotsmutex); - LP_tradebot_timeslice(bot); + LP_tradebot_timeslice(ctx,bot); + if ( bot->numpending > 0 && LP_numfinished > lastnumfinished ) + { + // expire pending trades and see if any still need their requestid/quoteid + for (i=flag=0; inumtrades; i++) + { + if ( (tp= bot->trades[i]) != 0 && tp->finished == 0 ) + { + if ( time(NULL) > tp->started+INSTANTDEX_LOCKTIME*2 ) + { + bot->pendbasesum -= tp->basevol; + bot->pendrelsum -= tp->relvol; + bot->numpending--; + tp->finished = (uint32_t)time(NULL); + printf("%s trade.%d of %d expired\n",bot->name,i,bot->numtrades); + } + else if ( tp->requestid == 0 && tp->quoteid == 0 ) + flag = 1; + } + } + if ( flag != 0 ) + { + // need to find the requestid/quoteid for aliceid + if ( (retstr= basilisk_swapentries(bot->base,bot->rel,0)) != 0 ) + { + if ( (retjson= cJSON_Parse(retstr)) != 0 ) + { + if ( (n= cJSON_GetArraySize(retjson)) != 0 ) + { + for (flag=j=0; jnumtrades; i++) + { + if ( (tp= bot->trades[i]) != 0 && tp->finished == 0 && tp->requestid == 0 && tp->quoteid == 0 ) + { + if ( tp->aliceid == aliceid ) + { + tp->requestid = juint(item,"requestid"); + tp->quoteid = juint(item,"quoteid"); + printf("found aliceid.%llx to set requestid.%u quoteid.%u\n",(long long)aliceid,tp->requestid,tp->quoteid); + flag = 1; + break; + } + } + } + } + } + free_json(retjson); + } + free(retstr); + } + } + // check for finished pending swap + for (i=0; inumtrades; i++) + { + if ( (tp= bot->trades[i]) != 0 && tp->finished == 0 && tp->requestid != 0 && tp->quoteid != 0 ) + { + if ( (retstr= basilisk_swapentry(tp->requestid,tp->quoteid)) != 0 ) + { + if ( (retjson= cJSON_Parse(retstr)) != 0 ) + { + if ( (status= jstr(retjson,"status")) != 0 && strcmp(status,"finished") == 0 ) + { + bot->pendbasesum -= tp->basevol, bot->basesum += tp->basevol; + bot->pendrelsum -= tp->relvol, bot->relsum += tp->relvol; + bot->numpending--, bot->completed++; + printf("detected completion aliceid.%llx r.%u q.%u\n",(long long)tp->aliceid,tp->requestid,tp->quoteid); + tp->finished = (uint32_t)time(NULL); + } + free_json(retjson); + } + free(retstr); + } + } + } + } portable_mutex_unlock(&LP_tradebotsmutex); sleep(1); } + lastnumfinished = LP_numfinished; sleep(10); } } From 0174ea595255415ad06156e6c7ee5c1faffa17b3 Mon Sep 17 00:00:00 2001 From: jl777 Date: Wed, 1 Nov 2017 18:53:15 +0200 Subject: [PATCH 0082/1664] Test --- iguana/exchanges/LP_tradebots.c | 28 +++++++++++++++++++++++++++- 1 file changed, 27 insertions(+), 1 deletion(-) diff --git a/iguana/exchanges/LP_tradebots.c b/iguana/exchanges/LP_tradebots.c index f6ede98e5..96d6d206c 100644 --- a/iguana/exchanges/LP_tradebots.c +++ b/iguana/exchanges/LP_tradebots.c @@ -399,11 +399,37 @@ char *LP_tradebot_list(void *ctx,int32_t pubsock,cJSON *argjson) char *LP_tradebot_buy(int32_t dispdir,char *base,char *rel,double maxprice,double relvolume) { - struct LP_tradebot *bot; struct iguana_info *basecoin,*relcoin; + struct LP_tradebot *bot; int32_t i,n; cJSON *array,*item,*retjson; uint64_t txfees,balance=0; struct iguana_info *basecoin,*relcoin; basecoin = LP_coinfind(base); relcoin = LP_coinfind(rel); if ( basecoin == 0 || relcoin == 0 || basecoin->inactive != 0 || relcoin->inactive != 0 ) return(clonestr("{\"error\":\"one or more coins inactive\"}")); + if ( (array= LP_inventory(rel)) != 0 ) + { + if ( (n= cJSON_GetArraySize(array)) > 0 && is_cJSON_Array(array) != 0 ) + { + for (i=0; itxfee; + if ( dstr(balance) < relvolume + dstr(txfees) ) + { + printf("%s inventory balance only %.8f, less than relvolume %.8f + txfees %.8f\n",rel,dstr(balance),relvolume,dstr(txfees)); + retjson = cJSON_CreateObject(); + jaddstr(retjson,"error","not enough funds"); + jaddstr(retjson,"coin",rel); + jaddnum(retjson,"balance",dstr(balance)); + jaddnum(retjson,"relvolume",relvolume); + jaddnum(retjson,"txfees",dstr(txfees)); + jaddnum(retjson,"shortfall",(relvolume + dstr(txfees)) - dstr(balance)); + return(jprint(retjson,1)); + } printf("disp.%d tradebot_buy(%s / %s) maxprice %.8f relvolume %.8f\n",dispdir,base,rel,maxprice,relvolume); if ( (bot= calloc(1,sizeof(*bot))) != 0 ) { From 996fba765e4bd56b2e810d39d3fadd570a03e5c7 Mon Sep 17 00:00:00 2001 From: jl777 Date: Wed, 1 Nov 2017 19:21:06 +0200 Subject: [PATCH 0083/1664] Test --- iguana/exchanges/LP_coins.c | 2 +- iguana/exchanges/LP_include.h | 2 +- iguana/exchanges/LP_rpc.c | 2 +- iguana/exchanges/LP_tradebots.c | 33 +++++++++++++++++++++++++++------ 4 files changed, 30 insertions(+), 9 deletions(-) diff --git a/iguana/exchanges/LP_coins.c b/iguana/exchanges/LP_coins.c index 945bd5915..5db73995d 100644 --- a/iguana/exchanges/LP_coins.c +++ b/iguana/exchanges/LP_coins.c @@ -198,7 +198,7 @@ cJSON *LP_coinjson(struct iguana_info *coin,int32_t showwif) if ( coin->userpass[0] != 0 ) { jaddnum(item,"height",LP_getheight(coin)); - balance = LP_smartbalance(coin); + balance = LP_RTsmartbalance(coin); jaddnum(item,"balance",dstr(balance)); jaddnum(item,"KMDvalue",dstr(LP_KMDvalue(coin,balance))); } diff --git a/iguana/exchanges/LP_include.h b/iguana/exchanges/LP_include.h index a250c9434..35e2aa43e 100644 --- a/iguana/exchanges/LP_include.h +++ b/iguana/exchanges/LP_include.h @@ -356,7 +356,7 @@ uint16_t LP_psock_get(char *connectaddr,char *connectaddr2,char *publicaddr,int3 //void LP_utxo_clientpublish(struct LP_utxoinfo *utxo); int32_t LP_coinbus(uint16_t coin_busport); int32_t LP_nanomsg_recvs(void *ctx); -uint64_t LP_smartbalance(struct iguana_info *coin); +uint64_t LP_RTsmartbalance(struct iguana_info *coin); int32_t LP_getheight(struct iguana_info *coin); int32_t LP_reserved_msg(char *base,char *rel,bits256 pubkey,char *msg); struct iguana_info *LP_coinfind(char *symbol); diff --git a/iguana/exchanges/LP_rpc.c b/iguana/exchanges/LP_rpc.c index 24d2cb5f2..e2fc80bb2 100644 --- a/iguana/exchanges/LP_rpc.c +++ b/iguana/exchanges/LP_rpc.c @@ -397,7 +397,7 @@ int32_t LP_getheight(struct iguana_info *coin) return(height); } -uint64_t LP_smartbalance(struct iguana_info *coin) +uint64_t LP_RTsmartbalance(struct iguana_info *coin) { cJSON *array,*item; char buf[512],*retstr; int32_t i,n; uint64_t valuesum,value; valuesum = 0; diff --git a/iguana/exchanges/LP_tradebots.c b/iguana/exchanges/LP_tradebots.c index 96d6d206c..77c694717 100644 --- a/iguana/exchanges/LP_tradebots.c +++ b/iguana/exchanges/LP_tradebots.c @@ -399,7 +399,7 @@ char *LP_tradebot_list(void *ctx,int32_t pubsock,cJSON *argjson) char *LP_tradebot_buy(int32_t dispdir,char *base,char *rel,double maxprice,double relvolume) { - struct LP_tradebot *bot; int32_t i,n; cJSON *array,*item,*retjson; uint64_t txfees,balance=0; struct iguana_info *basecoin,*relcoin; + struct LP_tradebot *bot; double shortfall; int32_t i,n; cJSON *array,*item,*retjson; uint64_t txfees,balance=0,abalance=0; struct iguana_info *basecoin,*relcoin; basecoin = LP_coinfind(base); relcoin = LP_coinfind(rel); if ( basecoin == 0 || relcoin == 0 || basecoin->inactive != 0 || relcoin->inactive != 0 ) @@ -412,22 +412,43 @@ char *LP_tradebot_buy(int32_t dispdir,char *base,char *rel,double maxprice,doubl { item = jitem(array,i); //valuesum += j64bits(item,"value") + j64bits(item,"value2"); - balance += j64bits(item,"satoshis"); + abalance += j64bits(item,"satoshis"); } } free_json(array); } txfees = 10 * relcoin->txfee; - if ( dstr(balance) < relvolume + dstr(txfees) ) + if ( dstr(abalance) < relvolume + dstr(txfees) ) { - printf("%s inventory balance only %.8f, less than relvolume %.8f + txfees %.8f\n",rel,dstr(balance),relvolume,dstr(txfees)); + printf("%s inventory balance only %.8f, less than relvolume %.8f + txfees %.8f\n",rel,dstr(abalance),relvolume,dstr(txfees)); retjson = cJSON_CreateObject(); jaddstr(retjson,"error","not enough funds"); jaddstr(retjson,"coin",rel); - jaddnum(retjson,"balance",dstr(balance)); + jaddnum(retjson,"balance",dstr(abalance)); jaddnum(retjson,"relvolume",relvolume); jaddnum(retjson,"txfees",dstr(txfees)); - jaddnum(retjson,"shortfall",(relvolume + dstr(txfees)) - dstr(balance)); + shortfall = (relvolume + dstr(txfees)) - dstr(balance); + jaddnum(retjson,"shortfall",shortfall); + if ( (balance= LP_RTsmartbalance(relcoin)) > abalance+SATOSHIDEN*shortfall ) + { + char *withdrawstr; cJSON *outputjson,*withdrawjson,*outputs,*item; + outputjson = cJSON_CreateObject(); + outputs = cJSON_CreateArray(); + item = cJSON_CreateObject(); + jaddnum(item,relcoin->smartaddr,relvolume+dstr(txfees)); + jaddi(outputs,item); + item = cJSON_CreateObject(); + jaddnum(item,relcoin->smartaddr,(relvolume+dstr(txfees))/777); + jaddi(outputs,item); + jadd(outputjson,"outputs",outputs); + if ( (withdrawstr= LP_withdraw(relcoin,outputjson)) != 0 ) + { + if ( (withdrawjson= cJSON_Parse(withdrawstr)) != 0 ) + jadd(retjson,"withdraw",withdrawjson); + free(withdrawstr); + } + free_json(outputjson); + } return(jprint(retjson,1)); } printf("disp.%d tradebot_buy(%s / %s) maxprice %.8f relvolume %.8f\n",dispdir,base,rel,maxprice,relvolume); From 1766ca95abafce928d341a1bd2671313a709a95b Mon Sep 17 00:00:00 2001 From: jl777 Date: Wed, 1 Nov 2017 19:31:11 +0200 Subject: [PATCH 0084/1664] Test --- iguana/exchanges/LP_tradebots.c | 12 +++++++++--- 1 file changed, 9 insertions(+), 3 deletions(-) diff --git a/iguana/exchanges/LP_tradebots.c b/iguana/exchanges/LP_tradebots.c index 77c694717..7496d8914 100644 --- a/iguana/exchanges/LP_tradebots.c +++ b/iguana/exchanges/LP_tradebots.c @@ -280,7 +280,7 @@ void LP_tradebot_timeslice(void *ctx,struct LP_tradebot *bot) printf("%s\n",jprint(LP_tradebot_json(bot),1)); } else printf("didnt get any trade pending %s\n",bot->name); free_json(pending); - } + } else printf("%s\n",retstr); free(retstr); } } @@ -418,9 +418,9 @@ char *LP_tradebot_buy(int32_t dispdir,char *base,char *rel,double maxprice,doubl free_json(array); } txfees = 10 * relcoin->txfee; + printf("%s inventory balance %.8f, relvolume %.8f + txfees %.8f\n",rel,dstr(abalance),relvolume,dstr(txfees)); if ( dstr(abalance) < relvolume + dstr(txfees) ) { - printf("%s inventory balance only %.8f, less than relvolume %.8f + txfees %.8f\n",rel,dstr(abalance),relvolume,dstr(txfees)); retjson = cJSON_CreateObject(); jaddstr(retjson,"error","not enough funds"); jaddstr(retjson,"coin",rel); @@ -429,7 +429,7 @@ char *LP_tradebot_buy(int32_t dispdir,char *base,char *rel,double maxprice,doubl jaddnum(retjson,"txfees",dstr(txfees)); shortfall = (relvolume + dstr(txfees)) - dstr(balance); jaddnum(retjson,"shortfall",shortfall); - if ( (balance= LP_RTsmartbalance(relcoin)) > abalance+SATOSHIDEN*shortfall ) + if ( (balance= LP_RTsmartbalance(relcoin)) > abalance+SATOSHIDEN*(shortfall+relvolume/77.) ) { char *withdrawstr; cJSON *outputjson,*withdrawjson,*outputs,*item; outputjson = cJSON_CreateObject(); @@ -440,6 +440,12 @@ char *LP_tradebot_buy(int32_t dispdir,char *base,char *rel,double maxprice,doubl item = cJSON_CreateObject(); jaddnum(item,relcoin->smartaddr,(relvolume+dstr(txfees))/777); jaddi(outputs,item); + item = cJSON_CreateObject(); + jaddnum(item,relcoin->smartaddr,(relvolume+dstr(txfees))/777); + jaddi(outputs,item); + item = cJSON_CreateObject(); + jaddnum(item,relcoin->smartaddr,(relvolume+dstr(txfees))/777); + jaddi(outputs,item); jadd(outputjson,"outputs",outputs); if ( (withdrawstr= LP_withdraw(relcoin,outputjson)) != 0 ) { From 0989658c5d1499b2676273b7f625b77e757dbbfe Mon Sep 17 00:00:00 2001 From: jl777 Date: Wed, 1 Nov 2017 19:37:24 +0200 Subject: [PATCH 0085/1664] Test --- iguana/exchanges/LP_ordermatch.c | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/iguana/exchanges/LP_ordermatch.c b/iguana/exchanges/LP_ordermatch.c index 0f0451750..0e5bd8852 100644 --- a/iguana/exchanges/LP_ordermatch.c +++ b/iguana/exchanges/LP_ordermatch.c @@ -411,6 +411,7 @@ char *LP_trade(void *ctx,char *myipaddr,int32_t mypubsock,struct LP_quoteinfo *q qp->aliceid = LP_aliceid_calc(qp->desttxid,qp->destvout,qp->feetxid,qp->feevout); LP_query(ctx,myipaddr,mypubsock,"request",qp); LP_Alicequery = *qp, LP_Alicemaxprice = maxprice, Alice_expiration = qp->timestamp + timeout; + printf("LP_trade %s/%s %.8f vol %.8f\n",qp->srccoin,qp->destcoin,dstr(qp->satoshis),dstr(qp->destsatoshis)); return(LP_recent_swaps(0)); } @@ -905,6 +906,7 @@ char *LP_autobuy(void *ctx,char *myipaddr,int32_t mypubsock,char *base,char *rel memset(pubkeys,0,sizeof(pubkeys)); LP_txfees(&txfee,&desttxfee,base,rel); destsatoshis = SATOSHIDEN * relvolume + 2*desttxfee; +printf("call bestfit\n"); if ( (autxo= LP_utxo_bestfit(rel,destsatoshis)) == 0 ) return(clonestr("{\"error\":\"cant find alice utxo that is big enough\"}")); if ( destsatoshis < autxo->S.satoshis ) @@ -914,6 +916,7 @@ char *LP_autobuy(void *ctx,char *myipaddr,int32_t mypubsock,char *base,char *rel printf("destsatoshis %.8f vs utxo %.8f this would have triggered an quote error -13\n",dstr(destsatoshis),dstr(autxo->payment.value)); return(clonestr("{\"error\":\"cant find alice utxo that is small enough\"}")); } + printf("update metrics\n"); LP_RTmetrics_update(base,rel); while ( 1 ) { @@ -929,6 +932,7 @@ char *LP_autobuy(void *ctx,char *myipaddr,int32_t mypubsock,char *base,char *rel return(clonestr("{\"error\":\"cant set ordermatch quote info\"}")); maxiters = 200; qprice = 1. / SMALLVAL; +printf("validate\n"); for (i=0; i Date: Wed, 1 Nov 2017 19:37:48 +0200 Subject: [PATCH 0086/1664] Test --- iguana/exchanges/LP_tradebots.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/iguana/exchanges/LP_tradebots.c b/iguana/exchanges/LP_tradebots.c index 7496d8914..3e0b7e93c 100644 --- a/iguana/exchanges/LP_tradebots.c +++ b/iguana/exchanges/LP_tradebots.c @@ -278,7 +278,7 @@ void LP_tradebot_timeslice(void *ctx,struct LP_tradebot *bot) else if ( (bot->pendrelsum+bot->relsum) >= bot->totalrelvolume-SMALLVAL || (bot->basesum+bot->pendbasesum) >= bot->totalbasevolume-SMALLVAL ) bot->pause = (uint32_t)time(NULL); printf("%s\n",jprint(LP_tradebot_json(bot),1)); - } else printf("didnt get any trade pending %s\n",bot->name); + } else printf("didnt get any trade pending %s\n\n",bot->name); free_json(pending); } else printf("%s\n",retstr); free(retstr); From d9b40f78a98bd1a77a6760d06cd2ac817e27769b Mon Sep 17 00:00:00 2001 From: jl777 Date: Wed, 1 Nov 2017 19:41:07 +0200 Subject: [PATCH 0087/1664] Test --- iguana/exchanges/LP_tradebots.c | 2 +- iguana/exchanges/LP_utxos.c | 3 ++- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/iguana/exchanges/LP_tradebots.c b/iguana/exchanges/LP_tradebots.c index 3e0b7e93c..714b171ba 100644 --- a/iguana/exchanges/LP_tradebots.c +++ b/iguana/exchanges/LP_tradebots.c @@ -278,7 +278,7 @@ void LP_tradebot_timeslice(void *ctx,struct LP_tradebot *bot) else if ( (bot->pendrelsum+bot->relsum) >= bot->totalrelvolume-SMALLVAL || (bot->basesum+bot->pendbasesum) >= bot->totalbasevolume-SMALLVAL ) bot->pause = (uint32_t)time(NULL); printf("%s\n",jprint(LP_tradebot_json(bot),1)); - } else printf("didnt get any trade pending %s\n\n",bot->name); + } else printf("didnt get any trade pending %s %s\n\n",bot->name,retstr); free_json(pending); } else printf("%s\n",retstr); free(retstr); diff --git a/iguana/exchanges/LP_utxos.c b/iguana/exchanges/LP_utxos.c index 49c11c283..3f1ed5f40 100644 --- a/iguana/exchanges/LP_utxos.c +++ b/iguana/exchanges/LP_utxos.c @@ -247,12 +247,13 @@ struct LP_utxoinfo *LP_utxo_bestfit(char *symbol,uint64_t destsatoshis) { if ( LP_iseligible(&srcvalue,&srcvalue2,utxo->iambob,symbol,utxo->payment.txid,utxo->payment.vout,utxo->S.satoshis,utxo->fee.txid,utxo->fee.vout) == 0 ) { + printf("not elibible\n"); //if ( utxo->T.spentflag == 0 ) // utxo->T.spentflag = (uint32_t)time(NULL); continue; } bestutxo = utxo; - } //else printf("skip alice utxo %.8f vs dest %.8f\n",dstr(utxo->S.satoshis),dstr(destsatoshis)); + } else printf("skip alice utxo %.8f vs dest %.8f\n",dstr(utxo->S.satoshis),dstr(destsatoshis)); } } return(bestutxo); From eca43db50ffdb59625ae3e9c41cefd6ac9f3d4b7 Mon Sep 17 00:00:00 2001 From: jl777 Date: Wed, 1 Nov 2017 20:02:05 +0200 Subject: [PATCH 0088/1664] Test --- iguana/exchanges/LP_utxos.c | 25 +++++++++++++++++++++++-- 1 file changed, 23 insertions(+), 2 deletions(-) diff --git a/iguana/exchanges/LP_utxos.c b/iguana/exchanges/LP_utxos.c index 3f1ed5f40..546a6aba0 100644 --- a/iguana/exchanges/LP_utxos.c +++ b/iguana/exchanges/LP_utxos.c @@ -229,7 +229,7 @@ cJSON *LP_utxojson(struct LP_utxoinfo *utxo) struct LP_utxoinfo *LP_utxo_bestfit(char *symbol,uint64_t destsatoshis) { - uint64_t srcvalue,srcvalue2; struct LP_utxoinfo *utxo,*tmp,*bestutxo = 0; int32_t iambob = 0; + uint64_t srcvalue,srcvalue2; struct LP_utxoinfo *utxo,*tmp,*bestutxo = 0; int32_t bestsize,iambob = 0; if ( symbol == 0 || destsatoshis == 0 ) { printf("LP_utxo_bestfit error symbol.%p %.8f\n",symbol,dstr(destsatoshis)); @@ -243,7 +243,28 @@ struct LP_utxoinfo *LP_utxo_bestfit(char *symbol,uint64_t destsatoshis) continue; if ( LP_isavailable(utxo) > 0 && LP_ismine(utxo) > 0 ) { - if ( utxo->S.satoshis >= destsatoshis && (bestutxo == 0 || (bestutxo->S.satoshis < destsatoshis && utxo->S.satoshis >= destsatoshis) || (bestutxo->S.satoshis >= destsatoshis && utxo->S.satoshis < bestutxo->S.satoshis)) ) + bestsize = 0; + if ( bestutxo == 0 ) + { + if ( utxo->S.satoshis > destsatoshis/LP_MINCLIENTVOL ) + bestsize = 1; + } + else + { + if ( bestutxo->S.satoshis < destsatoshis ) + { + if ( utxo->S.satoshis > destsatoshis ) + bestsize = 1; + else if ( utxo->S.satoshis > bestutxo->S.satoshis ) + bestsize = 1; + } + else + { + if ( utxo->S.satoshis > destsatoshis && utxo->S.satoshis < bestutxo->S.satoshis ) + bestsize = 1; + } + } + if ( bestsize > 0 ) { if ( LP_iseligible(&srcvalue,&srcvalue2,utxo->iambob,symbol,utxo->payment.txid,utxo->payment.vout,utxo->S.satoshis,utxo->fee.txid,utxo->fee.vout) == 0 ) { From 8639d9a241b962e212e387643f4272e56f13c4ed Mon Sep 17 00:00:00 2001 From: jl777 Date: Wed, 1 Nov 2017 20:14:50 +0200 Subject: [PATCH 0089/1664] Test --- iguana/exchanges/LP_ordermatch.c | 7 ++----- 1 file changed, 2 insertions(+), 5 deletions(-) diff --git a/iguana/exchanges/LP_ordermatch.c b/iguana/exchanges/LP_ordermatch.c index 0e5bd8852..b27a942af 100644 --- a/iguana/exchanges/LP_ordermatch.c +++ b/iguana/exchanges/LP_ordermatch.c @@ -905,9 +905,8 @@ char *LP_autobuy(void *ctx,char *myipaddr,int32_t mypubsock,char *base,char *rel else maxprice *= 1.001; memset(pubkeys,0,sizeof(pubkeys)); LP_txfees(&txfee,&desttxfee,base,rel); - destsatoshis = SATOSHIDEN * relvolume + 2*desttxfee; -printf("call bestfit\n"); - if ( (autxo= LP_utxo_bestfit(rel,destsatoshis)) == 0 ) + destsatoshis = SATOSHIDEN * relvolume; + if ( (autxo= LP_utxo_bestfit(rel,destsatoshis + 2*desttxfee)) == 0 ) return(clonestr("{\"error\":\"cant find alice utxo that is big enough\"}")); if ( destsatoshis < autxo->S.satoshis ) autxo->S.satoshis = destsatoshis; @@ -916,7 +915,6 @@ printf("call bestfit\n"); printf("destsatoshis %.8f vs utxo %.8f this would have triggered an quote error -13\n",dstr(destsatoshis),dstr(autxo->payment.value)); return(clonestr("{\"error\":\"cant find alice utxo that is small enough\"}")); } - printf("update metrics\n"); LP_RTmetrics_update(base,rel); while ( 1 ) { @@ -932,7 +930,6 @@ printf("call bestfit\n"); return(clonestr("{\"error\":\"cant set ordermatch quote info\"}")); maxiters = 200; qprice = 1. / SMALLVAL; -printf("validate\n"); for (i=0; i Date: Wed, 1 Nov 2017 20:18:11 +0200 Subject: [PATCH 0090/1664] Test --- iguana/exchanges/LP_ordermatch.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/iguana/exchanges/LP_ordermatch.c b/iguana/exchanges/LP_ordermatch.c index b27a942af..219146838 100644 --- a/iguana/exchanges/LP_ordermatch.c +++ b/iguana/exchanges/LP_ordermatch.c @@ -909,7 +909,7 @@ char *LP_autobuy(void *ctx,char *myipaddr,int32_t mypubsock,char *base,char *rel if ( (autxo= LP_utxo_bestfit(rel,destsatoshis + 2*desttxfee)) == 0 ) return(clonestr("{\"error\":\"cant find alice utxo that is big enough\"}")); if ( destsatoshis < autxo->S.satoshis ) - autxo->S.satoshis = destsatoshis; + autxo->S.satoshis = destsatoshis - 2*desttxfee; if ( destsatoshis < (autxo->payment.value / LP_MINCLIENTVOL) || autxo->payment.value < desttxfee*LP_MINSIZE_TXFEEMULT ) { printf("destsatoshis %.8f vs utxo %.8f this would have triggered an quote error -13\n",dstr(destsatoshis),dstr(autxo->payment.value)); From 2c32901a7cb62b6c06bb53e19b08b765e2d7e3c6 Mon Sep 17 00:00:00 2001 From: jl777 Date: Wed, 1 Nov 2017 20:21:39 +0200 Subject: [PATCH 0091/1664] Test --- iguana/exchanges/LP_ordermatch.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/iguana/exchanges/LP_ordermatch.c b/iguana/exchanges/LP_ordermatch.c index 219146838..6da5f6f86 100644 --- a/iguana/exchanges/LP_ordermatch.c +++ b/iguana/exchanges/LP_ordermatch.c @@ -910,6 +910,8 @@ char *LP_autobuy(void *ctx,char *myipaddr,int32_t mypubsock,char *base,char *rel return(clonestr("{\"error\":\"cant find alice utxo that is big enough\"}")); if ( destsatoshis < autxo->S.satoshis ) autxo->S.satoshis = destsatoshis - 2*desttxfee; + else if ( autxo->S.satoshis < destsatoshis ) + destsatoshis = autxo->S.satoshis - 2*desttxfee; if ( destsatoshis < (autxo->payment.value / LP_MINCLIENTVOL) || autxo->payment.value < desttxfee*LP_MINSIZE_TXFEEMULT ) { printf("destsatoshis %.8f vs utxo %.8f this would have triggered an quote error -13\n",dstr(destsatoshis),dstr(autxo->payment.value)); From d4372457120ef7e81816cd976dba8239a512d5d8 Mon Sep 17 00:00:00 2001 From: jl777 Date: Wed, 1 Nov 2017 20:26:13 +0200 Subject: [PATCH 0092/1664] Test --- iguana/exchanges/LP_ordermatch.c | 16 ++++++++++++---- 1 file changed, 12 insertions(+), 4 deletions(-) diff --git a/iguana/exchanges/LP_ordermatch.c b/iguana/exchanges/LP_ordermatch.c index 6da5f6f86..67e5db04d 100644 --- a/iguana/exchanges/LP_ordermatch.c +++ b/iguana/exchanges/LP_ordermatch.c @@ -908,10 +908,18 @@ char *LP_autobuy(void *ctx,char *myipaddr,int32_t mypubsock,char *base,char *rel destsatoshis = SATOSHIDEN * relvolume; if ( (autxo= LP_utxo_bestfit(rel,destsatoshis + 2*desttxfee)) == 0 ) return(clonestr("{\"error\":\"cant find alice utxo that is big enough\"}")); - if ( destsatoshis < autxo->S.satoshis ) - autxo->S.satoshis = destsatoshis - 2*desttxfee; - else if ( autxo->S.satoshis < destsatoshis ) - destsatoshis = autxo->S.satoshis - 2*desttxfee; + if ( destsatoshis - 2*desttxfee < autxo->S.satoshis ) + { + destsatoshis -= 2*desttxfee; + autxo->S.satoshis = destsatoshis; + printf("first path dest %.8f from %.8f\n",dstr(destsatoshis),dstr(autxo->S.satoshis)); + } + else if ( autxo->S.satoshis - 2*desttxfee < destsatoshis ) + { + autxo->S.satoshis -= 2*desttxfee; + destsatoshis = autxo->S.satoshis; + printf("second path dest %.8f from %.8f\n",dstr(destsatoshis),dstr(autxo->S.satoshis)); + } if ( destsatoshis < (autxo->payment.value / LP_MINCLIENTVOL) || autxo->payment.value < desttxfee*LP_MINSIZE_TXFEEMULT ) { printf("destsatoshis %.8f vs utxo %.8f this would have triggered an quote error -13\n",dstr(destsatoshis),dstr(autxo->payment.value)); From d379440946fb9a5de6213272537b5a6aa9695c76 Mon Sep 17 00:00:00 2001 From: jl777 Date: Wed, 1 Nov 2017 21:28:19 +0200 Subject: [PATCH 0093/1664] Test --- iguana/exchanges/LP_commands.c | 4 +- iguana/exchanges/LP_include.h | 31 ++++++++- iguana/exchanges/LP_ordermatch.c | 19 +++--- iguana/exchanges/LP_portfolio.c | 2 +- iguana/exchanges/LP_remember.c | 32 ++------- iguana/exchanges/LP_signatures.c | 4 +- iguana/exchanges/LP_statemachine.c | 59 ++++++++++++++++ iguana/exchanges/LP_swap.c | 8 +-- iguana/exchanges/LP_tradebots.c | 104 +++++++++-------------------- 9 files changed, 148 insertions(+), 115 deletions(-) diff --git a/iguana/exchanges/LP_commands.c b/iguana/exchanges/LP_commands.c index 2c147dc00..0dbd7c350 100644 --- a/iguana/exchanges/LP_commands.c +++ b/iguana/exchanges/LP_commands.c @@ -300,7 +300,7 @@ bot_resume(botid)\n\ //* if ( price > SMALLVAL ) { - return(LP_autobuy(ctx,myipaddr,pubsock,base,rel,price,jdouble(argjson,"relvolume"),jint(argjson,"timeout"),jint(argjson,"duration"),jstr(argjson,"gui"),juint(argjson,"nonce"),jbits256(argjson,"pubkey"))); + return(LP_autobuy(ctx,myipaddr,pubsock,base,rel,price,jdouble(argjson,"relvolume"),jint(argjson,"timeout"),jint(argjson,"duration"),jstr(argjson,"gui"),juint(argjson,"nonce"),jbits256(argjson,"pubkey"),0)); } else return(clonestr("{\"error\":\"no price set\"}")); } else if ( strcmp(method,"sell") == 0 ) @@ -308,7 +308,7 @@ bot_resume(botid)\n\ //* 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"),juint(argjson,"nonce"),jbits256(argjson,"pubkey"))); + 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"),jbits256(argjson,"pubkey"),0)); } else return(clonestr("{\"error\":\"no price set\"}")); } } diff --git a/iguana/exchanges/LP_include.h b/iguana/exchanges/LP_include.h index 35e2aa43e..51f336cd2 100644 --- a/iguana/exchanges/LP_include.h +++ b/iguana/exchanges/LP_include.h @@ -206,6 +206,31 @@ struct basilisk_swapinfo uint8_t userdata_bobrefund[256],userdata_bobrefundlen; }; +#define BASILISK_ALICESPEND 0 +#define BASILISK_BOBSPEND 1 +#define BASILISK_BOBPAYMENT 2 +#define BASILISK_ALICEPAYMENT 3 +#define BASILISK_BOBDEPOSIT 4 +#define BASILISK_OTHERFEE 5 +#define BASILISK_MYFEE 6 +#define BASILISK_BOBREFUND 7 +#define BASILISK_BOBRECLAIM 8 +#define BASILISK_ALICERECLAIM 9 +#define BASILISK_ALICECLAIM 10 +//0, 0, 1, 1, 1, 0, 1, 1, 1, 0, 0 +char *txnames[] = { "alicespend", "bobspend", "bobpayment", "alicepayment", "bobdeposit", "otherfee", "myfee", "bobrefund", "bobreclaim", "alicereclaim", "aliceclaim" }; + +struct LP_swap_remember +{ + bits256 pubA0,pubB0,pubB1,privAm,privBn,paymentspent,Apaymentspent,depositspent,myprivs[2],txids[sizeof(txnames)/sizeof(*txnames)]; + uint64_t Atxfee,Btxfee,srcamount,destamount,aliceid; + int64_t values[sizeof(txnames)/sizeof(*txnames)]; + uint32_t tradeid,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],Sdestaddr[64],alicepaymentaddr[64],bobpaymentaddr[64],bobdepositaddr[64],alicecoin[64],bobcoin[64],*txbytes[sizeof(txnames)/sizeof(*txnames)]; +}; + struct LP_outpoint { bits256 spendtxid; uint64_t value,interest; int32_t spendvini,spendheight; char coinaddr[64]; }; struct LP_transaction @@ -291,7 +316,8 @@ struct LP_quoteinfo struct basilisk_request R; bits256 srchash,desthash,txid,txid2,desttxid,feetxid,privkey; uint64_t satoshis,txfee,destsatoshis,desttxfee,aliceid; - uint32_t timestamp,quotetime; int32_t vout,vout2,destvout,feevout,pair; + uint32_t timestamp,quotetime,tradeid; + int32_t vout,vout2,destvout,feevout,pair; char srccoin[16],coinaddr[64],destcoin[16],destaddr[64],gui[64]; }; @@ -302,7 +328,8 @@ struct basilisk_swap void *ctx; struct iguana_info bobcoin,alicecoin; struct LP_utxoinfo *utxo; struct LP_endpoint N; void (*balancingtrade)(struct basilisk_swap *swap,int32_t iambob); - int32_t subsock,pushsock,connected,aliceunconf,depositunconf,paymentunconf; uint32_t lasttime,aborted; + int32_t subsock,pushsock,connected,aliceunconf,depositunconf,paymentunconf; + uint32_t lasttime,aborted,tradeid; FILE *fp; bits256 persistent_privkey,persistent_pubkey; struct basilisk_swapinfo I; diff --git a/iguana/exchanges/LP_ordermatch.c b/iguana/exchanges/LP_ordermatch.c index 67e5db04d..a9a21da85 100644 --- a/iguana/exchanges/LP_ordermatch.c +++ b/iguana/exchanges/LP_ordermatch.c @@ -78,7 +78,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.; char str[65]; cJSON *txout; uint64_t txfee,desttxfee,srcvalue=0,srcvalue2=0,destvalue=0,destvalue2=0; - 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)); + //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 ) @@ -163,7 +163,7 @@ double LP_quote_validate(struct LP_utxoinfo *autxo,struct LP_utxoinfo *butxo,str txfee = qp->txfee; if ( desttxfee < qp->desttxfee ) desttxfee = qp->desttxfee; - printf("qprice %.8f <- %.8f/%.8f txfees.(%.8f %.8f) vs (%.8f %.8f)\n",qprice,dstr(qp->destsatoshis),dstr(qp->satoshis),dstr(qp->txfee),dstr(qp->desttxfee),dstr(txfee),dstr(desttxfee)); + //printf("qprice %.8f <- %.8f/%.8f txfees.(%.8f %.8f) vs (%.8f %.8f)\n",qprice,dstr(qp->destsatoshis),dstr(qp->satoshis),dstr(qp->txfee),dstr(qp->desttxfee),dstr(txfee),dstr(desttxfee)); if ( qp->txfee < LP_REQUIRED_TXFEE*txfee || qp->desttxfee < LP_REQUIRED_TXFEE*desttxfee ) return(-14); if ( butxo != 0 ) @@ -399,7 +399,7 @@ int32_t LP_connectstartbob(void *ctx,int32_t pubsock,struct LP_utxoinfo *utxo,cJ struct LP_quoteinfo LP_Alicequery; double LP_Alicemaxprice; uint32_t Alice_expiration; -char *LP_trade(void *ctx,char *myipaddr,int32_t mypubsock,struct LP_quoteinfo *qp,double maxprice,int32_t timeout,int32_t duration) +char *LP_trade(void *ctx,char *myipaddr,int32_t mypubsock,struct LP_quoteinfo *qp,double maxprice,int32_t timeout,int32_t duration,uint32_t botid) { 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 ) @@ -409,6 +409,7 @@ char *LP_trade(void *ctx,char *myipaddr,int32_t mypubsock,struct LP_quoteinfo *q } price = 0.; qp->aliceid = LP_aliceid_calc(qp->desttxid,qp->destvout,qp->feetxid,qp->feevout); + qp->botid = botid; LP_query(ctx,myipaddr,mypubsock,"request",qp); LP_Alicequery = *qp, LP_Alicemaxprice = maxprice, Alice_expiration = qp->timestamp + timeout; printf("LP_trade %s/%s %.8f vol %.8f\n",qp->srccoin,qp->destcoin,dstr(qp->satoshis),dstr(qp->destsatoshis)); @@ -442,6 +443,7 @@ void LP_reserved(void *ctx,char *myipaddr,int32_t mypubsock,struct LP_quoteinfo price = LP_pricecache(qp,qp->srccoin,qp->destcoin,qp->txid,qp->vout); if ( LP_pricevalid(price) > 0 && maxprice > SMALLVAL && price <= maxprice ) { + qp->botid = LP_Alicequery.botid; memset(&LP_Alicequery,0,sizeof(LP_Alicequery)); LP_Alicemaxprice = 0.; Alice_expiration = 0; @@ -457,7 +459,7 @@ char *LP_connectedalice(cJSON *argjson) // alice clonestr("{\"error\":\"cant parse quote\"}"); if ( bits256_cmp(Q.desthash,G.LP_mypub25519) != 0 ) return(clonestr("{\"result\",\"update stats\"}")); - printf("CONNECTED.(%s) numpending.%d\n",jprint(argjson,0),G.LP_pendingswaps); + printf("CONNECTED.(%s) numpending.%d botid.%u\n",jprint(argjson,0),G.LP_pendingswaps,Q.botid); /*if ( LP_alice_eligible() == 0 || LP_quotecmp(&Q,&LP_Alicequery) != 0 ) { printf("reject mismatched alice query\n"); @@ -505,6 +507,7 @@ char *LP_connectedalice(cJSON *argjson) // alice //nn_setsockopt(pairsock,NN_SOL_SOCKET,NN_RCVTIMEO,&timeout,sizeof(timeout)); 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); swap = LP_swapinit(0,0,Q.privkey,&Q.R,&Q); + swap->botid = Q.botid; swap->N.pair = pairsock; autxo->S.swap = swap; swap->utxo = autxo; @@ -827,7 +830,7 @@ struct LP_utxoinfo *LP_buyutxo(double *ordermatchpricep,int64_t *bestsatoshisp,i { if ( (bestutxo= LP_ordermatch_iter(utxos,max,ordermatchpricep,bestsatoshisp,bestdestsatoshisp,basecoin,coinaddr,asatoshis,price,txfee,desttxfee,pubp->pubkey,gui)) != 0 ) { - printf("j.%d/%d ordermatch %.8f best satoshis %.8f destsatoshis %.8f txfees (%.8f %.8f)\n",j,maxiters,price,dstr(*bestsatoshisp),dstr(*bestdestsatoshisp),dstr(txfee),dstr(desttxfee)); + //printf("j.%d/%d ordermatch %.8f best satoshis %.8f destsatoshis %.8f txfees (%.8f %.8f)\n",j,maxiters,price,dstr(*bestsatoshisp),dstr(*bestdestsatoshisp),dstr(txfee),dstr(desttxfee)); break; } asatoshis = (asatoshis / 64) * 63; @@ -858,7 +861,7 @@ 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,uint32_t nonce,bits256 destpubkey) +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,bits256 destpubkey,uint32_t botid) { uint64_t desttxfee,txfee; uint32_t lastnonce; int32_t i,maxiters,numpubs = 0; int64_t bestsatoshis=0,destsatoshis,bestdestsatoshis=0; struct iguana_info *basecoin,*relcoin; struct LP_utxoinfo *autxo,*bestutxo = 0; double qprice,ordermatchprice=0.; struct LP_quoteinfo Q; bits256 pubkeys[100]; basecoin = LP_coinfind(base); @@ -949,7 +952,7 @@ char *LP_autobuy(void *ctx,char *myipaddr,int32_t mypubsock,char *base,char *rel } if ( qprice/ordermatchprice < 1.+SMALLVAL ) { - printf("i.%d/%d qprice %.8f < ordermatchprice %.8f\n",i,maxiters,qprice,ordermatchprice); + //printf("i.%d/%d qprice %.8f < ordermatchprice %.8f\n",i,maxiters,qprice,ordermatchprice); if ( strcmp("BTC",Q.destcoin) == 0 || strcmp("BTC",Q.srccoin) == 0 ) Q.satoshis *= 0.999; else Q.satoshis *= 0.9999; @@ -962,7 +965,7 @@ char *LP_autobuy(void *ctx,char *myipaddr,int32_t mypubsock,char *base,char *rel continue; else return(clonestr("{\"error\":\"cant ordermatch to destpubkey\"}")); } - return(LP_trade(ctx,myipaddr,mypubsock,&Q,maxprice,timeout,duration)); + return(LP_trade(ctx,myipaddr,mypubsock,&Q,maxprice,timeout,duration,botid)); } return(clonestr("{\"error\":\"cant get here\"}")); } diff --git a/iguana/exchanges/LP_portfolio.c b/iguana/exchanges/LP_portfolio.c index c67cda50a..19aba3cb4 100644 --- a/iguana/exchanges/LP_portfolio.c +++ b/iguana/exchanges/LP_portfolio.c @@ -495,7 +495,7 @@ int32_t LP_portfolio_trade(void *ctx,uint32_t *requestidp,uint32_t *quoteidp,str if ( LP_utxo_bestfit(sell->symbol,SATOSHIDEN * relvolume) != 0 ) { memset(zero.bytes,0,sizeof(zero)); - if ( (retstr2= LP_autobuy(ctx,"127.0.0.1",-1,buy->symbol,sell->symbol,maxprice,relvolume,60,24*3600,gui,LP_lastnonce+1,zero)) != 0 ) + if ( (retstr2= LP_autobuy(ctx,"127.0.0.1",-1,buy->symbol,sell->symbol,maxprice,relvolume,60,24*3600,gui,LP_lastnonce+1,zero,1)) != 0 ) { if ( (retjson2= cJSON_Parse(retstr2)) != 0 ) { diff --git a/iguana/exchanges/LP_remember.c b/iguana/exchanges/LP_remember.c index 953910c42..d4eeeb6e1 100644 --- a/iguana/exchanges/LP_remember.c +++ b/iguana/exchanges/LP_remember.c @@ -93,7 +93,7 @@ void basilisk_dontforget(struct basilisk_swap *swap,struct basilisk_rawtx *rawtx sprintf(fname,"%s/SWAPS/%u-%u",GLOBAL_DBDIR,swap->I.req.requestid,swap->I.req.quoteid), OS_compatible_path(fname); if ( (fp= fopen(fname,"wb")) != 0 ) { - fprintf(fp,"{\"aliceid\":\"%llu\",\"src\":\"%s\",\"srcamount\":%.8f,\"dest\":\"%s\",\"destamount\":%.8f,\"requestid\":%u,\"quoteid\":%u,\"iambob\":%d,\"state\":%u,\"otherstate\":%u,\"expiration\":%u,\"dlocktime\":%u,\"plocktime\":%u,\"Atxfee\":%llu,\"Btxfee\":%llu",(long long)swap->aliceid,swap->I.req.src,dstr(swap->I.req.srcamount),swap->I.req.dest,dstr(swap->I.req.destamount),swap->I.req.requestid,swap->I.req.quoteid,swap->I.iambob,swap->I.statebits,swap->I.otherstatebits,swap->I.expiration,swap->bobdeposit.I.locktime,swap->bobpayment.I.locktime,(long long)swap->I.Atxfee,(long long)swap->I.Btxfee); + fprintf(fp,"{\"tradeid\":%u,\"aliceid\":\"%llu\",\"src\":\"%s\",\"srcamount\":%.8f,\"dest\":\"%s\",\"destamount\":%.8f,\"requestid\":%u,\"quoteid\":%u,\"iambob\":%d,\"state\":%u,\"otherstate\":%u,\"expiration\":%u,\"dlocktime\":%u,\"plocktime\":%u,\"Atxfee\":%llu,\"Btxfee\":%llu",swap->tradeid,(long long)swap->aliceid,swap->I.req.src,dstr(swap->I.req.srcamount),swap->I.req.dest,dstr(swap->I.req.destamount),swap->I.req.requestid,swap->I.req.quoteid,swap->I.iambob,swap->I.statebits,swap->I.otherstatebits,swap->I.expiration,swap->bobdeposit.I.locktime,swap->bobpayment.I.locktime,(long long)swap->I.Atxfee,(long long)swap->I.Btxfee); if ( memcmp(zeroes,swap->I.secretAm,20) != 0 ) { init_hexbytes_noT(secretAmstr,swap->I.secretAm,20); @@ -303,20 +303,6 @@ bits256 basilisk_swap_spendupdate(int32_t iambob,char *symbol,char *spentaddr,in return(spendtxid); } -#define BASILISK_ALICESPEND 0 -#define BASILISK_BOBSPEND 1 -#define BASILISK_BOBPAYMENT 2 -#define BASILISK_ALICEPAYMENT 3 -#define BASILISK_BOBDEPOSIT 4 -#define BASILISK_OTHERFEE 5 -#define BASILISK_MYFEE 6 -#define BASILISK_BOBREFUND 7 -#define BASILISK_BOBRECLAIM 8 -#define BASILISK_ALICERECLAIM 9 -#define BASILISK_ALICECLAIM 10 -//0, 0, 1, 1, 1, 0, 1, 1, 1, 0, 0 -char *txnames[] = { "alicespend", "bobspend", "bobpayment", "alicepayment", "bobdeposit", "otherfee", "myfee", "bobrefund", "bobreclaim", "alicereclaim", "aliceclaim" }; - int32_t basilisk_isbobcoin(int32_t iambob,int32_t ind) { switch ( ind ) @@ -460,21 +446,11 @@ void LP_totals_update(int32_t iambob,char *alicecoin,char *bobcoin,int64_t *KMDt } } -struct LP_swap_remember -{ - bits256 pubA0,pubB0,pubB1,privAm,privBn,paymentspent,Apaymentspent,depositspent,myprivs[2],txids[sizeof(txnames)/sizeof(*txnames)]; - uint64_t Atxfee,Btxfee,srcamount,destamount,aliceid; - int64_t values[sizeof(txnames)/sizeof(*txnames)]; - 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],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) { cJSON *item,*array; int32_t i; item = cJSON_CreateObject(); + jaddnum(item,"tradeid",rswap->tradeid); jaddnum(item,"requestid",rswap->requestid); jaddnum(item,"quoteid",rswap->quoteid); jaddnum(item,"iambob",rswap->iambob); @@ -523,6 +499,7 @@ int32_t LP_rswap_init(struct LP_swap_remember *rswap,uint32_t requestid,uint32_t if ( (item= cJSON_Parse(fstr)) != 0 ) { rswap->iambob = jint(item,"iambob"); + rswap->tradeid = juint(item,"tradeid"); rswap->aliceid = j64bits(item,"aliceid"); if ( (secretstr= jstr(item,"secretAm")) != 0 && strlen(secretstr) == 40 ) decode_hex(rswap->secretAm,20,secretstr); @@ -1132,6 +1109,8 @@ cJSON *basilisk_remember(int64_t *KMDtotals,int64_t *BTCtotals,uint32_t requesti char fname[1024],*itemstr; FILE *fp; LP_numfinished++; printf("SWAP %u-%u finished LP_numfinished.%d !\n",requestid,quoteid,LP_numfinished); + if ( rswap.tradeid != 0 ) + LP_tradebot_finished(rswap.tradeid); sprintf(fname,"%s/SWAPS/%u-%u.finished",GLOBAL_DBDIR,rswap.requestid,rswap.quoteid), OS_compatible_path(fname); if ( (fp= fopen(fname,"wb")) != 0 ) { @@ -1308,6 +1287,7 @@ char *LP_recent_swaps(int32_t limit) item = cJSON_CreateObject(); jaddnum(item,"expiration",Alice_expiration); jaddnum(item,"timeleft",Alice_expiration-time(NULL)); + jaddnum(item,"tradeid",LP_Alicequery.tradeid); jaddnum(item,"requestid",LP_Alicequery.R.requestid); jaddnum(item,"quoteid",LP_Alicequery.R.quoteid); jaddstr(item,"bob",LP_Alicequery.srccoin); diff --git a/iguana/exchanges/LP_signatures.c b/iguana/exchanges/LP_signatures.c index 960e36127..a53f3b28f 100644 --- a/iguana/exchanges/LP_signatures.c +++ b/iguana/exchanges/LP_signatures.c @@ -44,6 +44,7 @@ cJSON *LP_quotejson(struct LP_quoteinfo *qp) double price; cJSON *retjson = cJSON_CreateObject(); jaddstr(retjson,"gui",qp->gui[0] != 0 ? qp->gui : LP_gui); jadd64bits(retjson,"aliceid",qp->aliceid); + jaddnum(retjson,"botid",qp->botid); jaddstr(retjson,"base",qp->srccoin); jaddstr(retjson,"rel",qp->destcoin); if ( qp->coinaddr[0] != 0 ) @@ -109,6 +110,7 @@ int32_t LP_quoteparse(struct LP_quoteinfo *qp,cJSON *argjson) safecopy(qp->destcoin,jstr(argjson,"rel"),sizeof(qp->destcoin)); safecopy(qp->destaddr,jstr(argjson,"destaddr"),sizeof(qp->destaddr)); qp->aliceid = j64bits(argjson,"aliceid"); + qp->botid = juint(argjson,"botid"); qp->timestamp = juint(argjson,"timestamp"); qp->quotetime = juint(argjson,"quotetime"); qp->txid = jbits256(argjson,"txid"); @@ -146,7 +148,7 @@ void LP_txfees(uint64_t *txfeep,uint64_t *desttxfeep,char *base,char *rel) { *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)); + //printf("LP_txfees(%.8f %.8f)\n",dstr(*txfeep),dstr(*desttxfeep)); } int32_t LP_quoteinfoinit(struct LP_quoteinfo *qp,struct LP_utxoinfo *utxo,char *destcoin,double price,uint64_t satoshis,uint64_t destsatoshis) diff --git a/iguana/exchanges/LP_statemachine.c b/iguana/exchanges/LP_statemachine.c index a3b824d36..f209a0737 100644 --- a/iguana/exchanges/LP_statemachine.c +++ b/iguana/exchanges/LP_statemachine.c @@ -1613,6 +1613,65 @@ void LP_address_monitor(struct LP_pubkeyinfo *pubp) return(LP_autotrade(ctx,myipaddr,pubsock,base,rel,price,jdouble(argjson,"relvolume"),jint(argjson,"timeout"),jint(argjson,"duration"))); } else return(clonestr("{\"error\":\"no price set\"}")); }*/ +if ( flag != 0 ) +{ + // need to find the requestid/quoteid for aliceid + if ( (retstr= basilisk_swapentries(bot->base,bot->rel,0)) != 0 ) + { + if ( (retjson= cJSON_Parse(retstr)) != 0 ) + { + if ( (n= cJSON_GetArraySize(retjson)) != 0 ) + { + for (flag=j=0; jnumtrades; i++) + { + if ( (tp= bot->trades[i]) != 0 && tp->finished == 0 && tp->requestid == 0 && tp->quoteid == 0 ) + { + if ( tp->aliceid == aliceid ) + { + tp->requestid = juint(item,"requestid"); + tp->quoteid = juint(item,"quoteid"); + printf("found aliceid.%llx to set requestid.%u quoteid.%u\n",(long long)aliceid,tp->requestid,tp->quoteid); + flag = 1; + break; + } + } + } + } + } + free_json(retjson); + } + free(retstr); + } +} +// check for finished pending swap +for (i=0; inumtrades; i++) +{ + if ( (tp= bot->trades[i]) != 0 && tp->finished == 0 && tp->requestid != 0 && tp->quoteid != 0 ) + { + if ( (retstr= basilisk_swapentry(tp->requestid,tp->quoteid)) != 0 ) + { + if ( (retjson= cJSON_Parse(retstr)) != 0 ) + { + if ( (status= jstr(retjson,"status")) != 0 && strcmp(status,"finished") == 0 ) + { + bot->pendbasesum -= tp->basevol, bot->basesum += tp->basevol; + bot->pendrelsum -= tp->relvol, bot->relsum += tp->relvol; + bot->numpending--, bot->completed++; + printf("detected completion aliceid.%llx r.%u q.%u\n",(long long)tp->aliceid,tp->requestid,tp->quoteid); + tp->finished = (uint32_t)time(NULL); + } + free_json(retjson); + } + free(retstr); + } + } +} +} + int32_t LP_utxopurge(int32_t allutxos) { char str[65]; struct LP_utxoinfo *utxo,*tmp; int32_t iambob,n = 0; diff --git a/iguana/exchanges/LP_swap.c b/iguana/exchanges/LP_swap.c index 72860cc80..267646c6d 100644 --- a/iguana/exchanges/LP_swap.c +++ b/iguana/exchanges/LP_swap.c @@ -785,7 +785,7 @@ void LP_bobloop(void *_swap) 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,m,swap->alicecoin.symbol,bits256_str(str,swap->alicepayment.I.signedtxid)); + char str[65];printf("%d wait for alicepayment %s numconfs.%d %s %s\n",n,swap->alicepayment.I.destaddr,m,swap->alicecoin.symbol,bits256_str(str,swap->alicepayment.I.signedtxid)); sleep(10); } if ( LP_swapdata_rawtxsend(swap->N.pair,swap,0x8000,data,maxlen,&swap->bobpayment,0x4000,0) == 0 ) @@ -842,7 +842,7 @@ void LP_aliceloop(void *_swap) 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,m,swap->alicecoin.symbol,bits256_str(str,swap->alicepayment.I.signedtxid)); + char str[65];printf("%d wait for alicepayment %s numconfs.%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; @@ -852,14 +852,14 @@ void LP_aliceloop(void *_swap) { while ( (n= LP_numconfirms(swap->bobcoin.symbol,swap->bobpayment.I.destaddr,swap->bobpayment.I.signedtxid,0,1)) < swap->I.bobconfirms ) { - 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)); + char str[65];printf("%d wait for bobpayment %s numconfs.%d %s %s\n",n,swap->bobpayment.I.destaddr,swap->I.bobconfirms,swap->bobcoin.symbol,bits256_str(str,swap->bobpayment.I.signedtxid)); sleep(10); } /*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)); + char str[65];printf("%d wait for alicespend %s numconfs.%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 ) diff --git a/iguana/exchanges/LP_tradebots.c b/iguana/exchanges/LP_tradebots.c index 714b171ba..fa1b881b9 100644 --- a/iguana/exchanges/LP_tradebots.c +++ b/iguana/exchanges/LP_tradebots.c @@ -26,7 +26,7 @@ struct LP_tradebot_trade double maxprice,totalrelvolume,basevol,relvol; uint64_t aliceid; int32_t dispdir; - uint32_t started,finished,requestid,quoteid; + uint32_t started,finished,requestid,quoteid,tradeid; char base[32],rel[32]; }; @@ -233,10 +233,11 @@ void LP_tradebotadd(struct LP_tradebot *bot) portable_mutex_unlock(&LP_tradebotsmutex); } -struct LP_tradebot_trade *LP_tradebot_pending(struct LP_tradebot *bot,cJSON *pending) +struct LP_tradebot_trade *LP_tradebot_pending(struct LP_tradebot *bot,cJSON *pending,uint32_t tradeid) { struct LP_tradebot_trade *tp; tp = calloc(1,sizeof(*tp)); + tp->tradeid = tradeid; tp->maxprice = bot->maxprice; tp->totalrelvolume = bot->totalrelvolume; tp->started = (uint32_t)time(NULL); @@ -254,7 +255,7 @@ struct LP_tradebot_trade *LP_tradebot_pending(struct LP_tradebot *bot,cJSON *pen void LP_tradebot_timeslice(void *ctx,struct LP_tradebot *bot) { - double remaining; bits256 destpubkey; char *retstr,*liststr; cJSON *retjson,*pending; + double remaining; uint32_t tradeid; bits256 destpubkey; char *retstr,*liststr; cJSON *retjson,*pending; memset(destpubkey.bytes,0,sizeof(destpubkey)); if ( bot->dead == 0 && bot->pause == 0 && bot->numtrades < sizeof(bot->trades)/sizeof(*bot->trades) ) { @@ -266,13 +267,14 @@ void LP_tradebot_timeslice(void *ctx,struct LP_tradebot *bot) { remaining = bot->totalrelvolume - (bot->relsum + bot->pendrelsum); printf("try autobuy %s/%s remaining %.8f maxprice %.8f\n",bot->base,bot->rel,remaining,bot->maxprice); - if ( (retstr= LP_autobuy(ctx,LP_myipaddr,LP_mypubsock,bot->base,bot->rel,bot->maxprice,remaining,0,0,G.gui,0,destpubkey)) != 0 ) + tradeid = rand(); + if ( (retstr= LP_autobuy(ctx,LP_myipaddr,LP_mypubsock,bot->base,bot->rel,bot->maxprice,remaining,0,0,G.gui,0,destpubkey,tradeid)) != 0 ) { if ( (pending= cJSON_Parse(retstr)) != 0 ) { if ( jobj(pending,"pending") != 0 ) { - bot->trades[bot->numtrades++] = LP_tradebot_pending(bot,pending); + bot->trades[bot->numtrades++] = LP_tradebot_pending(bot,pending,tradeid); if ( bot->relsum >= bot->totalrelvolume-SMALLVAL || bot->basesum >= bot->totalbasevolume-SMALLVAL ) bot->dead = (uint32_t)time(NULL); else if ( (bot->pendrelsum+bot->relsum) >= bot->totalrelvolume-SMALLVAL || (bot->basesum+bot->pendbasesum) >= bot->totalbasevolume-SMALLVAL ) @@ -293,19 +295,37 @@ void LP_tradebot_timeslice(void *ctx,struct LP_tradebot *bot) bot->pause = (uint32_t)time(NULL); } +void LP_tradebots_finished(uint32_t tradeid) +{ + struct LP_tradebot *bot,*tmp; int32_t i; struct LP_tradebot_trade *tp; + DL_FOREACH_SAFE(LP_tradebots,bot,tmp) + { + for (i=0; inumtrades; i++) + { + if ( (tp= bot->trades[i]) != 0 && tp->finished == 0 && tp->tradeid == tradeid ) + { + bot->pendbasesum -= tp->basevol, bot->basesum += tp->basevol; + bot->pendrelsum -= tp->relvol, bot->relsum += tp->relvol; + bot->numpending--, bot->completed++; + printf("detected completion aliceid.%llx r.%u q.%u\n",(long long)tp->aliceid,tp->requestid,tp->quoteid); + tp->finished = (uint32_t)time(NULL); + break; + } + } + } +} + void LP_tradebot_timeslices(void *ctx) { - struct LP_tradebot_trade *tp; struct LP_tradebot *bot,*tmp; char *retstr,*status; cJSON *retjson,*item; uint64_t aliceid; int32_t i,j,n,flag,lastnumfinished = 0; + struct LP_tradebot_trade *tp; struct LP_tradebot *bot,*tmp; int32_t i,lastnumfinished = 0; while ( 1 ) { DL_FOREACH_SAFE(LP_tradebots,bot,tmp) { - portable_mutex_lock(&LP_tradebotsmutex); - LP_tradebot_timeslice(ctx,bot); if ( bot->numpending > 0 && LP_numfinished > lastnumfinished ) { // expire pending trades and see if any still need their requestid/quoteid - for (i=flag=0; inumtrades; i++) + for (i=0; inumtrades; i++) { if ( (tp= bot->trades[i]) != 0 && tp->finished == 0 ) { @@ -317,73 +337,15 @@ void LP_tradebot_timeslices(void *ctx) tp->finished = (uint32_t)time(NULL); printf("%s trade.%d of %d expired\n",bot->name,i,bot->numtrades); } - else if ( tp->requestid == 0 && tp->quoteid == 0 ) - flag = 1; - } - } - if ( flag != 0 ) - { - // need to find the requestid/quoteid for aliceid - if ( (retstr= basilisk_swapentries(bot->base,bot->rel,0)) != 0 ) - { - if ( (retjson= cJSON_Parse(retstr)) != 0 ) - { - if ( (n= cJSON_GetArraySize(retjson)) != 0 ) - { - for (flag=j=0; jnumtrades; i++) - { - if ( (tp= bot->trades[i]) != 0 && tp->finished == 0 && tp->requestid == 0 && tp->quoteid == 0 ) - { - if ( tp->aliceid == aliceid ) - { - tp->requestid = juint(item,"requestid"); - tp->quoteid = juint(item,"quoteid"); - printf("found aliceid.%llx to set requestid.%u quoteid.%u\n",(long long)aliceid,tp->requestid,tp->quoteid); - flag = 1; - break; - } - } - } - } - } - free_json(retjson); - } - free(retstr); - } - } - // check for finished pending swap - for (i=0; inumtrades; i++) - { - if ( (tp= bot->trades[i]) != 0 && tp->finished == 0 && tp->requestid != 0 && tp->quoteid != 0 ) - { - if ( (retstr= basilisk_swapentry(tp->requestid,tp->quoteid)) != 0 ) - { - if ( (retjson= cJSON_Parse(retstr)) != 0 ) - { - if ( (status= jstr(retjson,"status")) != 0 && strcmp(status,"finished") == 0 ) - { - bot->pendbasesum -= tp->basevol, bot->basesum += tp->basevol; - bot->pendrelsum -= tp->relvol, bot->relsum += tp->relvol; - bot->numpending--, bot->completed++; - printf("detected completion aliceid.%llx r.%u q.%u\n",(long long)tp->aliceid,tp->requestid,tp->quoteid); - tp->finished = (uint32_t)time(NULL); - } - free_json(retjson); - } - free(retstr); - } } } + printf("%s\n",jprint(LP_tradebot_json(bot),1)); } - portable_mutex_unlock(&LP_tradebotsmutex); - sleep(1); + else if ( bot->numpending == 0 ) + LP_tradebot_timeslice(ctx,bot); } lastnumfinished = LP_numfinished; - sleep(10); + sleep(60); } } From 4fb6ba1178d4e5921c0ee445bf5133efc80f709b Mon Sep 17 00:00:00 2001 From: jl777 Date: Wed, 1 Nov 2017 21:30:11 +0200 Subject: [PATCH 0094/1664] Test --- iguana/exchanges/LP_ordermatch.c | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/iguana/exchanges/LP_ordermatch.c b/iguana/exchanges/LP_ordermatch.c index a9a21da85..197824077 100644 --- a/iguana/exchanges/LP_ordermatch.c +++ b/iguana/exchanges/LP_ordermatch.c @@ -399,7 +399,7 @@ int32_t LP_connectstartbob(void *ctx,int32_t pubsock,struct LP_utxoinfo *utxo,cJ struct LP_quoteinfo LP_Alicequery; double LP_Alicemaxprice; uint32_t Alice_expiration; -char *LP_trade(void *ctx,char *myipaddr,int32_t mypubsock,struct LP_quoteinfo *qp,double maxprice,int32_t timeout,int32_t duration,uint32_t botid) +char *LP_trade(void *ctx,char *myipaddr,int32_t mypubsock,struct LP_quoteinfo *qp,double maxprice,int32_t timeout,int32_t duration,uint32_t tradeid) { 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 ) @@ -409,7 +409,7 @@ char *LP_trade(void *ctx,char *myipaddr,int32_t mypubsock,struct LP_quoteinfo *q } price = 0.; qp->aliceid = LP_aliceid_calc(qp->desttxid,qp->destvout,qp->feetxid,qp->feevout); - qp->botid = botid; + qp->tradeid = tradeid; LP_query(ctx,myipaddr,mypubsock,"request",qp); LP_Alicequery = *qp, LP_Alicemaxprice = maxprice, Alice_expiration = qp->timestamp + timeout; printf("LP_trade %s/%s %.8f vol %.8f\n",qp->srccoin,qp->destcoin,dstr(qp->satoshis),dstr(qp->destsatoshis)); @@ -443,7 +443,7 @@ void LP_reserved(void *ctx,char *myipaddr,int32_t mypubsock,struct LP_quoteinfo price = LP_pricecache(qp,qp->srccoin,qp->destcoin,qp->txid,qp->vout); if ( LP_pricevalid(price) > 0 && maxprice > SMALLVAL && price <= maxprice ) { - qp->botid = LP_Alicequery.botid; + qp->tradeid = LP_Alicequery.tradeid; memset(&LP_Alicequery,0,sizeof(LP_Alicequery)); LP_Alicemaxprice = 0.; Alice_expiration = 0; @@ -459,7 +459,7 @@ char *LP_connectedalice(cJSON *argjson) // alice clonestr("{\"error\":\"cant parse quote\"}"); if ( bits256_cmp(Q.desthash,G.LP_mypub25519) != 0 ) return(clonestr("{\"result\",\"update stats\"}")); - printf("CONNECTED.(%s) numpending.%d botid.%u\n",jprint(argjson,0),G.LP_pendingswaps,Q.botid); + printf("CONNECTED.(%s) numpending.%d tradeid.%u\n",jprint(argjson,0),G.LP_pendingswaps,Q.tradeid); /*if ( LP_alice_eligible() == 0 || LP_quotecmp(&Q,&LP_Alicequery) != 0 ) { printf("reject mismatched alice query\n"); @@ -507,7 +507,7 @@ char *LP_connectedalice(cJSON *argjson) // alice //nn_setsockopt(pairsock,NN_SOL_SOCKET,NN_RCVTIMEO,&timeout,sizeof(timeout)); 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); swap = LP_swapinit(0,0,Q.privkey,&Q.R,&Q); - swap->botid = Q.botid; + swap->tradeid = Q.tradeid; swap->N.pair = pairsock; autxo->S.swap = swap; swap->utxo = autxo; @@ -861,7 +861,7 @@ 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,uint32_t nonce,bits256 destpubkey,uint32_t botid) +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,bits256 destpubkey,uint32_t tradeid) { uint64_t desttxfee,txfee; uint32_t lastnonce; int32_t i,maxiters,numpubs = 0; int64_t bestsatoshis=0,destsatoshis,bestdestsatoshis=0; struct iguana_info *basecoin,*relcoin; struct LP_utxoinfo *autxo,*bestutxo = 0; double qprice,ordermatchprice=0.; struct LP_quoteinfo Q; bits256 pubkeys[100]; basecoin = LP_coinfind(base); @@ -965,7 +965,7 @@ char *LP_autobuy(void *ctx,char *myipaddr,int32_t mypubsock,char *base,char *rel continue; else return(clonestr("{\"error\":\"cant ordermatch to destpubkey\"}")); } - return(LP_trade(ctx,myipaddr,mypubsock,&Q,maxprice,timeout,duration,botid)); + return(LP_trade(ctx,myipaddr,mypubsock,&Q,maxprice,timeout,duration,tradeid)); } return(clonestr("{\"error\":\"cant get here\"}")); } From 7439b00ca56ada1a5dd8651c7be4408daa4a8eab Mon Sep 17 00:00:00 2001 From: jl777 Date: Wed, 1 Nov 2017 21:32:27 +0200 Subject: [PATCH 0095/1664] Test --- iguana/exchanges/LP_include.h | 1 + iguana/exchanges/LP_signatures.c | 4 ++-- iguana/exchanges/LP_tradebots.c | 2 +- 3 files changed, 4 insertions(+), 3 deletions(-) diff --git a/iguana/exchanges/LP_include.h b/iguana/exchanges/LP_include.h index 51f336cd2..a431eeb72 100644 --- a/iguana/exchanges/LP_include.h +++ b/iguana/exchanges/LP_include.h @@ -389,6 +389,7 @@ 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); +void LP_tradebot_finished(uint32_t tradeid); 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); diff --git a/iguana/exchanges/LP_signatures.c b/iguana/exchanges/LP_signatures.c index a53f3b28f..7ce2350e2 100644 --- a/iguana/exchanges/LP_signatures.c +++ b/iguana/exchanges/LP_signatures.c @@ -44,7 +44,7 @@ cJSON *LP_quotejson(struct LP_quoteinfo *qp) double price; cJSON *retjson = cJSON_CreateObject(); jaddstr(retjson,"gui",qp->gui[0] != 0 ? qp->gui : LP_gui); jadd64bits(retjson,"aliceid",qp->aliceid); - jaddnum(retjson,"botid",qp->botid); + jaddnum(retjson,"tradeid",qp->tradeid); jaddstr(retjson,"base",qp->srccoin); jaddstr(retjson,"rel",qp->destcoin); if ( qp->coinaddr[0] != 0 ) @@ -110,7 +110,7 @@ int32_t LP_quoteparse(struct LP_quoteinfo *qp,cJSON *argjson) safecopy(qp->destcoin,jstr(argjson,"rel"),sizeof(qp->destcoin)); safecopy(qp->destaddr,jstr(argjson,"destaddr"),sizeof(qp->destaddr)); qp->aliceid = j64bits(argjson,"aliceid"); - qp->botid = juint(argjson,"botid"); + qp->tradeid = juint(argjson,"tradeid"); qp->timestamp = juint(argjson,"timestamp"); qp->quotetime = juint(argjson,"quotetime"); qp->txid = jbits256(argjson,"txid"); diff --git a/iguana/exchanges/LP_tradebots.c b/iguana/exchanges/LP_tradebots.c index fa1b881b9..42c0b2434 100644 --- a/iguana/exchanges/LP_tradebots.c +++ b/iguana/exchanges/LP_tradebots.c @@ -295,7 +295,7 @@ void LP_tradebot_timeslice(void *ctx,struct LP_tradebot *bot) bot->pause = (uint32_t)time(NULL); } -void LP_tradebots_finished(uint32_t tradeid) +void LP_tradebot_finished(uint32_t tradeid) { struct LP_tradebot *bot,*tmp; int32_t i; struct LP_tradebot_trade *tp; DL_FOREACH_SAFE(LP_tradebots,bot,tmp) From 86ea52d2ebb7f34db42208598e10e72fdedb21a4 Mon Sep 17 00:00:00 2001 From: jl777 Date: Wed, 1 Nov 2017 21:49:10 +0200 Subject: [PATCH 0096/1664] Test --- iguana/exchanges/LP_include.h | 2 +- iguana/exchanges/LP_remember.c | 2 +- iguana/exchanges/LP_tradebots.c | 15 ++++++++++----- 3 files changed, 12 insertions(+), 7 deletions(-) diff --git a/iguana/exchanges/LP_include.h b/iguana/exchanges/LP_include.h index a431eeb72..3000b44b3 100644 --- a/iguana/exchanges/LP_include.h +++ b/iguana/exchanges/LP_include.h @@ -389,7 +389,7 @@ 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); -void LP_tradebot_finished(uint32_t tradeid); +void LP_tradebot_finished(uint32_t tradeid,uint32_t requestid,uint32_t quoteid); 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); diff --git a/iguana/exchanges/LP_remember.c b/iguana/exchanges/LP_remember.c index d4eeeb6e1..e27a13aab 100644 --- a/iguana/exchanges/LP_remember.c +++ b/iguana/exchanges/LP_remember.c @@ -1110,7 +1110,7 @@ cJSON *basilisk_remember(int64_t *KMDtotals,int64_t *BTCtotals,uint32_t requesti LP_numfinished++; printf("SWAP %u-%u finished LP_numfinished.%d !\n",requestid,quoteid,LP_numfinished); if ( rswap.tradeid != 0 ) - LP_tradebot_finished(rswap.tradeid); + LP_tradebot_finished(rswap.tradeid,rswap.requestid,rswap.quoteid); sprintf(fname,"%s/SWAPS/%u-%u.finished",GLOBAL_DBDIR,rswap.requestid,rswap.quoteid), OS_compatible_path(fname); if ( (fp= fopen(fname,"wb")) != 0 ) { diff --git a/iguana/exchanges/LP_tradebots.c b/iguana/exchanges/LP_tradebots.c index 42c0b2434..33a25d890 100644 --- a/iguana/exchanges/LP_tradebots.c +++ b/iguana/exchanges/LP_tradebots.c @@ -100,8 +100,11 @@ cJSON *LP_tradebot_tradejson(struct LP_tradebot_trade *tp,int32_t dispflag) double price,basevol; cJSON *item = cJSON_CreateObject(); if ( tp == 0 ) return(cJSON_Parse("{}")); - jaddnum(item,"requestid",tp->requestid); - jaddnum(item,"quoteid",tp->quoteid); + if ( tp->requestid != 0 && tp->quoteid != 0 ) + { + jaddnum(item,"requestid",tp->requestid); + jaddnum(item,"quoteid",tp->quoteid); + } else jaddnum(item,"tradeid",tp->tradeid); if ( tp->basevol > SMALLVAL && tp->relvol > SMALLVAL ) { if ( dispflag > 0 ) @@ -295,7 +298,7 @@ void LP_tradebot_timeslice(void *ctx,struct LP_tradebot *bot) bot->pause = (uint32_t)time(NULL); } -void LP_tradebot_finished(uint32_t tradeid) +void LP_tradebot_finished(uint32_t tradeid,uint32_t requestid,uint32_t quoteid) { struct LP_tradebot *bot,*tmp; int32_t i; struct LP_tradebot_trade *tp; DL_FOREACH_SAFE(LP_tradebots,bot,tmp) @@ -304,11 +307,14 @@ void LP_tradebot_finished(uint32_t tradeid) { if ( (tp= bot->trades[i]) != 0 && tp->finished == 0 && tp->tradeid == tradeid ) { + tp->requestid = requestid; + tp->quoteid = quoteid; bot->pendbasesum -= tp->basevol, bot->basesum += tp->basevol; bot->pendrelsum -= tp->relvol, bot->relsum += tp->relvol; bot->numpending--, bot->completed++; - printf("detected completion aliceid.%llx r.%u q.%u\n",(long long)tp->aliceid,tp->requestid,tp->quoteid); + printf("bot.%u detected completion tradeid.%u aliceid.%llx r.%u q.%u\n",bot->id,tp->tradeid,(long long)tp->aliceid,tp->requestid,tp->quoteid); tp->finished = (uint32_t)time(NULL); + printf("%s\n",jprint(LP_tradebot_json(bot),1)); break; } } @@ -373,7 +379,6 @@ char *LP_tradebot_buy(int32_t dispdir,char *base,char *rel,double maxprice,doubl for (i=0; i Date: Wed, 1 Nov 2017 22:44:35 +0200 Subject: [PATCH 0097/1664] Test --- iguana/exchanges/LP_tradebots.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/iguana/exchanges/LP_tradebots.c b/iguana/exchanges/LP_tradebots.c index 33a25d890..92758f6d3 100644 --- a/iguana/exchanges/LP_tradebots.c +++ b/iguana/exchanges/LP_tradebots.c @@ -258,7 +258,7 @@ struct LP_tradebot_trade *LP_tradebot_pending(struct LP_tradebot *bot,cJSON *pen void LP_tradebot_timeslice(void *ctx,struct LP_tradebot *bot) { - double remaining; uint32_t tradeid; bits256 destpubkey; char *retstr,*liststr; cJSON *retjson,*pending; + double remaining; uint32_t tradeid; bits256 destpubkey; char *retstr,*liststr; cJSON *retjson,*retjson2,*pending; memset(destpubkey.bytes,0,sizeof(destpubkey)); if ( bot->dead == 0 && bot->pause == 0 && bot->numtrades < sizeof(bot->trades)/sizeof(*bot->trades) ) { @@ -273,9 +273,9 @@ void LP_tradebot_timeslice(void *ctx,struct LP_tradebot *bot) tradeid = rand(); if ( (retstr= LP_autobuy(ctx,LP_myipaddr,LP_mypubsock,bot->base,bot->rel,bot->maxprice,remaining,0,0,G.gui,0,destpubkey,tradeid)) != 0 ) { - if ( (pending= cJSON_Parse(retstr)) != 0 ) + if ( (retjson2= cJSON_Parse(retstr)) != 0 ) { - if ( jobj(pending,"pending") != 0 ) + if ( (pending= jobj(retjson2,"pending")) != 0 && juint(pending,"tradeid") == tradeid ) { bot->trades[bot->numtrades++] = LP_tradebot_pending(bot,pending,tradeid); if ( bot->relsum >= bot->totalrelvolume-SMALLVAL || bot->basesum >= bot->totalbasevolume-SMALLVAL ) @@ -284,7 +284,7 @@ void LP_tradebot_timeslice(void *ctx,struct LP_tradebot *bot) bot->pause = (uint32_t)time(NULL); printf("%s\n",jprint(LP_tradebot_json(bot),1)); } else printf("didnt get any trade pending %s %s\n\n",bot->name,retstr); - free_json(pending); + free_json(retjson2); } else printf("%s\n",retstr); free(retstr); } From 6b83f8f8ee44e4f4ee1ed01d78102d0506f7b0b0 Mon Sep 17 00:00:00 2001 From: jl777 Date: Wed, 1 Nov 2017 22:46:50 +0200 Subject: [PATCH 0098/1664] Test --- iguana/exchanges/LP_tradebots.c | 1 + 1 file changed, 1 insertion(+) diff --git a/iguana/exchanges/LP_tradebots.c b/iguana/exchanges/LP_tradebots.c index 92758f6d3..622ed8332 100644 --- a/iguana/exchanges/LP_tradebots.c +++ b/iguana/exchanges/LP_tradebots.c @@ -250,6 +250,7 @@ struct LP_tradebot_trade *LP_tradebot_pending(struct LP_tradebot *bot,cJSON *pen tp->aliceid = j64bits(pending,"aliceid"); tp->basevol = jdouble(pending,"basevalue"); tp->relvol = jdouble(pending,"relvalue"); + printf("tradebot pending basevol %.8f relvol %.8f\n",tp->basevol,tp->relvol); bot->pendrelsum += tp->relvol; bot->pendbasesum += tp->basevol; bot->numpending++; From 55785ee868404a54af48f24662a757febd67c7c4 Mon Sep 17 00:00:00 2001 From: jl777 Date: Wed, 1 Nov 2017 22:49:46 +0200 Subject: [PATCH 0099/1664] Test --- iguana/exchanges/LP_tradebots.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/iguana/exchanges/LP_tradebots.c b/iguana/exchanges/LP_tradebots.c index 622ed8332..1a9329d63 100644 --- a/iguana/exchanges/LP_tradebots.c +++ b/iguana/exchanges/LP_tradebots.c @@ -324,11 +324,13 @@ void LP_tradebot_finished(uint32_t tradeid,uint32_t requestid,uint32_t quoteid) void LP_tradebot_timeslices(void *ctx) { - struct LP_tradebot_trade *tp; struct LP_tradebot *bot,*tmp; int32_t i,lastnumfinished = 0; + struct LP_tradebot_trade *tp; struct iguana_info *relcoin; struct LP_tradebot *bot,*tmp; int32_t i,lastnumfinished = 0; while ( 1 ) { DL_FOREACH_SAFE(LP_tradebots,bot,tmp) { + if ( (relcoin= LP_coinfind(bot->rel)) != 0 ) + LP_listunspent_issue(bot->rel,relcoin->smartaddr,1); if ( bot->numpending > 0 && LP_numfinished > lastnumfinished ) { // expire pending trades and see if any still need their requestid/quoteid From ca9467ac6e65bc5cb01607ff6e78ed0a168f97bb Mon Sep 17 00:00:00 2001 From: jl777 Date: Wed, 1 Nov 2017 22:57:41 +0200 Subject: [PATCH 0100/1664] Test --- iguana/exchanges/LP_nativeDEX.c | 2 +- iguana/exchanges/LP_ordermatch.c | 6 +++--- iguana/exchanges/LP_rpc.c | 4 ++-- iguana/exchanges/LP_signatures.c | 3 +-- iguana/exchanges/LP_swap.c | 10 +++++----- iguana/exchanges/LP_transaction.c | 20 +++++++++----------- iguana/exchanges/LP_utxo.c | 2 +- iguana/exchanges/LP_utxos.c | 2 +- 8 files changed, 23 insertions(+), 26 deletions(-) diff --git a/iguana/exchanges/LP_nativeDEX.c b/iguana/exchanges/LP_nativeDEX.c index a4bf251b1..625a5fac2 100644 --- a/iguana/exchanges/LP_nativeDEX.c +++ b/iguana/exchanges/LP_nativeDEX.c @@ -147,7 +147,7 @@ char *LP_decrypt(uint8_t *ptr,int32_t *recvlenp) { printf("unexpected len %d vs recvlen.%d\n",(int32_t)strlen(jsonstr)+1,recvlen); jsonstr = 0; - } else printf("decrypted (%s)\n",jsonstr); + } //else printf("decrypted (%s)\n",jsonstr); } } else printf("cipher.%d too big for %d\n",cipherlen,(int32_t)sizeof(decoded)); *recvlenp = recvlen; diff --git a/iguana/exchanges/LP_ordermatch.c b/iguana/exchanges/LP_ordermatch.c index 197824077..6becabca6 100644 --- a/iguana/exchanges/LP_ordermatch.c +++ b/iguana/exchanges/LP_ordermatch.c @@ -599,7 +599,7 @@ int32_t LP_tradecommand(void *ctx,char *myipaddr,int32_t pubsock,cJSON *argjson, 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); LP_tradecommand_log(argjson); - printf("LP_tradecommand: check received method %s aliceid.%llx\n",method,(long long)Q.aliceid); + //printf("LP_tradecommand: check received method %s aliceid.%llx\n",method,(long long)Q.aliceid); retval = 1; if ( strcmp(method,"reserved") == 0 ) { @@ -616,7 +616,7 @@ int32_t LP_tradecommand(void *ctx,char *myipaddr,int32_t pubsock,cJSON *argjson, { 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)); + //printf("alice %s received CONNECTED.(%s)\n",bits256_str(str,G.LP_mypub25519),jprint(argjson,0)); if ( (retstr= LP_connectedalice(argjson)) != 0 ) free(retstr); } @@ -790,7 +790,7 @@ struct LP_utxoinfo *LP_buyutxo(double *ordermatchpricep,int64_t *bestsatoshisp,i else max = 40; utxos = calloc(max,sizeof(*utxos)); LP_txfees(&txfee,&desttxfee,base,autxo->coin); - printf("LP_buyutxo maxprice %.8f relvol %.8f %s/%s %.8f %.8f\n",maxprice,dstr(autxo->S.satoshis),base,autxo->coin,dstr(txfee),dstr(desttxfee)); + //printf("LP_buyutxo maxprice %.8f relvol %.8f %s/%s %.8f %.8f\n",maxprice,dstr(autxo->S.satoshis),base,autxo->coin,dstr(txfee),dstr(desttxfee)); if ( (obookstr= LP_orderbook(base,autxo->coin,duration)) != 0 ) { if ( (orderbook= cJSON_Parse(obookstr)) != 0 ) diff --git a/iguana/exchanges/LP_rpc.c b/iguana/exchanges/LP_rpc.c index e2fc80bb2..9a546dd8d 100644 --- a/iguana/exchanges/LP_rpc.c +++ b/iguana/exchanges/LP_rpc.c @@ -694,7 +694,7 @@ int32_t LP_listunspent_issue(char *symbol,char *coinaddr,int32_t fullflag) } else if ( IAMLP == 0 ) { - printf("LP_listunspent_query.(%s %s)\n",symbol,coinaddr); + //printf("LP_listunspent_query.(%s %s)\n",symbol,coinaddr); LP_listunspent_query(coin->symbol,coin->smartaddr); if ( fullflag != 0 ) { @@ -862,7 +862,7 @@ char *LP_sendrawtransaction(char *symbol,char *signedtx) jaddistr(array,signedtx); paramstr = jprint(array,1); retstr = bitcoind_passthru(symbol,coin->serverport,coin->userpass,"sendrawtransaction",paramstr); - printf(">>>>>>>>>>> %s dpow_sendrawtransaction.(%s) -> (%s)\n",coin->symbol,paramstr,retstr); + //printf(">>>>>>>>>>> %s dpow_sendrawtransaction.(%s) -> (%s)\n",coin->symbol,paramstr,retstr); free(paramstr); } else diff --git a/iguana/exchanges/LP_signatures.c b/iguana/exchanges/LP_signatures.c index 7ce2350e2..7db6a6a28 100644 --- a/iguana/exchanges/LP_signatures.c +++ b/iguana/exchanges/LP_signatures.c @@ -682,8 +682,7 @@ void LP_query(void *ctx,char *myipaddr,int32_t mypubsock,char *method,struct LP_ jaddnum(reqjson,"timestamp",time(NULL)); msg = jprint(reqjson,1); msg2 = clonestr(msg); - // LP_addsig - printf("QUERY.(%s)\n",msg); + //printf("QUERY.(%s)\n",msg); memset(&zero,0,sizeof(zero)); portable_mutex_lock(&LP_reservedmutex); if ( num_Reserved_msgs < sizeof(Reserved_msgs)/sizeof(*Reserved_msgs)-2 ) diff --git a/iguana/exchanges/LP_swap.c b/iguana/exchanges/LP_swap.c index 267646c6d..612c3ecd8 100644 --- a/iguana/exchanges/LP_swap.c +++ b/iguana/exchanges/LP_swap.c @@ -275,13 +275,13 @@ int32_t LP_choosei_verify(struct basilisk_swap *swap,uint8_t *data,int32_t datal swap->I.pubA0.bytes[i] = data[len++]; for (i=0; i<32; i++) swap->I.pubA1.bytes[i] = data[len++]; - printf("GOT pubA0/1 %s\n",bits256_str(str,swap->I.pubA0)); + //printf("GOT pubA0/1 %s\n",bits256_str(str,swap->I.pubA0)); swap->I.privBn = swap->privkeys[swap->I.otherchoosei]; memset(&swap->privkeys[swap->I.otherchoosei],0,sizeof(swap->privkeys[swap->I.otherchoosei])); revcalc_rmd160_sha256(swap->I.secretBn,swap->I.privBn);//.bytes,sizeof(swap->privBn)); vcalc_sha256(0,swap->I.secretBn256,swap->I.privBn.bytes,sizeof(swap->I.privBn)); swap->I.pubBn = bitcoin_pubkey33(swap->ctx,pubkey33,swap->I.privBn); - printf("set privBn.%s %s\n",bits256_str(str,swap->I.privBn),bits256_str(str2,*(bits256 *)swap->I.secretBn256)); + //printf("set privBn.%s %s\n",bits256_str(str,swap->I.privBn),bits256_str(str2,*(bits256 *)swap->I.secretBn256)); //basilisk_bobscripts_set(swap,1,1); } else @@ -290,18 +290,18 @@ int32_t LP_choosei_verify(struct basilisk_swap *swap,uint8_t *data,int32_t datal swap->I.pubB0.bytes[i] = data[len++]; for (i=0; i<32; i++) swap->I.pubB1.bytes[i] = data[len++]; - printf("GOT pubB0/1 %s\n",bits256_str(str,swap->I.pubB0)); + //printf("GOT pubB0/1 %s\n",bits256_str(str,swap->I.pubB0)); swap->I.privAm = swap->privkeys[swap->I.otherchoosei]; memset(&swap->privkeys[swap->I.otherchoosei],0,sizeof(swap->privkeys[swap->I.otherchoosei])); revcalc_rmd160_sha256(swap->I.secretAm,swap->I.privAm);//.bytes,sizeof(swap->privAm)); vcalc_sha256(0,swap->I.secretAm256,swap->I.privAm.bytes,sizeof(swap->I.privAm)); swap->I.pubAm = bitcoin_pubkey33(swap->ctx,pubkey33,swap->I.privAm); - printf("set privAm.%s %s\n",bits256_str(str,swap->I.privAm),bits256_str(str2,*(bits256 *)swap->I.secretAm256)); + //printf("set privAm.%s %s\n",bits256_str(str,swap->I.privAm),bits256_str(str2,*(bits256 *)swap->I.secretAm256)); swap->bobdeposit.I.pubkey33[0] = 2; swap->bobpayment.I.pubkey33[0] = 2; for (i=0; i<32; i++) swap->bobpayment.I.pubkey33[i+1] = swap->bobdeposit.I.pubkey33[i+1] = swap->I.pubA0.bytes[i]; - printf("SET bobdeposit pubkey33.(02%s)\n",bits256_str(str,swap->I.pubA0)); + //printf("SET bobdeposit pubkey33.(02%s)\n",bits256_str(str,swap->I.pubA0)); //basilisk_bobscripts_set(swap,0); } return(0); diff --git a/iguana/exchanges/LP_transaction.c b/iguana/exchanges/LP_transaction.c index 7d0f963a3..50fee8dcb 100644 --- a/iguana/exchanges/LP_transaction.c +++ b/iguana/exchanges/LP_transaction.c @@ -1554,10 +1554,9 @@ int32_t basilisk_bobscripts_set(struct basilisk_swap *swap,int32_t depositflag,i swap->bobdeposit.I.spendlen = basilisk_bobscript(swap->bobdeposit.I.rmd160,swap->bobdeposit.redeemscript,&swap->bobdeposit.I.redeemlen,swap->bobdeposit.spendscript,0,&swap->bobdeposit.I.locktime,&swap->bobdeposit.I.secretstart,&swap->I,1); bitcoin_address(swap->bobdeposit.p2shaddr,swap->bobcoin.taddr,swap->bobcoin.p2shtype,swap->bobdeposit.redeemscript,swap->bobdeposit.I.redeemlen); strcpy(swap->bobdeposit.I.destaddr,swap->bobdeposit.p2shaddr); - //LP_importaddress(swap->bobcoin.symbol,swap->bobdeposit.I.destaddr); - int32_t i; for (i=0; ibobdeposit.I.redeemlen; i++) - printf("%02x",swap->bobdeposit.redeemscript[i]); - printf(" <- bobdeposit redeem %d %s\n",i,swap->bobdeposit.I.destaddr); + //int32_t i; for (i=0; ibobdeposit.I.redeemlen; i++) + // printf("%02x",swap->bobdeposit.redeemscript[i]); + //printf(" <- bobdeposit redeem %d %s\n",i,swap->bobdeposit.I.destaddr); if ( genflag != 0 && (swap->bobdeposit.I.datalen == 0 || swap->bobrefund.I.datalen == 0) ) { basilisk_rawtx_gen(swap->ctx,"deposit",swap->I.started,swap->persistent_pubkey33,1,1,&swap->bobdeposit,swap->bobdeposit.I.locktime,swap->bobdeposit.spendscript,swap->bobdeposit.I.spendlen,swap->bobdeposit.coin->txfee,1,0,swap->persistent_privkey,swap->changermd160,coinaddr); @@ -1734,13 +1733,12 @@ int32_t LP_verify_bobdeposit(struct basilisk_swap *swap,uint8_t *data,int32_t da bitcoin_address(swap->bobdeposit.p2shaddr,swap->bobcoin.taddr,swap->bobcoin.p2shtype,swap->bobdeposit.redeemscript,swap->bobdeposit.I.redeemlen); strcpy(swap->bobdeposit.I.destaddr,swap->bobdeposit.p2shaddr); basilisk_dontforget_update(swap,&swap->bobdeposit); - //LP_importaddress(swap->bobcoin.symbol,swap->bobdeposit.I.destaddr); - int32_t i; char str[65]; for (i=0; ibobdeposit.I.datalen; i++) - printf("%02x",swap->bobdeposit.txbytes[i]); - printf(" <- bobdeposit.%d %s\n",swap->bobdeposit.I.datalen,bits256_str(str,swap->bobdeposit.I.signedtxid)); - for (i=0; ibobdeposit.I.redeemlen; i++) - printf("%02x",swap->bobdeposit.redeemscript[i]); - printf(" <- bobdeposit redeem %d %s suppress.%d\n",i,swap->bobdeposit.I.destaddr,swap->aliceclaim.I.suppress_pubkeys); + //int32_t i; char str[65]; for (i=0; ibobdeposit.I.datalen; i++) + // printf("%02x",swap->bobdeposit.txbytes[i]); + //printf(" <- bobdeposit.%d %s\n",swap->bobdeposit.I.datalen,bits256_str(str,swap->bobdeposit.I.signedtxid)); + //for (i=0; ibobdeposit.I.redeemlen; i++) + // printf("%02x",swap->bobdeposit.redeemscript[i]); + //printf(" <- bobdeposit redeem %d %s suppress.%d\n",i,swap->bobdeposit.I.destaddr,swap->aliceclaim.I.suppress_pubkeys); memcpy(swap->aliceclaim.redeemscript,swap->bobdeposit.redeemscript,swap->bobdeposit.I.redeemlen); swap->aliceclaim.I.redeemlen = swap->bobdeposit.I.redeemlen; memcpy(swap->aliceclaim.I.pubkey33,swap->persistent_pubkey33,33); diff --git a/iguana/exchanges/LP_utxo.c b/iguana/exchanges/LP_utxo.c index aca156389..8a7f0d0b6 100644 --- a/iguana/exchanges/LP_utxo.c +++ b/iguana/exchanges/LP_utxo.c @@ -168,7 +168,7 @@ int32_t LP_address_utxo_ptrs(struct iguana_info *coin,int32_t iambob,struct LP_a } else { - printf("LP_address_utxo_ptrs skips %s %s payment %s/v%d is spent\n",coin->symbol,coinaddr,bits256_str(str,up->U.txid),up->U.vout); + //printf("LP_address_utxo_ptrs skips %s %s payment %s/v%d is spent\n",coin->symbol,coinaddr,bits256_str(str,up->U.txid),up->U.vout); up->spendheight = 1; if ( (tx= LP_transactionfind(coin,up->U.txid)) != 0 && up->U.vout < tx->numvouts ) tx->outpoints[up->U.vout].spendheight = 1; diff --git a/iguana/exchanges/LP_utxos.c b/iguana/exchanges/LP_utxos.c index 546a6aba0..45dc9c614 100644 --- a/iguana/exchanges/LP_utxos.c +++ b/iguana/exchanges/LP_utxos.c @@ -274,7 +274,7 @@ struct LP_utxoinfo *LP_utxo_bestfit(char *symbol,uint64_t destsatoshis) continue; } bestutxo = utxo; - } else printf("skip alice utxo %.8f vs dest %.8f\n",dstr(utxo->S.satoshis),dstr(destsatoshis)); + } // else printf("skip alice utxo %.8f vs dest %.8f\n",dstr(utxo->S.satoshis),dstr(destsatoshis)); } } return(bestutxo); From ced78486cf24bc003f33b41a0078ebdbc3411ce1 Mon Sep 17 00:00:00 2001 From: jl777 Date: Wed, 1 Nov 2017 22:58:55 +0200 Subject: [PATCH 0101/1664] Test --- iguana/exchanges/LP_tradebots.c | 3 --- 1 file changed, 3 deletions(-) diff --git a/iguana/exchanges/LP_tradebots.c b/iguana/exchanges/LP_tradebots.c index 1a9329d63..845677124 100644 --- a/iguana/exchanges/LP_tradebots.c +++ b/iguana/exchanges/LP_tradebots.c @@ -283,7 +283,6 @@ void LP_tradebot_timeslice(void *ctx,struct LP_tradebot *bot) bot->dead = (uint32_t)time(NULL); else if ( (bot->pendrelsum+bot->relsum) >= bot->totalrelvolume-SMALLVAL || (bot->basesum+bot->pendbasesum) >= bot->totalbasevolume-SMALLVAL ) bot->pause = (uint32_t)time(NULL); - printf("%s\n",jprint(LP_tradebot_json(bot),1)); } else printf("didnt get any trade pending %s %s\n\n",bot->name,retstr); free_json(retjson2); } else printf("%s\n",retstr); @@ -315,7 +314,6 @@ void LP_tradebot_finished(uint32_t tradeid,uint32_t requestid,uint32_t quoteid) bot->numpending--, bot->completed++; printf("bot.%u detected completion tradeid.%u aliceid.%llx r.%u q.%u\n",bot->id,tp->tradeid,(long long)tp->aliceid,tp->requestid,tp->quoteid); tp->finished = (uint32_t)time(NULL); - printf("%s\n",jprint(LP_tradebot_json(bot),1)); break; } } @@ -348,7 +346,6 @@ void LP_tradebot_timeslices(void *ctx) } } } - printf("%s\n",jprint(LP_tradebot_json(bot),1)); } else if ( bot->numpending == 0 ) LP_tradebot_timeslice(ctx,bot); From ae2188f76d6e2a483e8307b9c72f31967b646c59 Mon Sep 17 00:00:00 2001 From: jl777 Date: Wed, 1 Nov 2017 23:00:12 +0200 Subject: [PATCH 0102/1664] Test --- iguana/exchanges/stats.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/iguana/exchanges/stats.c b/iguana/exchanges/stats.c index 2ff62895d..2cb647dde 100644 --- a/iguana/exchanges/stats.c +++ b/iguana/exchanges/stats.c @@ -32,7 +32,7 @@ char *stats_JSON(void *ctx,char *myipaddr,int32_t mypubsock,cJSON *argjson,char char *stats_validmethods[] = { - "getprices", "listunspent", "notify", "getpeers", "uitem", // from issue_ + "psock", "getprices", "listunspent", "notify", "getpeers", "uitem", // from issue_ "orderbook", "help", "getcoins", "pricearray", "balance" }; From 033a5664d608f266721768fb0d9ccbf53a5a3b83 Mon Sep 17 00:00:00 2001 From: jl777 Date: Wed, 1 Nov 2017 23:23:58 +0200 Subject: [PATCH 0103/1664] Test --- iguana/exchanges/LP_nativeDEX.c | 4 ++-- iguana/exchanges/LP_signatures.c | 2 +- iguana/exchanges/LP_tradebots.c | 12 ++++++------ 3 files changed, 9 insertions(+), 9 deletions(-) diff --git a/iguana/exchanges/LP_nativeDEX.c b/iguana/exchanges/LP_nativeDEX.c index 625a5fac2..1e76da0a3 100644 --- a/iguana/exchanges/LP_nativeDEX.c +++ b/iguana/exchanges/LP_nativeDEX.c @@ -236,8 +236,8 @@ char *LP_process_message(void *ctx,char *typestr,char *myipaddr,int32_t pubsock, else { memset(zero.bytes,0,sizeof(zero)); - if ( (method= jstr(reqjson,"method")) != 0 && (strcmp(method,"request") == 0 || strcmp(method,"requested") == 0 || strcmp(method,"connect") == 0 || strcmp(method,"connected") == 0) ) - printf("broadcast.(%s)\n",Broadcaststr); + /*if ( (method= jstr(reqjson,"method")) != 0 && (strcmp(method,"request") == 0 || strcmp(method,"requested") == 0 || strcmp(method,"connect") == 0 || strcmp(method,"connected") == 0) ) + printf("broadcast.(%s)\n",Broadcaststr);*/ LP_reserved_msg("","",zero,jprint(reqjson,0)); } retstr = clonestr("{\"result\":\"success\"}"); diff --git a/iguana/exchanges/LP_signatures.c b/iguana/exchanges/LP_signatures.c index 7db6a6a28..c300bf3e8 100644 --- a/iguana/exchanges/LP_signatures.c +++ b/iguana/exchanges/LP_signatures.c @@ -35,7 +35,7 @@ struct basilisk_request *LP_requestinit(struct basilisk_request *rp,bits256 srch rp->desthash = desthash; rp->destamount = destsatoshis; rp->quoteid = basilisk_quoteid(rp); - printf("r.%u %u, q.%u %u: %s %.8f -> %s %.8f\n",rp->timestamp,rp->requestid,rp->quotetime,rp->quoteid,rp->src,dstr(rp->srcamount),rp->dest,dstr(rp->destamount)); + //printf("r.%u %u, q.%u %u: %s %.8f -> %s %.8f\n",rp->timestamp,rp->requestid,rp->quotetime,rp->quoteid,rp->src,dstr(rp->srcamount),rp->dest,dstr(rp->destamount)); return(rp); } diff --git a/iguana/exchanges/LP_tradebots.c b/iguana/exchanges/LP_tradebots.c index 845677124..d5d309f1c 100644 --- a/iguana/exchanges/LP_tradebots.c +++ b/iguana/exchanges/LP_tradebots.c @@ -142,9 +142,9 @@ cJSON *LP_tradebot_json(struct LP_tradebot *bot) jaddnum(json,"maxprice",bot->maxprice); jaddnum(json,"totalrelvolume",bot->totalrelvolume); jaddnum(json,"totalbasevolume",bot->totalbasevolume); - if ( (vol= bot->relsum) > SMALLVAL ) + if ( (vol= bot->relsum) > SMALLVAL && bot->basesum > SMALLVAL ) { - jaddnum(json,"aveprice",bot->basesum/vol); + jaddnum(json,"aveprice",vol/bot->basesum); jaddnum(json,"volume",vol); } } @@ -157,9 +157,9 @@ cJSON *LP_tradebot_json(struct LP_tradebot *bot) jaddnum(json,"minprice",aveprice); jaddnum(json,"totalbasevolume",bot->totalrelvolume); jaddnum(json,"totalrelvolume",basevolume); - if ( (vol= bot->relsum) > SMALLVAL ) + if ( (vol= bot->relsum) > SMALLVAL && bot->basesum > SMALLVAL ) { - aveprice = LP_pricevol_invert(&basevolume,bot->basesum / vol,vol); + aveprice = LP_pricevol_invert(&basevolume,vol/bot->basesum,vol); jaddnum(json,"aveprice",aveprice); jaddnum(json,"volume",basevolume); } @@ -279,9 +279,9 @@ void LP_tradebot_timeslice(void *ctx,struct LP_tradebot *bot) if ( (pending= jobj(retjson2,"pending")) != 0 && juint(pending,"tradeid") == tradeid ) { bot->trades[bot->numtrades++] = LP_tradebot_pending(bot,pending,tradeid); - if ( bot->relsum >= bot->totalrelvolume-SMALLVAL || bot->basesum >= bot->totalbasevolume-SMALLVAL ) + if ( bot->relsum >= 0.99*bot->totalrelvolume-SMALLVAL || bot->basesum >= 0.99*bot->totalbasevolume-SMALLVAL ) bot->dead = (uint32_t)time(NULL); - else if ( (bot->pendrelsum+bot->relsum) >= bot->totalrelvolume-SMALLVAL || (bot->basesum+bot->pendbasesum) >= bot->totalbasevolume-SMALLVAL ) + else if ( (bot->pendrelsum+bot->relsum) >= 0.99*bot->totalrelvolume-SMALLVAL || (bot->basesum+bot->pendbasesum) >= 0.99*bot->totalbasevolume-SMALLVAL ) bot->pause = (uint32_t)time(NULL); } else printf("didnt get any trade pending %s %s\n\n",bot->name,retstr); free_json(retjson2); From 6e6f6d51e1af2960cd3b9de9e484f19882b70fe2 Mon Sep 17 00:00:00 2001 From: jl777 Date: Thu, 2 Nov 2017 09:30:57 +0200 Subject: [PATCH 0104/1664] Remove ws:// --- iguana/exchanges/LP_include.h | 2 +- iguana/exchanges/LP_nativeDEX.c | 11 ++++++----- iguana/exchanges/LP_network.c | 30 +++++++++++++++--------------- iguana/exchanges/LP_peers.c | 22 +++++++++++----------- iguana/exchanges/LP_swap.c | 2 +- 5 files changed, 34 insertions(+), 33 deletions(-) diff --git a/iguana/exchanges/LP_include.h b/iguana/exchanges/LP_include.h index 3000b44b3..38f8b1393 100644 --- a/iguana/exchanges/LP_include.h +++ b/iguana/exchanges/LP_include.h @@ -379,7 +379,7 @@ int64_t LP_komodo_interest(bits256 txid,int64_t value); 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); int32_t LP_pullsock_check(void *ctx,char **retstrp,char *myipaddr,int32_t pubsock,int32_t pullsock); -uint16_t LP_psock_get(char *connectaddr,char *connectaddr2,char *publicaddr,int32_t ispaired); +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); diff --git a/iguana/exchanges/LP_nativeDEX.c b/iguana/exchanges/LP_nativeDEX.c index 1e76da0a3..1b410bff7 100644 --- a/iguana/exchanges/LP_nativeDEX.c +++ b/iguana/exchanges/LP_nativeDEX.c @@ -19,6 +19,7 @@ // marketmaker // // electrum keepalive +// merge bots + portfoliot // verify portfolio, interest to KMD withdraw // dPoW security -> 4: KMD notarized, 5: BTC notarized, after next notary elections // bigendian architectures need to use little endian for sighash calcs @@ -825,7 +826,7 @@ int32_t LP_reserved_msg(char *base,char *rel,bits256 pubkey,char *msg) 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 valid,timeout,pubsock=-1; struct LP_peerinfo *mypeer=0; char pushaddr[128],bindaddr2[128],subaddr[128],bindaddr[128],*coins_str=0; cJSON *coinsjson=0; void *ctx = bitcoin_ctx(); + char *myipaddr=0; long filesize,n; int32_t valid,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(); LP_showwif = juint(argjson,"wif"); if ( passphrase == 0 || passphrase[0] == 0 ) { @@ -910,15 +911,15 @@ void LPinit(uint16_t myport,uint16_t mypullport,uint16_t mypubport,uint16_t mybu pubsock = -1; nanomsg_transportname(0,subaddr,myipaddr,mypubport); nanomsg_transportname(1,bindaddr,myipaddr,mypubport); - nanomsg_transportname2(1,bindaddr2,myipaddr,mypubport); + //nanomsg_transportname2(1,bindaddr2,myipaddr,mypubport); valid = 0; if ( (pubsock= nn_socket(AF_SP,NN_PUB)) >= 0 ) { valid = 0; if ( nn_bind(pubsock,bindaddr) >= 0 ) valid++; - if ( nn_bind(pubsock,bindaddr2) >= 0 ) - valid++; + //if ( nn_bind(pubsock,bindaddr2) >= 0 ) + // valid++; if ( valid > 0 ) { timeout = 1; @@ -931,7 +932,7 @@ void LPinit(uint16_t myport,uint16_t mypullport,uint16_t mypubport,uint16_t mybu nn_close(pubsock), pubsock = -1; } } else printf("error getting pubsock %d\n",pubsock); - printf(">>>>>>>>> myipaddr.(%s %s) (%s) pullsock.%d valid.%d\n",bindaddr,bindaddr2,subaddr,pubsock,valid); + printf(">>>>>>>>> myipaddr.(%s) (%s) pullsock.%d valid.%d\n",bindaddr,subaddr,pubsock,valid); LP_mypubsock = pubsock; } printf("got %s, initpeers\n",myipaddr); diff --git a/iguana/exchanges/LP_network.c b/iguana/exchanges/LP_network.c index b53e58159..e936e8fc8 100644 --- a/iguana/exchanges/LP_network.c +++ b/iguana/exchanges/LP_network.c @@ -98,17 +98,17 @@ int32_t nn_poll(struct nn_pollfd *fds, int nfds, int timeout) char *nanomsg_transportname(int32_t bindflag,char *str,char *ipaddr,uint16_t port) { - sprintf(str,"ws://%s:%u",bindflag == 0 ? ipaddr : "*",port); + sprintf(str,"tcp://%s:%u",bindflag == 0 ? ipaddr : "*",port); return(str); } -char *nanomsg_transportname2(int32_t bindflag,char *str,char *ipaddr,uint16_t port) +/*char *nanomsg_transportname2(int32_t bindflag,char *str,char *ipaddr,uint16_t port) { - sprintf(str,"tcp://%s:%u",bindflag == 0 ? ipaddr : "*",port+10); + sprintf(str,"ws://%s:%u",bindflag == 0 ? ipaddr : "*",port+10); return(str); } -/*int32_t _LP_send(int32_t sock,void *msg,int32_t sendlen,int32_t freeflag) +int32_t _LP_send(int32_t sock,void *msg,int32_t sendlen,int32_t freeflag) { int32_t sentbytes; if ( sock < 0 ) @@ -735,7 +735,7 @@ char *issue_LP_psock(char *destip,uint16_t destport,int32_t ispaired) return(retstr); } -uint16_t LP_psock_get(char *connectaddr,char *connectaddr2,char *publicaddr,int32_t ispaired) +uint16_t LP_psock_get(char *connectaddr,char *publicaddr,int32_t ispaired) { uint16_t publicport = 0; char *retstr,*addr; cJSON *retjson; struct LP_peerinfo *peer,*tmp; HASH_ITER(hh,LP_peerinfos,peer,tmp) @@ -750,8 +750,8 @@ uint16_t LP_psock_get(char *connectaddr,char *connectaddr2,char *publicaddr,int3 safecopy(publicaddr,addr,128); if ( (addr= jstr(retjson,"connectaddr")) != 0 ) safecopy(connectaddr,addr,128); - if ( (addr= jstr(retjson,"connectaddr2")) != 0 ) - safecopy(connectaddr2,addr,128); + //if ( (addr= jstr(retjson,"connectaddr2")) != 0 ) + // safecopy(connectaddr2,addr,128); if ( publicaddr[0] != 0 && connectaddr[0] != 0 ) publicport = juint(retjson,"publicport"); free_json(retjson); @@ -767,9 +767,9 @@ uint16_t LP_psock_get(char *connectaddr,char *connectaddr2,char *publicaddr,int3 int32_t LP_initpublicaddr(void *ctx,uint16_t *mypullportp,char *publicaddr,char *myipaddr,uint16_t mypullport,int32_t ispaired) { - int32_t nntype,pullsock,timeout; char bindaddr[128],bindaddr2[128],connectaddr[128],connectaddr2[128]; + int32_t nntype,pullsock,timeout; char bindaddr[128],connectaddr[128]; *mypullportp = mypullport; - connectaddr2[0] = 0; + //connectaddr2[0] = 0; if ( ispaired == 0 ) { if ( LP_canbind != 0 ) @@ -780,7 +780,7 @@ int32_t LP_initpublicaddr(void *ctx,uint16_t *mypullportp,char *publicaddr,char { nanomsg_transportname(0,publicaddr,myipaddr,mypullport); nanomsg_transportname(1,bindaddr,myipaddr,mypullport); - nanomsg_transportname2(1,bindaddr2,myipaddr,mypullport); + //nanomsg_transportname2(1,bindaddr2,myipaddr,mypullport); } else { @@ -792,7 +792,7 @@ int32_t LP_initpublicaddr(void *ctx,uint16_t *mypullportp,char *publicaddr,char } while ( *mypullportp == 0 ) { - if ( (*mypullportp= LP_psock_get(connectaddr,connectaddr2,publicaddr,ispaired)) != 0 ) + if ( (*mypullportp= LP_psock_get(connectaddr,publicaddr,ispaired)) != 0 ) break; sleep(10); printf("try to get publicaddr again\n"); @@ -811,8 +811,8 @@ int32_t LP_initpublicaddr(void *ctx,uint16_t *mypullportp,char *publicaddr,char } else { - if ( connectaddr2[0] != 0 && nn_connect(pullsock,connectaddr2) > 0 ) - printf("%s ",connectaddr2); + //if ( connectaddr2[0] != 0 && nn_connect(pullsock,connectaddr2) > 0 ) + // printf("%s ",connectaddr2); printf("nntype.%d NN_PAIR.%d connect to %s connectsock.%d\n",nntype,NN_PAIR,connectaddr,pullsock); } } @@ -823,8 +823,8 @@ int32_t LP_initpublicaddr(void *ctx,uint16_t *mypullportp,char *publicaddr,char printf("bind to %s error for %s: %s\n",bindaddr,publicaddr,nn_strerror(nn_errno())); exit(-1); } - if ( nn_bind(pullsock,bindaddr2) >= 0 ) - printf("bound to %s\n",bindaddr2); + //if ( nn_bind(pullsock,bindaddr2) >= 0 ) + // printf("bound to %s\n",bindaddr2); } timeout = 1; nn_setsockopt(pullsock,NN_SOL_SOCKET,NN_RCVTIMEO,&timeout,sizeof(timeout)); diff --git a/iguana/exchanges/LP_peers.c b/iguana/exchanges/LP_peers.c index 33c776969..8539fef27 100644 --- a/iguana/exchanges/LP_peers.c +++ b/iguana/exchanges/LP_peers.c @@ -56,7 +56,7 @@ char *LP_peers() struct LP_peerinfo *LP_addpeer(struct LP_peerinfo *mypeer,int32_t mypubsock,char *ipaddr,uint16_t port,uint16_t pushport,uint16_t subport,int32_t numpeers,int32_t numutxos,uint32_t sessionid) { - uint32_t ipbits; int32_t valid,pushsock,subsock,timeout; char checkip[64],subaddr2[64],pushaddr[64],pushaddr2[64],subaddr[64]; struct LP_peerinfo *peer = 0; + uint32_t ipbits; int32_t valid,pushsock,subsock,timeout; char checkip[64],pushaddr[64],subaddr[64]; struct LP_peerinfo *peer = 0; printf("addpeer (%s:%u) pushport.%u subport.%u\n",ipaddr,port,pushport,subport); #ifdef LP_STRICTPEERS if ( strncmp("5.9.253",ipaddr,strlen("5.9.253")) != 0 ) @@ -90,19 +90,19 @@ struct LP_peerinfo *LP_addpeer(struct LP_peerinfo *mypeer,int32_t mypubsock,char if ( pushport != 0 && subport != 0 && (pushsock= nn_socket(AF_SP,NN_PUSH)) >= 0 ) { nanomsg_transportname(0,pushaddr,peer->ipaddr,pushport); - nanomsg_transportname2(0,pushaddr2,peer->ipaddr,pushport); + //nanomsg_transportname2(0,pushaddr2,peer->ipaddr,pushport); valid = 0; if ( nn_connect(pushsock,pushaddr) >= 0 ) valid++; - if ( nn_connect(pushsock,pushaddr2) >= 0 ) - valid++; + //if ( nn_connect(pushsock,pushaddr2) >= 0 ) + // valid++; if ( valid > 0 ) { timeout = 1; nn_setsockopt(pushsock,NN_SOL_SOCKET,NN_SNDTIMEO,&timeout,sizeof(timeout)); //maxsize = 2 * 1024 * 1024; //nn_setsockopt(pushsock,NN_SOL_SOCKET,NN_SNDBUF,&maxsize,sizeof(maxsize)); - printf("connected to push.(%s %s) pushsock.%d valid.%d\n",pushaddr,pushaddr2,pushsock,valid); + printf("connected to push.(%s) pushsock.%d valid.%d\n",pushaddr,pushsock,valid); peer->connected = (uint32_t)time(NULL); peer->pushsock = pushsock; if ( (subsock= nn_socket(AF_SP,NN_SUB)) >= 0 ) @@ -111,20 +111,20 @@ struct LP_peerinfo *LP_addpeer(struct LP_peerinfo *mypeer,int32_t mypubsock,char nn_setsockopt(subsock,NN_SOL_SOCKET,NN_RCVTIMEO,&timeout,sizeof(timeout)); nn_setsockopt(subsock,NN_SUB,NN_SUB_SUBSCRIBE,"",0); nanomsg_transportname(0,subaddr,peer->ipaddr,subport); - nanomsg_transportname2(0,subaddr2,peer->ipaddr,subport); + //nanomsg_transportname2(0,subaddr2,peer->ipaddr,subport); valid = 0; if ( nn_connect(subsock,subaddr) >= 0 ) valid++; - if ( nn_connect(subsock,subaddr2) >= 0 ) - valid++; + //if ( nn_connect(subsock,subaddr2) >= 0 ) + // valid++; if ( valid > 0 ) { peer->subsock = subsock; - printf("connected to sub.(%s %s) subsock.%d valid.%d\n",subaddr,subaddr2,peer->subsock,valid); + printf("connected to sub.(%s) subsock.%d valid.%d\n",subaddr,peer->subsock,valid); } else { - printf("error connecting to subsock.%d (%s %s)\n",subsock,subaddr,subaddr2); + printf("error connecting to subsock.%d (%s)\n",subsock,subaddr); nn_close(subsock); subsock = -1; } @@ -134,7 +134,7 @@ struct LP_peerinfo *LP_addpeer(struct LP_peerinfo *mypeer,int32_t mypubsock,char { nn_close(pushsock); pushsock = -1; - printf("error connecting to push.(%s %s)\n",pushaddr,pushaddr2); + printf("error connecting to push.(%s)\n",pushaddr); } } else printf("%s pushport.%u subport.%u pushsock.%d\n",ipaddr,pushport,subport,pushsock); if ( peer->pushsock >= 0 && peer->subsock >= 0 ) diff --git a/iguana/exchanges/LP_swap.c b/iguana/exchanges/LP_swap.c index 612c3ecd8..41c65f031 100644 --- a/iguana/exchanges/LP_swap.c +++ b/iguana/exchanges/LP_swap.c @@ -262,7 +262,7 @@ int32_t LP_choosei_data(struct basilisk_swap *swap,uint8_t *data,int32_t maxlen) int32_t LP_choosei_verify(struct basilisk_swap *swap,uint8_t *data,int32_t datalen) { - int32_t otherchoosei=-1,i,len = 0; uint8_t pubkey33[33]; char str[65],str2[65]; + int32_t otherchoosei=-1,i,len = 0; uint8_t pubkey33[33]; if ( datalen == sizeof(otherchoosei)+sizeof(bits256)*2 ) { len += iguana_rwnum(0,data,sizeof(otherchoosei),&otherchoosei); From f8f99cc7ef2ecc1426ab9e9aead4800290908840 Mon Sep 17 00:00:00 2001 From: jl777 Date: Thu, 2 Nov 2017 09:52:53 +0200 Subject: [PATCH 0105/1664] Test --- iguana/exchanges/LP_nativeDEX.c | 8 +------ iguana/exchanges/LP_portfolio.c | 9 +++----- iguana/exchanges/LP_tradebots.c | 41 +++++++++++++++------------------ 3 files changed, 23 insertions(+), 35 deletions(-) diff --git a/iguana/exchanges/LP_nativeDEX.c b/iguana/exchanges/LP_nativeDEX.c index 1b410bff7..eb0f2bd68 100644 --- a/iguana/exchanges/LP_nativeDEX.c +++ b/iguana/exchanges/LP_nativeDEX.c @@ -994,7 +994,7 @@ void LPinit(uint16_t myport,uint16_t mypullport,uint16_t mypubport,uint16_t mybu printf("error launching queue_loop for port.%u\n",myport); exit(-1); } - if ( OS_thread_create(malloc(sizeof(pthread_t)),NULL,(void *)prices_loop,(void *)myipaddr) != 0 ) + if ( OS_thread_create(malloc(sizeof(pthread_t)),NULL,(void *)prices_loop,ctx) != 0 ) { printf("error launching prices_loop for port.%u\n",myport); exit(-1); @@ -1029,11 +1029,6 @@ void LPinit(uint16_t myport,uint16_t mypullport,uint16_t mypubport,uint16_t mybu printf("error launching LP_swapsloop for port.%u\n",myport); exit(-1); } - if ( OS_thread_create(malloc(sizeof(pthread_t)),NULL,(void *)LP_tradebot_timeslices,ctx) != 0 ) - { - printf("error launching LP_tradebot_timeslices\n"); - exit(-1); - } int32_t nonz; while ( 1 ) { @@ -1117,7 +1112,6 @@ void LP_fromjs_iter() { LP_notify_pubkeys(ctx,LP_mypubsock); LP_privkey_updates(ctx,LP_mypubsock,0); - prices_loop(0); if ( (retstr= basilisk_swapentry(0,0)) != 0 ) free(retstr); } diff --git a/iguana/exchanges/LP_portfolio.c b/iguana/exchanges/LP_portfolio.c index 19aba3cb4..38fe3ba69 100644 --- a/iguana/exchanges/LP_portfolio.c +++ b/iguana/exchanges/LP_portfolio.c @@ -586,15 +586,14 @@ int32_t LP_portfolio_order(struct LP_portfoliotrade *trades,int32_t max,cJSON *a return(n); } -void prices_loop(void *arg) +void prices_loop(void *ctx) { - char *retstr; cJSON *retjson,*array; char *buycoin,*sellcoin; struct iguana_info *buy,*sell; uint32_t requestid,quoteid; int32_t i,n,m; struct LP_portfoliotrade trades[256]; struct LP_priceinfo *btcpp; void *ctx = bitcoin_ctx(); + char *retstr; cJSON *retjson,*array; char *buycoin,*sellcoin; struct iguana_info *buy,*sell; uint32_t requestid,quoteid; int32_t i,n,m; struct LP_portfoliotrade trades[256]; struct LP_priceinfo *btcpp; while ( 1 ) { + LP_tradebots_timeslice(ctx); if ( (btcpp= LP_priceinfofind("BTC")) == 0 ) { - if ( arg == 0 ) - return; sleep(60); continue; } @@ -628,8 +627,6 @@ void prices_loop(void *arg) } free(retstr); } - if ( arg == 0 ) - return; sleep(60); } } diff --git a/iguana/exchanges/LP_tradebots.c b/iguana/exchanges/LP_tradebots.c index d5d309f1c..fc7cc2cb9 100644 --- a/iguana/exchanges/LP_tradebots.c +++ b/iguana/exchanges/LP_tradebots.c @@ -320,39 +320,36 @@ void LP_tradebot_finished(uint32_t tradeid,uint32_t requestid,uint32_t quoteid) } } -void LP_tradebot_timeslices(void *ctx) +void LP_tradebots_timeslice(void *ctx) { - struct LP_tradebot_trade *tp; struct iguana_info *relcoin; struct LP_tradebot *bot,*tmp; int32_t i,lastnumfinished = 0; - while ( 1 ) + static uint32_t lastnumfinished = 0; + struct LP_tradebot_trade *tp; struct iguana_info *relcoin; struct LP_tradebot *bot,*tmp; int32_t i; + DL_FOREACH_SAFE(LP_tradebots,bot,tmp) { - DL_FOREACH_SAFE(LP_tradebots,bot,tmp) + if ( (relcoin= LP_coinfind(bot->rel)) != 0 ) + LP_listunspent_issue(bot->rel,relcoin->smartaddr,1); + if ( bot->numpending > 0 && LP_numfinished > lastnumfinished ) { - if ( (relcoin= LP_coinfind(bot->rel)) != 0 ) - LP_listunspent_issue(bot->rel,relcoin->smartaddr,1); - if ( bot->numpending > 0 && LP_numfinished > lastnumfinished ) + // expire pending trades and see if any still need their requestid/quoteid + for (i=0; inumtrades; i++) { - // expire pending trades and see if any still need their requestid/quoteid - for (i=0; inumtrades; i++) + if ( (tp= bot->trades[i]) != 0 && tp->finished == 0 ) { - if ( (tp= bot->trades[i]) != 0 && tp->finished == 0 ) + if ( time(NULL) > tp->started+INSTANTDEX_LOCKTIME*2 ) { - if ( time(NULL) > tp->started+INSTANTDEX_LOCKTIME*2 ) - { - bot->pendbasesum -= tp->basevol; - bot->pendrelsum -= tp->relvol; - bot->numpending--; - tp->finished = (uint32_t)time(NULL); - printf("%s trade.%d of %d expired\n",bot->name,i,bot->numtrades); - } + bot->pendbasesum -= tp->basevol; + bot->pendrelsum -= tp->relvol; + bot->numpending--; + tp->finished = (uint32_t)time(NULL); + printf("%s trade.%d of %d expired\n",bot->name,i,bot->numtrades); } } } - else if ( bot->numpending == 0 ) - LP_tradebot_timeslice(ctx,bot); } - lastnumfinished = LP_numfinished; - sleep(60); + else if ( bot->numpending == 0 ) + LP_tradebot_timeslice(ctx,bot); } + lastnumfinished = LP_numfinished; } char *LP_tradebot_list(void *ctx,int32_t pubsock,cJSON *argjson) From ee624436c52c6ae8a8b561e0ab63896a22316ca7 Mon Sep 17 00:00:00 2001 From: jl777 Date: Thu, 2 Nov 2017 10:02:00 +0200 Subject: [PATCH 0106/1664] Test --- iguana/exchanges/LP_coins.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/iguana/exchanges/LP_coins.c b/iguana/exchanges/LP_coins.c index 5db73995d..c2771e308 100644 --- a/iguana/exchanges/LP_coins.c +++ b/iguana/exchanges/LP_coins.c @@ -389,9 +389,9 @@ struct iguana_info *LP_coinfind(char *symbol) if ( (coin= LP_coinadd(&cdata)) != 0 ) { coin->inactive = isinactive * (uint32_t)time(NULL); - if ( strcmp(symbol,"KMD") == 0 ) + /*if ( strcmp(symbol,"KMD") == 0 ) coin->inactive = 0; - else if ( strcmp(symbol,"BTC") == 0 ) + else*/ if ( strcmp(symbol,"BTC") == 0 ) { coin->inactive = (uint32_t)time(NULL) * !IAMLP; printf("BTC inactive.%u\n",coin->inactive); From ca8a512e221cc68fbc93849c754d81877b086852 Mon Sep 17 00:00:00 2001 From: jl777 Date: Thu, 2 Nov 2017 10:04:53 +0200 Subject: [PATCH 0107/1664] Handle null electrum server --- iguana/exchanges/LP_socket.c | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/iguana/exchanges/LP_socket.c b/iguana/exchanges/LP_socket.c index ca409527a..1b584ac28 100644 --- a/iguana/exchanges/LP_socket.c +++ b/iguana/exchanges/LP_socket.c @@ -971,7 +971,13 @@ void LP_dedicatedloop(void *arg) cJSON *LP_electrumserver(struct iguana_info *coin,char *ipaddr,uint16_t port) { - struct electrum_info *ep; int32_t already; cJSON *retjson = cJSON_CreateObject(); + struct electrum_info *ep; int32_t already; cJSON *retjson; + if ( ipaddr == 0 || ipaddr[0] == 0 || port == 0 ) + { + coin->electrum = 0; + return(cJSON_Parse("{\"result\":\"success\",\"status\":\"electrum mode disabled, now in native coin mode\"}")); + } + retjson = cJSON_CreateObject(); jaddstr(retjson,"ipaddr",ipaddr); jaddnum(retjson,"port",port); if ( (ep= LP_electrum_info(&already,coin->symbol,ipaddr,port,IGUANA_MAXPACKETSIZE * 10)) == 0 ) From bee2ac1fb835d1e0dedc910d1a28ce4f50128a7f Mon Sep 17 00:00:00 2001 From: jl777 Date: Thu, 2 Nov 2017 10:22:40 +0200 Subject: [PATCH 0108/1664] Test --- iguana/exchanges/LP_coins.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/iguana/exchanges/LP_coins.c b/iguana/exchanges/LP_coins.c index c2771e308..4a6736b6e 100644 --- a/iguana/exchanges/LP_coins.c +++ b/iguana/exchanges/LP_coins.c @@ -447,6 +447,8 @@ struct iguana_info *LP_coincreate(cJSON *item) } if ( 0 && coin != 0 && coin->inactive != 0 ) printf("LPnode.%d %s inactive.%u %p vs %p\n",IAMLP,coin->symbol,coin->inactive,assetname,name); + if ( coin != 0 && LP_getheight(coin) <= 0 ) + coin->inactive = (uint32_t)time(NULL); return(0); } From 1c61c5a978548544c6e62982a79692d72f420721 Mon Sep 17 00:00:00 2001 From: jl777 Date: Thu, 2 Nov 2017 10:32:47 +0200 Subject: [PATCH 0109/1664] Test --- iguana/exchanges/LP_include.h | 2 +- iguana/exchanges/LP_utxos.c | 21 +++++++++++---------- 2 files changed, 12 insertions(+), 11 deletions(-) diff --git a/iguana/exchanges/LP_include.h b/iguana/exchanges/LP_include.h index 38f8b1393..cbbd765ec 100644 --- a/iguana/exchanges/LP_include.h +++ b/iguana/exchanges/LP_include.h @@ -247,7 +247,7 @@ struct iguana_info portable_mutex_t txmutex,addrmutex; struct LP_transaction *transactions; struct LP_address *addresses; uint64_t txfee; int32_t longestchain,firstrefht,firstscanht,lastscanht,bussock,height; uint16_t busport; - uint32_t lastpushtime,lastutxosync,addr_listunspent_requested,lastutxos,updaterate,counter,inactive,lastmempool,lastgetinfo,ratetime,heighttime,lastmonitor,obooktime; + uint32_t 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[16],smartaddr[64],userpass[1024],serverport[128]; // portfolio diff --git a/iguana/exchanges/LP_utxos.c b/iguana/exchanges/LP_utxos.c index 45dc9c614..590ebcb30 100644 --- a/iguana/exchanges/LP_utxos.c +++ b/iguana/exchanges/LP_utxos.c @@ -733,18 +733,19 @@ bits256 LP_privkeycalc(void *ctx,uint8_t *pubkey33,bits256 *pubkeyp,struct iguan userpub = curve25519(userpass,curve25519_basepoint9()); printf("userpass.(%s)\n",bits256_str(G.USERPASS,userpub)); } - if ( coin->electrum == 0 && coin->userpass[0] != 0 ) + } + if ( coin->importedprivkey == 0 && coin->electrum == 0 && coin->userpass[0] != 0 && LP_getheight(coin) > 0 ) + { + LP_listunspent_issue(coin->symbol,coin->smartaddr,0); + if ( (retjson= LP_importprivkey(coin->symbol,tmpstr,coin->smartaddr,-1)) != 0 ) { - LP_listunspent_issue(coin->symbol,coin->smartaddr,0); - if ( (retjson= LP_importprivkey(coin->symbol,tmpstr,coin->smartaddr,-1)) != 0 ) + if ( jobj(retjson,"error") != 0 ) { - if ( jobj(retjson,"error") != 0 ) - { - printf("cant importprivkey.%s -> (%s), abort session\n",coin->symbol,jprint(retjson,1)); - exit(-1); - } - } else free_json(retjson); - } + printf("cant importprivkey.%s -> (%s), abort session\n",coin->symbol,jprint(retjson,1)); + exit(-1); + } + } else free_json(retjson); + coin->importedprivkey = (uint32_t)time(NULL); } vcalc_sha256(0,checkkey.bytes,privkey.bytes,sizeof(privkey)); checkkey.bytes[0] &= 248, checkkey.bytes[31] &= 127, checkkey.bytes[31] |= 64; From 9f333982f4dce2feac90d307b5f68fab9d05352b Mon Sep 17 00:00:00 2001 From: jl777 Date: Thu, 2 Nov 2017 10:38:38 +0200 Subject: [PATCH 0110/1664] Test --- iguana/exchanges/LP_coins.c | 2 -- iguana/exchanges/LP_nativeDEX.c | 15 +++++++++++---- 2 files changed, 11 insertions(+), 6 deletions(-) diff --git a/iguana/exchanges/LP_coins.c b/iguana/exchanges/LP_coins.c index 4a6736b6e..c2771e308 100644 --- a/iguana/exchanges/LP_coins.c +++ b/iguana/exchanges/LP_coins.c @@ -447,8 +447,6 @@ struct iguana_info *LP_coincreate(cJSON *item) } if ( 0 && coin != 0 && coin->inactive != 0 ) printf("LPnode.%d %s inactive.%u %p vs %p\n",IAMLP,coin->symbol,coin->inactive,assetname,name); - if ( coin != 0 && LP_getheight(coin) <= 0 ) - coin->inactive = (uint32_t)time(NULL); return(0); } diff --git a/iguana/exchanges/LP_nativeDEX.c b/iguana/exchanges/LP_nativeDEX.c index eb0f2bd68..3f7f7ea16 100644 --- a/iguana/exchanges/LP_nativeDEX.c +++ b/iguana/exchanges/LP_nativeDEX.c @@ -676,21 +676,28 @@ 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; + int32_t i,n; cJSON *item; char *symbol; struct iguana_info *coin; for (i=0; iinactive = (uint32_t)time(NULL); } if ( (n= cJSON_GetArraySize(coins)) > 0 ) { for (i=0; iinactive = (uint32_t)time(NULL); + } } } printf("privkey updates\n"); From a3b84b2e2b60a92da36ebe74bb0314aaa232120d Mon Sep 17 00:00:00 2001 From: jl777 Date: Thu, 2 Nov 2017 11:19:45 +0200 Subject: [PATCH 0111/1664] unspents cache --- iguana/exchanges/LP_include.h | 1 + iguana/exchanges/LP_nativeDEX.c | 2 ++ iguana/exchanges/LP_socket.c | 10 +++++++++- iguana/exchanges/LP_utxo.c | 34 +++++++++++++++++++++++++++++++++ iguana/exchanges/mm.c | 1 + 5 files changed, 47 insertions(+), 1 deletion(-) diff --git a/iguana/exchanges/LP_include.h b/iguana/exchanges/LP_include.h index cbbd765ec..eeb6a823a 100644 --- a/iguana/exchanges/LP_include.h +++ b/iguana/exchanges/LP_include.h @@ -379,6 +379,7 @@ int64_t LP_komodo_interest(bits256 txid,int64_t value); 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); int32_t LP_pullsock_check(void *ctx,char **retstrp,char *myipaddr,int32_t pubsock,int32_t pullsock); +void LP_unspents_cache(char *symbol,char *addr,char *arraystr); 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); diff --git a/iguana/exchanges/LP_nativeDEX.c b/iguana/exchanges/LP_nativeDEX.c index 3f7f7ea16..6ae7a566a 100644 --- a/iguana/exchanges/LP_nativeDEX.c +++ b/iguana/exchanges/LP_nativeDEX.c @@ -684,6 +684,7 @@ void LP_initcoins(void *ctx,int32_t pubsock,cJSON *coins) LP_priceinfoadd(activecoins[i]); if ( (coin= LP_coinfind(activecoins[i])) != 0 && LP_getheight(coin) <= 0 ) coin->inactive = (uint32_t)time(NULL); + LP_unspents_load(coin->symbol,coin->smartaddr); } if ( (n= cJSON_GetArraySize(coins)) > 0 ) { @@ -697,6 +698,7 @@ void LP_initcoins(void *ctx,int32_t pubsock,cJSON *coins) LP_priceinfoadd(jstr(item,"coin")); if ( (coin= LP_coinfind(symbol)) != 0 && LP_getheight(coin) <= 0 ) coin->inactive = (uint32_t)time(NULL); + LP_unspents_load(coin->symbol,coin->smartaddr); } } } diff --git a/iguana/exchanges/LP_socket.c b/iguana/exchanges/LP_socket.c index 1b584ac28..19a7b5363 100644 --- a/iguana/exchanges/LP_socket.c +++ b/iguana/exchanges/LP_socket.c @@ -543,7 +543,7 @@ cJSON *electrum_address_getmempool(char *symbol,struct electrum_info *ep,cJSON * cJSON *electrum_address_listunspent(char *symbol,struct electrum_info *ep,cJSON **retjsonp,char *addr,int32_t electrumflag) { - cJSON *retjson=0; struct LP_address *ap; struct iguana_info *coin; int32_t height,usecache=1; + cJSON *retjson=0; char *retstr; struct LP_address *ap; struct iguana_info *coin; int32_t height,usecache=1; if ( (coin= LP_coinfind(symbol)) == 0 ) return(0); if ( ep == 0 || ep->heightp == 0 ) @@ -565,7 +565,15 @@ cJSON *electrum_address_listunspent(char *symbol,struct electrum_info *ep,cJSON { printf("%s.%d u.%u/%d t.%ld %s LISTUNSPENT.(%d)\n",coin->symbol,height,ap->unspenttime,ap->unspentheight,time(NULL),addr,(int32_t)strlen(jprint(retjson,0))); if ( electrum_process_array(coin,ep,addr,retjson,electrumflag) != 0 ) + { LP_postutxos(coin->symbol,addr); + if ( strcmp(addr,coin->smartaddr) == 0 ) + { + retstr = jprint(retjson,0); + LP_unspents_cache(coin->symbol,coin->smartaddr,retstr); + free(retstr); + } + } if ( ap != 0 ) { ap->unspenttime = (uint32_t)time(NULL); diff --git a/iguana/exchanges/LP_utxo.c b/iguana/exchanges/LP_utxo.c index 8a7f0d0b6..ffd5d3f9e 100644 --- a/iguana/exchanges/LP_utxo.c +++ b/iguana/exchanges/LP_utxo.c @@ -981,3 +981,37 @@ int32_t LP_undospends(struct iguana_info *coin,int32_t lastheight) } return(num); } + +void LP_unspents_cache(char *symbol,char *addr,char *arraystr) +{ + char fname[1024]; FILE *fp; + sprintf(fname,"%s/UNSPENTS/%s_%s",GLOBAL_DBDIR,symbol,addr), OS_portable_path(fname); + if ( (fp= fopen(fname,"wb")) != 0 ) + { + fwrite(arraystr,1,strlen(arraystr),fp); + fclose(fp); + } +} + +void LP_unspents_load(char *symbol,char *addr) +{ + char fname[1024],*arraystr; long fsize; struct iguana_info *coin; cJSON *retjson; + if ( (coin= LP_coinfind(symbol)) != 0 ) + { + sprintf(fname,"%s/UNSPENTS/%s_%s",GLOBAL_DBDIR,symbol,addr), OS_portable_path(fname); + if ( (arraystr= OS_filestr(&fsize,fname)) != 0 ) + { + if ( (retjson= cJSON_Parse(arraystr)) != 0 ) + { + if ( electrum_process_array(coin,coin->electrum,coin->smartaddr,retjson,1) == 0 ) + printf("error electrum_process_array\n"); + else printf("processed %s\n",arraystr); + free_json(retjson); + } + free(arraystr); + } + } +} + + + diff --git a/iguana/exchanges/mm.c b/iguana/exchanges/mm.c index 632ab794d..b5cc4404e 100644 --- a/iguana/exchanges/mm.c +++ b/iguana/exchanges/mm.c @@ -882,6 +882,7 @@ int main(int argc, const char * argv[]) sprintf(dirname,"%s",GLOBAL_DBDIR), OS_ensure_directory(dirname); sprintf(dirname,"%s/SWAPS",GLOBAL_DBDIR), OS_ensure_directory(dirname); sprintf(dirname,"%s/PRICES",GLOBAL_DBDIR), OS_ensure_directory(dirname); + sprintf(dirname,"%s/UNSPENTS",GLOBAL_DBDIR), OS_ensure_directory(dirname); #ifdef FROM_JS argc = 2; retjson = cJSON_Parse("{\"client\":1,\"passphrase\":\"test\"}"); From 010a80c9c277896fe475d8c74d5fafa871dd0ba0 Mon Sep 17 00:00:00 2001 From: jl777 Date: Thu, 2 Nov 2017 11:49:52 +0200 Subject: [PATCH 0112/1664] Test --- iguana/exchanges/LP_socket.c | 12 +++++------- 1 file changed, 5 insertions(+), 7 deletions(-) diff --git a/iguana/exchanges/LP_socket.c b/iguana/exchanges/LP_socket.c index 19a7b5363..f2e91f2a8 100644 --- a/iguana/exchanges/LP_socket.c +++ b/iguana/exchanges/LP_socket.c @@ -565,14 +565,12 @@ cJSON *electrum_address_listunspent(char *symbol,struct electrum_info *ep,cJSON { printf("%s.%d u.%u/%d t.%ld %s LISTUNSPENT.(%d)\n",coin->symbol,height,ap->unspenttime,ap->unspentheight,time(NULL),addr,(int32_t)strlen(jprint(retjson,0))); if ( electrum_process_array(coin,ep,addr,retjson,electrumflag) != 0 ) - { LP_postutxos(coin->symbol,addr); - if ( strcmp(addr,coin->smartaddr) == 0 ) - { - retstr = jprint(retjson,0); - LP_unspents_cache(coin->symbol,coin->smartaddr,retstr); - free(retstr); - } + if ( strcmp(addr,coin->smartaddr) == 0 ) + { + retstr = jprint(retjson,0); + LP_unspents_cache(coin->symbol,coin->smartaddr,retstr); + free(retstr); } if ( ap != 0 ) { From 34fc21fa6b983e7f5ec4682b288b8700e6440b31 Mon Sep 17 00:00:00 2001 From: jl777 Date: Thu, 2 Nov 2017 11:56:33 +0200 Subject: [PATCH 0113/1664] Test --- iguana/exchanges/LP_include.h | 2 +- iguana/exchanges/LP_socket.c | 7 ++++--- iguana/exchanges/LP_utxo.c | 7 +++++-- 3 files changed, 10 insertions(+), 6 deletions(-) diff --git a/iguana/exchanges/LP_include.h b/iguana/exchanges/LP_include.h index eeb6a823a..870628dc9 100644 --- a/iguana/exchanges/LP_include.h +++ b/iguana/exchanges/LP_include.h @@ -379,7 +379,7 @@ int64_t LP_komodo_interest(bits256 txid,int64_t value); 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); int32_t LP_pullsock_check(void *ctx,char **retstrp,char *myipaddr,int32_t pubsock,int32_t pullsock); -void LP_unspents_cache(char *symbol,char *addr,char *arraystr); +void LP_unspents_cache(char *symbol,char *addr,char *arraystr,int32_t updatedflag); 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); diff --git a/iguana/exchanges/LP_socket.c b/iguana/exchanges/LP_socket.c index f2e91f2a8..87bb1560e 100644 --- a/iguana/exchanges/LP_socket.c +++ b/iguana/exchanges/LP_socket.c @@ -543,7 +543,7 @@ cJSON *electrum_address_getmempool(char *symbol,struct electrum_info *ep,cJSON * cJSON *electrum_address_listunspent(char *symbol,struct electrum_info *ep,cJSON **retjsonp,char *addr,int32_t electrumflag) { - cJSON *retjson=0; char *retstr; struct LP_address *ap; struct iguana_info *coin; int32_t height,usecache=1; + cJSON *retjson=0; char *retstr; struct LP_address *ap; struct iguana_info *coin; int32_t updatedflag,height,usecache=1; if ( (coin= LP_coinfind(symbol)) == 0 ) return(0); if ( ep == 0 || ep->heightp == 0 ) @@ -564,12 +564,13 @@ 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("%s.%d u.%u/%d t.%ld %s LISTUNSPENT.(%d)\n",coin->symbol,height,ap->unspenttime,ap->unspentheight,time(NULL),addr,(int32_t)strlen(jprint(retjson,0))); + updatedflag = 0; if ( electrum_process_array(coin,ep,addr,retjson,electrumflag) != 0 ) - LP_postutxos(coin->symbol,addr); + LP_postutxos(coin->symbol,addr), updatedflag = 1; if ( strcmp(addr,coin->smartaddr) == 0 ) { retstr = jprint(retjson,0); - LP_unspents_cache(coin->symbol,coin->smartaddr,retstr); + LP_unspents_cache(coin->symbol,coin->smartaddr,retstr,updatedflag); free(retstr); } if ( ap != 0 ) diff --git a/iguana/exchanges/LP_utxo.c b/iguana/exchanges/LP_utxo.c index ffd5d3f9e..39e414aff 100644 --- a/iguana/exchanges/LP_utxo.c +++ b/iguana/exchanges/LP_utxo.c @@ -982,11 +982,14 @@ int32_t LP_undospends(struct iguana_info *coin,int32_t lastheight) return(num); } -void LP_unspents_cache(char *symbol,char *addr,char *arraystr) +void LP_unspents_cache(char *symbol,char *addr,char *arraystr,int32_t updatedflag) { char fname[1024]; FILE *fp; sprintf(fname,"%s/UNSPENTS/%s_%s",GLOBAL_DBDIR,symbol,addr), OS_portable_path(fname); - if ( (fp= fopen(fname,"wb")) != 0 ) + if ( updatedflag == 0 && (fp= fopen(fname,"rb")) == 0 ) + updatedflag = 1; + else fclose(fp); + if ( updatedflag != 0 && (fp= fopen(fname,"wb")) != 0 ) { fwrite(arraystr,1,strlen(arraystr),fp); fclose(fp); From 35b9ac68b7108103c1946e2f84e0299a739aaff7 Mon Sep 17 00:00:00 2001 From: jl777 Date: Thu, 2 Nov 2017 11:58:58 +0200 Subject: [PATCH 0114/1664] Test --- iguana/exchanges/LP_utxo.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/iguana/exchanges/LP_utxo.c b/iguana/exchanges/LP_utxo.c index 39e414aff..30f6a0ab7 100644 --- a/iguana/exchanges/LP_utxo.c +++ b/iguana/exchanges/LP_utxo.c @@ -984,11 +984,12 @@ int32_t LP_undospends(struct iguana_info *coin,int32_t lastheight) void LP_unspents_cache(char *symbol,char *addr,char *arraystr,int32_t updatedflag) { - char fname[1024]; FILE *fp; + char fname[1024]; FILE *fp=0; sprintf(fname,"%s/UNSPENTS/%s_%s",GLOBAL_DBDIR,symbol,addr), OS_portable_path(fname); if ( updatedflag == 0 && (fp= fopen(fname,"rb")) == 0 ) updatedflag = 1; - else fclose(fp); + else if ( fp != 0 ) + fclose(fp); if ( updatedflag != 0 && (fp= fopen(fname,"wb")) != 0 ) { fwrite(arraystr,1,strlen(arraystr),fp); @@ -1006,6 +1007,7 @@ void LP_unspents_load(char *symbol,char *addr) { if ( (retjson= cJSON_Parse(arraystr)) != 0 ) { + printf("PROCESS UNSPENTS %s\n",arraystr); if ( electrum_process_array(coin,coin->electrum,coin->smartaddr,retjson,1) == 0 ) printf("error electrum_process_array\n"); else printf("processed %s\n",arraystr); From b7adbcad8b0f55a866a40d24cf34ce952fee5a88 Mon Sep 17 00:00:00 2001 From: jl777 Date: Thu, 2 Nov 2017 12:10:52 +0200 Subject: [PATCH 0115/1664] Test --- iguana/exchanges/LP_commands.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/iguana/exchanges/LP_commands.c b/iguana/exchanges/LP_commands.c index 0dbd7c350..515138f3f 100644 --- a/iguana/exchanges/LP_commands.c +++ b/iguana/exchanges/LP_commands.c @@ -337,6 +337,8 @@ bot_resume(botid)\n\ { ptr->inactive = 0; cJSON *array = cJSON_CreateArray(); + if ( ptr->smartaddr[0] != 0 ) + LP_unspents_load(coin,ptr->smartaddr); jaddi(array,LP_coinjson(ptr,0)); return(jprint(array,1)); } else return(clonestr("{\"error\":\"coin port conflicts with existing coin\"}")); From 9d33f4f7e4855df1f60bec802f77fc67c6c92ed6 Mon Sep 17 00:00:00 2001 From: jl777 Date: Thu, 2 Nov 2017 12:17:21 +0200 Subject: [PATCH 0116/1664] Test --- iguana/exchanges/LP_socket.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/iguana/exchanges/LP_socket.c b/iguana/exchanges/LP_socket.c index 87bb1560e..55e30ade7 100644 --- a/iguana/exchanges/LP_socket.c +++ b/iguana/exchanges/LP_socket.c @@ -410,8 +410,8 @@ cJSON *electrum_submit(char *symbol,struct electrum_info *ep,cJSON **retjsonp,ch } } else printf("couldnt find electrum server for (%s %s) or no retjsonp.%p\n",method,params,retjsonp); ep = ep->prev; - if ( ep != 0 ) - printf("using prev ep.%s\n",ep->symbol); + //if ( ep != 0 ) + // printf("using prev ep.%s\n",ep->symbol); } return(0); } @@ -563,7 +563,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("%s.%d u.%u/%d t.%ld %s LISTUNSPENT.(%d)\n",coin->symbol,height,ap->unspenttime,ap->unspentheight,time(NULL),addr,(int32_t)strlen(jprint(retjson,0))); + //printf("%s.%d u.%u/%d t.%ld %s LISTUNSPENT.(%d)\n",coin->symbol,height,ap->unspenttime,ap->unspentheight,time(NULL),addr,(int32_t)strlen(jprint(retjson,0))); updatedflag = 0; if ( electrum_process_array(coin,ep,addr,retjson,electrumflag) != 0 ) LP_postutxos(coin->symbol,addr), updatedflag = 1; From abb7a8ff3e7e10a93c615d9294b03c514d08ed98 Mon Sep 17 00:00:00 2001 From: jl777 Date: Thu, 2 Nov 2017 12:25:44 +0200 Subject: [PATCH 0117/1664] Test --- iguana/exchanges/LP_signatures.c | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) diff --git a/iguana/exchanges/LP_signatures.c b/iguana/exchanges/LP_signatures.c index c300bf3e8..32d02000b 100644 --- a/iguana/exchanges/LP_signatures.c +++ b/iguana/exchanges/LP_signatures.c @@ -528,21 +528,20 @@ int32_t LP_pubkey_sigcheck(struct LP_pubkeyinfo *pubp,cJSON *item) { if ( memcmp(rmd160,pubp->rmd160,20) != 0 ) { - for (i=0; i<20; i++) - printf("%02x",pubp->rmd160[i]); + //for (i=0; i<20; i++) + // printf("%02x",pubp->rmd160[i]); memcpy(pubp->rmd160,rmd160,sizeof(pubp->rmd160)); memcpy(pubp->pubsecp,pubsecp,sizeof(pubp->pubsecp)); memcpy(pubp->sig,sig,sizeof(pubp->sig)); pubp->siglen = siglen; - char str[65]; printf(" -> rmd160.(%s) for %s (%s) sig.%s\n",hexstr,bits256_str(str,pubp->pubkey),pubsecpstr,sigstr); - //pubp->timestamp = (uint32_t)time(NULL); + //char str[65]; printf(" -> rmd160.(%s) for %s (%s) sig.%s\n",hexstr,bits256_str(str,pubp->pubkey),pubsecpstr,sigstr); } pubp->timestamp = juint(item,"timestamp"); retval = 0; } else pubp->numerrors++; } } - else + else if ( 0 ) { for (i=0; i<20; i++) printf("%02x",rmd160[i]); From b740c7727f39e38de175e7110dbb4fb65093dbf5 Mon Sep 17 00:00:00 2001 From: jl777 Date: Thu, 2 Nov 2017 13:35:37 +0200 Subject: [PATCH 0118/1664] Test --- iguana/exchanges/LP_include.h | 1 + iguana/exchanges/LP_nativeDEX.c | 13 +++++++++++-- iguana/exchanges/LP_socket.c | 3 ++- 3 files changed, 14 insertions(+), 3 deletions(-) diff --git a/iguana/exchanges/LP_include.h b/iguana/exchanges/LP_include.h index 870628dc9..efce3fe4b 100644 --- a/iguana/exchanges/LP_include.h +++ b/iguana/exchanges/LP_include.h @@ -40,6 +40,7 @@ void emscripten_usleep(int32_t x); // returns immediate, no sense for sleeping #define LP_HTTP_TIMEOUT 3 // 1 is too small due to edge cases of time(NULL) #define LP_AUTOTRADE_TIMEOUT 15 #define ELECTRUM_TIMEOUT 10 +#define LP_ELECTRUM_KEEPALIVE 60 #define LP_ELECTRUM_MAXERRORS 777 #define LP_MEMPOOL_TIMEINCR 10 diff --git a/iguana/exchanges/LP_nativeDEX.c b/iguana/exchanges/LP_nativeDEX.c index 6ae7a566a..d8ff7961c 100644 --- a/iguana/exchanges/LP_nativeDEX.c +++ b/iguana/exchanges/LP_nativeDEX.c @@ -19,7 +19,6 @@ // marketmaker // // electrum keepalive -// merge bots + portfoliot // verify portfolio, interest to KMD withdraw // dPoW security -> 4: KMD notarized, 5: BTC notarized, after next notary elections // bigendian architectures need to use little endian for sighash calcs @@ -494,7 +493,7 @@ int32_t LP_utxos_sync(struct LP_peerinfo *peer) void LP_coinsloop(void *_coins) { - struct LP_address *ap=0,*atmp; 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; 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; while ( 1 ) { nonz = 0; @@ -548,6 +547,16 @@ void LP_coinsloop(void *_coins) } } } + while ( ep != 0 ) + { + if ( time(NULL) > ep->keepalive+LP_ELECTRUM_KEEPALIVE ) + { + printf("%s electrum.%p needs a keepalive: lag.%d\n",ep->symbol,ep,(int32_t)(time(NULL) - ep->keepalive)); + if ( (retjson= electrum_donation(ep->symbol,ep,&retjson)) != 0 ) + free_json(retjson); + } + ep = ep->prev; + } continue; } if ( coin->firstrefht == 0 ) diff --git a/iguana/exchanges/LP_socket.c b/iguana/exchanges/LP_socket.c index 55e30ade7..16da1a0c3 100644 --- a/iguana/exchanges/LP_socket.c +++ b/iguana/exchanges/LP_socket.c @@ -245,7 +245,7 @@ struct electrum_info struct electrum_info *prev; int32_t bufsize,sock,*heightp,numerrors; struct iguana_info *coin; - uint32_t stratumid,lasttime,pending,*heighttimep; + uint32_t stratumid,lasttime,keepalive,pending,*heighttimep; char ipaddr[64],symbol[16]; uint16_t port; uint8_t buf[]; @@ -931,6 +931,7 @@ void LP_dedicatedloop(void *arg) ep->sock = -1; break; } + ep->keepalive = (uint32_t)time(NULL); if ( sitem->expiration != 0 ) sitem->expiration += (uint32_t)time(NULL); else sitem->expiration = (uint32_t)time(NULL) + ELECTRUM_TIMEOUT; From e8172dcb0e742fa837757f7a23ff793c6a58bb2b Mon Sep 17 00:00:00 2001 From: jl777 Date: Thu, 2 Nov 2017 14:39:03 +0200 Subject: [PATCH 0119/1664] Test --- iguana/exchanges/LP_nativeDEX.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/iguana/exchanges/LP_nativeDEX.c b/iguana/exchanges/LP_nativeDEX.c index d8ff7961c..58f14293b 100644 --- a/iguana/exchanges/LP_nativeDEX.c +++ b/iguana/exchanges/LP_nativeDEX.c @@ -18,7 +18,6 @@ // LP_nativeDEX.c // marketmaker // -// electrum keepalive // verify portfolio, interest to KMD withdraw // dPoW security -> 4: KMD notarized, 5: BTC notarized, after next notary elections // bigendian architectures need to use little endian for sighash calcs @@ -551,7 +550,7 @@ void LP_coinsloop(void *_coins) { if ( time(NULL) > ep->keepalive+LP_ELECTRUM_KEEPALIVE ) { - printf("%s electrum.%p needs a keepalive: lag.%d\n",ep->symbol,ep,(int32_t)(time(NULL) - ep->keepalive)); + //printf("%s electrum.%p needs a keepalive: lag.%d\n",ep->symbol,ep,(int32_t)(time(NULL) - ep->keepalive)); if ( (retjson= electrum_donation(ep->symbol,ep,&retjson)) != 0 ) free_json(retjson); } From 8ea9f5b14a4fecbd357cd235c7e708e415b20ad9 Mon Sep 17 00:00:00 2001 From: DeckerSU Date: Thu, 2 Nov 2017 16:42:10 +0400 Subject: [PATCH 0120/1664] dexscripts for Windows samples (see how_to_use.md) --- iguana/dexscripts.win32/1-client.cmd | 16 ++++++++++++ iguana/dexscripts.win32/2-getuserpass.cmd | 7 +++++ iguana/dexscripts.win32/balance.cmd | 4 +++ iguana/dexscripts.win32/curl.exe | Bin 0 -> 2803200 bytes iguana/dexscripts.win32/enable.cmd | 4 +++ iguana/dexscripts.win32/getcoin.cmd | 4 +++ iguana/dexscripts.win32/getutxos.cmd | 4 +++ iguana/dexscripts.win32/how_to_use.md | 24 ++++++++++++++++++ iguana/dexscripts.win32/images/userpass.png | Bin 0 -> 17834 bytes .../images/userpass_usage.png | Bin 0 -> 10940 bytes iguana/dexscripts.win32/inventory.cmd | 4 +++ iguana/dexscripts.win32/listunspent.cmd | 4 +++ iguana/dexscripts.win32/orderbook.cmd | 4 +++ iguana/dexscripts.win32/passphrase | 1 + iguana/dexscripts.win32/portfolio.cmd | 4 +++ iguana/dexscripts.win32/snapshot.cmd | 5 ++++ iguana/dexscripts.win32/userpass | 0 17 files changed, 85 insertions(+) create mode 100644 iguana/dexscripts.win32/1-client.cmd create mode 100644 iguana/dexscripts.win32/2-getuserpass.cmd create mode 100644 iguana/dexscripts.win32/balance.cmd create mode 100644 iguana/dexscripts.win32/curl.exe create mode 100644 iguana/dexscripts.win32/enable.cmd create mode 100644 iguana/dexscripts.win32/getcoin.cmd create mode 100644 iguana/dexscripts.win32/getutxos.cmd create mode 100644 iguana/dexscripts.win32/how_to_use.md create mode 100644 iguana/dexscripts.win32/images/userpass.png create mode 100644 iguana/dexscripts.win32/images/userpass_usage.png create mode 100644 iguana/dexscripts.win32/inventory.cmd create mode 100644 iguana/dexscripts.win32/listunspent.cmd create mode 100644 iguana/dexscripts.win32/orderbook.cmd create mode 100644 iguana/dexscripts.win32/passphrase create mode 100644 iguana/dexscripts.win32/portfolio.cmd create mode 100644 iguana/dexscripts.win32/snapshot.cmd create mode 100644 iguana/dexscripts.win32/userpass diff --git a/iguana/dexscripts.win32/1-client.cmd b/iguana/dexscripts.win32/1-client.cmd new file mode 100644 index 000000000..21bec2717 --- /dev/null +++ b/iguana/dexscripts.win32/1-client.cmd @@ -0,0 +1,16 @@ +@echo off +set USERHOME=%APPDATA:\=\\% +rem [!] Coins config now taked from coins.json file, no need to put in environment variable +rem --------------------------------------------------------------------------------------- +rem set COINS=[{\"coin\":\"REVS\",\"active\":1,\"asset\":\"REVS\",\"rpcport\":10196}] +rem marketmaker "{\"gui\":\"nogui\",\"client\":1, \"userhome\":\"%USERHOME%\", \"passphrase\":\"mypassphrase\", \"coins\":%COINS%}" + +set COINS=\"\" +set /p PASSPHRASE= marketmaker.log 2>&1 +marketmaker "{\"gui\":\"nogui\",\"client\":1, \"userhome\":\"%USERHOME%\", \"passphrase\":\"%PASSPHRASE%\"}" + + + + diff --git a/iguana/dexscripts.win32/2-getuserpass.cmd b/iguana/dexscripts.win32/2-getuserpass.cmd new file mode 100644 index 000000000..87e633339 --- /dev/null +++ b/iguana/dexscripts.win32/2-getuserpass.cmd @@ -0,0 +1,7 @@ +@echo off +curl --url "http://127.0.0.1:7783" --data "{\"userpass\":null,\"method\":\"enable\",\"coin\":\" \"}" -s > userpass.json +for /f "tokens=2 delims=:," %%a in (' find "userpass" "userpass.json" ') do ( +echo UserPass: %%~a +echo %%~a > userpass +) +del userpass.json \ No newline at end of file diff --git a/iguana/dexscripts.win32/balance.cmd b/iguana/dexscripts.win32/balance.cmd new file mode 100644 index 000000000..551d1234a --- /dev/null +++ b/iguana/dexscripts.win32/balance.cmd @@ -0,0 +1,4 @@ +@echo off +set /p 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%0D?xTUDWtSrIDVF{}Mf*0rYee^k@V<+T=67ah*Vv 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�=FqhMB4WOk5sd<&^8 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%0DT`zS&P!fn|$Ag`2}uUkR7g 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�P+|2@H{d4 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

vwNk9 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

g+BQN6i(R%_vRyP=5Q3$3QYG>{1{B{M23hY0 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¥nG_K&L4nj=ZvLasA#||%3fVmT*K|rVD_VL zCo$@0as0TxP8guBu#FuW@*ocqUc**j32oV1qQdyK0`%>+1d;{0a<>~ydR1C zgrGlwoe-0?pY@LS%=c7d2?vPck3&0~y7Mtv#webW+S%$x8^fGmsx!B#3okr1@>=lA zN6y}*f~=wy_v84A@dF}3rhCa?5WxuqRj

QLjb?Eb3N9f%5aOjl%kr^q!SEwEBl% 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

B=$?*Wc%Y-N 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�l~ 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%0AE6wE@RhkD^z_aJ_t9+fj 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 literal 0 HcmV?d00001 diff --git a/iguana/dexscripts.win32/images/userpass_usage.png b/iguana/dexscripts.win32/images/userpass_usage.png new file mode 100644 index 0000000000000000000000000000000000000000..157251a4b8b29ca9769f3ee4cb9b7db7f389a652 GIT binary patch literal 10940 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 VoX7qKOn Date: Thu, 2 Nov 2017 15:44:27 +0300 Subject: [PATCH 0121/1664] Update how_to_use.md --- iguana/dexscripts.win32/how_to_use.md | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/iguana/dexscripts.win32/how_to_use.md b/iguana/dexscripts.win32/how_to_use.md index 0332e145a..82eb5b7e5 100644 --- a/iguana/dexscripts.win32/how_to_use.md +++ b/iguana/dexscripts.win32/how_to_use.md @@ -1,15 +1,15 @@ ## DexScripts for Windows. How to use? ## -**1. ** Before start you should put scripts and following binaries into one folder: +**1.** Before start you should put scripts and following binaries into one folder: - curl.exe (required for all scripts) - marketmaker.exe - libcurl.dll (required to run marketmaker) - nanomsg.dll (required to run marketmaker) -**2. ** Don't forget to put `coins.json` file into a same folder. This file is available it this repo. +**2.** Don't forget to put `coins.json` file into a same folder. This file is available it this repo. -**3. ** Type your passphrase into passphrase file in this folder (you should create file with name `passphrase` and without extension) and run `1-client.cmd`. This will run marketmaker. Next step is to obtain userpass needed for other scripts, you can simply copy and paste it from marketmaker output on startup into userpass file. +**3.** Type your passphrase into passphrase file in this folder (you should create file with name `passphrase` and without extension) and run `1-client.cmd`. This will run marketmaker. Next step is to obtain userpass needed for other scripts, you can simply copy and paste it from marketmaker output on startup into userpass file. ![](./images/userpass.png) @@ -21,4 +21,4 @@ Sample output of correct `2-getuserpass.cmd` usage is: You should see your userpass on screen, and after it will automatically copied in userpass file. It's important to all other scripts to have this password in userpass file. If output of `2-getuserpass.cmd` is not same as showed on screen above - wait some seconds and run `2-getuserpass.cmd` again. Also make sure that you have allowed marketmaker to accept incoming connections in your Windows Firewall (first time launched system should automatically asked for it). -**4.** For using other scripts please refer to barterDEX API. Or **barterDEX API Summary by Category** document by *shossain*. \ No newline at end of file +**4.** For using other scripts please refer to barterDEX API. Or **barterDEX API Summary by Category** document by *shossain*. From 8ff6f8e3936353edf418fa1a0d04c42a0f6395ba Mon Sep 17 00:00:00 2001 From: jl777 Date: Thu, 2 Nov 2017 17:10:06 +0200 Subject: [PATCH 0122/1664] Test --- iguana/exchanges/LP_RTmetrics.c | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/iguana/exchanges/LP_RTmetrics.c b/iguana/exchanges/LP_RTmetrics.c index c44c86dbe..7e97391c0 100644 --- a/iguana/exchanges/LP_RTmetrics.c +++ b/iguana/exchanges/LP_RTmetrics.c @@ -190,18 +190,22 @@ double _LP_RTmetric_calc(struct LP_metricinfo *mp,double bestprice,double maxpri if ( relvolume < mp->minvol ) { metric *= (mp->minvol / relvolume); + printf("relvolume < minvol %.8f\n",(mp->minvol / relvolume)); } else if ( relvolume > mp->maxvol ) { metric *= (relvolume / mp->maxvol); + printf("relvolume > minvol %.8f\n",(relvolume / mp->maxvol)); } if ( relvolume < mp->balance/LP_MINVOL ) { metric *= (mp->balance / relvolume); + printf("relvolume < balance %.8f\n",(mp->balance / relvolume)); } else if ( relvolume > mp->balance/mp->numutxos ) { metric *= (relvolume / (mp->balance/mp->numutxos)); + printf("relvolume < ave %.8f\n",(relvolume / (mp->balance/mp->numutxos))); } if ( mp->age > LP_ORDERBOOK_DURATION*0.8 ) metric *= 2; From dd4c32d78d828a5a44e1670079d3d59289cff9e4 Mon Sep 17 00:00:00 2001 From: jl777 Date: Thu, 2 Nov 2017 17:20:46 +0200 Subject: [PATCH 0123/1664] Test --- iguana/exchanges/LP_RTmetrics.c | 16 +++++++++++++++- 1 file changed, 15 insertions(+), 1 deletion(-) diff --git a/iguana/exchanges/LP_RTmetrics.c b/iguana/exchanges/LP_RTmetrics.c index 7e97391c0..023ae343f 100644 --- a/iguana/exchanges/LP_RTmetrics.c +++ b/iguana/exchanges/LP_RTmetrics.c @@ -233,6 +233,19 @@ void LP_RTmetric_calc(struct LP_metricinfo *sortbuf,int32_t ind,cJSON *item,doub sortbuf[ind].metric = _LP_RTmetric_calc(&sortbuf[ind],bestprice,maxprice,relvolume); } +int _increasing_metrics(const void *a,const void *b) +{ +#define ptr_a (*(struct LP_metricinfo **)a) +#define ptr_b (*(struct LP_metricinfo **)b) + if ( ptr_b->metric > ptr_a->metric ) + return(-1); + else if ( ptr_b->metric < ptr_a->metric ) + return(1); + return(0); +#undef ptr_a +#undef ptr_b +} + cJSON *LP_RTmetrics_sort(char *base,char *rel,cJSON *rawasks,int32_t numasks,double maxprice,double relvolume) { cJSON *array=rawasks,*item; int32_t i,num,groupi; double price,prevdepth,bestprice; struct LP_metricinfo *sortbuf; @@ -259,8 +272,9 @@ cJSON *LP_RTmetrics_sort(char *base,char *rel,cJSON *rawasks,int32_t numasks,dou item = jitem(rawasks,i); LP_RTmetric_calc(sortbuf,i,item,bestprice,maxprice,relvolume,prevdepth); prevdepth = jdouble(item,"depth"); + printf("%.8f ",sortbuf[i].metric); } - revsortds(&sortbuf[0].metric,groupi+1,sizeof(*sortbuf)); + qsort(&sortbuf[0].metric,groupi+1,sizeof(*sortbuf),_increasing_metrics); array = cJSON_CreateArray(); for (i=0; i<=groupi; i++) { From 5ac74b73ae50cd8c31748baecdbbbb4e9e3e19ba Mon Sep 17 00:00:00 2001 From: jl777 Date: Thu, 2 Nov 2017 17:25:30 +0200 Subject: [PATCH 0124/1664] Test --- iguana/exchanges/LP_RTmetrics.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/iguana/exchanges/LP_RTmetrics.c b/iguana/exchanges/LP_RTmetrics.c index 023ae343f..31479b8ce 100644 --- a/iguana/exchanges/LP_RTmetrics.c +++ b/iguana/exchanges/LP_RTmetrics.c @@ -235,8 +235,8 @@ void LP_RTmetric_calc(struct LP_metricinfo *sortbuf,int32_t ind,cJSON *item,doub int _increasing_metrics(const void *a,const void *b) { -#define ptr_a (*(struct LP_metricinfo **)a) -#define ptr_b (*(struct LP_metricinfo **)b) +#define ptr_a ((struct LP_metricinfo *)a) +#define ptr_b ((struct LP_metricinfo *)b) if ( ptr_b->metric > ptr_a->metric ) return(-1); else if ( ptr_b->metric < ptr_a->metric ) From 897afd3a6be99d052faf42e700f33803ea3cade4 Mon Sep 17 00:00:00 2001 From: jl777 Date: Thu, 2 Nov 2017 17:36:31 +0200 Subject: [PATCH 0125/1664] Test --- iguana/exchanges/LP_RTmetrics.c | 4 ++-- iguana/exchanges/LP_tradebots.c | 7 ++++--- 2 files changed, 6 insertions(+), 5 deletions(-) diff --git a/iguana/exchanges/LP_RTmetrics.c b/iguana/exchanges/LP_RTmetrics.c index 31479b8ce..e38ed8861 100644 --- a/iguana/exchanges/LP_RTmetrics.c +++ b/iguana/exchanges/LP_RTmetrics.c @@ -272,13 +272,13 @@ cJSON *LP_RTmetrics_sort(char *base,char *rel,cJSON *rawasks,int32_t numasks,dou item = jitem(rawasks,i); LP_RTmetric_calc(sortbuf,i,item,bestprice,maxprice,relvolume,prevdepth); prevdepth = jdouble(item,"depth"); - printf("%.8f ",sortbuf[i].metric); + //printf("%.8f ",sortbuf[i].metric); } qsort(&sortbuf[0].metric,groupi+1,sizeof(*sortbuf),_increasing_metrics); array = cJSON_CreateArray(); for (i=0; i<=groupi; i++) { - printf("(%d -> %d %.3f) ",i,sortbuf[i].ind,sortbuf[i].metric); + printf("(%d <- %d %.3f) ",i,sortbuf[i].ind,sortbuf[i].metric); item = jitem(rawasks,sortbuf[i].ind); jaddi(array,jduplicate(item)); } diff --git a/iguana/exchanges/LP_tradebots.c b/iguana/exchanges/LP_tradebots.c index fc7cc2cb9..f3b5b35fb 100644 --- a/iguana/exchanges/LP_tradebots.c +++ b/iguana/exchanges/LP_tradebots.c @@ -259,7 +259,7 @@ struct LP_tradebot_trade *LP_tradebot_pending(struct LP_tradebot *bot,cJSON *pen void LP_tradebot_timeslice(void *ctx,struct LP_tradebot *bot) { - double remaining; uint32_t tradeid; bits256 destpubkey; char *retstr,*liststr; cJSON *retjson,*retjson2,*pending; + double remaining; int32_t i,maxiters = 10; uint32_t tradeid; bits256 destpubkey; char *retstr,*liststr; cJSON *retjson,*retjson2,*pending; memset(destpubkey.bytes,0,sizeof(destpubkey)); if ( bot->dead == 0 && bot->pause == 0 && bot->numtrades < sizeof(bot->trades)/sizeof(*bot->trades) ) { @@ -272,7 +272,8 @@ void LP_tradebot_timeslice(void *ctx,struct LP_tradebot *bot) remaining = bot->totalrelvolume - (bot->relsum + bot->pendrelsum); printf("try autobuy %s/%s remaining %.8f maxprice %.8f\n",bot->base,bot->rel,remaining,bot->maxprice); tradeid = rand(); - if ( (retstr= LP_autobuy(ctx,LP_myipaddr,LP_mypubsock,bot->base,bot->rel,bot->maxprice,remaining,0,0,G.gui,0,destpubkey,tradeid)) != 0 ) + for (i=1; i<=maxiters; i++) + if ( (retstr= LP_autobuy(ctx,LP_myipaddr,LP_mypubsock,bot->base,bot->rel,bot->maxprice,remaining/i,0,0,G.gui,0,destpubkey,tradeid)) != 0 ) { if ( (retjson2= cJSON_Parse(retstr)) != 0 ) { @@ -285,7 +286,7 @@ void LP_tradebot_timeslice(void *ctx,struct LP_tradebot *bot) bot->pause = (uint32_t)time(NULL); } else printf("didnt get any trade pending %s %s\n\n",bot->name,retstr); free_json(retjson2); - } else printf("%s\n",retstr); + } else printf("iter.%d/%d %s\n",i,maxiters,retstr); free(retstr); } } From fc1d374ed1e45aeaca7da85c68d7a995e5a1b784 Mon Sep 17 00:00:00 2001 From: jl777 Date: Thu, 2 Nov 2017 17:50:11 +0200 Subject: [PATCH 0126/1664] Test --- iguana/exchanges/LP_RTmetrics.c | 10 +++++----- iguana/exchanges/LP_tradebots.c | 26 ++++++++++++++------------ 2 files changed, 19 insertions(+), 17 deletions(-) diff --git a/iguana/exchanges/LP_RTmetrics.c b/iguana/exchanges/LP_RTmetrics.c index e38ed8861..e8d0ba09e 100644 --- a/iguana/exchanges/LP_RTmetrics.c +++ b/iguana/exchanges/LP_RTmetrics.c @@ -184,28 +184,28 @@ double _LP_RTmetric_calc(struct LP_metricinfo *mp,double bestprice,double maxpri metric = origmetric; if ( mp->numutxos == 0 || relvolume == 0. || mp->maxvol == 0. || mp->balance == 0. ) { - printf("skip i.%d as no info\n",mp->ind); + //printf("skip i.%d as no info\n",mp->ind); return(metric * 100.); } if ( relvolume < mp->minvol ) { metric *= (mp->minvol / relvolume); - printf("relvolume < minvol %.8f\n",(mp->minvol / relvolume)); + //printf("relvolume < minvol %.8f\n",(mp->minvol / relvolume)); } else if ( relvolume > mp->maxvol ) { metric *= (relvolume / mp->maxvol); - printf("relvolume > minvol %.8f\n",(relvolume / mp->maxvol)); + //printf("relvolume > minvol %.8f\n",(relvolume / mp->maxvol)); } if ( relvolume < mp->balance/LP_MINVOL ) { metric *= (mp->balance / relvolume); - printf("relvolume < balance %.8f\n",(mp->balance / relvolume)); + //printf("relvolume < balance %.8f\n",(mp->balance / relvolume)); } else if ( relvolume > mp->balance/mp->numutxos ) { metric *= (relvolume / (mp->balance/mp->numutxos)); - printf("relvolume < ave %.8f\n",(relvolume / (mp->balance/mp->numutxos))); + //printf("relvolume < ave %.8f\n",(relvolume / (mp->balance/mp->numutxos))); } if ( mp->age > LP_ORDERBOOK_DURATION*0.8 ) metric *= 2; diff --git a/iguana/exchanges/LP_tradebots.c b/iguana/exchanges/LP_tradebots.c index f3b5b35fb..69ada5bd1 100644 --- a/iguana/exchanges/LP_tradebots.c +++ b/iguana/exchanges/LP_tradebots.c @@ -273,21 +273,23 @@ void LP_tradebot_timeslice(void *ctx,struct LP_tradebot *bot) printf("try autobuy %s/%s remaining %.8f maxprice %.8f\n",bot->base,bot->rel,remaining,bot->maxprice); tradeid = rand(); for (i=1; i<=maxiters; i++) - if ( (retstr= LP_autobuy(ctx,LP_myipaddr,LP_mypubsock,bot->base,bot->rel,bot->maxprice,remaining/i,0,0,G.gui,0,destpubkey,tradeid)) != 0 ) { - if ( (retjson2= cJSON_Parse(retstr)) != 0 ) + if ( (retstr= LP_autobuy(ctx,LP_myipaddr,LP_mypubsock,bot->base,bot->rel,bot->maxprice,remaining/i,0,0,G.gui,0,destpubkey,tradeid)) != 0 ) { - if ( (pending= jobj(retjson2,"pending")) != 0 && juint(pending,"tradeid") == tradeid ) + if ( (retjson2= cJSON_Parse(retstr)) != 0 ) { - bot->trades[bot->numtrades++] = LP_tradebot_pending(bot,pending,tradeid); - if ( bot->relsum >= 0.99*bot->totalrelvolume-SMALLVAL || bot->basesum >= 0.99*bot->totalbasevolume-SMALLVAL ) - bot->dead = (uint32_t)time(NULL); - else if ( (bot->pendrelsum+bot->relsum) >= 0.99*bot->totalrelvolume-SMALLVAL || (bot->basesum+bot->pendbasesum) >= 0.99*bot->totalbasevolume-SMALLVAL ) - bot->pause = (uint32_t)time(NULL); - } else printf("didnt get any trade pending %s %s\n\n",bot->name,retstr); - free_json(retjson2); - } else printf("iter.%d/%d %s\n",i,maxiters,retstr); - free(retstr); + if ( (pending= jobj(retjson2,"pending")) != 0 && juint(pending,"tradeid") == tradeid ) + { + bot->trades[bot->numtrades++] = LP_tradebot_pending(bot,pending,tradeid); + if ( bot->relsum >= 0.99*bot->totalrelvolume-SMALLVAL || bot->basesum >= 0.99*bot->totalbasevolume-SMALLVAL ) + bot->dead = (uint32_t)time(NULL); + else if ( (bot->pendrelsum+bot->relsum) >= 0.99*bot->totalrelvolume-SMALLVAL || (bot->basesum+bot->pendbasesum) >= 0.99*bot->totalbasevolume-SMALLVAL ) + bot->pause = (uint32_t)time(NULL); + } else printf("iter.%d/%d %.8f didnt get any trade pending %s %s\n\n",i,maxiters,remaining/i,bot->name,retstr); + free_json(retjson2); + } else printf("iter.%d/%d %.8f %s\n",i,maxiters,remaining/i,retstr); + free(retstr); + } } } free_json(retjson); From 8ff41a367b723a9fb1ffc15a16c2f0ac0625c975 Mon Sep 17 00:00:00 2001 From: jl777 Date: Thu, 2 Nov 2017 17:51:33 +0200 Subject: [PATCH 0127/1664] Test --- iguana/exchanges/LP_tradebots.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/iguana/exchanges/LP_tradebots.c b/iguana/exchanges/LP_tradebots.c index 69ada5bd1..eee996965 100644 --- a/iguana/exchanges/LP_tradebots.c +++ b/iguana/exchanges/LP_tradebots.c @@ -315,7 +315,7 @@ void LP_tradebot_finished(uint32_t tradeid,uint32_t requestid,uint32_t quoteid) bot->pendbasesum -= tp->basevol, bot->basesum += tp->basevol; bot->pendrelsum -= tp->relvol, bot->relsum += tp->relvol; bot->numpending--, bot->completed++; - printf("bot.%u detected completion tradeid.%u aliceid.%llx r.%u q.%u\n",bot->id,tp->tradeid,(long long)tp->aliceid,tp->requestid,tp->quoteid); + printf("bot.%u detected completion tradeid.%u aliceid.%llx r.%u q.%u, numpending.%d completed.%d\n",bot->id,tp->tradeid,(long long)tp->aliceid,tp->requestid,tp->quoteid,bot->numpending,bot->completed); tp->finished = (uint32_t)time(NULL); break; } From 1389cfe1003abac1ae3a0072facb56c31bc1cfb8 Mon Sep 17 00:00:00 2001 From: jl777 Date: Thu, 2 Nov 2017 17:56:10 +0200 Subject: [PATCH 0128/1664] Test --- iguana/exchanges/LP_tradebots.c | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/iguana/exchanges/LP_tradebots.c b/iguana/exchanges/LP_tradebots.c index eee996965..60bdcf986 100644 --- a/iguana/exchanges/LP_tradebots.c +++ b/iguana/exchanges/LP_tradebots.c @@ -285,6 +285,10 @@ void LP_tradebot_timeslice(void *ctx,struct LP_tradebot *bot) bot->dead = (uint32_t)time(NULL); else if ( (bot->pendrelsum+bot->relsum) >= 0.99*bot->totalrelvolume-SMALLVAL || (bot->basesum+bot->pendbasesum) >= 0.99*bot->totalbasevolume-SMALLVAL ) bot->pause = (uint32_t)time(NULL); + printf("issued bot trade.%u\n",tradeid); + free_json(retjson2); + free(retstr); + break; } else printf("iter.%d/%d %.8f didnt get any trade pending %s %s\n\n",i,maxiters,remaining/i,bot->name,retstr); free_json(retjson2); } else printf("iter.%d/%d %.8f %s\n",i,maxiters,remaining/i,retstr); @@ -367,7 +371,7 @@ char *LP_tradebot_list(void *ctx,int32_t pubsock,cJSON *argjson) char *LP_tradebot_buy(int32_t dispdir,char *base,char *rel,double maxprice,double relvolume) { - struct LP_tradebot *bot; double shortfall; int32_t i,n; cJSON *array,*item,*retjson; uint64_t txfees,balance=0,abalance=0; struct iguana_info *basecoin,*relcoin; + struct LP_tradebot *bot; char *retstr; double shortfall; int32_t i,n; cJSON *array,*item,*retjson; uint64_t txfees,balance=0,abalance=0; struct iguana_info *basecoin,*relcoin; basecoin = LP_coinfind(base); relcoin = LP_coinfind(rel); if ( basecoin == 0 || relcoin == 0 || basecoin->inactive != 0 || relcoin->inactive != 0 ) @@ -384,6 +388,8 @@ char *LP_tradebot_buy(int32_t dispdir,char *base,char *rel,double maxprice,doubl } free_json(array); } + if ( (retstr= LP_orderbook(base,rel,0)) != 0 ) + free(retstr); txfees = 10 * relcoin->txfee; printf("%s inventory balance %.8f, relvolume %.8f + txfees %.8f\n",rel,dstr(abalance),relvolume,dstr(txfees)); if ( dstr(abalance) < relvolume + dstr(txfees) ) From 14adbda69d9c3894189d0f02e5d683df9928b3cd Mon Sep 17 00:00:00 2001 From: jl777 Date: Thu, 2 Nov 2017 18:04:42 +0200 Subject: [PATCH 0129/1664] Test --- iguana/exchanges/LP_ordermatch.c | 2 +- iguana/exchanges/LP_tradebots.c | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/iguana/exchanges/LP_ordermatch.c b/iguana/exchanges/LP_ordermatch.c index 6becabca6..4ae2274a7 100644 --- a/iguana/exchanges/LP_ordermatch.c +++ b/iguana/exchanges/LP_ordermatch.c @@ -304,7 +304,7 @@ struct LP_utxoinfo *LP_address_utxopair(int32_t iambob,struct LP_address_utxo ** } } } //else printf("cant find targetval2 %.8f\n",dstr(targetval2)); - } else printf("failed ratio test %.8f\n",(double)up->U.value/targetval); + } //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); } //else printf("no %s utxos pass LP_address_utxo_ptrs filter\n",coinaddr); diff --git a/iguana/exchanges/LP_tradebots.c b/iguana/exchanges/LP_tradebots.c index 60bdcf986..f340ac6f6 100644 --- a/iguana/exchanges/LP_tradebots.c +++ b/iguana/exchanges/LP_tradebots.c @@ -285,7 +285,7 @@ void LP_tradebot_timeslice(void *ctx,struct LP_tradebot *bot) bot->dead = (uint32_t)time(NULL); else if ( (bot->pendrelsum+bot->relsum) >= 0.99*bot->totalrelvolume-SMALLVAL || (bot->basesum+bot->pendbasesum) >= 0.99*bot->totalbasevolume-SMALLVAL ) bot->pause = (uint32_t)time(NULL); - printf("issued bot trade.%u\n",tradeid); + printf("issued bot trade.%u %s\n",tradeid,retstr); free_json(retjson2); free(retstr); break; From e5f7f667230dfae994307aaf0d55b510206411b2 Mon Sep 17 00:00:00 2001 From: jl777 Date: Thu, 2 Nov 2017 18:18:41 +0200 Subject: [PATCH 0130/1664] Test --- iguana/exchanges/LP_RTmetrics.c | 2 +- iguana/exchanges/LP_ordermatch.c | 2 +- iguana/exchanges/LP_transaction.c | 6 +++--- 3 files changed, 5 insertions(+), 5 deletions(-) diff --git a/iguana/exchanges/LP_RTmetrics.c b/iguana/exchanges/LP_RTmetrics.c index e8d0ba09e..54d9300bd 100644 --- a/iguana/exchanges/LP_RTmetrics.c +++ b/iguana/exchanges/LP_RTmetrics.c @@ -175,7 +175,7 @@ void LP_RTmetrics_update(char *base,char *rel) char str[65]; printf("%s has %d pending swaps! which is more than %d\n",bits256_str(str,LP_RTmetrics.pending_pubkeys[i]),LP_RTmetrics.pending_swaps[i],LP_MAXPENDING_SWAPS); LP_RTmetrics_blacklistadd(LP_RTmetrics.pending_pubkeys[i]); } - printf("%d pubkeys have pending swaps, whitelist.%d blacklist.%d avoidtxids.%d\n",LP_RTmetrics.numpendings,LP_RTmetrics.numwhitelist,LP_RTmetrics.numblacklist,LP_RTmetrics.numavoidtxids); + //printf("%d pubkeys have pending swaps, whitelist.%d blacklist.%d avoidtxids.%d\n",LP_RTmetrics.numpendings,LP_RTmetrics.numwhitelist,LP_RTmetrics.numblacklist,LP_RTmetrics.numavoidtxids); } double _LP_RTmetric_calc(struct LP_metricinfo *mp,double bestprice,double maxprice,double relvolume) diff --git a/iguana/exchanges/LP_ordermatch.c b/iguana/exchanges/LP_ordermatch.c index 4ae2274a7..f035fc7d0 100644 --- a/iguana/exchanges/LP_ordermatch.c +++ b/iguana/exchanges/LP_ordermatch.c @@ -915,7 +915,7 @@ char *LP_autobuy(void *ctx,char *myipaddr,int32_t mypubsock,char *base,char *rel { destsatoshis -= 2*desttxfee; autxo->S.satoshis = destsatoshis; - printf("first path dest %.8f from %.8f\n",dstr(destsatoshis),dstr(autxo->S.satoshis)); + //printf("first path dest %.8f from %.8f\n",dstr(destsatoshis),dstr(autxo->S.satoshis)); } else if ( autxo->S.satoshis - 2*desttxfee < destsatoshis ) { diff --git a/iguana/exchanges/LP_transaction.c b/iguana/exchanges/LP_transaction.c index 50fee8dcb..95b999e72 100644 --- a/iguana/exchanges/LP_transaction.c +++ b/iguana/exchanges/LP_transaction.c @@ -643,10 +643,10 @@ char *basilisk_swap_bobtxspend(bits256 *signedtxidp,uint64_t txfee,char *name,ch { if ( value < satoshis+txfee ) { - if ( satoshis > value-txfee/2 ) + if ( (value-satoshis) > 3*txfee/4 ) { - satoshis = value - txfee; - printf("reduce satoshis by txfee %.8f to %.8f\n",dstr(txfee),dstr(satoshis)); + satoshis = value - 3*txfee/4; + printf("reduce satoshis %.8f by txfee %.8f to value %.8f\n",dstr(satoshis),dstr(txfee),dstr(value)); } else { From 3854c1081cd78a952d053a256e0d89393e8b86ef Mon Sep 17 00:00:00 2001 From: jl777 Date: Thu, 2 Nov 2017 18:32:48 +0200 Subject: [PATCH 0131/1664] Test --- iguana/exchanges/LP_ordermatch.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/iguana/exchanges/LP_ordermatch.c b/iguana/exchanges/LP_ordermatch.c index f035fc7d0..cc1307485 100644 --- a/iguana/exchanges/LP_ordermatch.c +++ b/iguana/exchanges/LP_ordermatch.c @@ -292,7 +292,7 @@ struct LP_utxoinfo *LP_address_utxopair(int32_t iambob,struct LP_address_utxo ** if ( (double)up->U.value/targetval < LP_MINVOL-1 ) { - if ( (mini= LP_nearest_utxovalue(coin,coinaddr,utxos,m,targetval2 * 1.01)) >= 0 ) + if ( (mini= LP_nearest_utxovalue(coin,coinaddr,utxos,m,(targetval2+2*txfee) * 1.01)) >= 0 ) { if ( up != 0 && (up2= utxos[mini]) != 0 ) { From 1c0f84c4af5334ceb7dbc43f35c9794f64c2bed6 Mon Sep 17 00:00:00 2001 From: jl777 Date: Thu, 2 Nov 2017 18:51:02 +0200 Subject: [PATCH 0132/1664] Test --- iguana/exchanges/LP_tradebots.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/iguana/exchanges/LP_tradebots.c b/iguana/exchanges/LP_tradebots.c index f340ac6f6..d758e6350 100644 --- a/iguana/exchanges/LP_tradebots.c +++ b/iguana/exchanges/LP_tradebots.c @@ -353,7 +353,7 @@ void LP_tradebots_timeslice(void *ctx) } } } - else if ( bot->numpending == 0 ) + else //if ( bot->numpending == 0 ) LP_tradebot_timeslice(ctx,bot); } lastnumfinished = LP_numfinished; From 73ab11303dd8185ebbeefdb3ba08a230fbf36755 Mon Sep 17 00:00:00 2001 From: jl777 Date: Thu, 2 Nov 2017 18:58:34 +0200 Subject: [PATCH 0133/1664] Test --- iguana/exchanges/LP_ordermatch.c | 1 + iguana/exchanges/LP_tradebots.c | 2 +- 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/iguana/exchanges/LP_ordermatch.c b/iguana/exchanges/LP_ordermatch.c index cc1307485..1b66f4180 100644 --- a/iguana/exchanges/LP_ordermatch.c +++ b/iguana/exchanges/LP_ordermatch.c @@ -965,6 +965,7 @@ char *LP_autobuy(void *ctx,char *myipaddr,int32_t mypubsock,char *base,char *rel continue; else return(clonestr("{\"error\":\"cant ordermatch to destpubkey\"}")); } + printf("i.%d maxiters.%d qprice %.8f vs maxprice %.8f\n",i,maxiters,dstr(qprice),dstr(maxprice)); return(LP_trade(ctx,myipaddr,mypubsock,&Q,maxprice,timeout,duration,tradeid)); } return(clonestr("{\"error\":\"cant get here\"}")); diff --git a/iguana/exchanges/LP_tradebots.c b/iguana/exchanges/LP_tradebots.c index d758e6350..f340ac6f6 100644 --- a/iguana/exchanges/LP_tradebots.c +++ b/iguana/exchanges/LP_tradebots.c @@ -353,7 +353,7 @@ void LP_tradebots_timeslice(void *ctx) } } } - else //if ( bot->numpending == 0 ) + else if ( bot->numpending == 0 ) LP_tradebot_timeslice(ctx,bot); } lastnumfinished = LP_numfinished; From f6ee03aa51adbf1f97339f352a556a0526d82443 Mon Sep 17 00:00:00 2001 From: jl777 Date: Thu, 2 Nov 2017 19:42:16 +0200 Subject: [PATCH 0134/1664] Test --- iguana/exchanges/LP_nativeDEX.c | 18 ++++++++++++------ 1 file changed, 12 insertions(+), 6 deletions(-) diff --git a/iguana/exchanges/LP_nativeDEX.c b/iguana/exchanges/LP_nativeDEX.c index 58f14293b..64f0a152a 100644 --- a/iguana/exchanges/LP_nativeDEX.c +++ b/iguana/exchanges/LP_nativeDEX.c @@ -690,9 +690,12 @@ void LP_initcoins(void *ctx,int32_t pubsock,cJSON *coins) printf("%s ",activecoins[i]); LP_coinfind(activecoins[i]); LP_priceinfoadd(activecoins[i]); - if ( (coin= LP_coinfind(activecoins[i])) != 0 && LP_getheight(coin) <= 0 ) - coin->inactive = (uint32_t)time(NULL); - LP_unspents_load(coin->symbol,coin->smartaddr); + if ( (coin= LP_coinfind(activecoins[i])) != 0 ) + { + if ( LP_getheight(coin) <= 0 ) + coin->inactive = (uint32_t)time(NULL); + LP_unspents_load(coin->symbol,coin->smartaddr); + } } if ( (n= cJSON_GetArraySize(coins)) > 0 ) { @@ -704,9 +707,12 @@ void LP_initcoins(void *ctx,int32_t pubsock,cJSON *coins) printf("%s ",jstr(item,"coin")); LP_coincreate(item); LP_priceinfoadd(jstr(item,"coin")); - if ( (coin= LP_coinfind(symbol)) != 0 && LP_getheight(coin) <= 0 ) - coin->inactive = (uint32_t)time(NULL); - LP_unspents_load(coin->symbol,coin->smartaddr); + if ( (coin= LP_coinfind(symbol)) != 0 ) + { + if ( LP_getheight(coin) <= 0 ) + coin->inactive = (uint32_t)time(NULL); + LP_unspents_load(coin->symbol,coin->smartaddr); + } } } } From 1067640169aac3ea95ea884139a5950302579f7b Mon Sep 17 00:00:00 2001 From: jl777 Date: Thu, 2 Nov 2017 20:10:51 +0200 Subject: [PATCH 0135/1664] Test --- iguana/exchanges/LP_nativeDEX.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/iguana/exchanges/LP_nativeDEX.c b/iguana/exchanges/LP_nativeDEX.c index 64f0a152a..6597389f0 100644 --- a/iguana/exchanges/LP_nativeDEX.c +++ b/iguana/exchanges/LP_nativeDEX.c @@ -765,9 +765,9 @@ void LP_pubkeysloop(void *ctx) while ( 1 ) { LP_counter += 100; - //printf("LP_pubkeysloop %d\n",LP_counter); + printf("LP_pubkeysloop %d\n",LP_counter); LP_notify_pubkeys(ctx,LP_mypubsock); - sleep(LP_ORDERBOOK_DURATION * .777); + sleep(60); } } From f478e4c893d0ee06595907b50a9f78a906200c56 Mon Sep 17 00:00:00 2001 From: jl777 Date: Thu, 2 Nov 2017 20:18:32 +0200 Subject: [PATCH 0136/1664] Test --- iguana/exchanges/LP_nativeDEX.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/iguana/exchanges/LP_nativeDEX.c b/iguana/exchanges/LP_nativeDEX.c index 6597389f0..aea16362d 100644 --- a/iguana/exchanges/LP_nativeDEX.c +++ b/iguana/exchanges/LP_nativeDEX.c @@ -765,7 +765,7 @@ void LP_pubkeysloop(void *ctx) while ( 1 ) { LP_counter += 100; - printf("LP_pubkeysloop %d\n",LP_counter); + //printf("LP_pubkeysloop %d\n",LP_counter); LP_notify_pubkeys(ctx,LP_mypubsock); sleep(60); } From 25a2a7df5135f59e871ef03a618c4ba7e395b04f Mon Sep 17 00:00:00 2001 From: jl777 Date: Thu, 2 Nov 2017 20:29:16 +0200 Subject: [PATCH 0137/1664] Test --- iguana/exchanges/LP_nativeDEX.c | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) diff --git a/iguana/exchanges/LP_nativeDEX.c b/iguana/exchanges/LP_nativeDEX.c index aea16362d..4ddda76f3 100644 --- a/iguana/exchanges/LP_nativeDEX.c +++ b/iguana/exchanges/LP_nativeDEX.c @@ -761,13 +761,17 @@ void LP_initpeers(int32_t pubsock,struct LP_peerinfo *mypeer,char *myipaddr,uint void LP_pubkeysloop(void *ctx) { + static uint32_t lasttime; sleep(10); while ( 1 ) { - LP_counter += 100; - //printf("LP_pubkeysloop %d\n",LP_counter); - LP_notify_pubkeys(ctx,LP_mypubsock); - sleep(60); + if ( time(NULL) > lasttime+60 ) + { + printf("LP_pubkeysloop %u\n",(uint32_t)time(NULL)); + LP_notify_pubkeys(ctx,LP_mypubsock); + lasttime = (uint32_t)time(NULL); + } + sleep(3); } } From 0a764e40c53ffebe161f90585dfb826942f69658 Mon Sep 17 00:00:00 2001 From: jl777 Date: Thu, 2 Nov 2017 20:39:15 +0200 Subject: [PATCH 0138/1664] Test --- iguana/exchanges/LP_nativeDEX.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/iguana/exchanges/LP_nativeDEX.c b/iguana/exchanges/LP_nativeDEX.c index 4ddda76f3..83dae1016 100644 --- a/iguana/exchanges/LP_nativeDEX.c +++ b/iguana/exchanges/LP_nativeDEX.c @@ -767,7 +767,7 @@ void LP_pubkeysloop(void *ctx) { if ( time(NULL) > lasttime+60 ) { - printf("LP_pubkeysloop %u\n",(uint32_t)time(NULL)); + //printf("LP_pubkeysloop %u\n",(uint32_t)time(NULL)); LP_notify_pubkeys(ctx,LP_mypubsock); lasttime = (uint32_t)time(NULL); } From a2188d77ed374a93ff029eefe51bac58746f2d2b Mon Sep 17 00:00:00 2001 From: jl777 Date: Thu, 2 Nov 2017 20:49:34 +0200 Subject: [PATCH 0139/1664] Test --- iguana/exchanges/LP_nativeDEX.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/iguana/exchanges/LP_nativeDEX.c b/iguana/exchanges/LP_nativeDEX.c index 83dae1016..665bc3cb9 100644 --- a/iguana/exchanges/LP_nativeDEX.c +++ b/iguana/exchanges/LP_nativeDEX.c @@ -514,6 +514,8 @@ void LP_coinsloop(void *_coins) memset(&zero,0,sizeof(zero)); if ( coin->inactive != 0 ) continue; + if ( coin->longestchain == 1 ) // special init value + coin->longestchain = LP_getheight(coin); if ( (ep= coin->electrum) != 0 ) { if ( (backupep= ep->prev) == 0 ) From 6e48a5372777af1fb33180f1d292ea68b86728bf Mon Sep 17 00:00:00 2001 From: jl777 Date: Thu, 2 Nov 2017 21:06:28 +0200 Subject: [PATCH 0140/1664] Test --- iguana/exchanges/LP_swap.c | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/iguana/exchanges/LP_swap.c b/iguana/exchanges/LP_swap.c index 41c65f031..bedec1175 100644 --- a/iguana/exchanges/LP_swap.c +++ b/iguana/exchanges/LP_swap.c @@ -1090,32 +1090,32 @@ struct basilisk_swap *bitcoin_swapinit(bits256 privkey,uint8_t *pubkey33,bits256 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 ) { - basilisk_rawtx_setparms("myfee",swap->I.req.quoteid,&swap->myfee,&swap->bobcoin,0,0,LP_DEXFEE(swap->I.bobsatoshis) + swap->bobcoin.txfee,0,0,jumblrflag); - basilisk_rawtx_setparms("otherfee",swap->I.req.quoteid,&swap->otherfee,&swap->alicecoin,0,0,LP_DEXFEE(swap->I.alicesatoshis) + swap->alicecoin.txfee,0,0,jumblrflag); + basilisk_rawtx_setparms("myfee",swap->I.req.quoteid,&swap->myfee,&swap->bobcoin,0,0,LP_DEXFEE(swap->I.bobsatoshis) + 0*swap->bobcoin.txfee,0,0,jumblrflag); + basilisk_rawtx_setparms("otherfee",swap->I.req.quoteid,&swap->otherfee,&swap->alicecoin,0,0,LP_DEXFEE(swap->I.alicesatoshis) + 0*swap->alicecoin.txfee,0,0,jumblrflag); bobpub33 = pubkey33; } else { - basilisk_rawtx_setparms("otherfee",swap->I.req.quoteid,&swap->otherfee,&swap->bobcoin,0,0,LP_DEXFEE(swap->I.bobsatoshis) + swap->bobcoin.txfee,0,0,jumblrflag); - basilisk_rawtx_setparms("myfee",swap->I.req.quoteid,&swap->myfee,&swap->alicecoin,0,0,LP_DEXFEE(swap->I.alicesatoshis) + swap->alicecoin.txfee,0,0,jumblrflag); + basilisk_rawtx_setparms("otherfee",swap->I.req.quoteid,&swap->otherfee,&swap->bobcoin,0,0,LP_DEXFEE(swap->I.bobsatoshis) + 0*swap->bobcoin.txfee,0,0,jumblrflag); + basilisk_rawtx_setparms("myfee",swap->I.req.quoteid,&swap->myfee,&swap->alicecoin,0,0,LP_DEXFEE(swap->I.alicesatoshis) + 0*swap->alicecoin.txfee,0,0,jumblrflag); alicepub33 = pubkey33; } swap->myfee.I.locktime = swap->I.started + 1; swap->otherfee.I.locktime = swap->I.started + 1; - basilisk_rawtx_setparms("bobdeposit",swap->I.req.quoteid,&swap->bobdeposit,&swap->bobcoin,swap->I.bobconfirms,0,LP_DEPOSITSATOSHIS(swap->I.bobsatoshis) + swap->bobcoin.txfee,4,0,jumblrflag); + basilisk_rawtx_setparms("bobdeposit",swap->I.req.quoteid,&swap->bobdeposit,&swap->bobcoin,swap->I.bobconfirms,0,LP_DEPOSITSATOSHIS(swap->I.bobsatoshis) + 0*swap->bobcoin.txfee,4,0,jumblrflag); basilisk_rawtx_setparms("bobrefund",swap->I.req.quoteid,&swap->bobrefund,&swap->bobcoin,1,4,LP_DEPOSITSATOSHIS(swap->I.bobsatoshis),1,bobpub33,jumblrflag); swap->bobrefund.I.suppress_pubkeys = 1; basilisk_rawtx_setparms("aliceclaim",swap->I.req.quoteid,&swap->aliceclaim,&swap->bobcoin,1,4,LP_DEPOSITSATOSHIS(swap->I.bobsatoshis),1,alicepub33,jumblrflag); swap->aliceclaim.I.suppress_pubkeys = 1; swap->aliceclaim.I.locktime = swap->I.started + swap->I.putduration+swap->I.callduration + 1; - basilisk_rawtx_setparms("bobpayment",swap->I.req.quoteid,&swap->bobpayment,&swap->bobcoin,swap->I.bobconfirms,0,swap->I.bobsatoshis + swap->bobcoin.txfee,3,0,jumblrflag); + basilisk_rawtx_setparms("bobpayment",swap->I.req.quoteid,&swap->bobpayment,&swap->bobcoin,swap->I.bobconfirms,0,swap->I.bobsatoshis + 0*swap->bobcoin.txfee,3,0,jumblrflag); basilisk_rawtx_setparms("alicespend",swap->I.req.quoteid,&swap->alicespend,&swap->bobcoin,swap->I.bobconfirms,3,swap->I.bobsatoshis,1,alicepub33,jumblrflag); swap->alicespend.I.suppress_pubkeys = 1; basilisk_rawtx_setparms("bobreclaim",swap->I.req.quoteid,&swap->bobreclaim,&swap->bobcoin,swap->I.bobconfirms,3,swap->I.bobsatoshis,1,bobpub33,jumblrflag); swap->bobreclaim.I.suppress_pubkeys = 1; swap->bobreclaim.I.locktime = swap->I.started + swap->I.putduration + 1; - basilisk_rawtx_setparms("alicepayment",swap->I.req.quoteid,&swap->alicepayment,&swap->alicecoin,swap->I.aliceconfirms,0,swap->I.alicesatoshis+swap->alicecoin.txfee,2,0,jumblrflag); + basilisk_rawtx_setparms("alicepayment",swap->I.req.quoteid,&swap->alicepayment,&swap->alicecoin,swap->I.aliceconfirms,0,swap->I.alicesatoshis + 0*swap->alicecoin.txfee,2,0,jumblrflag); basilisk_rawtx_setparms("bobspend",swap->I.req.quoteid,&swap->bobspend,&swap->alicecoin,swap->I.aliceconfirms,2,swap->I.alicesatoshis,1,bobpub33,jumblrflag); swap->bobspend.I.suppress_pubkeys = 1; basilisk_rawtx_setparms("alicereclaim",swap->I.req.quoteid,&swap->alicereclaim,&swap->alicecoin,swap->I.aliceconfirms,2,swap->I.alicesatoshis,1,alicepub33,jumblrflag); From b83df06c3f47f5b8549d14dd6fc50f610273c28f Mon Sep 17 00:00:00 2001 From: jl777 Date: Thu, 2 Nov 2017 21:12:27 +0200 Subject: [PATCH 0141/1664] Test --- crypto777/iguana_OS.c | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/crypto777/iguana_OS.c b/crypto777/iguana_OS.c index c8a7c888f..2000651a9 100755 --- a/crypto777/iguana_OS.c +++ b/crypto777/iguana_OS.c @@ -901,11 +901,15 @@ void *OS_loadfile(char *fname,char **bufp,long *lenp,long *allocsizep) return(buf); } -void *OS_filestr(long *allocsizep,char *fname) +void *OS_filestr(long *allocsizep,char *_fname) { - long filesize = 0; char *buf = 0; + long filesize = 0; char *fname,*buf = 0; void *retptr; *allocsizep = 0; - return(OS_loadfile(fname,&buf,&filesize,allocsizep)); + fname = malloc(strlen(_fname)+1); + strcpy(fname,_fname); + retptr = OS_loadfile(fname,&buf,&filesize,allocsizep); + free(fname); + return(retptr); } // following functions cant be fully implemented in one or more OS From 120f2b857d2a574bcb2f130bcc8dd8e70dd13b77 Mon Sep 17 00:00:00 2001 From: jl777 Date: Thu, 2 Nov 2017 21:24:20 +0200 Subject: [PATCH 0142/1664] Test --- iguana/exchanges/LP_swap.c | 2 +- iguana/exchanges/LP_transaction.c | 5 +++++ 2 files changed, 6 insertions(+), 1 deletion(-) diff --git a/iguana/exchanges/LP_swap.c b/iguana/exchanges/LP_swap.c index bedec1175..b631f22e6 100644 --- a/iguana/exchanges/LP_swap.c +++ b/iguana/exchanges/LP_swap.c @@ -626,7 +626,7 @@ int32_t LP_rawtx_spendscript(struct basilisk_swap *swap,int32_t height,struct ba txfee = swap->I.Atxfee; else txfee = LP_MIN_TXFEE; } - if ( j64bits(vout,"satoshis") >= rawtx->I.amount && (skey= jobj(vout,"scriptPubKey")) != 0 && (hexstr= jstr(skey,"hex")) != 0 ) + if ( j64bits(vout,"satoshis") >= rawtx->I.amount-txfee && (skey= jobj(vout,"scriptPubKey")) != 0 && (hexstr= jstr(skey,"hex")) != 0 ) { if ( (hexlen= (int32_t)strlen(hexstr) >> 1) < sizeof(rawtx->spendscript) ) { diff --git a/iguana/exchanges/LP_transaction.c b/iguana/exchanges/LP_transaction.c index 95b999e72..1071bf878 100644 --- a/iguana/exchanges/LP_transaction.c +++ b/iguana/exchanges/LP_transaction.c @@ -648,6 +648,11 @@ char *basilisk_swap_bobtxspend(bits256 *signedtxidp,uint64_t txfee,char *name,ch satoshis = value - 3*txfee/4; printf("reduce satoshis %.8f by txfee %.8f to value %.8f\n",dstr(satoshis),dstr(txfee),dstr(value)); } + else if ( value == satoshis && (double)txfee/value < 0.001 ) + { + satoshis = value - txfee; + printf("emergency txfee allocation from value %.8f identical to satoshis: %.8f txfee %.8f\n",dstr(value),dstr(satoshis),dstr(txfee)); + } else { printf("utxo %.8f too small for %.8f + %.8f\n",dstr(value),dstr(satoshis),dstr(txfee)); From 7c8ad66d8d6599d38770cbc133879fda0987d500 Mon Sep 17 00:00:00 2001 From: jl777 Date: Thu, 2 Nov 2017 21:50:23 +0200 Subject: [PATCH 0143/1664] Test --- iguana/exchanges/LP_tradebots.c | 33 ++++++++++++++++++++++++++++++++- 1 file changed, 32 insertions(+), 1 deletion(-) diff --git a/iguana/exchanges/LP_tradebots.c b/iguana/exchanges/LP_tradebots.c index f340ac6f6..9e5e9fd12 100644 --- a/iguana/exchanges/LP_tradebots.c +++ b/iguana/exchanges/LP_tradebots.c @@ -257,9 +257,35 @@ struct LP_tradebot_trade *LP_tradebot_pending(struct LP_tradebot *bot,cJSON *pen return(tp); } +double LP_orderbook_maxrel(char *base,char *rel,double maxprice) +{ + char *retstr; int32_t i,numasks; cJSON *retjson,*asks,*item; double maxvol,maxrel = 0.; + if ( (retstr= LP_orderbook(base,rel,0)) != 0 ) + { + if ( (retjson= cJSON_Parse(retstr)) != 0 ) + { + if ( (asks= jarray(&numasks,retjson,"asks")) != 0 ) + { + for (i=0; i maxprice ) + break; + maxvol = jdouble(item,"maxvolume"); + if ( maxvol > maxrel ) + maxrel = maxvol; + } + } + free_json(retjson); + } + free(retstr); + } + return(maxrel); +} + void LP_tradebot_timeslice(void *ctx,struct LP_tradebot *bot) { - double remaining; int32_t i,maxiters = 10; uint32_t tradeid; bits256 destpubkey; char *retstr,*liststr; cJSON *retjson,*retjson2,*pending; + double remaining,maxrel; int32_t i,maxiters = 10; uint32_t tradeid; bits256 destpubkey; char *retstr,*liststr; cJSON *retjson,*retjson2,*pending; memset(destpubkey.bytes,0,sizeof(destpubkey)); if ( bot->dead == 0 && bot->pause == 0 && bot->numtrades < sizeof(bot->trades)/sizeof(*bot->trades) ) { @@ -271,9 +297,14 @@ void LP_tradebot_timeslice(void *ctx,struct LP_tradebot *bot) { remaining = bot->totalrelvolume - (bot->relsum + bot->pendrelsum); printf("try autobuy %s/%s remaining %.8f maxprice %.8f\n",bot->base,bot->rel,remaining,bot->maxprice); + maxrel = LP_orderbook_maxrel(bot->base,bot->rel,bot->maxprice); + if ( maxrel < remaining ) + remaining = maxrel; tradeid = rand(); for (i=1; i<=maxiters; i++) { + if ( remaining < 0.001 ) + break; if ( (retstr= LP_autobuy(ctx,LP_myipaddr,LP_mypubsock,bot->base,bot->rel,bot->maxprice,remaining/i,0,0,G.gui,0,destpubkey,tradeid)) != 0 ) { if ( (retjson2= cJSON_Parse(retstr)) != 0 ) From e38498bb753a97cfe0c5041f91c4075ad1f63eb1 Mon Sep 17 00:00:00 2001 From: jl777 Date: Thu, 2 Nov 2017 21:58:17 +0200 Subject: [PATCH 0144/1664] Test --- iguana/exchanges/LP_tradebots.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/iguana/exchanges/LP_tradebots.c b/iguana/exchanges/LP_tradebots.c index 9e5e9fd12..defd5e695 100644 --- a/iguana/exchanges/LP_tradebots.c +++ b/iguana/exchanges/LP_tradebots.c @@ -296,8 +296,8 @@ void LP_tradebot_timeslice(void *ctx,struct LP_tradebot *bot) if ( jobj(retjson,"pending") == 0 ) { remaining = bot->totalrelvolume - (bot->relsum + bot->pendrelsum); - printf("try autobuy %s/%s remaining %.8f maxprice %.8f\n",bot->base,bot->rel,remaining,bot->maxprice); maxrel = LP_orderbook_maxrel(bot->base,bot->rel,bot->maxprice); + printf("try autobuy %s/%s remaining %.8f maxprice %.8f maxrel %.8f\n",bot->base,bot->rel,remaining,bot->maxprice,maxrel); if ( maxrel < remaining ) remaining = maxrel; tradeid = rand(); From 16d618499436e6b7fcb89d1fdcbd3e43a33cd50d Mon Sep 17 00:00:00 2001 From: jl777 Date: Thu, 2 Nov 2017 22:04:10 +0200 Subject: [PATCH 0145/1664] Test --- iguana/exchanges/LP_nativeDEX.c | 2 +- iguana/exchanges/LP_tradebots.c | 3 +++ 2 files changed, 4 insertions(+), 1 deletion(-) diff --git a/iguana/exchanges/LP_nativeDEX.c b/iguana/exchanges/LP_nativeDEX.c index 665bc3cb9..4e55cb270 100644 --- a/iguana/exchanges/LP_nativeDEX.c +++ b/iguana/exchanges/LP_nativeDEX.c @@ -585,7 +585,7 @@ void LP_coinsloop(void *_coins) continue; } nonz++; - //if ( (coin->lastscanht % 1000) == 0 ) + if ( coin->lastscanht < coin->longestchain-3 ) printf("[%s]: %s ref.%d scan.%d to %d, longest.%d\n",coins,coin->symbol,coin->firstrefht,coin->firstscanht,coin->lastscanht,coin->longestchain); for (j=0; j<100; j++) { diff --git a/iguana/exchanges/LP_tradebots.c b/iguana/exchanges/LP_tradebots.c index defd5e695..878bd8beb 100644 --- a/iguana/exchanges/LP_tradebots.c +++ b/iguana/exchanges/LP_tradebots.c @@ -262,6 +262,8 @@ double LP_orderbook_maxrel(char *base,char *rel,double maxprice) char *retstr; int32_t i,numasks; cJSON *retjson,*asks,*item; double maxvol,maxrel = 0.; if ( (retstr= LP_orderbook(base,rel,0)) != 0 ) { + + printf("maxprice %.8f %s/%s obook.(%s)\n",maxprice,base,rel,retstr); if ( (retjson= cJSON_Parse(retstr)) != 0 ) { if ( (asks= jarray(&numasks,retjson,"asks")) != 0 ) @@ -272,6 +274,7 @@ double LP_orderbook_maxrel(char *base,char *rel,double maxprice) if ( jdouble(item,"price") > maxprice ) break; maxvol = jdouble(item,"maxvolume"); + printf("%.8f ",maxvol); if ( maxvol > maxrel ) maxrel = maxvol; } From b055b37b0361dbfd0a278d90ec9aff01e7b6e2fd Mon Sep 17 00:00:00 2001 From: jl777 Date: Thu, 2 Nov 2017 22:07:22 +0200 Subject: [PATCH 0146/1664] Test --- iguana/exchanges/LP_tradebots.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/iguana/exchanges/LP_tradebots.c b/iguana/exchanges/LP_tradebots.c index 878bd8beb..aa59fc8ba 100644 --- a/iguana/exchanges/LP_tradebots.c +++ b/iguana/exchanges/LP_tradebots.c @@ -263,18 +263,18 @@ double LP_orderbook_maxrel(char *base,char *rel,double maxprice) if ( (retstr= LP_orderbook(base,rel,0)) != 0 ) { - printf("maxprice %.8f %s/%s obook.(%s)\n",maxprice,base,rel,retstr); + printf("maxprice %.8f %s/%s\n",maxprice,base,rel); if ( (retjson= cJSON_Parse(retstr)) != 0 ) { if ( (asks= jarray(&numasks,retjson,"asks")) != 0 ) { for (i=0; i maxprice ) break; maxvol = jdouble(item,"maxvolume"); - printf("%.8f ",maxvol); + printf("(%s) -> %.8f\n",jprint(item,0),maxvol); if ( maxvol > maxrel ) maxrel = maxvol; } From e2023878e41c76d6639ec8f16429462afdd71d75 Mon Sep 17 00:00:00 2001 From: jl777 Date: Thu, 2 Nov 2017 22:16:53 +0200 Subject: [PATCH 0147/1664] Test --- iguana/exchanges/LP_ordermatch.c | 8 +++++--- iguana/exchanges/LP_tradebots.c | 5 ++--- 2 files changed, 7 insertions(+), 6 deletions(-) diff --git a/iguana/exchanges/LP_ordermatch.c b/iguana/exchanges/LP_ordermatch.c index 1b66f4180..6496038b0 100644 --- a/iguana/exchanges/LP_ordermatch.c +++ b/iguana/exchanges/LP_ordermatch.c @@ -803,7 +803,9 @@ struct LP_utxoinfo *LP_buyutxo(double *ordermatchpricep,int64_t *bestsatoshisp,i { item = jitem(asks,i); price = jdouble(item,"price"); - price *= 1.005; + if ( price/maxprice < .9 ) + price *= 1.025; + else price *= 1.001; pubkey = jbits256(item,"pubkey"); if ( bits256_nonz(destpubkey) != 0 && bits256_cmp(destpubkey,pubkey) != 0 ) continue; @@ -824,8 +826,8 @@ struct LP_utxoinfo *LP_buyutxo(double *ordermatchpricep,int64_t *bestsatoshisp,i { bitcoin_address(coinaddr,basecoin->taddr,basecoin->pubtype,pubp->rmd160,sizeof(pubp->rmd160)); asatoshis = autxo->S.satoshis; - LP_listunspent_query(base,coinaddr); - LP_listunspent_both(base,coinaddr,1); + LP_listunspent_query(base,coinaddr); + //LP_listunspent_both(base,coinaddr,1); for (j=0; jpubkey,gui)) != 0 ) diff --git a/iguana/exchanges/LP_tradebots.c b/iguana/exchanges/LP_tradebots.c index aa59fc8ba..af5f385f8 100644 --- a/iguana/exchanges/LP_tradebots.c +++ b/iguana/exchanges/LP_tradebots.c @@ -262,8 +262,7 @@ double LP_orderbook_maxrel(char *base,char *rel,double maxprice) char *retstr; int32_t i,numasks; cJSON *retjson,*asks,*item; double maxvol,maxrel = 0.; if ( (retstr= LP_orderbook(base,rel,0)) != 0 ) { - - printf("maxprice %.8f %s/%s\n",maxprice,base,rel); + //printf("maxprice %.8f %s/%s\n",maxprice,base,rel); if ( (retjson= cJSON_Parse(retstr)) != 0 ) { if ( (asks= jarray(&numasks,retjson,"asks")) != 0 ) @@ -274,7 +273,7 @@ double LP_orderbook_maxrel(char *base,char *rel,double maxprice) if ( jdouble(item,"price") > maxprice ) break; maxvol = jdouble(item,"maxvolume"); - printf("(%s) -> %.8f\n",jprint(item,0),maxvol); + //printf("(%s) -> %.8f\n",jprint(item,0),maxvol); if ( maxvol > maxrel ) maxrel = maxvol; } From 58c9b201a42019966a1329244144c99972dc66d1 Mon Sep 17 00:00:00 2001 From: jl777 Date: Thu, 2 Nov 2017 22:30:08 +0200 Subject: [PATCH 0148/1664] Test --- iguana/exchanges/LP_include.h | 2 +- iguana/exchanges/LP_ordermatch.c | 8 ++++---- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/iguana/exchanges/LP_include.h b/iguana/exchanges/LP_include.h index efce3fe4b..44f92218c 100644 --- a/iguana/exchanges/LP_include.h +++ b/iguana/exchanges/LP_include.h @@ -38,7 +38,7 @@ void emscripten_usleep(int32_t x); // returns immediate, no sense for sleeping #define LP_MAGICBITS 8 #define LP_HTTP_TIMEOUT 3 // 1 is too small due to edge cases of time(NULL) -#define LP_AUTOTRADE_TIMEOUT 15 +#define LP_AUTOTRADE_TIMEOUT 20 #define ELECTRUM_TIMEOUT 10 #define LP_ELECTRUM_KEEPALIVE 60 #define LP_ELECTRUM_MAXERRORS 777 diff --git a/iguana/exchanges/LP_ordermatch.c b/iguana/exchanges/LP_ordermatch.c index 6496038b0..2792902c4 100644 --- a/iguana/exchanges/LP_ordermatch.c +++ b/iguana/exchanges/LP_ordermatch.c @@ -887,13 +887,13 @@ char *LP_autobuy(void *ctx,char *myipaddr,int32_t mypubsock,char *base,char *rel timeout = LP_AUTOTRADE_TIMEOUT; if ( basecoin->electrum != 0 && relcoin->electrum != 0 ) { - if ( timeout < 3*LP_AUTOTRADE_TIMEOUT ) - timeout = 3*LP_AUTOTRADE_TIMEOUT; + if ( timeout < 2*LP_AUTOTRADE_TIMEOUT ) + timeout = 2*LP_AUTOTRADE_TIMEOUT; } else if ( basecoin->electrum != 0 || relcoin->electrum != 0 ) { - if ( timeout < 2*LP_AUTOTRADE_TIMEOUT ) - timeout = 2*LP_AUTOTRADE_TIMEOUT; + if ( timeout < 1.5*LP_AUTOTRADE_TIMEOUT ) + timeout = 1.5*LP_AUTOTRADE_TIMEOUT; } if ( time(NULL) < Alice_expiration ) return(clonestr("{\"error\":\"only one pending request at a time\"}")); From b6c5a83771731dcb295e168779282c5b57ccd04a Mon Sep 17 00:00:00 2001 From: jl777 Date: Thu, 2 Nov 2017 22:42:28 +0200 Subject: [PATCH 0149/1664] Test --- iguana/exchanges/LP_include.h | 2 +- iguana/exchanges/LP_nativeDEX.c | 37 ++++++++++++++++++++------------ iguana/exchanges/LP_ordermatch.c | 16 ++++++++++---- iguana/exchanges/LP_peers.c | 2 +- iguana/exchanges/LP_prices.c | 2 +- iguana/exchanges/LP_remember.c | 6 ++++-- iguana/exchanges/LP_signatures.c | 10 ++++----- 7 files changed, 47 insertions(+), 28 deletions(-) diff --git a/iguana/exchanges/LP_include.h b/iguana/exchanges/LP_include.h index 44f92218c..c9d15c3b3 100644 --- a/iguana/exchanges/LP_include.h +++ b/iguana/exchanges/LP_include.h @@ -387,7 +387,7 @@ int32_t LP_coinbus(uint16_t coin_busport); int32_t LP_nanomsg_recvs(void *ctx); uint64_t LP_RTsmartbalance(struct iguana_info *coin); int32_t LP_getheight(struct iguana_info *coin); -int32_t LP_reserved_msg(char *base,char *rel,bits256 pubkey,char *msg); +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); diff --git a/iguana/exchanges/LP_nativeDEX.c b/iguana/exchanges/LP_nativeDEX.c index 4e55cb270..bf30e3be5 100644 --- a/iguana/exchanges/LP_nativeDEX.c +++ b/iguana/exchanges/LP_nativeDEX.c @@ -27,8 +27,8 @@ #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,LP_reservedmutex,LP_nanorecvsmutex,LP_tradebotsmutex; int32_t LP_canbind; -char *Broadcaststr,*Reserved_msgs[1000]; -int32_t num_Reserved_msgs,max_Reserved_msgs; +char *Broadcaststr,*Reserved_msgs[2][1000]; +int32_t num_Reserved_msgs[2],max_Reserved_msgs[2]; struct LP_peerinfo *LP_peerinfos,*LP_mypeer; struct LP_forwardinfo *LP_forwardinfos; struct iguana_info *LP_coins; @@ -237,7 +237,7 @@ char *LP_process_message(void *ctx,char *typestr,char *myipaddr,int32_t pubsock, memset(zero.bytes,0,sizeof(zero)); /*if ( (method= jstr(reqjson,"method")) != 0 && (strcmp(method,"request") == 0 || strcmp(method,"requested") == 0 || strcmp(method,"connect") == 0 || strcmp(method,"connected") == 0) ) printf("broadcast.(%s)\n",Broadcaststr);*/ - LP_reserved_msg("","",zero,jprint(reqjson,0)); + LP_reserved_msg(0,"","",zero,jprint(reqjson,0)); } retstr = clonestr("{\"result\":\"success\"}"); free_json(reqjson); @@ -809,7 +809,7 @@ void LP_reserved_msgs(void *ignore) memset(zero.bytes,0,sizeof(zero)); while ( 1 ) { - if ( num_Reserved_msgs > 0 ) + if ( num_Reserved_msgs[0] > 0 || num_Reserved_msgs[1] > 0 ) { flag = 0; if ( LP_mypubsock >= 0 ) @@ -823,9 +823,18 @@ void LP_reserved_msgs(void *ignore) if ( flag == 1 ) { portable_mutex_lock(&LP_reservedmutex); - num_Reserved_msgs--; - LP_broadcast_message(LP_mypubsock,"","",zero,Reserved_msgs[num_Reserved_msgs]); - Reserved_msgs[num_Reserved_msgs] = 0; + if ( num_Reserved_msgs[1] > 0 ) + { + num_Reserved_msgs[1]--; + LP_broadcast_message(LP_mypubsock,"","",zero,Reserved_msgs[1][num_Reserved_msgs[1]]); + Reserved_msgs[1][num_Reserved_msgs[1]] = 0; + } + else if ( num_Reserved_msgs[0] > 0 ) + { + num_Reserved_msgs[0]--; + LP_broadcast_message(LP_mypubsock,"","",zero,Reserved_msgs[0][num_Reserved_msgs[0]]); + Reserved_msgs[0][num_Reserved_msgs[0]] = 0; + } portable_mutex_unlock(&LP_reservedmutex); } } @@ -835,20 +844,20 @@ void LP_reserved_msgs(void *ignore) } } -int32_t LP_reserved_msg(char *base,char *rel,bits256 pubkey,char *msg) +int32_t LP_reserved_msg(int32_t priority,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) ) + if ( num_Reserved_msgs[priority] < sizeof(Reserved_msgs[priority])/sizeof(*Reserved_msgs[priority]) ) { - Reserved_msgs[num_Reserved_msgs++] = msg; - n = num_Reserved_msgs; + Reserved_msgs[priority][num_Reserved_msgs[priority]++] = msg; + n = num_Reserved_msgs[priority]; } else LP_broadcast_message(LP_mypubsock,base,rel,pubkey,msg); portable_mutex_unlock(&LP_reservedmutex); - if ( num_Reserved_msgs > max_Reserved_msgs ) + if ( num_Reserved_msgs[priority] > max_Reserved_msgs[priority] ) { - max_Reserved_msgs = num_Reserved_msgs; - printf("New max_Reserved_msgs.%d\n",max_Reserved_msgs); + max_Reserved_msgs[priority] = num_Reserved_msgs[priority]; + printf("New priority.%d max_Reserved_msgs.%d\n",priority,max_Reserved_msgs[priority]); } return(n); } diff --git a/iguana/exchanges/LP_ordermatch.c b/iguana/exchanges/LP_ordermatch.c index 2792902c4..c91082471 100644 --- a/iguana/exchanges/LP_ordermatch.c +++ b/iguana/exchanges/LP_ordermatch.c @@ -375,8 +375,12 @@ int32_t LP_connectstartbob(void *ctx,int32_t pubsock,struct LP_utxoinfo *utxo,cJ //jaddnum(retjson,"quoteid",qp->R.quoteid); // LP_addsig char str[65]; printf("BOB pubsock.%d binds to %d (%s)\n",pubsock,pair,bits256_str(str,utxo->S.otherpubkey)); - LP_reserved_msg(base,rel,utxo->S.otherpubkey,jprint(retjson,0)); - LP_broadcast_message(LP_mypubsock,qp->srccoin,qp->destcoin,qp->desthash,jprint(retjson,0)); + LP_reserved_msg(1,base,rel,utxo->S.otherpubkey,jprint(retjson,0)); + sleep(1); + bits256 zero; + memset(zero.bytes,0,sizeof(zero)); + LP_reserved_msg(1,base,rel,zero,jprint(retjson,0)); + //LP_broadcast_message(LP_mypubsock,qp->srccoin,qp->destcoin,qp->desthash,jprint(retjson,0)); free_json(retjson); retval = 0; } else printf("error launching swaploop\n"); @@ -734,8 +738,12 @@ int32_t LP_tradecommand(void *ctx,char *myipaddr,int32_t pubsock,cJSON *argjson, printf("return after queued RESERVED: set swappending.%u accept qprice %.8f, min %.8f\n(%s)\n",butxo->T.swappending,qprice,price,msg); // LP_addsig //msg2 = clonestr(msg); - LP_reserved_msg(Q.srccoin,Q.destcoin,butxo->S.otherpubkey,msg); - LP_broadcast_message(LP_mypubsock,Q.srccoin,Q.destcoin,Q.desthash,jprint(retjson,0)); + LP_reserved_msg(1,Q.srccoin,Q.destcoin,butxo->S.otherpubkey,msg); + sleep(1); + bits256 zero; + memset(zero.bytes,0,sizeof(zero)); + LP_reserved_msg(1,Q.srccoin,Q.destcoin,zero,msg); + //LP_broadcast_message(LP_mypubsock,Q.srccoin,Q.destcoin,Q.desthash,jprint(retjson,0)); free_json(retjson); return(retval); } else printf("warning swappending.%u swap.%p\n",butxo->T.swappending,butxo->S.swap); diff --git a/iguana/exchanges/LP_peers.c b/iguana/exchanges/LP_peers.c index 8539fef27..4aaae086d 100644 --- a/iguana/exchanges/LP_peers.c +++ b/iguana/exchanges/LP_peers.c @@ -153,7 +153,7 @@ struct LP_peerinfo *LP_addpeer(struct LP_peerinfo *mypeer,int32_t mypubsock,char 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_reserved_msg("","",zero,jprint(LP_peerjson(peer),1)); + LP_reserved_msg(0,"","",zero,jprint(LP_peerjson(peer),1)); if ( 0 ) { HASH_ITER(hh,LP_coins,coin,ctmp) diff --git a/iguana/exchanges/LP_prices.c b/iguana/exchanges/LP_prices.c index 6cc110671..404cd4f9e 100644 --- a/iguana/exchanges/LP_prices.c +++ b/iguana/exchanges/LP_prices.c @@ -713,7 +713,7 @@ void LP_pubkeys_query() jaddstr(reqjson,"method","wantnotify"); jaddbits256(reqjson,"pub",pubp->pubkey); //printf("LP_pubkeys_query %s\n",jprint(reqjson,0)); - LP_reserved_msg("","",zero,jprint(reqjson,1)); + LP_reserved_msg(0,"","",zero,jprint(reqjson,1)); } } } diff --git a/iguana/exchanges/LP_remember.c b/iguana/exchanges/LP_remember.c index e27a13aab..9fa8cfbd3 100644 --- a/iguana/exchanges/LP_remember.c +++ b/iguana/exchanges/LP_remember.c @@ -1118,8 +1118,10 @@ cJSON *basilisk_remember(int64_t *KMDtotals,int64_t *BTCtotals,uint32_t requesti itemstr = jprint(item,0); fprintf(fp,"%s\n",itemstr); LP_tradecommand_log(item); - LP_reserved_msg(rswap.src,rswap.dest,zero,clonestr(itemstr)); - LP_broadcast_message(LP_mypubsock,rswap.src,rswap.dest,zero,itemstr); + LP_reserved_msg(1,rswap.src,rswap.dest,zero,clonestr(itemstr)); + sleep(1); + LP_reserved_msg(0,rswap.src,rswap.dest,zero,clonestr(itemstr)); + //LP_broadcast_message(LP_mypubsock,rswap.src,rswap.dest,zero,itemstr); fclose(fp); } } diff --git a/iguana/exchanges/LP_signatures.c b/iguana/exchanges/LP_signatures.c index 32d02000b..bc1ad2e81 100644 --- a/iguana/exchanges/LP_signatures.c +++ b/iguana/exchanges/LP_signatures.c @@ -348,7 +348,7 @@ void LP_postutxos(char *symbol,char *coinaddr) //char str[65]; printf("utxoshash add %s\n",bits256_str(str,utxoshash)); LP_utxos_sigadd(reqjson,timestamp,G.LP_privkey,G.LP_pubsecp,G.LP_mypub25519,utxoshash); //printf("post (%s) -> %d\n",msg,LP_mypubsock); - LP_reserved_msg(symbol,symbol,zero,jprint(reqjson,1)); + LP_reserved_msg(0,symbol,symbol,zero,jprint(reqjson,1)); } } } @@ -463,7 +463,7 @@ char *LP_pricepings(void *ctx,char *myipaddr,int32_t pubsock,char *base,char *re init_hexbytes_noT(pubsecpstr,G.LP_pubsecp,33); jaddstr(reqjson,"pubsecp",pubsecpstr); LP_price_sigadd(reqjson,timestamp,G.LP_privkey,G.LP_pubsecp,G.LP_mypub25519,base,rel,price64); - LP_reserved_msg(base,rel,zero,jprint(reqjson,1)); + LP_reserved_msg(0,base,rel,zero,jprint(reqjson,1)); return(clonestr("{\"result\":\"success\"}")); } else return(clonestr("{\"error\":\"electrum node cant post bob asks\"}")); } @@ -569,7 +569,7 @@ void LP_notify_pubkeys(void *ctx,int32_t pubsock) timestamp = (uint32_t)time(NULL); jaddnum(reqjson,"timestamp",timestamp); LP_pubkey_sigadd(reqjson,timestamp,G.LP_privkey,G.LP_mypub25519,G.LP_myrmd160,G.LP_pubsecp); - LP_reserved_msg("","",zero,jprint(reqjson,1)); + LP_reserved_msg(0,"","",zero,jprint(reqjson,1)); } char *LP_notify_recv(cJSON *argjson) @@ -624,7 +624,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_reserved_msg("","",zero,jprint(req,1)); + LP_reserved_msg(0,"","",zero,jprint(req,1)); #endif } } @@ -657,7 +657,7 @@ void LP_listunspent_query(char *symbol,char *coinaddr) jaddstr(reqjson,"method","addr_unspents"); jaddstr(reqjson,"coin",symbol); jaddstr(reqjson,"address",coinaddr); - LP_reserved_msg("","",zero,jprint(reqjson,1)); + LP_reserved_msg(0,"","",zero,jprint(reqjson,1)); } void LP_query(void *ctx,char *myipaddr,int32_t mypubsock,char *method,struct LP_quoteinfo *qp) From d434c073b46fb95587f4ab78d557b5b7588c02e7 Mon Sep 17 00:00:00 2001 From: jl777 Date: Thu, 2 Nov 2017 22:44:00 +0200 Subject: [PATCH 0150/1664] Test --- iguana/exchanges/LP_signatures.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/iguana/exchanges/LP_signatures.c b/iguana/exchanges/LP_signatures.c index bc1ad2e81..298a856cd 100644 --- a/iguana/exchanges/LP_signatures.c +++ b/iguana/exchanges/LP_signatures.c @@ -684,9 +684,9 @@ void LP_query(void *ctx,char *myipaddr,int32_t mypubsock,char *method,struct LP_ //printf("QUERY.(%s)\n",msg); memset(&zero,0,sizeof(zero)); portable_mutex_lock(&LP_reservedmutex); - if ( num_Reserved_msgs < sizeof(Reserved_msgs)/sizeof(*Reserved_msgs)-2 ) + if ( num_Reserved_msgs[1] < sizeof(Reserved_msgs[1])/sizeof(*Reserved_msgs[1])-2 ) { - Reserved_msgs[num_Reserved_msgs++] = msg; + Reserved_msgs[1][num_Reserved_msgs[1]++] = msg; //Reserved_msgs[num_Reserved_msgs++] = msg2; } LP_broadcast_message(LP_mypubsock,qp->srccoin,qp->destcoin,zero,msg2); From 5849f83cadaa56bcfadf9f8c3543c281709a8c7a Mon Sep 17 00:00:00 2001 From: jl777 Date: Thu, 2 Nov 2017 22:51:21 +0200 Subject: [PATCH 0151/1664] Test --- iguana/exchanges/LP_ordermatch.c | 2 +- iguana/exchanges/LP_remember.c | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/iguana/exchanges/LP_ordermatch.c b/iguana/exchanges/LP_ordermatch.c index c91082471..6dd5837a9 100644 --- a/iguana/exchanges/LP_ordermatch.c +++ b/iguana/exchanges/LP_ordermatch.c @@ -738,7 +738,7 @@ int32_t LP_tradecommand(void *ctx,char *myipaddr,int32_t pubsock,cJSON *argjson, printf("return after queued RESERVED: set swappending.%u accept qprice %.8f, min %.8f\n(%s)\n",butxo->T.swappending,qprice,price,msg); // LP_addsig //msg2 = clonestr(msg); - LP_reserved_msg(1,Q.srccoin,Q.destcoin,butxo->S.otherpubkey,msg); + LP_reserved_msg(1,Q.srccoin,Q.destcoin,butxo->S.otherpubkey,clonestr(msg)); sleep(1); bits256 zero; memset(zero.bytes,0,sizeof(zero)); diff --git a/iguana/exchanges/LP_remember.c b/iguana/exchanges/LP_remember.c index 9fa8cfbd3..22b05ece7 100644 --- a/iguana/exchanges/LP_remember.c +++ b/iguana/exchanges/LP_remember.c @@ -1120,7 +1120,7 @@ cJSON *basilisk_remember(int64_t *KMDtotals,int64_t *BTCtotals,uint32_t requesti LP_tradecommand_log(item); LP_reserved_msg(1,rswap.src,rswap.dest,zero,clonestr(itemstr)); sleep(1); - LP_reserved_msg(0,rswap.src,rswap.dest,zero,clonestr(itemstr)); + LP_reserved_msg(0,rswap.src,rswap.dest,zero,itemstr); //LP_broadcast_message(LP_mypubsock,rswap.src,rswap.dest,zero,itemstr); fclose(fp); } From 23b101bc7cbdafadf7505f01d76f302a9ceb144a Mon Sep 17 00:00:00 2001 From: jl777 Date: Thu, 2 Nov 2017 22:58:40 +0200 Subject: [PATCH 0152/1664] Test --- iguana/exchanges/LP_transaction.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/iguana/exchanges/LP_transaction.c b/iguana/exchanges/LP_transaction.c index 1071bf878..9f0fdfa69 100644 --- a/iguana/exchanges/LP_transaction.c +++ b/iguana/exchanges/LP_transaction.c @@ -651,7 +651,7 @@ char *basilisk_swap_bobtxspend(bits256 *signedtxidp,uint64_t txfee,char *name,ch else if ( value == satoshis && (double)txfee/value < 0.001 ) { satoshis = value - txfee; - printf("emergency txfee allocation from value %.8f identical to satoshis: %.8f txfee %.8f\n",dstr(value),dstr(satoshis),dstr(txfee)); + printf("txfee allocation from value %.8f identical to satoshis: %.8f txfee %.8f\n",dstr(value),dstr(satoshis),dstr(txfee)); } else { From 8eddae1940804361f7d6a2175e6999fb8a66fedd Mon Sep 17 00:00:00 2001 From: DeckerSU Date: Fri, 3 Nov 2017 02:55:41 +0400 Subject: [PATCH 0153/1664] added small F.A.Q. in how_to_use.md, based on questions in #tradebots --- iguana/dexscripts.win32/how_to_use.md | 26 +++++++++++++++++++++++--- 1 file changed, 23 insertions(+), 3 deletions(-) diff --git a/iguana/dexscripts.win32/how_to_use.md b/iguana/dexscripts.win32/how_to_use.md index 82eb5b7e5..29fdcc537 100644 --- a/iguana/dexscripts.win32/how_to_use.md +++ b/iguana/dexscripts.win32/how_to_use.md @@ -1,15 +1,15 @@ ## DexScripts for Windows. How to use? ## -**1.** Before start you should put scripts and following binaries into one folder: +**1. ** Before start you should put scripts and following binaries into one folder: - curl.exe (required for all scripts) - marketmaker.exe - libcurl.dll (required to run marketmaker) - nanomsg.dll (required to run marketmaker) -**2.** Don't forget to put `coins.json` file into a same folder. This file is available it this repo. +**2. ** Don't forget to put `coins.json` file into a same folder. This file is available it this repo. -**3.** Type your passphrase into passphrase file in this folder (you should create file with name `passphrase` and without extension) and run `1-client.cmd`. This will run marketmaker. Next step is to obtain userpass needed for other scripts, you can simply copy and paste it from marketmaker output on startup into userpass file. +**3. ** Type your passphrase into passphrase file in this folder (you should create file with name `passphrase` and without extension) and run `1-client.cmd`. This will run marketmaker. Next step is to obtain userpass needed for other scripts, you can simply copy and paste it from marketmaker output on startup into userpass file. ![](./images/userpass.png) @@ -22,3 +22,23 @@ Sample output of correct `2-getuserpass.cmd` usage is: You should see your userpass on screen, and after it will automatically copied in userpass file. It's important to all other scripts to have this password in userpass file. If output of `2-getuserpass.cmd` is not same as showed on screen above - wait some seconds and run `2-getuserpass.cmd` again. Also make sure that you have allowed marketmaker to accept incoming connections in your Windows Firewall (first time launched system should automatically asked for it). **4.** For using other scripts please refer to barterDEX API. Or **barterDEX API Summary by Category** document by *shossain*. + +## F.A.Q. ## + +**Q.** Is any simple way how i can display JSON results returned by all scripts, like orderbook and others, in human readable form? +**A.** Yes, you can use this service [JSON Editor Online](http://jsoneditoronline.org/), just copy and paste output of script in left column and see structured output in right. + +**Q.** I see an output like this when i'm start `1-client.cmd` : + + bind(0.0.0.0) port.7783 failed: No error sock.1468. errno.0 + bind(0.0.0.0) port.7783 failed: No error sock.1516. errno.0 + bind(0.0.0.0) port.7783 failed: No error sock.1444. errno.0 + bind(0.0.0.0) port.7783 failed: No error sock.1484. errno.0 + bind(0.0.0.0) port.7783 failed: No error sock.1412. errno.0 + bind(0.0.0.0) port.7783 failed: No error sock.1524. errno.0 + bind(0.0.0.0) port.7783 failed: No error sock.1008. errno.0 + +And nothing works. + +**A.** Before run `1-client.cmd` make sure in Task Manager that you haven't already running `marketmaker.exe`. If have - kill this process via Task Manager or via command line command `taskkill /f /im taskkill.exe` . + From 19adc5d25dcb1368ed6fc03361efbdb29b7753f3 Mon Sep 17 00:00:00 2001 From: jl777 Date: Fri, 3 Nov 2017 17:55:11 +0200 Subject: [PATCH 0154/1664] Test --- iguana/exchanges/LP_nativeDEX.c | 8 ++++---- iguana/exchanges/LP_remember.c | 2 +- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/iguana/exchanges/LP_nativeDEX.c b/iguana/exchanges/LP_nativeDEX.c index bf30e3be5..7eb20c8a9 100644 --- a/iguana/exchanges/LP_nativeDEX.c +++ b/iguana/exchanges/LP_nativeDEX.c @@ -165,6 +165,7 @@ char *LP_process_message(void *ctx,char *typestr,char *myipaddr,int32_t pubsock, if ( duplicate != 0 ) dup++; else uniq++; + portable_mutex_lock(&LP_commandmutex); 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 ) @@ -245,17 +246,16 @@ char *LP_process_message(void *ctx,char *typestr,char *myipaddr,int32_t pubsock, } else { - portable_mutex_lock(&LP_commandmutex); if ( (retstr= LP_command_process(ctx,myipaddr,pubsock,argjson,&((uint8_t *)ptr)[len],recvlen - len)) != 0 ) { } - portable_mutex_unlock(&LP_commandmutex); //printf("%.3f %s LP_command_process\n",OS_milliseconds()-millis,jstr(argjson,"method")); } free_json(argjson); } } } //else printf("DUPLICATE.(%s)\n",(char *)ptr); + portable_mutex_unlock(&LP_commandmutex); if ( jsonstr != 0 && (void *)jsonstr != (void *)ptr && encrypted == 0 ) free(jsonstr); if ( ptr != 0 ) @@ -322,13 +322,13 @@ 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); } + portable_mutex_unlock(&LP_commandmutex); free_json(argjson); } free(str); diff --git a/iguana/exchanges/LP_remember.c b/iguana/exchanges/LP_remember.c index 22b05ece7..927af1771 100644 --- a/iguana/exchanges/LP_remember.c +++ b/iguana/exchanges/LP_remember.c @@ -839,7 +839,7 @@ cJSON *basilisk_remember(int64_t *KMDtotals,int64_t *BTCtotals,uint32_t requesti 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("legacy DB SWAPS files BOB.(%s) Alice.(%s) src.(%s) dest.(%s)\n",rswap.bobcoin,rswap.alicecoin,rswap.src,rswap.dest); + printf("legacy DB SWAPS.(%u %u) %llu files BOB.(%s) Alice.(%s) src.(%s) dest.(%s)\n",rswap.requestid,rswap.quoteid,(long long)rswap.aliceid,rswap.bobcoin,rswap.alicecoin,rswap.src,rswap.dest); return(cJSON_Parse("{\"error\":\"mismatched bob/alice vs src/dest coins??\"}")); } alice = LP_coinfind(rswap.alicecoin); From 04bfb59f37e41c1e16a6f0142b6ea6d015f83d4f Mon Sep 17 00:00:00 2001 From: jl777 Date: Fri, 3 Nov 2017 18:01:31 +0200 Subject: [PATCH 0155/1664] Test --- iguana/exchanges/stats.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/iguana/exchanges/stats.c b/iguana/exchanges/stats.c index 2cb647dde..e8112a2ae 100644 --- a/iguana/exchanges/stats.c +++ b/iguana/exchanges/stats.c @@ -729,6 +729,7 @@ void LP_rpc_processreq(void *_ptr) free(space); free(jsonbuf); closesocket(sock); + free(_ptr); } void stats_rpcloop(void *args) @@ -759,10 +760,10 @@ void stats_rpcloop(void *args) arg64 = ((uint64_t)ipbits << 32) | (sock & 0xffffffff); arg64ptr = malloc(sizeof(arg64)); memcpy(arg64ptr,&arg64,sizeof(arg64)); - if ( 1 ) + if ( 0 ) { LP_rpc_processreq((void *)&arg64); - free(arg64ptr); + //free(arg64ptr); } else if ( OS_thread_create(malloc(sizeof(pthread_t)),NULL,(void *)LP_rpc_processreq,arg64ptr) != 0 ) { From 3e004c63971ab582767e64c4b575ef8a6b833cc8 Mon Sep 17 00:00:00 2001 From: jl777 Date: Fri, 3 Nov 2017 19:48:33 +0200 Subject: [PATCH 0156/1664] Test --- iguana/exchanges/LP_include.h | 2 +- iguana/exchanges/LP_nativeDEX.c | 26 ++++++++++++++++++++++++++ iguana/exchanges/LP_network.c | 3 +++ iguana/exchanges/LP_signatures.c | 4 ++-- 4 files changed, 32 insertions(+), 3 deletions(-) diff --git a/iguana/exchanges/LP_include.h b/iguana/exchanges/LP_include.h index c9d15c3b3..c8cfa1bc2 100644 --- a/iguana/exchanges/LP_include.h +++ b/iguana/exchanges/LP_include.h @@ -54,7 +54,7 @@ void emscripten_usleep(int32_t x); // returns immediate, no sense for sleeping #define DPOW_MIN_ASSETCHAIN_SIGS 11 #define LP_ENCRYPTED_MAXSIZE (4096 + 2 + crypto_box_NONCEBYTES + crypto_box_ZEROBYTES) -#define LP_MAXPUBKEY_ERRORS 3 +#define LP_MAXPUBKEY_ERRORS 10 #define PSOCK_KEEPALIVE 3600 #define MAINLOOP_PERSEC 100 #define MAX_PSOCK_PORT 60000 diff --git a/iguana/exchanges/LP_nativeDEX.c b/iguana/exchanges/LP_nativeDEX.c index 7eb20c8a9..ce66dc219 100644 --- a/iguana/exchanges/LP_nativeDEX.c +++ b/iguana/exchanges/LP_nativeDEX.c @@ -33,6 +33,32 @@ struct LP_peerinfo *LP_peerinfos,*LP_mypeer; struct LP_forwardinfo *LP_forwardinfos; struct iguana_info *LP_coins; struct LP_pubkeyinfo *LP_pubkeyinfos; + +struct LP_millistats +{ + double lastmilli,millisum,threshold; + uint32_t count; + char name[64]; +} LP_psockloop_stats,LP_reserved_msgs_stats,utxosQ_loop_stats,stats_rpcloop_stats,command_rpcloop_stats,queue_loop_stats,prices_loop_stats,LP_coinsloop_stats,LP_coinsloop_statsBTC,LP_coinsloop_statsKMD,LP_pubkeysloop_stats,LP_privkeysloop_stats,LP_swapsloop_stats; + +void LP_millistats_update(struct LP_millistats *mp) +{ + double elapsed,millis; + if ( mp->lastmilli == 0. ) + mp->lastmilli = OS_milliseconds(); + else + { + mp->count++; + millis = OS_milliseconds(); + elapsed = (millis - mp->lastmilli); + mp->millisum += elapsed; + if ( mp->threshold != 0. && elapsed > mp->threshold ) + { + printf("%s elapsed %.3f millis > threshold %.3f, ave %.3f millis, count.%u\n",mp->name,elapsed,mp->threshold,mp->millisum/mp->count,mp->count); + } + } +} + #include "LP_network.c" char *activecoins[] = { "BTC", "KMD" }; diff --git a/iguana/exchanges/LP_network.c b/iguana/exchanges/LP_network.c index e936e8fc8..3fb64e5d6 100644 --- a/iguana/exchanges/LP_network.c +++ b/iguana/exchanges/LP_network.c @@ -474,8 +474,11 @@ void LP_psockloop(void *_ptr) // printouts seem to be needed for forwarding to w { static struct nn_pollfd *pfds; int32_t i,n,nonz,iter,retval,sentbytes,size=0,sendsock = -1; uint32_t now; struct psock *ptr=0; void *buf=0; char keepalive[512]; + strcpy(LP_psockloop_stats.name,"LP_psockloop"); + LP_psockloop_stats.threshold = 100.; while ( 1 ) { + LP_millistats_update(&LP_psockloop_stats); now = (uint32_t)time(NULL); if ( buf != 0 && ptr != 0 && sendsock >= 0 ) { diff --git a/iguana/exchanges/LP_signatures.c b/iguana/exchanges/LP_signatures.c index 298a856cd..e47e56d81 100644 --- a/iguana/exchanges/LP_signatures.c +++ b/iguana/exchanges/LP_signatures.c @@ -286,11 +286,11 @@ int32_t LP_utxos_sigcheck(uint32_t timestamp,char *sigstr,char *pubsecpstr,bits2 if ( memcmp(pub33,pubsecp,33) != 0 || retval != 0 ) { static uint32_t counter; - if ( counter++ < 10 ) + if ( counter++ <= LP_MAXPUBKEY_ERRORS ) { if ( pubp != 0 ) pubp->numerrors++; - if ( pubp != 0 && pubp->numerrors > 1 ) + if ( pubp != 0 && pubp->numerrors > LP_MAXPUBKEY_ERRORS/2 ) printf("LP_utxos_sigcheck failure.%d, probably from %s with older version\n",pubp!=0?pubp->numerrors:-1,bits256_str(str,pubkey)); } retval = -1; From bbcd36d6328e7d6bdeb94a3da052acff835d1488 Mon Sep 17 00:00:00 2001 From: jl777 Date: Fri, 3 Nov 2017 19:56:19 +0200 Subject: [PATCH 0157/1664] Test --- iguana/exchanges/LP_nativeDEX.c | 1 + 1 file changed, 1 insertion(+) diff --git a/iguana/exchanges/LP_nativeDEX.c b/iguana/exchanges/LP_nativeDEX.c index ce66dc219..ff2ee0fa4 100644 --- a/iguana/exchanges/LP_nativeDEX.c +++ b/iguana/exchanges/LP_nativeDEX.c @@ -56,6 +56,7 @@ void LP_millistats_update(struct LP_millistats *mp) { printf("%s elapsed %.3f millis > threshold %.3f, ave %.3f millis, count.%u\n",mp->name,elapsed,mp->threshold,mp->millisum/mp->count,mp->count); } + mp->lastmilli = millis; } } From 81837de1b45e75383f8115c19ff3ca44faeaf2a0 Mon Sep 17 00:00:00 2001 From: jl777 Date: Fri, 3 Nov 2017 19:57:40 +0200 Subject: [PATCH 0158/1664] Test --- iguana/exchanges/LP_network.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/iguana/exchanges/LP_network.c b/iguana/exchanges/LP_network.c index 3fb64e5d6..32692a61e 100644 --- a/iguana/exchanges/LP_network.c +++ b/iguana/exchanges/LP_network.c @@ -475,7 +475,7 @@ void LP_psockloop(void *_ptr) // printouts seem to be needed for forwarding to w static struct nn_pollfd *pfds; int32_t i,n,nonz,iter,retval,sentbytes,size=0,sendsock = -1; uint32_t now; struct psock *ptr=0; void *buf=0; char keepalive[512]; strcpy(LP_psockloop_stats.name,"LP_psockloop"); - LP_psockloop_stats.threshold = 100.; + LP_psockloop_stats.threshold = 110.; while ( 1 ) { LP_millistats_update(&LP_psockloop_stats); From 5b794df668cebe95463d3d8b6ce42372aedd4cce Mon Sep 17 00:00:00 2001 From: jl777 Date: Fri, 3 Nov 2017 20:03:00 +0200 Subject: [PATCH 0159/1664] Test --- crypto777/iguana_utils.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/crypto777/iguana_utils.c b/crypto777/iguana_utils.c index 5b0ce5743..153cd4529 100755 --- a/crypto777/iguana_utils.c +++ b/crypto777/iguana_utils.c @@ -303,7 +303,7 @@ struct iguana_thread *iguana_launch(struct iguana_info *coin,char *name,iguana_f coin->Launched[t->type]++; retval = OS_thread_create(&t->handle,NULL,(void *)iguana_launcher,(void *)t); if ( retval != 0 ) - printf("error launching %s\n",t->name); + printf("error launching %s retval.%d errno.%d\n",t->name,retval,errno); while ( (t= queue_dequeue(&TerminateQ)) != 0 ) { if ( (rand() % 100000) == 0 && coin != 0 ) From 129c32b36cf03a6693006c296cff5c907aa040b2 Mon Sep 17 00:00:00 2001 From: jl777 Date: Fri, 3 Nov 2017 20:14:02 +0200 Subject: [PATCH 0160/1664] Test --- iguana/exchanges/LP_nativeDEX.c | 26 ++++++++++++++++---------- iguana/exchanges/stats.c | 2 +- 2 files changed, 17 insertions(+), 11 deletions(-) diff --git a/iguana/exchanges/LP_nativeDEX.c b/iguana/exchanges/LP_nativeDEX.c index ff2ee0fa4..6a1f9adca 100644 --- a/iguana/exchanges/LP_nativeDEX.c +++ b/iguana/exchanges/LP_nativeDEX.c @@ -24,16 +24,6 @@ // BCH signing #include -#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,LP_reservedmutex,LP_nanorecvsmutex,LP_tradebotsmutex; -int32_t LP_canbind; -char *Broadcaststr,*Reserved_msgs[2][1000]; -int32_t num_Reserved_msgs[2],max_Reserved_msgs[2]; -struct LP_peerinfo *LP_peerinfos,*LP_mypeer; -struct LP_forwardinfo *LP_forwardinfos; -struct iguana_info *LP_coins; -struct LP_pubkeyinfo *LP_pubkeyinfos; - struct LP_millistats { double lastmilli,millisum,threshold; @@ -60,6 +50,16 @@ void LP_millistats_update(struct LP_millistats *mp) } } +#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,LP_reservedmutex,LP_nanorecvsmutex,LP_tradebotsmutex; +int32_t LP_canbind; +char *Broadcaststr,*Reserved_msgs[2][1000]; +int32_t num_Reserved_msgs[2],max_Reserved_msgs[2]; +struct LP_peerinfo *LP_peerinfos,*LP_mypeer; +struct LP_forwardinfo *LP_forwardinfos; +struct iguana_info *LP_coins; +struct LP_pubkeyinfo *LP_pubkeyinfos; + #include "LP_network.c" char *activecoins[] = { "BTC", "KMD" }; @@ -427,8 +427,11 @@ void command_rpcloop(void *myipaddr) void utxosQ_loop(void *myipaddr) { + strcpy(utxosQ_loop_stats.name,"utxosQ_loop"); + utxosQ_loop_stats.threshold = 20.; while ( 1 ) { + LP_millistats_update(&utxosQ_loop_stats); if ( LP_utxosQ_process() == 0 ) usleep(10000); } @@ -834,8 +837,11 @@ void LP_reserved_msgs(void *ignore) { bits256 zero; int32_t flag; struct nn_pollfd pfd; memset(zero.bytes,0,sizeof(zero)); + strcpy(LP_reserved_msgs_stats.name,"LP_reserved_msgs"); + LP_reserved_msgs_stats.threshold = 10.; while ( 1 ) { + LP_millistats_update(&LP_reserved_msgs_stats); if ( num_Reserved_msgs[0] > 0 || num_Reserved_msgs[1] > 0 ) { flag = 0; diff --git a/iguana/exchanges/stats.c b/iguana/exchanges/stats.c index e8112a2ae..e206f37b8 100644 --- a/iguana/exchanges/stats.c +++ b/iguana/exchanges/stats.c @@ -760,7 +760,7 @@ void stats_rpcloop(void *args) arg64 = ((uint64_t)ipbits << 32) | (sock & 0xffffffff); arg64ptr = malloc(sizeof(arg64)); memcpy(arg64ptr,&arg64,sizeof(arg64)); - if ( 0 ) + if ( 1 ) { LP_rpc_processreq((void *)&arg64); //free(arg64ptr); From 7b3c0b4aafc043916ab49f4d599121b0627c9ec0 Mon Sep 17 00:00:00 2001 From: jl777 Date: Fri, 3 Nov 2017 20:17:25 +0200 Subject: [PATCH 0161/1664] Test --- iguana/exchanges/stats.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/iguana/exchanges/stats.c b/iguana/exchanges/stats.c index e206f37b8..2cb647dde 100644 --- a/iguana/exchanges/stats.c +++ b/iguana/exchanges/stats.c @@ -729,7 +729,6 @@ void LP_rpc_processreq(void *_ptr) free(space); free(jsonbuf); closesocket(sock); - free(_ptr); } void stats_rpcloop(void *args) @@ -763,7 +762,7 @@ void stats_rpcloop(void *args) if ( 1 ) { LP_rpc_processreq((void *)&arg64); - //free(arg64ptr); + free(arg64ptr); } else if ( OS_thread_create(malloc(sizeof(pthread_t)),NULL,(void *)LP_rpc_processreq,arg64ptr) != 0 ) { From 6c76ad6eecf2405dc305398d254c0a74cb2ff487 Mon Sep 17 00:00:00 2001 From: jl777 Date: Fri, 3 Nov 2017 20:20:55 +0200 Subject: [PATCH 0162/1664] Test --- iguana/exchanges/LP_nativeDEX.c | 4 ++-- iguana/exchanges/stats.c | 6 ++++-- 2 files changed, 6 insertions(+), 4 deletions(-) diff --git a/iguana/exchanges/LP_nativeDEX.c b/iguana/exchanges/LP_nativeDEX.c index 6a1f9adca..74c0ca200 100644 --- a/iguana/exchanges/LP_nativeDEX.c +++ b/iguana/exchanges/LP_nativeDEX.c @@ -29,7 +29,7 @@ struct LP_millistats double lastmilli,millisum,threshold; uint32_t count; char name[64]; -} LP_psockloop_stats,LP_reserved_msgs_stats,utxosQ_loop_stats,stats_rpcloop_stats,command_rpcloop_stats,queue_loop_stats,prices_loop_stats,LP_coinsloop_stats,LP_coinsloop_statsBTC,LP_coinsloop_statsKMD,LP_pubkeysloop_stats,LP_privkeysloop_stats,LP_swapsloop_stats; +} LP_psockloop_stats,LP_reserved_msgs_stats,utxosQ_loop_stats,command_rpcloop_stats,queue_loop_stats,prices_loop_stats,LP_coinsloop_stats,LP_coinsloop_statsBTC,LP_coinsloop_statsKMD,LP_pubkeysloop_stats,LP_privkeysloop_stats,LP_swapsloop_stats; void LP_millistats_update(struct LP_millistats *mp) { @@ -838,7 +838,7 @@ void LP_reserved_msgs(void *ignore) bits256 zero; int32_t flag; struct nn_pollfd pfd; memset(zero.bytes,0,sizeof(zero)); strcpy(LP_reserved_msgs_stats.name,"LP_reserved_msgs"); - LP_reserved_msgs_stats.threshold = 10.; + LP_reserved_msgs_stats.threshold = 20.; while ( 1 ) { LP_millistats_update(&LP_reserved_msgs_stats); diff --git a/iguana/exchanges/stats.c b/iguana/exchanges/stats.c index 2cb647dde..94e024f26 100644 --- a/iguana/exchanges/stats.c +++ b/iguana/exchanges/stats.c @@ -728,7 +728,6 @@ void LP_rpc_processreq(void *_ptr) } free(space); free(jsonbuf); - closesocket(sock); } void stats_rpcloop(void *args) @@ -755,7 +754,6 @@ void stats_rpcloop(void *args) continue; } memcpy(&ipbits,&cli_addr.sin_addr.s_addr,sizeof(ipbits)); - //printf("remote RPC request from (%s) %x\n",remoteaddr,ipbits); arg64 = ((uint64_t)ipbits << 32) | (sock & 0xffffffff); arg64ptr = malloc(sizeof(arg64)); memcpy(arg64ptr,&arg64,sizeof(arg64)); @@ -763,6 +761,10 @@ void stats_rpcloop(void *args) { LP_rpc_processreq((void *)&arg64); free(arg64ptr); + closesocket(sock); + char remoteaddr[64]; + expand_ipbits(remoteaddr,ipbits); + printf("finished RPC request from (%s) %x\n",remoteaddr,ipbits); } else if ( OS_thread_create(malloc(sizeof(pthread_t)),NULL,(void *)LP_rpc_processreq,arg64ptr) != 0 ) { From fe0dbba840f39267d1d1692585351ecaadfef05e Mon Sep 17 00:00:00 2001 From: jl777 Date: Fri, 3 Nov 2017 20:31:27 +0200 Subject: [PATCH 0163/1664] Test --- iguana/exchanges/LP_nativeDEX.c | 25 ++++++++++++++++++++++++- iguana/exchanges/stats.c | 6 +++--- 2 files changed, 27 insertions(+), 4 deletions(-) diff --git a/iguana/exchanges/LP_nativeDEX.c b/iguana/exchanges/LP_nativeDEX.c index 74c0ca200..3baa96b7d 100644 --- a/iguana/exchanges/LP_nativeDEX.c +++ b/iguana/exchanges/LP_nativeDEX.c @@ -29,7 +29,7 @@ struct LP_millistats double lastmilli,millisum,threshold; uint32_t count; char name[64]; -} LP_psockloop_stats,LP_reserved_msgs_stats,utxosQ_loop_stats,command_rpcloop_stats,queue_loop_stats,prices_loop_stats,LP_coinsloop_stats,LP_coinsloop_statsBTC,LP_coinsloop_statsKMD,LP_pubkeysloop_stats,LP_privkeysloop_stats,LP_swapsloop_stats; +} LP_psockloop_stats,LP_reserved_msgs_stats,utxosQ_loop_stats,command_rpcloop_stats,queue_loop_stats,prices_loop_stats,LP_coinsloop_stats,LP_coinsloopBTC_stats,LP_coinsloopKMD_stats,LP_pubkeysloop_stats,LP_privkeysloop_stats,LP_swapsloop_stats; void LP_millistats_update(struct LP_millistats *mp) { @@ -409,8 +409,11 @@ void command_rpcloop(void *myipaddr) { int32_t nonz = 0; void *ctx; ctx = bitcoin_ctx(); + strcpy(command_rpcloop_stats.name,"command_rpcloop"); + command_rpcloop_stats.threshold = 20.; while ( 1 ) { + LP_millistats_update(&command_rpcloop_stats); nonz = LP_nanomsg_recvs(ctx); //if ( LP_mybussock >= 0 ) // nonz += LP_sock_check("BUS",ctx,origipaddr,-1,LP_mybussock); @@ -523,8 +526,28 @@ int32_t LP_utxos_sync(struct LP_peerinfo *peer) void LP_coinsloop(void *_coins) { struct LP_address *ap=0,*atmp; 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; + if ( strcmp("BTC",coins) == 0 ) + { + strcpy(LP_coinsloopBTC_stats.name,"BTC coin loop"); + LP_coinsloopBTC_stats.threshold = 20.; + } + else if ( strcmp("KMD",coins) == 0 ) + { + strcpy(LP_coinsloopKMD_stats.name,"KMD coin loop"); + LP_coinsloopKMD_stats.threshold = 20.; + } + else + { + strcpy(LP_coinsloop_stats.name,"other coins loop"); + LP_coinsloop_stats.threshold = 20.; + } while ( 1 ) { + if ( strcmp("BTC",coins) == 0 ) + LP_millistats_update(&LP_coinsloopBTC_stats); + else if ( strcmp("KMD",coins) == 0 ) + LP_millistats_update(&LP_coinsloopKMD_stats); + else LP_millistats_update(&LP_coinsloop_stats); nonz = 0; HASH_ITER(hh,LP_coins,coin,ctmp) // firstrefht,firstscanht,lastscanht { diff --git a/iguana/exchanges/stats.c b/iguana/exchanges/stats.c index 94e024f26..0996d3ede 100644 --- a/iguana/exchanges/stats.c +++ b/iguana/exchanges/stats.c @@ -762,9 +762,9 @@ void stats_rpcloop(void *args) LP_rpc_processreq((void *)&arg64); free(arg64ptr); closesocket(sock); - char remoteaddr[64]; - expand_ipbits(remoteaddr,ipbits); - printf("finished RPC request from (%s) %x\n",remoteaddr,ipbits); + //char remoteaddr[64]; + //expand_ipbits(remoteaddr,ipbits); + //printf("finished RPC request from (%s) %x\n",remoteaddr,ipbits); } else if ( OS_thread_create(malloc(sizeof(pthread_t)),NULL,(void *)LP_rpc_processreq,arg64ptr) != 0 ) { From fd14c9c88d43052b1e8dbdf1a047c043be240ff0 Mon Sep 17 00:00:00 2001 From: jl777 Date: Fri, 3 Nov 2017 20:39:14 +0200 Subject: [PATCH 0164/1664] Test --- iguana/exchanges/LP_nativeDEX.c | 17 +++++++++++++---- iguana/exchanges/LP_network.c | 3 +++ iguana/exchanges/LP_portfolio.c | 3 +++ 3 files changed, 19 insertions(+), 4 deletions(-) diff --git a/iguana/exchanges/LP_nativeDEX.c b/iguana/exchanges/LP_nativeDEX.c index 3baa96b7d..9a9075c5f 100644 --- a/iguana/exchanges/LP_nativeDEX.c +++ b/iguana/exchanges/LP_nativeDEX.c @@ -410,7 +410,7 @@ void command_rpcloop(void *myipaddr) int32_t nonz = 0; void *ctx; ctx = bitcoin_ctx(); strcpy(command_rpcloop_stats.name,"command_rpcloop"); - command_rpcloop_stats.threshold = 20.; + command_rpcloop_stats.threshold = 1000.; while ( 1 ) { LP_millistats_update(&command_rpcloop_stats); @@ -529,17 +529,17 @@ void LP_coinsloop(void *_coins) if ( strcmp("BTC",coins) == 0 ) { strcpy(LP_coinsloopBTC_stats.name,"BTC coin loop"); - LP_coinsloopBTC_stats.threshold = 20.; + LP_coinsloopBTC_stats.threshold = 200.; } else if ( strcmp("KMD",coins) == 0 ) { strcpy(LP_coinsloopKMD_stats.name,"KMD coin loop"); - LP_coinsloopKMD_stats.threshold = 20.; + LP_coinsloopKMD_stats.threshold = 200.; } else { strcpy(LP_coinsloop_stats.name,"other coins loop"); - LP_coinsloop_stats.threshold = 20.; + LP_coinsloop_stats.threshold = 200.; } while ( 1 ) { @@ -817,9 +817,12 @@ void LP_initpeers(int32_t pubsock,struct LP_peerinfo *mypeer,char *myipaddr,uint void LP_pubkeysloop(void *ctx) { static uint32_t lasttime; + strcpy(LP_pubkeysloop_stats.name,"LP_pubkeysloop"); + LP_pubkeysloop_stats.threshold = 3100.; sleep(10); while ( 1 ) { + LP_millistats_update(&LP_pubkeysloop_stats); if ( time(NULL) > lasttime+60 ) { //printf("LP_pubkeysloop %u\n",(uint32_t)time(NULL)); @@ -832,9 +835,12 @@ void LP_pubkeysloop(void *ctx) void LP_privkeysloop(void *ctx) { + strcpy(LP_privkeysloop_stats.name,"LP_privkeysloop"); + LP_privkeysloop_stats.threshold = (LP_ORDERBOOK_DURATION * .777 * 1000) + 1000; sleep(20); while ( 1 ) { + LP_millistats_update(&LP_privkeysloop_stats); LP_counter += 1000; //printf("LP_privkeysloop %u\n",LP_counter); LP_privkey_updates(ctx,LP_mypubsock,0); @@ -845,9 +851,12 @@ void LP_privkeysloop(void *ctx) void LP_swapsloop(void *ignore) { char *retstr; + strcpy(LP_swapsloop_stats.name,"LP_swapsloop"); + LP_swapsloop_stats.threshold = 605000.; sleep(50); while ( 1 ) { + LP_millistats_update(&LP_swapsloop_stats); LP_counter += 10000; //printf("LP_swapsloop %u\n",LP_counter); if ( (retstr= basilisk_swapentry(0,0)) != 0 ) diff --git a/iguana/exchanges/LP_network.c b/iguana/exchanges/LP_network.c index 32692a61e..c241d0eae 100644 --- a/iguana/exchanges/LP_network.c +++ b/iguana/exchanges/LP_network.c @@ -268,8 +268,11 @@ int32_t LP_peerindsock(int32_t *peerindp) void queue_loop(void *arg) { struct LP_queue *ptr,*tmp; int32_t sentbytes,nonz,flag,duplicate,n=0; + strcpy(queue_loop_stats.name,"queue_loop"); + queue_loop_stats.threshold = 20.; while ( 1 ) { + LP_millistats_update(&queue_loop_stats); 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; diff --git a/iguana/exchanges/LP_portfolio.c b/iguana/exchanges/LP_portfolio.c index 38fe3ba69..8c86683c9 100644 --- a/iguana/exchanges/LP_portfolio.c +++ b/iguana/exchanges/LP_portfolio.c @@ -589,8 +589,11 @@ int32_t LP_portfolio_order(struct LP_portfoliotrade *trades,int32_t max,cJSON *a void prices_loop(void *ctx) { char *retstr; cJSON *retjson,*array; char *buycoin,*sellcoin; struct iguana_info *buy,*sell; uint32_t requestid,quoteid; int32_t i,n,m; struct LP_portfoliotrade trades[256]; struct LP_priceinfo *btcpp; + strcpy(prices_loop_stats.name,"prices_loop"); + prices_loop_stats.threshold = 61000.; while ( 1 ) { + LP_millistats_update(&prices_loop_stats); LP_tradebots_timeslice(ctx); if ( (btcpp= LP_priceinfofind("BTC")) == 0 ) { From 3cb3fa8a0f6cfd845b104fb1ade51d0645ef760b Mon Sep 17 00:00:00 2001 From: jl777 Date: Fri, 3 Nov 2017 20:50:36 +0200 Subject: [PATCH 0165/1664] Mills --- crypto777/bitcoind_RPC.c | 4 +++- iguana/exchanges/LP_commands.c | 5 +++++ iguana/exchanges/LP_nativeDEX.c | 38 ++++++++++++++++++++++++--------- iguana/exchanges/millis | 3 +++ 4 files changed, 39 insertions(+), 11 deletions(-) create mode 100755 iguana/exchanges/millis diff --git a/crypto777/bitcoind_RPC.c b/crypto777/bitcoind_RPC.c index bc87b61f2..4f0a9cdd4 100755 --- a/crypto777/bitcoind_RPC.c +++ b/crypto777/bitcoind_RPC.c @@ -55,7 +55,9 @@ 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); +#ifdef FROM_MARKETMAKER + usleep(5000); +#endif //printf("<<<<<<<<<<< bitcoind_RPC: %s post_process_bitcoind_RPC.%s.[%s]\n",debugstr,command,rpcstr); if ( command == 0 || rpcstr == 0 || rpcstr[0] == 0 ) { diff --git a/iguana/exchanges/LP_commands.c b/iguana/exchanges/LP_commands.c index 515138f3f..7e4c9b249 100644 --- a/iguana/exchanges/LP_commands.c +++ b/iguana/exchanges/LP_commands.c @@ -199,6 +199,11 @@ bot_resume(botid)\n\ printf("DEBUG stop\n"); exit(0); } + else if ( strcmp(method,"millis") == 0 ) + { + LP_millistats_update(0); + return(clonestr("{\"result\":\"success\"}")); + } else if ( strcmp(method,"getmessages") == 0 ) { if ( (retjson= LP_getmessages(jint(argjson,"firsti"),jint(argjson,"num"))) != 0 ) diff --git a/iguana/exchanges/LP_nativeDEX.c b/iguana/exchanges/LP_nativeDEX.c index 9a9075c5f..dc5bddc03 100644 --- a/iguana/exchanges/LP_nativeDEX.c +++ b/iguana/exchanges/LP_nativeDEX.c @@ -34,19 +34,37 @@ struct LP_millistats void LP_millistats_update(struct LP_millistats *mp) { double elapsed,millis; - if ( mp->lastmilli == 0. ) - mp->lastmilli = OS_milliseconds(); + if ( mp == 0 ) + { + mp = &LP_psockloop_stats, printf("%s threshold %.3f, ave %.3f millis, count.%u\n",mp->name,mp->threshold,mp->millisum/(mp->count > 0 ? mp->count: 1),mp->count); + mp = &LP_reserved_msgs_stats, printf("%s threshold %.3f, ave %.3f millis, count.%u\n",mp->name,mp->threshold,mp->millisum/(mp->count > 0 ? mp->count: 1),mp->count); + mp = &utxosQ_loop_stats, printf("%s threshold %.3f, ave %.3f millis, count.%u\n",mp->name,mp->threshold,mp->millisum/(mp->count > 0 ? mp->count: 1),mp->count); + mp = &command_rpcloop_stats, printf("%s threshold %.3f, ave %.3f millis, count.%u\n",mp->name,mp->threshold,mp->millisum/(mp->count > 0 ? mp->count: 1),mp->count); + mp = &queue_loop_stats, printf("%s threshold %.3f, ave %.3f millis, count.%u\n",mp->name,mp->threshold,mp->millisum/(mp->count > 0 ? mp->count: 1),mp->count); + mp = &prices_loop_stats, printf("%s threshold %.3f, ave %.3f millis, count.%u\n",mp->name,mp->threshold,mp->millisum/(mp->count > 0 ? mp->count: 1),mp->count); + mp = &LP_coinsloop_stats, printf("%s threshold %.3f, ave %.3f millis, count.%u\n",mp->name,mp->threshold,mp->millisum/(mp->count > 0 ? mp->count: 1),mp->count); + mp = &LP_coinsloopBTC_stats, printf("%s threshold %.3f, ave %.3f millis, count.%u\n",mp->name,mp->threshold,mp->millisum/(mp->count > 0 ? mp->count: 1),mp->count); + mp = &LP_coinsloopKMD_stats, printf("%s threshold %.3f, ave %.3f millis, count.%u\n",mp->name,mp->threshold,mp->millisum/(mp->count > 0 ? mp->count: 1),mp->count); + mp = &LP_pubkeysloop_stats, printf("%s threshold %.3f, ave %.3f millis, count.%u\n",mp->name,mp->threshold,mp->millisum/(mp->count > 0 ? mp->count: 1),mp->count); + mp = &LP_privkeysloop_stats, printf("%s threshold %.3f, ave %.3f millis, count.%u\n",mp->name,mp->threshold,mp->millisum/(mp->count > 0 ? mp->count: 1),mp->count); + mp = &LP_swapsloop_stats, printf("%s threshold %.3f, ave %.3f millis, count.%u\n",mp->name,mp->threshold,mp->millisum/(mp->count > 0 ? mp->count: 1),mp->count); + } else { - mp->count++; - millis = OS_milliseconds(); - elapsed = (millis - mp->lastmilli); - mp->millisum += elapsed; - if ( mp->threshold != 0. && elapsed > mp->threshold ) + if ( mp->lastmilli == 0. ) + mp->lastmilli = OS_milliseconds(); + else { - printf("%s elapsed %.3f millis > threshold %.3f, ave %.3f millis, count.%u\n",mp->name,elapsed,mp->threshold,mp->millisum/mp->count,mp->count); + mp->count++; + millis = OS_milliseconds(); + elapsed = (millis - mp->lastmilli); + mp->millisum += elapsed; + if ( mp->threshold != 0. && elapsed > mp->threshold ) + { + printf("%s elapsed %.3f millis > threshold %.3f, ave %.3f millis, count.%u\n",mp->name,elapsed,mp->threshold,mp->millisum/mp->count,mp->count); + } + mp->lastmilli = millis; } - mp->lastmilli = millis; } } @@ -431,7 +449,7 @@ void command_rpcloop(void *myipaddr) void utxosQ_loop(void *myipaddr) { strcpy(utxosQ_loop_stats.name,"utxosQ_loop"); - utxosQ_loop_stats.threshold = 20.; + utxosQ_loop_stats.threshold = 50.; while ( 1 ) { LP_millistats_update(&utxosQ_loop_stats); diff --git a/iguana/exchanges/millis b/iguana/exchanges/millis new file mode 100755 index 000000000..025f581cd --- /dev/null +++ b/iguana/exchanges/millis @@ -0,0 +1,3 @@ +#!/bin/bash +source userpass +curl --url "http://127.0.0.1:7783" --data "{\"userpass\":\"$userpass\",\"method\":\"millis\"}" From 44fd39c1518f762248d182a45e1409d2c7b277fd Mon Sep 17 00:00:00 2001 From: jl777 Date: Fri, 3 Nov 2017 20:54:10 +0200 Subject: [PATCH 0166/1664] Test --- iguana/exchanges/LP_nativeDEX.c | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/iguana/exchanges/LP_nativeDEX.c b/iguana/exchanges/LP_nativeDEX.c index dc5bddc03..ea342430b 100644 --- a/iguana/exchanges/LP_nativeDEX.c +++ b/iguana/exchanges/LP_nativeDEX.c @@ -30,13 +30,17 @@ struct LP_millistats uint32_t count; char name[64]; } LP_psockloop_stats,LP_reserved_msgs_stats,utxosQ_loop_stats,command_rpcloop_stats,queue_loop_stats,prices_loop_stats,LP_coinsloop_stats,LP_coinsloopBTC_stats,LP_coinsloopKMD_stats,LP_pubkeysloop_stats,LP_privkeysloop_stats,LP_swapsloop_stats; +extern int32_t IAMLP; void LP_millistats_update(struct LP_millistats *mp) { double elapsed,millis; if ( mp == 0 ) { - mp = &LP_psockloop_stats, printf("%s threshold %.3f, ave %.3f millis, count.%u\n",mp->name,mp->threshold,mp->millisum/(mp->count > 0 ? mp->count: 1),mp->count); + if ( IAMLP != 0 ) + { + mp = &LP_psockloop_stats, printf("%s threshold %.3f, ave %.3f millis, count.%u\n",mp->name,mp->threshold,mp->millisum/(mp->count > 0 ? mp->count: 1),mp->count); + } mp = &LP_reserved_msgs_stats, printf("%s threshold %.3f, ave %.3f millis, count.%u\n",mp->name,mp->threshold,mp->millisum/(mp->count > 0 ? mp->count: 1),mp->count); mp = &utxosQ_loop_stats, printf("%s threshold %.3f, ave %.3f millis, count.%u\n",mp->name,mp->threshold,mp->millisum/(mp->count > 0 ? mp->count: 1),mp->count); mp = &command_rpcloop_stats, printf("%s threshold %.3f, ave %.3f millis, count.%u\n",mp->name,mp->threshold,mp->millisum/(mp->count > 0 ? mp->count: 1),mp->count); @@ -61,7 +65,7 @@ void LP_millistats_update(struct LP_millistats *mp) mp->millisum += elapsed; if ( mp->threshold != 0. && elapsed > mp->threshold ) { - printf("%s elapsed %.3f millis > threshold %.3f, ave %.3f millis, count.%u\n",mp->name,elapsed,mp->threshold,mp->millisum/mp->count,mp->count); + printf("%32s elapsed %8.3f millis > threshold %8.3f, ave %8.3f millis, count.%u\n",mp->name,elapsed,mp->threshold,mp->millisum/mp->count,mp->count); } mp->lastmilli = millis; } From 9a4c8d1171894855c7e42f6d295d5728074998a8 Mon Sep 17 00:00:00 2001 From: jl777 Date: Fri, 3 Nov 2017 20:57:36 +0200 Subject: [PATCH 0167/1664] Test --- iguana/exchanges/LP_nativeDEX.c | 24 ++++++++++++------------ 1 file changed, 12 insertions(+), 12 deletions(-) diff --git a/iguana/exchanges/LP_nativeDEX.c b/iguana/exchanges/LP_nativeDEX.c index ea342430b..256757083 100644 --- a/iguana/exchanges/LP_nativeDEX.c +++ b/iguana/exchanges/LP_nativeDEX.c @@ -39,19 +39,19 @@ void LP_millistats_update(struct LP_millistats *mp) { if ( IAMLP != 0 ) { - mp = &LP_psockloop_stats, printf("%s threshold %.3f, ave %.3f millis, count.%u\n",mp->name,mp->threshold,mp->millisum/(mp->count > 0 ? mp->count: 1),mp->count); + mp = &LP_psockloop_stats, printf("%32s millis > threshold %8.3f, ave %8.3f millis, count.%u\n",mp->name,mp->threshold,mp->millisum/(mp->count > 0 ? mp->count: 1),mp->count); } - mp = &LP_reserved_msgs_stats, printf("%s threshold %.3f, ave %.3f millis, count.%u\n",mp->name,mp->threshold,mp->millisum/(mp->count > 0 ? mp->count: 1),mp->count); - mp = &utxosQ_loop_stats, printf("%s threshold %.3f, ave %.3f millis, count.%u\n",mp->name,mp->threshold,mp->millisum/(mp->count > 0 ? mp->count: 1),mp->count); - mp = &command_rpcloop_stats, printf("%s threshold %.3f, ave %.3f millis, count.%u\n",mp->name,mp->threshold,mp->millisum/(mp->count > 0 ? mp->count: 1),mp->count); - mp = &queue_loop_stats, printf("%s threshold %.3f, ave %.3f millis, count.%u\n",mp->name,mp->threshold,mp->millisum/(mp->count > 0 ? mp->count: 1),mp->count); - mp = &prices_loop_stats, printf("%s threshold %.3f, ave %.3f millis, count.%u\n",mp->name,mp->threshold,mp->millisum/(mp->count > 0 ? mp->count: 1),mp->count); - mp = &LP_coinsloop_stats, printf("%s threshold %.3f, ave %.3f millis, count.%u\n",mp->name,mp->threshold,mp->millisum/(mp->count > 0 ? mp->count: 1),mp->count); - mp = &LP_coinsloopBTC_stats, printf("%s threshold %.3f, ave %.3f millis, count.%u\n",mp->name,mp->threshold,mp->millisum/(mp->count > 0 ? mp->count: 1),mp->count); - mp = &LP_coinsloopKMD_stats, printf("%s threshold %.3f, ave %.3f millis, count.%u\n",mp->name,mp->threshold,mp->millisum/(mp->count > 0 ? mp->count: 1),mp->count); - mp = &LP_pubkeysloop_stats, printf("%s threshold %.3f, ave %.3f millis, count.%u\n",mp->name,mp->threshold,mp->millisum/(mp->count > 0 ? mp->count: 1),mp->count); - mp = &LP_privkeysloop_stats, printf("%s threshold %.3f, ave %.3f millis, count.%u\n",mp->name,mp->threshold,mp->millisum/(mp->count > 0 ? mp->count: 1),mp->count); - mp = &LP_swapsloop_stats, printf("%s threshold %.3f, ave %.3f millis, count.%u\n",mp->name,mp->threshold,mp->millisum/(mp->count > 0 ? mp->count: 1),mp->count); + mp = &LP_reserved_msgs_stats, printf("%32s millis > threshold %8.3f, ave %8.3f millis, count.%u\n",mp->name,mp->threshold,mp->millisum/(mp->count > 0 ? mp->count: 1),mp->count); + mp = &utxosQ_loop_stats, printf("%32s millis > threshold %8.3f, ave %8.3f millis, count.%u\n",mp->name,mp->threshold,mp->millisum/(mp->count > 0 ? mp->count: 1),mp->count); + mp = &command_rpcloop_stats, printf("%32s millis > threshold %8.3f, ave %8.3f millis, count.%u\n",mp->name,mp->threshold,mp->millisum/(mp->count > 0 ? mp->count: 1),mp->count); + mp = &queue_loop_stats, printf("%32s millis > threshold %8.3f, ave %8.3f millis, count.%u\n",mp->name,mp->threshold,mp->millisum/(mp->count > 0 ? mp->count: 1),mp->count); + mp = &prices_loop_stats, printf("%32s millis > threshold %8.3f, ave %8.3f millis, count.%u\n",mp->name,mp->threshold,mp->millisum/(mp->count > 0 ? mp->count: 1),mp->count); + mp = &LP_coinsloop_stats, printf("%32s millis > threshold %8.3f, ave %8.3f millis, count.%u\n",mp->name,mp->threshold,mp->millisum/(mp->count > 0 ? mp->count: 1),mp->count); + mp = &LP_coinsloopBTC_stats, printf("%32s millis > threshold %8.3f, ave %8.3f millis, count.%u\n",mp->name,mp->threshold,mp->millisum/(mp->count > 0 ? mp->count: 1),mp->count); + mp = &LP_coinsloopKMD_stats, printf("%32s millis > threshold %8.3f, ave %8.3f millis, count.%u\n",mp->name,mp->threshold,mp->millisum/(mp->count > 0 ? mp->count: 1),mp->count); + mp = &LP_pubkeysloop_stats, printf("%32s millis > threshold %8.3f, ave %8.3f millis, count.%u\n",mp->name,mp->threshold,mp->millisum/(mp->count > 0 ? mp->count: 1),mp->count); + mp = &LP_privkeysloop_stats, printf("%32s millis > threshold %8.3f, ave %8.3f millis, count.%u\n",mp->name,mp->threshold,mp->millisum/(mp->count > 0 ? mp->count: 1),mp->count); + mp = &LP_swapsloop_stats, printf("%32s millis > threshold %8.3f, ave %8.3f millis, count.%u\n",mp->name,mp->threshold,mp->millisum/(mp->count > 0 ? mp->count: 1),mp->count); } else { From af3b62443a0118384dbbdeb5a9fa3dd2a62d25bf Mon Sep 17 00:00:00 2001 From: jl777 Date: Fri, 3 Nov 2017 21:03:01 +0200 Subject: [PATCH 0168/1664] Test --- iguana/exchanges/LP_nativeDEX.c | 24 ++++++++++++------------ iguana/exchanges/LP_network.c | 2 +- 2 files changed, 13 insertions(+), 13 deletions(-) diff --git a/iguana/exchanges/LP_nativeDEX.c b/iguana/exchanges/LP_nativeDEX.c index 256757083..6f12b497a 100644 --- a/iguana/exchanges/LP_nativeDEX.c +++ b/iguana/exchanges/LP_nativeDEX.c @@ -39,19 +39,19 @@ void LP_millistats_update(struct LP_millistats *mp) { if ( IAMLP != 0 ) { - mp = &LP_psockloop_stats, printf("%32s millis > threshold %8.3f, ave %8.3f millis, count.%u\n",mp->name,mp->threshold,mp->millisum/(mp->count > 0 ? mp->count: 1),mp->count); + mp = &LP_psockloop_stats, printf("%32s millis > threshold %8.3f, ave %8.3f millis, count.%u | lag %.3f\n",mp->name,mp->threshold,mp->millisum/(mp->count > 0 ? mp->count: 1),mp->count,OS_milliseconds() - mp->lastmilli); } - mp = &LP_reserved_msgs_stats, printf("%32s millis > threshold %8.3f, ave %8.3f millis, count.%u\n",mp->name,mp->threshold,mp->millisum/(mp->count > 0 ? mp->count: 1),mp->count); - mp = &utxosQ_loop_stats, printf("%32s millis > threshold %8.3f, ave %8.3f millis, count.%u\n",mp->name,mp->threshold,mp->millisum/(mp->count > 0 ? mp->count: 1),mp->count); - mp = &command_rpcloop_stats, printf("%32s millis > threshold %8.3f, ave %8.3f millis, count.%u\n",mp->name,mp->threshold,mp->millisum/(mp->count > 0 ? mp->count: 1),mp->count); - mp = &queue_loop_stats, printf("%32s millis > threshold %8.3f, ave %8.3f millis, count.%u\n",mp->name,mp->threshold,mp->millisum/(mp->count > 0 ? mp->count: 1),mp->count); - mp = &prices_loop_stats, printf("%32s millis > threshold %8.3f, ave %8.3f millis, count.%u\n",mp->name,mp->threshold,mp->millisum/(mp->count > 0 ? mp->count: 1),mp->count); - mp = &LP_coinsloop_stats, printf("%32s millis > threshold %8.3f, ave %8.3f millis, count.%u\n",mp->name,mp->threshold,mp->millisum/(mp->count > 0 ? mp->count: 1),mp->count); - mp = &LP_coinsloopBTC_stats, printf("%32s millis > threshold %8.3f, ave %8.3f millis, count.%u\n",mp->name,mp->threshold,mp->millisum/(mp->count > 0 ? mp->count: 1),mp->count); - mp = &LP_coinsloopKMD_stats, printf("%32s millis > threshold %8.3f, ave %8.3f millis, count.%u\n",mp->name,mp->threshold,mp->millisum/(mp->count > 0 ? mp->count: 1),mp->count); - mp = &LP_pubkeysloop_stats, printf("%32s millis > threshold %8.3f, ave %8.3f millis, count.%u\n",mp->name,mp->threshold,mp->millisum/(mp->count > 0 ? mp->count: 1),mp->count); - mp = &LP_privkeysloop_stats, printf("%32s millis > threshold %8.3f, ave %8.3f millis, count.%u\n",mp->name,mp->threshold,mp->millisum/(mp->count > 0 ? mp->count: 1),mp->count); - mp = &LP_swapsloop_stats, printf("%32s millis > threshold %8.3f, ave %8.3f millis, count.%u\n",mp->name,mp->threshold,mp->millisum/(mp->count > 0 ? mp->count: 1),mp->count); + mp = &LP_reserved_msgs_stats, printf("%32s millis > threshold %8.3f, ave %8.3f millis, count.%u | lag %.3f\n",mp->name,mp->threshold,mp->millisum/(mp->count > 0 ? mp->count: 1),mp->count,OS_milliseconds() - mp->lastmilli); + mp = &utxosQ_loop_stats, printf("%32s millis > threshold %8.3f, ave %8.3f millis, count.%u | lag %.3f\n",mp->name,mp->threshold,mp->millisum/(mp->count > 0 ? mp->count: 1),mp->count,OS_milliseconds() - mp->lastmilli); + mp = &command_rpcloop_stats, printf("%32s millis > threshold %8.3f, ave %8.3f millis, count.%u | lag %.3f\n",mp->name,mp->threshold,mp->millisum/(mp->count > 0 ? mp->count: 1),mp->count,OS_milliseconds() - mp->lastmilli); + mp = &queue_loop_stats, printf("%32s millis > threshold %8.2f, ave %8.2f millis, count.%u | lag %.3f\n",mp->name,mp->threshold,mp->millisum/(mp->count > 0 ? mp->count: 1),mp->count,OS_milliseconds() - mp->lastmilli); + mp = &prices_loop_stats, printf("%32s millis > threshold %8.3f, ave %8.3f millis, count.%u | lag %.3f\n",mp->name,mp->threshold,mp->millisum/(mp->count > 0 ? mp->count: 1),mp->count,OS_milliseconds() - mp->lastmilli); + mp = &LP_coinsloop_stats, printf("%32s millis > threshold %8.3f, ave %8.3f millis, count.%u | lag %.3f\n",mp->name,mp->threshold,mp->millisum/(mp->count > 0 ? mp->count: 1),mp->count,OS_milliseconds() - mp->lastmilli); + mp = &LP_coinsloopBTC_stats, printf("%32s millis > threshold %8.3f, ave %8.3f millis, count.%u | lag %.3f\n",mp->name,mp->threshold,mp->millisum/(mp->count > 0 ? mp->count: 1),mp->count,OS_milliseconds() - mp->lastmilli); + mp = &LP_coinsloopKMD_stats, printf("%32s millis > threshold %8.3f, ave %8.3f millis, count.%u | lag %.3f\n",mp->name,mp->threshold,mp->millisum/(mp->count > 0 ? mp->count: 1),mp->count,OS_milliseconds() - mp->lastmilli); + mp = &LP_pubkeysloop_stats, printf("%32s millis > threshold %8.3f, ave %8.3f millis, count.%u | lag %.3f\n",mp->name,mp->threshold,mp->millisum/(mp->count > 0 ? mp->count: 1),mp->count,OS_milliseconds() - mp->lastmilli); + mp = &LP_privkeysloop_stats, printf("%32s millis > threshold %8.3f, ave %8.3f millis, count.%u | lag %.3f\n",mp->name,mp->threshold,mp->millisum/(mp->count > 0 ? mp->count: 1),mp->count,OS_milliseconds() - mp->lastmilli); + mp = &LP_swapsloop_stats, printf("%32s millis > threshold %8.3f, ave %8.3f millis, count.%u | lag %.3f\n",mp->name,mp->threshold,mp->millisum/(mp->count > 0 ? mp->count: 1),mp->count,OS_milliseconds() - mp->lastmilli); } else { diff --git a/iguana/exchanges/LP_network.c b/iguana/exchanges/LP_network.c index c241d0eae..c96975a68 100644 --- a/iguana/exchanges/LP_network.c +++ b/iguana/exchanges/LP_network.c @@ -269,7 +269,7 @@ void queue_loop(void *arg) { struct LP_queue *ptr,*tmp; int32_t sentbytes,nonz,flag,duplicate,n=0; strcpy(queue_loop_stats.name,"queue_loop"); - queue_loop_stats.threshold = 20.; + queue_loop_stats.threshold = 50.; while ( 1 ) { LP_millistats_update(&queue_loop_stats); From e048de471b91ddde94d2913b27fe96d442cb7519 Mon Sep 17 00:00:00 2001 From: jl777 Date: Fri, 3 Nov 2017 21:09:40 +0200 Subject: [PATCH 0169/1664] Test --- iguana/exchanges/LP_nativeDEX.c | 26 +++++++++++++------------- 1 file changed, 13 insertions(+), 13 deletions(-) diff --git a/iguana/exchanges/LP_nativeDEX.c b/iguana/exchanges/LP_nativeDEX.c index 6f12b497a..d330e531a 100644 --- a/iguana/exchanges/LP_nativeDEX.c +++ b/iguana/exchanges/LP_nativeDEX.c @@ -39,19 +39,19 @@ void LP_millistats_update(struct LP_millistats *mp) { if ( IAMLP != 0 ) { - mp = &LP_psockloop_stats, printf("%32s millis > threshold %8.3f, ave %8.3f millis, count.%u | lag %.3f\n",mp->name,mp->threshold,mp->millisum/(mp->count > 0 ? mp->count: 1),mp->count,OS_milliseconds() - mp->lastmilli); + mp = &LP_psockloop_stats, printf("%32s lag %10.2f millis, threshold %10.2f, ave %10.2f millis, count.%u\n",mp->name,OS_milliseconds() - mp->lastmilli,mp->threshold,mp->millisum/(mp->count > 0 ? mp->count: 1),mp->count); } - mp = &LP_reserved_msgs_stats, printf("%32s millis > threshold %8.3f, ave %8.3f millis, count.%u | lag %.3f\n",mp->name,mp->threshold,mp->millisum/(mp->count > 0 ? mp->count: 1),mp->count,OS_milliseconds() - mp->lastmilli); - mp = &utxosQ_loop_stats, printf("%32s millis > threshold %8.3f, ave %8.3f millis, count.%u | lag %.3f\n",mp->name,mp->threshold,mp->millisum/(mp->count > 0 ? mp->count: 1),mp->count,OS_milliseconds() - mp->lastmilli); - mp = &command_rpcloop_stats, printf("%32s millis > threshold %8.3f, ave %8.3f millis, count.%u | lag %.3f\n",mp->name,mp->threshold,mp->millisum/(mp->count > 0 ? mp->count: 1),mp->count,OS_milliseconds() - mp->lastmilli); - mp = &queue_loop_stats, printf("%32s millis > threshold %8.2f, ave %8.2f millis, count.%u | lag %.3f\n",mp->name,mp->threshold,mp->millisum/(mp->count > 0 ? mp->count: 1),mp->count,OS_milliseconds() - mp->lastmilli); - mp = &prices_loop_stats, printf("%32s millis > threshold %8.3f, ave %8.3f millis, count.%u | lag %.3f\n",mp->name,mp->threshold,mp->millisum/(mp->count > 0 ? mp->count: 1),mp->count,OS_milliseconds() - mp->lastmilli); - mp = &LP_coinsloop_stats, printf("%32s millis > threshold %8.3f, ave %8.3f millis, count.%u | lag %.3f\n",mp->name,mp->threshold,mp->millisum/(mp->count > 0 ? mp->count: 1),mp->count,OS_milliseconds() - mp->lastmilli); - mp = &LP_coinsloopBTC_stats, printf("%32s millis > threshold %8.3f, ave %8.3f millis, count.%u | lag %.3f\n",mp->name,mp->threshold,mp->millisum/(mp->count > 0 ? mp->count: 1),mp->count,OS_milliseconds() - mp->lastmilli); - mp = &LP_coinsloopKMD_stats, printf("%32s millis > threshold %8.3f, ave %8.3f millis, count.%u | lag %.3f\n",mp->name,mp->threshold,mp->millisum/(mp->count > 0 ? mp->count: 1),mp->count,OS_milliseconds() - mp->lastmilli); - mp = &LP_pubkeysloop_stats, printf("%32s millis > threshold %8.3f, ave %8.3f millis, count.%u | lag %.3f\n",mp->name,mp->threshold,mp->millisum/(mp->count > 0 ? mp->count: 1),mp->count,OS_milliseconds() - mp->lastmilli); - mp = &LP_privkeysloop_stats, printf("%32s millis > threshold %8.3f, ave %8.3f millis, count.%u | lag %.3f\n",mp->name,mp->threshold,mp->millisum/(mp->count > 0 ? mp->count: 1),mp->count,OS_milliseconds() - mp->lastmilli); - mp = &LP_swapsloop_stats, printf("%32s millis > threshold %8.3f, ave %8.3f millis, count.%u | lag %.3f\n",mp->name,mp->threshold,mp->millisum/(mp->count > 0 ? mp->count: 1),mp->count,OS_milliseconds() - mp->lastmilli); + mp = &LP_reserved_msgs_stats, printf("%32s lag %10.2f millis, threshold %10.2f, ave %10.2f millis, count.%u\n",mp->name,OS_milliseconds() - mp->lastmilli,mp->threshold,mp->millisum/(mp->count > 0 ? mp->count: 1),mp->count); + mp = &utxosQ_loop_stats, printf("%32s lag %10.2f millis, threshold %10.2f, ave %10.2f millis, count.%u\n",mp->name,OS_milliseconds() - mp->lastmilli,mp->threshold,mp->millisum/(mp->count > 0 ? mp->count: 1),mp->count); + mp = &command_rpcloop_stats, printf("%32s lag %10.2f millis, threshold %10.2f, ave %10.2f millis, count.%u\n",mp->name,OS_milliseconds() - mp->lastmilli,mp->threshold,mp->millisum/(mp->count > 0 ? mp->count: 1),mp->count); + mp = &queue_loop_stats, printf("%32s lag %10.2f millis, threshold %10.2f, ave %10.2f millis, count.%u\n",mp->name,OS_milliseconds() - mp->lastmilli,mp->threshold,mp->millisum/(mp->count > 0 ? mp->count: 1),mp->count); + mp = &prices_loop_stats, printf("%32s lag %10.2f millis, threshold %10.2f, ave %10.2f millis, count.%u\n",mp->name,OS_milliseconds() - mp->lastmilli,mp->threshold,mp->millisum/(mp->count > 0 ? mp->count: 1),mp->count); + mp = &LP_coinsloop_stats, printf("%32s lag %10.2f millis, threshold %10.2f, ave %10.2f millis, count.%u\n",mp->name,OS_milliseconds() - mp->lastmilli,mp->threshold,mp->millisum/(mp->count > 0 ? mp->count: 1),mp->count); + mp = &LP_coinsloopBTC_stats, printf("%32s lag %10.2f millis, threshold %10.2f, ave %10.2f millis, count.%u\n",mp->name,OS_milliseconds() - mp->lastmilli,mp->threshold,mp->millisum/(mp->count > 0 ? mp->count: 1),mp->count); + mp = &LP_coinsloopKMD_stats, printf("%32s lag %10.2f millis, threshold %10.2f, ave %10.2f millis, count.%u\n",mp->name,OS_milliseconds() - mp->lastmilli,mp->threshold,mp->millisum/(mp->count > 0 ? mp->count: 1),mp->count); + mp = &LP_pubkeysloop_stats, printf("%32s lag %10.2f millis, threshold %10.2f, ave %10.2f millis, count.%u\n",mp->name,OS_milliseconds() - mp->lastmilli,mp->threshold,mp->millisum/(mp->count > 0 ? mp->count: 1),mp->count); + mp = &LP_privkeysloop_stats, printf("%32s lag %10.2f millis, threshold %10.2f, ave %10.2f millis, count.%u\n",mp->name,OS_milliseconds() - mp->lastmilli,mp->threshold,mp->millisum/(mp->count > 0 ? mp->count: 1),mp->count); + mp = &LP_swapsloop_stats, printf("%32s lag %10.2f millis, threshold %10.2f, ave %10.2f millis, count.%u\n",mp->name,OS_milliseconds() - mp->lastmilli,mp->threshold,mp->millisum/(mp->count > 0 ? mp->count: 1),mp->count); } else { @@ -65,7 +65,7 @@ void LP_millistats_update(struct LP_millistats *mp) mp->millisum += elapsed; if ( mp->threshold != 0. && elapsed > mp->threshold ) { - printf("%32s elapsed %8.3f millis > threshold %8.3f, ave %8.3f millis, count.%u\n",mp->name,elapsed,mp->threshold,mp->millisum/mp->count,mp->count); + printf("%32s elapsed %10.2 millis > threshold %10.2, ave %10.2 millis, count.%u\n",mp->name,elapsed,mp->threshold,mp->millisum/mp->count,mp->count); } mp->lastmilli = millis; } From 2b08388992432df52654d25a8f96d4047aba45a6 Mon Sep 17 00:00:00 2001 From: jl777 Date: Fri, 3 Nov 2017 21:20:35 +0200 Subject: [PATCH 0170/1664] Test --- iguana/exchanges/LP_nativeDEX.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/iguana/exchanges/LP_nativeDEX.c b/iguana/exchanges/LP_nativeDEX.c index d330e531a..9b74dee95 100644 --- a/iguana/exchanges/LP_nativeDEX.c +++ b/iguana/exchanges/LP_nativeDEX.c @@ -65,7 +65,7 @@ void LP_millistats_update(struct LP_millistats *mp) mp->millisum += elapsed; if ( mp->threshold != 0. && elapsed > mp->threshold ) { - printf("%32s elapsed %10.2 millis > threshold %10.2, ave %10.2 millis, count.%u\n",mp->name,elapsed,mp->threshold,mp->millisum/mp->count,mp->count); + printf("%32s elapsed %10.2f millis > threshold %10.2f, ave %10.2f millis, count.%u\n",mp->name,elapsed,mp->threshold,mp->millisum/mp->count,mp->count); } mp->lastmilli = millis; } From c7e9c48e34c1d84946703da73b9754547b413dd9 Mon Sep 17 00:00:00 2001 From: jl777 Date: Fri, 3 Nov 2017 21:30:02 +0200 Subject: [PATCH 0171/1664] Test --- iguana/exchanges/LP_nativeDEX.c | 1 + 1 file changed, 1 insertion(+) diff --git a/iguana/exchanges/LP_nativeDEX.c b/iguana/exchanges/LP_nativeDEX.c index 9b74dee95..a3665268a 100644 --- a/iguana/exchanges/LP_nativeDEX.c +++ b/iguana/exchanges/LP_nativeDEX.c @@ -883,6 +883,7 @@ void LP_swapsloop(void *ignore) //printf("LP_swapsloop %u\n",LP_counter); if ( (retstr= basilisk_swapentry(0,0)) != 0 ) free(retstr); + LP_millistats_update(0); sleep(600); } } From e32015711faffd2409c766637d92b41e31c0d642 Mon Sep 17 00:00:00 2001 From: jl777 Date: Fri, 3 Nov 2017 21:37:56 +0200 Subject: [PATCH 0172/1664] Test --- iguana/exchanges/LP_nativeDEX.c | 2 +- iguana/exchanges/LP_network.c | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/iguana/exchanges/LP_nativeDEX.c b/iguana/exchanges/LP_nativeDEX.c index a3665268a..51699b4d2 100644 --- a/iguana/exchanges/LP_nativeDEX.c +++ b/iguana/exchanges/LP_nativeDEX.c @@ -893,7 +893,7 @@ void LP_reserved_msgs(void *ignore) bits256 zero; int32_t flag; struct nn_pollfd pfd; memset(zero.bytes,0,sizeof(zero)); strcpy(LP_reserved_msgs_stats.name,"LP_reserved_msgs"); - LP_reserved_msgs_stats.threshold = 20.; + LP_reserved_msgs_stats.threshold = 50.; while ( 1 ) { LP_millistats_update(&LP_reserved_msgs_stats); diff --git a/iguana/exchanges/LP_network.c b/iguana/exchanges/LP_network.c index c96975a68..522abd999 100644 --- a/iguana/exchanges/LP_network.c +++ b/iguana/exchanges/LP_network.c @@ -269,7 +269,7 @@ void queue_loop(void *arg) { struct LP_queue *ptr,*tmp; int32_t sentbytes,nonz,flag,duplicate,n=0; strcpy(queue_loop_stats.name,"queue_loop"); - queue_loop_stats.threshold = 50.; + queue_loop_stats.threshold = 200.; while ( 1 ) { LP_millistats_update(&queue_loop_stats); @@ -478,7 +478,7 @@ void LP_psockloop(void *_ptr) // printouts seem to be needed for forwarding to w static struct nn_pollfd *pfds; int32_t i,n,nonz,iter,retval,sentbytes,size=0,sendsock = -1; uint32_t now; struct psock *ptr=0; void *buf=0; char keepalive[512]; strcpy(LP_psockloop_stats.name,"LP_psockloop"); - LP_psockloop_stats.threshold = 110.; + LP_psockloop_stats.threshold = 200.; while ( 1 ) { LP_millistats_update(&LP_psockloop_stats); From 34b524a356a831977c6c48899ae040e444848ec6 Mon Sep 17 00:00:00 2001 From: jl777 Date: Fri, 3 Nov 2017 21:44:09 +0200 Subject: [PATCH 0173/1664] Test --- iguana/exchanges/LP_portfolio.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/iguana/exchanges/LP_portfolio.c b/iguana/exchanges/LP_portfolio.c index 8c86683c9..8e8dc23ca 100644 --- a/iguana/exchanges/LP_portfolio.c +++ b/iguana/exchanges/LP_portfolio.c @@ -590,7 +590,7 @@ void prices_loop(void *ctx) { char *retstr; cJSON *retjson,*array; char *buycoin,*sellcoin; struct iguana_info *buy,*sell; uint32_t requestid,quoteid; int32_t i,n,m; struct LP_portfoliotrade trades[256]; struct LP_priceinfo *btcpp; strcpy(prices_loop_stats.name,"prices_loop"); - prices_loop_stats.threshold = 61000.; + prices_loop_stats.threshold = 91000.; while ( 1 ) { LP_millistats_update(&prices_loop_stats); From e621b4b90d108efef0c47b138fd479c79b5f88e7 Mon Sep 17 00:00:00 2001 From: jl777 Date: Fri, 3 Nov 2017 22:03:12 +0200 Subject: [PATCH 0174/1664] Test --- iguana/exchanges/LP_nativeDEX.c | 5 ++++- iguana/exchanges/install | 2 +- iguana/exchanges/mnzservers | 12 ++++++++++++ 3 files changed, 17 insertions(+), 2 deletions(-) create mode 100755 iguana/exchanges/mnzservers diff --git a/iguana/exchanges/LP_nativeDEX.c b/iguana/exchanges/LP_nativeDEX.c index 51699b4d2..42e41cfba 100644 --- a/iguana/exchanges/LP_nativeDEX.c +++ b/iguana/exchanges/LP_nativeDEX.c @@ -89,7 +89,10 @@ char GLOBAL_DBDIR[] = { "DB" }; char LP_myipaddr[64],LP_publicaddr[64],USERHOME[512] = { "/root" }; char LP_gui[16] = { "cli" }; -char *default_LPnodes[] = { "5.9.253.195", "5.9.253.196", "5.9.253.197", "5.9.253.198", "5.9.253.199", "5.9.253.200", "5.9.253.201", "5.9.253.202", "5.9.253.203", };//"5.9.253.204" }; // +char *default_LPnodes[] = { "5.9.253.195", "5.9.253.196", "5.9.253.197", "5.9.253.198", "5.9.253.199", "5.9.253.200", "5.9.253.201", "5.9.253.202", "5.9.253.203", + "51.15.203.171", "51.15.86.136", "51.15.94.249", "51.15.80.18", "51.15.91.40", "51.15.54.2", "51.15.86.31", "51.15.82.29", "51.15.89.155", +};//"5.9.253.204" }; // + //uint32_t LP_deadman_switch; uint16_t LP_fixed_pairport,LP_publicport; diff --git a/iguana/exchanges/install b/iguana/exchanges/install index ef6617a55..2f4946484 100755 --- a/iguana/exchanges/install +++ b/iguana/exchanges/install @@ -1,5 +1,5 @@ #!/bin/bash -cp bot_buy bot_list bot_pause bot_resume bot_sell bot_settings bot_status bot_stop guistats pubkeystats pendings coinswaps baserelswaps setpassphrase notarizations getrawtransaction parselog statsdisp m_js 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 stop millis mnzservers bot_buy bot_list bot_pause bot_resume bot_sell bot_settings bot_status bot_stop guistats pubkeystats pendings coinswaps baserelswaps setpassphrase notarizations getrawtransaction parselog statsdisp m_js 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 . diff --git a/iguana/exchanges/mnzservers b/iguana/exchanges/mnzservers new file mode 100755 index 000000000..40f904b49 --- /dev/null +++ b/iguana/exchanges/mnzservers @@ -0,0 +1,12 @@ +#!/bin/bash +source userpass + +curl --url "http://127.0.0.1:7783" --data "{\"userpass\":\"$userpass\",\"pubkey\":\"b4a6361506d847817205a8e51374eb129fc33c3b5466235afdbc65f2291ffb4c\",\"method\":\"trust\",\"trust\":1}" +curl --url "http://127.0.0.1:7783" --data "{\"userpass\":\"$userpass\",\"pubkey\":\"bd0c69da4ec3ed61613734f9f681f846fde5d8efc894c82dafbeeb7a01844872\",\"method\":\"trust\",\"trust\":1}" +curl --url "http://127.0.0.1:7783" --data "{\"userpass\":\"$userpass\",\"pubkey\":\"8f7782b532808a30a1fe6ffc1fa3c55fea6d734f000763fa88d42ccfed60d213\",\"method\":\"trust\",\"trust\":1}" +curl --url "http://127.0.0.1:7783" --data "{\"userpass\":\"$userpass\",\"pubkey\":\"d80a74847cd60899afdd673570f8b698e4089e5ad4d6e9e205b5e5891ec0c84f\",\"method\":\"trust\",\"trust\":1}" +curl --url "http://127.0.0.1:7783" --data "{\"userpass\":\"$userpass\",\"pubkey\":\"322e236db07484b31aea9400a6f3f5ed972e29c6d4115c63aaedaa541d41e758\",\"method\":\"trust\",\"trust\":1}" +curl --url "http://127.0.0.1:7783" --data "{\"userpass\":\"$userpass\",\"pubkey\":\"8579b74435093690d3d7680ecdac0dd1b892dc5ecd4fb603f0e22fd003176342\",\"method\":\"trust\",\"trust\":1}" +curl --url "http://127.0.0.1:7783" --data "{\"userpass\":\"$userpass\",\"pubkey\":\"c4e3c95bd9612cce3fe1cfcc0a0e9c625bab7e4b83bc68f0ede73633e6a8c17f\",\"method\":\"trust\",\"trust\":1}" +curl --url "http://127.0.0.1:7783" --data "{\"userpass\":\"$userpass\",\"pubkey\":\"43467b51e07fae3b19101fca7fe1bf250d34c8deecfd493c723f87d5eda1a64b\",\"method\":\"trust\",\"trust\":1}" +curl --url "http://127.0.0.1:7783" --data "{\"userpass\":\"$userpass\",\"pubkey\":\"e900c42a0d883d098f382b59cf5655dd1d92b2c94f6580095a4f6382514f7a59\",\"method\":\"trust\",\"trust\":1}" From a48f952622c50f4b8745ddb669e8bcfc7a87737a Mon Sep 17 00:00:00 2001 From: jl777 Date: Fri, 3 Nov 2017 22:06:41 +0200 Subject: [PATCH 0175/1664] Test --- iguana/exchanges/LP_nativeDEX.c | 10 +++++----- iguana/exchanges/LP_network.c | 2 +- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/iguana/exchanges/LP_nativeDEX.c b/iguana/exchanges/LP_nativeDEX.c index 42e41cfba..a24f6f8a1 100644 --- a/iguana/exchanges/LP_nativeDEX.c +++ b/iguana/exchanges/LP_nativeDEX.c @@ -554,17 +554,17 @@ void LP_coinsloop(void *_coins) if ( strcmp("BTC",coins) == 0 ) { strcpy(LP_coinsloopBTC_stats.name,"BTC coin loop"); - LP_coinsloopBTC_stats.threshold = 200.; + LP_coinsloopBTC_stats.threshold = 2000.; } else if ( strcmp("KMD",coins) == 0 ) { strcpy(LP_coinsloopKMD_stats.name,"KMD coin loop"); - LP_coinsloopKMD_stats.threshold = 200.; + LP_coinsloopKMD_stats.threshold = 1000.; } else { strcpy(LP_coinsloop_stats.name,"other coins loop"); - LP_coinsloop_stats.threshold = 200.; + LP_coinsloop_stats.threshold = 500.; } while ( 1 ) { @@ -843,7 +843,7 @@ void LP_pubkeysloop(void *ctx) { static uint32_t lasttime; strcpy(LP_pubkeysloop_stats.name,"LP_pubkeysloop"); - LP_pubkeysloop_stats.threshold = 3100.; + LP_pubkeysloop_stats.threshold = 5000.; sleep(10); while ( 1 ) { @@ -861,7 +861,7 @@ void LP_pubkeysloop(void *ctx) void LP_privkeysloop(void *ctx) { strcpy(LP_privkeysloop_stats.name,"LP_privkeysloop"); - LP_privkeysloop_stats.threshold = (LP_ORDERBOOK_DURATION * .777 * 1000) + 1000; + LP_privkeysloop_stats.threshold = (LP_ORDERBOOK_DURATION * .8 * 1000) + 10000; sleep(20); while ( 1 ) { diff --git a/iguana/exchanges/LP_network.c b/iguana/exchanges/LP_network.c index 522abd999..df8eab0f6 100644 --- a/iguana/exchanges/LP_network.c +++ b/iguana/exchanges/LP_network.c @@ -269,7 +269,7 @@ void queue_loop(void *arg) { struct LP_queue *ptr,*tmp; int32_t sentbytes,nonz,flag,duplicate,n=0; strcpy(queue_loop_stats.name,"queue_loop"); - queue_loop_stats.threshold = 200.; + queue_loop_stats.threshold = 500.; while ( 1 ) { LP_millistats_update(&queue_loop_stats); From 24ae83e907e483ddca3f4160535bcd437f5691c0 Mon Sep 17 00:00:00 2001 From: jl777 Date: Fri, 3 Nov 2017 22:20:37 +0200 Subject: [PATCH 0176/1664] Test --- iguana/exchanges/LP_nativeDEX.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/iguana/exchanges/LP_nativeDEX.c b/iguana/exchanges/LP_nativeDEX.c index a24f6f8a1..c952af9db 100644 --- a/iguana/exchanges/LP_nativeDEX.c +++ b/iguana/exchanges/LP_nativeDEX.c @@ -90,7 +90,7 @@ char LP_myipaddr[64],LP_publicaddr[64],USERHOME[512] = { "/root" }; char LP_gui[16] = { "cli" }; char *default_LPnodes[] = { "5.9.253.195", "5.9.253.196", "5.9.253.197", "5.9.253.198", "5.9.253.199", "5.9.253.200", "5.9.253.201", "5.9.253.202", "5.9.253.203", - "51.15.203.171", "51.15.86.136", "51.15.94.249", "51.15.80.18", "51.15.91.40", "51.15.54.2", "51.15.86.31", "51.15.82.29", "51.15.89.155", + //"51.15.203.171", "51.15.86.136", "51.15.94.249", "51.15.80.18", "51.15.91.40", "51.15.54.2", "51.15.86.31", "51.15.82.29", "51.15.89.155", };//"5.9.253.204" }; // From 2d10e5ff7ce8c2f9338ff7d281eea52681417737 Mon Sep 17 00:00:00 2001 From: jl777 Date: Fri, 3 Nov 2017 22:27:04 +0200 Subject: [PATCH 0177/1664] Test --- iguana/exchanges/stats.c | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/iguana/exchanges/stats.c b/iguana/exchanges/stats.c index 0996d3ede..af730f70b 100644 --- a/iguana/exchanges/stats.c +++ b/iguana/exchanges/stats.c @@ -750,7 +750,11 @@ void stats_rpcloop(void *args) sock = accept(bindsock,(struct sockaddr *)&cli_addr,&clilen); if ( sock < 0 ) { - //printf("iguana_rpcloop ERROR on accept usock.%d errno %d %s\n",sock,errno,strerror(errno)); + printf("iguana_rpcloop ERROR on accept usock.%d errno %d %s\n",sock,errno,strerror(errno)); + close(bindsock); + while ( (bindsock= iguana_socket(1,"0.0.0.0",port)) < 0 ) + sleep(3); + printf(">>>>>>>>>> DEX stats 127.0.0.1:%d bind sock.%d DEX stats API enabled <<<<<<<<<\n",port,bindsock); continue; } memcpy(&ipbits,&cli_addr.sin_addr.s_addr,sizeof(ipbits)); From 17edf22bd815e178e9592392fb06168c8dcaed7f Mon Sep 17 00:00:00 2001 From: jl777 Date: Fri, 3 Nov 2017 22:57:04 +0200 Subject: [PATCH 0178/1664] Test --- iguana/exchanges/LP_nativeDEX.c | 26 ++++---------------------- iguana/exchanges/LP_prices.c | 3 --- 2 files changed, 4 insertions(+), 25 deletions(-) diff --git a/iguana/exchanges/LP_nativeDEX.c b/iguana/exchanges/LP_nativeDEX.c index c952af9db..1b7f0a5bf 100644 --- a/iguana/exchanges/LP_nativeDEX.c +++ b/iguana/exchanges/LP_nativeDEX.c @@ -310,8 +310,6 @@ char *LP_process_message(void *ctx,char *typestr,char *myipaddr,int32_t pubsock, portable_mutex_unlock(&LP_commandmutex); if ( jsonstr != 0 && (void *)jsonstr != (void *)ptr && encrypted == 0 ) free(jsonstr); - if ( ptr != 0 ) - nn_freemsg(ptr), ptr = 0; return(retstr); } @@ -323,21 +321,16 @@ int32_t LP_sock_check(char *typestr,void *ctx,char *myipaddr,int32_t pubsock,int while ( nonz < maxdepth && recvlen > 0 ) { nonz++; -#ifndef FROM_JS memset(&pfd,0,sizeof(pfd)); pfd.fd = sock; pfd.events = NN_POLLIN; if ( nn_poll(&pfd,1,1) != 1 ) break; -#endif if ( (recvlen= nn_recv(sock,&ptr,NN_MSG,0)) > 0 ) { methodstr[0] = 0; - if ( 1 ) + if ( 0 ) { -#ifdef FROM_JS - printf("%s RECV.(%s)\n",typestr,(char *)ptr); -#endif cJSON *recvjson; char *mstr;//,*cstr; if ( (recvjson= cJSON_Parse((char *)ptr)) != 0 ) { @@ -349,10 +342,7 @@ int32_t LP_sock_check(char *typestr,void *ctx,char *myipaddr,int32_t pubsock,int free_json(recvjson); } } -#ifdef FROM_JS - else printf("%s got recv.%d\n",typestr,recvlen); -#endif - int32_t validreq = 0; double millis = OS_milliseconds(); + int32_t validreq = 0; if ( strlen((char *)ptr)+sizeof(bits256) <= recvlen ) { if ( LP_magic_check(ptr,recvlen,remoteaddr) <= 0 ) @@ -372,8 +362,6 @@ int32_t LP_sock_check(char *typestr,void *ctx,char *myipaddr,int32_t pubsock,int Broadcaststr = 0; if ( (argjson= cJSON_Parse(str)) != 0 ) { - 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 ) { @@ -385,9 +373,9 @@ int32_t LP_sock_check(char *typestr,void *ctx,char *myipaddr,int32_t pubsock,int } free(str); } - if ( OS_milliseconds()-millis > 1000 ) - printf("%.3f LP_process_message (%s)\n",OS_milliseconds()-millis,methodstr); } + if ( ptr != 0 ) + nn_freemsg(ptr), ptr = 0; } } } @@ -713,9 +701,6 @@ int32_t LP_mainloop_iter(void *ctx,char *myipaddr,struct LP_peerinfo *mypeer,int if ( strcmp(peer->ipaddr,myipaddr) != 0 ) { nonz++; -#ifdef FROM_JS - if ( (rand() % 100) == 0 ) -#endif LP_peersquery(mypeer,pubsock,peer->ipaddr,peer->port,myipaddr,myport); peer->diduquery = 0; LP_peer_pricesquery(peer); @@ -728,9 +713,6 @@ int32_t LP_mainloop_iter(void *ctx,char *myipaddr,struct LP_peerinfo *mypeer,int { peer->diduquery = now; nonz++; -#ifdef FROM_JS - if ( (rand() % 100) == 0 ) -#endif if ( (retstr= issue_LP_notify(peer->ipaddr,peer->port,"127.0.0.1",0,numpeers,G.LP_sessionid,G.LP_myrmd160str,G.LP_mypub25519)) != 0 ) free(retstr); peer->needping = 0; diff --git a/iguana/exchanges/LP_prices.c b/iguana/exchanges/LP_prices.c index 404cd4f9e..f8cb07d77 100644 --- a/iguana/exchanges/LP_prices.c +++ b/iguana/exchanges/LP_prices.c @@ -366,9 +366,6 @@ void LP_peer_pricesquery(struct LP_peerinfo *peer) peer->needping = (uint32_t)time(NULL); if ( (retstr= issue_LP_getprices(peer->ipaddr,peer->port)) != 0 ) { -#ifdef FROM_JS - printf("%s\n",retstr); -#endif if ( (array= cJSON_Parse(retstr)) != 0 ) { if ( is_cJSON_Array(array) && (n= cJSON_GetArraySize(array)) > 0 ) From 13699e717af9222bbd8af16c564218153fc57d8f Mon Sep 17 00:00:00 2001 From: jl777 Date: Fri, 3 Nov 2017 22:58:07 +0200 Subject: [PATCH 0179/1664] Test --- iguana/exchanges/LP_nativeDEX.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/iguana/exchanges/LP_nativeDEX.c b/iguana/exchanges/LP_nativeDEX.c index 1b7f0a5bf..86309dcd8 100644 --- a/iguana/exchanges/LP_nativeDEX.c +++ b/iguana/exchanges/LP_nativeDEX.c @@ -342,7 +342,7 @@ int32_t LP_sock_check(char *typestr,void *ctx,char *myipaddr,int32_t pubsock,int free_json(recvjson); } } - int32_t validreq = 0; + int32_t validreq = 1; if ( strlen((char *)ptr)+sizeof(bits256) <= recvlen ) { if ( LP_magic_check(ptr,recvlen,remoteaddr) <= 0 ) From 3abc82bbef462bb1fbd54fc337ae5d8cd7c62e15 Mon Sep 17 00:00:00 2001 From: jl777 Date: Fri, 3 Nov 2017 23:16:39 +0200 Subject: [PATCH 0180/1664] Test --- iguana/exchanges/LP_nativeDEX.c | 2 +- iguana/exchanges/LP_rpc.c | 1 + iguana/exchanges/stats.c | 22 ++++++++++++++-------- 3 files changed, 16 insertions(+), 9 deletions(-) diff --git a/iguana/exchanges/LP_nativeDEX.c b/iguana/exchanges/LP_nativeDEX.c index 86309dcd8..1b7f0a5bf 100644 --- a/iguana/exchanges/LP_nativeDEX.c +++ b/iguana/exchanges/LP_nativeDEX.c @@ -342,7 +342,7 @@ int32_t LP_sock_check(char *typestr,void *ctx,char *myipaddr,int32_t pubsock,int free_json(recvjson); } } - int32_t validreq = 1; + int32_t validreq = 0; if ( strlen((char *)ptr)+sizeof(bits256) <= recvlen ) { if ( LP_magic_check(ptr,recvlen,remoteaddr) <= 0 ) diff --git a/iguana/exchanges/LP_rpc.c b/iguana/exchanges/LP_rpc.c index 9a546dd8d..1ae9fa023 100644 --- a/iguana/exchanges/LP_rpc.c +++ b/iguana/exchanges/LP_rpc.c @@ -25,6 +25,7 @@ char *LP_issue_curl(char *debugstr,char *destip,uint16_t port,char *url) maxerrs = LP_MAXPEER_ERRORS; if ( peer == 0 || (peer->errors < maxerrs || peer->good >= LP_MINPEER_GOOD) ) { + printf("issue.(%s)\n",url); if ( (retstr= issue_curlt(url,LP_HTTP_TIMEOUT)) == 0 ) { if ( peer != 0 ) diff --git a/iguana/exchanges/stats.c b/iguana/exchanges/stats.c index af730f70b..d62bbe407 100644 --- a/iguana/exchanges/stats.c +++ b/iguana/exchanges/stats.c @@ -732,29 +732,33 @@ void LP_rpc_processreq(void *_ptr) void stats_rpcloop(void *args) { - uint16_t port; int32_t sock,bindsock; socklen_t clilen; struct sockaddr_in cli_addr; uint32_t ipbits; uint64_t arg64; void *arg64ptr; + uint16_t port; int32_t sock,bindsock=-1; socklen_t clilen; struct sockaddr_in cli_addr; uint32_t ipbits; uint64_t arg64; void *arg64ptr; if ( (port= *(uint16_t *)args) == 0 ) port = 7779; RPC_port = port; - while ( (bindsock= iguana_socket(1,"0.0.0.0",port)) < 0 ) + /*while ( (bindsock= iguana_socket(1,"0.0.0.0",port)) < 0 ) { //if ( coin->MAXPEERS == 1 ) // break; //exit(-1); sleep(3); } - printf(">>>>>>>>>> DEX stats 127.0.0.1:%d bind sock.%d DEX stats API enabled <<<<<<<<<\n",port,bindsock); - while ( bindsock >= 0 ) + printf(">>>>>>>>>> DEX stats 127.0.0.1:%d bind sock.%d DEX stats API enabled <<<<<<<<<\n",port,bindsock);*/ + while ( 1 ) { + if ( bindsock < 0 ) + { + while ( (bindsock= iguana_socket(1,"0.0.0.0",port)) < 0 ) + sleep(3); + printf(">>>>>>>>>> DEX stats 127.0.0.1:%d bind sock.%d DEX stats API enabled <<<<<<<<<\n",port,bindsock); + } clilen = sizeof(cli_addr); sock = accept(bindsock,(struct sockaddr *)&cli_addr,&clilen); if ( sock < 0 ) { printf("iguana_rpcloop ERROR on accept usock.%d errno %d %s\n",sock,errno,strerror(errno)); close(bindsock); - while ( (bindsock= iguana_socket(1,"0.0.0.0",port)) < 0 ) - sleep(3); - printf(">>>>>>>>>> DEX stats 127.0.0.1:%d bind sock.%d DEX stats API enabled <<<<<<<<<\n",port,bindsock); + bindsock = -1; continue; } memcpy(&ipbits,&cli_addr.sin_addr.s_addr,sizeof(ipbits)); @@ -773,8 +777,10 @@ void stats_rpcloop(void *args) else if ( OS_thread_create(malloc(sizeof(pthread_t)),NULL,(void *)LP_rpc_processreq,arg64ptr) != 0 ) { printf("error launching rpc handler on port %d\n",port); + // yes, small leak per command } - // yes, small leak per command + close(bindsock); + bindsock = -1; } } From 1e01debee187470a7addbb13de3c085f073b569b Mon Sep 17 00:00:00 2001 From: jl777 Date: Fri, 3 Nov 2017 23:24:41 +0200 Subject: [PATCH 0181/1664] Test --- iguana/exchanges/stats.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/iguana/exchanges/stats.c b/iguana/exchanges/stats.c index d62bbe407..ac33e4d55 100644 --- a/iguana/exchanges/stats.c +++ b/iguana/exchanges/stats.c @@ -732,6 +732,7 @@ void LP_rpc_processreq(void *_ptr) void stats_rpcloop(void *args) { + static uint32_t counter; uint16_t port; int32_t sock,bindsock=-1; socklen_t clilen; struct sockaddr_in cli_addr; uint32_t ipbits; uint64_t arg64; void *arg64ptr; if ( (port= *(uint16_t *)args) == 0 ) port = 7779; @@ -750,7 +751,8 @@ void stats_rpcloop(void *args) { while ( (bindsock= iguana_socket(1,"0.0.0.0",port)) < 0 ) sleep(3); - printf(">>>>>>>>>> DEX stats 127.0.0.1:%d bind sock.%d DEX stats API enabled <<<<<<<<<\n",port,bindsock); + if ( counter++ < 1 ) + printf(">>>>>>>>>> DEX stats 127.0.0.1:%d bind sock.%d DEX stats API enabled <<<<<<<<<\n",port,bindsock); } clilen = sizeof(cli_addr); sock = accept(bindsock,(struct sockaddr *)&cli_addr,&clilen); From 9ae0816f714d47af009af36e8a83524f76c55199 Mon Sep 17 00:00:00 2001 From: jl777 Date: Fri, 3 Nov 2017 23:25:54 +0200 Subject: [PATCH 0182/1664] Test --- iguana/exchanges/LP_rpc.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/iguana/exchanges/LP_rpc.c b/iguana/exchanges/LP_rpc.c index 1ae9fa023..2bdb4f807 100644 --- a/iguana/exchanges/LP_rpc.c +++ b/iguana/exchanges/LP_rpc.c @@ -25,7 +25,7 @@ char *LP_issue_curl(char *debugstr,char *destip,uint16_t port,char *url) maxerrs = LP_MAXPEER_ERRORS; if ( peer == 0 || (peer->errors < maxerrs || peer->good >= LP_MINPEER_GOOD) ) { - printf("issue.(%s)\n",url); + //printf("issue.(%s)\n",url); if ( (retstr= issue_curlt(url,LP_HTTP_TIMEOUT)) == 0 ) { if ( peer != 0 ) From 777c5d7d30408a898946aa713e11145044ca6858 Mon Sep 17 00:00:00 2001 From: jl777 Date: Fri, 3 Nov 2017 23:43:26 +0200 Subject: [PATCH 0183/1664] Test --- iguana/exchanges/stats.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/iguana/exchanges/stats.c b/iguana/exchanges/stats.c index ac33e4d55..a3df24a30 100644 --- a/iguana/exchanges/stats.c +++ b/iguana/exchanges/stats.c @@ -750,7 +750,7 @@ void stats_rpcloop(void *args) if ( bindsock < 0 ) { while ( (bindsock= iguana_socket(1,"0.0.0.0",port)) < 0 ) - sleep(3); + usleep(10000); if ( counter++ < 1 ) printf(">>>>>>>>>> DEX stats 127.0.0.1:%d bind sock.%d DEX stats API enabled <<<<<<<<<\n",port,bindsock); } From e74a8596470b5008e3c17bc65ad6397af06aa91c Mon Sep 17 00:00:00 2001 From: jl777 Date: Fri, 3 Nov 2017 23:44:08 +0200 Subject: [PATCH 0184/1664] Test --- iguana/exchanges/stats.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/iguana/exchanges/stats.c b/iguana/exchanges/stats.c index a3df24a30..0552e32ff 100644 --- a/iguana/exchanges/stats.c +++ b/iguana/exchanges/stats.c @@ -763,6 +763,8 @@ void stats_rpcloop(void *args) bindsock = -1; continue; } + close(bindsock); + bindsock = -1; memcpy(&ipbits,&cli_addr.sin_addr.s_addr,sizeof(ipbits)); arg64 = ((uint64_t)ipbits << 32) | (sock & 0xffffffff); arg64ptr = malloc(sizeof(arg64)); @@ -781,8 +783,6 @@ void stats_rpcloop(void *args) printf("error launching rpc handler on port %d\n",port); // yes, small leak per command } - close(bindsock); - bindsock = -1; } } From fa4bd37395431946cfec57ddb88d39e40ac96a2e Mon Sep 17 00:00:00 2001 From: jl777 Date: Fri, 3 Nov 2017 23:46:30 +0200 Subject: [PATCH 0185/1664] Test --- iguana/exchanges/stats.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/iguana/exchanges/stats.c b/iguana/exchanges/stats.c index 0552e32ff..2d93e296e 100644 --- a/iguana/exchanges/stats.c +++ b/iguana/exchanges/stats.c @@ -219,7 +219,7 @@ int32_t iguana_socket(int32_t bindflag,char *hostname,uint16_t port) return(-1); } } - if ( listen(sock,64) != 0 ) + if ( listen(sock,512) != 0 ) { printf("listen(%s) port.%d failed: %s sock.%d. errno.%d\n",hostname,port,strerror(errno),sock,errno); if ( sock >= 0 ) @@ -764,7 +764,7 @@ void stats_rpcloop(void *args) continue; } close(bindsock); - bindsock = -1; + bindsock = iguana_socket(1,"0.0.0.0",port); memcpy(&ipbits,&cli_addr.sin_addr.s_addr,sizeof(ipbits)); arg64 = ((uint64_t)ipbits << 32) | (sock & 0xffffffff); arg64ptr = malloc(sizeof(arg64)); From 4acaac35490d38316a6ba6f73054b9a6347bf89b Mon Sep 17 00:00:00 2001 From: jl777 Date: Sat, 4 Nov 2017 01:01:43 +0200 Subject: [PATCH 0186/1664] Test --- iguana/exchanges/stats.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/iguana/exchanges/stats.c b/iguana/exchanges/stats.c index 2d93e296e..c58a6f0ca 100644 --- a/iguana/exchanges/stats.c +++ b/iguana/exchanges/stats.c @@ -763,8 +763,6 @@ void stats_rpcloop(void *args) bindsock = -1; continue; } - close(bindsock); - bindsock = iguana_socket(1,"0.0.0.0",port); memcpy(&ipbits,&cli_addr.sin_addr.s_addr,sizeof(ipbits)); arg64 = ((uint64_t)ipbits << 32) | (sock & 0xffffffff); arg64ptr = malloc(sizeof(arg64)); @@ -783,6 +781,8 @@ void stats_rpcloop(void *args) printf("error launching rpc handler on port %d\n",port); // yes, small leak per command } + close(bindsock); + bindsock = iguana_socket(1,"0.0.0.0",port); } } From 66856863ff6155856dd14ba0d87762150e183159 Mon Sep 17 00:00:00 2001 From: jl777 Date: Sat, 4 Nov 2017 01:10:34 +0200 Subject: [PATCH 0187/1664] Test --- iguana/exchanges/stats.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/iguana/exchanges/stats.c b/iguana/exchanges/stats.c index c58a6f0ca..09f54d8c7 100644 --- a/iguana/exchanges/stats.c +++ b/iguana/exchanges/stats.c @@ -771,7 +771,6 @@ void stats_rpcloop(void *args) { LP_rpc_processreq((void *)&arg64); free(arg64ptr); - closesocket(sock); //char remoteaddr[64]; //expand_ipbits(remoteaddr,ipbits); //printf("finished RPC request from (%s) %x\n",remoteaddr,ipbits); @@ -782,6 +781,7 @@ void stats_rpcloop(void *args) // yes, small leak per command } close(bindsock); + closesocket(sock); bindsock = iguana_socket(1,"0.0.0.0",port); } } From 7f3723c894b36a5fa548ab6b8c6175e83d012914 Mon Sep 17 00:00:00 2001 From: jl777 Date: Sat, 4 Nov 2017 01:36:58 +0200 Subject: [PATCH 0188/1664] Test --- iguana/exchanges/LP_rpc.c | 4 +++- iguana/exchanges/LP_socket.c | 1 + 2 files changed, 4 insertions(+), 1 deletion(-) diff --git a/iguana/exchanges/LP_rpc.c b/iguana/exchanges/LP_rpc.c index 2bdb4f807..15175e95f 100644 --- a/iguana/exchanges/LP_rpc.c +++ b/iguana/exchanges/LP_rpc.c @@ -111,7 +111,7 @@ char *LP_apicall(struct iguana_info *coin,char *method,char *params) { if ( (retjson= electrum_submit(coin->symbol,coin->electrum,&retjson,method,params,ELECTRUM_TIMEOUT)) != 0 ) { - retstr = jprint(retjson,0); + retstr = jprint(retjson,1); //printf("got.%p (%s)\n",retjson,retstr); return(retstr); } return(clonestr("{\"error\":\"electrum no response\"}")); @@ -808,6 +808,8 @@ double _LP_getestimatedrate(struct iguana_info *coin) sprintf(buf,"[%d]",strcmp(coin->symbol,"BTC") == 0 ? 6 : 2); if ( (retstr= LP_apicall(coin,coin->electrum==0?"estimatefee" : "blockchain.estimatefee",buf)) != 0 ) { + if ( coin->electrum != 0 ) + printf("estimatefee.(%s)\n",retstr); if ( retstr[0] == '{' && (errjson= cJSON_Parse(retstr)) != 0 ) { if ( jobj(errjson,"error") != 0 ) diff --git a/iguana/exchanges/LP_socket.c b/iguana/exchanges/LP_socket.c index 16da1a0c3..8907be909 100644 --- a/iguana/exchanges/LP_socket.c +++ b/iguana/exchanges/LP_socket.c @@ -592,6 +592,7 @@ cJSON *electrum_addpeer(char *symbol,struct electrum_info *ep,cJSON **retjsonp,c cJSON *electrum_sendrawtransaction(char *symbol,struct electrum_info *ep,cJSON **retjsonp,char *rawtx) { return(electrum_strarg(symbol,ep,retjsonp,"blockchain.transaction.broadcast",rawtx,ELECTRUM_TIMEOUT)); } cJSON *electrum_estimatefee(char *symbol,struct electrum_info *ep,cJSON **retjsonp,int32_t numblocks) { return(electrum_intarg(symbol,ep,retjsonp,"blockchain.estimatefee",numblocks,ELECTRUM_TIMEOUT)); } + cJSON *electrum_getchunk(char *symbol,struct electrum_info *ep,cJSON **retjsonp,int32_t n) { return(electrum_intarg(symbol,ep,retjsonp,"blockchain.block.get_chunk",n,ELECTRUM_TIMEOUT)); } cJSON *electrum_getheader(char *symbol,struct electrum_info *ep,cJSON **retjsonp,int32_t n) From 66945feec7572f438a7b7fe951a52fe863fd4e8d Mon Sep 17 00:00:00 2001 From: jl777 Date: Sat, 4 Nov 2017 01:39:02 +0200 Subject: [PATCH 0189/1664] Test --- iguana/exchanges/stats.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/iguana/exchanges/stats.c b/iguana/exchanges/stats.c index 09f54d8c7..c75bee6f2 100644 --- a/iguana/exchanges/stats.c +++ b/iguana/exchanges/stats.c @@ -219,7 +219,7 @@ int32_t iguana_socket(int32_t bindflag,char *hostname,uint16_t port) return(-1); } } - if ( listen(sock,512) != 0 ) + if ( listen(sock,1) != 0 ) { printf("listen(%s) port.%d failed: %s sock.%d. errno.%d\n",hostname,port,strerror(errno),sock,errno); if ( sock >= 0 ) From 714bfc992c03a01e9a1d63a1389a343e3f2261a1 Mon Sep 17 00:00:00 2001 From: jl777 Date: Sat, 4 Nov 2017 01:46:55 +0200 Subject: [PATCH 0190/1664] Test --- iguana/exchanges/stats.c | 15 ++++++++------- 1 file changed, 8 insertions(+), 7 deletions(-) diff --git a/iguana/exchanges/stats.c b/iguana/exchanges/stats.c index c75bee6f2..979ed57da 100644 --- a/iguana/exchanges/stats.c +++ b/iguana/exchanges/stats.c @@ -733,10 +733,11 @@ void LP_rpc_processreq(void *_ptr) void stats_rpcloop(void *args) { static uint32_t counter; - uint16_t port; int32_t sock,bindsock=-1; socklen_t clilen; struct sockaddr_in cli_addr; uint32_t ipbits; uint64_t arg64; void *arg64ptr; + uint16_t port; int32_t sock,bindsock=-1; socklen_t clilen; struct sockaddr_in cli_addr; uint32_t ipbits,localhostbits; uint64_t arg64; void *arg64ptr; if ( (port= *(uint16_t *)args) == 0 ) port = 7779; RPC_port = port; + localhostbits = calc_ipbits("127.0.0.1"); /*while ( (bindsock= iguana_socket(1,"0.0.0.0",port)) < 0 ) { //if ( coin->MAXPEERS == 1 ) @@ -771,18 +772,18 @@ void stats_rpcloop(void *args) { LP_rpc_processreq((void *)&arg64); free(arg64ptr); - //char remoteaddr[64]; - //expand_ipbits(remoteaddr,ipbits); - //printf("finished RPC request from (%s) %x\n",remoteaddr,ipbits); + closesocket(sock); } else if ( OS_thread_create(malloc(sizeof(pthread_t)),NULL,(void *)LP_rpc_processreq,arg64ptr) != 0 ) { printf("error launching rpc handler on port %d\n",port); // yes, small leak per command } - close(bindsock); - closesocket(sock); - bindsock = iguana_socket(1,"0.0.0.0",port); + if ( ipbits != localhostbits ) + { + close(bindsock); + bindsock = iguana_socket(1,"0.0.0.0",port); + } else printf("skip close and rebind\n"); } } From e9195392925764f4ed382e33c4fa20b1b89d8934 Mon Sep 17 00:00:00 2001 From: jl777 Date: Sat, 4 Nov 2017 01:47:37 +0200 Subject: [PATCH 0191/1664] Test --- iguana/exchanges/stats.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/iguana/exchanges/stats.c b/iguana/exchanges/stats.c index 979ed57da..7351c6f5a 100644 --- a/iguana/exchanges/stats.c +++ b/iguana/exchanges/stats.c @@ -737,7 +737,7 @@ void stats_rpcloop(void *args) if ( (port= *(uint16_t *)args) == 0 ) port = 7779; RPC_port = port; - localhostbits = calc_ipbits("127.0.0.1"); + localhostbits = (uint32_t)calc_ipbits("127.0.0.1"); /*while ( (bindsock= iguana_socket(1,"0.0.0.0",port)) < 0 ) { //if ( coin->MAXPEERS == 1 ) @@ -783,7 +783,7 @@ void stats_rpcloop(void *args) { close(bindsock); bindsock = iguana_socket(1,"0.0.0.0",port); - } else printf("skip close and rebind\n"); + } //else printf("skip close and rebind\n"); } } From d4a6e190dd838b1c7a6ee768a01f319d9e952659 Mon Sep 17 00:00:00 2001 From: jl777 Date: Sat, 4 Nov 2017 01:54:21 +0200 Subject: [PATCH 0192/1664] Test --- iguana/exchanges/LP_rpc.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/iguana/exchanges/LP_rpc.c b/iguana/exchanges/LP_rpc.c index 15175e95f..eb9abe808 100644 --- a/iguana/exchanges/LP_rpc.c +++ b/iguana/exchanges/LP_rpc.c @@ -830,7 +830,7 @@ double _LP_getestimatedrate(struct iguana_info *coin) coin->ratetime = (uint32_t)time(NULL); } free(retstr); - } + } else rate = coin->rate; } else rate = coin->rate; return(rate); } From 22ae89f43781ef5a87de374f7a3208d8d67dd5f6 Mon Sep 17 00:00:00 2001 From: jl777 Date: Sat, 4 Nov 2017 06:09:34 +0200 Subject: [PATCH 0193/1664] Test --- iguana/exchanges/stats.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/iguana/exchanges/stats.c b/iguana/exchanges/stats.c index 7351c6f5a..27b44c8c1 100644 --- a/iguana/exchanges/stats.c +++ b/iguana/exchanges/stats.c @@ -779,7 +779,7 @@ void stats_rpcloop(void *args) printf("error launching rpc handler on port %d\n",port); // yes, small leak per command } - if ( ipbits != localhostbits ) + ///if ( ipbits != localhostbits ) { close(bindsock); bindsock = iguana_socket(1,"0.0.0.0",port); From b81df95c222402044899e8d79e10f95b2daf9499 Mon Sep 17 00:00:00 2001 From: jl777 Date: Sat, 4 Nov 2017 06:39:53 +0200 Subject: [PATCH 0194/1664] Test --- iguana/exchanges/stats.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/iguana/exchanges/stats.c b/iguana/exchanges/stats.c index 27b44c8c1..7351c6f5a 100644 --- a/iguana/exchanges/stats.c +++ b/iguana/exchanges/stats.c @@ -779,7 +779,7 @@ void stats_rpcloop(void *args) printf("error launching rpc handler on port %d\n",port); // yes, small leak per command } - ///if ( ipbits != localhostbits ) + if ( ipbits != localhostbits ) { close(bindsock); bindsock = iguana_socket(1,"0.0.0.0",port); From 68173f049dd1d84ec787b839b269dc5259b708eb Mon Sep 17 00:00:00 2001 From: jl777 Date: Sat, 4 Nov 2017 14:30:19 +0200 Subject: [PATCH 0195/1664] Test --- iguana/exchanges/stats.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/iguana/exchanges/stats.c b/iguana/exchanges/stats.c index 7351c6f5a..65e2f4208 100644 --- a/iguana/exchanges/stats.c +++ b/iguana/exchanges/stats.c @@ -730,6 +730,7 @@ void LP_rpc_processreq(void *_ptr) free(jsonbuf); } +extern int32_t IAMLP; void stats_rpcloop(void *args) { static uint32_t counter; @@ -779,7 +780,7 @@ void stats_rpcloop(void *args) printf("error launching rpc handler on port %d\n",port); // yes, small leak per command } - if ( ipbits != localhostbits ) + if ( IAMLP != 0 && ipbits != localhostbits ) { close(bindsock); bindsock = iguana_socket(1,"0.0.0.0",port); From 5b99aaf585ce4e2991bc60c1b0a2d592935c5606 Mon Sep 17 00:00:00 2001 From: jl777 Date: Sat, 4 Nov 2017 15:21:44 +0200 Subject: [PATCH 0196/1664] Increase listen --- iguana/exchanges/stats.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/iguana/exchanges/stats.c b/iguana/exchanges/stats.c index 65e2f4208..3c9bf0636 100644 --- a/iguana/exchanges/stats.c +++ b/iguana/exchanges/stats.c @@ -219,7 +219,7 @@ int32_t iguana_socket(int32_t bindflag,char *hostname,uint16_t port) return(-1); } } - if ( listen(sock,1) != 0 ) + if ( listen(sock,32) != 0 ) { printf("listen(%s) port.%d failed: %s sock.%d. errno.%d\n",hostname,port,strerror(errno),sock,errno); if ( sock >= 0 ) From d11f48d2d6afd44b9e398d1d6f8324af8d6c96a8 Mon Sep 17 00:00:00 2001 From: jl777 Date: Sat, 4 Nov 2017 15:22:11 +0200 Subject: [PATCH 0197/1664] Test --- iguana/exchanges/stats.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/iguana/exchanges/stats.c b/iguana/exchanges/stats.c index 65e2f4208..3f0f5784f 100644 --- a/iguana/exchanges/stats.c +++ b/iguana/exchanges/stats.c @@ -219,7 +219,7 @@ int32_t iguana_socket(int32_t bindflag,char *hostname,uint16_t port) return(-1); } } - if ( listen(sock,1) != 0 ) + if ( listen(sock,64) != 0 ) { printf("listen(%s) port.%d failed: %s sock.%d. errno.%d\n",hostname,port,strerror(errno),sock,errno); if ( sock >= 0 ) From 42462bd9c0a1305a7ad03e66fa3ee5b8b48bf42f Mon Sep 17 00:00:00 2001 From: jl777 Date: Sat, 4 Nov 2017 20:43:27 +0200 Subject: [PATCH 0198/1664] Test --- iguana/exchanges/LP_nativeDEX.c | 2 +- iguana/exchanges/stats.c | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/iguana/exchanges/LP_nativeDEX.c b/iguana/exchanges/LP_nativeDEX.c index 1b7f0a5bf..6ab35be68 100644 --- a/iguana/exchanges/LP_nativeDEX.c +++ b/iguana/exchanges/LP_nativeDEX.c @@ -1095,7 +1095,7 @@ void LPinit(uint16_t myport,uint16_t mypullport,uint16_t mypubport,uint16_t mybu printf("error launching stats rpcloop for port.%u\n",myport); exit(-1); } - if ( OS_thread_create(malloc(sizeof(pthread_t)),NULL,(void *)command_rpcloop,(void *)myipaddr) != 0 ) + if ( 0 && OS_thread_create(malloc(sizeof(pthread_t)),NULL,(void *)command_rpcloop,(void *)myipaddr) != 0 ) { printf("error launching command_rpcloop for port.%u\n",myport); exit(-1); diff --git a/iguana/exchanges/stats.c b/iguana/exchanges/stats.c index 3f0f5784f..e3ee8a3b5 100644 --- a/iguana/exchanges/stats.c +++ b/iguana/exchanges/stats.c @@ -780,7 +780,7 @@ void stats_rpcloop(void *args) printf("error launching rpc handler on port %d\n",port); // yes, small leak per command } - if ( IAMLP != 0 && ipbits != localhostbits ) + if ( 0 && IAMLP != 0 && ipbits != localhostbits ) { close(bindsock); bindsock = iguana_socket(1,"0.0.0.0",port); From de82ba78ada29813b8f96b998bf4967a09e094f7 Mon Sep 17 00:00:00 2001 From: jl777 Date: Sat, 4 Nov 2017 20:51:33 +0200 Subject: [PATCH 0199/1664] Test --- iguana/exchanges/LP_nativeDEX.c | 4 ++-- iguana/exchanges/LP_signatures.c | 7 +++---- 2 files changed, 5 insertions(+), 6 deletions(-) diff --git a/iguana/exchanges/LP_nativeDEX.c b/iguana/exchanges/LP_nativeDEX.c index 6ab35be68..aeb6c8801 100644 --- a/iguana/exchanges/LP_nativeDEX.c +++ b/iguana/exchanges/LP_nativeDEX.c @@ -926,12 +926,12 @@ int32_t LP_reserved_msg(int32_t priority,char *base,char *rel,bits256 pubkey,cha Reserved_msgs[priority][num_Reserved_msgs[priority]++] = msg; n = num_Reserved_msgs[priority]; } else LP_broadcast_message(LP_mypubsock,base,rel,pubkey,msg); - portable_mutex_unlock(&LP_reservedmutex); if ( num_Reserved_msgs[priority] > max_Reserved_msgs[priority] ) { max_Reserved_msgs[priority] = num_Reserved_msgs[priority]; printf("New priority.%d max_Reserved_msgs.%d\n",priority,max_Reserved_msgs[priority]); } + portable_mutex_unlock(&LP_reservedmutex); return(n); } @@ -1095,7 +1095,7 @@ void LPinit(uint16_t myport,uint16_t mypullport,uint16_t mypubport,uint16_t mybu printf("error launching stats rpcloop for port.%u\n",myport); exit(-1); } - if ( 0 && OS_thread_create(malloc(sizeof(pthread_t)),NULL,(void *)command_rpcloop,(void *)myipaddr) != 0 ) + if ( OS_thread_create(malloc(sizeof(pthread_t)),NULL,(void *)command_rpcloop,(void *)myipaddr) != 0 ) { printf("error launching command_rpcloop for port.%u\n",myport); exit(-1); diff --git a/iguana/exchanges/LP_signatures.c b/iguana/exchanges/LP_signatures.c index e47e56d81..1933f50a3 100644 --- a/iguana/exchanges/LP_signatures.c +++ b/iguana/exchanges/LP_signatures.c @@ -685,11 +685,10 @@ void LP_query(void *ctx,char *myipaddr,int32_t mypubsock,char *method,struct LP_ memset(&zero,0,sizeof(zero)); portable_mutex_lock(&LP_reservedmutex); if ( num_Reserved_msgs[1] < sizeof(Reserved_msgs[1])/sizeof(*Reserved_msgs[1])-2 ) - { Reserved_msgs[1][num_Reserved_msgs[1]++] = msg; - //Reserved_msgs[num_Reserved_msgs++] = msg2; - } - LP_broadcast_message(LP_mypubsock,qp->srccoin,qp->destcoin,zero,msg2); + if ( num_Reserved_msgs[0] < sizeof(Reserved_msgs[0])/sizeof(*Reserved_msgs[0])-2 ) + Reserved_msgs[0][num_Reserved_msgs[0]++] = msg2; + //LP_broadcast_message(LP_mypubsock,qp->srccoin,qp->destcoin,zero,msg2); portable_mutex_unlock(&LP_reservedmutex); } From dbda4bac05bb95026c2b4d8b7ea107c18d8aa992 Mon Sep 17 00:00:00 2001 From: jl777 Date: Sat, 4 Nov 2017 21:17:45 +0200 Subject: [PATCH 0200/1664] Test --- iguana/exchanges/LP_portfolio.c | 5 ++++- iguana/exchanges/stats.c | 4 ++-- 2 files changed, 6 insertions(+), 3 deletions(-) diff --git a/iguana/exchanges/LP_portfolio.c b/iguana/exchanges/LP_portfolio.c index 8e8dc23ca..c7ada04db 100644 --- a/iguana/exchanges/LP_portfolio.c +++ b/iguana/exchanges/LP_portfolio.c @@ -298,7 +298,7 @@ void LP_autopriceset(void *ctx,int32_t dir,struct LP_priceinfo *basepp,struct LP if ( (minprice= basepp->minprices[relpp->ind]) == 0. || price >= minprice ) { LP_mypriceset(&changed,relpp->symbol,basepp->symbol,newprice); - //printf("autoprice changed.%d %s/%s <- %.8f\n",changed,basepp->symbol,relpp->symbol,price); + printf("autoprice changed.%d %s/%s <- %.8f\n",changed,basepp->symbol,relpp->symbol,price); if ( changed != 0 || time(NULL) > lasttime+LP_ORDERBOOK_DURATION*.777) { lasttime = (uint32_t)time(NULL); @@ -468,7 +468,10 @@ void LP_autoprice_iter(void *ctx,struct LP_priceinfo *btcpp) basepp = LP_priceinfofind(LP_autorefs[i].base); relpp = LP_priceinfofind(LP_autorefs[i].rel); if ( basepp != 0 && relpp != 0 ) + { + printf("check ref-autoprice %s/%s\n",LP_autorefs[i].refbase,LP_autorefs[i].refrel); LP_autopriceset(ctx,1,basepp,relpp,0,LP_autorefs[i].refbase,LP_autorefs[i].refrel); + } } } diff --git a/iguana/exchanges/stats.c b/iguana/exchanges/stats.c index e3ee8a3b5..aa2067e0b 100644 --- a/iguana/exchanges/stats.c +++ b/iguana/exchanges/stats.c @@ -780,11 +780,11 @@ void stats_rpcloop(void *args) printf("error launching rpc handler on port %d\n",port); // yes, small leak per command } - if ( 0 && IAMLP != 0 && ipbits != localhostbits ) + /*if ( 0 && IAMLP != 0 && ipbits != localhostbits ) { close(bindsock); bindsock = iguana_socket(1,"0.0.0.0",port); - } //else printf("skip close and rebind\n"); + } //else printf("skip close and rebind\n");*/ } } From dfa52e84d7f8494376175d5130bfafc0f60ef5b2 Mon Sep 17 00:00:00 2001 From: jl777 Date: Sat, 4 Nov 2017 21:34:08 +0200 Subject: [PATCH 0201/1664] Test --- iguana/exchanges/stats.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/iguana/exchanges/stats.c b/iguana/exchanges/stats.c index aa2067e0b..21558ce18 100644 --- a/iguana/exchanges/stats.c +++ b/iguana/exchanges/stats.c @@ -651,7 +651,7 @@ void LP_rpc_processreq(void *_ptr) else { usleep(10000); - //printf("got.(%s) %d remains.%d of total.%d\n",jsonbuf,recvlen,remains,len); + printf("got.(%s) %d remains.%d of total.%d\n",jsonbuf,recvlen,remains,len); //retstr = iguana_rpcparse(space,size,&postflag,jsonbuf); if ( flag == 0 ) break; @@ -662,11 +662,11 @@ void LP_rpc_processreq(void *_ptr) if ( recvlen > 0 ) { jsonflag = postflag = 0; - portable_mutex_lock(&LP_commandmutex); + //portable_mutex_lock(&LP_commandmutex); retstr = stats_rpcparse(space,size,&jsonflag,&postflag,jsonbuf,remoteaddr,filetype,RPC_port); //if ( strcmp("5.9.253.195",remoteaddr) == 0 ) // printf("RPC.(%s)%s\n",jsonbuf,retstr); - portable_mutex_unlock(&LP_commandmutex); + //portable_mutex_unlock(&LP_commandmutex); if ( filetype[0] != 0 ) { static cJSON *mimejson; char *tmp,*typestr=0; long tmpsize; From 1c541ac34d3c2daa6a440f49a2d1c326e2cda429 Mon Sep 17 00:00:00 2001 From: jl777 Date: Sat, 4 Nov 2017 21:45:43 +0200 Subject: [PATCH 0202/1664] Test --- iguana/exchanges/LP_portfolio.c | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) diff --git a/iguana/exchanges/LP_portfolio.c b/iguana/exchanges/LP_portfolio.c index c7ada04db..5c94b9695 100644 --- a/iguana/exchanges/LP_portfolio.c +++ b/iguana/exchanges/LP_portfolio.c @@ -293,12 +293,10 @@ void LP_autopriceset(void *ctx,int32_t dir,struct LP_priceinfo *basepp,struct LP if ( dir > 0 ) newprice = (1. / price) * (1. + margin); else newprice = (price * (1. + margin)); - - //newprice = 1. / (price * (1. - margin)); if ( (minprice= basepp->minprices[relpp->ind]) == 0. || price >= minprice ) { LP_mypriceset(&changed,relpp->symbol,basepp->symbol,newprice); - printf("autoprice changed.%d %s/%s <- %.8f\n",changed,basepp->symbol,relpp->symbol,price); + //printf("autoprice changed.%d %s/%s <- %.8f\n",changed,basepp->symbol,relpp->symbol,price); if ( changed != 0 || time(NULL) > lasttime+LP_ORDERBOOK_DURATION*.777) { lasttime = (uint32_t)time(NULL); @@ -469,8 +467,8 @@ void LP_autoprice_iter(void *ctx,struct LP_priceinfo *btcpp) relpp = LP_priceinfofind(LP_autorefs[i].rel); if ( basepp != 0 && relpp != 0 ) { - printf("check ref-autoprice %s/%s\n",LP_autorefs[i].refbase,LP_autorefs[i].refrel); - LP_autopriceset(ctx,1,basepp,relpp,0,LP_autorefs[i].refbase,LP_autorefs[i].refrel); + //printf("check ref-autoprice %s/%s\n",LP_autorefs[i].refbase,LP_autorefs[i].refrel); + LP_autopriceset(ctx,1,basepp,relpp,0.,LP_autorefs[i].refbase,LP_autorefs[i].refrel); } } } @@ -600,6 +598,7 @@ void prices_loop(void *ctx) LP_tradebots_timeslice(ctx); if ( (btcpp= LP_priceinfofind("BTC")) == 0 ) { + printf("prices_loop BTC not in LP_priceinfofind\n"); sleep(60); continue; } From ac1f7c6eee02268949cdca9a3ee12b76732a1f2a Mon Sep 17 00:00:00 2001 From: jl777 Date: Sat, 4 Nov 2017 21:47:45 +0200 Subject: [PATCH 0203/1664] Test --- iguana/exchanges/stats.c | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/iguana/exchanges/stats.c b/iguana/exchanges/stats.c index 21558ce18..9028beaab 100644 --- a/iguana/exchanges/stats.c +++ b/iguana/exchanges/stats.c @@ -662,11 +662,9 @@ void LP_rpc_processreq(void *_ptr) if ( recvlen > 0 ) { jsonflag = postflag = 0; - //portable_mutex_lock(&LP_commandmutex); + portable_mutex_lock(&LP_commandmutex); retstr = stats_rpcparse(space,size,&jsonflag,&postflag,jsonbuf,remoteaddr,filetype,RPC_port); - //if ( strcmp("5.9.253.195",remoteaddr) == 0 ) - // printf("RPC.(%s)%s\n",jsonbuf,retstr); - //portable_mutex_unlock(&LP_commandmutex); + portable_mutex_unlock(&LP_commandmutex); if ( filetype[0] != 0 ) { static cJSON *mimejson; char *tmp,*typestr=0; long tmpsize; From 9c44f55fa742a439d1fe58f7a113d2bd5440d4ed Mon Sep 17 00:00:00 2001 From: jl777 Date: Sat, 4 Nov 2017 22:15:45 +0200 Subject: [PATCH 0204/1664] Test --- iguana/exchanges/stats.c | 30 +++++++++++++++--------------- 1 file changed, 15 insertions(+), 15 deletions(-) diff --git a/iguana/exchanges/stats.c b/iguana/exchanges/stats.c index 9028beaab..02dac05a6 100644 --- a/iguana/exchanges/stats.c +++ b/iguana/exchanges/stats.c @@ -590,17 +590,17 @@ int32_t iguana_getheadersize(char *buf,int32_t recvlen) uint16_t RPC_port; extern portable_mutex_t LP_commandmutex; +struct rpcrequest_info { pthread_t T; int32_t sock; uint32_t ipbits; }; void LP_rpc_processreq(void *_ptr) { - uint64_t arg64 = *(uint64_t *)_ptr; char filetype[128],content_type[128]; int32_t recvlen,flag,postflag=0,contentlen,remains,sock,numsent,jsonflag=0,hdrsize,len; - char helpname[512],remoteaddr[64],*buf,*retstr,*space,*jsonbuf; + char helpname[512],remoteaddr[64],*buf,*retstr,*space,*jsonbuf; struct rpcrequest_info *req = _ptr; uint32_t ipbits,i,size = 32*IGUANA_MAXPACKETSIZE + 512; - ipbits = (arg64 >> 32); + ipbits = req->ipbits;; expand_ipbits(remoteaddr,ipbits); - sock = (arg64 & 0xffffffff); + sock = req->sock; recvlen = flag = 0; retstr = 0; space = calloc(1,size); @@ -652,7 +652,6 @@ void LP_rpc_processreq(void *_ptr) { usleep(10000); printf("got.(%s) %d remains.%d of total.%d\n",jsonbuf,recvlen,remains,len); - //retstr = iguana_rpcparse(space,size,&postflag,jsonbuf); if ( flag == 0 ) break; } @@ -726,13 +725,15 @@ void LP_rpc_processreq(void *_ptr) } free(space); free(jsonbuf); + closesocket(sock); + free(_ptr); } extern int32_t IAMLP; void stats_rpcloop(void *args) { static uint32_t counter; - uint16_t port; int32_t sock,bindsock=-1; socklen_t clilen; struct sockaddr_in cli_addr; uint32_t ipbits,localhostbits; uint64_t arg64; void *arg64ptr; + uint16_t port; int32_t sock,bindsock=-1; socklen_t clilen; struct sockaddr_in cli_addr; uint32_t ipbits,localhostbits; struct rpcrequest_info *req; if ( (port= *(uint16_t *)args) == 0 ) port = 7779; RPC_port = port; @@ -764,19 +765,18 @@ void stats_rpcloop(void *args) continue; } memcpy(&ipbits,&cli_addr.sin_addr.s_addr,sizeof(ipbits)); - arg64 = ((uint64_t)ipbits << 32) | (sock & 0xffffffff); - arg64ptr = malloc(sizeof(arg64)); - memcpy(arg64ptr,&arg64,sizeof(arg64)); - if ( 1 ) + req = calloc(1,sizeof(*req)); + req->sock = sock; + req->ipbits = ipbits; + if ( 0 ) { - LP_rpc_processreq((void *)&arg64); - free(arg64ptr); - closesocket(sock); + //LP_rpc_processreq((void *)&arg64); + //free(arg64ptr); + //closesocket(sock); } - else if ( OS_thread_create(malloc(sizeof(pthread_t)),NULL,(void *)LP_rpc_processreq,arg64ptr) != 0 ) + else if ( OS_thread_create(&req->T,NULL,(void *)LP_rpc_processreq,req) != 0 ) { printf("error launching rpc handler on port %d\n",port); - // yes, small leak per command } /*if ( 0 && IAMLP != 0 && ipbits != localhostbits ) { From 9b11cc612ef18a08fed73a40f1d71b3993681e8c Mon Sep 17 00:00:00 2001 From: jl777 Date: Sat, 4 Nov 2017 22:56:47 +0200 Subject: [PATCH 0205/1664] Test --- crypto777/OS_portable.h | 8 ++++++++ iguana/exchanges/LP_nativeDEX.c | 1 + iguana/exchanges/LP_network.c | 11 ++++++++++- iguana/exchanges/stats.c | 18 +++++++++++++++--- 4 files changed, 34 insertions(+), 4 deletions(-) diff --git a/crypto777/OS_portable.h b/crypto777/OS_portable.h index 77e6ec5bc..6c4a3ecbc 100755 --- a/crypto777/OS_portable.h +++ b/crypto777/OS_portable.h @@ -143,6 +143,14 @@ typedef struct queue char name[64],initflag; } queue_t; +struct rpcrequest_info +{ + struct rpcrequest_info *next,*prev; + pthread_t T; + int32_t sock; + uint32_t ipbits; +}; + struct OS_mappedptr { char fname[512]; diff --git a/iguana/exchanges/LP_nativeDEX.c b/iguana/exchanges/LP_nativeDEX.c index aeb6c8801..1787e300d 100644 --- a/iguana/exchanges/LP_nativeDEX.c +++ b/iguana/exchanges/LP_nativeDEX.c @@ -81,6 +81,7 @@ struct LP_peerinfo *LP_peerinfos,*LP_mypeer; struct LP_forwardinfo *LP_forwardinfos; struct iguana_info *LP_coins; struct LP_pubkeyinfo *LP_pubkeyinfos; +struct rpcrequest_info *LP_garbage_collector; #include "LP_network.c" diff --git a/iguana/exchanges/LP_network.c b/iguana/exchanges/LP_network.c index df8eab0f6..14cae1f3a 100644 --- a/iguana/exchanges/LP_network.c +++ b/iguana/exchanges/LP_network.c @@ -267,12 +267,21 @@ int32_t LP_peerindsock(int32_t *peerindp) void queue_loop(void *arg) { - struct LP_queue *ptr,*tmp; int32_t sentbytes,nonz,flag,duplicate,n=0; + struct rpcrequest_info *req,*rtmp; struct LP_queue *ptr,*tmp; int32_t sentbytes,nonz,flag,duplicate,n=0; strcpy(queue_loop_stats.name,"queue_loop"); queue_loop_stats.threshold = 500.; while ( 1 ) { LP_millistats_update(&queue_loop_stats); + portable_mutex_lock(&LP_networkmutex); + DL_FOREACH_SAFE(LP_garbage_collector,req,rtmp) + { + DL_DELETE(LP_garbage_collector,req); + printf("garbage collect ipbits.%x\n",req->ipbits); + free(req); + } + portable_mutex_unlock(&LP_networkmutex); + 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; diff --git a/iguana/exchanges/stats.c b/iguana/exchanges/stats.c index 02dac05a6..ab82d9f53 100644 --- a/iguana/exchanges/stats.c +++ b/iguana/exchanges/stats.c @@ -589,11 +589,12 @@ int32_t iguana_getheadersize(char *buf,int32_t recvlen) } uint16_t RPC_port; -extern portable_mutex_t LP_commandmutex; -struct rpcrequest_info { pthread_t T; int32_t sock; uint32_t ipbits; }; +extern portable_mutex_t LP_commandmutex,LP_networkmutex; +extern struct rpcrequest_info *LP_garbage_collector; void LP_rpc_processreq(void *_ptr) { + static uint32_t spawned,maxspawned; char filetype[128],content_type[128]; int32_t recvlen,flag,postflag=0,contentlen,remains,sock,numsent,jsonflag=0,hdrsize,len; char helpname[512],remoteaddr[64],*buf,*retstr,*space,*jsonbuf; struct rpcrequest_info *req = _ptr; @@ -607,6 +608,14 @@ void LP_rpc_processreq(void *_ptr) jsonbuf = calloc(1,size); remains = size-1; buf = jsonbuf; + portable_mutex_lock(&LP_networkmutex); + spawned++; + portable_mutex_unlock(&LP_networkmutex); + if ( spawned > maxspawned ) + { + printf("max rpc threads spawned and alive %d <- %d\n",maxspawned,spawned); + spawned = maxspawned; + } while ( remains > 0 ) { //printf("flag.%d remains.%d recvlen.%d\n",flag,remains,recvlen); @@ -726,7 +735,10 @@ void LP_rpc_processreq(void *_ptr) free(space); free(jsonbuf); closesocket(sock); - free(_ptr); + portable_mutex_lock(&LP_networkmutex); + DL_APPEND(LP_garbage_collector,req); + spawned--; + portable_mutex_unlock(&LP_networkmutex); } extern int32_t IAMLP; From be41509919035da700e9933b1cc18107b6dea1e7 Mon Sep 17 00:00:00 2001 From: jl777 Date: Sat, 4 Nov 2017 22:58:32 +0200 Subject: [PATCH 0206/1664] Test --- iguana/exchanges/LP_network.c | 2 +- iguana/exchanges/stats.c | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/iguana/exchanges/LP_network.c b/iguana/exchanges/LP_network.c index 14cae1f3a..f36b31749 100644 --- a/iguana/exchanges/LP_network.c +++ b/iguana/exchanges/LP_network.c @@ -277,7 +277,7 @@ void queue_loop(void *arg) DL_FOREACH_SAFE(LP_garbage_collector,req,rtmp) { DL_DELETE(LP_garbage_collector,req); - printf("garbage collect ipbits.%x\n",req->ipbits); + //printf("garbage collect ipbits.%x\n",req->ipbits); free(req); } portable_mutex_unlock(&LP_networkmutex); diff --git a/iguana/exchanges/stats.c b/iguana/exchanges/stats.c index ab82d9f53..4eea97b8e 100644 --- a/iguana/exchanges/stats.c +++ b/iguana/exchanges/stats.c @@ -614,7 +614,7 @@ void LP_rpc_processreq(void *_ptr) if ( spawned > maxspawned ) { printf("max rpc threads spawned and alive %d <- %d\n",maxspawned,spawned); - spawned = maxspawned; + maxspawned = spawned; } while ( remains > 0 ) { From 0b9b34120852d64c125ddf625c80e017161be29c Mon Sep 17 00:00:00 2001 From: jl777 Date: Sat, 4 Nov 2017 23:24:13 +0200 Subject: [PATCH 0207/1664] Test --- iguana/exchanges/LP_prices.c | 14 +++++++------- iguana/exchanges/processfiles | 1 + 2 files changed, 8 insertions(+), 7 deletions(-) create mode 100755 iguana/exchanges/processfiles diff --git a/iguana/exchanges/LP_prices.c b/iguana/exchanges/LP_prices.c index f8cb07d77..a51aff113 100644 --- a/iguana/exchanges/LP_prices.c +++ b/iguana/exchanges/LP_prices.c @@ -34,7 +34,7 @@ struct LP_priceinfo double factors[LP_MAXPRICEINFOS]; //double maxprices[LP_MAXPRICEINFOS]; // autofill of base/rel //double relvols[LP_MAXPRICEINFOS]; - FILE *fps[LP_MAXPRICEINFOS]; + //FILE *fps[LP_MAXPRICEINFOS]; } LP_priceinfos[LP_MAXPRICEINFOS]; int32_t LP_numpriceinfos; @@ -1033,10 +1033,10 @@ void LP_pricefeedupdate(bits256 pubkey,char *base,char *rel,double price) //printf("check PRICEFEED UPDATE.(%s/%s) %.8f %s\n",base,rel,price,bits256_str(str,pubkey)); if ( LP_pricevalid(price) > 0 && (basepp= LP_priceinfofind(base)) != 0 && (relpp= LP_priceinfofind(rel)) != 0 ) { - if ( (fp= basepp->fps[relpp->ind]) == 0 ) + //if ( (fp= basepp->fps[relpp->ind]) == 0 ) { LP_pricefname(fname,base,rel); - fp = basepp->fps[relpp->ind] = OS_appendfile(fname); + fp = OS_appendfile(fname); //basepp->fps[relpp->ind] = } if ( fp != 0 ) { @@ -1044,12 +1044,12 @@ void LP_pricefeedupdate(bits256 pubkey,char *base,char *rel,double price) price64 = price * SATOSHIDEN; fwrite(&now,1,sizeof(now),fp); fwrite(&price64,1,sizeof(price64),fp); - fflush(fp); + fclose(fp); } - if ( (fp= relpp->fps[basepp->ind]) == 0 ) + //if ( (fp= relpp->fps[basepp->ind]) == 0 ) { sprintf(fname,"%s/PRICES/%s_%s",GLOBAL_DBDIR,rel,base); - fp = relpp->fps[basepp->ind] = OS_appendfile(fname); + fp = OS_appendfile(fname); //relpp->fps[basepp->ind] = } if ( fp != 0 ) { @@ -1057,7 +1057,7 @@ void LP_pricefeedupdate(bits256 pubkey,char *base,char *rel,double price) price64 = (1. / price) * SATOSHIDEN; fwrite(&now,1,sizeof(now),fp); fwrite(&price64,1,sizeof(price64),fp); - fflush(fp); + fclose(fp); } if ( (pubp= LP_pubkeyadd(pubkey)) != 0 ) { diff --git a/iguana/exchanges/processfiles b/iguana/exchanges/processfiles new file mode 100755 index 000000000..518d335ab --- /dev/null +++ b/iguana/exchanges/processfiles @@ -0,0 +1 @@ +`ls -l /proc/$1/fd From 09ccaadd2e073b42082f75561cd5876c04207e32 Mon Sep 17 00:00:00 2001 From: jl777 Date: Sat, 4 Nov 2017 23:29:01 +0200 Subject: [PATCH 0208/1664] Test --- iguana/exchanges/processfiles | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/iguana/exchanges/processfiles b/iguana/exchanges/processfiles index 518d335ab..9404f967a 100755 --- a/iguana/exchanges/processfiles +++ b/iguana/exchanges/processfiles @@ -1 +1,3 @@ -`ls -l /proc/$1/fd +ls -l /proc/$1/fd +echo sockstat +cat /proc/$1/net/sockstat From 3757b996da6dbed00cc56acd49c7d6b61c0c8fb7 Mon Sep 17 00:00:00 2001 From: jl777 Date: Sat, 4 Nov 2017 23:52:15 +0200 Subject: [PATCH 0209/1664] Test --- iguana/exchanges/LP_nativeDEX.c | 12 ++++++++---- iguana/exchanges/LP_network.c | 5 +++-- 2 files changed, 11 insertions(+), 6 deletions(-) diff --git a/iguana/exchanges/LP_nativeDEX.c b/iguana/exchanges/LP_nativeDEX.c index 1787e300d..17d54e5e7 100644 --- a/iguana/exchanges/LP_nativeDEX.c +++ b/iguana/exchanges/LP_nativeDEX.c @@ -17,7 +17,7 @@ // // LP_nativeDEX.c // marketmaker -// +// bots to do bobs // verify portfolio, interest to KMD withdraw // dPoW security -> 4: KMD notarized, 5: BTC notarized, after next notary elections // bigendian architectures need to use little endian for sighash calcs @@ -669,7 +669,7 @@ void LP_coinsloop(void *_coins) if ( coins == 0 ) return; if ( nonz == 0 ) - usleep(1000); + usleep(100000); } } @@ -876,15 +876,17 @@ void LP_swapsloop(void *ignore) void LP_reserved_msgs(void *ignore) { - bits256 zero; int32_t flag; struct nn_pollfd pfd; + bits256 zero; int32_t flag,nonz; struct nn_pollfd pfd; memset(zero.bytes,0,sizeof(zero)); strcpy(LP_reserved_msgs_stats.name,"LP_reserved_msgs"); LP_reserved_msgs_stats.threshold = 50.; while ( 1 ) { + nonz = 0; LP_millistats_update(&LP_reserved_msgs_stats); if ( num_Reserved_msgs[0] > 0 || num_Reserved_msgs[1] > 0 ) { + nonz++; flag = 0; if ( LP_mypubsock >= 0 ) { @@ -914,7 +916,9 @@ void LP_reserved_msgs(void *ignore) } if ( ignore == 0 ) break; - usleep(3000); + if ( nonz != 0 ) + usleep(3000); + else usleep(25000); } } diff --git a/iguana/exchanges/LP_network.c b/iguana/exchanges/LP_network.c index f36b31749..199e327fb 100644 --- a/iguana/exchanges/LP_network.c +++ b/iguana/exchanges/LP_network.c @@ -341,9 +341,10 @@ void queue_loop(void *arg) //if ( n != 0 ) // printf("LP_Q.[%d]\n",n); if ( nonz == 0 ) - usleep(5000); + usleep(25000); else if ( IAMLP == 0 ) - usleep(1000); + usleep(10000); + else usleep(1000); } } From 124df0f23f37ee9c8c15cdc78db1d497083a4204 Mon Sep 17 00:00:00 2001 From: jl777 Date: Sat, 4 Nov 2017 23:53:14 +0200 Subject: [PATCH 0210/1664] Test --- iguana/exchanges/LP_nativeDEX.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/iguana/exchanges/LP_nativeDEX.c b/iguana/exchanges/LP_nativeDEX.c index 17d54e5e7..99b536cd8 100644 --- a/iguana/exchanges/LP_nativeDEX.c +++ b/iguana/exchanges/LP_nativeDEX.c @@ -434,11 +434,11 @@ void command_rpcloop(void *myipaddr) if ( nonz == 0 ) { if ( IAMLP != 0 ) - usleep(1000); - else usleep(10000); + usleep(10000); + else usleep(50000); } else if ( IAMLP == 0 ) - usleep(100); + usleep(1000); } } From bf6da962454f3161a437efe57dc83021ce66fa1b Mon Sep 17 00:00:00 2001 From: jl777 Date: Sat, 4 Nov 2017 23:57:23 +0200 Subject: [PATCH 0211/1664] Test --- iguana/exchanges/LP_nativeDEX.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/iguana/exchanges/LP_nativeDEX.c b/iguana/exchanges/LP_nativeDEX.c index 99b536cd8..a48b4eff1 100644 --- a/iguana/exchanges/LP_nativeDEX.c +++ b/iguana/exchanges/LP_nativeDEX.c @@ -697,7 +697,7 @@ int32_t LP_mainloop_iter(void *ctx,char *myipaddr,struct LP_peerinfo *mypeer,int if ( IAMLP == 0 ) continue; } - if ( now > peer->lastpeers+60 || (rand() % 10000) == 0 ) + if ( now > peer->lastpeers+LP_ORDERBOOK_DURATION*.777 || (rand() % 100000) == 0 ) { if ( strcmp(peer->ipaddr,myipaddr) != 0 ) { @@ -722,7 +722,7 @@ int32_t LP_mainloop_iter(void *ctx,char *myipaddr,struct LP_peerinfo *mypeer,int } HASH_ITER(hh,LP_coins,coin,ctmp) // firstrefht,firstscanht,lastscanht { - if ( coin->addr_listunspent_requested != 0 && time(NULL) > coin->lastpushtime+60 ) + if ( coin->addr_listunspent_requested != 0 && time(NULL) > coin->lastpushtime+LP_ORDERBOOK_DURATION ) { //printf("PUSH addr_listunspent_requested %u\n",coin->addr_listunspent_requested); coin->lastpushtime = (uint32_t)time(NULL); From 325c3db68f7c69e54e26d99e538554ebb1440744 Mon Sep 17 00:00:00 2001 From: jl777 Date: Sun, 5 Nov 2017 00:19:57 +0200 Subject: [PATCH 0212/1664] Other lp nodes --- iguana/exchanges/LP_nativeDEX.c | 1 + 1 file changed, 1 insertion(+) diff --git a/iguana/exchanges/LP_nativeDEX.c b/iguana/exchanges/LP_nativeDEX.c index a48b4eff1..ae96d1aeb 100644 --- a/iguana/exchanges/LP_nativeDEX.c +++ b/iguana/exchanges/LP_nativeDEX.c @@ -91,6 +91,7 @@ char LP_myipaddr[64],LP_publicaddr[64],USERHOME[512] = { "/root" }; char LP_gui[16] = { "cli" }; char *default_LPnodes[] = { "5.9.253.195", "5.9.253.196", "5.9.253.197", "5.9.253.198", "5.9.253.199", "5.9.253.200", "5.9.253.201", "5.9.253.202", "5.9.253.203", + "24.54.206.138", "173.212.225.176", "136.243.45.140", "107.72.162.127", "72.50.16.86", "51.15.202.191", "173.228.198.88", //"51.15.203.171", "51.15.86.136", "51.15.94.249", "51.15.80.18", "51.15.91.40", "51.15.54.2", "51.15.86.31", "51.15.82.29", "51.15.89.155", };//"5.9.253.204" }; // From 32a9c0f10849b3ec929c95b18ee6656dd0cb9116 Mon Sep 17 00:00:00 2001 From: jl777 Date: Sun, 5 Nov 2017 00:35:15 +0200 Subject: [PATCH 0213/1664] test --- iguana/exchanges/LP_commands.c | 2 +- iguana/exchanges/LP_include.h | 5 ++++- iguana/exchanges/LP_peers.c | 6 ++++-- iguana/exchanges/LP_prices.c | 5 ++--- 4 files changed, 11 insertions(+), 7 deletions(-) diff --git a/iguana/exchanges/LP_commands.c b/iguana/exchanges/LP_commands.c index 7e4c9b249..417d91b51 100644 --- a/iguana/exchanges/LP_commands.c +++ b/iguana/exchanges/LP_commands.c @@ -523,7 +523,7 @@ bot_resume(botid)\n\ bits256 pub; static uint32_t lastnotify; pub = jbits256(argjson,"pub"); //char str[65]; printf("got wantnotify.(%s) vs %s\n",jprint(argjson,0),bits256_str(str,G.LP_mypub25519)); - if ( bits256_cmp(pub,G.LP_mypub25519) == 0 && time(NULL) > lastnotify+30 ) + if ( bits256_cmp(pub,G.LP_mypub25519) == 0 && time(NULL) > lastnotify+60 ) { lastnotify = (uint32_t)time(NULL); //printf("wantnotify for me!\n"); diff --git a/iguana/exchanges/LP_include.h b/iguana/exchanges/LP_include.h index c8cfa1bc2..e17bb5baa 100644 --- a/iguana/exchanges/LP_include.h +++ b/iguana/exchanges/LP_include.h @@ -44,6 +44,9 @@ void emscripten_usleep(int32_t x); // returns immediate, no sense for sleeping #define LP_ELECTRUM_MAXERRORS 777 #define LP_MEMPOOL_TIMEINCR 10 +#define LP_OPTIONAL_PEERS 16 +#define LP_MAX_PEERS 100 + // RTmetrics #define LP_RTMETRICS_TOPGROUP 1.01 #define LP_MAXPENDING_SWAPS 13 @@ -350,7 +353,7 @@ struct LP_pubkeyinfo bits256 pubkey; float matrix[LP_MAXPRICEINFOS][LP_MAXPRICEINFOS]; //uint32_t timestamps[LP_MAXPRICEINFOS][LP_MAXPRICEINFOS]; - uint32_t timestamp,numerrors; + uint32_t timestamp,numerrors,lasttime; int32_t istrusted; uint8_t rmd160[20],sig[65],pubsecp[33],siglen; }; diff --git a/iguana/exchanges/LP_peers.c b/iguana/exchanges/LP_peers.c index 4aaae086d..12a234a95 100644 --- a/iguana/exchanges/LP_peers.c +++ b/iguana/exchanges/LP_peers.c @@ -204,7 +204,7 @@ int32_t LP_coinbus(uint16_t coin_busport) int32_t LP_peersparse(struct LP_peerinfo *mypeer,int32_t mypubsock,char *destipaddr,uint16_t destport,char *retstr,uint32_t now) { - struct LP_peerinfo *peer; uint32_t argipbits; char *argipaddr; uint16_t argport,pushport,subport; cJSON *array,*item; int32_t i,n=0; + struct LP_peerinfo *peer; uint32_t argipbits; char *argipaddr; uint16_t argport,pushport,subport; cJSON *array,*item; int32_t numpeers,i,n=0; if ( (array= cJSON_Parse(retstr)) != 0 ) { if ( (n= cJSON_GetArraySize(array)) > 0 ) @@ -221,7 +221,9 @@ int32_t LP_peersparse(struct LP_peerinfo *mypeer,int32_t mypubsock,char *destipa argipbits = (uint32_t)calc_ipbits(argipaddr); if ( (peer= LP_peerfind(argipbits,argport)) == 0 ) { - peer = LP_addpeer(mypeer,mypubsock,argipaddr,argport,pushport,subport,jint(item,"numpeers"),jint(item,"numutxos"),juint(item,"session")); + numpeers = LP_numpeers(); + if ( IAMLP != 0 || (IAMLP == 0 && numpeers > LP_OPTIONAL_PEERS && (rand() % LP_MAX_PEERS) > numpeers) ) + peer = LP_addpeer(mypeer,mypubsock,argipaddr,argport,pushport,subport,jint(item,"numpeers"),jint(item,"numutxos"),juint(item,"session")); } if ( peer != 0 ) { diff --git a/iguana/exchanges/LP_prices.c b/iguana/exchanges/LP_prices.c index a51aff113..84a699410 100644 --- a/iguana/exchanges/LP_prices.c +++ b/iguana/exchanges/LP_prices.c @@ -697,15 +697,14 @@ struct LP_orderbookentry *LP_orderbookentry(char *address,char *base,char *rel,d void LP_pubkeys_query() { - static uint32_t lasttime; uint8_t zeroes[20]; bits256 zero; cJSON *reqjson; struct LP_pubkeyinfo *pubp=0,*tmp; memset(zero.bytes,0,sizeof(zero)); memset(zeroes,0,sizeof(zeroes)); HASH_ITER(hh,LP_pubkeyinfos,pubp,tmp) { - if ( memcmp(zeroes,pubp->rmd160,sizeof(pubp->rmd160)) == 0 && time(NULL) > lasttime+30 ) + if ( memcmp(zeroes,pubp->rmd160,sizeof(pubp->rmd160)) == 0 && time(NULL) > pubp->lasttime+60 ) { - lasttime = (uint32_t)time(NULL); + pubp->lasttime = (uint32_t)time(NULL); reqjson = cJSON_CreateObject(); jaddstr(reqjson,"method","wantnotify"); jaddbits256(reqjson,"pub",pubp->pubkey); From 2256c36d07c26983e751b234625d02a69a49c341 Mon Sep 17 00:00:00 2001 From: jl777 Date: Sun, 5 Nov 2017 00:45:00 +0200 Subject: [PATCH 0214/1664] Test --- iguana/exchanges/LP_peers.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/iguana/exchanges/LP_peers.c b/iguana/exchanges/LP_peers.c index 12a234a95..04ee5331e 100644 --- a/iguana/exchanges/LP_peers.c +++ b/iguana/exchanges/LP_peers.c @@ -222,7 +222,7 @@ int32_t LP_peersparse(struct LP_peerinfo *mypeer,int32_t mypubsock,char *destipa if ( (peer= LP_peerfind(argipbits,argport)) == 0 ) { numpeers = LP_numpeers(); - if ( IAMLP != 0 || (IAMLP == 0 && numpeers > LP_OPTIONAL_PEERS && (rand() % LP_MAX_PEERS) > numpeers) ) + if ( IAMLP != 0 || numpeers < LP_OPTIONAL_PEERS || (IAMLP == 0 && (rand() % LP_MAX_PEERS) > numpeers) ) peer = LP_addpeer(mypeer,mypubsock,argipaddr,argport,pushport,subport,jint(item,"numpeers"),jint(item,"numutxos"),juint(item,"session")); } if ( peer != 0 ) From beecd13a1016f2e948dc699edaf22f1cb38a0bdd Mon Sep 17 00:00:00 2001 From: jl777 Date: Sun, 5 Nov 2017 00:45:52 +0200 Subject: [PATCH 0215/1664] test --- iguana/exchanges/LP_include.h | 4 ++-- iguana/exchanges/LP_peers.c | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/iguana/exchanges/LP_include.h b/iguana/exchanges/LP_include.h index e17bb5baa..29c06f6ba 100644 --- a/iguana/exchanges/LP_include.h +++ b/iguana/exchanges/LP_include.h @@ -44,8 +44,8 @@ void emscripten_usleep(int32_t x); // returns immediate, no sense for sleeping #define LP_ELECTRUM_MAXERRORS 777 #define LP_MEMPOOL_TIMEINCR 10 -#define LP_OPTIONAL_PEERS 16 -#define LP_MAX_PEERS 100 +#define LP_MIN_PEERS 8 +#define LP_MAX_PEERS 32 // RTmetrics #define LP_RTMETRICS_TOPGROUP 1.01 diff --git a/iguana/exchanges/LP_peers.c b/iguana/exchanges/LP_peers.c index 04ee5331e..9412ae298 100644 --- a/iguana/exchanges/LP_peers.c +++ b/iguana/exchanges/LP_peers.c @@ -222,7 +222,7 @@ int32_t LP_peersparse(struct LP_peerinfo *mypeer,int32_t mypubsock,char *destipa if ( (peer= LP_peerfind(argipbits,argport)) == 0 ) { numpeers = LP_numpeers(); - if ( IAMLP != 0 || numpeers < LP_OPTIONAL_PEERS || (IAMLP == 0 && (rand() % LP_MAX_PEERS) > numpeers) ) + if ( IAMLP != 0 || numpeers < LP_MIN_PEERS || (IAMLP == 0 && (rand() % LP_MAX_PEERS) > numpeers) ) peer = LP_addpeer(mypeer,mypubsock,argipaddr,argport,pushport,subport,jint(item,"numpeers"),jint(item,"numutxos"),juint(item,"session")); } if ( peer != 0 ) From 21164e36c07fb1559a88ba983a3f4f8474b3b7f3 Mon Sep 17 00:00:00 2001 From: jl777 Date: Sun, 5 Nov 2017 01:00:59 +0200 Subject: [PATCH 0216/1664] Test --- iguana/exchanges/LP_network.c | 1 + 1 file changed, 1 insertion(+) diff --git a/iguana/exchanges/LP_network.c b/iguana/exchanges/LP_network.c index 199e327fb..831daf83f 100644 --- a/iguana/exchanges/LP_network.c +++ b/iguana/exchanges/LP_network.c @@ -390,6 +390,7 @@ void LP_broadcast_finish(int32_t pubsock,char *base,char *rel,uint8_t *msg,cJSON if ( IAMLP == 0 ) { free(msg); +printf("broadcast %s\n",jstr(argjson,"method")); jdelete(argjson,"method"); jaddstr(argjson,"method","broadcast"); if ( jobj(argjson,"timestamp") == 0 ) From 6712f480bb4b5eae23fac91dc0c3e39ce0925a6e Mon Sep 17 00:00:00 2001 From: jl777 Date: Sun, 5 Nov 2017 01:03:52 +0200 Subject: [PATCH 0217/1664] Test --- iguana/exchanges/LP_network.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/iguana/exchanges/LP_network.c b/iguana/exchanges/LP_network.c index 831daf83f..797c31d04 100644 --- a/iguana/exchanges/LP_network.c +++ b/iguana/exchanges/LP_network.c @@ -390,7 +390,7 @@ void LP_broadcast_finish(int32_t pubsock,char *base,char *rel,uint8_t *msg,cJSON if ( IAMLP == 0 ) { free(msg); -printf("broadcast %s\n",jstr(argjson,"method")); +//printf("broadcast %s\n",jstr(argjson,"method")); jdelete(argjson,"method"); jaddstr(argjson,"method","broadcast"); if ( jobj(argjson,"timestamp") == 0 ) From 51a90bc5becab863b3696b70c01772264aba189c Mon Sep 17 00:00:00 2001 From: jl777 Date: Sun, 5 Nov 2017 11:41:33 +0200 Subject: [PATCH 0218/1664] bot_statuslist --- iguana/exchanges/LP_commands.c | 1 + iguana/exchanges/LP_tradebots.c | 12 ++++++++++++ iguana/exchanges/bot_statuslist | 3 +++ 3 files changed, 16 insertions(+) create mode 100755 iguana/exchanges/bot_statuslist diff --git a/iguana/exchanges/LP_commands.c b/iguana/exchanges/LP_commands.c index 417d91b51..831675653 100644 --- a/iguana/exchanges/LP_commands.c +++ b/iguana/exchanges/LP_commands.c @@ -142,6 +142,7 @@ snapshot_balance(coin, height, addresses[])\n\ dividends(coin, height, )\n\ stop()\n\ bot_list()\n\ +bot_statuslist()\n\ bot_buy(base, rel, maxprice, relvolume) -> botid\n\ bot_sell(base, rel, minprice, basevolume) -> botid\n\ bot_settings(botid, newprice, newvolume)\n\ diff --git a/iguana/exchanges/LP_tradebots.c b/iguana/exchanges/LP_tradebots.c index af5f385f8..359e65c4a 100644 --- a/iguana/exchanges/LP_tradebots.c +++ b/iguana/exchanges/LP_tradebots.c @@ -402,6 +402,16 @@ char *LP_tradebot_list(void *ctx,int32_t pubsock,cJSON *argjson) return(jprint(array,1)); } +char *LP_tradebot_statuslist(void *ctx,int32_t pubsock,cJSON *argjson) +{ + struct LP_tradebot *bot,*tmp; cJSON *array = cJSON_CreateArray(); + DL_FOREACH_SAFE(LP_tradebots,bot,tmp) + { + jaddi(array,LP_tradebot_json(bot)); + } + return(jprint(array,1)); +} + char *LP_tradebot_buy(int32_t dispdir,char *base,char *rel,double maxprice,double relvolume) { struct LP_tradebot *bot; char *retstr; double shortfall; int32_t i,n; cJSON *array,*item,*retjson; uint64_t txfees,balance=0,abalance=0; struct iguana_info *basecoin,*relcoin; @@ -599,6 +609,8 @@ char *LP_istradebots_command(void *ctx,int32_t pubsock,char *method,cJSON *argjs return(0); if ( strcmp(method,"bot_list") == 0 ) return(LP_tradebot_list(ctx,pubsock,argjson)); + else if ( strcmp(method,"bot_statuslist") == 0 ) + return(LP_tradebot_statuslist(ctx,pubsock,argjson)); else if ( strcmp(method,"bot_buy") == 0 ) return(LP_tradebot_limitbuy(ctx,pubsock,argjson)); else if ( strcmp(method,"bot_sell") == 0 ) diff --git a/iguana/exchanges/bot_statuslist b/iguana/exchanges/bot_statuslist new file mode 100755 index 000000000..14b7e3522 --- /dev/null +++ b/iguana/exchanges/bot_statuslist @@ -0,0 +1,3 @@ +#!/bin/bash +source userpass +curl --url "http://127.0.0.1:7783" --data "{\"userpass\":\"$userpass\",\"method\":\"bot_statuslist\"}" From db5666a967d58f5a14a81af34614e026e07e85e8 Mon Sep 17 00:00:00 2001 From: jl777 Date: Sun, 5 Nov 2017 12:01:41 +0200 Subject: [PATCH 0219/1664] Test --- iguana/exchanges/install | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/iguana/exchanges/install b/iguana/exchanges/install index 2f4946484..342089ce3 100755 --- a/iguana/exchanges/install +++ b/iguana/exchanges/install @@ -1,5 +1,5 @@ #!/bin/bash -cp stop millis mnzservers bot_buy bot_list bot_pause bot_resume bot_sell bot_settings bot_status bot_stop guistats pubkeystats pendings coinswaps baserelswaps setpassphrase notarizations getrawtransaction parselog statsdisp m_js 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 processlist stop millis mnzservers bot_buy bot_list bot_statuslist bot_pause bot_resume bot_sell bot_settings bot_status bot_stop guistats pubkeystats pendings coinswaps baserelswaps setpassphrase notarizations getrawtransaction parselog statsdisp m_js 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 . From ff808f857a6ab4cd4962f7ff44f6370a002b9538 Mon Sep 17 00:00:00 2001 From: jl777 Date: Sun, 5 Nov 2017 15:28:54 +0200 Subject: [PATCH 0220/1664] Test --- iguana/exchanges/LP_nativeDEX.c | 4 ++-- iguana/exchanges/LP_transaction.c | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/iguana/exchanges/LP_nativeDEX.c b/iguana/exchanges/LP_nativeDEX.c index ae96d1aeb..fe8e56c94 100644 --- a/iguana/exchanges/LP_nativeDEX.c +++ b/iguana/exchanges/LP_nativeDEX.c @@ -446,7 +446,7 @@ void command_rpcloop(void *myipaddr) void utxosQ_loop(void *myipaddr) { strcpy(utxosQ_loop_stats.name,"utxosQ_loop"); - utxosQ_loop_stats.threshold = 50.; + utxosQ_loop_stats.threshold = 150.; while ( 1 ) { LP_millistats_update(&utxosQ_loop_stats); @@ -880,7 +880,7 @@ void LP_reserved_msgs(void *ignore) bits256 zero; int32_t flag,nonz; struct nn_pollfd pfd; memset(zero.bytes,0,sizeof(zero)); strcpy(LP_reserved_msgs_stats.name,"LP_reserved_msgs"); - LP_reserved_msgs_stats.threshold = 50.; + LP_reserved_msgs_stats.threshold = 150.; while ( 1 ) { nonz = 0; diff --git a/iguana/exchanges/LP_transaction.c b/iguana/exchanges/LP_transaction.c index 9f0fdfa69..e9f140178 100644 --- a/iguana/exchanges/LP_transaction.c +++ b/iguana/exchanges/LP_transaction.c @@ -648,7 +648,7 @@ char *basilisk_swap_bobtxspend(bits256 *signedtxidp,uint64_t txfee,char *name,ch satoshis = value - 3*txfee/4; printf("reduce satoshis %.8f by txfee %.8f to value %.8f\n",dstr(satoshis),dstr(txfee),dstr(value)); } - else if ( value == satoshis && (double)txfee/value < 0.001 ) + else if ( value == satoshis && (double)txfee/value < 0.1 ) { satoshis = value - txfee; printf("txfee allocation from value %.8f identical to satoshis: %.8f txfee %.8f\n",dstr(value),dstr(satoshis),dstr(txfee)); From 164e7c7ebc3f436d0cb9d6d573a3bc16694e9158 Mon Sep 17 00:00:00 2001 From: jl777 Date: Sun, 5 Nov 2017 15:47:20 +0200 Subject: [PATCH 0221/1664] Test --- iguana/exchanges/stats.c | 24 +++++++++--------------- 1 file changed, 9 insertions(+), 15 deletions(-) diff --git a/iguana/exchanges/stats.c b/iguana/exchanges/stats.c index 4eea97b8e..6ada27290 100644 --- a/iguana/exchanges/stats.c +++ b/iguana/exchanges/stats.c @@ -745,7 +745,7 @@ extern int32_t IAMLP; void stats_rpcloop(void *args) { static uint32_t counter; - uint16_t port; int32_t sock,bindsock=-1; socklen_t clilen; struct sockaddr_in cli_addr; uint32_t ipbits,localhostbits; struct rpcrequest_info *req; + uint16_t port; int32_t retval,sock,bindsock=-1; socklen_t clilen; struct sockaddr_in cli_addr; uint32_t ipbits,localhostbits; struct rpcrequest_info *req; if ( (port= *(uint16_t *)args) == 0 ) port = 7779; RPC_port = port; @@ -780,21 +780,15 @@ void stats_rpcloop(void *args) req = calloc(1,sizeof(*req)); req->sock = sock; req->ipbits = ipbits; - if ( 0 ) + if ( (retval= OS_thread_create(&req->T,NULL,(void *)LP_rpc_processreq,req)) != 0 ) { - //LP_rpc_processreq((void *)&arg64); - //free(arg64ptr); - //closesocket(sock); - } - else if ( OS_thread_create(&req->T,NULL,(void *)LP_rpc_processreq,req) != 0 ) - { - printf("error launching rpc handler on port %d\n",port); - } - /*if ( 0 && IAMLP != 0 && ipbits != localhostbits ) - { - close(bindsock); - bindsock = iguana_socket(1,"0.0.0.0",port); - } //else printf("skip close and rebind\n");*/ + printf("error launching rpc handler on port %d, retval.%d\n",port,retval); + if ( (retval= OS_thread_create(&req->T,NULL,(void *)LP_rpc_processreq,req)) != 0 ) + { + printf("error2 launching rpc handler on port %d, retval.%d\n",port,retval); + LP_rpc_processreq(req); + } + } } } From 42d25e36cdbb5eed4aac51c017cf8fad7dcf297d Mon Sep 17 00:00:00 2001 From: jl777 Date: Sun, 5 Nov 2017 15:50:42 +0200 Subject: [PATCH 0222/1664] Test --- iguana/exchanges/stats.c | 19 ++++++++++--------- 1 file changed, 10 insertions(+), 9 deletions(-) diff --git a/iguana/exchanges/stats.c b/iguana/exchanges/stats.c index 6ada27290..dc550354b 100644 --- a/iguana/exchanges/stats.c +++ b/iguana/exchanges/stats.c @@ -745,19 +745,11 @@ extern int32_t IAMLP; void stats_rpcloop(void *args) { static uint32_t counter; - uint16_t port; int32_t retval,sock,bindsock=-1; socklen_t clilen; struct sockaddr_in cli_addr; uint32_t ipbits,localhostbits; struct rpcrequest_info *req; + uint16_t port; int32_t retval,sock,bindsock=-1; socklen_t clilen; struct sockaddr_in cli_addr; uint32_t ipbits,localhostbits; struct rpcrequest_info *req,*req2,*rtmp; if ( (port= *(uint16_t *)args) == 0 ) port = 7779; RPC_port = port; localhostbits = (uint32_t)calc_ipbits("127.0.0.1"); - /*while ( (bindsock= iguana_socket(1,"0.0.0.0",port)) < 0 ) - { - //if ( coin->MAXPEERS == 1 ) - // break; - //exit(-1); - sleep(3); - } - printf(">>>>>>>>>> DEX stats 127.0.0.1:%d bind sock.%d DEX stats API enabled <<<<<<<<<\n",port,bindsock);*/ while ( 1 ) { if ( bindsock < 0 ) @@ -783,6 +775,15 @@ void stats_rpcloop(void *args) if ( (retval= OS_thread_create(&req->T,NULL,(void *)LP_rpc_processreq,req)) != 0 ) { printf("error launching rpc handler on port %d, retval.%d\n",port,retval); + close(bindsock); + bindsock = -1; + portable_mutex_lock(&LP_networkmutex); + DL_FOREACH_SAFE(LP_garbage_collector,req2,rtmp) + { + DL_DELETE(LP_garbage_collector,req2); + free(req2); + } + portable_mutex_unlock(&LP_networkmutex); if ( (retval= OS_thread_create(&req->T,NULL,(void *)LP_rpc_processreq,req)) != 0 ) { printf("error2 launching rpc handler on port %d, retval.%d\n",port,retval); From 54c7540e4c4b673c1f39624d23543d1962ad45e6 Mon Sep 17 00:00:00 2001 From: jl777 Date: Sun, 5 Nov 2017 17:13:38 +0200 Subject: [PATCH 0223/1664] Test --- iguana/exchanges/stats.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/iguana/exchanges/stats.c b/iguana/exchanges/stats.c index dc550354b..37514e596 100644 --- a/iguana/exchanges/stats.c +++ b/iguana/exchanges/stats.c @@ -772,6 +772,8 @@ void stats_rpcloop(void *args) req = calloc(1,sizeof(*req)); req->sock = sock; req->ipbits = ipbits; + LP_rpc_processreq(req); +continue; if ( (retval= OS_thread_create(&req->T,NULL,(void *)LP_rpc_processreq,req)) != 0 ) { printf("error launching rpc handler on port %d, retval.%d\n",port,retval); From 9fa58ccdb5d8f60f73c4145cd5fdb2a8dadca772 Mon Sep 17 00:00:00 2001 From: jl777 Date: Sun, 5 Nov 2017 17:38:07 +0200 Subject: [PATCH 0224/1664] Test --- iguana/exchanges/LP_nativeDEX.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/iguana/exchanges/LP_nativeDEX.c b/iguana/exchanges/LP_nativeDEX.c index fe8e56c94..32a484a39 100644 --- a/iguana/exchanges/LP_nativeDEX.c +++ b/iguana/exchanges/LP_nativeDEX.c @@ -65,7 +65,8 @@ void LP_millistats_update(struct LP_millistats *mp) mp->millisum += elapsed; if ( mp->threshold != 0. && elapsed > mp->threshold ) { - printf("%32s elapsed %10.2f millis > threshold %10.2f, ave %10.2f millis, count.%u\n",mp->name,elapsed,mp->threshold,mp->millisum/mp->count,mp->count); + if ( IAMLP == 0 ) + printf("%32s elapsed %10.2f millis > threshold %10.2f, ave %10.2f millis, count.%u\n",mp->name,elapsed,mp->threshold,mp->millisum/mp->count,mp->count); } mp->lastmilli = millis; } From c6a832c1bad7c7ae8f4fb2c160314d482419ff47 Mon Sep 17 00:00:00 2001 From: jl777 Date: Sun, 5 Nov 2017 17:50:12 +0200 Subject: [PATCH 0225/1664] Test --- iguana/exchanges/LP_nativeDEX.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/iguana/exchanges/LP_nativeDEX.c b/iguana/exchanges/LP_nativeDEX.c index 32a484a39..907f790c0 100644 --- a/iguana/exchanges/LP_nativeDEX.c +++ b/iguana/exchanges/LP_nativeDEX.c @@ -724,9 +724,9 @@ int32_t LP_mainloop_iter(void *ctx,char *myipaddr,struct LP_peerinfo *mypeer,int } HASH_ITER(hh,LP_coins,coin,ctmp) // firstrefht,firstscanht,lastscanht { - if ( coin->addr_listunspent_requested != 0 && time(NULL) > coin->lastpushtime+LP_ORDERBOOK_DURATION ) + if ( coin->addr_listunspent_requested != 0 && time(NULL) > coin->lastpushtime+10 ) { - //printf("PUSH addr_listunspent_requested %u\n",coin->addr_listunspent_requested); + printf("PUSH addr_listunspent_requested %u\n",coin->addr_listunspent_requested); coin->lastpushtime = (uint32_t)time(NULL); LP_smartutxos_push(coin); coin->addr_listunspent_requested = 0; From 5470b73651aca09cb9bbb594c9a9dba957ffa8eb Mon Sep 17 00:00:00 2001 From: jl777 Date: Sun, 5 Nov 2017 18:02:10 +0200 Subject: [PATCH 0226/1664] Test --- iguana/exchanges/LP_commands.c | 8 +++++++- iguana/exchanges/LP_nativeDEX.c | 6 +++--- 2 files changed, 10 insertions(+), 4 deletions(-) diff --git a/iguana/exchanges/LP_commands.c b/iguana/exchanges/LP_commands.c index 831675653..6a80ff7ed 100644 --- a/iguana/exchanges/LP_commands.c +++ b/iguana/exchanges/LP_commands.c @@ -342,9 +342,15 @@ bot_resume(botid)\n\ if ( LP_conflicts_find(ptr) == 0 ) { ptr->inactive = 0; - cJSON *array = cJSON_CreateArray(); + cJSON *array; if ( ptr->smartaddr[0] != 0 ) LP_unspents_load(coin,ptr->smartaddr); + if ( LP_getheight(ptr) <= 0 ) + { + ptr->inactive = (uint32_t)time(NULL); + return(clonestr("{\"error\":\"coin cant be activated till synced\"}")); + } else LP_unspents_load(coin,ptr->smartaddr); + array = cJSON_CreateArray(); jaddi(array,LP_coinjson(ptr,0)); return(jprint(array,1)); } else return(clonestr("{\"error\":\"coin port conflicts with existing coin\"}")); diff --git a/iguana/exchanges/LP_nativeDEX.c b/iguana/exchanges/LP_nativeDEX.c index 907f790c0..09cb57a93 100644 --- a/iguana/exchanges/LP_nativeDEX.c +++ b/iguana/exchanges/LP_nativeDEX.c @@ -726,7 +726,7 @@ int32_t LP_mainloop_iter(void *ctx,char *myipaddr,struct LP_peerinfo *mypeer,int { if ( coin->addr_listunspent_requested != 0 && time(NULL) > coin->lastpushtime+10 ) { - printf("PUSH addr_listunspent_requested %u\n",coin->addr_listunspent_requested); + //printf("PUSH addr_listunspent_requested %u\n",coin->addr_listunspent_requested); coin->lastpushtime = (uint32_t)time(NULL); LP_smartutxos_push(coin); coin->addr_listunspent_requested = 0; @@ -759,7 +759,7 @@ void LP_initcoins(void *ctx,int32_t pubsock,cJSON *coins) { if ( LP_getheight(coin) <= 0 ) coin->inactive = (uint32_t)time(NULL); - LP_unspents_load(coin->symbol,coin->smartaddr); + else LP_unspents_load(coin->symbol,coin->smartaddr); } } if ( (n= cJSON_GetArraySize(coins)) > 0 ) @@ -776,7 +776,7 @@ void LP_initcoins(void *ctx,int32_t pubsock,cJSON *coins) { if ( LP_getheight(coin) <= 0 ) coin->inactive = (uint32_t)time(NULL); - LP_unspents_load(coin->symbol,coin->smartaddr); + else LP_unspents_load(coin->symbol,coin->smartaddr); } } } From 3dea6e34d067a68b549de8e6acbd27f2662cc9fd Mon Sep 17 00:00:00 2001 From: jl777 Date: Sun, 5 Nov 2017 18:45:26 +0200 Subject: [PATCH 0227/1664] Test --- iguana/exchanges/LP_commands.c | 3 ++- iguana/exchanges/LP_nativeDEX.c | 2 +- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/iguana/exchanges/LP_commands.c b/iguana/exchanges/LP_commands.c index 6a80ff7ed..fe60a38a3 100644 --- a/iguana/exchanges/LP_commands.c +++ b/iguana/exchanges/LP_commands.c @@ -554,10 +554,11 @@ bot_resume(botid)\n\ //printf("network invoked\n"); LP_privkey_init(-1,ptr,G.LP_privkey,G.LP_mypub25519); //LP_smartutxos_push(ptr); + return(jprint(LP_address_utxos(ptr,coinaddr,1),1)); } else { - + return(clonestr("{\"error\":\"not my address\"}")); } } return(jprint(LP_address_utxos(ptr,coinaddr,1),1)); diff --git a/iguana/exchanges/LP_nativeDEX.c b/iguana/exchanges/LP_nativeDEX.c index 09cb57a93..8a4109323 100644 --- a/iguana/exchanges/LP_nativeDEX.c +++ b/iguana/exchanges/LP_nativeDEX.c @@ -724,7 +724,7 @@ int32_t LP_mainloop_iter(void *ctx,char *myipaddr,struct LP_peerinfo *mypeer,int } HASH_ITER(hh,LP_coins,coin,ctmp) // firstrefht,firstscanht,lastscanht { - if ( coin->addr_listunspent_requested != 0 && time(NULL) > coin->lastpushtime+10 ) + if ( coin->addr_listunspent_requested != 0 && time(NULL) > coin->lastpushtime+LP_ORDERBOOK_DURATION ) { //printf("PUSH addr_listunspent_requested %u\n",coin->addr_listunspent_requested); coin->lastpushtime = (uint32_t)time(NULL); From 6e2e7118303213aa84d02b51c672852d0104fa9c Mon Sep 17 00:00:00 2001 From: jl777 Date: Sun, 5 Nov 2017 19:13:34 +0200 Subject: [PATCH 0228/1664] Resubmit electrum version --- iguana/exchanges/LP_socket.c | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/iguana/exchanges/LP_socket.c b/iguana/exchanges/LP_socket.c index 8907be909..7fb553fc8 100644 --- a/iguana/exchanges/LP_socket.c +++ b/iguana/exchanges/LP_socket.c @@ -360,6 +360,9 @@ int32_t electrum_process_array(struct iguana_info *coin,struct electrum_info *ep return(flag); } +cJSON *electrum_version(char *symbol,struct electrum_info *ep,cJSON **retjsonp); +cJSON *electrum_headers_subscribe(char *symbol,struct electrum_info *ep,cJSON **retjsonp); + cJSON *electrum_submit(char *symbol,struct electrum_info *ep,cJSON **retjsonp,char *method,char *params,int32_t timeout) { // queue id and string and callback @@ -393,6 +396,11 @@ cJSON *electrum_submit(char *symbol,struct electrum_info *ep,cJSON **retjsonp,ch printf("error RE-connecting to %s:%u\n",ep->ipaddr,ep->port); else { + cJSON *retjson; + if ( (retjson= electrum_version(ep->symbol,ep,&retjson)) != 0 ) + printf("electrum_version %s\n",jprint(retjson,1)); + if ( (retjson= electrum_headers_subscribe(ep->symbol,ep,&retjson)) != 0 ) + free_json(retjson); printf("ep.%p %s numerrors.%d too big -> new %s:%u sock.%d\n",ep,ep->symbol,ep->numerrors,ep->ipaddr,ep->port,ep->sock); ep->numerrors = 0; } From 1d429795559bc487aae9b7c7d061ce439f9aedc2 Mon Sep 17 00:00:00 2001 From: jl777 Date: Sun, 5 Nov 2017 20:11:08 +0200 Subject: [PATCH 0229/1664] Test --- iguana/exchanges/LP_rpc.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/iguana/exchanges/LP_rpc.c b/iguana/exchanges/LP_rpc.c index eb9abe808..9f0fde29f 100644 --- a/iguana/exchanges/LP_rpc.c +++ b/iguana/exchanges/LP_rpc.c @@ -291,10 +291,9 @@ char *account = "NXT-MRBN-8DFH-PFMK-A4DBM"; msgstr = "encryptedMessage";//jstr(encjson,"data"); if ( (decjson= LP_NXT_decrypt(txnum,account,jstr(encjson,"data"),jstr(encjson,"nonce"),passphrase)) != 0 ) { - //printf("%s\n",jprint(decjson,0)); + printf("%s\n",jprint(decjson,0)); msgstr = jstr(decjson,"decryptedMessage"); } - } } } From d591bd67bed8dd35f134bfffed434a547b609eb5 Mon Sep 17 00:00:00 2001 From: jl777 Date: Sun, 5 Nov 2017 20:12:41 +0200 Subject: [PATCH 0230/1664] Test --- iguana/exchanges/LP_rpc.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/iguana/exchanges/LP_rpc.c b/iguana/exchanges/LP_rpc.c index 9f0fde29f..aed9a5d25 100644 --- a/iguana/exchanges/LP_rpc.c +++ b/iguana/exchanges/LP_rpc.c @@ -291,8 +291,9 @@ char *account = "NXT-MRBN-8DFH-PFMK-A4DBM"; msgstr = "encryptedMessage";//jstr(encjson,"data"); if ( (decjson= LP_NXT_decrypt(txnum,account,jstr(encjson,"data"),jstr(encjson,"nonce"),passphrase)) != 0 ) { - printf("%s\n",jprint(decjson,0)); - msgstr = jstr(decjson,"decryptedMessage"); + //printf("%s\n",jprint(decjson,0)); + if ( jstr(decjson,"decryptedMessage") != 0 ) + msgstr = jstr(decjson,"decryptedMessage"); } } } From 6de034731b2f748d5240237f0704dfff9b13904c Mon Sep 17 00:00:00 2001 From: jl777 Date: Sun, 5 Nov 2017 20:20:50 +0200 Subject: [PATCH 0231/1664] Test --- iguana/exchanges/LP_rpc.c | 20 +++++++++++++++++++- 1 file changed, 19 insertions(+), 1 deletion(-) diff --git a/iguana/exchanges/LP_rpc.c b/iguana/exchanges/LP_rpc.c index aed9a5d25..0efa274db 100644 --- a/iguana/exchanges/LP_rpc.c +++ b/iguana/exchanges/LP_rpc.c @@ -187,6 +187,24 @@ static char *assetids[][4] = { "10524562908394749924", "MGW", "1", "100000000" }, }; +void LP_sendtoaddress_line(char *validaddress,char *assetname,uint64_t satoshis) +{ + char line[1024],lowerstr[64]; + if ( strcmp(assetname,"SUPERNETx2") == 0 ) + { + sprintf(line,"fiat/supernet sendtoaddress %s %.8f",validaddress,dstr(satoshis)); + printf("%s\n",line); + sprintf(line,"fiat/revs sendtoaddress %s %.8f",validaddress,dstr(satoshis)); + } + else + { + strcpy(lowerstr,assetname); + tolowercase(lowerstr); + sprintf(line,"fiat/%s sendtoaddress %s %.8f",lowerstr,validaddress,dstr(satoshis)); + } + printf("%s\n",line); +} + uint64_t LP_assetid_mult(int32_t *assetindp,char *name,uint64_t assetid) { int32_t i; uint64_t mult = 0; @@ -319,7 +337,7 @@ char *account = "NXT-MRBN-8DFH-PFMK-A4DBM"; } else printf("%-4d: (%34s) <- %13.5f %10s tx.%llu\n",i,msgstr!=0?msgstr:jprint(item,0),dstr(qty * mult),assetname,(long long)txnum); if ( past_marker == 0 ) { - + LP_sendtoaddress_line(validaddress,assetname,dstr(qty * mult)); } } if ( msgjson != 0 ) From eaf4981b50b23b3422cbf1766e093298f904f238 Mon Sep 17 00:00:00 2001 From: jl777 Date: Sun, 5 Nov 2017 20:22:08 +0200 Subject: [PATCH 0232/1664] Test --- iguana/exchanges/LP_rpc.c | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/iguana/exchanges/LP_rpc.c b/iguana/exchanges/LP_rpc.c index 0efa274db..2db576c3c 100644 --- a/iguana/exchanges/LP_rpc.c +++ b/iguana/exchanges/LP_rpc.c @@ -187,20 +187,20 @@ static char *assetids[][4] = { "10524562908394749924", "MGW", "1", "100000000" }, }; -void LP_sendtoaddress_line(char *validaddress,char *assetname,uint64_t satoshis) +void LP_sendtoaddress_line(char *validaddress,char *assetname,uint64_t satoshis,uint64_t txnum) { char line[1024],lowerstr[64]; if ( strcmp(assetname,"SUPERNETx2") == 0 ) { - sprintf(line,"fiat/supernet sendtoaddress %s %.8f",validaddress,dstr(satoshis)); + sprintf(line,"fiat/supernet sendtoaddress %s %.8f # txnum.%llu",validaddress,dstr(satoshis),(long long_txnum)); printf("%s\n",line); - sprintf(line,"fiat/revs sendtoaddress %s %.8f",validaddress,dstr(satoshis)); + sprintf(line,"fiat/revs sendtoaddress %s %.8f # txnum.%llu",validaddress,dstr(satoshis),(long long_txnum); } else { strcpy(lowerstr,assetname); tolowercase(lowerstr); - sprintf(line,"fiat/%s sendtoaddress %s %.8f",lowerstr,validaddress,dstr(satoshis)); + sprintf(line,"fiat/%s sendtoaddress %s %.8f # txnum.%llu",lowerstr,validaddress,dstr(satoshis),(long long_txnum); } printf("%s\n",line); } @@ -337,7 +337,7 @@ char *account = "NXT-MRBN-8DFH-PFMK-A4DBM"; } else printf("%-4d: (%34s) <- %13.5f %10s tx.%llu\n",i,msgstr!=0?msgstr:jprint(item,0),dstr(qty * mult),assetname,(long long)txnum); if ( past_marker == 0 ) { - LP_sendtoaddress_line(validaddress,assetname,dstr(qty * mult)); + LP_sendtoaddress_line(validaddress,assetname,dstr(qty * mult),txnum); } } if ( msgjson != 0 ) From ef5a5731898615001cf0f33703897ef13fd5f2e6 Mon Sep 17 00:00:00 2001 From: jl777 Date: Sun, 5 Nov 2017 20:24:51 +0200 Subject: [PATCH 0233/1664] Test --- iguana/exchanges/LP_rpc.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/iguana/exchanges/LP_rpc.c b/iguana/exchanges/LP_rpc.c index 2db576c3c..5e96df3dc 100644 --- a/iguana/exchanges/LP_rpc.c +++ b/iguana/exchanges/LP_rpc.c @@ -192,15 +192,15 @@ void LP_sendtoaddress_line(char *validaddress,char *assetname,uint64_t satoshis, char line[1024],lowerstr[64]; if ( strcmp(assetname,"SUPERNETx2") == 0 ) { - sprintf(line,"fiat/supernet sendtoaddress %s %.8f # txnum.%llu",validaddress,dstr(satoshis),(long long_txnum)); + sprintf(line,"fiat/supernet sendtoaddress %s %.8f # txnum.%llu",validaddress,dstr(satoshis),(long long)txnum); printf("%s\n",line); - sprintf(line,"fiat/revs sendtoaddress %s %.8f # txnum.%llu",validaddress,dstr(satoshis),(long long_txnum); + sprintf(line,"fiat/revs sendtoaddress %s %.8f # txnum.%llu",validaddress,dstr(satoshis),(long long)txnum); } else { strcpy(lowerstr,assetname); tolowercase(lowerstr); - sprintf(line,"fiat/%s sendtoaddress %s %.8f # txnum.%llu",lowerstr,validaddress,dstr(satoshis),(long long_txnum); + sprintf(line,"fiat/%s sendtoaddress %s %.8f # txnum.%llu",lowerstr,validaddress,dstr(satoshis),(long long)txnum); } printf("%s\n",line); } From 902aaf9475ef33233611bb98a78242a3fc1bebbf Mon Sep 17 00:00:00 2001 From: jl777 Date: Sun, 5 Nov 2017 20:27:51 +0200 Subject: [PATCH 0234/1664] Test --- iguana/exchanges/LP_rpc.c | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/iguana/exchanges/LP_rpc.c b/iguana/exchanges/LP_rpc.c index 5e96df3dc..77d334024 100644 --- a/iguana/exchanges/LP_rpc.c +++ b/iguana/exchanges/LP_rpc.c @@ -333,12 +333,12 @@ char *account = "NXT-MRBN-8DFH-PFMK-A4DBM"; strncpy(validaddress,&msgstr[z],34); if ( strlen(validaddress) == 34 || strlen(validaddress) == 33 ) { - printf("%-4d: (%34s) <- %13.5f %10s tx.%llu past_marker.%d\n",i,validaddress,dstr(qty * mult),assetname,(long long)txnum,past_marker); + //printf("%-4d: (%34s) <- %13.5f %10s tx.%llu past_marker.%d\n",i,validaddress,dstr(qty * mult),assetname,(long long)txnum,past_marker); + if ( past_marker == 0 ) + { + LP_sendtoaddress_line(validaddress,assetname,(qty * mult),txnum); + } } else printf("%-4d: (%34s) <- %13.5f %10s tx.%llu\n",i,msgstr!=0?msgstr:jprint(item,0),dstr(qty * mult),assetname,(long long)txnum); - if ( past_marker == 0 ) - { - LP_sendtoaddress_line(validaddress,assetname,dstr(qty * mult),txnum); - } } if ( msgjson != 0 ) free_json(msgjson); From 13f4a616e4515b3c0495f6b9709c08e2408c24d3 Mon Sep 17 00:00:00 2001 From: jl777 Date: Sun, 5 Nov 2017 20:57:16 +0200 Subject: [PATCH 0235/1664] Test --- iguana/exchanges/LP_socket.c | 19 ++++++++++++++++--- 1 file changed, 16 insertions(+), 3 deletions(-) diff --git a/iguana/exchanges/LP_socket.c b/iguana/exchanges/LP_socket.c index 7fb553fc8..f66aaf218 100644 --- a/iguana/exchanges/LP_socket.c +++ b/iguana/exchanges/LP_socket.c @@ -599,7 +599,10 @@ cJSON *electrum_address_getbalance(char *symbol,struct electrum_info *ep,cJSON * cJSON *electrum_addpeer(char *symbol,struct electrum_info *ep,cJSON **retjsonp,char *endpoint) { return(electrum_strarg(symbol,ep,retjsonp,"server.add_peer",endpoint,ELECTRUM_TIMEOUT)); } cJSON *electrum_sendrawtransaction(char *symbol,struct electrum_info *ep,cJSON **retjsonp,char *rawtx) { return(electrum_strarg(symbol,ep,retjsonp,"blockchain.transaction.broadcast",rawtx,ELECTRUM_TIMEOUT)); } -cJSON *electrum_estimatefee(char *symbol,struct electrum_info *ep,cJSON **retjsonp,int32_t numblocks) { return(electrum_intarg(symbol,ep,retjsonp,"blockchain.estimatefee",numblocks,ELECTRUM_TIMEOUT)); } +cJSON *electrum_estimatefee(char *symbol,struct electrum_info *ep,cJSON **retjsonp,int32_t numblocks) +{ + return(electrum_intarg(symbol,ep,retjsonp,"blockchain.estimatefee",numblocks,ELECTRUM_TIMEOUT)); +} cJSON *electrum_getchunk(char *symbol,struct electrum_info *ep,cJSON **retjsonp,int32_t n) { return(electrum_intarg(symbol,ep,retjsonp,"blockchain.block.get_chunk",n,ELECTRUM_TIMEOUT)); } @@ -840,9 +843,19 @@ struct electrum_info *LP_electrum_info(int32_t *alreadyp,char *symbol,char *ipad int32_t LP_recvfunc(struct electrum_info *ep,char *str,int32_t len) { - cJSON *strjson,*errjson,*resultjson,*paramsjson; char *method; int32_t i,n,height; uint32_t idnum=0; struct stritem *stritem; struct iguana_info *coin; struct queueitem *tmp,*item = 0; + cJSON *strjson,*resitem,*errjson,*resultjson,*paramsjson; char *method; int32_t i,n,height; uint32_t idnum=0; struct stritem *stritem; struct iguana_info *coin; struct queueitem *tmp,*item = 0; + if ( str == 0 || len == 0 ) + return(-1); ep->lasttime = (uint32_t)time(NULL); - if ( (strjson= cJSON_Parse(str)) != 0 ) + if ( (strjson= cJSON_Parse(str)) == 0 ) + { + strjson = cJSON_CreateObject(); + resitem = cJSON_CreateObject(); + jaddstr(resitem,"string",str); + jadd(strjson,"result",resitem); + printf("mapped.(%s) -> %s\n",str,jprint(strjson,0)); + } + if ( 1 ) { resultjson = jobj(strjson,"result"); //printf("strjson.(%s)\n",jprint(strjson,0)); From 380491be626014dc69490d564a2cd6ade0a049fd Mon Sep 17 00:00:00 2001 From: jl777 Date: Sun, 5 Nov 2017 21:01:45 +0200 Subject: [PATCH 0236/1664] Test --- iguana/exchanges/LP_socket.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/iguana/exchanges/LP_socket.c b/iguana/exchanges/LP_socket.c index f66aaf218..7dd644f6a 100644 --- a/iguana/exchanges/LP_socket.c +++ b/iguana/exchanges/LP_socket.c @@ -858,7 +858,7 @@ int32_t LP_recvfunc(struct electrum_info *ep,char *str,int32_t len) if ( 1 ) { resultjson = jobj(strjson,"result"); - //printf("strjson.(%s)\n",jprint(strjson,0)); + printf("strjson.(%s)\n",jprint(strjson,0)); if ( (method= jstr(strjson,"method")) != 0 ) { if ( strcmp(method,"blockchain.headers.subscribe") == 0 ) From 5a7a77e10bb0e5e2e329129e69653c7815c12621 Mon Sep 17 00:00:00 2001 From: jl777 Date: Sun, 5 Nov 2017 21:07:19 +0200 Subject: [PATCH 0237/1664] Test --- iguana/exchanges/LP_socket.c | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/iguana/exchanges/LP_socket.c b/iguana/exchanges/LP_socket.c index 7dd644f6a..e9147c443 100644 --- a/iguana/exchanges/LP_socket.c +++ b/iguana/exchanges/LP_socket.c @@ -843,19 +843,19 @@ struct electrum_info *LP_electrum_info(int32_t *alreadyp,char *symbol,char *ipad int32_t LP_recvfunc(struct electrum_info *ep,char *str,int32_t len) { - cJSON *strjson,*resitem,*errjson,*resultjson,*paramsjson; char *method; int32_t i,n,height; uint32_t idnum=0; struct stritem *stritem; struct iguana_info *coin; struct queueitem *tmp,*item = 0; + cJSON *strjson,*errjson,*resultjson,*paramsjson; char *method; int32_t i,n,height; uint32_t idnum=0; struct stritem *stritem; struct iguana_info *coin; struct queueitem *tmp,*item = 0; if ( str == 0 || len == 0 ) return(-1); ep->lasttime = (uint32_t)time(NULL); - if ( (strjson= cJSON_Parse(str)) == 0 ) + /*if ( (strjson= cJSON_Parse(str)) == 0 ) { strjson = cJSON_CreateObject(); resitem = cJSON_CreateObject(); jaddstr(resitem,"string",str); jadd(strjson,"result",resitem); - printf("mapped.(%s) -> %s\n",str,jprint(strjson,0)); - } - if ( 1 ) + printf("mapped.(%s) -> %s\n",str,jprint(strjson,0)); + }*/ + if ( (strjson= cJSON_Parse(str)) != 0 ) { resultjson = jobj(strjson,"result"); printf("strjson.(%s)\n",jprint(strjson,0)); @@ -899,7 +899,7 @@ int32_t LP_recvfunc(struct electrum_info *ep,char *str,int32_t len) { //printf("matched idnum.%d result.%p\n",idnum,resultjson); DL_DELETE(ep->pendingQ.list,item); - *((cJSON **)stritem->retptrp) = (resultjson != 0 ? jduplicate(resultjson) : strjson); + *((cJSON **)stritem->retptrp) = (resultjson != 0 ? jduplicate(resultjson) : jduplicate(strjson)); resultjson = strjson = 0; free(item); break; From 6dc03dad4ab5c8b1cf96a26d8d776dc00bc78ce4 Mon Sep 17 00:00:00 2001 From: jl777 Date: Sun, 5 Nov 2017 21:12:45 +0200 Subject: [PATCH 0238/1664] Test --- iguana/exchanges/LP_rpc.c | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/iguana/exchanges/LP_rpc.c b/iguana/exchanges/LP_rpc.c index 77d334024..3b8e5fdd4 100644 --- a/iguana/exchanges/LP_rpc.c +++ b/iguana/exchanges/LP_rpc.c @@ -826,8 +826,6 @@ double _LP_getestimatedrate(struct iguana_info *coin) sprintf(buf,"[%d]",strcmp(coin->symbol,"BTC") == 0 ? 6 : 2); if ( (retstr= LP_apicall(coin,coin->electrum==0?"estimatefee" : "blockchain.estimatefee",buf)) != 0 ) { - if ( coin->electrum != 0 ) - printf("estimatefee.(%s)\n",retstr); if ( retstr[0] == '{' && (errjson= cJSON_Parse(retstr)) != 0 ) { if ( jobj(errjson,"error") != 0 ) @@ -847,7 +845,8 @@ double _LP_getestimatedrate(struct iguana_info *coin) coin->rate = rate; coin->ratetime = (uint32_t)time(NULL); } - free(retstr); + if ( coin->electrum == 0 ) + free(retstr); } else rate = coin->rate; } else rate = coin->rate; return(rate); From 4720c6d5f745d3021773beb18d9e1954c01483e7 Mon Sep 17 00:00:00 2001 From: jl777 Date: Sun, 5 Nov 2017 21:16:45 +0200 Subject: [PATCH 0239/1664] Test --- iguana/exchanges/LP_socket.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/iguana/exchanges/LP_socket.c b/iguana/exchanges/LP_socket.c index e9147c443..f1a02583c 100644 --- a/iguana/exchanges/LP_socket.c +++ b/iguana/exchanges/LP_socket.c @@ -858,7 +858,7 @@ int32_t LP_recvfunc(struct electrum_info *ep,char *str,int32_t len) if ( (strjson= cJSON_Parse(str)) != 0 ) { resultjson = jobj(strjson,"result"); - printf("strjson.(%s)\n",jprint(strjson,0)); + //printf("strjson.(%s)\n",jprint(strjson,0)); if ( (method= jstr(strjson,"method")) != 0 ) { if ( strcmp(method,"blockchain.headers.subscribe") == 0 ) From f153903b3277697ce1a412401c03ae34b72582af Mon Sep 17 00:00:00 2001 From: jl777 Date: Sun, 5 Nov 2017 21:23:20 +0200 Subject: [PATCH 0240/1664] Test --- iguana/exchanges/LP_socket.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/iguana/exchanges/LP_socket.c b/iguana/exchanges/LP_socket.c index f1a02583c..6a2903ea9 100644 --- a/iguana/exchanges/LP_socket.c +++ b/iguana/exchanges/LP_socket.c @@ -897,9 +897,9 @@ int32_t LP_recvfunc(struct electrum_info *ep,char *str,int32_t len) stritem = (struct stritem *)item; if ( item->type == idnum ) { - //printf("matched idnum.%d result.%p\n",idnum,resultjson); DL_DELETE(ep->pendingQ.list,item); *((cJSON **)stritem->retptrp) = (resultjson != 0 ? jduplicate(resultjson) : jduplicate(strjson)); + printf("matched idnum.%d result.(%s)\n",idnum,jprint(*((cJSON **)stritem->retptrp),0)); resultjson = strjson = 0; free(item); break; @@ -916,6 +916,7 @@ int32_t LP_recvfunc(struct electrum_info *ep,char *str,int32_t len) *((cJSON **)stritem->retptrp) = errjson; } free(item); + item = 0; } } } From c685d032e4144ef58c6510359e9e5f7256642fcb Mon Sep 17 00:00:00 2001 From: jl777 Date: Sun, 5 Nov 2017 21:33:09 +0200 Subject: [PATCH 0241/1664] Test --- iguana/exchanges/LP_socket.c | 17 ++++++++++++++--- 1 file changed, 14 insertions(+), 3 deletions(-) diff --git a/iguana/exchanges/LP_socket.c b/iguana/exchanges/LP_socket.c index 6a2903ea9..75529b2e7 100644 --- a/iguana/exchanges/LP_socket.c +++ b/iguana/exchanges/LP_socket.c @@ -892,15 +892,26 @@ int32_t LP_recvfunc(struct electrum_info *ep,char *str,int32_t len) portable_mutex_lock(&ep->pendingQ.mutex); if ( ep->pendingQ.list != 0 ) { + cJSON *tmpjson; char *tmpstr; DL_FOREACH_SAFE(ep->pendingQ.list,item,tmp) { stritem = (struct stritem *)item; if ( item->type == idnum ) { DL_DELETE(ep->pendingQ.list,item); - *((cJSON **)stritem->retptrp) = (resultjson != 0 ? jduplicate(resultjson) : jduplicate(strjson)); - printf("matched idnum.%d result.(%s)\n",idnum,jprint(*((cJSON **)stritem->retptrp),0)); - resultjson = strjson = 0; + if ( resultjson != 0 ) + { + tmpstr = jprint(resultjson,0); + if ( (tmpjson= cJSON_Parse(tmpstr)) == 0 ) + { + tmpjson = cJSON_CreateObject(); + jadd(tmpjson,"result",jduplicate(resultjson)); + } + free(tmpstr); + } else tmpjson = cJSON_CreateObject(); + //*((cJSON **)stritem->retptrp) = (resultjson != 0 ? jduplicate(resultjson) : jduplicate(strjson)); + *((cJSON **)stritem->retptrp) = tmpjson; + printf("matched idnum.%d result.(%s)\n",idnum,jprint(tmpjson,0)); free(item); break; } From 788f761c20f7a896179d8fbe4b03181f3ec85a8c Mon Sep 17 00:00:00 2001 From: jl777 Date: Sun, 5 Nov 2017 21:38:41 +0200 Subject: [PATCH 0242/1664] Test --- iguana/exchanges/LP_socket.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/iguana/exchanges/LP_socket.c b/iguana/exchanges/LP_socket.c index 75529b2e7..b1b04b5d0 100644 --- a/iguana/exchanges/LP_socket.c +++ b/iguana/exchanges/LP_socket.c @@ -902,7 +902,7 @@ int32_t LP_recvfunc(struct electrum_info *ep,char *str,int32_t len) if ( resultjson != 0 ) { tmpstr = jprint(resultjson,0); - if ( (tmpjson= cJSON_Parse(tmpstr)) == 0 ) + if ( (tmpstr[0] != '[' && tmpstr[0] != '{') || (tmpjson= cJSON_Parse(tmpstr)) == 0 ) { tmpjson = cJSON_CreateObject(); jadd(tmpjson,"result",jduplicate(resultjson)); From 18aafde22db18fa4c9ce2247edc3f559717011fd Mon Sep 17 00:00:00 2001 From: jl777 Date: Sun, 5 Nov 2017 21:51:49 +0200 Subject: [PATCH 0243/1664] Test --- iguana/exchanges/LP_rpc.c | 19 ++++++++++++++----- iguana/exchanges/LP_socket.c | 18 +++--------------- 2 files changed, 17 insertions(+), 20 deletions(-) diff --git a/iguana/exchanges/LP_rpc.c b/iguana/exchanges/LP_rpc.c index 3b8e5fdd4..9b3345ab6 100644 --- a/iguana/exchanges/LP_rpc.c +++ b/iguana/exchanges/LP_rpc.c @@ -820,11 +820,21 @@ int32_t LP_importaddress(char *symbol,char *address) double _LP_getestimatedrate(struct iguana_info *coin) { - char buf[512],*retstr; cJSON *errjson; double rate = 0.00000020; + char buf[512],*retstr=0; int32_t numblocks; cJSON *errjson,*retjson; double rate = 0.00000020; if ( coin->rate < 0. || time(NULL) > coin->ratetime+30 ) { - sprintf(buf,"[%d]",strcmp(coin->symbol,"BTC") == 0 ? 6 : 2); - if ( (retstr= LP_apicall(coin,coin->electrum==0?"estimatefee" : "blockchain.estimatefee",buf)) != 0 ) + numblocks = strcmp(coin->symbol,"BTC") == 0 ? 6 : 2; + if ( coin->electrum == 0 ) + { + sprintf(buf,"[%d]",numblocks); + retstr = LP_apicall(coin,"estimatefee",buf); + } + else + { + if ( (retjson= electrum_estimatefee(coin->symbol,coin->electrum,&retjson,numblocks)) != 0 ) + retstr = jprint(retjson,1); + } + if ( retstr != 0 ) { if ( retstr[0] == '{' && (errjson= cJSON_Parse(retstr)) != 0 ) { @@ -845,8 +855,7 @@ double _LP_getestimatedrate(struct iguana_info *coin) coin->rate = rate; coin->ratetime = (uint32_t)time(NULL); } - if ( coin->electrum == 0 ) - free(retstr); + free(retstr); } else rate = coin->rate; } else rate = coin->rate; return(rate); diff --git a/iguana/exchanges/LP_socket.c b/iguana/exchanges/LP_socket.c index b1b04b5d0..55e40f3fe 100644 --- a/iguana/exchanges/LP_socket.c +++ b/iguana/exchanges/LP_socket.c @@ -892,26 +892,15 @@ int32_t LP_recvfunc(struct electrum_info *ep,char *str,int32_t len) portable_mutex_lock(&ep->pendingQ.mutex); if ( ep->pendingQ.list != 0 ) { - cJSON *tmpjson; char *tmpstr; DL_FOREACH_SAFE(ep->pendingQ.list,item,tmp) { stritem = (struct stritem *)item; if ( item->type == idnum ) { DL_DELETE(ep->pendingQ.list,item); - if ( resultjson != 0 ) - { - tmpstr = jprint(resultjson,0); - if ( (tmpstr[0] != '[' && tmpstr[0] != '{') || (tmpjson= cJSON_Parse(tmpstr)) == 0 ) - { - tmpjson = cJSON_CreateObject(); - jadd(tmpjson,"result",jduplicate(resultjson)); - } - free(tmpstr); - } else tmpjson = cJSON_CreateObject(); - //*((cJSON **)stritem->retptrp) = (resultjson != 0 ? jduplicate(resultjson) : jduplicate(strjson)); - *((cJSON **)stritem->retptrp) = tmpjson; - printf("matched idnum.%d result.(%s)\n",idnum,jprint(tmpjson,0)); + *((cJSON **)stritem->retptrp) = (resultjson != 0 ? jduplicate(resultjson) : jduplicate(strjson)); + resultjson = strjson = 0; + printf("matched idnum.%d result.%p\n",idnum,resultjson); free(item); break; } @@ -927,7 +916,6 @@ int32_t LP_recvfunc(struct electrum_info *ep,char *str,int32_t len) *((cJSON **)stritem->retptrp) = errjson; } free(item); - item = 0; } } } From c926c02ad6e8bdc9bc33a500f36dbcc2a4085166 Mon Sep 17 00:00:00 2001 From: jl777 Date: Sun, 5 Nov 2017 21:59:13 +0200 Subject: [PATCH 0244/1664] Test --- iguana/exchanges/LP_socket.c | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/iguana/exchanges/LP_socket.c b/iguana/exchanges/LP_socket.c index 55e40f3fe..5e1bfdc9a 100644 --- a/iguana/exchanges/LP_socket.c +++ b/iguana/exchanges/LP_socket.c @@ -899,8 +899,8 @@ int32_t LP_recvfunc(struct electrum_info *ep,char *str,int32_t len) { DL_DELETE(ep->pendingQ.list,item); *((cJSON **)stritem->retptrp) = (resultjson != 0 ? jduplicate(resultjson) : jduplicate(strjson)); - resultjson = strjson = 0; printf("matched idnum.%d result.%p\n",idnum,resultjson); + resultjson = strjson = 0; free(item); break; } @@ -936,6 +936,12 @@ void LP_dedicatedloop(void *arg) printf("electrum_version %s\n",jprint(retjson,1)); if ( (retjson= electrum_headers_subscribe(ep->symbol,ep,&retjson)) != 0 ) free_json(retjson); + for (i=0; i<3; i++) + if ( (retjson= electrum_estimatefee(coin->symbol,coin->electrum,&retjson,2)) != 0 ) + { + printf("estimate fee (%s)\n",jprint(retjson,0)); + free_json(retjson); + } printf("LP_dedicatedloop ep.%p sock.%d for %s:%u num.%d %p %s ht.%d\n",ep,ep->sock,ep->ipaddr,ep->port,Num_electrums,&Num_electrums,ep->symbol,*ep->heightp); while ( ep->sock >= 0 ) { From 19b23b378609cb15d3d0153ad19c7524c64a245b Mon Sep 17 00:00:00 2001 From: jl777 Date: Sun, 5 Nov 2017 22:01:38 +0200 Subject: [PATCH 0245/1664] Test --- iguana/exchanges/LP_socket.c | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/iguana/exchanges/LP_socket.c b/iguana/exchanges/LP_socket.c index 5e1bfdc9a..d08ba1e1d 100644 --- a/iguana/exchanges/LP_socket.c +++ b/iguana/exchanges/LP_socket.c @@ -937,10 +937,13 @@ void LP_dedicatedloop(void *arg) if ( (retjson= electrum_headers_subscribe(ep->symbol,ep,&retjson)) != 0 ) free_json(retjson); for (i=0; i<3; i++) - if ( (retjson= electrum_estimatefee(coin->symbol,coin->electrum,&retjson,2)) != 0 ) { - printf("estimate fee (%s)\n",jprint(retjson,0)); - free_json(retjson); + printf("call estimatefee\n"); + if ( (retjson= electrum_estimatefee(coin->symbol,coin->electrum,&retjson,2)) != 0 ) + { + printf("estimate fee (%s)\n",jprint(retjson,0)); + free_json(retjson); + } else printf("null value from electrum_estimatefee\n"); } printf("LP_dedicatedloop ep.%p sock.%d for %s:%u num.%d %p %s ht.%d\n",ep,ep->sock,ep->ipaddr,ep->port,Num_electrums,&Num_electrums,ep->symbol,*ep->heightp); while ( ep->sock >= 0 ) From ac2f5ac86bdd3c041b79486a44b6004b5614fbc8 Mon Sep 17 00:00:00 2001 From: jl777 Date: Sun, 5 Nov 2017 22:06:30 +0200 Subject: [PATCH 0246/1664] Test --- iguana/exchanges/LP_socket.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/iguana/exchanges/LP_socket.c b/iguana/exchanges/LP_socket.c index d08ba1e1d..eda80712b 100644 --- a/iguana/exchanges/LP_socket.c +++ b/iguana/exchanges/LP_socket.c @@ -932,10 +932,6 @@ void LP_dedicatedloop(void *arg) if ( (coin= LP_coinfind(ep->symbol)) != 0 ) ep->heightp = &coin->height, ep->heighttimep = &coin->heighttime; sleep(2); - if ( (retjson= electrum_version(ep->symbol,ep,&retjson)) != 0 ) - printf("electrum_version %s\n",jprint(retjson,1)); - if ( (retjson= electrum_headers_subscribe(ep->symbol,ep,&retjson)) != 0 ) - free_json(retjson); for (i=0; i<3; i++) { printf("call estimatefee\n"); @@ -945,6 +941,10 @@ void LP_dedicatedloop(void *arg) free_json(retjson); } else printf("null value from electrum_estimatefee\n"); } + if ( (retjson= electrum_version(ep->symbol,ep,&retjson)) != 0 ) + printf("electrum_version %s\n",jprint(retjson,1)); + if ( (retjson= electrum_headers_subscribe(ep->symbol,ep,&retjson)) != 0 ) + free_json(retjson); printf("LP_dedicatedloop ep.%p sock.%d for %s:%u num.%d %p %s ht.%d\n",ep,ep->sock,ep->ipaddr,ep->port,Num_electrums,&Num_electrums,ep->symbol,*ep->heightp); while ( ep->sock >= 0 ) { From fc05d424a1759b887170e621097e25a3f4389f33 Mon Sep 17 00:00:00 2001 From: jl777 Date: Sun, 5 Nov 2017 22:09:12 +0200 Subject: [PATCH 0247/1664] Test --- iguana/exchanges/LP_socket.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/iguana/exchanges/LP_socket.c b/iguana/exchanges/LP_socket.c index eda80712b..9b5e22bcd 100644 --- a/iguana/exchanges/LP_socket.c +++ b/iguana/exchanges/LP_socket.c @@ -931,6 +931,8 @@ void LP_dedicatedloop(void *arg) struct pollfd fds; int32_t i,len,flag,timeout = 10; struct iguana_info *coin; cJSON *retjson; struct stritem *sitem; struct electrum_info *ep = arg; if ( (coin= LP_coinfind(ep->symbol)) != 0 ) ep->heightp = &coin->height, ep->heighttimep = &coin->heighttime; + if ( (retjson= electrum_headers_subscribe(ep->symbol,ep,&retjson)) != 0 ) + free_json(retjson); sleep(2); for (i=0; i<3; i++) { @@ -943,8 +945,6 @@ void LP_dedicatedloop(void *arg) } if ( (retjson= electrum_version(ep->symbol,ep,&retjson)) != 0 ) printf("electrum_version %s\n",jprint(retjson,1)); - if ( (retjson= electrum_headers_subscribe(ep->symbol,ep,&retjson)) != 0 ) - free_json(retjson); printf("LP_dedicatedloop ep.%p sock.%d for %s:%u num.%d %p %s ht.%d\n",ep,ep->sock,ep->ipaddr,ep->port,Num_electrums,&Num_electrums,ep->symbol,*ep->heightp); while ( ep->sock >= 0 ) { From 89efa12c76ddd26e52e211f4dfb7829850f64146 Mon Sep 17 00:00:00 2001 From: jl777 Date: Sun, 5 Nov 2017 22:22:08 +0200 Subject: [PATCH 0248/1664] Test --- iguana/exchanges/LP_socket.c | 50 +++++++++++++++++++++++------------- 1 file changed, 32 insertions(+), 18 deletions(-) diff --git a/iguana/exchanges/LP_socket.c b/iguana/exchanges/LP_socket.c index 9b5e22bcd..d8829ac22 100644 --- a/iguana/exchanges/LP_socket.c +++ b/iguana/exchanges/LP_socket.c @@ -363,6 +363,16 @@ int32_t electrum_process_array(struct iguana_info *coin,struct electrum_info *ep cJSON *electrum_version(char *symbol,struct electrum_info *ep,cJSON **retjsonp); cJSON *electrum_headers_subscribe(char *symbol,struct electrum_info *ep,cJSON **retjsonp); +struct stritem *electrum_sitem(struct electrum_info *ep,char *stratumreq,int32_t timeout,cJSON **retjsonp) +{ + struct stritem *sitem = (struct stritem *)queueitem(stratumreq); + sitem->expiration = timeout; + sitem->DL.type = ep->stratumid++; + sitem->retptrp = (void **)retjsonp; + queue_enqueue("sendQ",&ep->sendQ,&sitem->DL); + return(sitem); +} + cJSON *electrum_submit(char *symbol,struct electrum_info *ep,cJSON **retjsonp,char *method,char *params,int32_t timeout) { // queue id and string and callback @@ -377,12 +387,13 @@ cJSON *electrum_submit(char *symbol,struct electrum_info *ep,cJSON **retjsonp,ch sprintf(stratumreq,"{ \"jsonrpc\":\"2.0\", \"id\": %u, \"method\":\"%s\", \"params\": %s }\n",ep->stratumid,method,params); //printf("%s %s",symbol,stratumreq); memset(ep->buf,0,ep->bufsize); - sitem = (struct stritem *)queueitem(stratumreq); + sitem = electrum_sitem(ep,stratumreq,timeout,retjsonp); + /*sitem = (struct stritem *)queueitem(stratumreq); sitem->expiration = timeout; sitem->DL.type = ep->stratumid++; - sitem->retptrp = (void **)retjsonp; + sitem->retptrp = (void **)retjsonp;*/ portable_mutex_lock(&ep->mutex); - queue_enqueue("sendQ",&ep->sendQ,&sitem->DL); + //queue_enqueue("sendQ",&ep->sendQ,&sitem->DL); expiration = (uint32_t)time(NULL) + timeout + 1; while ( *retjsonp == 0 && time(NULL) <= expiration ) usleep(5000); @@ -928,23 +939,26 @@ int32_t LP_recvfunc(struct electrum_info *ep,char *str,int32_t len) void LP_dedicatedloop(void *arg) { - struct pollfd fds; int32_t i,len,flag,timeout = 10; struct iguana_info *coin; cJSON *retjson; struct stritem *sitem; struct electrum_info *ep = arg; + char stratumreq[1024]; struct pollfd fds; int32_t i,len,flag,timeout = 10; struct iguana_info *coin; cJSON *retjson=0; struct stritem *sitem; struct electrum_info *ep = arg; if ( (coin= LP_coinfind(ep->symbol)) != 0 ) ep->heightp = &coin->height, ep->heighttimep = &coin->heighttime; - if ( (retjson= electrum_headers_subscribe(ep->symbol,ep,&retjson)) != 0 ) - free_json(retjson); - sleep(2); - for (i=0; i<3; i++) - { - printf("call estimatefee\n"); - if ( (retjson= electrum_estimatefee(coin->symbol,coin->electrum,&retjson,2)) != 0 ) - { - printf("estimate fee (%s)\n",jprint(retjson,0)); - free_json(retjson); - } else printf("null value from electrum_estimatefee\n"); - } - if ( (retjson= electrum_version(ep->symbol,ep,&retjson)) != 0 ) - printf("electrum_version %s\n",jprint(retjson,1)); + retjson = 0; + sprintf(stratumreq,"{ \"jsonrpc\":\"2.0\", \"id\": %u, \"method\":\"%s\", \"params\": %s }\n",ep->stratumid,"blockchain.headers.subscribe","[]"); + electrum_sitem(ep,stratumreq,3,&retjson); + + retjson = 0; + sprintf(stratumreq,"{ \"jsonrpc\":\"2.0\", \"id\": %u, \"method\":\"%s\", \"params\": %s }\n",ep->stratumid,"server.version","[\"barterDEX\", [\"1.1\", \"1.1\"]]"); + electrum_sitem(ep,stratumreq,3,&retjson); + + retjson = 0; + sprintf(stratumreq,"{ \"jsonrpc\":\"2.0\", \"id\": %u, \"method\":\"%s\", \"params\": %s }\n",ep->stratumid,"blockchain.estimatefee","[2]"); + electrum_sitem(ep,stratumreq,3,&retjson); + + + //if ( (retjson= electrum_headers_subscribe(ep->symbol,ep,&retjson)) != 0 ) + // free_json(retjson); + //if ( (retjson= electrum_version(ep->symbol,ep,&retjson)) != 0 ) + // printf("electrum_version %s\n",jprint(retjson,1)); printf("LP_dedicatedloop ep.%p sock.%d for %s:%u num.%d %p %s ht.%d\n",ep,ep->sock,ep->ipaddr,ep->port,Num_electrums,&Num_electrums,ep->symbol,*ep->heightp); while ( ep->sock >= 0 ) { From 982e9097953be34cde7560e6777446c2e19d3766 Mon Sep 17 00:00:00 2001 From: jl777 Date: Sun, 5 Nov 2017 22:24:36 +0200 Subject: [PATCH 0249/1664] Test --- iguana/exchanges/LP_socket.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/iguana/exchanges/LP_socket.c b/iguana/exchanges/LP_socket.c index d8829ac22..500239802 100644 --- a/iguana/exchanges/LP_socket.c +++ b/iguana/exchanges/LP_socket.c @@ -910,7 +910,7 @@ int32_t LP_recvfunc(struct electrum_info *ep,char *str,int32_t len) { DL_DELETE(ep->pendingQ.list,item); *((cJSON **)stritem->retptrp) = (resultjson != 0 ? jduplicate(resultjson) : jduplicate(strjson)); - printf("matched idnum.%d result.%p\n",idnum,resultjson); + printf("matched idnum.%d result.(%s)\n",idnum,jprint(*((cJSON **)stritem->retptrp),0)); resultjson = strjson = 0; free(item); break; From fb535fb7e20aa7b3668341cd34ec49d58bd69757 Mon Sep 17 00:00:00 2001 From: jl777 Date: Sun, 5 Nov 2017 22:26:09 +0200 Subject: [PATCH 0250/1664] Test --- iguana/exchanges/LP_socket.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/iguana/exchanges/LP_socket.c b/iguana/exchanges/LP_socket.c index 500239802..5eca7fd1c 100644 --- a/iguana/exchanges/LP_socket.c +++ b/iguana/exchanges/LP_socket.c @@ -910,7 +910,7 @@ int32_t LP_recvfunc(struct electrum_info *ep,char *str,int32_t len) { DL_DELETE(ep->pendingQ.list,item); *((cJSON **)stritem->retptrp) = (resultjson != 0 ? jduplicate(resultjson) : jduplicate(strjson)); - printf("matched idnum.%d result.(%s)\n",idnum,jprint(*((cJSON **)stritem->retptrp),0)); + //printf("matched idnum.%d result.(%s)\n",idnum,jprint(*((cJSON **)stritem->retptrp),0)); resultjson = strjson = 0; free(item); break; From 3bb803f23752dcb07f6642a8e4b330a077c11c22 Mon Sep 17 00:00:00 2001 From: jl777 Date: Sun, 5 Nov 2017 22:34:55 +0200 Subject: [PATCH 0251/1664] Test --- iguana/exchanges/LP_socket.c | 43 +++++++++++++++++------------------- 1 file changed, 20 insertions(+), 23 deletions(-) diff --git a/iguana/exchanges/LP_socket.c b/iguana/exchanges/LP_socket.c index 5eca7fd1c..dafac13b2 100644 --- a/iguana/exchanges/LP_socket.c +++ b/iguana/exchanges/LP_socket.c @@ -373,6 +373,22 @@ struct stritem *electrum_sitem(struct electrum_info *ep,char *stratumreq,int32_t return(sitem); } +void electrum_initial_requests(struct electrum_info *ep) +{ + cJSON *retjson; char stratumreq[1024]; + retjson = 0; + sprintf(stratumreq,"{ \"jsonrpc\":\"2.0\", \"id\": %u, \"method\":\"%s\", \"params\": %s }\n",ep->stratumid,"blockchain.headers.subscribe","[]"); + electrum_sitem(ep,stratumreq,3,&retjson); + + retjson = 0; + sprintf(stratumreq,"{ \"jsonrpc\":\"2.0\", \"id\": %u, \"method\":\"%s\", \"params\": %s }\n",ep->stratumid,"server.version","[\"barterDEX\", [\"1.1\", \"1.1\"]]"); + electrum_sitem(ep,stratumreq,3,&retjson); + + retjson = 0; + sprintf(stratumreq,"{ \"jsonrpc\":\"2.0\", \"id\": %u, \"method\":\"%s\", \"params\": %s }\n",ep->stratumid,"blockchain.estimatefee","[2]"); + electrum_sitem(ep,stratumreq,3,&retjson); +} + cJSON *electrum_submit(char *symbol,struct electrum_info *ep,cJSON **retjsonp,char *method,char *params,int32_t timeout) { // queue id and string and callback @@ -407,11 +423,8 @@ cJSON *electrum_submit(char *symbol,struct electrum_info *ep,cJSON **retjsonp,ch printf("error RE-connecting to %s:%u\n",ep->ipaddr,ep->port); else { - cJSON *retjson; - if ( (retjson= electrum_version(ep->symbol,ep,&retjson)) != 0 ) - printf("electrum_version %s\n",jprint(retjson,1)); - if ( (retjson= electrum_headers_subscribe(ep->symbol,ep,&retjson)) != 0 ) - free_json(retjson); + ep->stratumid = 0; + electrum_initial_requests(ep); printf("ep.%p %s numerrors.%d too big -> new %s:%u sock.%d\n",ep,ep->symbol,ep->numerrors,ep->ipaddr,ep->port,ep->sock); ep->numerrors = 0; } @@ -939,26 +952,10 @@ int32_t LP_recvfunc(struct electrum_info *ep,char *str,int32_t len) void LP_dedicatedloop(void *arg) { - char stratumreq[1024]; struct pollfd fds; int32_t i,len,flag,timeout = 10; struct iguana_info *coin; cJSON *retjson=0; struct stritem *sitem; struct electrum_info *ep = arg; + struct pollfd fds; int32_t i,len,flag,timeout = 10; struct iguana_info *coin; struct stritem *sitem; struct electrum_info *ep = arg; if ( (coin= LP_coinfind(ep->symbol)) != 0 ) ep->heightp = &coin->height, ep->heighttimep = &coin->heighttime; - retjson = 0; - sprintf(stratumreq,"{ \"jsonrpc\":\"2.0\", \"id\": %u, \"method\":\"%s\", \"params\": %s }\n",ep->stratumid,"blockchain.headers.subscribe","[]"); - electrum_sitem(ep,stratumreq,3,&retjson); - - retjson = 0; - sprintf(stratumreq,"{ \"jsonrpc\":\"2.0\", \"id\": %u, \"method\":\"%s\", \"params\": %s }\n",ep->stratumid,"server.version","[\"barterDEX\", [\"1.1\", \"1.1\"]]"); - electrum_sitem(ep,stratumreq,3,&retjson); - - retjson = 0; - sprintf(stratumreq,"{ \"jsonrpc\":\"2.0\", \"id\": %u, \"method\":\"%s\", \"params\": %s }\n",ep->stratumid,"blockchain.estimatefee","[2]"); - electrum_sitem(ep,stratumreq,3,&retjson); - - - //if ( (retjson= electrum_headers_subscribe(ep->symbol,ep,&retjson)) != 0 ) - // free_json(retjson); - //if ( (retjson= electrum_version(ep->symbol,ep,&retjson)) != 0 ) - // printf("electrum_version %s\n",jprint(retjson,1)); + electrum_initial_requests(ep); printf("LP_dedicatedloop ep.%p sock.%d for %s:%u num.%d %p %s ht.%d\n",ep,ep->sock,ep->ipaddr,ep->port,Num_electrums,&Num_electrums,ep->symbol,*ep->heightp); while ( ep->sock >= 0 ) { From 053bb32ce7bf881216e7293389ee63ea61b3edc3 Mon Sep 17 00:00:00 2001 From: jl777 Date: Mon, 6 Nov 2017 06:32:38 +0200 Subject: [PATCH 0252/1664] Pub key -> destpubkey --- iguana/exchanges/LP_bitcoin.c | 12 ++++++++++++ iguana/exchanges/LP_commands.c | 8 ++++---- 2 files changed, 16 insertions(+), 4 deletions(-) diff --git a/iguana/exchanges/LP_bitcoin.c b/iguana/exchanges/LP_bitcoin.c index 1c2c5d0c5..0eef539d1 100644 --- a/iguana/exchanges/LP_bitcoin.c +++ b/iguana/exchanges/LP_bitcoin.c @@ -1959,6 +1959,18 @@ int32_t bitcoin_timelockspend(uint8_t *script,int32_t n,uint8_t rmd160[20],uint3 return(n); } +int32_t bitcoin_performancebond(uint8_t p2sh_rmd160[20],uint8_t *script,int32_t n,uint32_t unlocktimestamp,uint8_t cltv_rmd160[20],uint8_t anytime_rmd160[20]) +{ + script[n++] = SCRIPT_OP_IF; + n = bitcoin_checklocktimeverify(script,n,unlocktimestamp); + n = bitcoin_standardspend(script,n,cltv_rmd160); + script[n++] = SCRIPT_OP_ELSE; + n = bitcoin_standardspend(script,n,anytime_rmd160); + script[n++] = SCRIPT_OP_ENDIF; + calc_rmd160_sha256(p2sh_rmd160,script,n); + return(n); +} + int32_t bitcoin_MofNspendscript(uint8_t p2sh_rmd160[20],uint8_t *script,int32_t n,const struct vin_info *vp) { int32_t i,plen; diff --git a/iguana/exchanges/LP_commands.c b/iguana/exchanges/LP_commands.c index fe60a38a3..831f81ccb 100644 --- a/iguana/exchanges/LP_commands.c +++ b/iguana/exchanges/LP_commands.c @@ -111,8 +111,8 @@ getrawtransaction(coin, txid)\n\ inventory(coin)\n\ bestfit(rel, relvolume)\n\ lastnonce()\n\ -buy(base, rel, price, relvolume, timeout=10, duration=3600, nonce, pubkey="")\n\ -sell(base, rel, price, basevolume, timeout=10, duration=3600, nonce, pubkey="")\n\ +buy(base, rel, price, relvolume, timeout=10, duration=3600, nonce, destpubkey="")\n\ +sell(base, rel, price, basevolume, timeout=10, duration=3600, nonce, destpubkey="")\n\ withdraw(coin, outputs[])\n\ sendrawtransaction(coin, signedtx)\n\ swapstatus()\n\ @@ -306,7 +306,7 @@ bot_resume(botid)\n\ //* if ( price > SMALLVAL ) { - return(LP_autobuy(ctx,myipaddr,pubsock,base,rel,price,jdouble(argjson,"relvolume"),jint(argjson,"timeout"),jint(argjson,"duration"),jstr(argjson,"gui"),juint(argjson,"nonce"),jbits256(argjson,"pubkey"),0)); + return(LP_autobuy(ctx,myipaddr,pubsock,base,rel,price,jdouble(argjson,"relvolume"),jint(argjson,"timeout"),jint(argjson,"duration"),jstr(argjson,"gui"),juint(argjson,"nonce"),jbits256(argjson,"destpubkey"),0)); } else return(clonestr("{\"error\":\"no price set\"}")); } else if ( strcmp(method,"sell") == 0 ) @@ -314,7 +314,7 @@ bot_resume(botid)\n\ //* 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"),juint(argjson,"nonce"),jbits256(argjson,"pubkey"),0)); + 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"),jbits256(argjson,"destpubkey"),0)); } else return(clonestr("{\"error\":\"no price set\"}")); } } From ef30184405157ccf78b77d670b858c386653e6ed Mon Sep 17 00:00:00 2001 From: jl777 Date: Mon, 6 Nov 2017 10:50:26 +0200 Subject: [PATCH 0253/1664] Test --- iguana/exchanges/LP_nativeDEX.c | 8 +++++++- iguana/exchanges/LP_network.c | 26 ++++++++++++++++++++------ 2 files changed, 27 insertions(+), 7 deletions(-) diff --git a/iguana/exchanges/LP_nativeDEX.c b/iguana/exchanges/LP_nativeDEX.c index 8a4109323..9a6809a04 100644 --- a/iguana/exchanges/LP_nativeDEX.c +++ b/iguana/exchanges/LP_nativeDEX.c @@ -29,7 +29,7 @@ struct LP_millistats double lastmilli,millisum,threshold; uint32_t count; char name[64]; -} LP_psockloop_stats,LP_reserved_msgs_stats,utxosQ_loop_stats,command_rpcloop_stats,queue_loop_stats,prices_loop_stats,LP_coinsloop_stats,LP_coinsloopBTC_stats,LP_coinsloopKMD_stats,LP_pubkeysloop_stats,LP_privkeysloop_stats,LP_swapsloop_stats; +} LP_psockloop_stats,LP_reserved_msgs_stats,utxosQ_loop_stats,command_rpcloop_stats,queue_loop_stats,prices_loop_stats,LP_coinsloop_stats,LP_coinsloopBTC_stats,LP_coinsloopKMD_stats,LP_pubkeysloop_stats,LP_privkeysloop_stats,LP_swapsloop_stats,LP_gcloop_stats; extern int32_t IAMLP; void LP_millistats_update(struct LP_millistats *mp) @@ -52,6 +52,7 @@ void LP_millistats_update(struct LP_millistats *mp) mp = &LP_pubkeysloop_stats, printf("%32s lag %10.2f millis, threshold %10.2f, ave %10.2f millis, count.%u\n",mp->name,OS_milliseconds() - mp->lastmilli,mp->threshold,mp->millisum/(mp->count > 0 ? mp->count: 1),mp->count); mp = &LP_privkeysloop_stats, printf("%32s lag %10.2f millis, threshold %10.2f, ave %10.2f millis, count.%u\n",mp->name,OS_milliseconds() - mp->lastmilli,mp->threshold,mp->millisum/(mp->count > 0 ? mp->count: 1),mp->count); mp = &LP_swapsloop_stats, printf("%32s lag %10.2f millis, threshold %10.2f, ave %10.2f millis, count.%u\n",mp->name,OS_milliseconds() - mp->lastmilli,mp->threshold,mp->millisum/(mp->count > 0 ? mp->count: 1),mp->count); + mp = &LP_gcloop_stats, printf("%32s lag %10.2f millis, threshold %10.2f, ave %10.2f millis, count.%u\n",mp->name,OS_milliseconds() - mp->lastmilli,mp->threshold,mp->millisum/(mp->count > 0 ? mp->count: 1),mp->count); } else { @@ -1112,6 +1113,11 @@ void LPinit(uint16_t myport,uint16_t mypullport,uint16_t mypubport,uint16_t mybu printf("error launching queue_loop for port.%u\n",myport); exit(-1); } + if ( OS_thread_create(malloc(sizeof(pthread_t)),NULL,(void *)gc_loop,(void *)myipaddr) != 0 ) + { + printf("error launching gc_loop for port.%u\n",myport); + exit(-1); + } if ( OS_thread_create(malloc(sizeof(pthread_t)),NULL,(void *)prices_loop,ctx) != 0 ) { printf("error launching prices_loop for port.%u\n",myport); diff --git a/iguana/exchanges/LP_network.c b/iguana/exchanges/LP_network.c index 797c31d04..1e207c2dc 100644 --- a/iguana/exchanges/LP_network.c +++ b/iguana/exchanges/LP_network.c @@ -265,23 +265,37 @@ int32_t LP_peerindsock(int32_t *peerindp) return(-1); } -void queue_loop(void *arg) +void gc_loop(void *arg) { - struct rpcrequest_info *req,*rtmp; struct LP_queue *ptr,*tmp; int32_t sentbytes,nonz,flag,duplicate,n=0; - strcpy(queue_loop_stats.name,"queue_loop"); - queue_loop_stats.threshold = 500.; + struct rpcrequest_info *req,*rtmp; int32_t flag = 0; + strcpy(queue_loop_stats.name,"gc_loop"); + queue_loop_stats.threshold = 50.; while ( 1 ) { - LP_millistats_update(&queue_loop_stats); + flag = 0; + LP_millistats_update(&LP_gcloop_stats); portable_mutex_lock(&LP_networkmutex); DL_FOREACH_SAFE(LP_garbage_collector,req,rtmp) { DL_DELETE(LP_garbage_collector,req); //printf("garbage collect ipbits.%x\n",req->ipbits); free(req); + flag++; } portable_mutex_unlock(&LP_networkmutex); + if ( flag == 0 ) + usleep(25000); + } +} +void queue_loop(void *arg) +{ + struct LP_queue *ptr,*tmp; int32_t sentbytes,nonz,flag,duplicate,n=0; + strcpy(queue_loop_stats.name,"queue_loop"); + queue_loop_stats.threshold = 500.; + while ( 1 ) + { + LP_millistats_update(&queue_loop_stats); 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; @@ -291,7 +305,7 @@ void queue_loop(void *arg) flag = 0; if ( ptr->sock >= 0 ) { - if ( LP_sockcheck(ptr->sock) > 0 ) + //if ( LP_sockcheck(ptr->sock) > 0 ) { bits256 magic; magic = LP_calc_magic(ptr->msg,(int32_t)(ptr->msglen - sizeof(bits256))); From eb1207676cbc8a09e096881f5495805e117bf44b Mon Sep 17 00:00:00 2001 From: jl777 Date: Mon, 6 Nov 2017 10:50:58 +0200 Subject: [PATCH 0254/1664] Test --- iguana/exchanges/LP_network.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/iguana/exchanges/LP_network.c b/iguana/exchanges/LP_network.c index 1e207c2dc..fa803467d 100644 --- a/iguana/exchanges/LP_network.c +++ b/iguana/exchanges/LP_network.c @@ -269,7 +269,7 @@ void gc_loop(void *arg) { struct rpcrequest_info *req,*rtmp; int32_t flag = 0; strcpy(queue_loop_stats.name,"gc_loop"); - queue_loop_stats.threshold = 50.; + queue_loop_stats.threshold = 27.; while ( 1 ) { flag = 0; From 84475181967899fd98a6826d0c55decd6fadfd7d Mon Sep 17 00:00:00 2001 From: jl777 Date: Mon, 6 Nov 2017 10:51:27 +0200 Subject: [PATCH 0255/1664] Test --- iguana/exchanges/LP_network.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/iguana/exchanges/LP_network.c b/iguana/exchanges/LP_network.c index fa803467d..9d8bbb46d 100644 --- a/iguana/exchanges/LP_network.c +++ b/iguana/exchanges/LP_network.c @@ -269,7 +269,7 @@ void gc_loop(void *arg) { struct rpcrequest_info *req,*rtmp; int32_t flag = 0; strcpy(queue_loop_stats.name,"gc_loop"); - queue_loop_stats.threshold = 27.; + queue_loop_stats.threshold = 26.; while ( 1 ) { flag = 0; @@ -292,7 +292,7 @@ void queue_loop(void *arg) { struct LP_queue *ptr,*tmp; int32_t sentbytes,nonz,flag,duplicate,n=0; strcpy(queue_loop_stats.name,"queue_loop"); - queue_loop_stats.threshold = 500.; + queue_loop_stats.threshold = 50.; while ( 1 ) { LP_millistats_update(&queue_loop_stats); From e73be6059706d121d7ca89c5a486ec5447915cee Mon Sep 17 00:00:00 2001 From: jl777 Date: Mon, 6 Nov 2017 10:52:58 +0200 Subject: [PATCH 0256/1664] Test --- iguana/exchanges/LP_network.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/iguana/exchanges/LP_network.c b/iguana/exchanges/LP_network.c index 9d8bbb46d..a2d4ae860 100644 --- a/iguana/exchanges/LP_network.c +++ b/iguana/exchanges/LP_network.c @@ -305,7 +305,7 @@ void queue_loop(void *arg) flag = 0; if ( ptr->sock >= 0 ) { - //if ( LP_sockcheck(ptr->sock) > 0 ) + if ( LP_sockcheck(ptr->sock) > 0 ) { bits256 magic; magic = LP_calc_magic(ptr->msg,(int32_t)(ptr->msglen - sizeof(bits256))); From 2e036b4873247db8128c9b99ef36c9204ac819fe Mon Sep 17 00:00:00 2001 From: jl777 Date: Mon, 6 Nov 2017 10:58:12 +0200 Subject: [PATCH 0257/1664] Test --- iguana/exchanges/LP_network.c | 15 +++++++-------- 1 file changed, 7 insertions(+), 8 deletions(-) diff --git a/iguana/exchanges/LP_network.c b/iguana/exchanges/LP_network.c index a2d4ae860..bccc03ce0 100644 --- a/iguana/exchanges/LP_network.c +++ b/iguana/exchanges/LP_network.c @@ -269,7 +269,7 @@ void gc_loop(void *arg) { struct rpcrequest_info *req,*rtmp; int32_t flag = 0; strcpy(queue_loop_stats.name,"gc_loop"); - queue_loop_stats.threshold = 26.; + queue_loop_stats.threshold = 6.; while ( 1 ) { flag = 0; @@ -284,7 +284,8 @@ void gc_loop(void *arg) } portable_mutex_unlock(&LP_networkmutex); if ( flag == 0 ) - usleep(25000); + usleep(5000); + else printf("gc_loop.%d\n",flag); } } @@ -292,15 +293,15 @@ void queue_loop(void *arg) { struct LP_queue *ptr,*tmp; int32_t sentbytes,nonz,flag,duplicate,n=0; strcpy(queue_loop_stats.name,"queue_loop"); - queue_loop_stats.threshold = 50.; + queue_loop_stats.threshold = 11.; while ( 1 ) { LP_millistats_update(&queue_loop_stats); - 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; + n = nonz = 0; DL_FOREACH_SAFE(LP_Q,ptr,tmp) { + nonz = 0; n++; flag = 0; if ( ptr->sock >= 0 ) @@ -348,6 +349,7 @@ void queue_loop(void *arg) portable_mutex_unlock(&LP_networkmutex); free(ptr); ptr = 0; + break; } } if ( arg == 0 ) @@ -355,10 +357,7 @@ void queue_loop(void *arg) //if ( n != 0 ) // printf("LP_Q.[%d]\n",n); if ( nonz == 0 ) - usleep(25000); - else if ( IAMLP == 0 ) usleep(10000); - else usleep(1000); } } From 8dadab25e5dcb4ae2e49532f418e71135da6c869 Mon Sep 17 00:00:00 2001 From: jl777 Date: Mon, 6 Nov 2017 11:00:13 +0200 Subject: [PATCH 0258/1664] Test --- iguana/exchanges/LP_network.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/iguana/exchanges/LP_network.c b/iguana/exchanges/LP_network.c index bccc03ce0..6aee50faf 100644 --- a/iguana/exchanges/LP_network.c +++ b/iguana/exchanges/LP_network.c @@ -269,7 +269,7 @@ void gc_loop(void *arg) { struct rpcrequest_info *req,*rtmp; int32_t flag = 0; strcpy(queue_loop_stats.name,"gc_loop"); - queue_loop_stats.threshold = 6.; + queue_loop_stats.threshold = 12.; while ( 1 ) { flag = 0; From a1316241883868afbad3e19b618561124622bd40 Mon Sep 17 00:00:00 2001 From: jl777 Date: Mon, 6 Nov 2017 11:19:01 +0200 Subject: [PATCH 0259/1664] Test --- iguana/exchanges/LP_nativeDEX.c | 3 ++- iguana/exchanges/LP_network.c | 15 +++++++-------- iguana/exchanges/stats.c | 12 +++++------- 3 files changed, 14 insertions(+), 16 deletions(-) diff --git a/iguana/exchanges/LP_nativeDEX.c b/iguana/exchanges/LP_nativeDEX.c index 9a6809a04..24f1cf450 100644 --- a/iguana/exchanges/LP_nativeDEX.c +++ b/iguana/exchanges/LP_nativeDEX.c @@ -75,7 +75,7 @@ void LP_millistats_update(struct LP_millistats *mp) } #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,LP_reservedmutex,LP_nanorecvsmutex,LP_tradebotsmutex; +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,LP_tradebotsmutex,LP_gcmutex; int32_t LP_canbind; char *Broadcaststr,*Reserved_msgs[2][1000]; int32_t num_Reserved_msgs[2],max_Reserved_msgs[2]; @@ -995,6 +995,7 @@ void LPinit(uint16_t myport,uint16_t mypullport,uint16_t mypubport,uint16_t mybu portable_mutex_init(&LP_swaplistmutex); portable_mutex_init(&LP_cachemutex); portable_mutex_init(&LP_networkmutex); + portable_mutex_init(&LP_gcmutex); portable_mutex_init(&LP_forwardmutex); portable_mutex_init(&LP_psockmutex); portable_mutex_init(&LP_coinmutex); diff --git a/iguana/exchanges/LP_network.c b/iguana/exchanges/LP_network.c index 6aee50faf..596f7ba75 100644 --- a/iguana/exchanges/LP_network.c +++ b/iguana/exchanges/LP_network.c @@ -274,7 +274,7 @@ void gc_loop(void *arg) { flag = 0; LP_millistats_update(&LP_gcloop_stats); - portable_mutex_lock(&LP_networkmutex); + portable_mutex_lock(&LP_gcmutex); DL_FOREACH_SAFE(LP_garbage_collector,req,rtmp) { DL_DELETE(LP_garbage_collector,req); @@ -282,10 +282,10 @@ void gc_loop(void *arg) free(req); flag++; } - portable_mutex_unlock(&LP_networkmutex); + portable_mutex_unlock(&LP_gcmutex); if ( flag == 0 ) usleep(5000); - else printf("gc_loop.%d\n",flag); + //else printf("gc_loop.%d\n",flag); } } @@ -301,7 +301,6 @@ void queue_loop(void *arg) n = nonz = 0; DL_FOREACH_SAFE(LP_Q,ptr,tmp) { - nonz = 0; n++; flag = 0; if ( ptr->sock >= 0 ) @@ -313,10 +312,10 @@ void queue_loop(void *arg) memcpy(&ptr->msg[ptr->msglen - sizeof(bits256)],&magic,sizeof(magic)); if ( (sentbytes= nn_send(ptr->sock,ptr->msg,ptr->msglen,0)) != ptr->msglen ) printf("%d LP_send sent %d instead of %d\n",n,sentbytes,ptr->msglen); + else flag++; ptr->sock = -1; if ( ptr->peerind > 0 ) ptr->starttime = (uint32_t)time(NULL); - else flag = 1; } //else printf("sock not ready to send.%d\n",ptr->msglen); } else if ( 0 && time(NULL) > ptr->starttime+13 ) @@ -327,7 +326,7 @@ void queue_loop(void *arg) LP_Qfound++; 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; + flag++; } else if ( 0 ) // too much beyond duplicate filter when network is busy { @@ -336,7 +335,7 @@ void queue_loop(void *arg) if ( (ptr->sock= LP_peerindsock(&ptr->peerind)) < 0 ) { printf("%d no more peers to try at peerind.%d %p Q_LP.%p\n",n,ptr->peerind,ptr,LP_Q); - flag = 1; + flag++; LP_Qerrors++; } } @@ -349,7 +348,6 @@ void queue_loop(void *arg) portable_mutex_unlock(&LP_networkmutex); free(ptr); ptr = 0; - break; } } if ( arg == 0 ) @@ -358,6 +356,7 @@ void queue_loop(void *arg) // printf("LP_Q.[%d]\n",n); if ( nonz == 0 ) usleep(10000); + else printf("queue_loop nonz.%d flag.%d n.%d\n",nonz,flag,n); } } diff --git a/iguana/exchanges/stats.c b/iguana/exchanges/stats.c index 37514e596..2cc747ae0 100644 --- a/iguana/exchanges/stats.c +++ b/iguana/exchanges/stats.c @@ -589,7 +589,7 @@ int32_t iguana_getheadersize(char *buf,int32_t recvlen) } uint16_t RPC_port; -extern portable_mutex_t LP_commandmutex,LP_networkmutex; +extern portable_mutex_t LP_commandmutex,LP_gcmutex; extern struct rpcrequest_info *LP_garbage_collector; void LP_rpc_processreq(void *_ptr) @@ -608,9 +608,7 @@ void LP_rpc_processreq(void *_ptr) jsonbuf = calloc(1,size); remains = size-1; buf = jsonbuf; - portable_mutex_lock(&LP_networkmutex); spawned++; - portable_mutex_unlock(&LP_networkmutex); if ( spawned > maxspawned ) { printf("max rpc threads spawned and alive %d <- %d\n",maxspawned,spawned); @@ -735,10 +733,10 @@ void LP_rpc_processreq(void *_ptr) free(space); free(jsonbuf); closesocket(sock); - portable_mutex_lock(&LP_networkmutex); + portable_mutex_lock(&LP_gcmutex); DL_APPEND(LP_garbage_collector,req); spawned--; - portable_mutex_unlock(&LP_networkmutex); + portable_mutex_unlock(&LP_gcmutex); } extern int32_t IAMLP; @@ -779,13 +777,13 @@ continue; printf("error launching rpc handler on port %d, retval.%d\n",port,retval); close(bindsock); bindsock = -1; - portable_mutex_lock(&LP_networkmutex); + portable_mutex_lock(&LP_gcmutex); DL_FOREACH_SAFE(LP_garbage_collector,req2,rtmp) { DL_DELETE(LP_garbage_collector,req2); free(req2); } - portable_mutex_unlock(&LP_networkmutex); + portable_mutex_unlock(&LP_gcmutex); if ( (retval= OS_thread_create(&req->T,NULL,(void *)LP_rpc_processreq,req)) != 0 ) { printf("error2 launching rpc handler on port %d, retval.%d\n",port,retval); From 1b363373b7ee389e66597747ed0073f22162886a Mon Sep 17 00:00:00 2001 From: jl777 Date: Mon, 6 Nov 2017 11:25:24 +0200 Subject: [PATCH 0260/1664] Test --- iguana/exchanges/LP_nativeDEX.c | 2 +- iguana/exchanges/LP_network.c | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/iguana/exchanges/LP_nativeDEX.c b/iguana/exchanges/LP_nativeDEX.c index 24f1cf450..395ba7ffc 100644 --- a/iguana/exchanges/LP_nativeDEX.c +++ b/iguana/exchanges/LP_nativeDEX.c @@ -66,7 +66,7 @@ void LP_millistats_update(struct LP_millistats *mp) mp->millisum += elapsed; if ( mp->threshold != 0. && elapsed > mp->threshold ) { - if ( IAMLP == 0 ) + //if ( IAMLP == 0 ) printf("%32s elapsed %10.2f millis > threshold %10.2f, ave %10.2f millis, count.%u\n",mp->name,elapsed,mp->threshold,mp->millisum/mp->count,mp->count); } mp->lastmilli = millis; diff --git a/iguana/exchanges/LP_network.c b/iguana/exchanges/LP_network.c index 596f7ba75..5284bac2c 100644 --- a/iguana/exchanges/LP_network.c +++ b/iguana/exchanges/LP_network.c @@ -298,7 +298,7 @@ void queue_loop(void *arg) { LP_millistats_update(&queue_loop_stats); //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 = nonz = 0; + n = nonz = flag = 0; DL_FOREACH_SAFE(LP_Q,ptr,tmp) { n++; @@ -356,7 +356,7 @@ void queue_loop(void *arg) // printf("LP_Q.[%d]\n",n); if ( nonz == 0 ) usleep(10000); - else printf("queue_loop nonz.%d flag.%d n.%d\n",nonz,flag,n); + else printf("queue_loop nonz.%d n.%d\n",nonz,n); } } From 5219d88727a03efe0a5b317bdfc191a449994783 Mon Sep 17 00:00:00 2001 From: jl777 Date: Mon, 6 Nov 2017 11:28:05 +0200 Subject: [PATCH 0261/1664] Test --- iguana/exchanges/LP_network.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/iguana/exchanges/LP_network.c b/iguana/exchanges/LP_network.c index 5284bac2c..eb3c0d7ea 100644 --- a/iguana/exchanges/LP_network.c +++ b/iguana/exchanges/LP_network.c @@ -275,7 +275,7 @@ void gc_loop(void *arg) flag = 0; LP_millistats_update(&LP_gcloop_stats); portable_mutex_lock(&LP_gcmutex); - DL_FOREACH_SAFE(LP_garbage_collector,req,rtmp) + DL_FOREACH(LP_garbage_collector,req) { DL_DELETE(LP_garbage_collector,req); //printf("garbage collect ipbits.%x\n",req->ipbits); @@ -285,7 +285,7 @@ void gc_loop(void *arg) portable_mutex_unlock(&LP_gcmutex); if ( flag == 0 ) usleep(5000); - //else printf("gc_loop.%d\n",flag); + else printf("gc_loop.%d\n",flag); } } From 7aabcd1ae94ded0872462ddbcc841ec2ffc8efa3 Mon Sep 17 00:00:00 2001 From: jl777 Date: Mon, 6 Nov 2017 11:30:47 +0200 Subject: [PATCH 0262/1664] test --- iguana/exchanges/LP_network.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/iguana/exchanges/LP_network.c b/iguana/exchanges/LP_network.c index eb3c0d7ea..eef7658b7 100644 --- a/iguana/exchanges/LP_network.c +++ b/iguana/exchanges/LP_network.c @@ -275,7 +275,7 @@ void gc_loop(void *arg) flag = 0; LP_millistats_update(&LP_gcloop_stats); portable_mutex_lock(&LP_gcmutex); - DL_FOREACH(LP_garbage_collector,req) + DL_FOREACH_SAFE(LP_garbage_collector,req,rtmp) { DL_DELETE(LP_garbage_collector,req); //printf("garbage collect ipbits.%x\n",req->ipbits); From 3d49071cb011a88f5abdae1cdbad0f0e04e0f653 Mon Sep 17 00:00:00 2001 From: jl777 Date: Mon, 6 Nov 2017 11:33:10 +0200 Subject: [PATCH 0263/1664] Test --- iguana/exchanges/LP_network.c | 4 ++-- iguana/exchanges/stats.c | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/iguana/exchanges/LP_network.c b/iguana/exchanges/LP_network.c index eef7658b7..38f03ede7 100644 --- a/iguana/exchanges/LP_network.c +++ b/iguana/exchanges/LP_network.c @@ -274,7 +274,7 @@ void gc_loop(void *arg) { flag = 0; LP_millistats_update(&LP_gcloop_stats); - portable_mutex_lock(&LP_gcmutex); + //portable_mutex_lock(&LP_gcmutex); DL_FOREACH_SAFE(LP_garbage_collector,req,rtmp) { DL_DELETE(LP_garbage_collector,req); @@ -282,7 +282,7 @@ void gc_loop(void *arg) free(req); flag++; } - portable_mutex_unlock(&LP_gcmutex); + //portable_mutex_unlock(&LP_gcmutex); if ( flag == 0 ) usleep(5000); else printf("gc_loop.%d\n",flag); diff --git a/iguana/exchanges/stats.c b/iguana/exchanges/stats.c index 2cc747ae0..b4d680e03 100644 --- a/iguana/exchanges/stats.c +++ b/iguana/exchanges/stats.c @@ -733,10 +733,10 @@ void LP_rpc_processreq(void *_ptr) free(space); free(jsonbuf); closesocket(sock); - portable_mutex_lock(&LP_gcmutex); + //portable_mutex_lock(&LP_gcmutex); DL_APPEND(LP_garbage_collector,req); spawned--; - portable_mutex_unlock(&LP_gcmutex); + //portable_mutex_unlock(&LP_gcmutex); } extern int32_t IAMLP; From 9452e4c9891ae01c18e2e9627278057177c85a64 Mon Sep 17 00:00:00 2001 From: jl777 Date: Mon, 6 Nov 2017 11:35:20 +0200 Subject: [PATCH 0264/1664] Test --- iguana/exchanges/LP_network.c | 8 ++++---- iguana/exchanges/stats.c | 4 ++-- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/iguana/exchanges/LP_network.c b/iguana/exchanges/LP_network.c index 38f03ede7..e869759b2 100644 --- a/iguana/exchanges/LP_network.c +++ b/iguana/exchanges/LP_network.c @@ -269,12 +269,12 @@ void gc_loop(void *arg) { struct rpcrequest_info *req,*rtmp; int32_t flag = 0; strcpy(queue_loop_stats.name,"gc_loop"); - queue_loop_stats.threshold = 12.; + queue_loop_stats.threshold = 1001.; while ( 1 ) { flag = 0; LP_millistats_update(&LP_gcloop_stats); - //portable_mutex_lock(&LP_gcmutex); + portable_mutex_lock(&LP_gcmutex); DL_FOREACH_SAFE(LP_garbage_collector,req,rtmp) { DL_DELETE(LP_garbage_collector,req); @@ -282,9 +282,9 @@ void gc_loop(void *arg) free(req); flag++; } - //portable_mutex_unlock(&LP_gcmutex); + portable_mutex_unlock(&LP_gcmutex); if ( flag == 0 ) - usleep(5000); + sleep(1); else printf("gc_loop.%d\n",flag); } } diff --git a/iguana/exchanges/stats.c b/iguana/exchanges/stats.c index b4d680e03..2cc747ae0 100644 --- a/iguana/exchanges/stats.c +++ b/iguana/exchanges/stats.c @@ -733,10 +733,10 @@ void LP_rpc_processreq(void *_ptr) free(space); free(jsonbuf); closesocket(sock); - //portable_mutex_lock(&LP_gcmutex); + portable_mutex_lock(&LP_gcmutex); DL_APPEND(LP_garbage_collector,req); spawned--; - //portable_mutex_unlock(&LP_gcmutex); + portable_mutex_unlock(&LP_gcmutex); } extern int32_t IAMLP; From f8651e0e312105f785be05e115a45c012640a4b4 Mon Sep 17 00:00:00 2001 From: jl777 Date: Mon, 6 Nov 2017 11:37:32 +0200 Subject: [PATCH 0265/1664] Test --- iguana/exchanges/LP_network.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/iguana/exchanges/LP_network.c b/iguana/exchanges/LP_network.c index e869759b2..64f1905bc 100644 --- a/iguana/exchanges/LP_network.c +++ b/iguana/exchanges/LP_network.c @@ -283,9 +283,9 @@ void gc_loop(void *arg) flag++; } portable_mutex_unlock(&LP_gcmutex); - if ( flag == 0 ) - sleep(1); - else printf("gc_loop.%d\n",flag); + if ( flag != 0 ) + printf("gc_loop.%d\n",flag); + sleep(1); } } From be8d3eae2d1bdd51b4bc9f1a48ffc5a6a5dc9a54 Mon Sep 17 00:00:00 2001 From: jl777 Date: Mon, 6 Nov 2017 11:40:08 +0200 Subject: [PATCH 0266/1664] Test --- iguana/exchanges/LP_network.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/iguana/exchanges/LP_network.c b/iguana/exchanges/LP_network.c index 64f1905bc..8896a8c70 100644 --- a/iguana/exchanges/LP_network.c +++ b/iguana/exchanges/LP_network.c @@ -293,7 +293,7 @@ void queue_loop(void *arg) { struct LP_queue *ptr,*tmp; int32_t sentbytes,nonz,flag,duplicate,n=0; strcpy(queue_loop_stats.name,"queue_loop"); - queue_loop_stats.threshold = 11.; + queue_loop_stats.threshold = 51.; while ( 1 ) { LP_millistats_update(&queue_loop_stats); @@ -354,9 +354,9 @@ void queue_loop(void *arg) break; //if ( n != 0 ) // printf("LP_Q.[%d]\n",n); - if ( nonz == 0 ) - usleep(10000); - else printf("queue_loop nonz.%d n.%d\n",nonz,n); + if ( n != 0 ) + printf("queue_loop nonz.%d n.%d\n",nonz,n); + usleep(50000); } } From f8253540feca225b96c08a6db6f65c35be51307c Mon Sep 17 00:00:00 2001 From: jl777 Date: Mon, 6 Nov 2017 11:45:34 +0200 Subject: [PATCH 0267/1664] Test --- iguana/exchanges/LP_network.c | 38 ++++++++++++++++++++--------------- 1 file changed, 22 insertions(+), 16 deletions(-) diff --git a/iguana/exchanges/LP_network.c b/iguana/exchanges/LP_network.c index 8896a8c70..d314b3d85 100644 --- a/iguana/exchanges/LP_network.c +++ b/iguana/exchanges/LP_network.c @@ -140,7 +140,7 @@ struct LP_queue { struct LP_queue *next,*prev; int32_t sock,peerind,msglen; - uint32_t starttime,crc32; + uint32_t starttime,crc32,notready; uint8_t msg[]; } *LP_Q; int32_t LP_Qenqueued,LP_Qerrors,LP_Qfound; @@ -305,18 +305,26 @@ void queue_loop(void *arg) flag = 0; if ( ptr->sock >= 0 ) { - if ( LP_sockcheck(ptr->sock) > 0 ) + if ( ptr->notready == 0 || (rand() % ptr->notready) == 0 ) { - bits256 magic; - magic = LP_calc_magic(ptr->msg,(int32_t)(ptr->msglen - sizeof(bits256))); - memcpy(&ptr->msg[ptr->msglen - sizeof(bits256)],&magic,sizeof(magic)); - if ( (sentbytes= nn_send(ptr->sock,ptr->msg,ptr->msglen,0)) != ptr->msglen ) - printf("%d LP_send sent %d instead of %d\n",n,sentbytes,ptr->msglen); - else flag++; - ptr->sock = -1; - if ( ptr->peerind > 0 ) - ptr->starttime = (uint32_t)time(NULL); - } //else printf("sock not ready to send.%d\n",ptr->msglen); + if ( LP_sockcheck(ptr->sock) > 0 ) + { + bits256 magic; + magic = LP_calc_magic(ptr->msg,(int32_t)(ptr->msglen - sizeof(bits256))); + memcpy(&ptr->msg[ptr->msglen - sizeof(bits256)],&magic,sizeof(magic)); + if ( (sentbytes= nn_send(ptr->sock,ptr->msg,ptr->msglen,0)) != ptr->msglen ) + printf("%d LP_send sent %d instead of %d\n",n,sentbytes,ptr->msglen); + else flag++; + ptr->sock = -1; + if ( ptr->peerind > 0 ) + ptr->starttime = (uint32_t)time(NULL); + } + else + { + if ( ptr->notready++ > 1000 ) + flag = 1; + } + } } else if ( 0 && time(NULL) > ptr->starttime+13 ) { @@ -352,11 +360,9 @@ void queue_loop(void *arg) } if ( arg == 0 ) break; - //if ( n != 0 ) - // printf("LP_Q.[%d]\n",n); - if ( n != 0 ) + if ( n+nonz != 0 ) printf("queue_loop nonz.%d n.%d\n",nonz,n); - usleep(50000); + else usleep(50000); } } From 97ba511f73c943ba887bbae13128468a95fbc30f Mon Sep 17 00:00:00 2001 From: jl777 Date: Mon, 6 Nov 2017 11:48:25 +0200 Subject: [PATCH 0268/1664] Test --- iguana/exchanges/LP_network.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/iguana/exchanges/LP_network.c b/iguana/exchanges/LP_network.c index d314b3d85..12b626bb7 100644 --- a/iguana/exchanges/LP_network.c +++ b/iguana/exchanges/LP_network.c @@ -360,7 +360,7 @@ void queue_loop(void *arg) } if ( arg == 0 ) break; - if ( n+nonz != 0 ) + if ( nonz != 0 ) printf("queue_loop nonz.%d n.%d\n",nonz,n); else usleep(50000); } From 17a822dc9f646ce53d20bdba7918c67e2a0b9079 Mon Sep 17 00:00:00 2001 From: jl777 Date: Mon, 6 Nov 2017 11:50:59 +0200 Subject: [PATCH 0269/1664] Test --- iguana/exchanges/LP_network.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/iguana/exchanges/LP_network.c b/iguana/exchanges/LP_network.c index 12b626bb7..bf212278b 100644 --- a/iguana/exchanges/LP_network.c +++ b/iguana/exchanges/LP_network.c @@ -268,8 +268,8 @@ int32_t LP_peerindsock(int32_t *peerindp) void gc_loop(void *arg) { struct rpcrequest_info *req,*rtmp; int32_t flag = 0; - strcpy(queue_loop_stats.name,"gc_loop"); - queue_loop_stats.threshold = 1001.; + strcpy(LP_gcloop_stats.name,"gc_loop"); + LP_gcloop_stats.threshold = 1001.; while ( 1 ) { flag = 0; From 957d87387953c4a9ada808303d345bf20bff3114 Mon Sep 17 00:00:00 2001 From: jl777 Date: Mon, 6 Nov 2017 11:54:36 +0200 Subject: [PATCH 0270/1664] Test --- iguana/exchanges/LP_network.c | 13 ++++++++----- 1 file changed, 8 insertions(+), 5 deletions(-) diff --git a/iguana/exchanges/LP_network.c b/iguana/exchanges/LP_network.c index bf212278b..9bf43463c 100644 --- a/iguana/exchanges/LP_network.c +++ b/iguana/exchanges/LP_network.c @@ -283,7 +283,7 @@ void gc_loop(void *arg) flag++; } portable_mutex_unlock(&LP_gcmutex); - if ( flag != 0 ) + if ( 0 && flag != 0 ) printf("gc_loop.%d\n",flag); sleep(1); } @@ -293,7 +293,7 @@ void queue_loop(void *arg) { struct LP_queue *ptr,*tmp; int32_t sentbytes,nonz,flag,duplicate,n=0; strcpy(queue_loop_stats.name,"queue_loop"); - queue_loop_stats.threshold = 51.; + queue_loop_stats.threshold = 100.; while ( 1 ) { LP_millistats_update(&queue_loop_stats); @@ -360,9 +360,12 @@ void queue_loop(void *arg) } if ( arg == 0 ) break; - if ( nonz != 0 ) - printf("queue_loop nonz.%d n.%d\n",nonz,n); - else usleep(50000); + if ( nonz == 0 ) + { + if ( IAMLP == 0 ) + usleep(50000); + else usleep(10000); + } } } From 4c2897ea4ea2cac6d35cee2de033e5b848571b6e Mon Sep 17 00:00:00 2001 From: jl777 Date: Mon, 6 Nov 2017 12:08:38 +0200 Subject: [PATCH 0271/1664] Test --- iguana/exchanges/LP_network.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/iguana/exchanges/LP_network.c b/iguana/exchanges/LP_network.c index 9bf43463c..9a52b86d4 100644 --- a/iguana/exchanges/LP_network.c +++ b/iguana/exchanges/LP_network.c @@ -269,7 +269,7 @@ void gc_loop(void *arg) { struct rpcrequest_info *req,*rtmp; int32_t flag = 0; strcpy(LP_gcloop_stats.name,"gc_loop"); - LP_gcloop_stats.threshold = 1001.; + LP_gcloop_stats.threshold = 1100.; while ( 1 ) { flag = 0; From e5052cf17b64df02161af4ef7e845fcfa84deed4 Mon Sep 17 00:00:00 2001 From: jl777 Date: Mon, 6 Nov 2017 12:18:17 +0200 Subject: [PATCH 0272/1664] Test --- iguana/exchanges/LP_nativeDEX.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/iguana/exchanges/LP_nativeDEX.c b/iguana/exchanges/LP_nativeDEX.c index 395ba7ffc..fd41a9857 100644 --- a/iguana/exchanges/LP_nativeDEX.c +++ b/iguana/exchanges/LP_nativeDEX.c @@ -453,7 +453,7 @@ void utxosQ_loop(void *myipaddr) { LP_millistats_update(&utxosQ_loop_stats); if ( LP_utxosQ_process() == 0 ) - usleep(10000); + usleep(50000); } } From abbd42ced7dae88e0b98171715e390d14955fa5e Mon Sep 17 00:00:00 2001 From: jl777 Date: Mon, 6 Nov 2017 14:20:32 +0200 Subject: [PATCH 0273/1664] Test --- iguana/exchanges/install | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/iguana/exchanges/install b/iguana/exchanges/install index 342089ce3..e67ab5bc0 100755 --- a/iguana/exchanges/install +++ b/iguana/exchanges/install @@ -1,5 +1,5 @@ #!/bin/bash -cp processlist stop millis mnzservers bot_buy bot_list bot_statuslist bot_pause bot_resume bot_sell bot_settings bot_status bot_stop guistats pubkeystats pendings coinswaps baserelswaps setpassphrase notarizations getrawtransaction parselog statsdisp m_js 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 processfiles stop millis mnzservers bot_buy bot_list bot_statuslist bot_pause bot_resume bot_sell bot_settings bot_status bot_stop guistats pubkeystats pendings coinswaps baserelswaps setpassphrase notarizations getrawtransaction parselog statsdisp m_js 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 . From 9db4d96d0858f2c27b31a6cceaacc2ba1d99e845 Mon Sep 17 00:00:00 2001 From: jl777 Date: Mon, 6 Nov 2017 16:59:34 +0200 Subject: [PATCH 0274/1664] Null symbol crash fixed --- iguana/exchanges/LP_coins.c | 62 ++++++++++++++++++++-------------- iguana/exchanges/LP_commands.c | 9 +++-- 2 files changed, 43 insertions(+), 28 deletions(-) diff --git a/iguana/exchanges/LP_coins.c b/iguana/exchanges/LP_coins.c index c2771e308..fe9c20f34 100644 --- a/iguana/exchanges/LP_coins.c +++ b/iguana/exchanges/LP_coins.c @@ -23,9 +23,12 @@ char *portstrs[][3] = { { "BTC", "8332" }, { "KMD", "7771" } }; uint16_t LP_rpcport(char *symbol) { int32_t i; - for (i=0; iinactive != 0 || coin->electrum != 0 || coin == refcoin ) - continue; - if ( strcmp(coin->serverport,refcoin->serverport) == 0 ) - break; + HASH_ITER(hh,LP_coins,coin,tmp) + { + if ( coin->inactive != 0 || coin->electrum != 0 || coin == refcoin ) + continue; + if ( strcmp(coin->serverport,refcoin->serverport) == 0 ) + break; + } } return(coin); } @@ -254,31 +260,37 @@ cJSON *LP_coinsjson(int32_t showwif) char *LP_getcoin(char *symbol) { int32_t numenabled,numdisabled; struct iguana_info *coin,*tmp; cJSON *item=0,*retjson; - numenabled = numdisabled = 0; retjson = cJSON_CreateObject(); - HASH_ITER(hh,LP_coins,coin,tmp) + if ( symbol != 0 && symbol[0] != 0 ) { - if ( strcmp(symbol,coin->symbol) == 0 ) - item = LP_coinjson(coin,0); - if ( coin->inactive == 0 ) - numenabled++; - else numdisabled++; + numenabled = numdisabled = 0; + HASH_ITER(hh,LP_coins,coin,tmp) + { + if ( strcmp(symbol,coin->symbol) == 0 ) + item = LP_coinjson(coin,0); + if ( coin->inactive == 0 ) + numenabled++; + else numdisabled++; + } + jaddstr(retjson,"result","success"); + jaddnum(retjson,"enabled",numenabled); + jaddnum(retjson,"disabled",numdisabled); + if ( item == 0 ) + item = cJSON_CreateObject(); + jadd(retjson,"coin",item); } - jaddstr(retjson,"result","success"); - jaddnum(retjson,"enabled",numenabled); - jaddnum(retjson,"disabled",numdisabled); - if ( item == 0 ) - item = cJSON_CreateObject(); - jadd(retjson,"coin",item); return(jprint(retjson,1)); } struct iguana_info *LP_coinsearch(char *symbol) { - struct iguana_info *coin; - portable_mutex_lock(&LP_coinmutex); - HASH_FIND(hh,LP_coins,symbol,strlen(symbol),coin); - portable_mutex_unlock(&LP_coinmutex); + struct iguana_info *coin = 0; + if ( symbol != 0 && symbol[0] != 0 ) + { + portable_mutex_lock(&LP_coinmutex); + HASH_FIND(hh,LP_coins,symbol,strlen(symbol),coin); + portable_mutex_unlock(&LP_coinmutex); + } return(coin); } diff --git a/iguana/exchanges/LP_commands.c b/iguana/exchanges/LP_commands.c index 831f81ccb..740c156c6 100644 --- a/iguana/exchanges/LP_commands.c +++ b/iguana/exchanges/LP_commands.c @@ -153,9 +153,12 @@ bot_resume(botid)\n\ \"}")); //sell(base, rel, price, basevolume, timeout=10, duration=3600)\n\ - base = jstr(argjson,"base"); - rel = jstr(argjson,"rel"); - coin = jstr(argjson,"coin"); + if ( (base= jstr(argjson,"base")) == 0 ) + base = ""; + if ((rel= jstr(argjson,"rel")) == 0 ) + rel = ""; + if ( (coin= jstr(argjson,"coin")) == 0 ) + coin = ""; if ( G.USERPASS[0] != 0 && strcmp(remoteaddr,"127.0.0.1") == 0 && port != 0 ) // protected localhost { if ( G.USERPASS_COUNTER == 0 ) From 62d80ea648c0680651254715e81eb28531751ab5 Mon Sep 17 00:00:00 2001 From: jl777 Date: Mon, 6 Nov 2017 17:11:54 +0200 Subject: [PATCH 0275/1664] Fix --- iguana/exchanges/LP_commands.c | 10 +++++----- iguana/exchanges/LP_network.c | 2 +- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/iguana/exchanges/LP_commands.c b/iguana/exchanges/LP_commands.c index 740c156c6..4e86095b8 100644 --- a/iguana/exchanges/LP_commands.c +++ b/iguana/exchanges/LP_commands.c @@ -190,7 +190,7 @@ bot_resume(botid)\n\ { if ( jobj(argjson,"method2") == 0 ) { - LP_broadcast_message(LP_mypubsock,base!=0?base:jstr(argjson,"coin"),rel,jbits256(argjson,"pubkey"),jprint(argjson,0)); + LP_broadcast_message(LP_mypubsock,base!=0?base:coin,rel,jbits256(argjson,"pubkey"),jprint(argjson,0)); } return(clonestr("{\"result\":\"success\"}")); } @@ -328,7 +328,7 @@ bot_resume(botid)\n\ return(LP_bestfit(rel,relvolume)); else return(clonestr("{\"error\":\"no relvolume set\"}")); } - else if ( (coin= jstr(argjson,"coin")) != 0 ) + else if ( coin[0] != 0 ) { if ( strcmp(method,"enable") == 0 ) { @@ -506,7 +506,7 @@ bot_resume(botid)\n\ } else if ( strcmp(method,"balance") == 0 ) { - if ( (ptr= LP_coinsearch(jstr(argjson,"coin"))) != 0 ) + if ( (ptr= LP_coinsearch(coin)) != 0 ) return(jprint(LP_address_balance(ptr,jstr(argjson,"address"),1),1)); else return(clonestr("{\"error\":\"cant find coind\"}")); } @@ -543,7 +543,7 @@ bot_resume(botid)\n\ } else if ( strcmp(method,"listunspent") == 0 ) { - if ( (ptr= LP_coinsearch(jstr(argjson,"coin"))) != 0 ) + if ( (ptr= LP_coinsearch(coin)) != 0 ) { char *coinaddr; if ( (coinaddr= jstr(argjson,"address")) != 0 ) @@ -571,7 +571,7 @@ bot_resume(botid)\n\ else if ( strcmp(method,"addr_unspents") == 0 ) { //printf("GOT ADDR_UNSPENTS %s %s\n",jstr(argjson,"coin"),jstr(argjson,"address")); - if ( (ptr= LP_coinsearch(jstr(argjson,"coin"))) != 0 ) + if ( (ptr= LP_coinsearch(coin)) != 0 ) { char *coinaddr; if ( (coinaddr= jstr(argjson,"address")) != 0 ) diff --git a/iguana/exchanges/LP_network.c b/iguana/exchanges/LP_network.c index 9a52b86d4..0a6812890 100644 --- a/iguana/exchanges/LP_network.c +++ b/iguana/exchanges/LP_network.c @@ -293,7 +293,7 @@ void queue_loop(void *arg) { struct LP_queue *ptr,*tmp; int32_t sentbytes,nonz,flag,duplicate,n=0; strcpy(queue_loop_stats.name,"queue_loop"); - queue_loop_stats.threshold = 100.; + queue_loop_stats.threshold = 1000.; while ( 1 ) { LP_millistats_update(&queue_loop_stats); From d9e15e536aaec2439f54afee6ffdc167a8254b73 Mon Sep 17 00:00:00 2001 From: jl777 Date: Mon, 6 Nov 2017 17:15:06 +0200 Subject: [PATCH 0276/1664] Test --- iguana/exchanges/LP_commands.c | 10 +++++----- iguana/exchanges/mm.c | 2 +- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/iguana/exchanges/LP_commands.c b/iguana/exchanges/LP_commands.c index 4e86095b8..f7927ba8a 100644 --- a/iguana/exchanges/LP_commands.c +++ b/iguana/exchanges/LP_commands.c @@ -260,15 +260,15 @@ bot_resume(botid)\n\ uint32_t requestid,quoteid; if ( (requestid= juint(argjson,"requestid")) != 0 && (quoteid= juint(argjson,"quoteid")) != 0 ) return(basilisk_swapentry(requestid,quoteid)); - else if ( coin != 0 && coin[0] != 0 ) + else if ( coin[0] != 0 ) return(basilisk_swapentries(coin,0,jint(argjson,"limit"))); - else if ( base != 0 && base[0] != 0 && rel != 0 && rel[0] != 0 ) + else if ( base[0] != 0 && rel[0] != 0 ) return(basilisk_swapentries(base,rel,jint(argjson,"limit"))); else return(basilisk_swaplist(0,0)); } else if ( (retstr= LP_istradebots_command(ctx,pubsock,method,argjson)) != 0 ) return(retstr); - if ( base != 0 && rel != 0 ) + if ( base[0] != 0 && rel[0] != 0 ) { double price,bid,ask; if ( IAMLP == 0 && LP_isdisabled(base,rel) != 0 ) @@ -321,7 +321,7 @@ bot_resume(botid)\n\ } else return(clonestr("{\"error\":\"no price set\"}")); } } - else if ( rel != 0 && strcmp(method,"bestfit") == 0 ) + else if ( rel[0] != 0 && strcmp(method,"bestfit") == 0 ) { double relvolume; if ( (relvolume= jdouble(argjson,"relvolume")) > SMALLVAL ) @@ -513,7 +513,7 @@ bot_resume(botid)\n\ else if ( strcmp(method,"pricearray") == 0 ) { uint32_t firsttime; - if ( base != 0 && rel != 0 ) + if ( base[0] != 0 && rel[0] != 0 ) { if ( (firsttime= juint(argjson,"firsttime")) < time(NULL)-30*24*3600 ) firsttime = (uint32_t)(time(NULL)-30*24*3600); diff --git a/iguana/exchanges/mm.c b/iguana/exchanges/mm.c index b5cc4404e..7aafd9055 100644 --- a/iguana/exchanges/mm.c +++ b/iguana/exchanges/mm.c @@ -907,7 +907,7 @@ int main(int argc, const char * argv[]) } //else printf("(%s) launched.(%s)\n",argv[1],passphrase); incr = 100.; while ( (1) ) - sleep(1); + sleep(100000); profitmargin = jdouble(retjson,"profitmargin"); minask = jdouble(retjson,"minask"); maxbid = jdouble(retjson,"maxbid"); From fa4419fa0a8bc2d7a0df238355225888dbf3a228 Mon Sep 17 00:00:00 2001 From: jl777 Date: Mon, 6 Nov 2017 18:03:08 +0200 Subject: [PATCH 0277/1664] PURA --- iguana/exchanges/coins | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/iguana/exchanges/coins b/iguana/exchanges/coins index 60511920f..d81e18c4d 100644 --- a/iguana/exchanges/coins +++ b/iguana/exchanges/coins @@ -1,4 +1,4 @@ -export coins="[{\"coin\":\"DSR\",\"name\":\"desire\",\"confpath\":\"${HOME#}/.desirecore/desire.conf\",\"rpcport\":9918,\"pubtype\":30,\"p2shtype\":16,\"wiftype\":204,\"txfee\":10000}, {\"coin\":\"MNZ\",\"asset\":\"MNZ\",\"rpcport\":14337},{\"coin\":\"BTCZ\",\"name\":\"bitcoinz\",\"rpcport\":1979,\"taddr\":28,\"pubtype\":184,\"p2shtype\":189,\"wiftype\":128,\"txfee\":10000}, {\"coin\":\"MAGA\",\"name\":\"magacoin\",\"rpcport\":5332,\"pubtype\":23,\"p2shtype\":50,\"wiftype\":176,\"txfee\":100000}, {\"coin\":\"BSD\",\"name\":\"bitsend\",\"rpcport\":8800,\"pubtype\":102,\"p2shtype\":5,\"wiftype\":204,\"txfee\":10000}, {\"coin\":\"IOP\",\"name\":\"IoP\",\"rpcport\":8337,\"pubtype\":117,\"p2shtype\":174,\"wiftype\":49,\"txfee\":10000}, {\"coin\":\"BLOCK\",\"name\":\"blocknetdx\",\"rpcport\":41414,\"pubtype\":26,\"p2shtype\":28,\"wiftype\":154,\"txfee\":10000}, {\"coin\":\"CHIPS\", \"name\": \"chips\", \"rpcport\":57776,\"pubtype\":60, \"p2shtype\":85, \"wiftype\":188, \"txfee\":10000}, {\"coin\":\"888\",\"name\":\"octocoin\",\"rpcport\":22888,\"pubtype\":18,\"p2shtype\":5,\"wiftype\":176,\"txfee\":2000000}, {\"coin\":\"ARG\",\"name\":\"argentum\",\"rpcport\":13581,\"pubtype\":23,\"p2shtype\":5,\"wiftype\":151,\"txfee\":50000}, {\"coin\":\"GLT\",\"name\":\"globaltoken\",\"rpcport\":9320,\"pubtype\":38,\"p2shtype\":5,\"wiftype\":166,\"txfee\":10000}, {\"coin\":\"ZER\",\"name\":\"zero\",\"rpcport\":23801,\"taddr\":28,\"pubtype\":184,\"p2shtype\":189,\"wiftype\":128,\"txfee\":1000}, {\"coin\":\"HODLC\",\"name\":\"hodlcoin\",\"rpcport\":11989,\"pubtype\":40,\"p2shtype\":5,\"wiftype\":168,\"txfee\":5000}, {\"coin\":\"UIS\",\"name\":\"unitus\",\"rpcport\":50604,\"pubtype\":68,\"p2shtype\":10,\"wiftype\":132,\"txfee\":2000000}, {\"coin\":\"CRW\",\"name\":\"crown\",\"rpcport\":9341,\"pubtype\":0,\"p2shtype\":5,\"wiftype\":128,\"txfee\":10000}, {\"coin\":\"HUC\",\"name\":\"huntercoin\",\"rpcport\":8399,\"pubtype\":40,\"p2shtype\":13,\"wiftype\":168,\"txfee\":100000}, {\"coin\":\"PIVX\",\"name\":\"pivx\",\"rpcport\":51473,\"pubtype\":30,\"p2shtype\":13,\"wiftype\":212,\"txfee\":10000}, {\"coin\":\"BDL\",\"name\":\"bitdeal\",\"rpcport\":9332,\"pubtype\":38,\"p2shtype\":5,\"wiftype\":176,\"txfee\":100000}, {\"coin\":\"ARC\",\"name\":\"arcticcoin\",\"confpath\":\"${HOME#}/.arcticcore/arcticcoin.conf\",\"rpcport\":7208,\"pubtype\":23,\"p2shtype\":8,\"wiftype\":176,\"txfee\":10000}, {\"coin\":\"ZCL\",\"name\":\"zclassic\",\"rpcport\":8023,\"taddr\":28,\"pubtype\":184,\"p2shtype\":189,\"wiftype\":128,\"txfee\":1000}, {\"coin\":\"VIA\",\"name\":\"viacoin\",\"rpcport\":5222,\"pubtype\":71,\"p2shtype\":33,\"wiftype\":199,\"txfee\":100000}, {\"coin\":\"ERC\",\"name\":\"europecoin\",\"rpcport\":11989,\"pubtype\":33,\"p2shtype\":5,\"wiftype\":168,\"txfee\":10000},{\"coin\":\"FAIR\",\"name\":\"faircoin\",\"confpath\":\"${HOME#}/.faircoin2/faircoin.conf\",\"rpcport\":40405,\"pubtype\":95,\"p2shtype\":36,\"wiftype\":223,\"txfee\":1000000}, {\"coin\":\"FLO\",\"name\":\"florincoin\",\"rpcport\":7313,\"pubtype\":35,\"p2shtype\":8,\"wiftype\":176,\"txfee\":100000}, {\"coin\":\"SXC\",\"name\":\"sexcoin\",\"rpcport\":9561,\"pubtype\":62,\"p2shtype\":5,\"wiftype\":190,\"txfee\":100000}, {\"coin\":\"CREA\",\"name\":\"creativecoin\",\"rpcport\":17711,\"pubtype\":28,\"p2shtype\":5,\"wiftype\":176,\"txfee\":100000}, {\"coin\":\"TRC\",\"name\":\"terracoin\",\"confpath\":\"${HOME#}/.terracoincore/terracoin.conf\",\"rpcport\":13332,\"pubtype\":0,\"p2shtype\":5,\"wiftype\":128,\"txfee\":10000}, {\"coin\":\"BTA\",\"name\":\"bata\",\"rpcport\":5493,\"pubtype\":25,\"p2shtype\":5,\"wiftype\":188,\"txfee\":100000}, {\"coin\":\"SMC\",\"name\":\"smartcoin\",\"rpcport\":58583,\"pubtype\":63,\"p2shtype\":5,\"wiftype\":191,\"txfee\":1000000}, {\"coin\":\"NMC\",\"name\":\"namecoin\",\"rpcport\":8336,\"pubtype\":52,\"p2shtype\":13,\"wiftype\":180,\"txfee\":100000}, {\"coin\":\"NAV\",\"name\":\"navcoin\",\"isPoS\":1,\"confpath\":\"${HOME#}/.navcoin4/navcoin.conf\",\"rpcport\":44444,\"pubtype\":53,\"p2shtype\":85,\"wiftype\":150,\"txfee\":10000}, {\"coin\":\"MOON\",\"name\":\"Mooncoin\",\"rpcport\":44663,\"pubtype\":3,\"p2shtype\":22,\"wiftype\":131,\"txfee\":100000}, {\"coin\":\"EMC2\",\"name\":\"einsteinium\",\"rpcport\":41879,\"pubtype\":33,\"p2shtype\":5,\"wiftype\":176,\"txfee\":100000},{\"coin\":\"SYS\",\"name\":\"syscoin\",\"rpcport\":8370,\"pubtype\":0,\"p2shtype\":5,\"wiftype\":128,\"txfee\":1000}, {\"coin\":\"I0C\",\"name\":\"i0coin\",\"rpcport\":7332,\"pubtype\":105,\"p2shtype\":5,\"wiftype\":128,\"txfee\":1000}, {\"coin\":\"DASH\",\"confpath\":\"${HOME#}/.dashcore/dash.conf\",\"name\":\"dashcore\",\"rpcport\":9998,\"pubtype\":76,\"p2shtype\":16,\"wiftype\":204,\"txfee\":10000}, {\"coin\":\"STRAT\", \"name\": \"stratis\", \"active\":0, \"rpcport\":16174,\"pubtype\":63, \"p2shtype\":125, \"wiftype\":191, \"txfee\":10000}, {\"confpath\":\"${HOME#}/.muecore/mue.conf\",\"coin\":\"MUE\",\"name\":\"muecore\",\"rpcport\":29683,\"pubtype\":16,\"p2shtype\":76,\"wiftype\":126,\"txfee\":10000}, {\"coin\":\"MONA\",\"name\":\"monacoin\",\"rpcport\":9402,\"pubtype\":50,\"p2shtype\":5,\"wiftype\":176,\"txfee\":100000},{\"coin\":\"XMY\",\"name\":\"myriadcoin\",\"rpcport\":10889,\"pubtype\":50,\"p2shtype\":9,\"wiftype\":178,\"txfee\":5000}, {\"coin\":\"MAC\",\"name\":\"machinecoin\",\"rpcport\":40332,\"pubtype\":50,\"p2shtype\":5,\"wiftype\":178,\"txfee\":50000}, {\"coin\":\"BTX\",\"name\":\"bitcore\",\"rpcport\":8556,\"pubtype\":0,\"p2shtype\":5,\"wiftype\":128,\"txfee\":50000}, {\"coin\":\"XRE\",\"name\":\"revolvercoin\",\"rpcport\":8775,\"pubtype\":0,\"p2shtype\":5,\"wiftype\":128,\"txfee\":1000}, {\"coin\":\"LBC\",\"name\":\"lbrycrd\",\"rpcport\":9245,\"pubtype\":85,\"p2shtype\":122,\"wiftype\":28,\"txfee\":1000}, {\"coin\":\"SIB\",\"name\":\"sibcoin\",\"rpcport\":1944,\"pubtype\":63,\"p2shtype\":40,\"wiftype\":128,\"txfee\":10000}, {\"coin\":\"VTC\", \"name\":\"vertcoin\", \"rpcport\":5888, \"pubtype\":71, \"p2shtype\":5, \"wiftype\":128, \"txfee\":100000 }, {\"coin\":\"REVS\",\"active\":0, \"asset\":\"REVS\",\"rpcport\":10196}, {\"coin\":\"JUMBLR\",\"active\":0, \"asset\":\"JUMBLR\",\"rpcport\":15106}, {\"coin\":\"DOGE\",\"name\":\"dogecoin\",\"rpcport\":22555,\"pubtype\":30,\"p2shtype\":22,\"wiftype\":158,\"txfee\":100000000}, {\"coin\":\"HUSH\",\"name\":\"hush\",\"rpcport\":8822,\"taddr\":28,\"pubtype\":184,\"p2shtype\":189,\"wiftype\":128,\"txfee\":1000 }, {\"active\":0,\"coin\":\"ZEC\",\"name\":\"zcash\",\"rpcport\":8232,\"taddr\":28,\"pubtype\":184,\"p2shtype\":189,\"wiftype\":128,\"txfee\":10000 }, {\"coin\":\"DGB\",\"name\":\"digibyte\",\"rpcport\":14022,\"pubtype\":30,\"p2shtype\":5,\"wiftype\":128,\"txfee\":100000}, {\"coin\":\"ZET\", \"name\":\"zetacoin\", \"pubtype\":80, \"p2shtype\":9,\"rpcport\":8332, \"wiftype\":224, \"txfee\":10000}, {\"coin\":\"GAME\", \"rpcport\":40001, \"name\":\"gamecredits\", \"pubtype\":38, \"p2shtype\":5, \"wiftype\":166, \"txfee\":100000}, {\"coin\":\"LTC\", \"name\":\"litecoin\", \"rpcport\":9332, \"pubtype\":48, \"p2shtype\":5, \"wiftype\":176, \"txfee\":100000 }, {\"coin\":\"SUPERNET\",\"asset\":\"SUPERNET\",\"rpcport\":11341}, {\"coin\":\"WLC\",\"asset\":\"WLC\",\"rpcport\":12167}, {\"coin\":\"PANGEA\",\"asset\":\"PANGEA\",\"rpcport\":14068}, {\"coin\":\"DEX\",\"asset\":\"DEX\",\"rpcport\":11890}, {\"coin\":\"BET\",\"asset\":\"BET\",\"rpcport\":14250}, {\"coin\":\"CRYPTO\",\"asset\":\"CRYPTO\",\"rpcport\":8516}, {\"coin\":\"HODL\",\"asset\":\"HODL\",\"rpcport\":14431}, {\"coin\":\"SHARK\",\"asset\":\"SHARK\",\"rpcport\":10114}, {\"coin\":\"BOTS\",\"asset\":\"BOTS\",\"rpcport\":11964}, {\"coin\":\"MGW\",\"asset\":\"MGW\",\"rpcport\":12386}, {\"coin\":\"COQUI\",\"asset\":\"COQUI\",\"rpcport\":14276}, {\"coin\":\"KV\",\"asset\":\"KV\",\"rpcport\":8299}, {\"coin\":\"CEAL\",\"asset\":\"CEAL\",\"rpcport\":11116}, {\"coin\":\"MESH\",\"asset\":\"MESH\",\"rpcport\":9455}]" +export coins="[{\"coin\":\"PURA\",\"name\":\"pura\",\"rpcport\":55555,\"pubtype\":55,\"p2shtype\":16,\"wiftype\":150,\"txfee\":10000}, {\"coin\":\"DSR\",\"name\":\"desire\",\"confpath\":\"${HOME#}/.desirecore/desire.conf\",\"rpcport\":9918,\"pubtype\":30,\"p2shtype\":16,\"wiftype\":204,\"txfee\":10000}, {\"coin\":\"MNZ\",\"asset\":\"MNZ\",\"rpcport\":14337},{\"coin\":\"BTCZ\",\"name\":\"bitcoinz\",\"rpcport\":1979,\"taddr\":28,\"pubtype\":184,\"p2shtype\":189,\"wiftype\":128,\"txfee\":10000}, {\"coin\":\"MAGA\",\"name\":\"magacoin\",\"rpcport\":5332,\"pubtype\":23,\"p2shtype\":50,\"wiftype\":176,\"txfee\":100000}, {\"coin\":\"BSD\",\"name\":\"bitsend\",\"rpcport\":8800,\"pubtype\":102,\"p2shtype\":5,\"wiftype\":204,\"txfee\":10000}, {\"coin\":\"IOP\",\"name\":\"IoP\",\"rpcport\":8337,\"pubtype\":117,\"p2shtype\":174,\"wiftype\":49,\"txfee\":10000}, {\"coin\":\"BLOCK\",\"name\":\"blocknetdx\",\"rpcport\":41414,\"pubtype\":26,\"p2shtype\":28,\"wiftype\":154,\"txfee\":10000}, {\"coin\":\"CHIPS\", \"name\": \"chips\", \"rpcport\":57776,\"pubtype\":60, \"p2shtype\":85, \"wiftype\":188, \"txfee\":10000}, {\"coin\":\"888\",\"name\":\"octocoin\",\"rpcport\":22888,\"pubtype\":18,\"p2shtype\":5,\"wiftype\":176,\"txfee\":2000000}, {\"coin\":\"ARG\",\"name\":\"argentum\",\"rpcport\":13581,\"pubtype\":23,\"p2shtype\":5,\"wiftype\":151,\"txfee\":50000}, {\"coin\":\"GLT\",\"name\":\"globaltoken\",\"rpcport\":9320,\"pubtype\":38,\"p2shtype\":5,\"wiftype\":166,\"txfee\":10000}, {\"coin\":\"ZER\",\"name\":\"zero\",\"rpcport\":23801,\"taddr\":28,\"pubtype\":184,\"p2shtype\":189,\"wiftype\":128,\"txfee\":1000}, {\"coin\":\"HODLC\",\"name\":\"hodlcoin\",\"rpcport\":11989,\"pubtype\":40,\"p2shtype\":5,\"wiftype\":168,\"txfee\":5000}, {\"coin\":\"UIS\",\"name\":\"unitus\",\"rpcport\":50604,\"pubtype\":68,\"p2shtype\":10,\"wiftype\":132,\"txfee\":2000000}, {\"coin\":\"CRW\",\"name\":\"crown\",\"rpcport\":9341,\"pubtype\":0,\"p2shtype\":5,\"wiftype\":128,\"txfee\":10000}, {\"coin\":\"HUC\",\"name\":\"huntercoin\",\"rpcport\":8399,\"pubtype\":40,\"p2shtype\":13,\"wiftype\":168,\"txfee\":100000}, {\"coin\":\"PIVX\",\"name\":\"pivx\",\"rpcport\":51473,\"pubtype\":30,\"p2shtype\":13,\"wiftype\":212,\"txfee\":10000}, {\"coin\":\"BDL\",\"name\":\"bitdeal\",\"rpcport\":9332,\"pubtype\":38,\"p2shtype\":5,\"wiftype\":176,\"txfee\":100000}, {\"coin\":\"ARC\",\"name\":\"arcticcoin\",\"confpath\":\"${HOME#}/.arcticcore/arcticcoin.conf\",\"rpcport\":7208,\"pubtype\":23,\"p2shtype\":8,\"wiftype\":176,\"txfee\":10000}, {\"coin\":\"ZCL\",\"name\":\"zclassic\",\"rpcport\":8023,\"taddr\":28,\"pubtype\":184,\"p2shtype\":189,\"wiftype\":128,\"txfee\":1000}, {\"coin\":\"VIA\",\"name\":\"viacoin\",\"rpcport\":5222,\"pubtype\":71,\"p2shtype\":33,\"wiftype\":199,\"txfee\":100000}, {\"coin\":\"ERC\",\"name\":\"europecoin\",\"rpcport\":11989,\"pubtype\":33,\"p2shtype\":5,\"wiftype\":168,\"txfee\":10000},{\"coin\":\"FAIR\",\"name\":\"faircoin\",\"confpath\":\"${HOME#}/.faircoin2/faircoin.conf\",\"rpcport\":40405,\"pubtype\":95,\"p2shtype\":36,\"wiftype\":223,\"txfee\":1000000}, {\"coin\":\"FLO\",\"name\":\"florincoin\",\"rpcport\":7313,\"pubtype\":35,\"p2shtype\":8,\"wiftype\":176,\"txfee\":100000}, {\"coin\":\"SXC\",\"name\":\"sexcoin\",\"rpcport\":9561,\"pubtype\":62,\"p2shtype\":5,\"wiftype\":190,\"txfee\":100000}, {\"coin\":\"CREA\",\"name\":\"creativecoin\",\"rpcport\":17711,\"pubtype\":28,\"p2shtype\":5,\"wiftype\":176,\"txfee\":100000}, {\"coin\":\"TRC\",\"name\":\"terracoin\",\"confpath\":\"${HOME#}/.terracoincore/terracoin.conf\",\"rpcport\":13332,\"pubtype\":0,\"p2shtype\":5,\"wiftype\":128,\"txfee\":10000}, {\"coin\":\"BTA\",\"name\":\"bata\",\"rpcport\":5493,\"pubtype\":25,\"p2shtype\":5,\"wiftype\":188,\"txfee\":100000}, {\"coin\":\"SMC\",\"name\":\"smartcoin\",\"rpcport\":58583,\"pubtype\":63,\"p2shtype\":5,\"wiftype\":191,\"txfee\":1000000}, {\"coin\":\"NMC\",\"name\":\"namecoin\",\"rpcport\":8336,\"pubtype\":52,\"p2shtype\":13,\"wiftype\":180,\"txfee\":100000}, {\"coin\":\"NAV\",\"name\":\"navcoin\",\"isPoS\":1,\"confpath\":\"${HOME#}/.navcoin4/navcoin.conf\",\"rpcport\":44444,\"pubtype\":53,\"p2shtype\":85,\"wiftype\":150,\"txfee\":10000}, {\"coin\":\"MOON\",\"name\":\"Mooncoin\",\"rpcport\":44663,\"pubtype\":3,\"p2shtype\":22,\"wiftype\":131,\"txfee\":100000}, {\"coin\":\"EMC2\",\"name\":\"einsteinium\",\"rpcport\":41879,\"pubtype\":33,\"p2shtype\":5,\"wiftype\":176,\"txfee\":100000},{\"coin\":\"SYS\",\"name\":\"syscoin\",\"rpcport\":8370,\"pubtype\":0,\"p2shtype\":5,\"wiftype\":128,\"txfee\":1000}, {\"coin\":\"I0C\",\"name\":\"i0coin\",\"rpcport\":7332,\"pubtype\":105,\"p2shtype\":5,\"wiftype\":128,\"txfee\":1000}, {\"coin\":\"DASH\",\"confpath\":\"${HOME#}/.dashcore/dash.conf\",\"name\":\"dashcore\",\"rpcport\":9998,\"pubtype\":76,\"p2shtype\":16,\"wiftype\":204,\"txfee\":10000}, {\"coin\":\"STRAT\", \"name\": \"stratis\", \"active\":0, \"rpcport\":16174,\"pubtype\":63, \"p2shtype\":125, \"wiftype\":191, \"txfee\":10000}, {\"confpath\":\"${HOME#}/.muecore/mue.conf\",\"coin\":\"MUE\",\"name\":\"muecore\",\"rpcport\":29683,\"pubtype\":16,\"p2shtype\":76,\"wiftype\":126,\"txfee\":10000}, {\"coin\":\"MONA\",\"name\":\"monacoin\",\"rpcport\":9402,\"pubtype\":50,\"p2shtype\":5,\"wiftype\":176,\"txfee\":100000},{\"coin\":\"XMY\",\"name\":\"myriadcoin\",\"rpcport\":10889,\"pubtype\":50,\"p2shtype\":9,\"wiftype\":178,\"txfee\":5000}, {\"coin\":\"MAC\",\"name\":\"machinecoin\",\"rpcport\":40332,\"pubtype\":50,\"p2shtype\":5,\"wiftype\":178,\"txfee\":50000}, {\"coin\":\"BTX\",\"name\":\"bitcore\",\"rpcport\":8556,\"pubtype\":0,\"p2shtype\":5,\"wiftype\":128,\"txfee\":50000}, {\"coin\":\"XRE\",\"name\":\"revolvercoin\",\"rpcport\":8775,\"pubtype\":0,\"p2shtype\":5,\"wiftype\":128,\"txfee\":1000}, {\"coin\":\"LBC\",\"name\":\"lbrycrd\",\"rpcport\":9245,\"pubtype\":85,\"p2shtype\":122,\"wiftype\":28,\"txfee\":1000}, {\"coin\":\"SIB\",\"name\":\"sibcoin\",\"rpcport\":1944,\"pubtype\":63,\"p2shtype\":40,\"wiftype\":128,\"txfee\":10000}, {\"coin\":\"VTC\", \"name\":\"vertcoin\", \"rpcport\":5888, \"pubtype\":71, \"p2shtype\":5, \"wiftype\":128, \"txfee\":100000 }, {\"coin\":\"REVS\",\"active\":0, \"asset\":\"REVS\",\"rpcport\":10196}, {\"coin\":\"JUMBLR\",\"active\":0, \"asset\":\"JUMBLR\",\"rpcport\":15106}, {\"coin\":\"DOGE\",\"name\":\"dogecoin\",\"rpcport\":22555,\"pubtype\":30,\"p2shtype\":22,\"wiftype\":158,\"txfee\":100000000}, {\"coin\":\"HUSH\",\"name\":\"hush\",\"rpcport\":8822,\"taddr\":28,\"pubtype\":184,\"p2shtype\":189,\"wiftype\":128,\"txfee\":1000 }, {\"active\":0,\"coin\":\"ZEC\",\"name\":\"zcash\",\"rpcport\":8232,\"taddr\":28,\"pubtype\":184,\"p2shtype\":189,\"wiftype\":128,\"txfee\":10000 }, {\"coin\":\"DGB\",\"name\":\"digibyte\",\"rpcport\":14022,\"pubtype\":30,\"p2shtype\":5,\"wiftype\":128,\"txfee\":100000}, {\"coin\":\"ZET\", \"name\":\"zetacoin\", \"pubtype\":80, \"p2shtype\":9,\"rpcport\":8332, \"wiftype\":224, \"txfee\":10000}, {\"coin\":\"GAME\", \"rpcport\":40001, \"name\":\"gamecredits\", \"pubtype\":38, \"p2shtype\":5, \"wiftype\":166, \"txfee\":100000}, {\"coin\":\"LTC\", \"name\":\"litecoin\", \"rpcport\":9332, \"pubtype\":48, \"p2shtype\":5, \"wiftype\":176, \"txfee\":100000 }, {\"coin\":\"SUPERNET\",\"asset\":\"SUPERNET\",\"rpcport\":11341}, {\"coin\":\"WLC\",\"asset\":\"WLC\",\"rpcport\":12167}, {\"coin\":\"PANGEA\",\"asset\":\"PANGEA\",\"rpcport\":14068}, {\"coin\":\"DEX\",\"asset\":\"DEX\",\"rpcport\":11890}, {\"coin\":\"BET\",\"asset\":\"BET\",\"rpcport\":14250}, {\"coin\":\"CRYPTO\",\"asset\":\"CRYPTO\",\"rpcport\":8516}, {\"coin\":\"HODL\",\"asset\":\"HODL\",\"rpcport\":14431}, {\"coin\":\"SHARK\",\"asset\":\"SHARK\",\"rpcport\":10114}, {\"coin\":\"BOTS\",\"asset\":\"BOTS\",\"rpcport\":11964}, {\"coin\":\"MGW\",\"asset\":\"MGW\",\"rpcport\":12386}, {\"coin\":\"COQUI\",\"asset\":\"COQUI\",\"rpcport\":14276}, {\"coin\":\"KV\",\"asset\":\"KV\",\"rpcport\":8299}, {\"coin\":\"CEAL\",\"asset\":\"CEAL\",\"rpcport\":11116}, {\"coin\":\"MESH\",\"asset\":\"MESH\",\"rpcport\":9455}]" #, {\"coin\":\"AUD\",\"asset\":\"AUD\",\"rpcport\":8045}, {\"coin\":\"BGN\",\"asset\":\"BGN\",\"rpcport\":9110}, {\"coin\":\"CAD\",\"asset\":\"CAD\",\"rpcport\":8720}, {\"coin\":\"CHF\",\"asset\":\"CHF\",\"rpcport\":15312}, {\"coin\":\"CNY\",\"asset\":\"CNY\",\"rpcport\":10384}, {\"coin\":\"CZK\",\"asset\":\"CZK\",\"rpcport\":9482}, {\"coin\":\"DKK\",\"asset\":\"DKK\",\"rpcport\":13830}, {\"coin\":\"EUR\",\"asset\":\"EUR\",\"rpcport\":8065}, {\"coin\":\"GBP\",\"asset\":\"GBP\",\"rpcport\":11505}, {\"coin\":\"HKD\",\"asset\":\"HKD\",\"rpcport\":15409}, {\"coin\":\"HRK\",\"asset\":\"HRK\",\"rpcport\":12617}, {\"coin\":\"HUF\",\"asset\":\"HUF\",\"rpcport\":13699}, {\"coin\":\"IDR\",\"asset\":\"IDR\",\"rpcport\":14459}, {\"coin\":\"ILS\",\"asset\":\"ILS\",\"rpcport\":14638}, {\"coin\":\"INR\",\"asset\":\"INR\",\"rpcport\":10536}, {\"coin\":\"JPY\",\"asset\":\"JPY\",\"rpcport\":13145}, {\"coin\":\"KRW\",\"asset\":\"KRW\",\"rpcport\":14020}, {\"coin\":\"MXN\",\"asset\":\"MXN\",\"rpcport\":13970}, {\"coin\":\"MYR\",\"asset\":\"MYR\",\"rpcport\":10688}, {\"coin\":\"NOK\",\"asset\":\"NOK\",\"rpcport\":11588}, {\"coin\":\"NZD\",\"asset\":\"NZD\",\"rpcport\":10915}, {\"coin\":\"PHP\",\"asset\":\"PHP\",\"rpcport\":11181}, {\"coin\":\"PLN\",\"asset\":\"PLN\",\"rpcport\":13493}, {\"coin\":\"BRL\",\"asset\":\"BRL\",\"rpcport\":9914}, {\"coin\":\"RON\",\"asset\":\"RON\",\"rpcport\":8675}, {\"coin\":\"RUB\",\"asset\":\"RUB\",\"rpcport\":8199}, {\"coin\":\"SEK\",\"asset\":\"SEK\",\"rpcport\":11447}, {\"coin\":\"SGD\",\"asset\":\"SGD\",\"rpcport\":14475}, {\"coin\":\"THB\",\"asset\":\"THB\",\"rpcport\":11847}, {\"coin\":\"TRY\",\"asset\":\"TRY\",\"rpcport\":13924}, {\"coin\":\"USD\",\"asset\":\"USD\",\"rpcport\":13967}, {\"coin\":\"ZAR\",\"asset\":\"ZAR\",\"rpcport\":15160}]" #{\"coin\":\"ZEN\",\"name\":\"zen\",\"rpcport\":8231,\"pubtype\":137,\"taddr\":32,\"p2shtype\":150,\"wiftype\":128,\"txfee\":10000}, #{\"coin\":\"BLK\",\"name\":\"blackcoin\",\"rpcport\":15715,\"pubtype\":25,\"p2shtype\":85,\"wiftype\":153,\"txfee\":10000}, From 5efe3188acc1a50b69a64c73f39f4fc3fd0117dc Mon Sep 17 00:00:00 2001 From: jl777 Date: Mon, 6 Nov 2017 18:03:36 +0200 Subject: [PATCH 0278/1664] coins.json --- iguana/exchanges/coins.json | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/iguana/exchanges/coins.json b/iguana/exchanges/coins.json index cadc82f08..2fad617b6 100644 --- a/iguana/exchanges/coins.json +++ b/iguana/exchanges/coins.json @@ -1,2 +1,4 @@ -[{\"coin\":\"DSR\",\"name\":\"desire\",\"confpath\":\"${HOME#}/.desirecore/desire.conf\",\"rpcport\":9918,\"pubtype\":30,\"p2shtype\":16,\"wiftype\":204,\"txfee\":10000}, {\"coin\":\"MNZ\",\"asset\":\"MNZ\",\"rpcport\":14337},{\"coin\":\"BTCZ\",\"name\":\"bitcoinz\",\"rpcport\":1979,\"taddr\":28,\"pubtype\":184,\"p2shtype\":189,\"wiftype\":128,\"txfee\":10000}, {\"coin\":\"MAGA\",\"name\":\"magacoin\",\"rpcport\":5332,\"pubtype\":23,\"p2shtype\":50,\"wiftype\":176,\"txfee\":100000}, {\"coin\":\"BSD\",\"name\":\"bitsend\",\"rpcport\":8800,\"pubtype\":102,\"p2shtype\":5,\"wiftype\":204,\"txfee\":10000}, {\"coin\":\"IOP\",\"name\":\"IoP\",\"rpcport\":8337,\"pubtype\":117,\"p2shtype\":174,\"wiftype\":49,\"txfee\":10000}, {\"coin\":\"BLOCK\",\"name\":\"blocknetdx\",\"rpcport\":41414,\"pubtype\":26,\"p2shtype\":28,\"wiftype\":154,\"txfee\":10000}, {\"coin\":\"CHIPS\", \"name\": \"chips\", \"rpcport\":57776,\"pubtype\":60, \"p2shtype\":85, \"wiftype\":188, \"txfee\":10000}, {\"coin\":\"888\",\"name\":\"octocoin\",\"rpcport\":22888,\"pubtype\":18,\"p2shtype\":5,\"wiftype\":176,\"txfee\":2000000}, {\"coin\":\"ARG\",\"name\":\"argentum\",\"rpcport\":13581,\"pubtype\":23,\"p2shtype\":5,\"wiftype\":151,\"txfee\":50000}, {\"coin\":\"GLT\",\"name\":\"globaltoken\",\"rpcport\":9320,\"pubtype\":38,\"p2shtype\":5,\"wiftype\":166,\"txfee\":10000}, {\"coin\":\"ZER\",\"name\":\"zero\",\"rpcport\":23801,\"taddr\":28,\"pubtype\":184,\"p2shtype\":189,\"wiftype\":128,\"txfee\":1000}, {\"coin\":\"HODLC\",\"name\":\"hodlcoin\",\"rpcport\":11989,\"pubtype\":40,\"p2shtype\":5,\"wiftype\":168,\"txfee\":5000}, {\"coin\":\"UIS\",\"name\":\"unitus\",\"rpcport\":50604,\"pubtype\":68,\"p2shtype\":10,\"wiftype\":132,\"txfee\":2000000}, {\"coin\":\"CRW\",\"name\":\"crown\",\"rpcport\":9341,\"pubtype\":0,\"p2shtype\":5,\"wiftype\":128,\"txfee\":10000}, {\"coin\":\"HUC\",\"name\":\"huntercoin\",\"rpcport\":8399,\"pubtype\":40,\"p2shtype\":13,\"wiftype\":168,\"txfee\":100000}, {\"coin\":\"PIVX\",\"name\":\"pivx\",\"rpcport\":51473,\"pubtype\":30,\"p2shtype\":13,\"wiftype\":212,\"txfee\":10000}, {\"coin\":\"BDL\",\"name\":\"bitdeal\",\"rpcport\":9332,\"pubtype\":38,\"p2shtype\":5,\"wiftype\":176,\"txfee\":100000}, {\"coin\":\"ARC\",\"name\":\"arcticcoin\",\"confpath\":\"${HOME#}/.arcticcore/arcticcoin.conf\",\"rpcport\":7208,\"pubtype\":23,\"p2shtype\":8,\"wiftype\":176,\"txfee\":10000}, {\"coin\":\"ZCL\",\"name\":\"zclassic\",\"rpcport\":8023,\"taddr\":28,\"pubtype\":184,\"p2shtype\":189,\"wiftype\":128,\"txfee\":1000}, {\"coin\":\"VIA\",\"name\":\"viacoin\",\"rpcport\":5222,\"pubtype\":71,\"p2shtype\":33,\"wiftype\":199,\"txfee\":100000}, {\"coin\":\"ERC\",\"name\":\"europecoin\",\"rpcport\":11989,\"pubtype\":33,\"p2shtype\":5,\"wiftype\":168,\"txfee\":10000},{\"coin\":\"FAIR\",\"name\":\"faircoin\",\"confpath\":\"${HOME#}/.faircoin2/faircoin.conf\",\"rpcport\":40405,\"pubtype\":95,\"p2shtype\":36,\"wiftype\":223,\"txfee\":1000000}, {\"coin\":\"FLO\",\"name\":\"florincoin\",\"rpcport\":7313,\"pubtype\":35,\"p2shtype\":8,\"wiftype\":176,\"txfee\":100000}, {\"coin\":\"SXC\",\"name\":\"sexcoin\",\"rpcport\":9561,\"pubtype\":62,\"p2shtype\":5,\"wiftype\":190,\"txfee\":100000}, {\"coin\":\"CREA\",\"name\":\"creativecoin\",\"rpcport\":17711,\"pubtype\":28,\"p2shtype\":5,\"wiftype\":176,\"txfee\":100000}, {\"coin\":\"TRC\",\"name\":\"terracoin\",\"confpath\":\"${HOME#}/.terracoincore/terracoin.conf\",\"rpcport\":13332,\"pubtype\":0,\"p2shtype\":5,\"wiftype\":128,\"txfee\":10000}, {\"coin\":\"BTA\",\"name\":\"bata\",\"rpcport\":5493,\"pubtype\":25,\"p2shtype\":5,\"wiftype\":188,\"txfee\":100000}, {\"coin\":\"SMC\",\"name\":\"smartcoin\",\"rpcport\":58583,\"pubtype\":63,\"p2shtype\":5,\"wiftype\":191,\"txfee\":1000000}, {\"coin\":\"NMC\",\"name\":\"namecoin\",\"rpcport\":8336,\"pubtype\":52,\"p2shtype\":13,\"wiftype\":180,\"txfee\":100000}, {\"coin\":\"NAV\",\"name\":\"navcoin\",\"isPoS\":1,\"confpath\":\"${HOME#}/.navcoin4/navcoin.conf\",\"rpcport\":44444,\"pubtype\":53,\"p2shtype\":85,\"wiftype\":150,\"txfee\":10000}, {\"coin\":\"MOON\",\"name\":\"Mooncoin\",\"rpcport\":44663,\"pubtype\":3,\"p2shtype\":22,\"wiftype\":131,\"txfee\":100000}, {\"coin\":\"EMC2\",\"name\":\"einsteinium\",\"rpcport\":41879,\"pubtype\":33,\"p2shtype\":5,\"wiftype\":176,\"txfee\":100000},{\"coin\":\"SYS\",\"name\":\"syscoin\",\"rpcport\":8370,\"pubtype\":0,\"p2shtype\":5,\"wiftype\":128,\"txfee\":1000}, {\"coin\":\"I0C\",\"name\":\"i0coin\",\"rpcport\":7332,\"pubtype\":105,\"p2shtype\":5,\"wiftype\":128,\"txfee\":1000}, {\"coin\":\"DASH\",\"confpath\":\"${HOME#}/.dashcore/dash.conf\",\"name\":\"dashcore\",\"rpcport\":9998,\"pubtype\":76,\"p2shtype\":16,\"wiftype\":204,\"txfee\":10000}, {\"coin\":\"STRAT\", \"name\": \"stratis\", \"active\":0, \"rpcport\":16174,\"pubtype\":63, \"p2shtype\":125, \"wiftype\":191, \"txfee\":10000}, {\"confpath\":\"${HOME#}/.muecore/mue.conf\",\"coin\":\"MUE\",\"name\":\"muecore\",\"rpcport\":29683,\"pubtype\":16,\"p2shtype\":76,\"wiftype\":126,\"txfee\":10000}, {\"coin\":\"MONA\",\"name\":\"monacoin\",\"rpcport\":9402,\"pubtype\":50,\"p2shtype\":5,\"wiftype\":176,\"txfee\":100000},{\"coin\":\"XMY\",\"name\":\"myriadcoin\",\"rpcport\":10889,\"pubtype\":50,\"p2shtype\":9,\"wiftype\":178,\"txfee\":5000}, {\"coin\":\"MAC\",\"name\":\"machinecoin\",\"rpcport\":40332,\"pubtype\":50,\"p2shtype\":5,\"wiftype\":178,\"txfee\":50000}, {\"coin\":\"BTX\",\"name\":\"bitcore\",\"rpcport\":8556,\"pubtype\":0,\"p2shtype\":5,\"wiftype\":128,\"txfee\":50000}, {\"coin\":\"XRE\",\"name\":\"revolvercoin\",\"rpcport\":8775,\"pubtype\":0,\"p2shtype\":5,\"wiftype\":128,\"txfee\":1000}, {\"coin\":\"LBC\",\"name\":\"lbrycrd\",\"rpcport\":9245,\"pubtype\":85,\"p2shtype\":122,\"wiftype\":28,\"txfee\":1000}, {\"coin\":\"SIB\",\"name\":\"sibcoin\",\"rpcport\":1944,\"pubtype\":63,\"p2shtype\":40,\"wiftype\":128,\"txfee\":10000}, {\"coin\":\"VTC\", \"name\":\"vertcoin\", \"rpcport\":5888, \"pubtype\":71, \"p2shtype\":5, \"wiftype\":128, \"txfee\":100000 }, {\"coin\":\"REVS\",\"active\":0, \"asset\":\"REVS\",\"rpcport\":10196}, {\"coin\":\"JUMBLR\",\"active\":0, \"asset\":\"JUMBLR\",\"rpcport\":15106}, {\"coin\":\"DOGE\",\"name\":\"dogecoin\",\"rpcport\":22555,\"pubtype\":30,\"p2shtype\":22,\"wiftype\":158,\"txfee\":100000000}, {\"coin\":\"HUSH\",\"name\":\"hush\",\"rpcport\":8822,\"taddr\":28,\"pubtype\":184,\"p2shtype\":189,\"wiftype\":128,\"txfee\":1000 }, {\"active\":0,\"coin\":\"ZEC\",\"name\":\"zcash\",\"rpcport\":8232,\"taddr\":28,\"pubtype\":184,\"p2shtype\":189,\"wiftype\":128,\"txfee\":10000 }, {\"coin\":\"DGB\",\"name\":\"digibyte\",\"rpcport\":14022,\"pubtype\":30,\"p2shtype\":5,\"wiftype\":128,\"txfee\":100000}, {\"coin\":\"ZET\", \"name\":\"zetacoin\", \"pubtype\":80, \"p2shtype\":9,\"rpcport\":8332, \"wiftype\":224, \"txfee\":10000}, {\"coin\":\"GAME\", \"rpcport\":40001, \"name\":\"gamecredits\", \"pubtype\":38, \"p2shtype\":5, \"wiftype\":166, \"txfee\":100000}, {\"coin\":\"LTC\", \"name\":\"litecoin\", \"rpcport\":9332, \"pubtype\":48, \"p2shtype\":5, \"wiftype\":176, \"txfee\":100000 }, {\"coin\":\"SUPERNET\",\"asset\":\"SUPERNET\",\"rpcport\":11341}, {\"coin\":\"WLC\",\"asset\":\"WLC\",\"rpcport\":12167}, {\"coin\":\"PANGEA\",\"asset\":\"PANGEA\",\"rpcport\":14068}, {\"coin\":\"DEX\",\"asset\":\"DEX\",\"rpcport\":11890}, {\"coin\":\"BET\",\"asset\":\"BET\",\"rpcport\":14250}, {\"coin\":\"CRYPTO\",\"asset\":\"CRYPTO\",\"rpcport\":8516}, {\"coin\":\"HODL\",\"asset\":\"HODL\",\"rpcport\":14431}, {\"coin\":\"SHARK\",\"asset\":\"SHARK\",\"rpcport\":10114}, {\"coin\":\"BOTS\",\"asset\":\"BOTS\",\"rpcport\":11964}, {\"coin\":\"MGW\",\"asset\":\"MGW\",\"rpcport\":12386}, {\"coin\":\"COQUI\",\"asset\":\"COQUI\",\"rpcport\":14276}, {\"coin\":\"KV\",\"asset\":\"KV\",\"rpcport\":8299}, {\"coin\":\"CEAL\",\"asset\":\"CEAL\",\"rpcport\":11116}, {\"coin\":\"MESH\",\"asset\":\"MESH\",\"rpcport\":9455}]" -#, {\"coin\":\"AUD\",\"asset\":\"AUD\",\"rpcport\":8045}, {\"coin\":\"BGN\",\"asset\":\"BGN\",\"rpcport\":9110}, {\"coin\":\"CAD\",\"asset\":\"CAD\",\"rpcport\":8720}, {\"coin\":\"CHF\",\"asset\":\"CHF\",\"rpcport\":15312}, {\"coin\":\"CNY\",\"asset\":\"CNY\",\"rpcport\":10384}, {\"coin\":\"CZK\",\"asset\":\"CZK\",\"rpcport\":9482}, {\"coin\":\"DKK\",\"asset\":\"DKK\",\"rpcport\":13830}, {\"coin\":\"EUR\",\"asset\":\"EUR\",\"rpcport\":8065}, {\"coin\":\"GBP\",\"asset\":\"GBP\",\"rpcport\":11505}, {\"coin\":\"HKD\",\"asset\":\"HKD\",\"rpcport\":15409}, {\"coin\":\"HRK\",\"asset\":\"HRK\",\"rpcport\":12617}, {\"coin\":\"HUF\",\"asset\":\"HUF\",\"rpcport\":13699}, {\"coin\":\"IDR\",\"asset\":\"IDR\",\"rpcport\":14459}, {\"coin\":\"ILS\",\"asset\":\"ILS\",\"rpcport\":14638}, {\"coin\":\"INR\",\"asset\":\"INR\",\"rpcport\":10536}, {\"coin\":\"JPY\",\"asset\":\"JPY\",\"rpcport\":13145}, {\"coin\":\"KRW\",\"asset\":\"KRW\",\"rpcport\":14020}, {\"coin\":\"MXN\",\"asset\":\"MXN\",\"rpcport\":13970}, {\"coin\":\"MYR\",\"asset\":\"MYR\",\"rpcport\":10688}, {\"coin\":\"NOK\",\"asset\":\"NOK\",\"rpcport\":11588}, {\"coin\":\"NZD\",\"asset\":\"NZD\",\"rpcport\":10915}, {\"coin\":\"PHP\",\"asset\":\"PHP\",\"rpcport\":11181}, {\"coin\":\"PLN\",\"asset\":\"PLN\",\"rpcport\":13493}, {\"coin\":\"BRL\",\"asset\":\"BRL\",\"rpcport\":9914}, {\"coin\":\"RON\",\"asset\":\"RON\",\"rpcport\":8675}, {\"coin\":\"RUB\",\"asset\":\"RUB\",\"rpcport\":8199}, {\"coin\":\"SEK\",\"asset\":\"SEK\",\"rpcport\":11447}, {\"coin\":\"SGD\",\"asset\":\"SGD\",\"rpcport\":14475}, {\"coin\":\"THB\",\"asset\":\"THB\",\"rpcport\":11847}, {\"coin\":\"TRY\",\"asset\":\"TRY\",\"rpcport\":13924}, {\"coin\":\"USD\",\"asset\":\"USD\",\"rpcport\":13967}, {\"coin\":\"ZAR\",\"asset\":\"ZAR\",\"rpcport\":15160}] +[{\"coin\":\"PURA\",\"name\":\"pura\",\"rpcport\":55555,\"pubtype\":55,\"p2shtype\":16,\"wiftype\":150,\"txfee\":10000}, {\"coin\":\"DSR\",\"name\":\"desire\",\"confpath\":\"${HOME#}/.desirecore/desire.conf\",\"rpcport\":9918,\"pubtype\":30,\"p2shtype\":16,\"wiftype\":204,\"txfee\":10000}, {\"coin\":\"MNZ\",\"asset\":\"MNZ\",\"rpcport\":14337},{\"coin\":\"BTCZ\",\"name\":\"bitcoinz\",\"rpcport\":1979,\"taddr\":28,\"pubtype\":184,\"p2shtype\":189,\"wiftype\":128,\"txfee\":10000}, {\"coin\":\"MAGA\",\"name\":\"magacoin\",\"rpcport\":5332,\"pubtype\":23,\"p2shtype\":50,\"wiftype\":176,\"txfee\":100000}, {\"coin\":\"BSD\",\"name\":\"bitsend\",\"rpcport\":8800,\"pubtype\":102,\"p2shtype\":5,\"wiftype\":204,\"txfee\":10000}, {\"coin\":\"IOP\",\"name\":\"IoP\",\"rpcport\":8337,\"pubtype\":117,\"p2shtype\":174,\"wiftype\":49,\"txfee\":10000}, {\"coin\":\"BLOCK\",\"name\":\"blocknetdx\",\"rpcport\":41414,\"pubtype\":26,\"p2shtype\":28,\"wiftype\":154,\"txfee\":10000}, {\"coin\":\"CHIPS\", \"name\": \"chips\", \"rpcport\":57776,\"pubtype\":60, \"p2shtype\":85, \"wiftype\":188, \"txfee\":10000}, {\"coin\":\"888\",\"name\":\"octocoin\",\"rpcport\":22888,\"pubtype\":18,\"p2shtype\":5,\"wiftype\":176,\"txfee\":2000000}, {\"coin\":\"ARG\",\"name\":\"argentum\",\"rpcport\":13581,\"pubtype\":23,\"p2shtype\":5,\"wiftype\":151,\"txfee\":50000}, {\"coin\":\"GLT\",\"name\":\"globaltoken\",\"rpcport\":9320,\"pubtype\":38,\"p2shtype\":5,\"wiftype\":166,\"txfee\":10000}, {\"coin\":\"ZER\",\"name\":\"zero\",\"rpcport\":23801,\"taddr\":28,\"pubtype\":184,\"p2shtype\":189,\"wiftype\":128,\"txfee\":1000}, {\"coin\":\"HODLC\",\"name\":\"hodlcoin\",\"rpcport\":11989,\"pubtype\":40,\"p2shtype\":5,\"wiftype\":168,\"txfee\":5000}, {\"coin\":\"UIS\",\"name\":\"unitus\",\"rpcport\":50604,\"pubtype\":68,\"p2shtype\":10,\"wiftype\":132,\"txfee\":2000000}, {\"coin\":\"CRW\",\"name\":\"crown\",\"rpcport\":9341,\"pubtype\":0,\"p2shtype\":5,\"wiftype\":128,\"txfee\":10000}, {\"coin\":\"HUC\",\"name\":\"huntercoin\",\"rpcport\":8399,\"pubtype\":40,\"p2shtype\":13,\"wiftype\":168,\"txfee\":100000}, {\"coin\":\"PIVX\",\"name\":\"pivx\",\"rpcport\":51473,\"pubtype\":30,\"p2shtype\":13,\"wiftype\":212,\"txfee\":10000}, {\"coin\":\"BDL\",\"name\":\"bitdeal\",\"rpcport\":9332,\"pubtype\":38,\"p2shtype\":5,\"wiftype\":176,\"txfee\":100000}, {\"coin\":\"ARC\",\"name\":\"arcticcoin\",\"confpath\":\"${HOME#}/.arcticcore/arcticcoin.conf\",\"rpcport\":7208,\"pubtype\":23,\"p2shtype\":8,\"wiftype\":176,\"txfee\":10000}, {\"coin\":\"ZCL\",\"name\":\"zclassic\",\"rpcport\":8023,\"taddr\":28,\"pubtype\":184,\"p2shtype\":189,\"wiftype\":128,\"txfee\":1000}, {\"coin\":\"VIA\",\"name\":\"viacoin\",\"rpcport\":5222,\"pubtype\":71,\"p2shtype\":33,\"wiftype\":199,\"txfee\":100000}, {\"coin\":\"ERC\",\"name\":\"europecoin\",\"rpcport\":11989,\"pubtype\":33,\"p2shtype\":5,\"wiftype\":168,\"txfee\":10000},{\"coin\":\"FAIR\",\"name\":\"faircoin\",\"confpath\":\"${HOME#}/.faircoin2/faircoin.conf\",\"rpcport\":40405,\"pubtype\":95,\"p2shtype\":36,\"wiftype\":223,\"txfee\":1000000}, {\"coin\":\"FLO\",\"name\":\"florincoin\",\"rpcport\":7313,\"pubtype\":35,\"p2shtype\":8,\"wiftype\":176,\"txfee\":100000}, {\"coin\":\"SXC\",\"name\":\"sexcoin\",\"rpcport\":9561,\"pubtype\":62,\"p2shtype\":5,\"wiftype\":190,\"txfee\":100000}, {\"coin\":\"CREA\",\"name\":\"creativecoin\",\"rpcport\":17711,\"pubtype\":28,\"p2shtype\":5,\"wiftype\":176,\"txfee\":100000}, {\"coin\":\"TRC\",\"name\":\"terracoin\",\"confpath\":\"${HOME#}/.terracoincore/terracoin.conf\",\"rpcport\":13332,\"pubtype\":0,\"p2shtype\":5,\"wiftype\":128,\"txfee\":10000}, {\"coin\":\"BTA\",\"name\":\"bata\",\"rpcport\":5493,\"pubtype\":25,\"p2shtype\":5,\"wiftype\":188,\"txfee\":100000}, {\"coin\":\"SMC\",\"name\":\"smartcoin\",\"rpcport\":58583,\"pubtype\":63,\"p2shtype\":5,\"wiftype\":191,\"txfee\":1000000}, {\"coin\":\"NMC\",\"name\":\"namecoin\",\"rpcport\":8336,\"pubtype\":52,\"p2shtype\":13,\"wiftype\":180,\"txfee\":100000}, {\"coin\":\"NAV\",\"name\":\"navcoin\",\"isPoS\":1,\"confpath\":\"${HOME#}/.navcoin4/navcoin.conf\",\"rpcport\":44444,\"pubtype\":53,\"p2shtype\":85,\"wiftype\":150,\"txfee\":10000}, {\"coin\":\"MOON\",\"name\":\"Mooncoin\",\"rpcport\":44663,\"pubtype\":3,\"p2shtype\":22,\"wiftype\":131,\"txfee\":100000}, {\"coin\":\"EMC2\",\"name\":\"einsteinium\",\"rpcport\":41879,\"pubtype\":33,\"p2shtype\":5,\"wiftype\":176,\"txfee\":100000},{\"coin\":\"SYS\",\"name\":\"syscoin\",\"rpcport\":8370,\"pubtype\":0,\"p2shtype\":5,\"wiftype\":128,\"txfee\":1000}, {\"coin\":\"I0C\",\"name\":\"i0coin\",\"rpcport\":7332,\"pubtype\":105,\"p2shtype\":5,\"wiftype\":128,\"txfee\":1000}, {\"coin\":\"DASH\",\"confpath\":\"${HOME#}/.dashcore/dash.conf\",\"name\":\"dashcore\",\"rpcport\":9998,\"pubtype\":76,\"p2shtype\":16,\"wiftype\":204,\"txfee\":10000}, {\"coin\":\"STRAT\", \"name\": \"stratis\", \"active\":0, \"rpcport\":16174,\"pubtype\":63, \"p2shtype\":125, \"wiftype\":191, \"txfee\":10000}, {\"confpath\":\"${HOME#}/.muecore/mue.conf\",\"coin\":\"MUE\",\"name\":\"muecore\",\"rpcport\":29683,\"pubtype\":16,\"p2shtype\":76,\"wiftype\":126,\"txfee\":10000}, {\"coin\":\"MONA\",\"name\":\"monacoin\",\"rpcport\":9402,\"pubtype\":50,\"p2shtype\":5,\"wiftype\":176,\"txfee\":100000},{\"coin\":\"XMY\",\"name\":\"myriadcoin\",\"rpcport\":10889,\"pubtype\":50,\"p2shtype\":9,\"wiftype\":178,\"txfee\":5000}, {\"coin\":\"MAC\",\"name\":\"machinecoin\",\"rpcport\":40332,\"pubtype\":50,\"p2shtype\":5,\"wiftype\":178,\"txfee\":50000}, {\"coin\":\"BTX\",\"name\":\"bitcore\",\"rpcport\":8556,\"pubtype\":0,\"p2shtype\":5,\"wiftype\":128,\"txfee\":50000}, {\"coin\":\"XRE\",\"name\":\"revolvercoin\",\"rpcport\":8775,\"pubtype\":0,\"p2shtype\":5,\"wiftype\":128,\"txfee\":1000}, {\"coin\":\"LBC\",\"name\":\"lbrycrd\",\"rpcport\":9245,\"pubtype\":85,\"p2shtype\":122,\"wiftype\":28,\"txfee\":1000}, {\"coin\":\"SIB\",\"name\":\"sibcoin\",\"rpcport\":1944,\"pubtype\":63,\"p2shtype\":40,\"wiftype\":128,\"txfee\":10000}, {\"coin\":\"VTC\", \"name\":\"vertcoin\", \"rpcport\":5888, \"pubtype\":71, \"p2shtype\":5, \"wiftype\":128, \"txfee\":100000 }, {\"coin\":\"REVS\",\"active\":0, \"asset\":\"REVS\",\"rpcport\":10196}, {\"coin\":\"JUMBLR\",\"active\":0, \"asset\":\"JUMBLR\",\"rpcport\":15106}, {\"coin\":\"DOGE\",\"name\":\"dogecoin\",\"rpcport\":22555,\"pubtype\":30,\"p2shtype\":22,\"wiftype\":158,\"txfee\":100000000}, {\"coin\":\"HUSH\",\"name\":\"hush\",\"rpcport\":8822,\"taddr\":28,\"pubtype\":184,\"p2shtype\":189,\"wiftype\":128,\"txfee\":1000 }, {\"active\":0,\"coin\":\"ZEC\",\"name\":\"zcash\",\"rpcport\":8232,\"taddr\":28,\"pubtype\":184,\"p2shtype\":189,\"wiftype\":128,\"txfee\":10000 }, {\"coin\":\"DGB\",\"name\":\"digibyte\",\"rpcport\":14022,\"pubtype\":30,\"p2shtype\":5,\"wiftype\":128,\"txfee\":100000}, {\"coin\":\"ZET\", \"name\":\"zetacoin\", \"pubtype\":80, \"p2shtype\":9,\"rpcport\":8332, \"wiftype\":224, \"txfee\":10000}, {\"coin\":\"GAME\", \"rpcport\":40001, \"name\":\"gamecredits\", \"pubtype\":38, \"p2shtype\":5, \"wiftype\":166, \"txfee\":100000}, {\"coin\":\"LTC\", \"name\":\"litecoin\", \"rpcport\":9332, \"pubtype\":48, \"p2shtype\":5, \"wiftype\":176, \"txfee\":100000 }, {\"coin\":\"SUPERNET\",\"asset\":\"SUPERNET\",\"rpcport\":11341}, {\"coin\":\"WLC\",\"asset\":\"WLC\",\"rpcport\":12167}, {\"coin\":\"PANGEA\",\"asset\":\"PANGEA\",\"rpcport\":14068}, {\"coin\":\"DEX\",\"asset\":\"DEX\",\"rpcport\":11890}, {\"coin\":\"BET\",\"asset\":\"BET\",\"rpcport\":14250}, {\"coin\":\"CRYPTO\",\"asset\":\"CRYPTO\",\"rpcport\":8516}, {\"coin\":\"HODL\",\"asset\":\"HODL\",\"rpcport\":14431}, {\"coin\":\"SHARK\",\"asset\":\"SHARK\",\"rpcport\":10114}, {\"coin\":\"BOTS\",\"asset\":\"BOTS\",\"rpcport\":11964}, {\"coin\":\"MGW\",\"asset\":\"MGW\",\"rpcport\":12386}, {\"coin\":\"COQUI\",\"asset\":\"COQUI\",\"rpcport\":14276}, {\"coin\":\"KV\",\"asset\":\"KV\",\"rpcport\":8299}, {\"coin\":\"CEAL\",\"asset\":\"CEAL\",\"rpcport\":11116}, {\"coin\":\"MESH\",\"asset\":\"MESH\",\"rpcport\":9455}] +#, {\"coin\":\"AUD\",\"asset\":\"AUD\",\"rpcport\":8045}, {\"coin\":\"BGN\",\"asset\":\"BGN\",\"rpcport\":9110}, {\"coin\":\"CAD\",\"asset\":\"CAD\",\"rpcport\":8720}, {\"coin\":\"CHF\",\"asset\":\"CHF\",\"rpcport\":15312}, {\"coin\":\"CNY\",\"asset\":\"CNY\",\"rpcport\":10384}, {\"coin\":\"CZK\",\"asset\":\"CZK\",\"rpcport\":9482}, {\"coin\":\"DKK\",\"asset\":\"DKK\",\"rpcport\":13830}, {\"coin\":\"EUR\",\"asset\":\"EUR\",\"rpcport\":8065}, {\"coin\":\"GBP\",\"asset\":\"GBP\",\"rpcport\":11505}, {\"coin\":\"HKD\",\"asset\":\"HKD\",\"rpcport\":15409}, {\"coin\":\"HRK\",\"asset\":\"HRK\",\"rpcport\":12617}, {\"coin\":\"HUF\",\"asset\":\"HUF\",\"rpcport\":13699}, {\"coin\":\"IDR\",\"asset\":\"IDR\",\"rpcport\":14459}, {\"coin\":\"ILS\",\"asset\":\"ILS\",\"rpcport\":14638}, {\"coin\":\"INR\",\"asset\":\"INR\",\"rpcport\":10536}, {\"coin\":\"JPY\",\"asset\":\"JPY\",\"rpcport\":13145}, {\"coin\":\"KRW\",\"asset\":\"KRW\",\"rpcport\":14020}, {\"coin\":\"MXN\",\"asset\":\"MXN\",\"rpcport\":13970}, {\"coin\":\"MYR\",\"asset\":\"MYR\",\"rpcport\":10688}, {\"coin\":\"NOK\",\"asset\":\"NOK\",\"rpcport\":11588}, {\"coin\":\"NZD\",\"asset\":\"NZD\",\"rpcport\":10915}, {\"coin\":\"PHP\",\"asset\":\"PHP\",\"rpcport\":11181}, {\"coin\":\"PLN\",\"asset\":\"PLN\",\"rpcport\":13493}, {\"coin\":\"BRL\",\"asset\":\"BRL\",\"rpcport\":9914}, {\"coin\":\"RON\",\"asset\":\"RON\",\"rpcport\":8675}, {\"coin\":\"RUB\",\"asset\":\"RUB\",\"rpcport\":8199}, {\"coin\":\"SEK\",\"asset\":\"SEK\",\"rpcport\":11447}, {\"coin\":\"SGD\",\"asset\":\"SGD\",\"rpcport\":14475}, {\"coin\":\"THB\",\"asset\":\"THB\",\"rpcport\":11847}, {\"coin\":\"TRY\",\"asset\":\"TRY\",\"rpcport\":13924}, {\"coin\":\"USD\",\"asset\":\"USD\",\"rpcport\":13967}, {\"coin\":\"ZAR\",\"asset\":\"ZAR\",\"rpcport\":15160}]" +#{\"coin\":\"ZEN\",\"name\":\"zen\",\"rpcport\":8231,\"pubtype\":137,\"taddr\":32,\"p2shtype\":150,\"wiftype\":128,\"txfee\":10000}, +#{\"coin\":\"BLK\",\"name\":\"blackcoin\",\"rpcport\":15715,\"pubtype\":25,\"p2shtype\":85,\"wiftype\":153,\"txfee\":10000}, From ec0f7f22aed7e96f3d987acf6d850a865a5eccad Mon Sep 17 00:00:00 2001 From: jl777 Date: Mon, 6 Nov 2017 21:21:46 +0200 Subject: [PATCH 0279/1664] Test --- iguana/exchanges/LP_include.h | 5 ++- iguana/exchanges/LP_nativeDEX.c | 3 +- iguana/exchanges/LP_remember.c | 8 ++--- iguana/exchanges/LP_rpc.c | 1 + iguana/exchanges/LP_transaction.c | 42 +++++++++++++++++++------ iguana/exchanges/LP_utxo.c | 52 +++++++++++++++++++++++++++++++ iguana/exchanges/LP_utxos.c | 1 + iguana/exchanges/stats.c | 2 +- 8 files changed, 98 insertions(+), 16 deletions(-) diff --git a/iguana/exchanges/LP_include.h b/iguana/exchanges/LP_include.h index 29c06f6ba..70dc2248b 100644 --- a/iguana/exchanges/LP_include.h +++ b/iguana/exchanges/LP_include.h @@ -47,6 +47,9 @@ void emscripten_usleep(int32_t x); // returns immediate, no sense for sleeping #define LP_MIN_PEERS 8 #define LP_MAX_PEERS 32 +#define LP_MAXDESIRED_UTXOS 128 +#define LP_MINDESIRED_UTXOS 64 + // RTmetrics #define LP_RTMETRICS_TOPGROUP 1.01 #define LP_MAXPENDING_SWAPS 13 @@ -250,7 +253,7 @@ 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 longestchain,firstrefht,firstscanht,lastscanht,bussock,height; uint16_t busport; + int32_t numutxos,longestchain,firstrefht,firstscanht,lastscanht,bussock,height; uint16_t busport; uint32_t 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[16],smartaddr[64],userpass[1024],serverport[128]; diff --git a/iguana/exchanges/LP_nativeDEX.c b/iguana/exchanges/LP_nativeDEX.c index fd41a9857..1a92188a8 100644 --- a/iguana/exchanges/LP_nativeDEX.c +++ b/iguana/exchanges/LP_nativeDEX.c @@ -17,7 +17,8 @@ // // LP_nativeDEX.c // marketmaker -// bots to do bobs +// +// autoadd dust utxo to vin for initial atomic tx // verify portfolio, interest to KMD withdraw // dPoW security -> 4: KMD notarized, 5: BTC notarized, after next notary elections // bigendian architectures need to use little endian for sighash calcs diff --git a/iguana/exchanges/LP_remember.c b/iguana/exchanges/LP_remember.c index 927af1771..594b1fd03 100644 --- a/iguana/exchanges/LP_remember.c +++ b/iguana/exchanges/LP_remember.c @@ -937,7 +937,7 @@ cJSON *basilisk_remember(int64_t *KMDtotals,int64_t *BTCtotals,uint32_t requesti } for (j=0; j<32; j++) rev.bytes[j] = rswap.myprivs[0].bytes[31 - j]; - if ( (rswap.txbytes[BASILISK_ALICESPEND]= basilisk_swap_bobtxspend(&signedtxid,rswap.Btxfee,"alicespend",rswap.bobcoin,bob->wiftaddr,bob->taddr,bob->pubtype,bob->p2shtype,bob->isPoS,bob->wiftype,ctx,rswap.myprivs[0],0,redeemscript,redeemlen,userdata,len,rswap.txids[BASILISK_BOBPAYMENT],0,0,rswap.pubkey33,1,rswap.expiration,&rswap.values[BASILISK_ALICESPEND],0,0,rswap.bobpaymentaddr,1,bob->zcash)) != 0 ) + if ( (rswap.txbytes[BASILISK_ALICESPEND]= basilisk_swap_bobtxspend(0,&signedtxid,rswap.Btxfee,"alicespend",rswap.bobcoin,bob->wiftaddr,bob->taddr,bob->pubtype,bob->p2shtype,bob->isPoS,bob->wiftype,ctx,rswap.myprivs[0],0,redeemscript,redeemlen,userdata,len,rswap.txids[BASILISK_BOBPAYMENT],0,0,rswap.pubkey33,1,rswap.expiration,&rswap.values[BASILISK_ALICESPEND],0,0,rswap.bobpaymentaddr,1,bob->zcash)) != 0 ) printf("alicespend.(%s)\n",rswap.txbytes[BASILISK_ALICESPEND]); } LP_txbytes_update("alicespend",rswap.bobcoin,rswap.txbytes[BASILISK_ALICESPEND],&rswap.txids[BASILISK_ALICESPEND],&rswap.paymentspent,&rswap.sentflags[BASILISK_ALICESPEND]); @@ -967,7 +967,7 @@ cJSON *basilisk_remember(int64_t *KMDtotals,int64_t *BTCtotals,uint32_t requesti if ( bits256_nonz(rswap.privBn) != 0 ) { len = basilisk_swapuserdata(userdata,zero,1,rswap.myprivs[0],redeemscript,redeemlen); - if ( (rswap.txbytes[BASILISK_ALICECLAIM]= basilisk_swap_bobtxspend(&signedtxid,rswap.Btxfee,"aliceclaim",rswap.bobcoin,bob->wiftaddr,bob->taddr,bob->pubtype,bob->p2shtype,bob->isPoS,bob->wiftype,ctx,rswap.myprivs[0],0,redeemscript,redeemlen,userdata,len,rswap.txids[BASILISK_BOBDEPOSIT],0,0,rswap.pubkey33,0,rswap.expiration,&rswap.values[BASILISK_ALICECLAIM],0,0,rswap.bobdepositaddr,1,bob->zcash)) != 0 ) + if ( (rswap.txbytes[BASILISK_ALICECLAIM]= basilisk_swap_bobtxspend(0,&signedtxid,rswap.Btxfee,"aliceclaim",rswap.bobcoin,bob->wiftaddr,bob->taddr,bob->pubtype,bob->p2shtype,bob->isPoS,bob->wiftype,ctx,rswap.myprivs[0],0,redeemscript,redeemlen,userdata,len,rswap.txids[BASILISK_BOBDEPOSIT],0,0,rswap.pubkey33,0,rswap.expiration,&rswap.values[BASILISK_ALICECLAIM],0,0,rswap.bobdepositaddr,1,bob->zcash)) != 0 ) printf("privBn.(%s) aliceclaim.(%s)\n",bits256_str(str,rswap.privBn),rswap.txbytes[BASILISK_ALICECLAIM]); } } @@ -1042,7 +1042,7 @@ cJSON *basilisk_remember(int64_t *KMDtotals,int64_t *BTCtotals,uint32_t requesti if ( redeemlen > 0 ) { len = basilisk_swapuserdata(userdata,zero,1,rswap.myprivs[1],redeemscript,redeemlen); - if ( (rswap.txbytes[BASILISK_BOBRECLAIM]= basilisk_swap_bobtxspend(&signedtxid,rswap.Btxfee,"bobrefund",rswap.bobcoin,bob->wiftaddr,bob->taddr,bob->pubtype,bob->p2shtype,bob->isPoS,bob->wiftype,ctx,rswap.myprivs[1],0,redeemscript,redeemlen,userdata,len,rswap.txids[BASILISK_BOBPAYMENT],0,0,rswap.pubkey33,0,rswap.expiration,&rswap.values[BASILISK_BOBRECLAIM],0,0,rswap.bobpaymentaddr,1,bob->zcash)) != 0 ) + if ( (rswap.txbytes[BASILISK_BOBRECLAIM]= basilisk_swap_bobtxspend(0,&signedtxid,rswap.Btxfee,"bobrefund",rswap.bobcoin,bob->wiftaddr,bob->taddr,bob->pubtype,bob->p2shtype,bob->isPoS,bob->wiftype,ctx,rswap.myprivs[1],0,redeemscript,redeemlen,userdata,len,rswap.txids[BASILISK_BOBPAYMENT],0,0,rswap.pubkey33,0,rswap.expiration,&rswap.values[BASILISK_BOBRECLAIM],0,0,rswap.bobpaymentaddr,1,bob->zcash)) != 0 ) { int32_t z; for (z=0; z<20; z++) @@ -1073,7 +1073,7 @@ cJSON *basilisk_remember(int64_t *KMDtotals,int64_t *BTCtotals,uint32_t requesti vcalc_sha256(0,rswap.secretBn256,rswap.privBn.bytes,sizeof(rswap.privBn)); redeemlen = basilisk_swap_bobredeemscript(1,&secretstart,redeemscript,rswap.dlocktime,rswap.pubA0,rswap.pubB0,rswap.pubB1,rswap.privAm,rswap.privBn,rswap.secretAm,rswap.secretAm256,rswap.secretBn,rswap.secretBn256); len = basilisk_swapuserdata(userdata,rswap.privBn,0,rswap.myprivs[0],redeemscript,redeemlen); - if ( (rswap.txbytes[BASILISK_BOBREFUND]= basilisk_swap_bobtxspend(&signedtxid,rswap.Btxfee,"bobrefund",rswap.bobcoin,bob->wiftaddr,bob->taddr,bob->pubtype,bob->p2shtype,bob->isPoS,bob->wiftype,ctx,rswap.myprivs[0],0,redeemscript,redeemlen,userdata,len,rswap.txids[BASILISK_BOBDEPOSIT],0,0,rswap.pubkey33,1,rswap.expiration,&rswap.values[BASILISK_BOBREFUND],0,0,rswap.bobdepositaddr,1,bob->zcash)) != 0 ) + if ( (rswap.txbytes[BASILISK_BOBREFUND]= basilisk_swap_bobtxspend(0,&signedtxid,rswap.Btxfee,"bobrefund",rswap.bobcoin,bob->wiftaddr,bob->taddr,bob->pubtype,bob->p2shtype,bob->isPoS,bob->wiftype,ctx,rswap.myprivs[0],0,redeemscript,redeemlen,userdata,len,rswap.txids[BASILISK_BOBDEPOSIT],0,0,rswap.pubkey33,1,rswap.expiration,&rswap.values[BASILISK_BOBREFUND],0,0,rswap.bobdepositaddr,1,bob->zcash)) != 0 ) 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]); diff --git a/iguana/exchanges/LP_rpc.c b/iguana/exchanges/LP_rpc.c index 9b3345ab6..25f2c9b7d 100644 --- a/iguana/exchanges/LP_rpc.c +++ b/iguana/exchanges/LP_rpc.c @@ -709,6 +709,7 @@ int32_t LP_listunspent_issue(char *symbol,char *coinaddr,int32_t fullflag) if ( strcmp(coin->smartaddr,coinaddr) == 0 ) { retjson = LP_listunspent(symbol,coinaddr); + coin->numutxos = cJSON_GetArraySize(retjson); //printf("SELF_LISTUNSPENT.(%s %s)\n",symbol,coinaddr); } else if ( IAMLP == 0 ) diff --git a/iguana/exchanges/LP_transaction.c b/iguana/exchanges/LP_transaction.c index e9f140178..87b395b8a 100644 --- a/iguana/exchanges/LP_transaction.c +++ b/iguana/exchanges/LP_transaction.c @@ -603,9 +603,9 @@ int32_t iguana_signrawtransaction(void *ctx,char *symbol,uint8_t wiftaddr,uint8_ return(complete); } -char *basilisk_swap_bobtxspend(bits256 *signedtxidp,uint64_t txfee,char *name,char *symbol,uint8_t wiftaddr,uint8_t taddr,uint8_t pubtype,uint8_t p2shtype,uint8_t isPoS,uint8_t wiftype,void *ctx,bits256 privkey,bits256 *privkey2p,uint8_t *redeemscript,int32_t redeemlen,uint8_t *userdata,int32_t userdatalen,bits256 utxotxid,int32_t utxovout,char *destaddr,uint8_t *pubkey33,int32_t finalseqid,uint32_t expiration,int64_t *destamountp,uint64_t satoshis,char *changeaddr,char *vinaddr,int32_t suppress_pubkeys,int32_t zcash) +char *basilisk_swap_bobtxspend(int32_t dustcombine,bits256 *signedtxidp,uint64_t txfee,char *name,char *symbol,uint8_t wiftaddr,uint8_t taddr,uint8_t pubtype,uint8_t p2shtype,uint8_t isPoS,uint8_t wiftype,void *ctx,bits256 privkey,bits256 *privkey2p,uint8_t *redeemscript,int32_t redeemlen,uint8_t *userdata,int32_t userdatalen,bits256 utxotxid,int32_t utxovout,char *destaddr,uint8_t *pubkey33,int32_t finalseqid,uint32_t expiration,int64_t *destamountp,uint64_t satoshis,char *changeaddr,char *vinaddr,int32_t suppress_pubkeys,int32_t zcash) { - char *rawtxbytes=0,*signedtx=0,str[65],tmpaddr[64],hexstr[999],wifstr[128],_destaddr[64]; uint8_t spendscript[512],addrtype,rmd160[20]; cJSON *txobj,*vins,*obj,*vouts,*item,*privkeys; int32_t completed,spendlen,n,ignore_cltverr=1; struct vin_info V[2]; uint32_t timestamp,locktime = 0,sequenceid = 0xffffffff * finalseqid; bits256 txid; uint64_t value=0,change = 0; struct iguana_msgtx msgtx; struct iguana_info *coin; + char *rawtxbytes=0,*signedtx=0,str[65],tmpaddr[64],hexstr[999],wifstr[128],_destaddr[64]; uint8_t spendscript[512],addrtype,rmd160[20]; cJSON *items[2],*txobj,*vins,*obj,*vouts,*item,*privkeys; int32_t i,completed,spendlen,n,ignore_cltverr=1; struct vin_info V[8]; uint32_t timestamp,locktime = 0,sequenceid = 0xffffffff * finalseqid; bits256 txid; uint64_t value=0,change = 0; struct iguana_msgtx msgtx; struct iguana_info *coin; LP_mark_spent(symbol,utxotxid,utxovout); if ( txfee > 0 && txfee < 10000 ) txfee = 10000; @@ -617,9 +617,9 @@ char *basilisk_swap_bobtxspend(bits256 *signedtxidp,uint64_t txfee,char *name,ch if ( redeemlen < 0 ) return(0); value = 0; -#ifndef BASILISK_DISABLESENDTX if ( (coin= LP_coinfind(symbol)) != 0 ) { +#ifndef BASILISK_DISABLESENDTX if ( (txobj= LP_gettx(symbol,utxotxid)) != 0 ) { if ( (vouts= jarray(&n,txobj,"vout")) != 0 && utxovout < n ) @@ -629,16 +629,30 @@ char *basilisk_swap_bobtxspend(bits256 *signedtxidp,uint64_t txfee,char *name,ch //printf("value in vout.%d %.8f (%s)\n",vout,dstr(value),jprint(txobj,0)); } free_json(txobj); - //if ( value != 0 ) - // gettxout } else printf("cant gettx\n"); if ( value == 0 ) { printf("basilisk_swap_bobtxspend.%s %s utxo.(%s).v%d already spent or doesnt exist\n",name,symbol,bits256_str(str,utxotxid),utxovout); return(0); } - } + if ( coin->electrum != 0 || coin->numutxos < LP_MINDESIRED_UTXOS ) + dustcombine = 0; + else if ( coin->numutxos >= LP_MINDESIRED_UTXOS ) + dustcombine = 2; + if ( dustcombine != 0 ) + { + uint64_t more; + if ( privkey2p != 0 ) + dustcombine = 1; + memset(items,0,sizeof(items)); + more = LP_dustcombine(items,dustcombine,coin); + if ( more != 0 ) + printf("%s dustcombine.%d -> %.8f (%s) + (%s)\n",coin->symbol,dustcombine,dstr(more),items[0] != 0 ? jprint(items[0],0) : "",items[1] != 0 ? jprint(items[1],0) : ""); + value += more; + dustcombine = (items[0] != 0) + (items[1] != 0); + } #endif + } if ( satoshis != 0 ) { if ( value < satoshis+txfee ) @@ -696,6 +710,13 @@ char *basilisk_swap_bobtxspend(bits256 *signedtxidp,uint64_t txfee,char *name,ch jaddistr(privkeys,wifstr); V[0].suppress_pubkeys = suppress_pubkeys; V[0].ignore_cltverr = ignore_cltverr; + for (i=0; iI.signedtxid,iter == 0 ? txfee : newtxfee,str,coin->symbol,coin->wiftaddr,coin->taddr,coin->pubtype,coin->p2shtype,coin->isPoS,coin->wiftype,ctx,privkey,0,0,0,0,0,rawtx->utxotxid,rawtx->utxovout,rawtx->I.destaddr,pubkey33,1,0,&destamount,rawtx->I.amount,changeaddr,vinaddr,rawtx->I.suppress_pubkeys,coin->zcash)) != 0 ) + if ( (signedtx= basilisk_swap_bobtxspend(1,&rawtx->I.signedtxid,iter == 0 ? txfee : newtxfee,str,coin->symbol,coin->wiftaddr,coin->taddr,coin->pubtype,coin->p2shtype,coin->isPoS,coin->wiftype,ctx,privkey,0,0,0,0,0,rawtx->utxotxid,rawtx->utxovout,rawtx->I.destaddr,pubkey33,1,0,&destamount,rawtx->I.amount,changeaddr,vinaddr,rawtx->I.suppress_pubkeys,coin->zcash)) != 0 ) { rawtx->I.datalen = (int32_t)strlen(signedtx) >> 1; if ( rawtx->I.datalen <= sizeof(rawtx->txbytes) ) @@ -1148,7 +1172,7 @@ int32_t basilisk_rawtx_sign(char *symbol,uint8_t wiftaddr,uint8_t taddr,uint8_t } for (iter=0; iter<2; iter++) { - if ( (signedtx= basilisk_swap_bobtxspend(&dest->I.signedtxid,iter == 0 ? txfee : newtxfee,rawtx->name,symbol,wiftaddr,taddr,pubtype,p2shtype,isPoS,wiftype,swap->ctx,privkey,privkey2,rawtx->redeemscript,rawtx->I.redeemlen,userdata,userdatalen,dest->utxotxid,dest->utxovout,dest->I.destaddr,rawtx->I.pubkey33,1,0,&destamount,rawtx->I.amount,changeaddr,vinaddr,dest->I.suppress_pubkeys,zcash)) != 0 ) + if ( (signedtx= basilisk_swap_bobtxspend(0,&dest->I.signedtxid,iter == 0 ? txfee : newtxfee,rawtx->name,symbol,wiftaddr,taddr,pubtype,p2shtype,isPoS,wiftype,swap->ctx,privkey,privkey2,rawtx->redeemscript,rawtx->I.redeemlen,userdata,userdatalen,dest->utxotxid,dest->utxovout,dest->I.destaddr,rawtx->I.pubkey33,1,0,&destamount,rawtx->I.amount,changeaddr,vinaddr,dest->I.suppress_pubkeys,zcash)) != 0 ) { dest->I.datalen = (int32_t)strlen(signedtx) >> 1; if ( dest->I.datalen <= sizeof(dest->txbytes) ) @@ -1208,7 +1232,7 @@ char *basilisk_swap_Aspend(char *name,char *symbol,uint64_t Atxfee,uint8_t wifta txfee = LP_MIN_TXFEE; } //txfee = LP_txfee(symbol); - signedtx = basilisk_swap_bobtxspend(&signedtxid,txfee,name,symbol,wiftaddr,taddr,pubtype,p2shtype,isPoS,wiftype,ctx,privAm,&privBn,redeemscript,redeemlen,0,0,utxotxid,utxovout,0,pubkey33,1,expiration,destamountp,0,0,vinaddr,1,zcash); + signedtx = basilisk_swap_bobtxspend(0,&signedtxid,txfee,name,symbol,wiftaddr,taddr,pubtype,p2shtype,isPoS,wiftype,ctx,privAm,&privBn,redeemscript,redeemlen,0,0,utxotxid,utxovout,0,pubkey33,1,expiration,destamountp,0,0,vinaddr,1,zcash); LP_mark_spent(symbol,utxotxid,utxovout); } return(signedtx); diff --git a/iguana/exchanges/LP_utxo.c b/iguana/exchanges/LP_utxo.c index 30f6a0ab7..9c226160d 100644 --- a/iguana/exchanges/LP_utxo.c +++ b/iguana/exchanges/LP_utxo.c @@ -957,6 +957,58 @@ int32_t LP_inventory_prevent(int32_t iambob,char *symbol,bits256 txid,int32_t vo return(0); } +cJSON *LP_dustcombine_item(struct LP_address_utxo *up) +{ + cJSON *item = cJSON_CreateObject(); + jaddbits256(item,"txid",up->U.txid); + jaddnum(item,"vout",up->U.vout); + return(item); +} + +uint64_t LP_dustcombine(cJSON *items[2],int32_t dustcombine,struct iguana_info *coin) +{ + struct LP_address *ap=0; struct LP_address_utxo *up,*tmp,*min0,*min1; cJSON *txobj; + if ( coin == 0 || coin->electrum != 0 || dustcombine <= 0 || dustcombine > 2 ) + return(0); + min1 = min0 = 0; + if ( (ap= _LP_addressfind(coin,coin->smartaddr)) != 0 ) + { + DL_FOREACH_SAFE(ap->utxos,up,tmp) + { + if ( up->spendheight <= 0 && up->U.height > 0 && up->U.value != 0 ) + { + if ( (txobj= LP_gettxout(coin->symbol,coin->smartaddr,up->U.txid,up->U.vout)) == 0 ) + up->spendheight = 1; + else + { + free_json(txobj); + if ( LP_inventory_prevent(0,coin->symbol,up->U.txid,up->U.vout) == 0 && LP_inventory_prevent(1,coin->symbol,up->U.txid,up->U.vout) == 0 ) + { + if ( min1 == 0 || up->U.value < min1->U.value ) + { + if ( min0 == 0 || up->U.value < min0->U.value ) + { + min1 = min0; + min0 = up; + } else min1 = up; + } + } + } + } + } + } + if ( min0 != 0 ) + { + items[0] = LP_dustcombine_item(min0); + if ( dustcombine == 2 && min1 != 0 ) + { + items[1] = LP_dustcombine_item(min1); + return(min0->U.value + min1->U.value); + } else return(min0->U.value); + } + return(0); +} + int32_t LP_undospends(struct iguana_info *coin,int32_t lastheight) { int32_t i,ht,num = 0; struct LP_transaction *tx,*tmp; diff --git a/iguana/exchanges/LP_utxos.c b/iguana/exchanges/LP_utxos.c index 590ebcb30..6425637e8 100644 --- a/iguana/exchanges/LP_utxos.c +++ b/iguana/exchanges/LP_utxos.c @@ -512,6 +512,7 @@ int32_t LP_privkey_init(int32_t mypubsock,struct iguana_info *coin,bits256 mypri txfee = LP_txfeecalc(coin,0,0); if ( is_cJSON_Array(array) != 0 && (n= cJSON_GetArraySize(array)) > 0 ) { + coin->numutxos = n; //printf("LP_privkey_init %s %s\n",coin->symbol,jprint(array,0)); for (iambob=0; iambob<=1; iambob++) { diff --git a/iguana/exchanges/stats.c b/iguana/exchanges/stats.c index 2cc747ae0..e56227223 100644 --- a/iguana/exchanges/stats.c +++ b/iguana/exchanges/stats.c @@ -598,7 +598,7 @@ void LP_rpc_processreq(void *_ptr) char filetype[128],content_type[128]; int32_t recvlen,flag,postflag=0,contentlen,remains,sock,numsent,jsonflag=0,hdrsize,len; char helpname[512],remoteaddr[64],*buf,*retstr,*space,*jsonbuf; struct rpcrequest_info *req = _ptr; - uint32_t ipbits,i,size = 32*IGUANA_MAXPACKETSIZE + 512; + uint32_t ipbits,i,size = IGUANA_MAXPACKETSIZE + 512; ipbits = req->ipbits;; expand_ipbits(remoteaddr,ipbits); sock = req->sock; From 5179fa01001d53a025097b0cc235f43844f24c46 Mon Sep 17 00:00:00 2001 From: jl777 Date: Mon, 6 Nov 2017 21:31:13 +0200 Subject: [PATCH 0280/1664] Test --- iguana/exchanges/LP_utxo.c | 1 + 1 file changed, 1 insertion(+) diff --git a/iguana/exchanges/LP_utxo.c b/iguana/exchanges/LP_utxo.c index 9c226160d..760641da8 100644 --- a/iguana/exchanges/LP_utxo.c +++ b/iguana/exchanges/LP_utxo.c @@ -970,6 +970,7 @@ uint64_t LP_dustcombine(cJSON *items[2],int32_t dustcombine,struct iguana_info * struct LP_address *ap=0; struct LP_address_utxo *up,*tmp,*min0,*min1; cJSON *txobj; if ( coin == 0 || coin->electrum != 0 || dustcombine <= 0 || dustcombine > 2 ) return(0); +return(0); min1 = min0 = 0; if ( (ap= _LP_addressfind(coin,coin->smartaddr)) != 0 ) { From c1654d3710230608a8f1401c993ce3d2a3faabfb Mon Sep 17 00:00:00 2001 From: jl777 Date: Mon, 6 Nov 2017 22:02:30 +0200 Subject: [PATCH 0281/1664] Test --- iguana/exchanges/LP_transaction.c | 4 ++++ iguana/exchanges/LP_utxo.c | 2 +- 2 files changed, 5 insertions(+), 1 deletion(-) diff --git a/iguana/exchanges/LP_transaction.c b/iguana/exchanges/LP_transaction.c index 87b395b8a..fce01d038 100644 --- a/iguana/exchanges/LP_transaction.c +++ b/iguana/exchanges/LP_transaction.c @@ -647,7 +647,11 @@ char *basilisk_swap_bobtxspend(int32_t dustcombine,bits256 *signedtxidp,uint64_t memset(items,0,sizeof(items)); more = LP_dustcombine(items,dustcombine,coin); if ( more != 0 ) + { printf("%s dustcombine.%d -> %.8f (%s) + (%s)\n",coin->symbol,dustcombine,dstr(more),items[0] != 0 ? jprint(items[0],0) : "",items[1] != 0 ? jprint(items[1],0) : ""); +memset(items,0,sizeof(items)); +more = 0 ; + } value += more; dustcombine = (items[0] != 0) + (items[1] != 0); } diff --git a/iguana/exchanges/LP_utxo.c b/iguana/exchanges/LP_utxo.c index 760641da8..a1e6ce758 100644 --- a/iguana/exchanges/LP_utxo.c +++ b/iguana/exchanges/LP_utxo.c @@ -970,8 +970,8 @@ uint64_t LP_dustcombine(cJSON *items[2],int32_t dustcombine,struct iguana_info * struct LP_address *ap=0; struct LP_address_utxo *up,*tmp,*min0,*min1; cJSON *txobj; if ( coin == 0 || coin->electrum != 0 || dustcombine <= 0 || dustcombine > 2 ) return(0); -return(0); min1 = min0 = 0; + printf("LP_dustcombine\n"); if ( (ap= _LP_addressfind(coin,coin->smartaddr)) != 0 ) { DL_FOREACH_SAFE(ap->utxos,up,tmp) From d7a9dc306e7d23dca5ce0f58e1472ac621f40037 Mon Sep 17 00:00:00 2001 From: jl777 Date: Mon, 6 Nov 2017 22:08:45 +0200 Subject: [PATCH 0282/1664] Test --- iguana/exchanges/LP_include.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/iguana/exchanges/LP_include.h b/iguana/exchanges/LP_include.h index 70dc2248b..cd39393ff 100644 --- a/iguana/exchanges/LP_include.h +++ b/iguana/exchanges/LP_include.h @@ -47,8 +47,8 @@ void emscripten_usleep(int32_t x); // returns immediate, no sense for sleeping #define LP_MIN_PEERS 8 #define LP_MAX_PEERS 32 -#define LP_MAXDESIRED_UTXOS 128 -#define LP_MINDESIRED_UTXOS 64 +#define LP_MAXDESIRED_UTXOS 8 +#define LP_MINDESIRED_UTXOS 16 // RTmetrics #define LP_RTMETRICS_TOPGROUP 1.01 From 8308444e64f037da3762c71ef8ad3a78bc2b7b5a Mon Sep 17 00:00:00 2001 From: jl777 Date: Mon, 6 Nov 2017 22:21:54 +0200 Subject: [PATCH 0283/1664] Activate dust combine --- iguana/exchanges/LP_transaction.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/iguana/exchanges/LP_transaction.c b/iguana/exchanges/LP_transaction.c index fce01d038..0c55bc5fd 100644 --- a/iguana/exchanges/LP_transaction.c +++ b/iguana/exchanges/LP_transaction.c @@ -649,8 +649,8 @@ char *basilisk_swap_bobtxspend(int32_t dustcombine,bits256 *signedtxidp,uint64_t if ( more != 0 ) { printf("%s dustcombine.%d -> %.8f (%s) + (%s)\n",coin->symbol,dustcombine,dstr(more),items[0] != 0 ? jprint(items[0],0) : "",items[1] != 0 ? jprint(items[1],0) : ""); -memset(items,0,sizeof(items)); -more = 0 ; +//memset(items,0,sizeof(items)); +//more = 0 ; } value += more; dustcombine = (items[0] != 0) + (items[1] != 0); From 7d3bff1544286b25dcf1e108184b3f741c3f3e8d Mon Sep 17 00:00:00 2001 From: jl777 Date: Mon, 6 Nov 2017 22:42:17 +0200 Subject: [PATCH 0284/1664] Test --- iguana/exchanges/LP_transaction.c | 1 + iguana/exchanges/LP_utxo.c | 4 +--- 2 files changed, 2 insertions(+), 3 deletions(-) diff --git a/iguana/exchanges/LP_transaction.c b/iguana/exchanges/LP_transaction.c index 0c55bc5fd..7a8ec872b 100644 --- a/iguana/exchanges/LP_transaction.c +++ b/iguana/exchanges/LP_transaction.c @@ -720,6 +720,7 @@ char *basilisk_swap_bobtxspend(int32_t dustcombine,bits256 *signedtxidp,uint64_t V[i+1].suppress_pubkeys = 0; V[i+1].ignore_cltverr = 0; V[i+1].N = V[i+1].M = 1; + jaddistr(privkeys,wifstr); } if ( redeemlen != 0 ) memcpy(V[0].p2shscript,redeemscript,redeemlen), V[0].p2shlen = redeemlen; diff --git a/iguana/exchanges/LP_utxo.c b/iguana/exchanges/LP_utxo.c index a1e6ce758..2ccef6517 100644 --- a/iguana/exchanges/LP_utxo.c +++ b/iguana/exchanges/LP_utxo.c @@ -1061,9 +1061,7 @@ void LP_unspents_load(char *symbol,char *addr) if ( (retjson= cJSON_Parse(arraystr)) != 0 ) { printf("PROCESS UNSPENTS %s\n",arraystr); - if ( electrum_process_array(coin,coin->electrum,coin->smartaddr,retjson,1) == 0 ) - printf("error electrum_process_array\n"); - else printf("processed %s\n",arraystr); + electrum_process_array(coin,coin->electrum,coin->smartaddr,retjson,1); free_json(retjson); } free(arraystr); From c97b78bf89b786d70b052aa1cf1db4ea67c80ea4 Mon Sep 17 00:00:00 2001 From: jl777 Date: Mon, 6 Nov 2017 22:51:15 +0200 Subject: [PATCH 0285/1664] Test --- iguana/exchanges/LP_transaction.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/iguana/exchanges/LP_transaction.c b/iguana/exchanges/LP_transaction.c index 7a8ec872b..ec1f2549e 100644 --- a/iguana/exchanges/LP_transaction.c +++ b/iguana/exchanges/LP_transaction.c @@ -649,8 +649,8 @@ char *basilisk_swap_bobtxspend(int32_t dustcombine,bits256 *signedtxidp,uint64_t if ( more != 0 ) { printf("%s dustcombine.%d -> %.8f (%s) + (%s)\n",coin->symbol,dustcombine,dstr(more),items[0] != 0 ? jprint(items[0],0) : "",items[1] != 0 ? jprint(items[1],0) : ""); -//memset(items,0,sizeof(items)); -//more = 0 ; +memset(items,0,sizeof(items)); +more = 0 ; } value += more; dustcombine = (items[0] != 0) + (items[1] != 0); From aec5287830934d654b29ca4a9c84b5b313553c97 Mon Sep 17 00:00:00 2001 From: jl777 Date: Tue, 7 Nov 2017 02:28:39 +0200 Subject: [PATCH 0286/1664] Disable disabling electrum --- iguana/exchanges/LP_socket.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/iguana/exchanges/LP_socket.c b/iguana/exchanges/LP_socket.c index dafac13b2..28b7d2e16 100644 --- a/iguana/exchanges/LP_socket.c +++ b/iguana/exchanges/LP_socket.c @@ -1024,7 +1024,8 @@ cJSON *LP_electrumserver(struct iguana_info *coin,char *ipaddr,uint16_t port) struct electrum_info *ep; int32_t already; cJSON *retjson; if ( ipaddr == 0 || ipaddr[0] == 0 || port == 0 ) { - coin->electrum = 0; + //coin->electrum = 0; + printf("would have disabled %s electrum here\n",coin->symbol); return(cJSON_Parse("{\"result\":\"success\",\"status\":\"electrum mode disabled, now in native coin mode\"}")); } retjson = cJSON_CreateObject(); From 26b6ba84ba1a1a767250154d88d73dff33937ec7 Mon Sep 17 00:00:00 2001 From: jl777 Date: Tue, 7 Nov 2017 03:38:25 +0200 Subject: [PATCH 0287/1664] Fixed price --- iguana/exchanges/LP_portfolio.c | 13 +++++++++++-- iguana/exchanges/LP_prices.c | 1 + 2 files changed, 12 insertions(+), 2 deletions(-) diff --git a/iguana/exchanges/LP_portfolio.c b/iguana/exchanges/LP_portfolio.c index 5c94b9695..62b50d9d2 100644 --- a/iguana/exchanges/LP_portfolio.c +++ b/iguana/exchanges/LP_portfolio.c @@ -222,7 +222,7 @@ struct LP_autoprice_ref int32_t LP_autoprice(char *base,char *rel,cJSON *argjson) { //curl --url "http://127.0.0.1:7783" --data "{\"userpass\":\"$userpass\",\"method\":\"autoprice\",\"base\":\"MNZ\",\"rel\":\"KMD\",\"offset\":0.1,\"refbase\":\"KMD\",\refrel\":\"BTC\",\"factor\":15000,\"margin\":0.01}" - struct LP_priceinfo *basepp,*relpp; int32_t i; char *refbase,*refrel; double minprice,margin,offset,factor; + struct LP_priceinfo *basepp,*relpp; int32_t i; char *refbase,*refrel; double minprice,margin,offset,factor,fixedprice; //printf("autoprice.(%s %s) %s\n",base,rel,jprint(argjson,0)); if ( (basepp= LP_priceinfofind(base)) != 0 && (relpp= LP_priceinfofind(rel)) != 0 ) { @@ -232,6 +232,8 @@ int32_t LP_autoprice(char *base,char *rel,cJSON *argjson) margin = jdouble(argjson,"margin"); offset = jdouble(argjson,"offset"); factor = jdouble(argjson,"factor"); + fixedprice = jdouble(argjson,"fixed"); + basepp->fixedprices[relpp->ind] = fixedprice; basepp->minprices[relpp->ind] = minprice; basepp->margins[relpp->ind] = margin; basepp->offsets[relpp->ind] = offset; @@ -267,9 +269,16 @@ int32_t LP_autoprice(char *base,char *rel,cJSON *argjson) void LP_autopriceset(void *ctx,int32_t dir,struct LP_priceinfo *basepp,struct LP_priceinfo *relpp,double price,char *refbase,char *refrel) { static uint32_t lasttime; - double margin,minprice,newprice,oppomargin,factor,offset; double bid,ask; int32_t changed; + double margin,minprice,newprice,oppomargin,fixedprice,factor,offset; double bid,ask; int32_t changed; margin = basepp->margins[relpp->ind]; oppomargin = relpp->margins[basepp->ind]; + if ( (fixedprice= relpp->fixedprices[basepp->ind]) > SMALLVAL ) + { + LP_mypriceset(&changed,relpp->symbol,basepp->symbol,fixedprice); + printf("autoprice FIXED %s/%s <- %.8f\n",basepp->symbol,relpp->symbol,fixedprice); + LP_pricepings(ctx,LP_myipaddr,LP_mypubsock,relpp->symbol,basepp->symbol,fixedprice); + return; + } if ( margin != 0. || oppomargin != 0. ) { offset = basepp->offsets[relpp->ind]; diff --git a/iguana/exchanges/LP_prices.c b/iguana/exchanges/LP_prices.c index 84a699410..ae78a770d 100644 --- a/iguana/exchanges/LP_prices.c +++ b/iguana/exchanges/LP_prices.c @@ -29,6 +29,7 @@ struct LP_priceinfo double relvals[LP_MAXPRICEINFOS]; double myprices[LP_MAXPRICEINFOS]; double minprices[LP_MAXPRICEINFOS]; // autoprice + double fixedprices[LP_MAXPRICEINFOS]; // fixedprices double margins[LP_MAXPRICEINFOS]; double offsets[LP_MAXPRICEINFOS]; double factors[LP_MAXPRICEINFOS]; From 60cc6c199f4448955cb7e3bc155fb253c348a18c Mon Sep 17 00:00:00 2001 From: jl777 Date: Tue, 7 Nov 2017 11:24:33 +0200 Subject: [PATCH 0288/1664] QTUM --- iguana/exchanges/coins | 2 +- iguana/exchanges/coins.json | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/iguana/exchanges/coins b/iguana/exchanges/coins index d81e18c4d..9b5789e13 100644 --- a/iguana/exchanges/coins +++ b/iguana/exchanges/coins @@ -1,4 +1,4 @@ -export coins="[{\"coin\":\"PURA\",\"name\":\"pura\",\"rpcport\":55555,\"pubtype\":55,\"p2shtype\":16,\"wiftype\":150,\"txfee\":10000}, {\"coin\":\"DSR\",\"name\":\"desire\",\"confpath\":\"${HOME#}/.desirecore/desire.conf\",\"rpcport\":9918,\"pubtype\":30,\"p2shtype\":16,\"wiftype\":204,\"txfee\":10000}, {\"coin\":\"MNZ\",\"asset\":\"MNZ\",\"rpcport\":14337},{\"coin\":\"BTCZ\",\"name\":\"bitcoinz\",\"rpcport\":1979,\"taddr\":28,\"pubtype\":184,\"p2shtype\":189,\"wiftype\":128,\"txfee\":10000}, {\"coin\":\"MAGA\",\"name\":\"magacoin\",\"rpcport\":5332,\"pubtype\":23,\"p2shtype\":50,\"wiftype\":176,\"txfee\":100000}, {\"coin\":\"BSD\",\"name\":\"bitsend\",\"rpcport\":8800,\"pubtype\":102,\"p2shtype\":5,\"wiftype\":204,\"txfee\":10000}, {\"coin\":\"IOP\",\"name\":\"IoP\",\"rpcport\":8337,\"pubtype\":117,\"p2shtype\":174,\"wiftype\":49,\"txfee\":10000}, {\"coin\":\"BLOCK\",\"name\":\"blocknetdx\",\"rpcport\":41414,\"pubtype\":26,\"p2shtype\":28,\"wiftype\":154,\"txfee\":10000}, {\"coin\":\"CHIPS\", \"name\": \"chips\", \"rpcport\":57776,\"pubtype\":60, \"p2shtype\":85, \"wiftype\":188, \"txfee\":10000}, {\"coin\":\"888\",\"name\":\"octocoin\",\"rpcport\":22888,\"pubtype\":18,\"p2shtype\":5,\"wiftype\":176,\"txfee\":2000000}, {\"coin\":\"ARG\",\"name\":\"argentum\",\"rpcport\":13581,\"pubtype\":23,\"p2shtype\":5,\"wiftype\":151,\"txfee\":50000}, {\"coin\":\"GLT\",\"name\":\"globaltoken\",\"rpcport\":9320,\"pubtype\":38,\"p2shtype\":5,\"wiftype\":166,\"txfee\":10000}, {\"coin\":\"ZER\",\"name\":\"zero\",\"rpcport\":23801,\"taddr\":28,\"pubtype\":184,\"p2shtype\":189,\"wiftype\":128,\"txfee\":1000}, {\"coin\":\"HODLC\",\"name\":\"hodlcoin\",\"rpcport\":11989,\"pubtype\":40,\"p2shtype\":5,\"wiftype\":168,\"txfee\":5000}, {\"coin\":\"UIS\",\"name\":\"unitus\",\"rpcport\":50604,\"pubtype\":68,\"p2shtype\":10,\"wiftype\":132,\"txfee\":2000000}, {\"coin\":\"CRW\",\"name\":\"crown\",\"rpcport\":9341,\"pubtype\":0,\"p2shtype\":5,\"wiftype\":128,\"txfee\":10000}, {\"coin\":\"HUC\",\"name\":\"huntercoin\",\"rpcport\":8399,\"pubtype\":40,\"p2shtype\":13,\"wiftype\":168,\"txfee\":100000}, {\"coin\":\"PIVX\",\"name\":\"pivx\",\"rpcport\":51473,\"pubtype\":30,\"p2shtype\":13,\"wiftype\":212,\"txfee\":10000}, {\"coin\":\"BDL\",\"name\":\"bitdeal\",\"rpcport\":9332,\"pubtype\":38,\"p2shtype\":5,\"wiftype\":176,\"txfee\":100000}, {\"coin\":\"ARC\",\"name\":\"arcticcoin\",\"confpath\":\"${HOME#}/.arcticcore/arcticcoin.conf\",\"rpcport\":7208,\"pubtype\":23,\"p2shtype\":8,\"wiftype\":176,\"txfee\":10000}, {\"coin\":\"ZCL\",\"name\":\"zclassic\",\"rpcport\":8023,\"taddr\":28,\"pubtype\":184,\"p2shtype\":189,\"wiftype\":128,\"txfee\":1000}, {\"coin\":\"VIA\",\"name\":\"viacoin\",\"rpcport\":5222,\"pubtype\":71,\"p2shtype\":33,\"wiftype\":199,\"txfee\":100000}, {\"coin\":\"ERC\",\"name\":\"europecoin\",\"rpcport\":11989,\"pubtype\":33,\"p2shtype\":5,\"wiftype\":168,\"txfee\":10000},{\"coin\":\"FAIR\",\"name\":\"faircoin\",\"confpath\":\"${HOME#}/.faircoin2/faircoin.conf\",\"rpcport\":40405,\"pubtype\":95,\"p2shtype\":36,\"wiftype\":223,\"txfee\":1000000}, {\"coin\":\"FLO\",\"name\":\"florincoin\",\"rpcport\":7313,\"pubtype\":35,\"p2shtype\":8,\"wiftype\":176,\"txfee\":100000}, {\"coin\":\"SXC\",\"name\":\"sexcoin\",\"rpcport\":9561,\"pubtype\":62,\"p2shtype\":5,\"wiftype\":190,\"txfee\":100000}, {\"coin\":\"CREA\",\"name\":\"creativecoin\",\"rpcport\":17711,\"pubtype\":28,\"p2shtype\":5,\"wiftype\":176,\"txfee\":100000}, {\"coin\":\"TRC\",\"name\":\"terracoin\",\"confpath\":\"${HOME#}/.terracoincore/terracoin.conf\",\"rpcport\":13332,\"pubtype\":0,\"p2shtype\":5,\"wiftype\":128,\"txfee\":10000}, {\"coin\":\"BTA\",\"name\":\"bata\",\"rpcport\":5493,\"pubtype\":25,\"p2shtype\":5,\"wiftype\":188,\"txfee\":100000}, {\"coin\":\"SMC\",\"name\":\"smartcoin\",\"rpcport\":58583,\"pubtype\":63,\"p2shtype\":5,\"wiftype\":191,\"txfee\":1000000}, {\"coin\":\"NMC\",\"name\":\"namecoin\",\"rpcport\":8336,\"pubtype\":52,\"p2shtype\":13,\"wiftype\":180,\"txfee\":100000}, {\"coin\":\"NAV\",\"name\":\"navcoin\",\"isPoS\":1,\"confpath\":\"${HOME#}/.navcoin4/navcoin.conf\",\"rpcport\":44444,\"pubtype\":53,\"p2shtype\":85,\"wiftype\":150,\"txfee\":10000}, {\"coin\":\"MOON\",\"name\":\"Mooncoin\",\"rpcport\":44663,\"pubtype\":3,\"p2shtype\":22,\"wiftype\":131,\"txfee\":100000}, {\"coin\":\"EMC2\",\"name\":\"einsteinium\",\"rpcport\":41879,\"pubtype\":33,\"p2shtype\":5,\"wiftype\":176,\"txfee\":100000},{\"coin\":\"SYS\",\"name\":\"syscoin\",\"rpcport\":8370,\"pubtype\":0,\"p2shtype\":5,\"wiftype\":128,\"txfee\":1000}, {\"coin\":\"I0C\",\"name\":\"i0coin\",\"rpcport\":7332,\"pubtype\":105,\"p2shtype\":5,\"wiftype\":128,\"txfee\":1000}, {\"coin\":\"DASH\",\"confpath\":\"${HOME#}/.dashcore/dash.conf\",\"name\":\"dashcore\",\"rpcport\":9998,\"pubtype\":76,\"p2shtype\":16,\"wiftype\":204,\"txfee\":10000}, {\"coin\":\"STRAT\", \"name\": \"stratis\", \"active\":0, \"rpcport\":16174,\"pubtype\":63, \"p2shtype\":125, \"wiftype\":191, \"txfee\":10000}, {\"confpath\":\"${HOME#}/.muecore/mue.conf\",\"coin\":\"MUE\",\"name\":\"muecore\",\"rpcport\":29683,\"pubtype\":16,\"p2shtype\":76,\"wiftype\":126,\"txfee\":10000}, {\"coin\":\"MONA\",\"name\":\"monacoin\",\"rpcport\":9402,\"pubtype\":50,\"p2shtype\":5,\"wiftype\":176,\"txfee\":100000},{\"coin\":\"XMY\",\"name\":\"myriadcoin\",\"rpcport\":10889,\"pubtype\":50,\"p2shtype\":9,\"wiftype\":178,\"txfee\":5000}, {\"coin\":\"MAC\",\"name\":\"machinecoin\",\"rpcport\":40332,\"pubtype\":50,\"p2shtype\":5,\"wiftype\":178,\"txfee\":50000}, {\"coin\":\"BTX\",\"name\":\"bitcore\",\"rpcport\":8556,\"pubtype\":0,\"p2shtype\":5,\"wiftype\":128,\"txfee\":50000}, {\"coin\":\"XRE\",\"name\":\"revolvercoin\",\"rpcport\":8775,\"pubtype\":0,\"p2shtype\":5,\"wiftype\":128,\"txfee\":1000}, {\"coin\":\"LBC\",\"name\":\"lbrycrd\",\"rpcport\":9245,\"pubtype\":85,\"p2shtype\":122,\"wiftype\":28,\"txfee\":1000}, {\"coin\":\"SIB\",\"name\":\"sibcoin\",\"rpcport\":1944,\"pubtype\":63,\"p2shtype\":40,\"wiftype\":128,\"txfee\":10000}, {\"coin\":\"VTC\", \"name\":\"vertcoin\", \"rpcport\":5888, \"pubtype\":71, \"p2shtype\":5, \"wiftype\":128, \"txfee\":100000 }, {\"coin\":\"REVS\",\"active\":0, \"asset\":\"REVS\",\"rpcport\":10196}, {\"coin\":\"JUMBLR\",\"active\":0, \"asset\":\"JUMBLR\",\"rpcport\":15106}, {\"coin\":\"DOGE\",\"name\":\"dogecoin\",\"rpcport\":22555,\"pubtype\":30,\"p2shtype\":22,\"wiftype\":158,\"txfee\":100000000}, {\"coin\":\"HUSH\",\"name\":\"hush\",\"rpcport\":8822,\"taddr\":28,\"pubtype\":184,\"p2shtype\":189,\"wiftype\":128,\"txfee\":1000 }, {\"active\":0,\"coin\":\"ZEC\",\"name\":\"zcash\",\"rpcport\":8232,\"taddr\":28,\"pubtype\":184,\"p2shtype\":189,\"wiftype\":128,\"txfee\":10000 }, {\"coin\":\"DGB\",\"name\":\"digibyte\",\"rpcport\":14022,\"pubtype\":30,\"p2shtype\":5,\"wiftype\":128,\"txfee\":100000}, {\"coin\":\"ZET\", \"name\":\"zetacoin\", \"pubtype\":80, \"p2shtype\":9,\"rpcport\":8332, \"wiftype\":224, \"txfee\":10000}, {\"coin\":\"GAME\", \"rpcport\":40001, \"name\":\"gamecredits\", \"pubtype\":38, \"p2shtype\":5, \"wiftype\":166, \"txfee\":100000}, {\"coin\":\"LTC\", \"name\":\"litecoin\", \"rpcport\":9332, \"pubtype\":48, \"p2shtype\":5, \"wiftype\":176, \"txfee\":100000 }, {\"coin\":\"SUPERNET\",\"asset\":\"SUPERNET\",\"rpcport\":11341}, {\"coin\":\"WLC\",\"asset\":\"WLC\",\"rpcport\":12167}, {\"coin\":\"PANGEA\",\"asset\":\"PANGEA\",\"rpcport\":14068}, {\"coin\":\"DEX\",\"asset\":\"DEX\",\"rpcport\":11890}, {\"coin\":\"BET\",\"asset\":\"BET\",\"rpcport\":14250}, {\"coin\":\"CRYPTO\",\"asset\":\"CRYPTO\",\"rpcport\":8516}, {\"coin\":\"HODL\",\"asset\":\"HODL\",\"rpcport\":14431}, {\"coin\":\"SHARK\",\"asset\":\"SHARK\",\"rpcport\":10114}, {\"coin\":\"BOTS\",\"asset\":\"BOTS\",\"rpcport\":11964}, {\"coin\":\"MGW\",\"asset\":\"MGW\",\"rpcport\":12386}, {\"coin\":\"COQUI\",\"asset\":\"COQUI\",\"rpcport\":14276}, {\"coin\":\"KV\",\"asset\":\"KV\",\"rpcport\":8299}, {\"coin\":\"CEAL\",\"asset\":\"CEAL\",\"rpcport\":11116}, {\"coin\":\"MESH\",\"asset\":\"MESH\",\"rpcport\":9455}]" +export coins="[{\"coin\":\"QTUM\",\"name\":\"qtum\",\"rpcport\":3889,\"pubtype\":58,\"p2shtype\":50,\"wiftype\":128,\"txfee\":400000}, {\"coin\":\"PURA\",\"name\":\"pura\",\"rpcport\":55555,\"pubtype\":55,\"p2shtype\":16,\"wiftype\":150,\"txfee\":10000}, {\"coin\":\"DSR\",\"name\":\"desire\",\"confpath\":\"${HOME#}/.desirecore/desire.conf\",\"rpcport\":9918,\"pubtype\":30,\"p2shtype\":16,\"wiftype\":204,\"txfee\":10000}, {\"coin\":\"MNZ\",\"asset\":\"MNZ\",\"rpcport\":14337},{\"coin\":\"BTCZ\",\"name\":\"bitcoinz\",\"rpcport\":1979,\"taddr\":28,\"pubtype\":184,\"p2shtype\":189,\"wiftype\":128,\"txfee\":10000}, {\"coin\":\"MAGA\",\"name\":\"magacoin\",\"rpcport\":5332,\"pubtype\":23,\"p2shtype\":50,\"wiftype\":176,\"txfee\":100000}, {\"coin\":\"BSD\",\"name\":\"bitsend\",\"rpcport\":8800,\"pubtype\":102,\"p2shtype\":5,\"wiftype\":204,\"txfee\":10000}, {\"coin\":\"IOP\",\"name\":\"IoP\",\"rpcport\":8337,\"pubtype\":117,\"p2shtype\":174,\"wiftype\":49,\"txfee\":10000}, {\"coin\":\"BLOCK\",\"name\":\"blocknetdx\",\"rpcport\":41414,\"pubtype\":26,\"p2shtype\":28,\"wiftype\":154,\"txfee\":10000}, {\"coin\":\"CHIPS\", \"name\": \"chips\", \"rpcport\":57776,\"pubtype\":60, \"p2shtype\":85, \"wiftype\":188, \"txfee\":10000}, {\"coin\":\"888\",\"name\":\"octocoin\",\"rpcport\":22888,\"pubtype\":18,\"p2shtype\":5,\"wiftype\":176,\"txfee\":2000000}, {\"coin\":\"ARG\",\"name\":\"argentum\",\"rpcport\":13581,\"pubtype\":23,\"p2shtype\":5,\"wiftype\":151,\"txfee\":50000}, {\"coin\":\"GLT\",\"name\":\"globaltoken\",\"rpcport\":9320,\"pubtype\":38,\"p2shtype\":5,\"wiftype\":166,\"txfee\":10000}, {\"coin\":\"ZER\",\"name\":\"zero\",\"rpcport\":23801,\"taddr\":28,\"pubtype\":184,\"p2shtype\":189,\"wiftype\":128,\"txfee\":1000}, {\"coin\":\"HODLC\",\"name\":\"hodlcoin\",\"rpcport\":11989,\"pubtype\":40,\"p2shtype\":5,\"wiftype\":168,\"txfee\":5000}, {\"coin\":\"UIS\",\"name\":\"unitus\",\"rpcport\":50604,\"pubtype\":68,\"p2shtype\":10,\"wiftype\":132,\"txfee\":2000000}, {\"coin\":\"CRW\",\"name\":\"crown\",\"rpcport\":9341,\"pubtype\":0,\"p2shtype\":5,\"wiftype\":128,\"txfee\":10000}, {\"coin\":\"HUC\",\"name\":\"huntercoin\",\"rpcport\":8399,\"pubtype\":40,\"p2shtype\":13,\"wiftype\":168,\"txfee\":100000}, {\"coin\":\"PIVX\",\"name\":\"pivx\",\"rpcport\":51473,\"pubtype\":30,\"p2shtype\":13,\"wiftype\":212,\"txfee\":10000}, {\"coin\":\"BDL\",\"name\":\"bitdeal\",\"rpcport\":9332,\"pubtype\":38,\"p2shtype\":5,\"wiftype\":176,\"txfee\":100000}, {\"coin\":\"ARC\",\"name\":\"arcticcoin\",\"confpath\":\"${HOME#}/.arcticcore/arcticcoin.conf\",\"rpcport\":7208,\"pubtype\":23,\"p2shtype\":8,\"wiftype\":176,\"txfee\":10000}, {\"coin\":\"ZCL\",\"name\":\"zclassic\",\"rpcport\":8023,\"taddr\":28,\"pubtype\":184,\"p2shtype\":189,\"wiftype\":128,\"txfee\":1000}, {\"coin\":\"VIA\",\"name\":\"viacoin\",\"rpcport\":5222,\"pubtype\":71,\"p2shtype\":33,\"wiftype\":199,\"txfee\":100000}, {\"coin\":\"ERC\",\"name\":\"europecoin\",\"rpcport\":11989,\"pubtype\":33,\"p2shtype\":5,\"wiftype\":168,\"txfee\":10000},{\"coin\":\"FAIR\",\"name\":\"faircoin\",\"confpath\":\"${HOME#}/.faircoin2/faircoin.conf\",\"rpcport\":40405,\"pubtype\":95,\"p2shtype\":36,\"wiftype\":223,\"txfee\":1000000}, {\"coin\":\"FLO\",\"name\":\"florincoin\",\"rpcport\":7313,\"pubtype\":35,\"p2shtype\":8,\"wiftype\":176,\"txfee\":100000}, {\"coin\":\"SXC\",\"name\":\"sexcoin\",\"rpcport\":9561,\"pubtype\":62,\"p2shtype\":5,\"wiftype\":190,\"txfee\":100000}, {\"coin\":\"CREA\",\"name\":\"creativecoin\",\"rpcport\":17711,\"pubtype\":28,\"p2shtype\":5,\"wiftype\":176,\"txfee\":100000}, {\"coin\":\"TRC\",\"name\":\"terracoin\",\"confpath\":\"${HOME#}/.terracoincore/terracoin.conf\",\"rpcport\":13332,\"pubtype\":0,\"p2shtype\":5,\"wiftype\":128,\"txfee\":10000}, {\"coin\":\"BTA\",\"name\":\"bata\",\"rpcport\":5493,\"pubtype\":25,\"p2shtype\":5,\"wiftype\":188,\"txfee\":100000}, {\"coin\":\"SMC\",\"name\":\"smartcoin\",\"rpcport\":58583,\"pubtype\":63,\"p2shtype\":5,\"wiftype\":191,\"txfee\":1000000}, {\"coin\":\"NMC\",\"name\":\"namecoin\",\"rpcport\":8336,\"pubtype\":52,\"p2shtype\":13,\"wiftype\":180,\"txfee\":100000}, {\"coin\":\"NAV\",\"name\":\"navcoin\",\"isPoS\":1,\"confpath\":\"${HOME#}/.navcoin4/navcoin.conf\",\"rpcport\":44444,\"pubtype\":53,\"p2shtype\":85,\"wiftype\":150,\"txfee\":10000}, {\"coin\":\"MOON\",\"name\":\"Mooncoin\",\"rpcport\":44663,\"pubtype\":3,\"p2shtype\":22,\"wiftype\":131,\"txfee\":100000}, {\"coin\":\"EMC2\",\"name\":\"einsteinium\",\"rpcport\":41879,\"pubtype\":33,\"p2shtype\":5,\"wiftype\":176,\"txfee\":100000},{\"coin\":\"SYS\",\"name\":\"syscoin\",\"rpcport\":8370,\"pubtype\":0,\"p2shtype\":5,\"wiftype\":128,\"txfee\":1000}, {\"coin\":\"I0C\",\"name\":\"i0coin\",\"rpcport\":7332,\"pubtype\":105,\"p2shtype\":5,\"wiftype\":128,\"txfee\":1000}, {\"coin\":\"DASH\",\"confpath\":\"${HOME#}/.dashcore/dash.conf\",\"name\":\"dashcore\",\"rpcport\":9998,\"pubtype\":76,\"p2shtype\":16,\"wiftype\":204,\"txfee\":10000}, {\"coin\":\"STRAT\", \"name\": \"stratis\", \"active\":0, \"rpcport\":16174,\"pubtype\":63, \"p2shtype\":125, \"wiftype\":191, \"txfee\":10000}, {\"confpath\":\"${HOME#}/.muecore/mue.conf\",\"coin\":\"MUE\",\"name\":\"muecore\",\"rpcport\":29683,\"pubtype\":16,\"p2shtype\":76,\"wiftype\":126,\"txfee\":10000}, {\"coin\":\"MONA\",\"name\":\"monacoin\",\"rpcport\":9402,\"pubtype\":50,\"p2shtype\":5,\"wiftype\":176,\"txfee\":100000},{\"coin\":\"XMY\",\"name\":\"myriadcoin\",\"rpcport\":10889,\"pubtype\":50,\"p2shtype\":9,\"wiftype\":178,\"txfee\":5000}, {\"coin\":\"MAC\",\"name\":\"machinecoin\",\"rpcport\":40332,\"pubtype\":50,\"p2shtype\":5,\"wiftype\":178,\"txfee\":50000}, {\"coin\":\"BTX\",\"name\":\"bitcore\",\"rpcport\":8556,\"pubtype\":0,\"p2shtype\":5,\"wiftype\":128,\"txfee\":50000}, {\"coin\":\"XRE\",\"name\":\"revolvercoin\",\"rpcport\":8775,\"pubtype\":0,\"p2shtype\":5,\"wiftype\":128,\"txfee\":1000}, {\"coin\":\"LBC\",\"name\":\"lbrycrd\",\"rpcport\":9245,\"pubtype\":85,\"p2shtype\":122,\"wiftype\":28,\"txfee\":1000}, {\"coin\":\"SIB\",\"name\":\"sibcoin\",\"rpcport\":1944,\"pubtype\":63,\"p2shtype\":40,\"wiftype\":128,\"txfee\":10000}, {\"coin\":\"VTC\", \"name\":\"vertcoin\", \"rpcport\":5888, \"pubtype\":71, \"p2shtype\":5, \"wiftype\":128, \"txfee\":100000 }, {\"coin\":\"REVS\",\"active\":0, \"asset\":\"REVS\",\"rpcport\":10196}, {\"coin\":\"JUMBLR\",\"active\":0, \"asset\":\"JUMBLR\",\"rpcport\":15106}, {\"coin\":\"DOGE\",\"name\":\"dogecoin\",\"rpcport\":22555,\"pubtype\":30,\"p2shtype\":22,\"wiftype\":158,\"txfee\":100000000}, {\"coin\":\"HUSH\",\"name\":\"hush\",\"rpcport\":8822,\"taddr\":28,\"pubtype\":184,\"p2shtype\":189,\"wiftype\":128,\"txfee\":1000 }, {\"active\":0,\"coin\":\"ZEC\",\"name\":\"zcash\",\"rpcport\":8232,\"taddr\":28,\"pubtype\":184,\"p2shtype\":189,\"wiftype\":128,\"txfee\":10000 }, {\"coin\":\"DGB\",\"name\":\"digibyte\",\"rpcport\":14022,\"pubtype\":30,\"p2shtype\":5,\"wiftype\":128,\"txfee\":100000}, {\"coin\":\"ZET\", \"name\":\"zetacoin\", \"pubtype\":80, \"p2shtype\":9,\"rpcport\":8332, \"wiftype\":224, \"txfee\":10000}, {\"coin\":\"GAME\", \"rpcport\":40001, \"name\":\"gamecredits\", \"pubtype\":38, \"p2shtype\":5, \"wiftype\":166, \"txfee\":100000}, {\"coin\":\"LTC\", \"name\":\"litecoin\", \"rpcport\":9332, \"pubtype\":48, \"p2shtype\":5, \"wiftype\":176, \"txfee\":100000 }, {\"coin\":\"SUPERNET\",\"asset\":\"SUPERNET\",\"rpcport\":11341}, {\"coin\":\"WLC\",\"asset\":\"WLC\",\"rpcport\":12167}, {\"coin\":\"PANGEA\",\"asset\":\"PANGEA\",\"rpcport\":14068}, {\"coin\":\"DEX\",\"asset\":\"DEX\",\"rpcport\":11890}, {\"coin\":\"BET\",\"asset\":\"BET\",\"rpcport\":14250}, {\"coin\":\"CRYPTO\",\"asset\":\"CRYPTO\",\"rpcport\":8516}, {\"coin\":\"HODL\",\"asset\":\"HODL\",\"rpcport\":14431}, {\"coin\":\"SHARK\",\"asset\":\"SHARK\",\"rpcport\":10114}, {\"coin\":\"BOTS\",\"asset\":\"BOTS\",\"rpcport\":11964}, {\"coin\":\"MGW\",\"asset\":\"MGW\",\"rpcport\":12386}, {\"coin\":\"COQUI\",\"asset\":\"COQUI\",\"rpcport\":14276}, {\"coin\":\"KV\",\"asset\":\"KV\",\"rpcport\":8299}, {\"coin\":\"CEAL\",\"asset\":\"CEAL\",\"rpcport\":11116}, {\"coin\":\"MESH\",\"asset\":\"MESH\",\"rpcport\":9455}]" #, {\"coin\":\"AUD\",\"asset\":\"AUD\",\"rpcport\":8045}, {\"coin\":\"BGN\",\"asset\":\"BGN\",\"rpcport\":9110}, {\"coin\":\"CAD\",\"asset\":\"CAD\",\"rpcport\":8720}, {\"coin\":\"CHF\",\"asset\":\"CHF\",\"rpcport\":15312}, {\"coin\":\"CNY\",\"asset\":\"CNY\",\"rpcport\":10384}, {\"coin\":\"CZK\",\"asset\":\"CZK\",\"rpcport\":9482}, {\"coin\":\"DKK\",\"asset\":\"DKK\",\"rpcport\":13830}, {\"coin\":\"EUR\",\"asset\":\"EUR\",\"rpcport\":8065}, {\"coin\":\"GBP\",\"asset\":\"GBP\",\"rpcport\":11505}, {\"coin\":\"HKD\",\"asset\":\"HKD\",\"rpcport\":15409}, {\"coin\":\"HRK\",\"asset\":\"HRK\",\"rpcport\":12617}, {\"coin\":\"HUF\",\"asset\":\"HUF\",\"rpcport\":13699}, {\"coin\":\"IDR\",\"asset\":\"IDR\",\"rpcport\":14459}, {\"coin\":\"ILS\",\"asset\":\"ILS\",\"rpcport\":14638}, {\"coin\":\"INR\",\"asset\":\"INR\",\"rpcport\":10536}, {\"coin\":\"JPY\",\"asset\":\"JPY\",\"rpcport\":13145}, {\"coin\":\"KRW\",\"asset\":\"KRW\",\"rpcport\":14020}, {\"coin\":\"MXN\",\"asset\":\"MXN\",\"rpcport\":13970}, {\"coin\":\"MYR\",\"asset\":\"MYR\",\"rpcport\":10688}, {\"coin\":\"NOK\",\"asset\":\"NOK\",\"rpcport\":11588}, {\"coin\":\"NZD\",\"asset\":\"NZD\",\"rpcport\":10915}, {\"coin\":\"PHP\",\"asset\":\"PHP\",\"rpcport\":11181}, {\"coin\":\"PLN\",\"asset\":\"PLN\",\"rpcport\":13493}, {\"coin\":\"BRL\",\"asset\":\"BRL\",\"rpcport\":9914}, {\"coin\":\"RON\",\"asset\":\"RON\",\"rpcport\":8675}, {\"coin\":\"RUB\",\"asset\":\"RUB\",\"rpcport\":8199}, {\"coin\":\"SEK\",\"asset\":\"SEK\",\"rpcport\":11447}, {\"coin\":\"SGD\",\"asset\":\"SGD\",\"rpcport\":14475}, {\"coin\":\"THB\",\"asset\":\"THB\",\"rpcport\":11847}, {\"coin\":\"TRY\",\"asset\":\"TRY\",\"rpcport\":13924}, {\"coin\":\"USD\",\"asset\":\"USD\",\"rpcport\":13967}, {\"coin\":\"ZAR\",\"asset\":\"ZAR\",\"rpcport\":15160}]" #{\"coin\":\"ZEN\",\"name\":\"zen\",\"rpcport\":8231,\"pubtype\":137,\"taddr\":32,\"p2shtype\":150,\"wiftype\":128,\"txfee\":10000}, #{\"coin\":\"BLK\",\"name\":\"blackcoin\",\"rpcport\":15715,\"pubtype\":25,\"p2shtype\":85,\"wiftype\":153,\"txfee\":10000}, diff --git a/iguana/exchanges/coins.json b/iguana/exchanges/coins.json index 2fad617b6..320b6ccaf 100644 --- a/iguana/exchanges/coins.json +++ b/iguana/exchanges/coins.json @@ -1,4 +1,4 @@ -[{\"coin\":\"PURA\",\"name\":\"pura\",\"rpcport\":55555,\"pubtype\":55,\"p2shtype\":16,\"wiftype\":150,\"txfee\":10000}, {\"coin\":\"DSR\",\"name\":\"desire\",\"confpath\":\"${HOME#}/.desirecore/desire.conf\",\"rpcport\":9918,\"pubtype\":30,\"p2shtype\":16,\"wiftype\":204,\"txfee\":10000}, {\"coin\":\"MNZ\",\"asset\":\"MNZ\",\"rpcport\":14337},{\"coin\":\"BTCZ\",\"name\":\"bitcoinz\",\"rpcport\":1979,\"taddr\":28,\"pubtype\":184,\"p2shtype\":189,\"wiftype\":128,\"txfee\":10000}, {\"coin\":\"MAGA\",\"name\":\"magacoin\",\"rpcport\":5332,\"pubtype\":23,\"p2shtype\":50,\"wiftype\":176,\"txfee\":100000}, {\"coin\":\"BSD\",\"name\":\"bitsend\",\"rpcport\":8800,\"pubtype\":102,\"p2shtype\":5,\"wiftype\":204,\"txfee\":10000}, {\"coin\":\"IOP\",\"name\":\"IoP\",\"rpcport\":8337,\"pubtype\":117,\"p2shtype\":174,\"wiftype\":49,\"txfee\":10000}, {\"coin\":\"BLOCK\",\"name\":\"blocknetdx\",\"rpcport\":41414,\"pubtype\":26,\"p2shtype\":28,\"wiftype\":154,\"txfee\":10000}, {\"coin\":\"CHIPS\", \"name\": \"chips\", \"rpcport\":57776,\"pubtype\":60, \"p2shtype\":85, \"wiftype\":188, \"txfee\":10000}, {\"coin\":\"888\",\"name\":\"octocoin\",\"rpcport\":22888,\"pubtype\":18,\"p2shtype\":5,\"wiftype\":176,\"txfee\":2000000}, {\"coin\":\"ARG\",\"name\":\"argentum\",\"rpcport\":13581,\"pubtype\":23,\"p2shtype\":5,\"wiftype\":151,\"txfee\":50000}, {\"coin\":\"GLT\",\"name\":\"globaltoken\",\"rpcport\":9320,\"pubtype\":38,\"p2shtype\":5,\"wiftype\":166,\"txfee\":10000}, {\"coin\":\"ZER\",\"name\":\"zero\",\"rpcport\":23801,\"taddr\":28,\"pubtype\":184,\"p2shtype\":189,\"wiftype\":128,\"txfee\":1000}, {\"coin\":\"HODLC\",\"name\":\"hodlcoin\",\"rpcport\":11989,\"pubtype\":40,\"p2shtype\":5,\"wiftype\":168,\"txfee\":5000}, {\"coin\":\"UIS\",\"name\":\"unitus\",\"rpcport\":50604,\"pubtype\":68,\"p2shtype\":10,\"wiftype\":132,\"txfee\":2000000}, {\"coin\":\"CRW\",\"name\":\"crown\",\"rpcport\":9341,\"pubtype\":0,\"p2shtype\":5,\"wiftype\":128,\"txfee\":10000}, {\"coin\":\"HUC\",\"name\":\"huntercoin\",\"rpcport\":8399,\"pubtype\":40,\"p2shtype\":13,\"wiftype\":168,\"txfee\":100000}, {\"coin\":\"PIVX\",\"name\":\"pivx\",\"rpcport\":51473,\"pubtype\":30,\"p2shtype\":13,\"wiftype\":212,\"txfee\":10000}, {\"coin\":\"BDL\",\"name\":\"bitdeal\",\"rpcport\":9332,\"pubtype\":38,\"p2shtype\":5,\"wiftype\":176,\"txfee\":100000}, {\"coin\":\"ARC\",\"name\":\"arcticcoin\",\"confpath\":\"${HOME#}/.arcticcore/arcticcoin.conf\",\"rpcport\":7208,\"pubtype\":23,\"p2shtype\":8,\"wiftype\":176,\"txfee\":10000}, {\"coin\":\"ZCL\",\"name\":\"zclassic\",\"rpcport\":8023,\"taddr\":28,\"pubtype\":184,\"p2shtype\":189,\"wiftype\":128,\"txfee\":1000}, {\"coin\":\"VIA\",\"name\":\"viacoin\",\"rpcport\":5222,\"pubtype\":71,\"p2shtype\":33,\"wiftype\":199,\"txfee\":100000}, {\"coin\":\"ERC\",\"name\":\"europecoin\",\"rpcport\":11989,\"pubtype\":33,\"p2shtype\":5,\"wiftype\":168,\"txfee\":10000},{\"coin\":\"FAIR\",\"name\":\"faircoin\",\"confpath\":\"${HOME#}/.faircoin2/faircoin.conf\",\"rpcport\":40405,\"pubtype\":95,\"p2shtype\":36,\"wiftype\":223,\"txfee\":1000000}, {\"coin\":\"FLO\",\"name\":\"florincoin\",\"rpcport\":7313,\"pubtype\":35,\"p2shtype\":8,\"wiftype\":176,\"txfee\":100000}, {\"coin\":\"SXC\",\"name\":\"sexcoin\",\"rpcport\":9561,\"pubtype\":62,\"p2shtype\":5,\"wiftype\":190,\"txfee\":100000}, {\"coin\":\"CREA\",\"name\":\"creativecoin\",\"rpcport\":17711,\"pubtype\":28,\"p2shtype\":5,\"wiftype\":176,\"txfee\":100000}, {\"coin\":\"TRC\",\"name\":\"terracoin\",\"confpath\":\"${HOME#}/.terracoincore/terracoin.conf\",\"rpcport\":13332,\"pubtype\":0,\"p2shtype\":5,\"wiftype\":128,\"txfee\":10000}, {\"coin\":\"BTA\",\"name\":\"bata\",\"rpcport\":5493,\"pubtype\":25,\"p2shtype\":5,\"wiftype\":188,\"txfee\":100000}, {\"coin\":\"SMC\",\"name\":\"smartcoin\",\"rpcport\":58583,\"pubtype\":63,\"p2shtype\":5,\"wiftype\":191,\"txfee\":1000000}, {\"coin\":\"NMC\",\"name\":\"namecoin\",\"rpcport\":8336,\"pubtype\":52,\"p2shtype\":13,\"wiftype\":180,\"txfee\":100000}, {\"coin\":\"NAV\",\"name\":\"navcoin\",\"isPoS\":1,\"confpath\":\"${HOME#}/.navcoin4/navcoin.conf\",\"rpcport\":44444,\"pubtype\":53,\"p2shtype\":85,\"wiftype\":150,\"txfee\":10000}, {\"coin\":\"MOON\",\"name\":\"Mooncoin\",\"rpcport\":44663,\"pubtype\":3,\"p2shtype\":22,\"wiftype\":131,\"txfee\":100000}, {\"coin\":\"EMC2\",\"name\":\"einsteinium\",\"rpcport\":41879,\"pubtype\":33,\"p2shtype\":5,\"wiftype\":176,\"txfee\":100000},{\"coin\":\"SYS\",\"name\":\"syscoin\",\"rpcport\":8370,\"pubtype\":0,\"p2shtype\":5,\"wiftype\":128,\"txfee\":1000}, {\"coin\":\"I0C\",\"name\":\"i0coin\",\"rpcport\":7332,\"pubtype\":105,\"p2shtype\":5,\"wiftype\":128,\"txfee\":1000}, {\"coin\":\"DASH\",\"confpath\":\"${HOME#}/.dashcore/dash.conf\",\"name\":\"dashcore\",\"rpcport\":9998,\"pubtype\":76,\"p2shtype\":16,\"wiftype\":204,\"txfee\":10000}, {\"coin\":\"STRAT\", \"name\": \"stratis\", \"active\":0, \"rpcport\":16174,\"pubtype\":63, \"p2shtype\":125, \"wiftype\":191, \"txfee\":10000}, {\"confpath\":\"${HOME#}/.muecore/mue.conf\",\"coin\":\"MUE\",\"name\":\"muecore\",\"rpcport\":29683,\"pubtype\":16,\"p2shtype\":76,\"wiftype\":126,\"txfee\":10000}, {\"coin\":\"MONA\",\"name\":\"monacoin\",\"rpcport\":9402,\"pubtype\":50,\"p2shtype\":5,\"wiftype\":176,\"txfee\":100000},{\"coin\":\"XMY\",\"name\":\"myriadcoin\",\"rpcport\":10889,\"pubtype\":50,\"p2shtype\":9,\"wiftype\":178,\"txfee\":5000}, {\"coin\":\"MAC\",\"name\":\"machinecoin\",\"rpcport\":40332,\"pubtype\":50,\"p2shtype\":5,\"wiftype\":178,\"txfee\":50000}, {\"coin\":\"BTX\",\"name\":\"bitcore\",\"rpcport\":8556,\"pubtype\":0,\"p2shtype\":5,\"wiftype\":128,\"txfee\":50000}, {\"coin\":\"XRE\",\"name\":\"revolvercoin\",\"rpcport\":8775,\"pubtype\":0,\"p2shtype\":5,\"wiftype\":128,\"txfee\":1000}, {\"coin\":\"LBC\",\"name\":\"lbrycrd\",\"rpcport\":9245,\"pubtype\":85,\"p2shtype\":122,\"wiftype\":28,\"txfee\":1000}, {\"coin\":\"SIB\",\"name\":\"sibcoin\",\"rpcport\":1944,\"pubtype\":63,\"p2shtype\":40,\"wiftype\":128,\"txfee\":10000}, {\"coin\":\"VTC\", \"name\":\"vertcoin\", \"rpcport\":5888, \"pubtype\":71, \"p2shtype\":5, \"wiftype\":128, \"txfee\":100000 }, {\"coin\":\"REVS\",\"active\":0, \"asset\":\"REVS\",\"rpcport\":10196}, {\"coin\":\"JUMBLR\",\"active\":0, \"asset\":\"JUMBLR\",\"rpcport\":15106}, {\"coin\":\"DOGE\",\"name\":\"dogecoin\",\"rpcport\":22555,\"pubtype\":30,\"p2shtype\":22,\"wiftype\":158,\"txfee\":100000000}, {\"coin\":\"HUSH\",\"name\":\"hush\",\"rpcport\":8822,\"taddr\":28,\"pubtype\":184,\"p2shtype\":189,\"wiftype\":128,\"txfee\":1000 }, {\"active\":0,\"coin\":\"ZEC\",\"name\":\"zcash\",\"rpcport\":8232,\"taddr\":28,\"pubtype\":184,\"p2shtype\":189,\"wiftype\":128,\"txfee\":10000 }, {\"coin\":\"DGB\",\"name\":\"digibyte\",\"rpcport\":14022,\"pubtype\":30,\"p2shtype\":5,\"wiftype\":128,\"txfee\":100000}, {\"coin\":\"ZET\", \"name\":\"zetacoin\", \"pubtype\":80, \"p2shtype\":9,\"rpcport\":8332, \"wiftype\":224, \"txfee\":10000}, {\"coin\":\"GAME\", \"rpcport\":40001, \"name\":\"gamecredits\", \"pubtype\":38, \"p2shtype\":5, \"wiftype\":166, \"txfee\":100000}, {\"coin\":\"LTC\", \"name\":\"litecoin\", \"rpcport\":9332, \"pubtype\":48, \"p2shtype\":5, \"wiftype\":176, \"txfee\":100000 }, {\"coin\":\"SUPERNET\",\"asset\":\"SUPERNET\",\"rpcport\":11341}, {\"coin\":\"WLC\",\"asset\":\"WLC\",\"rpcport\":12167}, {\"coin\":\"PANGEA\",\"asset\":\"PANGEA\",\"rpcport\":14068}, {\"coin\":\"DEX\",\"asset\":\"DEX\",\"rpcport\":11890}, {\"coin\":\"BET\",\"asset\":\"BET\",\"rpcport\":14250}, {\"coin\":\"CRYPTO\",\"asset\":\"CRYPTO\",\"rpcport\":8516}, {\"coin\":\"HODL\",\"asset\":\"HODL\",\"rpcport\":14431}, {\"coin\":\"SHARK\",\"asset\":\"SHARK\",\"rpcport\":10114}, {\"coin\":\"BOTS\",\"asset\":\"BOTS\",\"rpcport\":11964}, {\"coin\":\"MGW\",\"asset\":\"MGW\",\"rpcport\":12386}, {\"coin\":\"COQUI\",\"asset\":\"COQUI\",\"rpcport\":14276}, {\"coin\":\"KV\",\"asset\":\"KV\",\"rpcport\":8299}, {\"coin\":\"CEAL\",\"asset\":\"CEAL\",\"rpcport\":11116}, {\"coin\":\"MESH\",\"asset\":\"MESH\",\"rpcport\":9455}] -#, {\"coin\":\"AUD\",\"asset\":\"AUD\",\"rpcport\":8045}, {\"coin\":\"BGN\",\"asset\":\"BGN\",\"rpcport\":9110}, {\"coin\":\"CAD\",\"asset\":\"CAD\",\"rpcport\":8720}, {\"coin\":\"CHF\",\"asset\":\"CHF\",\"rpcport\":15312}, {\"coin\":\"CNY\",\"asset\":\"CNY\",\"rpcport\":10384}, {\"coin\":\"CZK\",\"asset\":\"CZK\",\"rpcport\":9482}, {\"coin\":\"DKK\",\"asset\":\"DKK\",\"rpcport\":13830}, {\"coin\":\"EUR\",\"asset\":\"EUR\",\"rpcport\":8065}, {\"coin\":\"GBP\",\"asset\":\"GBP\",\"rpcport\":11505}, {\"coin\":\"HKD\",\"asset\":\"HKD\",\"rpcport\":15409}, {\"coin\":\"HRK\",\"asset\":\"HRK\",\"rpcport\":12617}, {\"coin\":\"HUF\",\"asset\":\"HUF\",\"rpcport\":13699}, {\"coin\":\"IDR\",\"asset\":\"IDR\",\"rpcport\":14459}, {\"coin\":\"ILS\",\"asset\":\"ILS\",\"rpcport\":14638}, {\"coin\":\"INR\",\"asset\":\"INR\",\"rpcport\":10536}, {\"coin\":\"JPY\",\"asset\":\"JPY\",\"rpcport\":13145}, {\"coin\":\"KRW\",\"asset\":\"KRW\",\"rpcport\":14020}, {\"coin\":\"MXN\",\"asset\":\"MXN\",\"rpcport\":13970}, {\"coin\":\"MYR\",\"asset\":\"MYR\",\"rpcport\":10688}, {\"coin\":\"NOK\",\"asset\":\"NOK\",\"rpcport\":11588}, {\"coin\":\"NZD\",\"asset\":\"NZD\",\"rpcport\":10915}, {\"coin\":\"PHP\",\"asset\":\"PHP\",\"rpcport\":11181}, {\"coin\":\"PLN\",\"asset\":\"PLN\",\"rpcport\":13493}, {\"coin\":\"BRL\",\"asset\":\"BRL\",\"rpcport\":9914}, {\"coin\":\"RON\",\"asset\":\"RON\",\"rpcport\":8675}, {\"coin\":\"RUB\",\"asset\":\"RUB\",\"rpcport\":8199}, {\"coin\":\"SEK\",\"asset\":\"SEK\",\"rpcport\":11447}, {\"coin\":\"SGD\",\"asset\":\"SGD\",\"rpcport\":14475}, {\"coin\":\"THB\",\"asset\":\"THB\",\"rpcport\":11847}, {\"coin\":\"TRY\",\"asset\":\"TRY\",\"rpcport\":13924}, {\"coin\":\"USD\",\"asset\":\"USD\",\"rpcport\":13967}, {\"coin\":\"ZAR\",\"asset\":\"ZAR\",\"rpcport\":15160}]" +[{\"coin\":\"QTUM\",\"name\":\"qtum\",\"rpcport\":3889,\"pubtype\":58,\"p2shtype\":50,\"wiftype\":128,\"txfee\":400000}, {\"coin\":\"PURA\",\"name\":\"pura\",\"rpcport\":55555,\"pubtype\":55,\"p2shtype\":16,\"wiftype\":150,\"txfee\":10000}, {\"coin\":\"DSR\",\"name\":\"desire\",\"confpath\":\"${HOME#}/.desirecore/desire.conf\",\"rpcport\":9918,\"pubtype\":30,\"p2shtype\":16,\"wiftype\":204,\"txfee\":10000}, {\"coin\":\"MNZ\",\"asset\":\"MNZ\",\"rpcport\":14337},{\"coin\":\"BTCZ\",\"name\":\"bitcoinz\",\"rpcport\":1979,\"taddr\":28,\"pubtype\":184,\"p2shtype\":189,\"wiftype\":128,\"txfee\":10000}, {\"coin\":\"MAGA\",\"name\":\"magacoin\",\"rpcport\":5332,\"pubtype\":23,\"p2shtype\":50,\"wiftype\":176,\"txfee\":100000}, {\"coin\":\"BSD\",\"name\":\"bitsend\",\"rpcport\":8800,\"pubtype\":102,\"p2shtype\":5,\"wiftype\":204,\"txfee\":10000}, {\"coin\":\"IOP\",\"name\":\"IoP\",\"rpcport\":8337,\"pubtype\":117,\"p2shtype\":174,\"wiftype\":49,\"txfee\":10000}, {\"coin\":\"BLOCK\",\"name\":\"blocknetdx\",\"rpcport\":41414,\"pubtype\":26,\"p2shtype\":28,\"wiftype\":154,\"txfee\":10000}, {\"coin\":\"CHIPS\", \"name\": \"chips\", \"rpcport\":57776,\"pubtype\":60, \"p2shtype\":85, \"wiftype\":188, \"txfee\":10000}, {\"coin\":\"888\",\"name\":\"octocoin\",\"rpcport\":22888,\"pubtype\":18,\"p2shtype\":5,\"wiftype\":176,\"txfee\":2000000}, {\"coin\":\"ARG\",\"name\":\"argentum\",\"rpcport\":13581,\"pubtype\":23,\"p2shtype\":5,\"wiftype\":151,\"txfee\":50000}, {\"coin\":\"GLT\",\"name\":\"globaltoken\",\"rpcport\":9320,\"pubtype\":38,\"p2shtype\":5,\"wiftype\":166,\"txfee\":10000}, {\"coin\":\"ZER\",\"name\":\"zero\",\"rpcport\":23801,\"taddr\":28,\"pubtype\":184,\"p2shtype\":189,\"wiftype\":128,\"txfee\":1000}, {\"coin\":\"HODLC\",\"name\":\"hodlcoin\",\"rpcport\":11989,\"pubtype\":40,\"p2shtype\":5,\"wiftype\":168,\"txfee\":5000}, {\"coin\":\"UIS\",\"name\":\"unitus\",\"rpcport\":50604,\"pubtype\":68,\"p2shtype\":10,\"wiftype\":132,\"txfee\":2000000}, {\"coin\":\"CRW\",\"name\":\"crown\",\"rpcport\":9341,\"pubtype\":0,\"p2shtype\":5,\"wiftype\":128,\"txfee\":10000}, {\"coin\":\"HUC\",\"name\":\"huntercoin\",\"rpcport\":8399,\"pubtype\":40,\"p2shtype\":13,\"wiftype\":168,\"txfee\":100000}, {\"coin\":\"PIVX\",\"name\":\"pivx\",\"rpcport\":51473,\"pubtype\":30,\"p2shtype\":13,\"wiftype\":212,\"txfee\":10000}, {\"coin\":\"BDL\",\"name\":\"bitdeal\",\"rpcport\":9332,\"pubtype\":38,\"p2shtype\":5,\"wiftype\":176,\"txfee\":100000}, {\"coin\":\"ARC\",\"name\":\"arcticcoin\",\"confpath\":\"${HOME#}/.arcticcore/arcticcoin.conf\",\"rpcport\":7208,\"pubtype\":23,\"p2shtype\":8,\"wiftype\":176,\"txfee\":10000}, {\"coin\":\"ZCL\",\"name\":\"zclassic\",\"rpcport\":8023,\"taddr\":28,\"pubtype\":184,\"p2shtype\":189,\"wiftype\":128,\"txfee\":1000}, {\"coin\":\"VIA\",\"name\":\"viacoin\",\"rpcport\":5222,\"pubtype\":71,\"p2shtype\":33,\"wiftype\":199,\"txfee\":100000}, {\"coin\":\"ERC\",\"name\":\"europecoin\",\"rpcport\":11989,\"pubtype\":33,\"p2shtype\":5,\"wiftype\":168,\"txfee\":10000},{\"coin\":\"FAIR\",\"name\":\"faircoin\",\"confpath\":\"${HOME#}/.faircoin2/faircoin.conf\",\"rpcport\":40405,\"pubtype\":95,\"p2shtype\":36,\"wiftype\":223,\"txfee\":1000000}, {\"coin\":\"FLO\",\"name\":\"florincoin\",\"rpcport\":7313,\"pubtype\":35,\"p2shtype\":8,\"wiftype\":176,\"txfee\":100000}, {\"coin\":\"SXC\",\"name\":\"sexcoin\",\"rpcport\":9561,\"pubtype\":62,\"p2shtype\":5,\"wiftype\":190,\"txfee\":100000}, {\"coin\":\"CREA\",\"name\":\"creativecoin\",\"rpcport\":17711,\"pubtype\":28,\"p2shtype\":5,\"wiftype\":176,\"txfee\":100000}, {\"coin\":\"TRC\",\"name\":\"terracoin\",\"confpath\":\"${HOME#}/.terracoincore/terracoin.conf\",\"rpcport\":13332,\"pubtype\":0,\"p2shtype\":5,\"wiftype\":128,\"txfee\":10000}, {\"coin\":\"BTA\",\"name\":\"bata\",\"rpcport\":5493,\"pubtype\":25,\"p2shtype\":5,\"wiftype\":188,\"txfee\":100000}, {\"coin\":\"SMC\",\"name\":\"smartcoin\",\"rpcport\":58583,\"pubtype\":63,\"p2shtype\":5,\"wiftype\":191,\"txfee\":1000000}, {\"coin\":\"NMC\",\"name\":\"namecoin\",\"rpcport\":8336,\"pubtype\":52,\"p2shtype\":13,\"wiftype\":180,\"txfee\":100000}, {\"coin\":\"NAV\",\"name\":\"navcoin\",\"isPoS\":1,\"confpath\":\"${HOME#}/.navcoin4/navcoin.conf\",\"rpcport\":44444,\"pubtype\":53,\"p2shtype\":85,\"wiftype\":150,\"txfee\":10000}, {\"coin\":\"MOON\",\"name\":\"Mooncoin\",\"rpcport\":44663,\"pubtype\":3,\"p2shtype\":22,\"wiftype\":131,\"txfee\":100000}, {\"coin\":\"EMC2\",\"name\":\"einsteinium\",\"rpcport\":41879,\"pubtype\":33,\"p2shtype\":5,\"wiftype\":176,\"txfee\":100000},{\"coin\":\"SYS\",\"name\":\"syscoin\",\"rpcport\":8370,\"pubtype\":0,\"p2shtype\":5,\"wiftype\":128,\"txfee\":1000}, {\"coin\":\"I0C\",\"name\":\"i0coin\",\"rpcport\":7332,\"pubtype\":105,\"p2shtype\":5,\"wiftype\":128,\"txfee\":1000}, {\"coin\":\"DASH\",\"confpath\":\"${HOME#}/.dashcore/dash.conf\",\"name\":\"dashcore\",\"rpcport\":9998,\"pubtype\":76,\"p2shtype\":16,\"wiftype\":204,\"txfee\":10000}, {\"coin\":\"STRAT\", \"name\": \"stratis\", \"active\":0, \"rpcport\":16174,\"pubtype\":63, \"p2shtype\":125, \"wiftype\":191, \"txfee\":10000}, {\"confpath\":\"${HOME#}/.muecore/mue.conf\",\"coin\":\"MUE\",\"name\":\"muecore\",\"rpcport\":29683,\"pubtype\":16,\"p2shtype\":76,\"wiftype\":126,\"txfee\":10000}, {\"coin\":\"MONA\",\"name\":\"monacoin\",\"rpcport\":9402,\"pubtype\":50,\"p2shtype\":5,\"wiftype\":176,\"txfee\":100000},{\"coin\":\"XMY\",\"name\":\"myriadcoin\",\"rpcport\":10889,\"pubtype\":50,\"p2shtype\":9,\"wiftype\":178,\"txfee\":5000}, {\"coin\":\"MAC\",\"name\":\"machinecoin\",\"rpcport\":40332,\"pubtype\":50,\"p2shtype\":5,\"wiftype\":178,\"txfee\":50000}, {\"coin\":\"BTX\",\"name\":\"bitcore\",\"rpcport\":8556,\"pubtype\":0,\"p2shtype\":5,\"wiftype\":128,\"txfee\":50000}, {\"coin\":\"XRE\",\"name\":\"revolvercoin\",\"rpcport\":8775,\"pubtype\":0,\"p2shtype\":5,\"wiftype\":128,\"txfee\":1000}, {\"coin\":\"LBC\",\"name\":\"lbrycrd\",\"rpcport\":9245,\"pubtype\":85,\"p2shtype\":122,\"wiftype\":28,\"txfee\":1000}, {\"coin\":\"SIB\",\"name\":\"sibcoin\",\"rpcport\":1944,\"pubtype\":63,\"p2shtype\":40,\"wiftype\":128,\"txfee\":10000}, {\"coin\":\"VTC\", \"name\":\"vertcoin\", \"rpcport\":5888, \"pubtype\":71, \"p2shtype\":5, \"wiftype\":128, \"txfee\":100000 }, {\"coin\":\"REVS\",\"active\":0, \"asset\":\"REVS\",\"rpcport\":10196}, {\"coin\":\"JUMBLR\",\"active\":0, \"asset\":\"JUMBLR\",\"rpcport\":15106}, {\"coin\":\"DOGE\",\"name\":\"dogecoin\",\"rpcport\":22555,\"pubtype\":30,\"p2shtype\":22,\"wiftype\":158,\"txfee\":100000000}, {\"coin\":\"HUSH\",\"name\":\"hush\",\"rpcport\":8822,\"taddr\":28,\"pubtype\":184,\"p2shtype\":189,\"wiftype\":128,\"txfee\":1000 }, {\"active\":0,\"coin\":\"ZEC\",\"name\":\"zcash\",\"rpcport\":8232,\"taddr\":28,\"pubtype\":184,\"p2shtype\":189,\"wiftype\":128,\"txfee\":10000 }, {\"coin\":\"DGB\",\"name\":\"digibyte\",\"rpcport\":14022,\"pubtype\":30,\"p2shtype\":5,\"wiftype\":128,\"txfee\":100000}, {\"coin\":\"ZET\", \"name\":\"zetacoin\", \"pubtype\":80, \"p2shtype\":9,\"rpcport\":8332, \"wiftype\":224, \"txfee\":10000}, {\"coin\":\"GAME\", \"rpcport\":40001, \"name\":\"gamecredits\", \"pubtype\":38, \"p2shtype\":5, \"wiftype\":166, \"txfee\":100000}, {\"coin\":\"LTC\", \"name\":\"litecoin\", \"rpcport\":9332, \"pubtype\":48, \"p2shtype\":5, \"wiftype\":176, \"txfee\":100000 }, {\"coin\":\"SUPERNET\",\"asset\":\"SUPERNET\",\"rpcport\":11341}, {\"coin\":\"WLC\",\"asset\":\"WLC\",\"rpcport\":12167}, {\"coin\":\"PANGEA\",\"asset\":\"PANGEA\",\"rpcport\":14068}, {\"coin\":\"DEX\",\"asset\":\"DEX\",\"rpcport\":11890}, {\"coin\":\"BET\",\"asset\":\"BET\",\"rpcport\":14250}, {\"coin\":\"CRYPTO\",\"asset\":\"CRYPTO\",\"rpcport\":8516}, {\"coin\":\"HODL\",\"asset\":\"HODL\",\"rpcport\":14431}, {\"coin\":\"SHARK\",\"asset\":\"SHARK\",\"rpcport\":10114}, {\"coin\":\"BOTS\",\"asset\":\"BOTS\",\"rpcport\":11964}, {\"coin\":\"MGW\",\"asset\":\"MGW\",\"rpcport\":12386}, {\"coin\":\"COQUI\",\"asset\":\"COQUI\",\"rpcport\":14276}, {\"coin\":\"KV\",\"asset\":\"KV\",\"rpcport\":8299}, {\"coin\":\"CEAL\",\"asset\":\"CEAL\",\"rpcport\":11116}, {\"coin\":\"MESH\",\"asset\":\"MESH\",\"rpcport\":9455}]" +#, {\"coin\":\"AUD\",\"asset\":\"AUD\",\"rpcport\":8045}, {\"coin\":\"BGN\",\"asset\":\"BGN\",\"rpcport\":9110}, {\"coin\":\"CAD\",\"asset\":\"CAD\",\"rpcport\":8720}, {\"coin\":\"CHF\",\"asset\":\"CHF\",\"rpcport\":15312}, {\"coin\":\"CNY\",\"asset\":\"CNY\",\"rpcport\":10384}, {\"coin\":\"CZK\",\"asset\":\"CZK\",\"rpcport\":9482}, {\"coin\":\"DKK\",\"asset\":\"DKK\",\"rpcport\":13830}, {\"coin\":\"EUR\",\"asset\":\"EUR\",\"rpcport\":8065}, {\"coin\":\"GBP\",\"asset\":\"GBP\",\"rpcport\":11505}, {\"coin\":\"HKD\",\"asset\":\"HKD\",\"rpcport\":15409}, {\"coin\":\"HRK\",\"asset\":\"HRK\",\"rpcport\":12617}, {\"coin\":\"HUF\",\"asset\":\"HUF\",\"rpcport\":13699}, {\"coin\":\"IDR\",\"asset\":\"IDR\",\"rpcport\":14459}, {\"coin\":\"ILS\",\"asset\":\"ILS\",\"rpcport\":14638}, {\"coin\":\"INR\",\"asset\":\"INR\",\"rpcport\":10536}, {\"coin\":\"JPY\",\"asset\":\"JPY\",\"rpcport\":13145}, {\"coin\":\"KRW\",\"asset\":\"KRW\",\"rpcport\":14020}, {\"coin\":\"MXN\",\"asset\":\"MXN\",\"rpcport\":13970}, {\"coin\":\"MYR\",\"asset\":\"MYR\",\"rpcport\":10688}, {\"coin\":\"NOK\",\"asset\":\"NOK\",\"rpcport\":11588}, {\"coin\":\"NZD\",\"asset\":\"NZD\",\"rpcport\":10915}, {\"coin\":\"PHP\",\"asset\":\"PHP\",\"rpcport\":11181}, {\"coin\":\"PLN\",\"asset\":\"PLN\",\"rpcport\":13493}, {\"coin\":\"BRL\",\"asset\":\"BRL\",\"rpcport\":9914}, {\"coin\":\"RON\",\"asset\":\"RON\",\"rpcport\":8675}, {\"coin\":\"RUB\",\"asset\":\"RUB\",\"rpcport\":8199}, {\"coin\":\"SEK\",\"asset\":\"SEK\",\"rpcport\":11447}, {\"coin\":\"SGD\",\"asset\":\"SGD\",\"rpcport\":14475}, {\"coin\":\"THB\",\"asset\":\"THB\",\"rpcport\":11847}, {\"coin\":\"TRY\",\"asset\":\"TRY\",\"rpcport\":13924}, {\"coin\":\"USD\",\"asset\":\"USD\",\"rpcport\":13967}, {\"coin\":\"ZAR\",\"asset\":\"ZAR\",\"rpcport\":15160}] #{\"coin\":\"ZEN\",\"name\":\"zen\",\"rpcport\":8231,\"pubtype\":137,\"taddr\":32,\"p2shtype\":150,\"wiftype\":128,\"txfee\":10000}, #{\"coin\":\"BLK\",\"name\":\"blackcoin\",\"rpcport\":15715,\"pubtype\":25,\"p2shtype\":85,\"wiftype\":153,\"txfee\":10000}, From 43f663f388078a3c17b01584a83ddfa2b8eb15d2 Mon Sep 17 00:00:00 2001 From: jl777 Date: Tue, 7 Nov 2017 12:52:05 +0200 Subject: [PATCH 0289/1664] Dustcombine in withdraw --- iguana/exchanges/LP_remember.c | 8 +- iguana/exchanges/LP_transaction.c | 156 +++++++++++++++++------------- iguana/exchanges/LP_utxo.c | 10 +- 3 files changed, 96 insertions(+), 78 deletions(-) diff --git a/iguana/exchanges/LP_remember.c b/iguana/exchanges/LP_remember.c index 594b1fd03..927af1771 100644 --- a/iguana/exchanges/LP_remember.c +++ b/iguana/exchanges/LP_remember.c @@ -937,7 +937,7 @@ cJSON *basilisk_remember(int64_t *KMDtotals,int64_t *BTCtotals,uint32_t requesti } for (j=0; j<32; j++) rev.bytes[j] = rswap.myprivs[0].bytes[31 - j]; - if ( (rswap.txbytes[BASILISK_ALICESPEND]= basilisk_swap_bobtxspend(0,&signedtxid,rswap.Btxfee,"alicespend",rswap.bobcoin,bob->wiftaddr,bob->taddr,bob->pubtype,bob->p2shtype,bob->isPoS,bob->wiftype,ctx,rswap.myprivs[0],0,redeemscript,redeemlen,userdata,len,rswap.txids[BASILISK_BOBPAYMENT],0,0,rswap.pubkey33,1,rswap.expiration,&rswap.values[BASILISK_ALICESPEND],0,0,rswap.bobpaymentaddr,1,bob->zcash)) != 0 ) + if ( (rswap.txbytes[BASILISK_ALICESPEND]= basilisk_swap_bobtxspend(&signedtxid,rswap.Btxfee,"alicespend",rswap.bobcoin,bob->wiftaddr,bob->taddr,bob->pubtype,bob->p2shtype,bob->isPoS,bob->wiftype,ctx,rswap.myprivs[0],0,redeemscript,redeemlen,userdata,len,rswap.txids[BASILISK_BOBPAYMENT],0,0,rswap.pubkey33,1,rswap.expiration,&rswap.values[BASILISK_ALICESPEND],0,0,rswap.bobpaymentaddr,1,bob->zcash)) != 0 ) printf("alicespend.(%s)\n",rswap.txbytes[BASILISK_ALICESPEND]); } LP_txbytes_update("alicespend",rswap.bobcoin,rswap.txbytes[BASILISK_ALICESPEND],&rswap.txids[BASILISK_ALICESPEND],&rswap.paymentspent,&rswap.sentflags[BASILISK_ALICESPEND]); @@ -967,7 +967,7 @@ cJSON *basilisk_remember(int64_t *KMDtotals,int64_t *BTCtotals,uint32_t requesti if ( bits256_nonz(rswap.privBn) != 0 ) { len = basilisk_swapuserdata(userdata,zero,1,rswap.myprivs[0],redeemscript,redeemlen); - if ( (rswap.txbytes[BASILISK_ALICECLAIM]= basilisk_swap_bobtxspend(0,&signedtxid,rswap.Btxfee,"aliceclaim",rswap.bobcoin,bob->wiftaddr,bob->taddr,bob->pubtype,bob->p2shtype,bob->isPoS,bob->wiftype,ctx,rswap.myprivs[0],0,redeemscript,redeemlen,userdata,len,rswap.txids[BASILISK_BOBDEPOSIT],0,0,rswap.pubkey33,0,rswap.expiration,&rswap.values[BASILISK_ALICECLAIM],0,0,rswap.bobdepositaddr,1,bob->zcash)) != 0 ) + if ( (rswap.txbytes[BASILISK_ALICECLAIM]= basilisk_swap_bobtxspend(&signedtxid,rswap.Btxfee,"aliceclaim",rswap.bobcoin,bob->wiftaddr,bob->taddr,bob->pubtype,bob->p2shtype,bob->isPoS,bob->wiftype,ctx,rswap.myprivs[0],0,redeemscript,redeemlen,userdata,len,rswap.txids[BASILISK_BOBDEPOSIT],0,0,rswap.pubkey33,0,rswap.expiration,&rswap.values[BASILISK_ALICECLAIM],0,0,rswap.bobdepositaddr,1,bob->zcash)) != 0 ) printf("privBn.(%s) aliceclaim.(%s)\n",bits256_str(str,rswap.privBn),rswap.txbytes[BASILISK_ALICECLAIM]); } } @@ -1042,7 +1042,7 @@ cJSON *basilisk_remember(int64_t *KMDtotals,int64_t *BTCtotals,uint32_t requesti if ( redeemlen > 0 ) { len = basilisk_swapuserdata(userdata,zero,1,rswap.myprivs[1],redeemscript,redeemlen); - if ( (rswap.txbytes[BASILISK_BOBRECLAIM]= basilisk_swap_bobtxspend(0,&signedtxid,rswap.Btxfee,"bobrefund",rswap.bobcoin,bob->wiftaddr,bob->taddr,bob->pubtype,bob->p2shtype,bob->isPoS,bob->wiftype,ctx,rswap.myprivs[1],0,redeemscript,redeemlen,userdata,len,rswap.txids[BASILISK_BOBPAYMENT],0,0,rswap.pubkey33,0,rswap.expiration,&rswap.values[BASILISK_BOBRECLAIM],0,0,rswap.bobpaymentaddr,1,bob->zcash)) != 0 ) + if ( (rswap.txbytes[BASILISK_BOBRECLAIM]= basilisk_swap_bobtxspend(&signedtxid,rswap.Btxfee,"bobrefund",rswap.bobcoin,bob->wiftaddr,bob->taddr,bob->pubtype,bob->p2shtype,bob->isPoS,bob->wiftype,ctx,rswap.myprivs[1],0,redeemscript,redeemlen,userdata,len,rswap.txids[BASILISK_BOBPAYMENT],0,0,rswap.pubkey33,0,rswap.expiration,&rswap.values[BASILISK_BOBRECLAIM],0,0,rswap.bobpaymentaddr,1,bob->zcash)) != 0 ) { int32_t z; for (z=0; z<20; z++) @@ -1073,7 +1073,7 @@ cJSON *basilisk_remember(int64_t *KMDtotals,int64_t *BTCtotals,uint32_t requesti vcalc_sha256(0,rswap.secretBn256,rswap.privBn.bytes,sizeof(rswap.privBn)); redeemlen = basilisk_swap_bobredeemscript(1,&secretstart,redeemscript,rswap.dlocktime,rswap.pubA0,rswap.pubB0,rswap.pubB1,rswap.privAm,rswap.privBn,rswap.secretAm,rswap.secretAm256,rswap.secretBn,rswap.secretBn256); len = basilisk_swapuserdata(userdata,rswap.privBn,0,rswap.myprivs[0],redeemscript,redeemlen); - if ( (rswap.txbytes[BASILISK_BOBREFUND]= basilisk_swap_bobtxspend(0,&signedtxid,rswap.Btxfee,"bobrefund",rswap.bobcoin,bob->wiftaddr,bob->taddr,bob->pubtype,bob->p2shtype,bob->isPoS,bob->wiftype,ctx,rswap.myprivs[0],0,redeemscript,redeemlen,userdata,len,rswap.txids[BASILISK_BOBDEPOSIT],0,0,rswap.pubkey33,1,rswap.expiration,&rswap.values[BASILISK_BOBREFUND],0,0,rswap.bobdepositaddr,1,bob->zcash)) != 0 ) + if ( (rswap.txbytes[BASILISK_BOBREFUND]= basilisk_swap_bobtxspend(&signedtxid,rswap.Btxfee,"bobrefund",rswap.bobcoin,bob->wiftaddr,bob->taddr,bob->pubtype,bob->p2shtype,bob->isPoS,bob->wiftype,ctx,rswap.myprivs[0],0,redeemscript,redeemlen,userdata,len,rswap.txids[BASILISK_BOBDEPOSIT],0,0,rswap.pubkey33,1,rswap.expiration,&rswap.values[BASILISK_BOBREFUND],0,0,rswap.bobdepositaddr,1,bob->zcash)) != 0 ) 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]); diff --git a/iguana/exchanges/LP_transaction.c b/iguana/exchanges/LP_transaction.c index ec1f2549e..4fc950db8 100644 --- a/iguana/exchanges/LP_transaction.c +++ b/iguana/exchanges/LP_transaction.c @@ -603,9 +603,9 @@ int32_t iguana_signrawtransaction(void *ctx,char *symbol,uint8_t wiftaddr,uint8_ return(complete); } -char *basilisk_swap_bobtxspend(int32_t dustcombine,bits256 *signedtxidp,uint64_t txfee,char *name,char *symbol,uint8_t wiftaddr,uint8_t taddr,uint8_t pubtype,uint8_t p2shtype,uint8_t isPoS,uint8_t wiftype,void *ctx,bits256 privkey,bits256 *privkey2p,uint8_t *redeemscript,int32_t redeemlen,uint8_t *userdata,int32_t userdatalen,bits256 utxotxid,int32_t utxovout,char *destaddr,uint8_t *pubkey33,int32_t finalseqid,uint32_t expiration,int64_t *destamountp,uint64_t satoshis,char *changeaddr,char *vinaddr,int32_t suppress_pubkeys,int32_t zcash) +char *basilisk_swap_bobtxspend(bits256 *signedtxidp,uint64_t txfee,char *name,char *symbol,uint8_t wiftaddr,uint8_t taddr,uint8_t pubtype,uint8_t p2shtype,uint8_t isPoS,uint8_t wiftype,void *ctx,bits256 privkey,bits256 *privkey2p,uint8_t *redeemscript,int32_t redeemlen,uint8_t *userdata,int32_t userdatalen,bits256 utxotxid,int32_t utxovout,char *destaddr,uint8_t *pubkey33,int32_t finalseqid,uint32_t expiration,int64_t *destamountp,uint64_t satoshis,char *changeaddr,char *vinaddr,int32_t suppress_pubkeys,int32_t zcash) { - char *rawtxbytes=0,*signedtx=0,str[65],tmpaddr[64],hexstr[999],wifstr[128],_destaddr[64]; uint8_t spendscript[512],addrtype,rmd160[20]; cJSON *items[2],*txobj,*vins,*obj,*vouts,*item,*privkeys; int32_t i,completed,spendlen,n,ignore_cltverr=1; struct vin_info V[8]; uint32_t timestamp,locktime = 0,sequenceid = 0xffffffff * finalseqid; bits256 txid; uint64_t value=0,change = 0; struct iguana_msgtx msgtx; struct iguana_info *coin; + char *rawtxbytes=0,*signedtx=0,str[65],tmpaddr[64],hexstr[999],wifstr[128],_destaddr[64]; uint8_t spendscript[512],addrtype,rmd160[20]; cJSON *txobj,*vins,*obj,*vouts,*item,*privkeys; int32_t completed,spendlen,n,ignore_cltverr=1; struct vin_info V[8]; uint32_t timestamp,locktime = 0,sequenceid = 0xffffffff * finalseqid; bits256 txid; uint64_t value=0,change = 0; struct iguana_msgtx msgtx; struct iguana_info *coin; LP_mark_spent(symbol,utxotxid,utxovout); if ( txfee > 0 && txfee < 10000 ) txfee = 10000; @@ -635,26 +635,6 @@ char *basilisk_swap_bobtxspend(int32_t dustcombine,bits256 *signedtxidp,uint64_t printf("basilisk_swap_bobtxspend.%s %s utxo.(%s).v%d already spent or doesnt exist\n",name,symbol,bits256_str(str,utxotxid),utxovout); return(0); } - if ( coin->electrum != 0 || coin->numutxos < LP_MINDESIRED_UTXOS ) - dustcombine = 0; - else if ( coin->numutxos >= LP_MINDESIRED_UTXOS ) - dustcombine = 2; - if ( dustcombine != 0 ) - { - uint64_t more; - if ( privkey2p != 0 ) - dustcombine = 1; - memset(items,0,sizeof(items)); - more = LP_dustcombine(items,dustcombine,coin); - if ( more != 0 ) - { - printf("%s dustcombine.%d -> %.8f (%s) + (%s)\n",coin->symbol,dustcombine,dstr(more),items[0] != 0 ? jprint(items[0],0) : "",items[1] != 0 ? jprint(items[1],0) : ""); -memset(items,0,sizeof(items)); -more = 0 ; - } - value += more; - dustcombine = (items[0] != 0) + (items[1] != 0); - } #endif } if ( satoshis != 0 ) @@ -714,14 +694,14 @@ more = 0 ; jaddistr(privkeys,wifstr); V[0].suppress_pubkeys = suppress_pubkeys; V[0].ignore_cltverr = ignore_cltverr; - for (i=0; iwiftaddr,wifstr,privkey,coin->wiftype); - for (i=n=0; iU.vout && bits256_cmp(utxotxid,up->U.txid) == 0 ) { - printf("error finding unspent i.%d of %d, %.8f vs %.8f\n",i,numunspents,dstr(remains),dstr(amount)); - return(0); + preselected[numpre++] = up; + utxos[j] = 0; + continue; } - if ( belowi < 0 || abovei >= 0 ) - ind = abovei; - else ind = belowi; - if ( ind < 0 ) + if ( up->spendheight <= 0 && up->U.height > 0 && up->U.value != 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); + if ( (txobj= LP_gettxout(coin->symbol,coin->smartaddr,up->U.txid,up->U.vout)) == 0 ) + { + up->spendheight = 1; + utxos[j] = 0; + } + else + { + free_json(txobj); + if ( LP_inventory_prevent(1,coin->symbol,up->U.txid,up->U.vout) == 0 ) + { + if ( min1 == 0 || up->U.value < min1->U.value ) + { + if ( min0 == 0 || up->U.value < min0->U.value ) + { + min1 = min0; + min0 = up; + } else min1 = up; + } + } else utxos[j] = 0; + } + } + } + if ( dustcombine >= 1 && min0 != 0 ) + preselected[numpre++] = min0; + if ( dustcombine >= 2 && min1 != 0 ) + preselected[numpre++] = min1; + for (i=0; iU.txid),up->U.vout,dstr(up->U.value)); + } + else + { + 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; } - up = utxos[ind]; - utxos[ind] = utxos[--numunspents]; - utxos[numunspents] = 0; total += up->U.value; remains -= up->U.value; if ( up->U.height < 7777777 && strcmp(coin->symbol,"KMD") == 0 ) @@ -929,8 +956,6 @@ int32_t LP_vins_select(void *ctx,struct iguana_info *coin,int64_t *totalp,int64_ 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 ) @@ -943,10 +968,10 @@ int32_t LP_vins_select(void *ctx,struct iguana_info *coin,int64_t *totalp,int64_ 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) +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,bits256 utxotxid,int32_t utxovout) { 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; + 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,dustcombine,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; @@ -961,6 +986,11 @@ char *LP_createrawtransaction(cJSON **txobjp,int32_t *numvinsp,struct iguana_inf printf("LP_createrawtransaction: illegal coin.%p outputs.%p or arraysize.%d, error\n",coin,outputs,numvouts); return(0); } + if ( coin->electrum != 0 || coin->numutxos < LP_MINDESIRED_UTXOS ) + dustcombine = 0; + else if ( coin->numutxos >= LP_MINDESIRED_UTXOS ) + dustcombine = 2; + else dustcombine = 1; amount = txfee; for (i=0; itxfee; if ( ctx == 0 ) ctx = bitcoin_ctx(); @@ -1076,7 +1108,7 @@ char *LP_withdraw(struct iguana_info *coin,cJSON *argjson) 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 ) + if ( (rawtx= LP_createrawtransaction(&txobj,&numvins,coin,V,maxV,privkey,outputs,vins,privkeys,iter == 0 ? txfee : newtxfee,utxotxid,utxovout)) != 0 ) { completed = 0; memset(&msgtx,0,sizeof(msgtx)); @@ -1138,7 +1170,7 @@ int32_t basilisk_rawtx_gen(void *ctx,char *str,uint32_t swapstarted,uint8_t *pub txfee = LP_MIN_TXFEE; for (iter=0; iter<2; iter++) { - if ( (signedtx= basilisk_swap_bobtxspend(1,&rawtx->I.signedtxid,iter == 0 ? txfee : newtxfee,str,coin->symbol,coin->wiftaddr,coin->taddr,coin->pubtype,coin->p2shtype,coin->isPoS,coin->wiftype,ctx,privkey,0,0,0,0,0,rawtx->utxotxid,rawtx->utxovout,rawtx->I.destaddr,pubkey33,1,0,&destamount,rawtx->I.amount,changeaddr,vinaddr,rawtx->I.suppress_pubkeys,coin->zcash)) != 0 ) + if ( (signedtx= basilisk_swap_bobtxspend(&rawtx->I.signedtxid,iter == 0 ? txfee : newtxfee,str,coin->symbol,coin->wiftaddr,coin->taddr,coin->pubtype,coin->p2shtype,coin->isPoS,coin->wiftype,ctx,privkey,0,0,0,0,0,rawtx->utxotxid,rawtx->utxovout,rawtx->I.destaddr,pubkey33,1,0,&destamount,rawtx->I.amount,changeaddr,vinaddr,rawtx->I.suppress_pubkeys,coin->zcash)) != 0 ) { rawtx->I.datalen = (int32_t)strlen(signedtx) >> 1; if ( rawtx->I.datalen <= sizeof(rawtx->txbytes) ) @@ -1177,7 +1209,7 @@ int32_t basilisk_rawtx_sign(char *symbol,uint8_t wiftaddr,uint8_t taddr,uint8_t } for (iter=0; iter<2; iter++) { - if ( (signedtx= basilisk_swap_bobtxspend(0,&dest->I.signedtxid,iter == 0 ? txfee : newtxfee,rawtx->name,symbol,wiftaddr,taddr,pubtype,p2shtype,isPoS,wiftype,swap->ctx,privkey,privkey2,rawtx->redeemscript,rawtx->I.redeemlen,userdata,userdatalen,dest->utxotxid,dest->utxovout,dest->I.destaddr,rawtx->I.pubkey33,1,0,&destamount,rawtx->I.amount,changeaddr,vinaddr,dest->I.suppress_pubkeys,zcash)) != 0 ) + if ( (signedtx= basilisk_swap_bobtxspend(&dest->I.signedtxid,iter == 0 ? txfee : newtxfee,rawtx->name,symbol,wiftaddr,taddr,pubtype,p2shtype,isPoS,wiftype,swap->ctx,privkey,privkey2,rawtx->redeemscript,rawtx->I.redeemlen,userdata,userdatalen,dest->utxotxid,dest->utxovout,dest->I.destaddr,rawtx->I.pubkey33,1,0,&destamount,rawtx->I.amount,changeaddr,vinaddr,dest->I.suppress_pubkeys,zcash)) != 0 ) { dest->I.datalen = (int32_t)strlen(signedtx) >> 1; if ( dest->I.datalen <= sizeof(dest->txbytes) ) @@ -1224,20 +1256,12 @@ char *basilisk_swap_Aspend(char *name,char *symbol,uint64_t Atxfee,uint8_t wifta //printf("pubAm.(%s)\n",bits256_str(str,pubAm)); //printf("pubBn.(%s)\n",bits256_str(str,pubBn)); spendlen = basilisk_alicescript(redeemscript,&redeemlen,spendscript,0,msigaddr,taddr,p2shtype,pubAm,pubBn); - //char str[65]; printf("%s utxo.(%s) redeemlen.%d spendlen.%d\n",msigaddr,bits256_str(str,utxotxid),redeemlen,spendlen); - /*rev = privAm; - for (i=0; i<32; i++) - privAm.bytes[i] = rev.bytes[31 - i]; - rev = privBn; - for (i=0; i<32; i++) - privBn.bytes[i] = rev.bytes[31 - i];*/ if ( (txfee= Atxfee) == 0 ) { if ( (txfee= LP_getestimatedrate(LP_coinfind(symbol)) * LP_AVETXSIZE) < LP_MIN_TXFEE ) txfee = LP_MIN_TXFEE; } - //txfee = LP_txfee(symbol); - signedtx = basilisk_swap_bobtxspend(0,&signedtxid,txfee,name,symbol,wiftaddr,taddr,pubtype,p2shtype,isPoS,wiftype,ctx,privAm,&privBn,redeemscript,redeemlen,0,0,utxotxid,utxovout,0,pubkey33,1,expiration,destamountp,0,0,vinaddr,1,zcash); + signedtx = basilisk_swap_bobtxspend(&signedtxid,txfee,name,symbol,wiftaddr,taddr,pubtype,p2shtype,isPoS,wiftype,ctx,privAm,&privBn,redeemscript,redeemlen,0,0,utxotxid,utxovout,0,pubkey33,1,expiration,destamountp,0,0,vinaddr,1,zcash); LP_mark_spent(symbol,utxotxid,utxovout); } return(signedtx); @@ -1656,12 +1680,6 @@ void basilisk_alicepayment(struct basilisk_swap *swap,struct iguana_info *coin,s { char coinaddr[64]; alicepayment->I.spendlen = basilisk_alicescript(alicepayment->redeemscript,&alicepayment->I.redeemlen,alicepayment->spendscript,0,alicepayment->I.destaddr,coin->taddr,coin->p2shtype,pubAm,pubBn); - /*for (i=0; i<33; i++) - printf("%02x",swap->persistent_pubkey33[i]); - printf(" pubkey33, "); - for (i=0; i<20; i++) - printf("%02x",swap->changermd160[i]); - printf(" rmd160, ");*/ bitcoin_address(coinaddr,coin->taddr,coin->pubtype,swap->changermd160,20); //printf("%s suppress.%d fee.%d\n",coinaddr,alicepayment->I.suppress_pubkeys,swap->myfee.I.suppress_pubkeys); basilisk_rawtx_gen(swap->ctx,"alicepayment",swap->I.started,swap->persistent_pubkey33,0,1,alicepayment,alicepayment->I.locktime,alicepayment->spendscript,alicepayment->I.spendlen,swap->I.Atxfee,1,0,swap->persistent_privkey,swap->changermd160,coinaddr); diff --git a/iguana/exchanges/LP_utxo.c b/iguana/exchanges/LP_utxo.c index 2ccef6517..bb9e9b224 100644 --- a/iguana/exchanges/LP_utxo.c +++ b/iguana/exchanges/LP_utxo.c @@ -965,13 +965,13 @@ cJSON *LP_dustcombine_item(struct LP_address_utxo *up) return(item); } -uint64_t LP_dustcombine(cJSON *items[2],int32_t dustcombine,struct iguana_info *coin) +uint64_t LP_dustcombine(struct LP_address_utxo *ups[2],int32_t dustcombine,struct iguana_info *coin) { struct LP_address *ap=0; struct LP_address_utxo *up,*tmp,*min0,*min1; cJSON *txobj; if ( coin == 0 || coin->electrum != 0 || dustcombine <= 0 || dustcombine > 2 ) return(0); min1 = min0 = 0; - printf("LP_dustcombine\n"); + ups[0] = ups[1] = 0; if ( (ap= _LP_addressfind(coin,coin->smartaddr)) != 0 ) { DL_FOREACH_SAFE(ap->utxos,up,tmp) @@ -983,7 +983,7 @@ uint64_t LP_dustcombine(cJSON *items[2],int32_t dustcombine,struct iguana_info * else { free_json(txobj); - if ( LP_inventory_prevent(0,coin->symbol,up->U.txid,up->U.vout) == 0 && LP_inventory_prevent(1,coin->symbol,up->U.txid,up->U.vout) == 0 ) + if ( LP_inventory_prevent(1,coin->symbol,up->U.txid,up->U.vout) == 0 ) { if ( min1 == 0 || up->U.value < min1->U.value ) { @@ -1000,10 +1000,10 @@ uint64_t LP_dustcombine(cJSON *items[2],int32_t dustcombine,struct iguana_info * } if ( min0 != 0 ) { - items[0] = LP_dustcombine_item(min0); + ups[0] = min0; if ( dustcombine == 2 && min1 != 0 ) { - items[1] = LP_dustcombine_item(min1); + ups[1] = min1; return(min0->U.value + min1->U.value); } else return(min0->U.value); } From 165de053ae61fbe81ef93c5a2a2655a8cec20057 Mon Sep 17 00:00:00 2001 From: jl777 Date: Tue, 7 Nov 2017 12:57:24 +0200 Subject: [PATCH 0290/1664] Test --- iguana/exchanges/LP_nativeDEX.c | 1 + iguana/exchanges/LP_transaction.c | 2 +- 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/iguana/exchanges/LP_nativeDEX.c b/iguana/exchanges/LP_nativeDEX.c index 1a92188a8..23d598e95 100644 --- a/iguana/exchanges/LP_nativeDEX.c +++ b/iguana/exchanges/LP_nativeDEX.c @@ -18,6 +18,7 @@ // LP_nativeDEX.c // marketmaker // +// selftest and fix rpc port // autoadd dust utxo to vin for initial atomic tx // verify portfolio, interest to KMD withdraw // dPoW security -> 4: KMD notarized, 5: BTC notarized, after next notary elections diff --git a/iguana/exchanges/LP_transaction.c b/iguana/exchanges/LP_transaction.c index 4fc950db8..ce2e973cb 100644 --- a/iguana/exchanges/LP_transaction.c +++ b/iguana/exchanges/LP_transaction.c @@ -986,7 +986,7 @@ char *LP_createrawtransaction(cJSON **txobjp,int32_t *numvinsp,struct iguana_inf printf("LP_createrawtransaction: illegal coin.%p outputs.%p or arraysize.%d, error\n",coin,outputs,numvouts); return(0); } - if ( coin->electrum != 0 || coin->numutxos < LP_MINDESIRED_UTXOS ) + if ( coin->numutxos < LP_MINDESIRED_UTXOS ) dustcombine = 0; else if ( coin->numutxos >= LP_MINDESIRED_UTXOS ) dustcombine = 2; From 2a112a68bb75836835abaeaf951d0528e88d174c Mon Sep 17 00:00:00 2001 From: jl777 Date: Tue, 7 Nov 2017 13:00:33 +0200 Subject: [PATCH 0291/1664] Test --- iguana/exchanges/LP_transaction.c | 1 + 1 file changed, 1 insertion(+) diff --git a/iguana/exchanges/LP_transaction.c b/iguana/exchanges/LP_transaction.c index ce2e973cb..b84434f93 100644 --- a/iguana/exchanges/LP_transaction.c +++ b/iguana/exchanges/LP_transaction.c @@ -991,6 +991,7 @@ char *LP_createrawtransaction(cJSON **txobjp,int32_t *numvinsp,struct iguana_inf else if ( coin->numutxos >= LP_MINDESIRED_UTXOS ) dustcombine = 2; else dustcombine = 1; +dustcombine = 2; amount = txfee; for (i=0; i Date: Tue, 7 Nov 2017 13:41:40 +0200 Subject: [PATCH 0292/1664] Test --- iguana/exchanges/LP_transaction.c | 66 +++++++++++++++++++++++++------ 1 file changed, 54 insertions(+), 12 deletions(-) diff --git a/iguana/exchanges/LP_transaction.c b/iguana/exchanges/LP_transaction.c index b84434f93..d7acd2d44 100644 --- a/iguana/exchanges/LP_transaction.c +++ b/iguana/exchanges/LP_transaction.c @@ -968,10 +968,10 @@ int32_t LP_vins_select(void *ctx,struct iguana_info *coin,int64_t *totalp,int64_ 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,bits256 utxotxid,int32_t utxovout) +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,bits256 utxotxid,int32_t utxovout,uint32_t locktime) { 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,dustcombine,scriptlen,spendlen,suppress_pubkeys,ignore_cltverr,numvouts=0,numvins=0,numutxos=0; struct LP_address_utxo *utxos[256]; struct LP_address *ap; + cJSON *txobj,*item; uint8_t addrtype,rmd160[20],script[64],spendscript[64]; char *coinaddr,*rawtxbytes; bits256 txid; uint32_t timestamp; int64_t change=0,adjust=0,total,value,amount = 0; int32_t i,dustcombine,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; @@ -991,7 +991,6 @@ char *LP_createrawtransaction(cJSON **txobjp,int32_t *numvinsp,struct iguana_inf else if ( coin->numutxos >= LP_MINDESIRED_UTXOS ) dustcombine = 2; else dustcombine = 1; -dustcombine = 2; amount = txfee; for (i=0; isymbol) == 0 ) + if ( locktime == 0 && 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)); @@ -1084,7 +1082,9 @@ dustcombine = 2; char *LP_withdraw(struct iguana_info *coin,cJSON *argjson) { static void *ctx; - int32_t iter,utxovout,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 utxotxid,signedtxid; uint64_t txfee,newtxfee=10000; + int32_t iter,utxovout,autofee,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; uint32_t locktime; cJSON *retjson,*outputs,*vins=0,*txobj=0,*privkeys=0; struct iguana_msgtx msgtx; bits256 utxotxid,signedtxid; uint64_t txfee,newtxfee=10000; + if ( ctx == 0 ) + ctx = bitcoin_ctx(); if ( (outputs= jarray(&numvouts,argjson,"outputs")) == 0 ) { printf("no outputs in argjson (%s)\n",jprint(argjson,0)); @@ -1092,11 +1092,16 @@ char *LP_withdraw(struct iguana_info *coin,cJSON *argjson) } utxotxid = jbits256(argjson,"utxotxid"); utxovout = jint(argjson,"utxovout"); - txfee = coin->txfee; - if ( ctx == 0 ) - ctx = bitcoin_ctx(); - if ( txfee > 0 && txfee < 10000 ) - txfee = 10000; + locktime = juint(argjson,"locktime"); + txfee = juint(argjson,"txfee"); + autofee = (strcmp(coin->symbol,"BTC") == 0); + if ( txfee == 0 ) + { + autofee = 1; + txfee = coin->txfee; + if ( txfee > 0 && txfee < 10000 ) + txfee = 10000; + } else autofee = 0; suppress_pubkeys = 0; memset(signedtxid.bytes,0,sizeof(signedtxid)); safecopy(changeaddr,coin->smartaddr,sizeof(changeaddr)); @@ -1109,7 +1114,7 @@ char *LP_withdraw(struct iguana_info *coin,cJSON *argjson) 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,utxotxid,utxovout)) != 0 ) + if ( (rawtx= LP_createrawtransaction(&txobj,&numvins,coin,V,maxV,privkey,outputs,vins,privkeys,iter == 0 ? txfee : newtxfee,utxotxid,utxovout,locktime)) != 0 ) { completed = 0; memset(&msgtx,0,sizeof(msgtx)); @@ -1156,6 +1161,42 @@ char *LP_withdraw(struct iguana_info *coin,cJSON *argjson) 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) { + struct iguana_info *coin; int32_t len,retval=-1; char *retstr,*hexstr; cJSON *argjson,*outputs,*item,*retjson,*obj; + if ( (coin= rawtx->coin) == 0 ) + return(-1); + if ( strcmp(coin->smartaddr,vinaddr) != 0 ) + { + printf("basilisk_rawtx_gen mismatched vinaddr.%s != %s\n",vinaddr,coin->smartaddr); + return(-1); + } + argjson = cJSON_CreateObject(); + jaddbits256(argjson,"utxotxid",rawtx->utxotxid); + jaddnum(argjson,"utxovout",rawtx->utxovout); + jadd64bits(argjson,"txfee",txfee); + outputs = cJSON_CreateArray(); + item = cJSON_CreateObject(); + jaddnum(item,rawtx->I.destaddr,dstr(rawtx->I.amount)); + jaddi(outputs,item); + jadd(argjson,"outputs",outputs); + if ( (retstr= LP_withdraw(coin,argjson)) != 0 ) + { + if ( (retjson= cJSON_Parse(retstr)) != 0 ) + { + if ( (obj= jobj(retjson,"complete")) != 0 && is_cJSON_True(obj) != 0 && (hexstr= jstr(retjson,"hex")) != 0 && (len= is_hexstr(hexstr,0)) > 16 ) + { + rawtx->I.datalen = len >> 1; + decode_hex(rawtx->txbytes,rawtx->I.datalen,hexstr); + rawtx->I.completed = 1; + rawtx->I.signedtxid = jbits256(retjson,"txid"); + retval = 0; + } + free_json(retjson); + } + free(retstr); + } + free_json(argjson); + return(retval); +#ifdef old 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 ) @@ -1190,6 +1231,7 @@ int32_t basilisk_rawtx_gen(void *ctx,char *str,uint32_t swapstarted,uint8_t *pub break; } return(retval); +#endif } int32_t basilisk_rawtx_sign(char *symbol,uint8_t wiftaddr,uint8_t taddr,uint8_t pubtype,uint8_t p2shtype,uint8_t isPoS,uint8_t wiftype,struct basilisk_swap *swap,struct basilisk_rawtx *dest,struct basilisk_rawtx *rawtx,bits256 privkey,bits256 *privkey2,uint8_t *userdata,int32_t userdatalen,int32_t ignore_cltverr,uint8_t *changermd160,char *vinaddr,int32_t zcash) From fdc0800201a149634b30ce0391911812c2f4af69 Mon Sep 17 00:00:00 2001 From: jl777 Date: Tue, 7 Nov 2017 13:50:13 +0200 Subject: [PATCH 0293/1664] Test --- iguana/exchanges/LP_nativeDEX.c | 2 +- iguana/exchanges/LP_utxo.c | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/iguana/exchanges/LP_nativeDEX.c b/iguana/exchanges/LP_nativeDEX.c index 23d598e95..749dd11ae 100644 --- a/iguana/exchanges/LP_nativeDEX.c +++ b/iguana/exchanges/LP_nativeDEX.c @@ -602,7 +602,7 @@ void LP_coinsloop(void *_coins) { nonz++; up->SPV = LP_merkleproof(coin,backupep,up->U.txid,up->U.height); - if ( 0 && up->SPV > 0 ) + if ( 1 && up->SPV > 0 ) printf("%s %s: SPV.%d\n",coin->symbol,bits256_str(str,up->U.txid),up->SPV); } else if ( up->SPV == -1 ) diff --git a/iguana/exchanges/LP_utxo.c b/iguana/exchanges/LP_utxo.c index bb9e9b224..d66fe074e 100644 --- a/iguana/exchanges/LP_utxo.c +++ b/iguana/exchanges/LP_utxo.c @@ -179,7 +179,7 @@ int32_t LP_address_utxo_ptrs(struct iguana_info *coin,int32_t iambob,struct LP_a { if ( up->SPV <= 0 || up->U.height == 0 ) { - printf("LP_address_utxo_ptrs skips %s/v%u due to SPV.%d ht.%d\n",bits256_str(str,up->U.txid),up->U.vout,up->SPV,up->U.height); + //printf("LP_address_utxo_ptrs skips %s/v%u due to SPV.%d ht.%d\n",bits256_str(str,up->U.txid),up->U.vout,up->SPV,up->U.height); if ( (tx= LP_transactionfind(coin,up->U.txid)) != 0 && up->U.vout < tx->numvouts ) tx->outpoints[up->U.vout].spendheight = 1; continue; From 786fdddcaaba09ea606b83cf567abf2bc3e0d244 Mon Sep 17 00:00:00 2001 From: jl777 Date: Tue, 7 Nov 2017 13:54:20 +0200 Subject: [PATCH 0294/1664] Test --- iguana/exchanges/LP_utxo.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/iguana/exchanges/LP_utxo.c b/iguana/exchanges/LP_utxo.c index d66fe074e..1c2f158e8 100644 --- a/iguana/exchanges/LP_utxo.c +++ b/iguana/exchanges/LP_utxo.c @@ -177,7 +177,7 @@ int32_t LP_address_utxo_ptrs(struct iguana_info *coin,int32_t iambob,struct LP_a } else { - if ( up->SPV <= 0 || up->U.height == 0 ) + if ( up->SPV < 0 || up->U.height == 0 ) { //printf("LP_address_utxo_ptrs skips %s/v%u due to SPV.%d ht.%d\n",bits256_str(str,up->U.txid),up->U.vout,up->SPV,up->U.height); if ( (tx= LP_transactionfind(coin,up->U.txid)) != 0 && up->U.vout < tx->numvouts ) From 0c864ae373df029ed97376a7f3b47b8314a793c0 Mon Sep 17 00:00:00 2001 From: jl777 Date: Tue, 7 Nov 2017 13:57:54 +0200 Subject: [PATCH 0295/1664] Test --- iguana/exchanges/LP_nativeDEX.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/iguana/exchanges/LP_nativeDEX.c b/iguana/exchanges/LP_nativeDEX.c index 749dd11ae..59908163d 100644 --- a/iguana/exchanges/LP_nativeDEX.c +++ b/iguana/exchanges/LP_nativeDEX.c @@ -19,6 +19,7 @@ // marketmaker // // selftest and fix rpc port +// quotevalidate to do SPV // autoadd dust utxo to vin for initial atomic tx // verify portfolio, interest to KMD withdraw // dPoW security -> 4: KMD notarized, 5: BTC notarized, after next notary elections @@ -602,7 +603,7 @@ void LP_coinsloop(void *_coins) { nonz++; up->SPV = LP_merkleproof(coin,backupep,up->U.txid,up->U.height); - if ( 1 && up->SPV > 0 ) + if ( 0 && up->SPV > 0 ) printf("%s %s: SPV.%d\n",coin->symbol,bits256_str(str,up->U.txid),up->SPV); } else if ( up->SPV == -1 ) From e67abb39e8a6aae66cbd1c11ee327ac54cdb871c Mon Sep 17 00:00:00 2001 From: jl777 Date: Tue, 7 Nov 2017 18:20:06 +0200 Subject: [PATCH 0296/1664] test --- iguana/exchanges/LP_include.h | 4 +-- iguana/exchanges/LP_ordermatch.c | 60 +++++++++++++++++++------------ iguana/exchanges/LP_transaction.c | 6 +++- 3 files changed, 45 insertions(+), 25 deletions(-) diff --git a/iguana/exchanges/LP_include.h b/iguana/exchanges/LP_include.h index cd39393ff..1920c475e 100644 --- a/iguana/exchanges/LP_include.h +++ b/iguana/exchanges/LP_include.h @@ -47,8 +47,8 @@ void emscripten_usleep(int32_t x); // returns immediate, no sense for sleeping #define LP_MIN_PEERS 8 #define LP_MAX_PEERS 32 -#define LP_MAXDESIRED_UTXOS 8 -#define LP_MINDESIRED_UTXOS 16 +#define LP_MAXDESIRED_UTXOS 128 +#define LP_MINDESIRED_UTXOS 32 // RTmetrics #define LP_RTMETRICS_TOPGROUP 1.01 diff --git a/iguana/exchanges/LP_ordermatch.c b/iguana/exchanges/LP_ordermatch.c index 6dd5837a9..d54e955e8 100644 --- a/iguana/exchanges/LP_ordermatch.c +++ b/iguana/exchanges/LP_ordermatch.c @@ -654,32 +654,48 @@ int32_t LP_tradecommand(void *ctx,char *myipaddr,int32_t pubsock,cJSON *argjson, memset(autxo,0,sizeof(*autxo)); memset(butxo,0,sizeof(*butxo)); LP_abutxo_set(autxo,butxo,&Q); - printf("utxopairfind\n"); - if ( (butxo= LP_utxopairfind(1,Q.txid,Q.vout,Q.txid2,Q.vout2)) == 0 ) - butxo = &B; + //printf("utxopairfind\n"); + //if ( (butxo= LP_utxopairfind(1,Q.txid,Q.vout,Q.txid2,Q.vout2)) == 0 ) + // butxo = &B; //LP_butxo_swapfields(butxo); if ( strcmp(method,"request") == 0 ) { char str[65],str2[65]; printf("request.(%s)\n",jprint(argjson,0)); - if ( 1 )//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 ) + if ( (qprice= LP_quote_validate(autxo,butxo,&Q,1)) > SMALLVAL ) { - LP_RTmetrics_update(Q.srccoin,Q.destcoin); - if ( LP_RTmetrics_blacklisted(Q.desthash) >= 0 ) + value = LP_txvalue(Q.coinaddr,Q.srccoin,Q.txid,Q.vout); + value2 = LP_txvalue(Q.coinaddr,Q.srccoin,Q.txid2,Q.vout2); + if ( (butxo= LP_utxoadd(1,coin->symbol,Q.txid,Q.vout,value,Q.txid2,Q.vout2,value2,Q.coinaddr,Q.srchash,G.gui,0)) == 0 ) { - printf("request from blacklisted %s, ignore\n",bits256_str(str,Q.desthash)); - return(retval); + LP_RTmetrics_update(Q.srccoin,Q.destcoin); + if ( LP_RTmetrics_blacklisted(Q.desthash) >= 0 ) + { + printf("request from blacklisted %s, ignore\n",bits256_str(str,Q.desthash)); + return(retval); + } + 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,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; + Q.vout = butxo->payment.vout; + Q.txid2 = butxo->deposit.txid; + Q.vout2 = butxo->deposit.vout; + printf("set butxo.%p %s/v%d %s/v%d %.8f %.8f -> bsat %.8f asat %.8f\n",butxo,bits256_str(str,butxo->payment.txid),butxo->payment.vout,bits256_str(str2,butxo->deposit.txid),butxo->deposit.vout,dstr(butxo->payment.value),dstr(butxo->deposit.value),dstr(butxo->S.satoshis),dstr(autxo->S.satoshis)); + } + else + { + printf("cant find utxopair\n"); + } } - 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,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; - Q.vout = butxo->payment.vout; - Q.txid2 = butxo->deposit.txid; - Q.vout2 = butxo->deposit.vout; - printf("set butxo.%p %s/v%d %s/v%d %.8f %.8f -> bsat %.8f asat %.8f\n",butxo,bits256_str(str,butxo->payment.txid),butxo->payment.vout,bits256_str(str2,butxo->deposit.txid),butxo->deposit.vout,dstr(butxo->payment.value),dstr(butxo->deposit.value),dstr(butxo->S.satoshis),dstr(autxo->S.satoshis)); - } else printf("cant find utxopair\n"); + } + else + { + butxo = LP_utxopairfind(1,Q.txid,Q.vout,Q.txid2,Q.vout2); + } + /*if ( 1 )//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 ) + { //LP_abutxo_set(0,butxo,&Q); //LP_butxo_swapfields(butxo); } @@ -691,17 +707,17 @@ int32_t LP_tradecommand(void *ctx,char *myipaddr,int32_t pubsock,cJSON *argjson, if ( (butxo= LP_utxoadd(1,coin->symbol,Q.txid,Q.vout,value,Q.txid2,Q.vout2,value2,Q.coinaddr,G.LP_mypub25519,G.gui,0)) == 0 ) printf("couldnt create bob's utxopair\n"); else printf("created butxo.(%s %s)\n",bits256_str(str,butxo->payment.txid),bits256_str(str2,butxo->deposit.txid)); - } + }*/ } - if ( butxo == 0 || butxo == &B ) - butxo = LP_utxopairfind(1,Q.txid,Q.vout,Q.txid2,Q.vout2); + /*if ( butxo == 0 || butxo == &B ) + / butxo = LP_utxopairfind(1,Q.txid,Q.vout,Q.txid2,Q.vout2); if ( butxo == 0 || bits256_cmp(Q.txid,butxo->payment.txid) != 0 || bits256_cmp(Q.txid2,butxo->deposit.txid) != 0 ) { printf("%s %s null butxo.%p case\n",Q.srccoin,Q.coinaddr,butxo); value = LP_txvalue(Q.coinaddr,Q.srccoin,Q.txid,Q.vout); value2 = LP_txvalue(Q.coinaddr,Q.srccoin,Q.txid2,Q.vout2); butxo = LP_utxoadd(1,Q.srccoin,Q.txid,Q.vout,value,Q.txid2,Q.vout2,value2,Q.coinaddr,Q.srchash,LP_gui,0); - } + }*/ char str[65],str2[65]; printf("butxo.%p (%s %s) TRADECOMMAND.(%s)\n",butxo,butxo!=0?bits256_str(str,butxo->payment.txid):"",butxo!=0?bits256_str(str2,butxo->deposit.txid):"",jprint(argjson,0)); if ( butxo == 0 || bits256_nonz(butxo->payment.txid) == 0 || bits256_nonz(butxo->deposit.txid) == 0 || butxo->payment.vout < 0 || butxo->deposit.vout < 0 ) { diff --git a/iguana/exchanges/LP_transaction.c b/iguana/exchanges/LP_transaction.c index d7acd2d44..6a9c15c1d 100644 --- a/iguana/exchanges/LP_transaction.c +++ b/iguana/exchanges/LP_transaction.c @@ -1776,12 +1776,16 @@ int32_t basilisk_alicetxs(int32_t pairsock,struct basilisk_swap *swap,uint8_t *d int32_t LP_verify_otherfee(struct basilisk_swap *swap,uint8_t *data,int32_t datalen) { + int32_t diff; if ( LP_rawtx_spendscript(swap,swap->bobcoin.longestchain,&swap->otherfee,0,data,datalen,0) == 0 ) { printf("otherfee amount %.8f -> %s vs %s locktime %u vs %u\n",dstr(swap->otherfee.I.amount),swap->otherfee.p2shaddr,swap->otherfee.I.destaddr,swap->otherfee.I.locktime,swap->I.started+1); if ( strcmp(swap->otherfee.I.destaddr,swap->otherfee.p2shaddr) == 0 ) { - if ( swap->otherfee.I.locktime == swap->I.started+1 ) + diff = swap->otherfee.I.locktime - (swap->I.started+1); + if ( diff < 0 ) + diff = -diff; + if ( diff < 30 ) printf("dexfee verified\n"); else printf("locktime mismatch in otherfee, reject %u vs %u\n",swap->otherfee.I.locktime,swap->I.started+1); return(0); From a9a23c86116c63925588f3fe8825d637869ca7f4 Mon Sep 17 00:00:00 2001 From: jl777 Date: Tue, 7 Nov 2017 18:36:41 +0200 Subject: [PATCH 0297/1664] Test --- iguana/exchanges/LP_ordermatch.c | 87 ++++++++++++-------------------- 1 file changed, 33 insertions(+), 54 deletions(-) diff --git a/iguana/exchanges/LP_ordermatch.c b/iguana/exchanges/LP_ordermatch.c index d54e955e8..5bbf46545 100644 --- a/iguana/exchanges/LP_ordermatch.c +++ b/iguana/exchanges/LP_ordermatch.c @@ -596,7 +596,7 @@ int32_t LP_aliceonly(char *symbol) int32_t LP_tradecommand(void *ctx,char *myipaddr,int32_t pubsock,cJSON *argjson,uint8_t *data,int32_t datalen) { - 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)); + 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,recalc,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) ) { // LP_checksig @@ -633,6 +633,7 @@ int32_t LP_tradecommand(void *ctx,char *myipaddr,int32_t pubsock,cJSON *argjson, printf("this node has no price for %s/%s\n",Q.srccoin,Q.destcoin); return(retval); } + price = ask; /*if ( coin->electrum != 0 ) { printf("electrum can only be for alice\n"); @@ -648,76 +649,54 @@ int32_t LP_tradecommand(void *ctx,char *myipaddr,int32_t pubsock,cJSON *argjson, printf("bob is patching Q.coinaddr %s mismatch != %s\n",Q.coinaddr,coin->smartaddr); strcpy(Q.coinaddr,coin->smartaddr); } - price = ask; autxo = &A; butxo = &B; memset(autxo,0,sizeof(*autxo)); memset(butxo,0,sizeof(*butxo)); LP_abutxo_set(autxo,butxo,&Q); - //printf("utxopairfind\n"); - //if ( (butxo= LP_utxopairfind(1,Q.txid,Q.vout,Q.txid2,Q.vout2)) == 0 ) - // butxo = &B; - //LP_butxo_swapfields(butxo); if ( strcmp(method,"request") == 0 ) { char str[65],str2[65]; - printf("request.(%s)\n",jprint(argjson,0)); - if ( (qprice= LP_quote_validate(autxo,butxo,&Q,1)) > SMALLVAL ) + printf("address.(%s/%s) request.(%s)\n",Q.coinaddr,coin->smartaddr,jprint(argjson,0)); + recalc = 0; + if ( (qprice= LP_quote_validate(autxo,butxo,&Q,1)) < SMALLVAL ) + recalc = 1; + else { value = LP_txvalue(Q.coinaddr,Q.srccoin,Q.txid,Q.vout); value2 = LP_txvalue(Q.coinaddr,Q.srccoin,Q.txid2,Q.vout2); if ( (butxo= LP_utxoadd(1,coin->symbol,Q.txid,Q.vout,value,Q.txid2,Q.vout2,value2,Q.coinaddr,Q.srchash,G.gui,0)) == 0 ) - { - LP_RTmetrics_update(Q.srccoin,Q.destcoin); - if ( LP_RTmetrics_blacklisted(Q.desthash) >= 0 ) - { - printf("request from blacklisted %s, ignore\n",bits256_str(str,Q.desthash)); - return(retval); - } - 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,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; - Q.vout = butxo->payment.vout; - Q.txid2 = butxo->deposit.txid; - Q.vout2 = butxo->deposit.vout; - printf("set butxo.%p %s/v%d %s/v%d %.8f %.8f -> bsat %.8f asat %.8f\n",butxo,bits256_str(str,butxo->payment.txid),butxo->payment.vout,bits256_str(str2,butxo->deposit.txid),butxo->deposit.vout,dstr(butxo->payment.value),dstr(butxo->deposit.value),dstr(butxo->S.satoshis),dstr(autxo->S.satoshis)); - } - else - { - printf("cant find utxopair\n"); - } - } - } - else - { - butxo = LP_utxopairfind(1,Q.txid,Q.vout,Q.txid2,Q.vout2); + recalc = 1; } - /*if ( 1 )//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 ) + if ( recalc != 0 ) { - //LP_abutxo_set(0,butxo,&Q); - //LP_butxo_swapfields(butxo); + LP_RTmetrics_update(Q.srccoin,Q.destcoin); + if ( LP_RTmetrics_blacklisted(Q.desthash) >= 0 ) + { + printf("request from blacklisted %s, ignore\n",bits256_str(str,Q.desthash)); + return(retval); + } + printf("butxo.%p recalc 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,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; + Q.vout = butxo->payment.vout; + Q.txid2 = butxo->deposit.txid; + Q.vout2 = butxo->deposit.vout; + printf("set butxo.%p %s/v%d %s/v%d %.8f %.8f -> bsat %.8f asat %.8f\n",butxo,bits256_str(str,butxo->payment.txid),butxo->payment.vout,bits256_str(str2,butxo->deposit.txid),butxo->deposit.vout,dstr(butxo->payment.value),dstr(butxo->deposit.value),dstr(butxo->S.satoshis),dstr(autxo->S.satoshis)); + } + else + { + printf("cant find utxopair\n"); + return(retval); + } } - else - { - printf("other path %p %p %.8f\n",LP_allocated(butxo->payment.txid,butxo->payment.vout),LP_allocated(butxo->deposit.txid,butxo->deposit.vout), LP_quote_validate(autxo,butxo,&Q,1)); - value = LP_txvalue(Q.coinaddr,Q.srccoin,Q.txid,Q.vout); - value2 = LP_txvalue(Q.coinaddr,Q.srccoin,Q.txid2,Q.vout2); - if ( (butxo= LP_utxoadd(1,coin->symbol,Q.txid,Q.vout,value,Q.txid2,Q.vout2,value2,Q.coinaddr,G.LP_mypub25519,G.gui,0)) == 0 ) - printf("couldnt create bob's utxopair\n"); - else printf("created butxo.(%s %s)\n",bits256_str(str,butxo->payment.txid),bits256_str(str2,butxo->deposit.txid)); - }*/ } - /*if ( butxo == 0 || butxo == &B ) - / butxo = LP_utxopairfind(1,Q.txid,Q.vout,Q.txid2,Q.vout2); - if ( butxo == 0 || bits256_cmp(Q.txid,butxo->payment.txid) != 0 || bits256_cmp(Q.txid2,butxo->deposit.txid) != 0 ) + else // "connect" { - printf("%s %s null butxo.%p case\n",Q.srccoin,Q.coinaddr,butxo); - value = LP_txvalue(Q.coinaddr,Q.srccoin,Q.txid,Q.vout); - value2 = LP_txvalue(Q.coinaddr,Q.srccoin,Q.txid2,Q.vout2); - butxo = LP_utxoadd(1,Q.srccoin,Q.txid,Q.vout,value,Q.txid2,Q.vout2,value2,Q.coinaddr,Q.srchash,LP_gui,0); - }*/ + butxo = LP_utxopairfind(1,Q.txid,Q.vout,Q.txid2,Q.vout2); + } char str[65],str2[65]; printf("butxo.%p (%s %s) TRADECOMMAND.(%s)\n",butxo,butxo!=0?bits256_str(str,butxo->payment.txid):"",butxo!=0?bits256_str(str2,butxo->deposit.txid):"",jprint(argjson,0)); if ( butxo == 0 || bits256_nonz(butxo->payment.txid) == 0 || bits256_nonz(butxo->deposit.txid) == 0 || butxo->payment.vout < 0 || butxo->deposit.vout < 0 ) { From d0470cff6e5a3e71693a9ac25874fcb52a195f92 Mon Sep 17 00:00:00 2001 From: jl777 Date: Tue, 7 Nov 2017 18:40:33 +0200 Subject: [PATCH 0298/1664] Test --- iguana/exchanges/LP_ordermatch.c | 1 + iguana/exchanges/LP_utxos.c | 2 +- 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/iguana/exchanges/LP_ordermatch.c b/iguana/exchanges/LP_ordermatch.c index 5bbf46545..f3fd7d56d 100644 --- a/iguana/exchanges/LP_ordermatch.c +++ b/iguana/exchanges/LP_ordermatch.c @@ -665,6 +665,7 @@ int32_t LP_tradecommand(void *ctx,char *myipaddr,int32_t pubsock,cJSON *argjson, { value = LP_txvalue(Q.coinaddr,Q.srccoin,Q.txid,Q.vout); value2 = LP_txvalue(Q.coinaddr,Q.srccoin,Q.txid2,Q.vout2); + printf("call LP_utxoadd.(%s) %.8f %.8f\n",Q.coinaddr,dstr(value),dstr(value2)); if ( (butxo= LP_utxoadd(1,coin->symbol,Q.txid,Q.vout,value,Q.txid2,Q.vout2,value2,Q.coinaddr,Q.srchash,G.gui,0)) == 0 ) recalc = 1; } diff --git a/iguana/exchanges/LP_utxos.c b/iguana/exchanges/LP_utxos.c index 6425637e8..762315b04 100644 --- a/iguana/exchanges/LP_utxos.c +++ b/iguana/exchanges/LP_utxos.c @@ -292,7 +292,7 @@ struct LP_utxoinfo *LP_utxoadd(int32_t iambob,char *symbol,bits256 txid,int32_t uint64_t val,val2=0,tmpsatoshis,txfee; int32_t spendvini,numconfirms,selector; bits256 spendtxid; struct iguana_info *coin; struct _LP_utxoinfo u; struct LP_utxoinfo *utxo = 0; if ( symbol == 0 || symbol[0] == 0 || coinaddr == 0 || coinaddr[0] == 0 || bits256_nonz(txid) == 0 || bits256_nonz(txid2) == 0 || vout < 0 || vout2 < 0 || value <= 0 || value2 <= 0 )//|| sessionid == 0 ) { - char str[65],str2[65]; printf("REJECT %s iambob.%d %s utxoadd.(%.8f %.8f) %s/v%d %s/v%d\n",coinaddr,iambob,symbol,dstr(value),dstr(value2),bits256_str(str,txid),vout,bits256_str(str2,txid2),vout2); + char str[65],str2[65]; printf("REJECT (%s) iambob.%d %s utxoadd.(%.8f %.8f) %s/v%d %s/v%d\n",coinaddr,iambob,symbol,dstr(value),dstr(value2),bits256_str(str,txid),vout,bits256_str(str2,txid2),vout2); printf("session.%u addutxo %d %d %d %d %d %d %d %d\n",sessionid,symbol == 0,coinaddr == 0,bits256_nonz(txid) == 0,bits256_nonz(txid2) == 0,vout < 0,vout2 < 0,value <= 0,value2 <= 0); return(0); } From 8ea8ed8abb699f0ac46839e1fe55f208bcb2372c Mon Sep 17 00:00:00 2001 From: jl777 Date: Tue, 7 Nov 2017 19:01:03 +0200 Subject: [PATCH 0299/1664] Test --- iguana/exchanges/LP_transaction.c | 21 ++++++++++++++++++++- 1 file changed, 20 insertions(+), 1 deletion(-) diff --git a/iguana/exchanges/LP_transaction.c b/iguana/exchanges/LP_transaction.c index 6a9c15c1d..2fa93648b 100644 --- a/iguana/exchanges/LP_transaction.c +++ b/iguana/exchanges/LP_transaction.c @@ -865,7 +865,7 @@ int64_t LP_komodo_interest(bits256 txid,int64_t value) 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,bits256 utxotxid,int32_t utxovout,int32_t dustcombine) { - char wifstr[128],spendscriptstr[128]; int32_t i,j,n,numpre,ind,abovei,belowi,maxmode=0; struct vin_info *vp; cJSON *txobj; struct LP_address_utxo *up,*min0,*min1,*preselected[3]; int64_t interest,interestsum,above,below,remains = amount,total = 0; + char wifstr[128],spendscriptstr[128]; int32_t i,j,n,numpre,ind,abovei,belowi,maxmode=0; struct vin_info *vp; cJSON *txobj; struct LP_address_utxo *up,*min0,*min1,*preselected[3]; int64_t value,interest,interestsum,above,below,remains = amount,total = 0; *totalp = 0; interestsum = 0; init_hexbytes_noT(spendscriptstr,script,scriptlen); @@ -879,6 +879,7 @@ int32_t LP_vins_select(void *ctx,struct iguana_info *coin,int64_t *totalp,int64_ if ( utxovout == up->U.vout && bits256_cmp(utxotxid,up->U.txid) == 0 ) { preselected[numpre++] = up; + printf("found utxotxid in slot.%d\n",j); utxos[j] = 0; continue; } @@ -906,6 +907,24 @@ int32_t LP_vins_select(void *ctx,struct iguana_info *coin,int64_t *totalp,int64_ } } } + if ( bits256_nonz(utxotxid) != 0 && numpre == 0 ) + { + up = LP_address_utxofind(coin,coin->smartaddr,utxotxid,utxovout); + printf("have utxotxid but wasnt found up.%p\n",up); + if ( up == 0 ) + { + value = LP_txvalue(coin->smartaddr,coin->symbol,utxotxid,utxovout); + LP_address_utxoadd("withdraw",coin,coin->smartaddr,utxotxid,utxovout,value,1,-1); + printf("added after not finding\n"); + } + if ( (up= LP_address_utxofind(coin,coin->smartaddr,utxotxid,utxovout)) != 0 ) + preselected[numpre++] = up; + else + { + printf("couldnt add address_utxo after not finding\n"); + return(0); + } + } if ( dustcombine >= 1 && min0 != 0 ) preselected[numpre++] = min0; if ( dustcombine >= 2 && min1 != 0 ) From 978f687a6797c2f6a5c5d7cb900b744c1682e254 Mon Sep 17 00:00:00 2001 From: jl777 Date: Tue, 7 Nov 2017 19:07:12 +0200 Subject: [PATCH 0300/1664] Test --- iguana/exchanges/LP_ordermatch.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/iguana/exchanges/LP_ordermatch.c b/iguana/exchanges/LP_ordermatch.c index f3fd7d56d..d73ff53f5 100644 --- a/iguana/exchanges/LP_ordermatch.c +++ b/iguana/exchanges/LP_ordermatch.c @@ -663,8 +663,9 @@ int32_t LP_tradecommand(void *ctx,char *myipaddr,int32_t pubsock,cJSON *argjson, recalc = 1; else { - value = LP_txvalue(Q.coinaddr,Q.srccoin,Q.txid,Q.vout); - value2 = LP_txvalue(Q.coinaddr,Q.srccoin,Q.txid2,Q.vout2); + char tmp[64]; + value = LP_txvalue(tmp,Q.srccoin,Q.txid,Q.vout); + value2 = LP_txvalue(tmp,Q.srccoin,Q.txid2,Q.vout2); printf("call LP_utxoadd.(%s) %.8f %.8f\n",Q.coinaddr,dstr(value),dstr(value2)); if ( (butxo= LP_utxoadd(1,coin->symbol,Q.txid,Q.vout,value,Q.txid2,Q.vout2,value2,Q.coinaddr,Q.srchash,G.gui,0)) == 0 ) recalc = 1; From e595ef7c13daf89fe64828c4174661c647507b1c Mon Sep 17 00:00:00 2001 From: jl777 Date: Tue, 7 Nov 2017 19:16:58 +0200 Subject: [PATCH 0301/1664] Test --- iguana/exchanges/LP_utxo.c | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/iguana/exchanges/LP_utxo.c b/iguana/exchanges/LP_utxo.c index 1c2f158e8..b66f73930 100644 --- a/iguana/exchanges/LP_utxo.c +++ b/iguana/exchanges/LP_utxo.c @@ -886,13 +886,25 @@ int32_t LP_iseligible(uint64_t *valp,uint64_t *val2p,int32_t iambob,char *symbol if ( coin != 0 ) { if ( (tx= LP_transactionfind(coin,txid)) != 0 && vout < tx->numvouts && tx->outpoints[vout].spendheight > 0 ) + { + printf("txid spent\n"); return(0); + } if ( (tx= LP_transactionfind(coin,txid2)) != 0 && vout2 < tx->numvouts && tx->outpoints[vout2].spendheight > 0 ) + { + printf("txid2 spent\n"); return(0); + } if ( (up= LP_address_utxofind(coin,destaddr,txid,vout)) != 0 && up->spendheight > 0 ) + { + printf("txid %s spentB\n",destaddr); return(0); + } if ( (up= LP_address_utxofind(coin,destaddr,txid2,vout2)) != 0 && up->spendheight > 0 ) + { + printf("txid2 %s spentB\n",destaddr); return(0); + } } return(1); } From c81f33264340ddfcff9b2a871b1bab09c5487706 Mon Sep 17 00:00:00 2001 From: jl777 Date: Tue, 7 Nov 2017 19:18:52 +0200 Subject: [PATCH 0302/1664] Test --- iguana/exchanges/LP_ordermatch.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/iguana/exchanges/LP_ordermatch.c b/iguana/exchanges/LP_ordermatch.c index d73ff53f5..582dc3733 100644 --- a/iguana/exchanges/LP_ordermatch.c +++ b/iguana/exchanges/LP_ordermatch.c @@ -83,7 +83,7 @@ double LP_quote_validate(struct LP_utxoinfo *autxo,struct LP_utxoinfo *butxo,str { if ( LP_iseligible(&srcvalue,&srcvalue2,1,qp->srccoin,qp->txid,qp->vout,qp->satoshis,qp->txid2,qp->vout2) == 0 ) { - printf("bob not eligible %s\n",jprint(LP_quotejson(qp),1)); + printf("bob not eligible %s (%.8f %.8f)\n",jprint(LP_quotejson(qp),1),dstr(srcvalue),dstr(srcvalue2)); return(-2); } if ( (txout= LP_gettxout(qp->srccoin,qp->coinaddr,qp->txid,qp->vout)) != 0 ) From 8f0d139bb371cfd20a0bcb155bfed73209f70bc1 Mon Sep 17 00:00:00 2001 From: jl777 Date: Tue, 7 Nov 2017 19:25:50 +0200 Subject: [PATCH 0303/1664] Test --- iguana/exchanges/LP_transaction.c | 1 + 1 file changed, 1 insertion(+) diff --git a/iguana/exchanges/LP_transaction.c b/iguana/exchanges/LP_transaction.c index 2fa93648b..017f8455e 100644 --- a/iguana/exchanges/LP_transaction.c +++ b/iguana/exchanges/LP_transaction.c @@ -929,6 +929,7 @@ int32_t LP_vins_select(void *ctx,struct iguana_info *coin,int64_t *totalp,int64_ preselected[numpre++] = min0; if ( dustcombine >= 2 && min1 != 0 ) preselected[numpre++] = min1; + printf("dustcombine.%d numpre.%d min0.%p min1.%p numutxos.%d\n",dustcombine,numpre,min0,min1,numunspents); for (i=0; i Date: Tue, 7 Nov 2017 19:45:00 +0200 Subject: [PATCH 0304/1664] Test --- iguana/exchanges/LP_transaction.c | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/iguana/exchanges/LP_transaction.c b/iguana/exchanges/LP_transaction.c index 017f8455e..d5b3db7cd 100644 --- a/iguana/exchanges/LP_transaction.c +++ b/iguana/exchanges/LP_transaction.c @@ -930,7 +930,7 @@ int32_t LP_vins_select(void *ctx,struct iguana_info *coin,int64_t *totalp,int64_ if ( dustcombine >= 2 && min1 != 0 ) preselected[numpre++] = min1; printf("dustcombine.%d numpre.%d min0.%p min1.%p numutxos.%d\n",dustcombine,numpre,min0,min1,numunspents); - for (i=0; isuppress_pubkeys = suppress_pubkeys; vp->ignore_cltverr = ignore_cltverr; jaddi(vins,LP_inputjson(up->U.txid,up->U.vout,spendscriptstr)); - if ( remains <= 0 ) + if ( remains <= 0 && i >= numpre ) break; if ( numunspents == 0 ) { @@ -991,7 +991,7 @@ int32_t LP_vins_select(void *ctx,struct iguana_info *coin,int64_t *totalp,int64_ 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,bits256 utxotxid,int32_t utxovout,uint32_t locktime) { static void *ctx; - cJSON *txobj,*item; uint8_t addrtype,rmd160[20],script[64],spendscript[64]; char *coinaddr,*rawtxbytes; bits256 txid; uint32_t timestamp; int64_t change=0,adjust=0,total,value,amount = 0; int32_t i,dustcombine,scriptlen,spendlen,suppress_pubkeys,ignore_cltverr,numvouts=0,numvins=0,numutxos=0; struct LP_address_utxo *utxos[256]; struct LP_address *ap; + cJSON *txobj,*item; uint8_t addrtype,rmd160[20],script[64],spendscript[256]; char *coinaddr,*rawtxbytes; bits256 txid; uint32_t timestamp; int64_t change=0,adjust=0,total,value,amount = 0; int32_t i,dustcombine,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; @@ -1081,7 +1081,9 @@ char *LP_createrawtransaction(cJSON **txobjp,int32_t *numvinsp,struct iguana_inf return(0); } bitcoin_addr2rmd160(coin->taddr,&addrtype,rmd160,coinaddr); - spendlen = bitcoin_standardspend(spendscript,0,rmd160); + if ( addrtype == coin->pubtype ) + spendlen = bitcoin_standardspend(spendscript,0,rmd160); + else spendlen = bitcoin_p2shspend(spendscript,0,rmd160); txobj = bitcoin_txoutput(txobj,spendscript,spendlen,value + adjust); } else From 8d987a697956954cd151ec934e54bdfffb83fdfd Mon Sep 17 00:00:00 2001 From: jl777 Date: Tue, 7 Nov 2017 19:53:10 +0200 Subject: [PATCH 0305/1664] Test --- iguana/exchanges/LP_transaction.c | 1 + 1 file changed, 1 insertion(+) diff --git a/iguana/exchanges/LP_transaction.c b/iguana/exchanges/LP_transaction.c index d5b3db7cd..cd81192cc 100644 --- a/iguana/exchanges/LP_transaction.c +++ b/iguana/exchanges/LP_transaction.c @@ -1194,6 +1194,7 @@ int32_t basilisk_rawtx_gen(void *ctx,char *str,uint32_t swapstarted,uint8_t *pub argjson = cJSON_CreateObject(); jaddbits256(argjson,"utxotxid",rawtx->utxotxid); jaddnum(argjson,"utxovout",rawtx->utxovout); + jaddnum(argjson,"locktime",locktime); jadd64bits(argjson,"txfee",txfee); outputs = cJSON_CreateArray(); item = cJSON_CreateObject(); From 89a7dce8dc8ec73b31530df8ed28fa3850a23874 Mon Sep 17 00:00:00 2001 From: jl777 Date: Tue, 7 Nov 2017 20:10:57 +0200 Subject: [PATCH 0306/1664] Test --- iguana/exchanges/LP_transaction.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/iguana/exchanges/LP_transaction.c b/iguana/exchanges/LP_transaction.c index cd81192cc..bea8733c9 100644 --- a/iguana/exchanges/LP_transaction.c +++ b/iguana/exchanges/LP_transaction.c @@ -905,7 +905,7 @@ int32_t LP_vins_select(void *ctx,struct iguana_info *coin,int64_t *totalp,int64_ } } else utxos[j] = 0; } - } + } else utxos[j] = 0; } if ( bits256_nonz(utxotxid) != 0 && numpre == 0 ) { @@ -1011,6 +1011,7 @@ char *LP_createrawtransaction(cJSON **txobjp,int32_t *numvinsp,struct iguana_inf else if ( coin->numutxos >= LP_MINDESIRED_UTXOS ) dustcombine = 2; else dustcombine = 1; +dustcombine = 2; amount = txfee; for (i=0; imyfee.coin->symbol,"BTC") == 0 ? LP_MIN_TXFEE : swap->myfee.coin->txfee)); bitcoin_address(coinaddr,swap->alicecoin.taddr,swap->alicecoin.pubtype,swap->changermd160,20); - if ( basilisk_rawtx_gen(swap->ctx,"myfee",swap->I.started,swap->persistent_pubkey33,swap->I.iambob,1,&swap->myfee,0,swap->myfee.spendscript,swap->myfee.I.spendlen,strcmp(swap->myfee.coin->symbol,"BTC") == 0 ? LP_MIN_TXFEE : swap->myfee.coin->txfee,1,0,swap->persistent_privkey,swap->changermd160,coinaddr) == 0 ) + if ( basilisk_rawtx_gen(swap->ctx,"myfee",swap->I.started,swap->persistent_pubkey33,swap->I.iambob,1,&swap->myfee,swap->myfee.I.locktime,swap->myfee.spendscript,swap->myfee.I.spendlen,strcmp(swap->myfee.coin->symbol,"BTC") == 0 ? LP_MIN_TXFEE : swap->myfee.coin->txfee,1,0,swap->persistent_privkey,swap->changermd160,coinaddr) == 0 ) { printf("rawtxsend %s %.8f\n",swap->myfee.coin->symbol,dstr(strcmp(swap->myfee.coin->symbol,"BTC") == 0 ? LP_MIN_TXFEE : swap->myfee.coin->txfee)); swap->I.statebits |= LP_swapdata_rawtxsend(pairsock,swap,0x80,data,maxlen,&swap->myfee,0x40,0); From 153fdbfbc6f629e1a287e071b1cd5f89d38a5486 Mon Sep 17 00:00:00 2001 From: jl777 Date: Tue, 7 Nov 2017 20:20:05 +0200 Subject: [PATCH 0307/1664] Test --- iguana/exchanges/LP_transaction.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/iguana/exchanges/LP_transaction.c b/iguana/exchanges/LP_transaction.c index bea8733c9..a2537ba16 100644 --- a/iguana/exchanges/LP_transaction.c +++ b/iguana/exchanges/LP_transaction.c @@ -1011,7 +1011,7 @@ char *LP_createrawtransaction(cJSON **txobjp,int32_t *numvinsp,struct iguana_inf else if ( coin->numutxos >= LP_MINDESIRED_UTXOS ) dustcombine = 2; else dustcombine = 1; -dustcombine = 2; +dustcombine = 0; amount = txfee; for (i=0; i Date: Tue, 7 Nov 2017 20:30:31 +0200 Subject: [PATCH 0308/1664] Test --- iguana/exchanges/LP_transaction.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/iguana/exchanges/LP_transaction.c b/iguana/exchanges/LP_transaction.c index a2537ba16..eceb35d2a 100644 --- a/iguana/exchanges/LP_transaction.c +++ b/iguana/exchanges/LP_transaction.c @@ -892,7 +892,6 @@ int32_t LP_vins_select(void *ctx,struct iguana_info *coin,int64_t *totalp,int64_ } else { - free_json(txobj); if ( LP_inventory_prevent(1,coin->symbol,up->U.txid,up->U.vout) == 0 ) { if ( min1 == 0 || up->U.value < min1->U.value ) @@ -904,6 +903,9 @@ int32_t LP_vins_select(void *ctx,struct iguana_info *coin,int64_t *totalp,int64_ } else min1 = up; } } else utxos[j] = 0; + if ( utxos[j] != 0 ) + printf("gettxout j.%d (%s)\n",j,jprint(txobj,0)); + free_json(txobj); } } else utxos[j] = 0; } @@ -976,7 +978,7 @@ int32_t LP_vins_select(void *ctx,struct iguana_info *coin,int64_t *totalp,int64_ vp->suppress_pubkeys = suppress_pubkeys; vp->ignore_cltverr = ignore_cltverr; jaddi(vins,LP_inputjson(up->U.txid,up->U.vout,spendscriptstr)); - if ( remains <= 0 && i >= numpre ) + if ( remains <= 0 && i >= numpre-1 ) break; if ( numunspents == 0 ) { From 22f4e2d0e14febc78f2ac28c5bc6ca0998285508 Mon Sep 17 00:00:00 2001 From: jl777 Date: Tue, 7 Nov 2017 20:40:25 +0200 Subject: [PATCH 0309/1664] Test --- iguana/exchanges/LP_transaction.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/iguana/exchanges/LP_transaction.c b/iguana/exchanges/LP_transaction.c index eceb35d2a..8c3796eee 100644 --- a/iguana/exchanges/LP_transaction.c +++ b/iguana/exchanges/LP_transaction.c @@ -865,7 +865,7 @@ int64_t LP_komodo_interest(bits256 txid,int64_t value) 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,bits256 utxotxid,int32_t utxovout,int32_t dustcombine) { - char wifstr[128],spendscriptstr[128]; int32_t i,j,n,numpre,ind,abovei,belowi,maxmode=0; struct vin_info *vp; cJSON *txobj; struct LP_address_utxo *up,*min0,*min1,*preselected[3]; int64_t value,interest,interestsum,above,below,remains = amount,total = 0; + char wifstr[128],spendscriptstr[128],str[65]; int32_t i,j,n,numpre,ind,abovei,belowi,maxmode=0; struct vin_info *vp; cJSON *txobj; struct LP_address_utxo *up,*min0,*min1,*preselected[3]; int64_t value,interest,interestsum,above,below,remains = amount,total = 0; *totalp = 0; interestsum = 0; init_hexbytes_noT(spendscriptstr,script,scriptlen); @@ -904,7 +904,7 @@ int32_t LP_vins_select(void *ctx,struct iguana_info *coin,int64_t *totalp,int64_ } } else utxos[j] = 0; if ( utxos[j] != 0 ) - printf("gettxout j.%d (%s)\n",j,jprint(txobj,0)); + printf("gettxout j.%d %s/v%d (%s)\n",j,bits256_str(str,up->U.txid),up->U.vout,jprint(txobj,0)); free_json(txobj); } } else utxos[j] = 0; @@ -1013,7 +1013,7 @@ char *LP_createrawtransaction(cJSON **txobjp,int32_t *numvinsp,struct iguana_inf else if ( coin->numutxos >= LP_MINDESIRED_UTXOS ) dustcombine = 2; else dustcombine = 1; -dustcombine = 0; +dustcombine = 2; amount = txfee; for (i=0; i Date: Tue, 7 Nov 2017 20:43:10 +0200 Subject: [PATCH 0310/1664] Test --- iguana/exchanges/LP_transaction.c | 13 +------------ 1 file changed, 1 insertion(+), 12 deletions(-) diff --git a/iguana/exchanges/LP_transaction.c b/iguana/exchanges/LP_transaction.c index 8c3796eee..b23e44d96 100644 --- a/iguana/exchanges/LP_transaction.c +++ b/iguana/exchanges/LP_transaction.c @@ -694,14 +694,6 @@ char *basilisk_swap_bobtxspend(bits256 *signedtxidp,uint64_t txfee,char *name,ch jaddistr(privkeys,wifstr); V[0].suppress_pubkeys = suppress_pubkeys; V[0].ignore_cltverr = ignore_cltverr; - /*for (i=0; iotherfee.I.locktime - (swap->I.started+1); if ( diff < 0 ) diff = -diff; - if ( diff < 30 ) + if ( diff == 0 ) printf("dexfee verified\n"); else printf("locktime mismatch in otherfee, reject %u vs %u\n",swap->otherfee.I.locktime,swap->I.started+1); return(0); From 25883e2a1cbdf291423a98b4fe30e8cdb7c3adee Mon Sep 17 00:00:00 2001 From: jl777 Date: Tue, 7 Nov 2017 20:48:17 +0200 Subject: [PATCH 0311/1664] Test --- iguana/exchanges/LP_transaction.c | 1 + 1 file changed, 1 insertion(+) diff --git a/iguana/exchanges/LP_transaction.c b/iguana/exchanges/LP_transaction.c index b23e44d96..7d616fd4b 100644 --- a/iguana/exchanges/LP_transaction.c +++ b/iguana/exchanges/LP_transaction.c @@ -949,6 +949,7 @@ int32_t LP_vins_select(void *ctx,struct iguana_info *coin,int64_t *totalp,int64_ utxos[ind] = utxos[--numunspents]; utxos[numunspents] = 0; } + up->spendheight = 1; total += up->U.value; remains -= up->U.value; if ( up->U.height < 7777777 && strcmp(coin->symbol,"KMD") == 0 ) From 0022c5b86c669fdeb55a960982ee84bc95c58e86 Mon Sep 17 00:00:00 2001 From: jl777 Date: Tue, 7 Nov 2017 20:54:47 +0200 Subject: [PATCH 0312/1664] Test --- iguana/exchanges/LP_transaction.c | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/iguana/exchanges/LP_transaction.c b/iguana/exchanges/LP_transaction.c index 7d616fd4b..d6c9407ac 100644 --- a/iguana/exchanges/LP_transaction.c +++ b/iguana/exchanges/LP_transaction.c @@ -916,9 +916,9 @@ int32_t LP_vins_select(void *ctx,struct iguana_info *coin,int64_t *totalp,int64_ return(0); } } - if ( dustcombine >= 1 && min0 != 0 ) + if ( dustcombine >= 1 && min0 != 0 && min0->U.value < SATOSHIDEN ) preselected[numpre++] = min0; - if ( dustcombine >= 2 && min1 != 0 ) + if ( dustcombine >= 2 && min1 != 0 && min1->U.value < SATOSHIDEN ) preselected[numpre++] = min1; printf("dustcombine.%d numpre.%d min0.%p min1.%p numutxos.%d\n",dustcombine,numpre,min0,min1,numunspents); for (i=0; inumutxos >= LP_MINDESIRED_UTXOS ) dustcombine = 2; else dustcombine = 1; -dustcombine = 2; amount = txfee; for (i=0; i Date: Tue, 7 Nov 2017 21:04:07 +0200 Subject: [PATCH 0313/1664] Test --- iguana/exchanges/LP_transaction.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/iguana/exchanges/LP_transaction.c b/iguana/exchanges/LP_transaction.c index d6c9407ac..ee7d28a07 100644 --- a/iguana/exchanges/LP_transaction.c +++ b/iguana/exchanges/LP_transaction.c @@ -1037,7 +1037,7 @@ char *LP_createrawtransaction(cJSON **txobjp,int32_t *numvinsp,struct iguana_inf if ( (numutxos= LP_address_utxo_ptrs(coin,0,utxos,max,ap,coin->smartaddr)) <= 0 ) { printf("LP_createrawtransaction: address_utxo_ptrs %d, error\n",numutxos); - return(0); + //return(0); } ignore_cltverr = 0; suppress_pubkeys = 1; From 3b48785e8ce4cdf6a73cac166a7c2c7d168b5269 Mon Sep 17 00:00:00 2001 From: jl777 Date: Tue, 7 Nov 2017 21:27:53 +0200 Subject: [PATCH 0314/1664] Test --- iguana/exchanges/LP_commands.c | 12 ++++++------ iguana/exchanges/LP_transaction.c | 2 +- 2 files changed, 7 insertions(+), 7 deletions(-) diff --git a/iguana/exchanges/LP_commands.c b/iguana/exchanges/LP_commands.c index f7927ba8a..af12cb1c2 100644 --- a/iguana/exchanges/LP_commands.c +++ b/iguana/exchanges/LP_commands.c @@ -69,12 +69,12 @@ char *stats_JSON(void *ctx,char *myipaddr,int32_t pubsock,cJSON *argjson,char *r printf("stats_JSON no method: (%s) (%s:%u)\n",jprint(argjson,0),ipaddr,argport); return(0); } - /*if ( strcmp(method,"hello") == 0 ) - { - //printf("got hello from %s:%u\n",ipaddr!=0?ipaddr:"",argport); - return(0); - } - else*/ if ( strcmp(method,"sendmessage") == 0 && jobj(argjson,"userpass") == 0 ) + if ( strcmp(method,"hello") == 0 ) + { + //printf("got hello from %s:%u\n",ipaddr!=0?ipaddr:"",argport); + return(clonestr("{\"result\":\"success\",\"status\":\"got hello\"}")); + } + else if ( strcmp(method,"sendmessage") == 0 && jobj(argjson,"userpass") == 0 ) { static char *laststr; char *newstr; bits256 pubkey = jbits256(argjson,"pubkey"); diff --git a/iguana/exchanges/LP_transaction.c b/iguana/exchanges/LP_transaction.c index ee7d28a07..595f505b0 100644 --- a/iguana/exchanges/LP_transaction.c +++ b/iguana/exchanges/LP_transaction.c @@ -892,7 +892,7 @@ int32_t LP_vins_select(void *ctx,struct iguana_info *coin,int64_t *totalp,int64_ } else min1 = up; } } else utxos[j] = 0; - if ( utxos[j] != 0 ) + if ( 0 && utxos[j] != 0 ) printf("gettxout j.%d %s/v%d (%s)\n",j,bits256_str(str,up->U.txid),up->U.vout,jprint(txobj,0)); free_json(txobj); } From c05c7629be6fc387791911beb0399568dac24d64 Mon Sep 17 00:00:00 2001 From: jl777 Date: Tue, 7 Nov 2017 21:41:41 +0200 Subject: [PATCH 0315/1664] Test --- iguana/exchanges/LP_transaction.c | 24 +++++++++++++++++++++--- 1 file changed, 21 insertions(+), 3 deletions(-) diff --git a/iguana/exchanges/LP_transaction.c b/iguana/exchanges/LP_transaction.c index 595f505b0..6e2b4db1d 100644 --- a/iguana/exchanges/LP_transaction.c +++ b/iguana/exchanges/LP_transaction.c @@ -854,7 +854,7 @@ int64_t LP_komodo_interest(bits256 txid,int64_t value) 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,bits256 utxotxid,int32_t utxovout,int32_t dustcombine) { - char wifstr[128],spendscriptstr[128],str[65]; int32_t i,j,n,numpre,ind,abovei,belowi,maxmode=0; struct vin_info *vp; cJSON *txobj; struct LP_address_utxo *up,*min0,*min1,*preselected[3]; int64_t value,interest,interestsum,above,below,remains = amount,total = 0; + char wifstr[128],spendscriptstr[128],str[65]; int32_t i,j,n,numpre,ind,abovei,belowi,maxmode=0; struct vin_info *vp; cJSON *txobj; struct LP_address_utxo *up,*min0,*min1,*preselected[3]; struct electrum_info *ep,*backupep; int64_t value,interest,interestsum,above,below,remains = amount,total = 0; *totalp = 0; interestsum = 0; init_hexbytes_noT(spendscriptstr,script,scriptlen); @@ -916,10 +916,12 @@ int32_t LP_vins_select(void *ctx,struct iguana_info *coin,int64_t *totalp,int64_ return(0); } } - if ( dustcombine >= 1 && min0 != 0 && min0->U.value < SATOSHIDEN ) + if ( dustcombine >= 1 && min0 != 0 && min0->U.value < SATOSHIDEN && (coin->electrum == 0 || min0->SPV > 0) ) preselected[numpre++] = min0; - if ( dustcombine >= 2 && min1 != 0 && min1->U.value < SATOSHIDEN ) + else min0 = 0; + if ( dustcombine >= 2 && min1 != 0 && min1->U.value < SATOSHIDEN && (coin->electrum == 0 || min1->SPV > 0) ) preselected[numpre++] = min1; + else min1 = 0; printf("dustcombine.%d numpre.%d min0.%p min1.%p numutxos.%d\n",dustcombine,numpre,min0,min1,numunspents); for (i=0; ielectrum) != 0 && up->SPV <= 0 ) + { + if ( up->SPV < 0 ) + continue; + if ( (backupep= ep->prev) == 0 ) + backupep = ep; + up->SPV = LP_merkleproof(coin,backupep,up->U.txid,up->U.height); + if ( up->SPV <= 0 ) + continue; + } } + up->spendheight = 1; total += up->U.value; remains -= up->U.value; From 59e0222ef07aadd400026cc0502e0c617c180bf1 Mon Sep 17 00:00:00 2001 From: jl777 Date: Tue, 7 Nov 2017 21:59:46 +0200 Subject: [PATCH 0316/1664] Test --- iguana/exchanges/LP_include.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/iguana/exchanges/LP_include.h b/iguana/exchanges/LP_include.h index 1920c475e..d0d2d282b 100644 --- a/iguana/exchanges/LP_include.h +++ b/iguana/exchanges/LP_include.h @@ -39,7 +39,7 @@ void emscripten_usleep(int32_t x); // returns immediate, no sense for sleeping #define LP_HTTP_TIMEOUT 3 // 1 is too small due to edge cases of time(NULL) #define LP_AUTOTRADE_TIMEOUT 20 -#define ELECTRUM_TIMEOUT 10 +#define ELECTRUM_TIMEOUT 20 #define LP_ELECTRUM_KEEPALIVE 60 #define LP_ELECTRUM_MAXERRORS 777 #define LP_MEMPOOL_TIMEINCR 10 From 2f5cb12eddc48e0ade407d2068e21ba7a99c1e10 Mon Sep 17 00:00:00 2001 From: jl777 Date: Tue, 7 Nov 2017 22:12:27 +0200 Subject: [PATCH 0317/1664] Test --- iguana/exchanges/LP_nativeDEX.c | 1 + 1 file changed, 1 insertion(+) diff --git a/iguana/exchanges/LP_nativeDEX.c b/iguana/exchanges/LP_nativeDEX.c index 59908163d..b9ecb4f8a 100644 --- a/iguana/exchanges/LP_nativeDEX.c +++ b/iguana/exchanges/LP_nativeDEX.c @@ -595,6 +595,7 @@ void LP_coinsloop(void *_coins) backupep = ep; HASH_ITER(hh,coin->addresses,ap,atmp) { + break; DL_FOREACH_SAFE(ap->utxos,up,tmp) { if ( up->U.height > 0 && up->spendheight < 0 ) From b018ee6374b1ea1156b534adb425cd6dfd73cb18 Mon Sep 17 00:00:00 2001 From: jl777 Date: Tue, 7 Nov 2017 22:29:04 +0200 Subject: [PATCH 0318/1664] Test --- iguana/exchanges/LP_include.h | 1 + iguana/exchanges/LP_nativeDEX.c | 2 +- iguana/exchanges/LP_ordermatch.c | 54 +++++++++++++++++++++++++++++-- iguana/exchanges/LP_transaction.c | 14 ++------ 4 files changed, 57 insertions(+), 14 deletions(-) diff --git a/iguana/exchanges/LP_include.h b/iguana/exchanges/LP_include.h index d0d2d282b..bafcc2950 100644 --- a/iguana/exchanges/LP_include.h +++ b/iguana/exchanges/LP_include.h @@ -408,6 +408,7 @@ struct LP_address_utxo *LP_address_utxofind(struct iguana_info *coin,char *coina int32_t LP_destaddr(char *destaddr,cJSON *item); int32_t LP_waitmempool(char *symbol,char *coinaddr,bits256 txid,int32_t vout,int32_t duration); char *LP_statslog_disp(int32_t n,uint32_t starttime,uint32_t endtime,char *refgui,bits256 refpubkey); +int32_t LP_validSPV(char *symbol,char *coinaddr,bits256 txid,int32_t vout); struct LP_transaction *LP_transactionfind(struct iguana_info *coin,bits256 txid); cJSON *LP_transactioninit(struct iguana_info *coin,bits256 txid,int32_t iter,cJSON *txobj); int32_t LP_mempoolscan(char *symbol,bits256 searchtxid); diff --git a/iguana/exchanges/LP_nativeDEX.c b/iguana/exchanges/LP_nativeDEX.c index b9ecb4f8a..86bb4fcdd 100644 --- a/iguana/exchanges/LP_nativeDEX.c +++ b/iguana/exchanges/LP_nativeDEX.c @@ -595,7 +595,7 @@ void LP_coinsloop(void *_coins) backupep = ep; HASH_ITER(hh,coin->addresses,ap,atmp) { - break; + break; // causes timeouts probably due to too much usage, SPV validation done on tx spending DL_FOREACH_SAFE(ap->utxos,up,tmp) { if ( up->U.height > 0 && up->spendheight < 0 ) diff --git a/iguana/exchanges/LP_ordermatch.c b/iguana/exchanges/LP_ordermatch.c index 582dc3733..8130706bf 100644 --- a/iguana/exchanges/LP_ordermatch.c +++ b/iguana/exchanges/LP_ordermatch.c @@ -246,7 +246,7 @@ int32_t LP_nearest_utxovalue(struct iguana_info *coin,char *coinaddr,struct LP_a //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 || up->SPV > 0) && dist >= 0 && dist < mindist ) + if ( dist >= 0 && dist < mindist ) //(coin->electrum == 0 || up->SPV > 0) && { //printf("(%.8f %.8f %.8f).%d ",dstr(up->U.value),dstr(dist),dstr(mindist),mini); mini = i; @@ -594,6 +594,26 @@ int32_t LP_aliceonly(char *symbol) else return(0); } +int32_t LP_validSPV(char *symbol,char *coinaddr,bits256 txid,int32_t vout) +{ + struct electrum_info *ep,*backupep; struct LP_address_utxo *up; struct iguana_info *coin; + coin = LP_coinfind(symbol); + if ( coin != 0 && (ep= coin->electrum) != 0 ) + { + if ( (up= LP_address_utxofind(coin,coinaddr,txid,vout)) != 0 ) + { + if ( up->SPV < 0 ) + return(-1); + if ( (backupep= ep->prev) == 0 ) + backupep = ep; + up->SPV = LP_merkleproof(coin,backupep,up->U.txid,up->U.height); + if ( up->SPV <= 0 ) + return(-1); + } + } + return(0); +} + int32_t LP_tradecommand(void *ctx,char *myipaddr,int32_t pubsock,cJSON *argjson,uint8_t *data,int32_t datalen) { 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,recalc,max=(int32_t)(sizeof(utxos)/sizeof(*utxos)); @@ -605,8 +625,28 @@ int32_t LP_tradecommand(void *ctx,char *myipaddr,int32_t pubsock,cJSON *argjson, LP_tradecommand_log(argjson); //printf("LP_tradecommand: check received method %s aliceid.%llx\n",method,(long long)Q.aliceid); retval = 1; + if ( LP_validSPV(Q.destcoin,Q.destaddr,Q.desttxid,Q.destvout) < 0 ) + { + printf("%s dest %s failed SPV check\n",Q.destcoin,bits256_str(str,Q.desttxid)); + return(retval); + } + else if (LP_validSPV(Q.destcoin,Q.destaddr,Q.feetxid,Q.feevout) < 0 ) + { + printf("%s dexfee %s failed SPV check\n",Q.destcoin,bits256_str(str,Q.feetxid)); + return(retval); + } if ( strcmp(method,"reserved") == 0 ) { + if ( LP_validSPV(Q.srccoin,Q.coinaddr,Q.txid,Q.vout) < 0 ) + { + printf("%s src %s failed SPV check\n",Q.srccoin,bits256_str(str,Q.txid)); + return(retval); + } + else if (LP_validSPV(Q.srccoin,Q.coinaddr,Q.txid2,Q.vout2) < 0 ) + { + printf("%s src2 %s failed SPV check\n",Q.srccoin,bits256_str(str,Q.txid2)); + return(retval); + } if ( bits256_cmp(G.LP_mypub25519,Q.desthash) == 0 && bits256_cmp(G.LP_mypub25519,Q.srchash) != 0 && LP_alice_eligible() > 0 ) { printf("alice %s received RESERVED.(%s)\n",bits256_str(str,G.LP_mypub25519),jprint(argjson,0)); @@ -620,7 +660,17 @@ int32_t LP_tradecommand(void *ctx,char *myipaddr,int32_t pubsock,cJSON *argjson, { 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 ( LP_validSPV(Q.srccoin,Q.coinaddr,Q.txid,Q.vout) < 0 ) + { + printf("%s src %s failed SPV check\n",Q.srccoin,bits256_str(str,Q.txid)); + return(retval); + } + else if (LP_validSPV(Q.srccoin,Q.coinaddr,Q.txid2,Q.vout2) < 0 ) + { + printf("%s src2 %s failed SPV check\n",Q.srccoin,bits256_str(str,Q.txid2)); + return(retval); + } + //printf("alice %s received CONNECTED.(%s)\n",bits256_str(str,G.LP_mypub25519),jprint(argjson,0)); if ( (retstr= LP_connectedalice(argjson)) != 0 ) free(retstr); } diff --git a/iguana/exchanges/LP_transaction.c b/iguana/exchanges/LP_transaction.c index 6e2b4db1d..48e710878 100644 --- a/iguana/exchanges/LP_transaction.c +++ b/iguana/exchanges/LP_transaction.c @@ -854,7 +854,7 @@ int64_t LP_komodo_interest(bits256 txid,int64_t value) 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,bits256 utxotxid,int32_t utxovout,int32_t dustcombine) { - char wifstr[128],spendscriptstr[128],str[65]; int32_t i,j,n,numpre,ind,abovei,belowi,maxmode=0; struct vin_info *vp; cJSON *txobj; struct LP_address_utxo *up,*min0,*min1,*preselected[3]; struct electrum_info *ep,*backupep; int64_t value,interest,interestsum,above,below,remains = amount,total = 0; + char wifstr[128],spendscriptstr[128],str[65]; int32_t i,j,n,numpre,ind,abovei,belowi,maxmode=0; struct vin_info *vp; cJSON *txobj; struct LP_address_utxo *up,*min0,*min1,*preselected[3]; int64_t value,interest,interestsum,above,below,remains = amount,total = 0; *totalp = 0; interestsum = 0; init_hexbytes_noT(spendscriptstr,script,scriptlen); @@ -955,16 +955,8 @@ int32_t LP_vins_select(void *ctx,struct iguana_info *coin,int64_t *totalp,int64_ break; if ( j < numpre ) continue; - if ( (ep= coin->electrum) != 0 && up->SPV <= 0 ) - { - if ( up->SPV < 0 ) - continue; - if ( (backupep= ep->prev) == 0 ) - backupep = ep; - up->SPV = LP_merkleproof(coin,backupep,up->U.txid,up->U.height); - if ( up->SPV <= 0 ) - continue; - } + if ( LP_validSPV(coin->symbol,coin->smartaddr,up->U.txid,up->U.vout) < 0 ) + continue; } up->spendheight = 1; From 821ed9528e0e6d77aecfa008c391723fe5f0aa62 Mon Sep 17 00:00:00 2001 From: jl777 Date: Tue, 7 Nov 2017 22:35:26 +0200 Subject: [PATCH 0319/1664] Test --- iguana/exchanges/LP_rpc.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/iguana/exchanges/LP_rpc.c b/iguana/exchanges/LP_rpc.c index 25f2c9b7d..959000fee 100644 --- a/iguana/exchanges/LP_rpc.c +++ b/iguana/exchanges/LP_rpc.c @@ -578,7 +578,7 @@ cJSON *LP_gettxout(char *symbol,char *coinaddr,bits256 txid,int32_t vout) return(retjson); } } - printf("couldnt find %s/v%d\n",bits256_str(str,txid),vout); + printf("couldnt find %s (%s) %s/v%d\n",symbol,coinaddr,bits256_str(str,txid),vout); return(cJSON_Parse("{\"error\":\"couldnt get tx\"}")); } } From 31b600ea2c1ee7d54f634e600bcac7158b3e9c04 Mon Sep 17 00:00:00 2001 From: jl777 Date: Tue, 7 Nov 2017 22:49:40 +0200 Subject: [PATCH 0320/1664] Test --- iguana/exchanges/LP_socket.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/iguana/exchanges/LP_socket.c b/iguana/exchanges/LP_socket.c index 28b7d2e16..c609a62d4 100644 --- a/iguana/exchanges/LP_socket.c +++ b/iguana/exchanges/LP_socket.c @@ -602,7 +602,7 @@ cJSON *electrum_address_listunspent(char *symbol,struct electrum_info *ep,cJSON if ( strcmp(addr,coin->smartaddr) == 0 ) { retstr = jprint(retjson,0); - LP_unspents_cache(coin->symbol,coin->smartaddr,retstr,updatedflag); + LP_unspents_cache(coin->symbol,coin->smartaddr,retstr,1); free(retstr); } if ( ap != 0 ) From 47817e762c8bb13c3ad58d9ea3065f8a5ef5106d Mon Sep 17 00:00:00 2001 From: jl777 Date: Tue, 7 Nov 2017 23:02:32 +0200 Subject: [PATCH 0321/1664] Test --- iguana/exchanges/LP_include.h | 1 + iguana/exchanges/LP_utxo.c | 50 +++++++++++++++++++++++++++++------ 2 files changed, 43 insertions(+), 8 deletions(-) diff --git a/iguana/exchanges/LP_include.h b/iguana/exchanges/LP_include.h index bafcc2950..1f63d7f2d 100644 --- a/iguana/exchanges/LP_include.h +++ b/iguana/exchanges/LP_include.h @@ -408,6 +408,7 @@ struct LP_address_utxo *LP_address_utxofind(struct iguana_info *coin,char *coina int32_t LP_destaddr(char *destaddr,cJSON *item); int32_t LP_waitmempool(char *symbol,char *coinaddr,bits256 txid,int32_t vout,int32_t duration); char *LP_statslog_disp(int32_t n,uint32_t starttime,uint32_t endtime,char *refgui,bits256 refpubkey); +uint64_t LP_unspents_load(char *symbol,char *addr); int32_t LP_validSPV(char *symbol,char *coinaddr,bits256 txid,int32_t vout); struct LP_transaction *LP_transactionfind(struct iguana_info *coin,bits256 txid); cJSON *LP_transactioninit(struct iguana_info *coin,bits256 txid,int32_t iter,cJSON *txobj); diff --git a/iguana/exchanges/LP_utxo.c b/iguana/exchanges/LP_utxo.c index b66f73930..4cbe86e58 100644 --- a/iguana/exchanges/LP_utxo.c +++ b/iguana/exchanges/LP_utxo.c @@ -472,13 +472,38 @@ cJSON *LP_address_utxos(struct iguana_info *coin,char *coinaddr,int32_t electrum cJSON *LP_address_balance(struct iguana_info *coin,char *coinaddr,int32_t electrumret) { - cJSON *array,*retjson; int32_t i,n; uint64_t balance = 0; - if ( (array= LP_address_utxos(coin,coinaddr,1)) != 0 ) + cJSON *array,*retjson,*item; int32_t i,n; uint64_t balance = 0; + if ( coin->electrum == 0 ) { - if ( (n= cJSON_GetArraySize(array)) > 0 ) + if ( (array= LP_listunspent(coin->symbol,coinaddr)) != 0 ) { - for (i=0; i 0 ) + { + for (i=0; ismartaddr,coinaddr) == 0 ) + balance = LP_unspents_load(coin->symbol,coinaddr); + else + { + if ( (array= LP_address_utxos(coin,coinaddr,1)) != 0 ) + { + if ( (n= cJSON_GetArraySize(array)) > 0 ) + { + for (i=0; i 0 ) + { + for (i=0; ielectrum,coin->smartaddr,retjson,1); free_json(retjson); } free(arraystr); } } + return(balance); } From 039476f993ddb83a6cbf257264eafdf3202914ce Mon Sep 17 00:00:00 2001 From: jl777 Date: Tue, 7 Nov 2017 23:06:07 +0200 Subject: [PATCH 0322/1664] Test --- iguana/exchanges/LP_include.h | 1 + iguana/exchanges/LP_transaction.c | 4 ++-- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/iguana/exchanges/LP_include.h b/iguana/exchanges/LP_include.h index 1f63d7f2d..4ccfa4d71 100644 --- a/iguana/exchanges/LP_include.h +++ b/iguana/exchanges/LP_include.h @@ -49,6 +49,7 @@ void emscripten_usleep(int32_t x); // returns immediate, no sense for sleeping #define LP_MAXDESIRED_UTXOS 128 #define LP_MINDESIRED_UTXOS 32 +#define LP_DUSTCOMBINE_THRESHOLD 1000000 // RTmetrics #define LP_RTMETRICS_TOPGROUP 1.01 diff --git a/iguana/exchanges/LP_transaction.c b/iguana/exchanges/LP_transaction.c index 48e710878..3148e9f0f 100644 --- a/iguana/exchanges/LP_transaction.c +++ b/iguana/exchanges/LP_transaction.c @@ -916,10 +916,10 @@ int32_t LP_vins_select(void *ctx,struct iguana_info *coin,int64_t *totalp,int64_ return(0); } } - if ( dustcombine >= 1 && min0 != 0 && min0->U.value < SATOSHIDEN && (coin->electrum == 0 || min0->SPV > 0) ) + if ( dustcombine >= 1 && min0 != 0 && min0->U.value < LP_DUSTCOMBINE_THRESHOLD && (coin->electrum == 0 || min0->SPV > 0) ) preselected[numpre++] = min0; else min0 = 0; - if ( dustcombine >= 2 && min1 != 0 && min1->U.value < SATOSHIDEN && (coin->electrum == 0 || min1->SPV > 0) ) + if ( dustcombine >= 2 && min1 != 0 && min1->U.value < LP_DUSTCOMBINE_THRESHOLD && (coin->electrum == 0 || min1->SPV > 0) ) preselected[numpre++] = min1; else min1 = 0; printf("dustcombine.%d numpre.%d min0.%p min1.%p numutxos.%d\n",dustcombine,numpre,min0,min1,numunspents); From b4ba8618654e1b22e9312e38fba0a9f9d54ae7da Mon Sep 17 00:00:00 2001 From: jl777 Date: Tue, 7 Nov 2017 23:10:54 +0200 Subject: [PATCH 0323/1664] Test --- iguana/exchanges/LP_nativeDEX.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/iguana/exchanges/LP_nativeDEX.c b/iguana/exchanges/LP_nativeDEX.c index 86bb4fcdd..97b9e042a 100644 --- a/iguana/exchanges/LP_nativeDEX.c +++ b/iguana/exchanges/LP_nativeDEX.c @@ -627,7 +627,7 @@ void LP_coinsloop(void *_coins) if ( time(NULL) > ep->keepalive+LP_ELECTRUM_KEEPALIVE ) { //printf("%s electrum.%p needs a keepalive: lag.%d\n",ep->symbol,ep,(int32_t)(time(NULL) - ep->keepalive)); - if ( (retjson= electrum_donation(ep->symbol,ep,&retjson)) != 0 ) + if ( (retjson= electrum_address_listunspent(coin->symbol,ep,&retjson,coin->smartaddr,1)) != 0 ) free_json(retjson); } ep = ep->prev; From 34d129f955541e961c1debb69a1df4531abc035d Mon Sep 17 00:00:00 2001 From: jl777 Date: Tue, 7 Nov 2017 23:19:11 +0200 Subject: [PATCH 0324/1664] Test --- iguana/exchanges/LP_include.h | 2 +- iguana/exchanges/LP_nativeDEX.c | 8 ++++++-- iguana/exchanges/stats.c | 19 ++++++++++--------- 3 files changed, 17 insertions(+), 12 deletions(-) diff --git a/iguana/exchanges/LP_include.h b/iguana/exchanges/LP_include.h index 4ccfa4d71..0e7ce20b1 100644 --- a/iguana/exchanges/LP_include.h +++ b/iguana/exchanges/LP_include.h @@ -255,7 +255,7 @@ struct iguana_info 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 importedprivkey,lastpushtime,lastutxosync,addr_listunspent_requested,lastutxos,updaterate,counter,inactive,lastmempool,lastgetinfo,ratetime,heighttime,lastmonitor,obooktime; + uint32_t 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[16],smartaddr[64],userpass[1024],serverport[128]; // portfolio diff --git a/iguana/exchanges/LP_nativeDEX.c b/iguana/exchanges/LP_nativeDEX.c index 97b9e042a..0294018d3 100644 --- a/iguana/exchanges/LP_nativeDEX.c +++ b/iguana/exchanges/LP_nativeDEX.c @@ -19,8 +19,6 @@ // marketmaker // // selftest and fix rpc port -// quotevalidate to do SPV -// autoadd dust utxo to vin for initial atomic tx // verify portfolio, interest to KMD withdraw // dPoW security -> 4: KMD notarized, 5: BTC notarized, after next notary elections // bigendian architectures need to use little endian for sighash calcs @@ -622,6 +620,12 @@ void LP_coinsloop(void *_coins) } } } + if ( time(NULL) > coin->lastunspent+30 ) + { + if ( (retjson= electrum_address_listunspent(coin->symbol,ep,&retjson,coin->smartaddr,1)) != 0 ) + free_json(retjson); + coin->lastunspent = (uint32_t)time(NULL); + } while ( ep != 0 ) { if ( time(NULL) > ep->keepalive+LP_ELECTRUM_KEEPALIVE ) diff --git a/iguana/exchanges/stats.c b/iguana/exchanges/stats.c index e56227223..cd1249c0b 100644 --- a/iguana/exchanges/stats.c +++ b/iguana/exchanges/stats.c @@ -740,30 +740,31 @@ void LP_rpc_processreq(void *_ptr) } extern int32_t IAMLP; +int32_t LP_bindsock = -1; void stats_rpcloop(void *args) { static uint32_t counter; - uint16_t port; int32_t retval,sock,bindsock=-1; socklen_t clilen; struct sockaddr_in cli_addr; uint32_t ipbits,localhostbits; struct rpcrequest_info *req,*req2,*rtmp; + uint16_t port; int32_t retval,sock; socklen_t clilen; struct sockaddr_in cli_addr; uint32_t ipbits,localhostbits; struct rpcrequest_info *req,*req2,*rtmp; if ( (port= *(uint16_t *)args) == 0 ) port = 7779; RPC_port = port; localhostbits = (uint32_t)calc_ipbits("127.0.0.1"); while ( 1 ) { - if ( bindsock < 0 ) + if ( LP_bindsock < 0 ) { - while ( (bindsock= iguana_socket(1,"0.0.0.0",port)) < 0 ) + while ( (LP_bindsock= iguana_socket(1,"0.0.0.0",port)) < 0 ) usleep(10000); if ( counter++ < 1 ) - printf(">>>>>>>>>> DEX stats 127.0.0.1:%d bind sock.%d DEX stats API enabled <<<<<<<<<\n",port,bindsock); + printf(">>>>>>>>>> DEX stats 127.0.0.1:%d bind sock.%d DEX stats API enabled <<<<<<<<<\n",port,LP_bindsock); } clilen = sizeof(cli_addr); - sock = accept(bindsock,(struct sockaddr *)&cli_addr,&clilen); + sock = accept(LP_bindsock,(struct sockaddr *)&cli_addr,&clilen); if ( sock < 0 ) { printf("iguana_rpcloop ERROR on accept usock.%d errno %d %s\n",sock,errno,strerror(errno)); - close(bindsock); - bindsock = -1; + close(LP_bindsock); + LP_bindsock = -1; continue; } memcpy(&ipbits,&cli_addr.sin_addr.s_addr,sizeof(ipbits)); @@ -775,8 +776,8 @@ continue; if ( (retval= OS_thread_create(&req->T,NULL,(void *)LP_rpc_processreq,req)) != 0 ) { printf("error launching rpc handler on port %d, retval.%d\n",port,retval); - close(bindsock); - bindsock = -1; + close(LP_bindsock); + LP_bindsock = -1; portable_mutex_lock(&LP_gcmutex); DL_FOREACH_SAFE(LP_garbage_collector,req2,rtmp) { From 52e69dfba5291773ee441be20a269d3e5928bde6 Mon Sep 17 00:00:00 2001 From: jl777 Date: Tue, 7 Nov 2017 23:22:42 +0200 Subject: [PATCH 0325/1664] Test --- iguana/exchanges/LP_nativeDEX.c | 1 + 1 file changed, 1 insertion(+) diff --git a/iguana/exchanges/LP_nativeDEX.c b/iguana/exchanges/LP_nativeDEX.c index 0294018d3..3d16e7dba 100644 --- a/iguana/exchanges/LP_nativeDEX.c +++ b/iguana/exchanges/LP_nativeDEX.c @@ -622,6 +622,7 @@ void LP_coinsloop(void *_coins) } if ( time(NULL) > coin->lastunspent+30 ) { + printf("call electrum listunspent.%s\n",coin->symbol); if ( (retjson= electrum_address_listunspent(coin->symbol,ep,&retjson,coin->smartaddr,1)) != 0 ) free_json(retjson); coin->lastunspent = (uint32_t)time(NULL); From db32a9faf2a04993cabaa30c4eb6cdaf97dd923f Mon Sep 17 00:00:00 2001 From: jl777 Date: Tue, 7 Nov 2017 23:25:42 +0200 Subject: [PATCH 0326/1664] Test --- iguana/exchanges/LP_nativeDEX.c | 2 +- iguana/exchanges/LP_socket.c | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/iguana/exchanges/LP_nativeDEX.c b/iguana/exchanges/LP_nativeDEX.c index 3d16e7dba..8c877aec4 100644 --- a/iguana/exchanges/LP_nativeDEX.c +++ b/iguana/exchanges/LP_nativeDEX.c @@ -623,7 +623,7 @@ void LP_coinsloop(void *_coins) if ( time(NULL) > coin->lastunspent+30 ) { printf("call electrum listunspent.%s\n",coin->symbol); - if ( (retjson= electrum_address_listunspent(coin->symbol,ep,&retjson,coin->smartaddr,1)) != 0 ) + if ( (retjson= electrum_address_listunspent(coin->symbol,ep,&retjson,coin->smartaddr,2)) != 0 ) free_json(retjson); coin->lastunspent = (uint32_t)time(NULL); } diff --git a/iguana/exchanges/LP_socket.c b/iguana/exchanges/LP_socket.c index c609a62d4..c759c764d 100644 --- a/iguana/exchanges/LP_socket.c +++ b/iguana/exchanges/LP_socket.c @@ -591,11 +591,11 @@ cJSON *electrum_address_listunspent(char *symbol,struct electrum_info *ep,cJSON usecache = 0; } //printf("electrum.%s/%s listunspent last.(%s lag %d)\n",ep->symbol,coin->symbol,coin->lastunspent,(int32_t)(time(NULL) - coin->unspenttime)); - if ( usecache == 0 ) + if ( usecache == 0 || electrumflag > 1 ) { if ( (retjson= electrum_strarg(symbol,ep,retjsonp,"blockchain.address.listunspent",addr,ELECTRUM_TIMEOUT)) != 0 ) { - //printf("%s.%d u.%u/%d t.%ld %s LISTUNSPENT.(%d)\n",coin->symbol,height,ap->unspenttime,ap->unspentheight,time(NULL),addr,(int32_t)strlen(jprint(retjson,0))); + printf("%s.%d u.%u/%d t.%ld %s LISTUNSPENT.(%d)\n",coin->symbol,height,ap->unspenttime,ap->unspentheight,time(NULL),addr,(int32_t)strlen(jprint(retjson,0))); updatedflag = 0; if ( electrum_process_array(coin,ep,addr,retjson,electrumflag) != 0 ) LP_postutxos(coin->symbol,addr), updatedflag = 1; From c655a72ed37c083d33d935ca56142a4167f64228 Mon Sep 17 00:00:00 2001 From: jl777 Date: Tue, 7 Nov 2017 23:27:42 +0200 Subject: [PATCH 0327/1664] Test --- iguana/exchanges/LP_nativeDEX.c | 2 +- iguana/exchanges/LP_socket.c | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/iguana/exchanges/LP_nativeDEX.c b/iguana/exchanges/LP_nativeDEX.c index 8c877aec4..0ba43d0b2 100644 --- a/iguana/exchanges/LP_nativeDEX.c +++ b/iguana/exchanges/LP_nativeDEX.c @@ -622,7 +622,7 @@ void LP_coinsloop(void *_coins) } if ( time(NULL) > coin->lastunspent+30 ) { - printf("call electrum listunspent.%s\n",coin->symbol); + //printf("call electrum listunspent.%s\n",coin->symbol); if ( (retjson= electrum_address_listunspent(coin->symbol,ep,&retjson,coin->smartaddr,2)) != 0 ) free_json(retjson); coin->lastunspent = (uint32_t)time(NULL); diff --git a/iguana/exchanges/LP_socket.c b/iguana/exchanges/LP_socket.c index c759c764d..1670591f9 100644 --- a/iguana/exchanges/LP_socket.c +++ b/iguana/exchanges/LP_socket.c @@ -595,7 +595,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("%s.%d u.%u/%d t.%ld %s LISTUNSPENT.(%d)\n",coin->symbol,height,ap->unspenttime,ap->unspentheight,time(NULL),addr,(int32_t)strlen(jprint(retjson,0))); + //printf("%s.%d u.%u/%d t.%ld %s LISTUNSPENT.(%d)\n",coin->symbol,height,ap->unspenttime,ap->unspentheight,time(NULL),addr,(int32_t)strlen(jprint(retjson,0))); updatedflag = 0; if ( electrum_process_array(coin,ep,addr,retjson,electrumflag) != 0 ) LP_postutxos(coin->symbol,addr), updatedflag = 1; From 0da65da7b0ebaa0129f91fd797f30c4c022bbbbd Mon Sep 17 00:00:00 2001 From: jl777 Date: Tue, 7 Nov 2017 23:33:14 +0200 Subject: [PATCH 0328/1664] Test --- iguana/exchanges/LP_nativeDEX.c | 6 ++++++ iguana/exchanges/stats.c | 8 ++++---- 2 files changed, 10 insertions(+), 4 deletions(-) diff --git a/iguana/exchanges/LP_nativeDEX.c b/iguana/exchanges/LP_nativeDEX.c index 0ba43d0b2..76e348c68 100644 --- a/iguana/exchanges/LP_nativeDEX.c +++ b/iguana/exchanges/LP_nativeDEX.c @@ -1179,6 +1179,12 @@ void LPinit(uint16_t myport,uint16_t mypullport,uint16_t mypubport,uint16_t mybu usleep(1000); else if ( IAMLP == 0 ) usleep(1000); + if ( (rand() % 10000) == 0 ) + { + printf("rpc port reset test\n"); + closesocket(LP_bindsock); + LP_bindsock = -1; + } } #endif } diff --git a/iguana/exchanges/stats.c b/iguana/exchanges/stats.c index cd1249c0b..24f78f5bf 100644 --- a/iguana/exchanges/stats.c +++ b/iguana/exchanges/stats.c @@ -743,7 +743,7 @@ extern int32_t IAMLP; int32_t LP_bindsock = -1; void stats_rpcloop(void *args) { - static uint32_t counter; + //static uint32_t counter; uint16_t port; int32_t retval,sock; socklen_t clilen; struct sockaddr_in cli_addr; uint32_t ipbits,localhostbits; struct rpcrequest_info *req,*req2,*rtmp; if ( (port= *(uint16_t *)args) == 0 ) port = 7779; @@ -755,7 +755,7 @@ void stats_rpcloop(void *args) { while ( (LP_bindsock= iguana_socket(1,"0.0.0.0",port)) < 0 ) usleep(10000); - if ( counter++ < 1 ) + //if ( counter++ < 1 ) printf(">>>>>>>>>> DEX stats 127.0.0.1:%d bind sock.%d DEX stats API enabled <<<<<<<<<\n",port,LP_bindsock); } clilen = sizeof(cli_addr); @@ -763,7 +763,7 @@ void stats_rpcloop(void *args) if ( sock < 0 ) { printf("iguana_rpcloop ERROR on accept usock.%d errno %d %s\n",sock,errno,strerror(errno)); - close(LP_bindsock); + closesocket(LP_bindsock); LP_bindsock = -1; continue; } @@ -776,7 +776,7 @@ continue; if ( (retval= OS_thread_create(&req->T,NULL,(void *)LP_rpc_processreq,req)) != 0 ) { printf("error launching rpc handler on port %d, retval.%d\n",port,retval); - close(LP_bindsock); + closesocket(LP_bindsock); LP_bindsock = -1; portable_mutex_lock(&LP_gcmutex); DL_FOREACH_SAFE(LP_garbage_collector,req2,rtmp) From 1b8bc2269e7fafb1cd835f4cfbbcd8894e940591 Mon Sep 17 00:00:00 2001 From: jl777 Date: Tue, 7 Nov 2017 23:35:20 +0200 Subject: [PATCH 0329/1664] Test --- iguana/exchanges/LP_socket.c | 34 ++++++++++++++++++++++------------ 1 file changed, 22 insertions(+), 12 deletions(-) diff --git a/iguana/exchanges/LP_socket.c b/iguana/exchanges/LP_socket.c index 1670591f9..3eef131f4 100644 --- a/iguana/exchanges/LP_socket.c +++ b/iguana/exchanges/LP_socket.c @@ -595,23 +595,33 @@ 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("%s.%d u.%u/%d t.%ld %s LISTUNSPENT.(%d)\n",coin->symbol,height,ap->unspenttime,ap->unspentheight,time(NULL),addr,(int32_t)strlen(jprint(retjson,0))); - updatedflag = 0; - if ( electrum_process_array(coin,ep,addr,retjson,electrumflag) != 0 ) - LP_postutxos(coin->symbol,addr), updatedflag = 1; - if ( strcmp(addr,coin->smartaddr) == 0 ) + if ( jobj(retjson,"error") == 0 && is_cJSON_Array(retjson) != 0 ) { - retstr = jprint(retjson,0); - LP_unspents_cache(coin->symbol,coin->smartaddr,retstr,1); - free(retstr); + //printf("%s.%d u.%u/%d t.%ld %s LISTUNSPENT.(%d)\n",coin->symbol,height,ap->unspenttime,ap->unspentheight,time(NULL),addr,(int32_t)strlen(jprint(retjson,0))); + updatedflag = 0; + if ( electrum_process_array(coin,ep,addr,retjson,electrumflag) != 0 ) + LP_postutxos(coin->symbol,addr), updatedflag = 1; + if ( strcmp(addr,coin->smartaddr) == 0 ) + { + retstr = jprint(retjson,0); + LP_unspents_cache(coin->symbol,coin->smartaddr,retstr,1); + free(retstr); + } + if ( ap != 0 ) + { + ap->unspenttime = (uint32_t)time(NULL); + ap->unspentheight = height; + } } - if ( ap != 0 ) + else { - ap->unspenttime = (uint32_t)time(NULL); - ap->unspentheight = height; + free_json(retjson); + retjson = 0; } } - } else retjson = LP_address_utxos(coin,addr,1); + } + if ( retjson == 0 ) + retjson = LP_address_utxos(coin,addr,1); return(retjson); } From 6121f31a274c8244bd7fff98f8ca55ff9bf455ba Mon Sep 17 00:00:00 2001 From: jl777 Date: Tue, 7 Nov 2017 23:35:59 +0200 Subject: [PATCH 0330/1664] Test --- iguana/exchanges/LP_nativeDEX.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/iguana/exchanges/LP_nativeDEX.c b/iguana/exchanges/LP_nativeDEX.c index 76e348c68..960c5ffd3 100644 --- a/iguana/exchanges/LP_nativeDEX.c +++ b/iguana/exchanges/LP_nativeDEX.c @@ -1179,7 +1179,7 @@ void LPinit(uint16_t myport,uint16_t mypullport,uint16_t mypubport,uint16_t mybu usleep(1000); else if ( IAMLP == 0 ) usleep(1000); - if ( (rand() % 10000) == 0 ) + if ( (rand() % 100) == 0 ) { printf("rpc port reset test\n"); closesocket(LP_bindsock); From 1ca201edcbbab6f52641f38d3afc1d2afa697afa Mon Sep 17 00:00:00 2001 From: jl777 Date: Tue, 7 Nov 2017 23:38:06 +0200 Subject: [PATCH 0331/1664] Test --- iguana/exchanges/LP_nativeDEX.c | 7 +------ 1 file changed, 1 insertion(+), 6 deletions(-) diff --git a/iguana/exchanges/LP_nativeDEX.c b/iguana/exchanges/LP_nativeDEX.c index 960c5ffd3..526b3d9db 100644 --- a/iguana/exchanges/LP_nativeDEX.c +++ b/iguana/exchanges/LP_nativeDEX.c @@ -1179,12 +1179,7 @@ void LPinit(uint16_t myport,uint16_t mypullport,uint16_t mypubport,uint16_t mybu usleep(1000); else if ( IAMLP == 0 ) usleep(1000); - if ( (rand() % 100) == 0 ) - { - printf("rpc port reset test\n"); - closesocket(LP_bindsock); - LP_bindsock = -1; - } + printf("mainloop\n"); } #endif } From 9f2bd77cd4c5827370afcde8128fb1d7051fe080 Mon Sep 17 00:00:00 2001 From: jl777 Date: Tue, 7 Nov 2017 23:43:52 +0200 Subject: [PATCH 0332/1664] Test --- iguana/exchanges/LP_nativeDEX.c | 8 +++++++- iguana/exchanges/LP_utxos.c | 1 + 2 files changed, 8 insertions(+), 1 deletion(-) diff --git a/iguana/exchanges/LP_nativeDEX.c b/iguana/exchanges/LP_nativeDEX.c index 526b3d9db..da0bd67fd 100644 --- a/iguana/exchanges/LP_nativeDEX.c +++ b/iguana/exchanges/LP_nativeDEX.c @@ -1179,7 +1179,13 @@ void LPinit(uint16_t myport,uint16_t mypullport,uint16_t mypubport,uint16_t mybu usleep(1000); else if ( IAMLP == 0 ) usleep(1000); - printf("mainloop\n"); + if ( (rand() % 10000) == 0 ) + { + int32_t sock = LP_bindsock; + printf("bindsock reset test\n"); + LP_bindsock = -1; + closesocket(sock); + } } #endif } diff --git a/iguana/exchanges/LP_utxos.c b/iguana/exchanges/LP_utxos.c index 762315b04..a162aab5a 100644 --- a/iguana/exchanges/LP_utxos.c +++ b/iguana/exchanges/LP_utxos.c @@ -826,6 +826,7 @@ int32_t LP_passphrase_init(char *passphrase,char *gui) G.LP_sessionid = (uint32_t)time(NULL); safecopy(G.gui,gui,sizeof(G.gui)); G.USERPASS_COUNTER = counter; + G.initializing = 0; return(0); } From 5843dafb781e1a78fec52144149a281854f5bd10 Mon Sep 17 00:00:00 2001 From: jl777 Date: Tue, 7 Nov 2017 23:51:55 +0200 Subject: [PATCH 0333/1664] Test --- iguana/exchanges/LP_commands.c | 5 ++++- iguana/exchanges/LP_nativeDEX.c | 4 ++-- iguana/exchanges/stats.c | 1 + 3 files changed, 7 insertions(+), 3 deletions(-) diff --git a/iguana/exchanges/LP_commands.c b/iguana/exchanges/LP_commands.c index af12cb1c2..b6cb2291c 100644 --- a/iguana/exchanges/LP_commands.c +++ b/iguana/exchanges/LP_commands.c @@ -375,7 +375,10 @@ bot_resume(botid)\n\ if ( (ptr= LP_coinsearch(coin)) != 0 ) { ptr->inactive = 0; - return(jprint(LP_electrumserver(ptr,jstr(argjson,"ipaddr"),juint(argjson,"port")),1)); + retstr = jprint(LP_electrumserver(ptr,jstr(argjson,"ipaddr"),juint(argjson,"port")),1); + if ( ptr->electrum != 0 && (retjson= electrum_address_listunspent(ptr->symbol,ptr->electrum,&retjson,ptr->smartaddr,2)) != 0 ) + free_json(retjson); + return(retstr); } else return(clonestr("{\"error\":\"cant find coind\"}")); } else if ( strcmp(method,"sendrawtransaction") == 0 ) diff --git a/iguana/exchanges/LP_nativeDEX.c b/iguana/exchanges/LP_nativeDEX.c index da0bd67fd..4c4c8a7ee 100644 --- a/iguana/exchanges/LP_nativeDEX.c +++ b/iguana/exchanges/LP_nativeDEX.c @@ -1179,13 +1179,13 @@ void LPinit(uint16_t myport,uint16_t mypullport,uint16_t mypubport,uint16_t mybu usleep(1000); else if ( IAMLP == 0 ) usleep(1000); - if ( (rand() % 10000) == 0 ) + /*if ( (rand() % 1000) == 0 ) { int32_t sock = LP_bindsock; printf("bindsock reset test\n"); LP_bindsock = -1; closesocket(sock); - } + }*/ } #endif } diff --git a/iguana/exchanges/stats.c b/iguana/exchanges/stats.c index 24f78f5bf..0c5cab321 100644 --- a/iguana/exchanges/stats.c +++ b/iguana/exchanges/stats.c @@ -751,6 +751,7 @@ void stats_rpcloop(void *args) localhostbits = (uint32_t)calc_ipbits("127.0.0.1"); while ( 1 ) { + printf("LP_bindsock.%d\n",LP_bindsock); if ( LP_bindsock < 0 ) { while ( (LP_bindsock= iguana_socket(1,"0.0.0.0",port)) < 0 ) From a327d58dbb8703643e0c1f2d6671f98a5f0eb810 Mon Sep 17 00:00:00 2001 From: jl777 Date: Tue, 7 Nov 2017 23:52:06 +0200 Subject: [PATCH 0334/1664] Test --- iguana/exchanges/stats.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/iguana/exchanges/stats.c b/iguana/exchanges/stats.c index 0c5cab321..fe31d3888 100644 --- a/iguana/exchanges/stats.c +++ b/iguana/exchanges/stats.c @@ -751,7 +751,7 @@ void stats_rpcloop(void *args) localhostbits = (uint32_t)calc_ipbits("127.0.0.1"); while ( 1 ) { - printf("LP_bindsock.%d\n",LP_bindsock); + //printf("LP_bindsock.%d\n",LP_bindsock); if ( LP_bindsock < 0 ) { while ( (LP_bindsock= iguana_socket(1,"0.0.0.0",port)) < 0 ) From 771bbf1d9fb9c98de71e8117e0baac2b1b9b88b2 Mon Sep 17 00:00:00 2001 From: jl777 Date: Tue, 7 Nov 2017 23:54:11 +0200 Subject: [PATCH 0335/1664] Test --- iguana/exchanges/LP_nativeDEX.c | 4 ++-- iguana/exchanges/stats.c | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/iguana/exchanges/LP_nativeDEX.c b/iguana/exchanges/LP_nativeDEX.c index 4c4c8a7ee..8fbb2de08 100644 --- a/iguana/exchanges/LP_nativeDEX.c +++ b/iguana/exchanges/LP_nativeDEX.c @@ -1179,13 +1179,13 @@ void LPinit(uint16_t myport,uint16_t mypullport,uint16_t mypubport,uint16_t mybu usleep(1000); else if ( IAMLP == 0 ) usleep(1000); - /*if ( (rand() % 1000) == 0 ) + if ( (rand() % 1000) == 0 ) { int32_t sock = LP_bindsock; printf("bindsock reset test\n"); LP_bindsock = -1; closesocket(sock); - }*/ + } } #endif } diff --git a/iguana/exchanges/stats.c b/iguana/exchanges/stats.c index fe31d3888..0c5cab321 100644 --- a/iguana/exchanges/stats.c +++ b/iguana/exchanges/stats.c @@ -751,7 +751,7 @@ void stats_rpcloop(void *args) localhostbits = (uint32_t)calc_ipbits("127.0.0.1"); while ( 1 ) { - //printf("LP_bindsock.%d\n",LP_bindsock); + printf("LP_bindsock.%d\n",LP_bindsock); if ( LP_bindsock < 0 ) { while ( (LP_bindsock= iguana_socket(1,"0.0.0.0",port)) < 0 ) From e8343f63509ba58b211db4e02dcd704054e7a490 Mon Sep 17 00:00:00 2001 From: jl777 Date: Wed, 8 Nov 2017 00:04:35 +0200 Subject: [PATCH 0336/1664] Test --- iguana/exchanges/LP_commands.c | 5 +---- iguana/exchanges/LP_socket.c | 2 +- 2 files changed, 2 insertions(+), 5 deletions(-) diff --git a/iguana/exchanges/LP_commands.c b/iguana/exchanges/LP_commands.c index b6cb2291c..af12cb1c2 100644 --- a/iguana/exchanges/LP_commands.c +++ b/iguana/exchanges/LP_commands.c @@ -375,10 +375,7 @@ bot_resume(botid)\n\ if ( (ptr= LP_coinsearch(coin)) != 0 ) { ptr->inactive = 0; - retstr = jprint(LP_electrumserver(ptr,jstr(argjson,"ipaddr"),juint(argjson,"port")),1); - if ( ptr->electrum != 0 && (retjson= electrum_address_listunspent(ptr->symbol,ptr->electrum,&retjson,ptr->smartaddr,2)) != 0 ) - free_json(retjson); - return(retstr); + 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 ) diff --git a/iguana/exchanges/LP_socket.c b/iguana/exchanges/LP_socket.c index 3eef131f4..25ccc79c5 100644 --- a/iguana/exchanges/LP_socket.c +++ b/iguana/exchanges/LP_socket.c @@ -1055,7 +1055,7 @@ cJSON *LP_electrumserver(struct iguana_info *coin,char *ipaddr,uint16_t port) } else { - printf("launched electrum.(%s:%u)\n",ep->ipaddr,ep->port); + printf("launched %s electrum.(%s:%u)\n",coin->symbol,ep->ipaddr,ep->port); jaddstr(retjson,"result","success"); ep->prev = coin->electrum; coin->electrum = ep; From 69591d1f8cff9ec64513c3510061f731a6f93200 Mon Sep 17 00:00:00 2001 From: jl777 Date: Wed, 8 Nov 2017 00:08:49 +0200 Subject: [PATCH 0337/1664] Test --- iguana/exchanges/stats.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/iguana/exchanges/stats.c b/iguana/exchanges/stats.c index 0c5cab321..30eeb71fd 100644 --- a/iguana/exchanges/stats.c +++ b/iguana/exchanges/stats.c @@ -741,6 +741,7 @@ void LP_rpc_processreq(void *_ptr) extern int32_t IAMLP; int32_t LP_bindsock = -1; + void stats_rpcloop(void *args) { //static uint32_t counter; @@ -759,6 +760,7 @@ void stats_rpcloop(void *args) //if ( counter++ < 1 ) printf(">>>>>>>>>> DEX stats 127.0.0.1:%d bind sock.%d DEX stats API enabled <<<<<<<<<\n",port,LP_bindsock); } + printf("after LP_bindsock.%d\n",LP_bindsock); clilen = sizeof(cli_addr); sock = accept(LP_bindsock,(struct sockaddr *)&cli_addr,&clilen); if ( sock < 0 ) From 902bd2e1c55a14b487c5b1e49ee69766ada66303 Mon Sep 17 00:00:00 2001 From: jl777 Date: Wed, 8 Nov 2017 00:10:43 +0200 Subject: [PATCH 0338/1664] Test --- iguana/exchanges/LP_nativeDEX.c | 4 ++-- iguana/exchanges/stats.c | 8 ++++---- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/iguana/exchanges/LP_nativeDEX.c b/iguana/exchanges/LP_nativeDEX.c index 8fbb2de08..c461997b6 100644 --- a/iguana/exchanges/LP_nativeDEX.c +++ b/iguana/exchanges/LP_nativeDEX.c @@ -1179,13 +1179,13 @@ void LPinit(uint16_t myport,uint16_t mypullport,uint16_t mypubport,uint16_t mybu usleep(1000); else if ( IAMLP == 0 ) usleep(1000); - if ( (rand() % 1000) == 0 ) + /*if ( (rand() % 10000) == 0 ) { int32_t sock = LP_bindsock; printf("bindsock reset test\n"); LP_bindsock = -1; closesocket(sock); - } + }*/ } #endif } diff --git a/iguana/exchanges/stats.c b/iguana/exchanges/stats.c index 30eeb71fd..1ebed2aec 100644 --- a/iguana/exchanges/stats.c +++ b/iguana/exchanges/stats.c @@ -744,7 +744,7 @@ int32_t LP_bindsock = -1; void stats_rpcloop(void *args) { - //static uint32_t counter; + static uint32_t counter; uint16_t port; int32_t retval,sock; socklen_t clilen; struct sockaddr_in cli_addr; uint32_t ipbits,localhostbits; struct rpcrequest_info *req,*req2,*rtmp; if ( (port= *(uint16_t *)args) == 0 ) port = 7779; @@ -752,15 +752,15 @@ void stats_rpcloop(void *args) localhostbits = (uint32_t)calc_ipbits("127.0.0.1"); while ( 1 ) { - printf("LP_bindsock.%d\n",LP_bindsock); + //printf("LP_bindsock.%d\n",LP_bindsock); if ( LP_bindsock < 0 ) { while ( (LP_bindsock= iguana_socket(1,"0.0.0.0",port)) < 0 ) usleep(10000); - //if ( counter++ < 1 ) + if ( counter++ < 1 ) printf(">>>>>>>>>> DEX stats 127.0.0.1:%d bind sock.%d DEX stats API enabled <<<<<<<<<\n",port,LP_bindsock); } - printf("after LP_bindsock.%d\n",LP_bindsock); + //printf("after LP_bindsock.%d\n",LP_bindsock); clilen = sizeof(cli_addr); sock = accept(LP_bindsock,(struct sockaddr *)&cli_addr,&clilen); if ( sock < 0 ) From 4f0446b564f1a4cdae63b297768aa6932fe2d2a3 Mon Sep 17 00:00:00 2001 From: jl777 Date: Wed, 8 Nov 2017 00:28:37 +0200 Subject: [PATCH 0339/1664] Test --- iguana/exchanges/LP_include.h | 2 +- iguana/exchanges/LP_nativeDEX.c | 45 +++++++++++++++++++++++---------- iguana/exchanges/LP_rpc.c | 8 ++++++ iguana/exchanges/LP_socket.c | 3 ++- 4 files changed, 42 insertions(+), 16 deletions(-) diff --git a/iguana/exchanges/LP_include.h b/iguana/exchanges/LP_include.h index 0e7ce20b1..843ace61b 100644 --- a/iguana/exchanges/LP_include.h +++ b/iguana/exchanges/LP_include.h @@ -255,7 +255,7 @@ struct iguana_info 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 lastunspent,importedprivkey,lastpushtime,lastutxosync,addr_listunspent_requested,lastutxos,updaterate,counter,inactive,lastmempool,lastgetinfo,ratetime,heighttime,lastmonitor,obooktime; + uint32_t 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[16],smartaddr[64],userpass[1024],serverport[128]; // portfolio diff --git a/iguana/exchanges/LP_nativeDEX.c b/iguana/exchanges/LP_nativeDEX.c index c461997b6..3190d9475 100644 --- a/iguana/exchanges/LP_nativeDEX.c +++ b/iguana/exchanges/LP_nativeDEX.c @@ -620,13 +620,6 @@ void LP_coinsloop(void *_coins) } } } - if ( time(NULL) > coin->lastunspent+30 ) - { - //printf("call electrum listunspent.%s\n",coin->symbol); - if ( (retjson= electrum_address_listunspent(coin->symbol,ep,&retjson,coin->smartaddr,2)) != 0 ) - free_json(retjson); - coin->lastunspent = (uint32_t)time(NULL); - } while ( ep != 0 ) { if ( time(NULL) > ep->keepalive+LP_ELECTRUM_KEEPALIVE ) @@ -836,13 +829,23 @@ void LP_initpeers(int32_t pubsock,struct LP_peerinfo *mypeer,char *myipaddr,uint void LP_pubkeysloop(void *ctx) { - static uint32_t lasttime; + static uint32_t lasttime; cJSON *retjson; struct iguana_info *coin,*tmp; strcpy(LP_pubkeysloop_stats.name,"LP_pubkeysloop"); LP_pubkeysloop_stats.threshold = 5000.; sleep(10); while ( 1 ) { LP_millistats_update(&LP_pubkeysloop_stats); + HASH_ITER(hh,LP_coins,coin,tmp) // firstrefht,firstscanht,lastscanht + { + if ( coin->electrum != 0 && time(NULL) > coin->lastunspent+30 ) + { + //printf("call electrum listunspent.%s\n",coin->symbol); + if ( (retjson= electrum_address_listunspent(coin->symbol,coin->electrum,&retjson,coin->smartaddr,2)) != 0 ) + free_json(retjson); + coin->lastunspent = (uint32_t)time(NULL); + } + } if ( time(NULL) > lasttime+60 ) { //printf("LP_pubkeysloop %u\n",(uint32_t)time(NULL)); @@ -1179,13 +1182,27 @@ void LPinit(uint16_t myport,uint16_t mypullport,uint16_t mypubport,uint16_t mybu usleep(1000); else if ( IAMLP == 0 ) usleep(1000); - /*if ( (rand() % 10000) == 0 ) + if ( (rand() % 10000) == 0 ) { - int32_t sock = LP_bindsock; - printf("bindsock reset test\n"); - LP_bindsock = -1; - closesocket(sock); - }*/ + char *hellostr,*retstr; cJSON *retjson; int32_t allgood,sock = LP_bindsock; + allgood = 0; + if ( (retstr= issue_hello(myport)) != 0 ) + { + if ( (retjson= cJSON_Parse(retstr)) != 0 ) + { + if ( (hellostr= jstr(retjson,"status")) != 0 && strcmp(hellostr,"") == 0 ) + allgood = 1, printf("allgood.(%s)\n",retstr); + free_json(retjson); + } else printf("couldnt parse hello return.(%s)\n",retstr); + free(retstr); + } else printf("issue_hello NULL return\n"); + if ( allgood == 0 ) + { + printf("RPC port got stuck, kick it\n"); + LP_bindsock = -1; + closesocket(sock); + } + } } #endif } diff --git a/iguana/exchanges/LP_rpc.c b/iguana/exchanges/LP_rpc.c index 959000fee..535b93264 100644 --- a/iguana/exchanges/LP_rpc.c +++ b/iguana/exchanges/LP_rpc.c @@ -93,6 +93,14 @@ char *issue_LP_getprices(char *destip,uint16_t destport) //return(issue_curlt(url,LP_HTTP_TIMEOUT)); } +char *issue_hello(uint16_t port) +{ + char url[512]; + sprintf(url,"http://127.0.0.1:%u/api/stats/getprices",port); + //printf("getutxo.(%s)\n",url); + return(LP_issue_curl("hello","127.0.0.1",port,url)); +} + char *issue_LP_listunspent(char *destip,uint16_t destport,char *symbol,char *coinaddr) { char url[512],*retstr; diff --git a/iguana/exchanges/LP_socket.c b/iguana/exchanges/LP_socket.c index 25ccc79c5..036ef0ed7 100644 --- a/iguana/exchanges/LP_socket.c +++ b/iguana/exchanges/LP_socket.c @@ -597,7 +597,8 @@ cJSON *electrum_address_listunspent(char *symbol,struct electrum_info *ep,cJSON { if ( jobj(retjson,"error") == 0 && is_cJSON_Array(retjson) != 0 ) { - //printf("%s.%d u.%u/%d t.%ld %s LISTUNSPENT.(%d)\n",coin->symbol,height,ap->unspenttime,ap->unspentheight,time(NULL),addr,(int32_t)strlen(jprint(retjson,0))); + if ( electrumflag > 1 ) + printf("%s.%d u.%u/%d t.%ld %s LISTUNSPENT.(%d)\n",coin->symbol,height,ap->unspenttime,ap->unspentheight,time(NULL),addr,(int32_t)strlen(jprint(retjson,0))); updatedflag = 0; if ( electrum_process_array(coin,ep,addr,retjson,electrumflag) != 0 ) LP_postutxos(coin->symbol,addr), updatedflag = 1; From e744037026317ea01c559b15ede9d2b3b45282f7 Mon Sep 17 00:00:00 2001 From: jl777 Date: Wed, 8 Nov 2017 00:36:07 +0200 Subject: [PATCH 0340/1664] Test --- iguana/exchanges/LP_nativeDEX.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/iguana/exchanges/LP_nativeDEX.c b/iguana/exchanges/LP_nativeDEX.c index 3190d9475..b54ba272f 100644 --- a/iguana/exchanges/LP_nativeDEX.c +++ b/iguana/exchanges/LP_nativeDEX.c @@ -1192,11 +1192,12 @@ void LPinit(uint16_t myport,uint16_t mypullport,uint16_t mypubport,uint16_t mybu { if ( (hellostr= jstr(retjson,"status")) != 0 && strcmp(hellostr,"") == 0 ) allgood = 1, printf("allgood.(%s)\n",retstr); + else printf("strange return.(%s)\n",jprint(retjson,0)); free_json(retjson); } else printf("couldnt parse hello return.(%s)\n",retstr); free(retstr); } else printf("issue_hello NULL return\n"); - if ( allgood == 0 ) + if ( 0 && allgood == 0 ) { printf("RPC port got stuck, kick it\n"); LP_bindsock = -1; From 3dcde456c3642d3a4f7b22d73223e020b0ba35bf Mon Sep 17 00:00:00 2001 From: jl777 Date: Wed, 8 Nov 2017 00:44:24 +0200 Subject: [PATCH 0341/1664] Test --- iguana/exchanges/LP_rpc.c | 2 +- iguana/exchanges/LP_socket.c | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/iguana/exchanges/LP_rpc.c b/iguana/exchanges/LP_rpc.c index 535b93264..b76416c5a 100644 --- a/iguana/exchanges/LP_rpc.c +++ b/iguana/exchanges/LP_rpc.c @@ -96,7 +96,7 @@ char *issue_LP_getprices(char *destip,uint16_t destport) char *issue_hello(uint16_t port) { char url[512]; - sprintf(url,"http://127.0.0.1:%u/api/stats/getprices",port); + sprintf(url,"http://127.0.0.1:%u/api/stats/hello",port); //printf("getutxo.(%s)\n",url); return(LP_issue_curl("hello","127.0.0.1",port,url)); } diff --git a/iguana/exchanges/LP_socket.c b/iguana/exchanges/LP_socket.c index 036ef0ed7..30dd047b5 100644 --- a/iguana/exchanges/LP_socket.c +++ b/iguana/exchanges/LP_socket.c @@ -597,7 +597,7 @@ cJSON *electrum_address_listunspent(char *symbol,struct electrum_info *ep,cJSON { if ( jobj(retjson,"error") == 0 && is_cJSON_Array(retjson) != 0 ) { - if ( electrumflag > 1 ) + if ( 0 && electrumflag > 1 ) printf("%s.%d u.%u/%d t.%ld %s LISTUNSPENT.(%d)\n",coin->symbol,height,ap->unspenttime,ap->unspentheight,time(NULL),addr,(int32_t)strlen(jprint(retjson,0))); updatedflag = 0; if ( electrum_process_array(coin,ep,addr,retjson,electrumflag) != 0 ) From 37eaf4b54b9d3c8573595d3573f747de90d68617 Mon Sep 17 00:00:00 2001 From: jl777 Date: Wed, 8 Nov 2017 00:50:21 +0200 Subject: [PATCH 0342/1664] Test --- iguana/exchanges/LP_nativeDEX.c | 12 +++++++++--- iguana/exchanges/stats.c | 9 +++++---- 2 files changed, 14 insertions(+), 7 deletions(-) diff --git a/iguana/exchanges/LP_nativeDEX.c b/iguana/exchanges/LP_nativeDEX.c index b54ba272f..803b1928c 100644 --- a/iguana/exchanges/LP_nativeDEX.c +++ b/iguana/exchanges/LP_nativeDEX.c @@ -1190,18 +1190,24 @@ void LPinit(uint16_t myport,uint16_t mypullport,uint16_t mypubport,uint16_t mybu { if ( (retjson= cJSON_Parse(retstr)) != 0 ) { - if ( (hellostr= jstr(retjson,"status")) != 0 && strcmp(hellostr,"") == 0 ) + if ( (hellostr= jstr(retjson,"status")) != 0 && strcmp(hellostr,"got hello") == 0 ) allgood = 1, printf("allgood.(%s)\n",retstr); else printf("strange return.(%s)\n",jprint(retjson,0)); free_json(retjson); } else printf("couldnt parse hello return.(%s)\n",retstr); free(retstr); } else printf("issue_hello NULL return\n"); - if ( 0 && allgood == 0 ) + if ( allgood == 0 ) { - printf("RPC port got stuck, kick it\n"); + printf("RPC port got stuck, start a new thread\n"); LP_bindsock = -1; closesocket(sock); + LP_bindsock_reset++; + if ( OS_thread_create(malloc(sizeof(pthread_t)),NULL,(void *)stats_rpcloop,(void *)&myport) != 0 ) + { + printf("error launching stats rpcloop for port.%u\n",myport); + exit(-1); + } } } } diff --git a/iguana/exchanges/stats.c b/iguana/exchanges/stats.c index 1ebed2aec..436c0b32d 100644 --- a/iguana/exchanges/stats.c +++ b/iguana/exchanges/stats.c @@ -740,17 +740,17 @@ void LP_rpc_processreq(void *_ptr) } extern int32_t IAMLP; -int32_t LP_bindsock = -1; +int32_t LP_bindsock_reset,LP_bindsock = -1; void stats_rpcloop(void *args) { - static uint32_t counter; - uint16_t port; int32_t retval,sock; socklen_t clilen; struct sockaddr_in cli_addr; uint32_t ipbits,localhostbits; struct rpcrequest_info *req,*req2,*rtmp; + uint16_t port; int32_t retval,sock,initial_bindsock_reset; socklen_t clilen; struct sockaddr_in cli_addr; uint32_t ipbits,localhostbits,counter=0; struct rpcrequest_info *req,*req2,*rtmp; if ( (port= *(uint16_t *)args) == 0 ) port = 7779; RPC_port = port; localhostbits = (uint32_t)calc_ipbits("127.0.0.1"); - while ( 1 ) + initial_bindsock_reset = LP_bindsock_reset; + while ( LP_bindsock_reset == initial_bindsock_reset ) { //printf("LP_bindsock.%d\n",LP_bindsock); if ( LP_bindsock < 0 ) @@ -776,6 +776,7 @@ void stats_rpcloop(void *args) req->ipbits = ipbits; LP_rpc_processreq(req); continue; + // this leads to cant open file errors if ( (retval= OS_thread_create(&req->T,NULL,(void *)LP_rpc_processreq,req)) != 0 ) { printf("error launching rpc handler on port %d, retval.%d\n",port,retval); From 16cff05525a5ae5270884da18afba36004986c1d Mon Sep 17 00:00:00 2001 From: jl777 Date: Wed, 8 Nov 2017 00:57:41 +0200 Subject: [PATCH 0343/1664] Test --- iguana/exchanges/LP_nativeDEX.c | 9 +++++---- iguana/exchanges/stats.c | 1 + 2 files changed, 6 insertions(+), 4 deletions(-) diff --git a/iguana/exchanges/LP_nativeDEX.c b/iguana/exchanges/LP_nativeDEX.c index 803b1928c..984d98705 100644 --- a/iguana/exchanges/LP_nativeDEX.c +++ b/iguana/exchanges/LP_nativeDEX.c @@ -1166,7 +1166,7 @@ void LPinit(uint16_t myport,uint16_t mypullport,uint16_t mypubport,uint16_t mybu printf("error launching LP_swapsloop for port.%u\n",myport); exit(-1); } - int32_t nonz; + int32_t nonz; uint32_t lasthello = 0; while ( 1 ) { nonz = 0; @@ -1182,7 +1182,7 @@ void LPinit(uint16_t myport,uint16_t mypullport,uint16_t mypubport,uint16_t mybu usleep(1000); else if ( IAMLP == 0 ) usleep(1000); - if ( (rand() % 10000) == 0 ) + if ( time(NULL) > lasthello+60 ) { char *hellostr,*retstr; cJSON *retjson; int32_t allgood,sock = LP_bindsock; allgood = 0; @@ -1191,13 +1191,14 @@ void LPinit(uint16_t myport,uint16_t mypullport,uint16_t mypubport,uint16_t mybu if ( (retjson= cJSON_Parse(retstr)) != 0 ) { if ( (hellostr= jstr(retjson,"status")) != 0 && strcmp(hellostr,"got hello") == 0 ) - allgood = 1, printf("allgood.(%s)\n",retstr); + allgood = 1; else printf("strange return.(%s)\n",jprint(retjson,0)); free_json(retjson); } else printf("couldnt parse hello return.(%s)\n",retstr); free(retstr); } else printf("issue_hello NULL return\n"); - if ( allgood == 0 ) + lasthello = (uint32_t)time(NULL); + if ( 1 || allgood == 0 ) { printf("RPC port got stuck, start a new thread\n"); LP_bindsock = -1; diff --git a/iguana/exchanges/stats.c b/iguana/exchanges/stats.c index 436c0b32d..3561773b9 100644 --- a/iguana/exchanges/stats.c +++ b/iguana/exchanges/stats.c @@ -796,6 +796,7 @@ continue; } } } + printf("i got killed\n"); } #ifndef FROM_MARKETMAKER From 0d869866ada72d8cd45e72b44378fda9c15cee6b Mon Sep 17 00:00:00 2001 From: jl777 Date: Wed, 8 Nov 2017 01:00:30 +0200 Subject: [PATCH 0344/1664] Test --- iguana/exchanges/LP_include.h | 2 +- iguana/exchanges/LP_socket.c | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/iguana/exchanges/LP_include.h b/iguana/exchanges/LP_include.h index 843ace61b..444858583 100644 --- a/iguana/exchanges/LP_include.h +++ b/iguana/exchanges/LP_include.h @@ -39,7 +39,7 @@ void emscripten_usleep(int32_t x); // returns immediate, no sense for sleeping #define LP_HTTP_TIMEOUT 3 // 1 is too small due to edge cases of time(NULL) #define LP_AUTOTRADE_TIMEOUT 20 -#define ELECTRUM_TIMEOUT 20 +#define ELECTRUM_TIMEOUT 5 #define LP_ELECTRUM_KEEPALIVE 60 #define LP_ELECTRUM_MAXERRORS 777 #define LP_MEMPOOL_TIMEINCR 10 diff --git a/iguana/exchanges/LP_socket.c b/iguana/exchanges/LP_socket.c index 30dd047b5..c459e725a 100644 --- a/iguana/exchanges/LP_socket.c +++ b/iguana/exchanges/LP_socket.c @@ -408,12 +408,12 @@ cJSON *electrum_submit(char *symbol,struct electrum_info *ep,cJSON **retjsonp,ch sitem->expiration = timeout; sitem->DL.type = ep->stratumid++; sitem->retptrp = (void **)retjsonp;*/ - portable_mutex_lock(&ep->mutex); + //portable_mutex_lock(&ep->mutex); //queue_enqueue("sendQ",&ep->sendQ,&sitem->DL); expiration = (uint32_t)time(NULL) + timeout + 1; while ( *retjsonp == 0 && time(NULL) <= expiration ) usleep(5000); - portable_mutex_unlock(&ep->mutex); + //portable_mutex_unlock(&ep->mutex); if ( *retjsonp == 0 || jobj(*retjsonp,"error") != 0 ) { if ( ++ep->numerrors >= LP_ELECTRUM_MAXERRORS ) From c3105acf1d59f6a3dc59c7f063c0126ef79ec1bd Mon Sep 17 00:00:00 2001 From: jl777 Date: Wed, 8 Nov 2017 01:01:47 +0200 Subject: [PATCH 0345/1664] Test --- iguana/exchanges/LP_nativeDEX.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/iguana/exchanges/LP_nativeDEX.c b/iguana/exchanges/LP_nativeDEX.c index 984d98705..f31e39421 100644 --- a/iguana/exchanges/LP_nativeDEX.c +++ b/iguana/exchanges/LP_nativeDEX.c @@ -1198,7 +1198,7 @@ void LPinit(uint16_t myport,uint16_t mypullport,uint16_t mypubport,uint16_t mybu free(retstr); } else printf("issue_hello NULL return\n"); lasthello = (uint32_t)time(NULL); - if ( 1 || allgood == 0 ) + if ( allgood == 0 ) { printf("RPC port got stuck, start a new thread\n"); LP_bindsock = -1; From bcff592f3a93b5ee17ab526fd6861f2e409378c4 Mon Sep 17 00:00:00 2001 From: jl777 Date: Wed, 8 Nov 2017 01:16:04 +0200 Subject: [PATCH 0346/1664] Test --- iguana/exchanges/LP_nativeDEX.c | 6 ------ iguana/exchanges/stats.c | 16 ++++++++++++++++ 2 files changed, 16 insertions(+), 6 deletions(-) diff --git a/iguana/exchanges/LP_nativeDEX.c b/iguana/exchanges/LP_nativeDEX.c index f31e39421..394d422a2 100644 --- a/iguana/exchanges/LP_nativeDEX.c +++ b/iguana/exchanges/LP_nativeDEX.c @@ -1203,12 +1203,6 @@ void LPinit(uint16_t myport,uint16_t mypullport,uint16_t mypubport,uint16_t mybu printf("RPC port got stuck, start a new thread\n"); LP_bindsock = -1; closesocket(sock); - LP_bindsock_reset++; - if ( OS_thread_create(malloc(sizeof(pthread_t)),NULL,(void *)stats_rpcloop,(void *)&myport) != 0 ) - { - printf("error launching stats rpcloop for port.%u\n",myport); - exit(-1); - } } } } diff --git a/iguana/exchanges/stats.c b/iguana/exchanges/stats.c index 3561773b9..896234485 100644 --- a/iguana/exchanges/stats.c +++ b/iguana/exchanges/stats.c @@ -23,6 +23,9 @@ #include #include +#include /* See NOTES */ +#define _GNU_SOURCE /* See feature_test_macros(7) */ +#include #include "../../crypto777/OS_portable.h" #define MAX(a,b) ((a) > (b) ? (a) : (b)) #define STATS_DESTDIR "/var/www/html" @@ -762,7 +765,20 @@ void stats_rpcloop(void *args) } //printf("after LP_bindsock.%d\n",LP_bindsock); clilen = sizeof(cli_addr); +#ifdef _WIN32 sock = accept(LP_bindsock,(struct sockaddr *)&cli_addr,&clilen); +#else +#ifdef __APPLE__ + sock = accept(LP_bindsock,(struct sockaddr *)&cli_addr,&clilen); +#else + sock = accept4(LP_bindsock,(struct sockaddr *)&cli_addr,&clilen,SOCK_NONBLOCK); + if ( sock < 0 ) + { + usleep(50000); + continue; + } +#endif +#endif if ( sock < 0 ) { printf("iguana_rpcloop ERROR on accept usock.%d errno %d %s\n",sock,errno,strerror(errno)); From e4fee8e52bbfd9d6ae8baf669e60026d7d41b1fe Mon Sep 17 00:00:00 2001 From: jl777 Date: Wed, 8 Nov 2017 01:19:45 +0200 Subject: [PATCH 0347/1664] Test --- iguana/exchanges/stats.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/iguana/exchanges/stats.c b/iguana/exchanges/stats.c index 896234485..9b6b47575 100644 --- a/iguana/exchanges/stats.c +++ b/iguana/exchanges/stats.c @@ -26,6 +26,7 @@ #include /* See NOTES */ #define _GNU_SOURCE /* See feature_test_macros(7) */ #include +int32_t accept4(int fildes, struct sockaddr *sock_addr, socklen_t *sock_addr_size, int flags); #include "../../crypto777/OS_portable.h" #define MAX(a,b) ((a) > (b) ? (a) : (b)) #define STATS_DESTDIR "/var/www/html" @@ -747,7 +748,7 @@ int32_t LP_bindsock_reset,LP_bindsock = -1; void stats_rpcloop(void *args) { - uint16_t port; int32_t retval,sock,initial_bindsock_reset; socklen_t clilen; struct sockaddr_in cli_addr; uint32_t ipbits,localhostbits,counter=0; struct rpcrequest_info *req,*req2,*rtmp; + uint16_t port; int32_t retval,sock,initial_bindsock_reset; socklen_t clilen; struct sockaddr_in cli_addr; uint32_t ipbits,localhostbits; struct rpcrequest_info *req,*req2,*rtmp; if ( (port= *(uint16_t *)args) == 0 ) port = 7779; RPC_port = port; @@ -760,7 +761,7 @@ void stats_rpcloop(void *args) { while ( (LP_bindsock= iguana_socket(1,"0.0.0.0",port)) < 0 ) usleep(10000); - if ( counter++ < 1 ) + //if ( counter++ < 1 ) printf(">>>>>>>>>> DEX stats 127.0.0.1:%d bind sock.%d DEX stats API enabled <<<<<<<<<\n",port,LP_bindsock); } //printf("after LP_bindsock.%d\n",LP_bindsock); @@ -774,6 +775,7 @@ void stats_rpcloop(void *args) sock = accept4(LP_bindsock,(struct sockaddr *)&cli_addr,&clilen,SOCK_NONBLOCK); if ( sock < 0 ) { + fprintf(stderr,"."); usleep(50000); continue; } From 807e83acf2af6b616907b0f4d0e1bf2d007dc70e Mon Sep 17 00:00:00 2001 From: jl777 Date: Wed, 8 Nov 2017 01:29:44 +0200 Subject: [PATCH 0348/1664] Test --- iguana/exchanges/stats.c | 18 ++++++------------ 1 file changed, 6 insertions(+), 12 deletions(-) diff --git a/iguana/exchanges/stats.c b/iguana/exchanges/stats.c index 9b6b47575..1a73926f8 100644 --- a/iguana/exchanges/stats.c +++ b/iguana/exchanges/stats.c @@ -23,10 +23,6 @@ #include #include -#include /* See NOTES */ -#define _GNU_SOURCE /* See feature_test_macros(7) */ -#include -int32_t accept4(int fildes, struct sockaddr *sock_addr, socklen_t *sock_addr_size, int flags); #include "../../crypto777/OS_portable.h" #define MAX(a,b) ((a) > (b) ? (a) : (b)) #define STATS_DESTDIR "/var/www/html" @@ -761,26 +757,23 @@ void stats_rpcloop(void *args) { while ( (LP_bindsock= iguana_socket(1,"0.0.0.0",port)) < 0 ) usleep(10000); +#ifndef _WIN32 + fcntl(LP_bindsock, F_SETFL, fcntl(LP_bindsock, F_GETFL, 0) | O_NONBLOCK); +#endif //if ( counter++ < 1 ) printf(">>>>>>>>>> DEX stats 127.0.0.1:%d bind sock.%d DEX stats API enabled <<<<<<<<<\n",port,LP_bindsock); } //printf("after LP_bindsock.%d\n",LP_bindsock); clilen = sizeof(cli_addr); -#ifdef _WIN32 - sock = accept(LP_bindsock,(struct sockaddr *)&cli_addr,&clilen); -#else -#ifdef __APPLE__ sock = accept(LP_bindsock,(struct sockaddr *)&cli_addr,&clilen); -#else - sock = accept4(LP_bindsock,(struct sockaddr *)&cli_addr,&clilen,SOCK_NONBLOCK); +#ifdef _WIN32 if ( sock < 0 ) { fprintf(stderr,"."); usleep(50000); continue; } -#endif -#endif +#else if ( sock < 0 ) { printf("iguana_rpcloop ERROR on accept usock.%d errno %d %s\n",sock,errno,strerror(errno)); @@ -788,6 +781,7 @@ void stats_rpcloop(void *args) LP_bindsock = -1; continue; } +#endif memcpy(&ipbits,&cli_addr.sin_addr.s_addr,sizeof(ipbits)); req = calloc(1,sizeof(*req)); req->sock = sock; From 009f69ecf673593208b29a6039dbfaf99ac373d6 Mon Sep 17 00:00:00 2001 From: jl777 Date: Wed, 8 Nov 2017 01:32:58 +0200 Subject: [PATCH 0349/1664] Test --- iguana/exchanges/stats.c | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/iguana/exchanges/stats.c b/iguana/exchanges/stats.c index 1a73926f8..c7edbfeda 100644 --- a/iguana/exchanges/stats.c +++ b/iguana/exchanges/stats.c @@ -769,16 +769,16 @@ void stats_rpcloop(void *args) #ifdef _WIN32 if ( sock < 0 ) { - fprintf(stderr,"."); - usleep(50000); + printf("iguana_rpcloop ERROR on accept usock.%d errno %d %s\n",sock,errno,strerror(errno)); + closesocket(LP_bindsock); + LP_bindsock = -1; continue; } #else if ( sock < 0 ) { - printf("iguana_rpcloop ERROR on accept usock.%d errno %d %s\n",sock,errno,strerror(errno)); - closesocket(LP_bindsock); - LP_bindsock = -1; + fprintf(stderr,"."); + usleep(50000); continue; } #endif From 2a05b019c2da1bfeb6571f675d6a9f73e4ed098e Mon Sep 17 00:00:00 2001 From: jl777 Date: Wed, 8 Nov 2017 01:35:26 +0200 Subject: [PATCH 0350/1664] Test --- iguana/exchanges/stats.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/iguana/exchanges/stats.c b/iguana/exchanges/stats.c index c7edbfeda..3b5c53248 100644 --- a/iguana/exchanges/stats.c +++ b/iguana/exchanges/stats.c @@ -777,7 +777,7 @@ void stats_rpcloop(void *args) #else if ( sock < 0 ) { - fprintf(stderr,"."); + //fprintf(stderr,"."); usleep(50000); continue; } From 0f8ad4504f04f2300a50c729c6f3df6babdd651c Mon Sep 17 00:00:00 2001 From: jl777 Date: Wed, 8 Nov 2017 01:38:27 +0200 Subject: [PATCH 0351/1664] Test --- iguana/exchanges/stats.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/iguana/exchanges/stats.c b/iguana/exchanges/stats.c index 3b5c53248..872f7b332 100644 --- a/iguana/exchanges/stats.c +++ b/iguana/exchanges/stats.c @@ -778,7 +778,9 @@ void stats_rpcloop(void *args) if ( sock < 0 ) { //fprintf(stderr,"."); - usleep(50000); + if ( IAMLP == 0 ) + usleep(50000); + else usleep(2500); continue; } #endif From 6e93ea1e4100ad1ad9bd654c9cb3491eb14eba4a Mon Sep 17 00:00:00 2001 From: jl777 Date: Wed, 8 Nov 2017 01:47:34 +0200 Subject: [PATCH 0352/1664] Test --- iguana/exchanges/LP_nativeDEX.c | 6 ++---- iguana/exchanges/LP_rpc.c | 2 +- 2 files changed, 3 insertions(+), 5 deletions(-) diff --git a/iguana/exchanges/LP_nativeDEX.c b/iguana/exchanges/LP_nativeDEX.c index 394d422a2..27c15480b 100644 --- a/iguana/exchanges/LP_nativeDEX.c +++ b/iguana/exchanges/LP_nativeDEX.c @@ -18,11 +18,9 @@ // LP_nativeDEX.c // marketmaker // -// selftest and fix rpc port -// verify portfolio, interest to KMD withdraw +// BCH signing // dPoW security -> 4: KMD notarized, 5: BTC notarized, after next notary elections // bigendian architectures need to use little endian for sighash calcs -// BCH signing #include struct LP_millistats @@ -1200,7 +1198,7 @@ void LPinit(uint16_t myport,uint16_t mypullport,uint16_t mypubport,uint16_t mybu lasthello = (uint32_t)time(NULL); if ( allgood == 0 ) { - printf("RPC port got stuck, start a new thread\n"); + printf("RPC port got stuck, close bindsocket\n"); LP_bindsock = -1; closesocket(sock); } diff --git a/iguana/exchanges/LP_rpc.c b/iguana/exchanges/LP_rpc.c index b76416c5a..343106e90 100644 --- a/iguana/exchanges/LP_rpc.c +++ b/iguana/exchanges/LP_rpc.c @@ -98,7 +98,7 @@ char *issue_hello(uint16_t port) char url[512]; sprintf(url,"http://127.0.0.1:%u/api/stats/hello",port); //printf("getutxo.(%s)\n",url); - return(LP_issue_curl("hello","127.0.0.1",port,url)); + return(issue_curlt(url,60)); // might be starting a trade } char *issue_LP_listunspent(char *destip,uint16_t destport,char *symbol,char *coinaddr) From 8cd733469a00f60536503170226d702248be25d6 Mon Sep 17 00:00:00 2001 From: jl777 Date: Wed, 8 Nov 2017 02:14:39 +0200 Subject: [PATCH 0353/1664] Test --- iguana/exchanges/LP_commands.c | 4 +++- iguana/exchanges/LP_utxo.c | 12 +++++++++--- 2 files changed, 12 insertions(+), 4 deletions(-) diff --git a/iguana/exchanges/LP_commands.c b/iguana/exchanges/LP_commands.c index af12cb1c2..7de090f22 100644 --- a/iguana/exchanges/LP_commands.c +++ b/iguana/exchanges/LP_commands.c @@ -557,7 +557,9 @@ bot_resume(botid)\n\ //printf("network invoked\n"); LP_privkey_init(-1,ptr,G.LP_privkey,G.LP_mypub25519); //LP_smartutxos_push(ptr); - return(jprint(LP_address_utxos(ptr,coinaddr,1),1)); + if ( ptr->electrum != 0 ) + return(LP_unspents_filestr(coin,ptr->smartaddr)); + else return(jprint(LP_address_utxos(ptr,coinaddr,1),1)); } else { diff --git a/iguana/exchanges/LP_utxo.c b/iguana/exchanges/LP_utxo.c index 4cbe86e58..161e19502 100644 --- a/iguana/exchanges/LP_utxo.c +++ b/iguana/exchanges/LP_utxo.c @@ -1087,13 +1087,19 @@ void LP_unspents_cache(char *symbol,char *addr,char *arraystr,int32_t updatedfla } } +char *LP_unspents_filestr(char *symbol,char *addr) +{ + char fname[1024]; long fsize; + sprintf(fname,"%s/UNSPENTS/%s_%s",GLOBAL_DBDIR,symbol,addr), OS_portable_path(fname); + return(OS_filestr(&fsize,fname)); +} + uint64_t LP_unspents_load(char *symbol,char *addr) { - char fname[1024],*arraystr; uint64_t balance = 0; int32_t i,n; long fsize; struct iguana_info *coin; cJSON *retjson,*item; + char *arraystr; uint64_t balance = 0; int32_t i,n; cJSON *retjson,*item; struct iguana_info *coin; if ( (coin= LP_coinfind(symbol)) != 0 ) { - sprintf(fname,"%s/UNSPENTS/%s_%s",GLOBAL_DBDIR,symbol,addr), OS_portable_path(fname); - if ( (arraystr= OS_filestr(&fsize,fname)) != 0 ) + if ( (arraystr= LP_unspents_filestr(symbol,addr)) != 0 ) { if ( (retjson= cJSON_Parse(arraystr)) != 0 ) { From 348b63705f73949e1e8893bf0e88dc23e8a0d92c Mon Sep 17 00:00:00 2001 From: jl777 Date: Wed, 8 Nov 2017 02:27:03 +0200 Subject: [PATCH 0354/1664] Test --- iguana/exchanges/LP_rpc.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/iguana/exchanges/LP_rpc.c b/iguana/exchanges/LP_rpc.c index 343106e90..975b25cd7 100644 --- a/iguana/exchanges/LP_rpc.c +++ b/iguana/exchanges/LP_rpc.c @@ -694,7 +694,7 @@ cJSON *LP_listunspent(char *symbol,char *coinaddr) sprintf(buf,"[%d, 99999999, [\"%s\"]]",numconfs,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,1)); + } else return(electrum_address_listunspent(symbol,coin->electrum,&retjson,coinaddr,2)); } int32_t LP_listunspent_issue(char *symbol,char *coinaddr,int32_t fullflag) From 3ecfc1abc6b5bdc14b8749c8acb3d8a84236bc98 Mon Sep 17 00:00:00 2001 From: jl777 Date: Wed, 8 Nov 2017 02:30:10 +0200 Subject: [PATCH 0355/1664] Test --- iguana/exchanges/LP_include.h | 1 + iguana/exchanges/LP_socket.c | 8 +++++++- 2 files changed, 8 insertions(+), 1 deletion(-) diff --git a/iguana/exchanges/LP_include.h b/iguana/exchanges/LP_include.h index 444858583..517786bc9 100644 --- a/iguana/exchanges/LP_include.h +++ b/iguana/exchanges/LP_include.h @@ -425,6 +425,7 @@ 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 fullflag); uint16_t LP_randpeer(char *destip); +char *LP_unspents_filestr(char *symbol,char *addr); 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 zcash); //int32_t LP_butxo_findeither(bits256 txid,int32_t vout); cJSON *LP_listunspent(char *symbol,char *coinaddr); diff --git a/iguana/exchanges/LP_socket.c b/iguana/exchanges/LP_socket.c index c459e725a..2024d0deb 100644 --- a/iguana/exchanges/LP_socket.c +++ b/iguana/exchanges/LP_socket.c @@ -622,7 +622,13 @@ cJSON *electrum_address_listunspent(char *symbol,struct electrum_info *ep,cJSON } } if ( retjson == 0 ) - retjson = LP_address_utxos(coin,addr,1); + { + if ( strcmp(addr,coin->smartaddr) == 0 && (retstr= LP_unspents_filestr(symbol,coin->smartaddr)) != 0 ) + { + retjson = LP_address_utxos(coin,addr,1); + free(retstr); + } else retjson = LP_address_utxos(coin,addr,1); + } return(retjson); } From 1e4e6b41e71bb00f07e3cef9dac1a4edd6c85090 Mon Sep 17 00:00:00 2001 From: jl777 Date: Wed, 8 Nov 2017 02:51:07 +0200 Subject: [PATCH 0356/1664] Test --- iguana/exchanges/LP_commands.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/iguana/exchanges/LP_commands.c b/iguana/exchanges/LP_commands.c index 7de090f22..ddd95bc15 100644 --- a/iguana/exchanges/LP_commands.c +++ b/iguana/exchanges/LP_commands.c @@ -99,7 +99,7 @@ char *stats_JSON(void *ctx,char *myipaddr,int32_t pubsock,cJSON *argjson,char *r available localhost RPC commands: \n \ pricearray(base, rel, starttime=0, endtime=-1, timescale=60) -> [timestamp, avebid, aveask, highbid, lowask]\n\ setprice(base, rel, price)\n\ -autoprice(base, rel, minprice, margin, refbase, refrel, factor, offset)*\n\ +autoprice(base, rel, fixed, minprice, margin, refbase, refrel, factor, offset)*\n\ goal(coin=*, val=)\n\ myprice(base, rel)\n\ enable(coin)\n\ From b33ce9dec274549ae4fc7e886d1877b593441cd7 Mon Sep 17 00:00:00 2001 From: jl777 Date: Wed, 8 Nov 2017 03:31:00 +0200 Subject: [PATCH 0357/1664] Test --- iguana/exchanges/LP_nativeDEX.c | 1 + iguana/exchanges/LP_tradebots.c | 2 +- 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/iguana/exchanges/LP_nativeDEX.c b/iguana/exchanges/LP_nativeDEX.c index 27c15480b..a5a8677e9 100644 --- a/iguana/exchanges/LP_nativeDEX.c +++ b/iguana/exchanges/LP_nativeDEX.c @@ -18,6 +18,7 @@ // LP_nativeDEX.c // marketmaker // +// bot status 1600% ? // BCH signing // dPoW security -> 4: KMD notarized, 5: BTC notarized, after next notary elections // bigendian architectures need to use little endian for sighash calcs diff --git a/iguana/exchanges/LP_tradebots.c b/iguana/exchanges/LP_tradebots.c index 359e65c4a..fa7ab0292 100644 --- a/iguana/exchanges/LP_tradebots.c +++ b/iguana/exchanges/LP_tradebots.c @@ -445,7 +445,7 @@ char *LP_tradebot_buy(int32_t dispdir,char *base,char *rel,double maxprice,doubl jaddnum(retjson,"txfees",dstr(txfees)); shortfall = (relvolume + dstr(txfees)) - dstr(balance); jaddnum(retjson,"shortfall",shortfall); - if ( (balance= LP_RTsmartbalance(relcoin)) > abalance+SATOSHIDEN*(shortfall+relvolume/77.) ) + if ( (balance= LP_RTsmartbalance(relcoin)) > abalance+SATOSHIDEN*(shortfall+relvolume/777.) ) { char *withdrawstr; cJSON *outputjson,*withdrawjson,*outputs,*item; outputjson = cJSON_CreateObject(); From 805b228599dba7b684c32d38c0f14e44bd19e279 Mon Sep 17 00:00:00 2001 From: jl777 Date: Wed, 8 Nov 2017 03:35:03 +0200 Subject: [PATCH 0358/1664] Test --- iguana/exchanges/LP_tradebots.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/iguana/exchanges/LP_tradebots.c b/iguana/exchanges/LP_tradebots.c index fa7ab0292..83369a3b2 100644 --- a/iguana/exchanges/LP_tradebots.c +++ b/iguana/exchanges/LP_tradebots.c @@ -445,7 +445,10 @@ char *LP_tradebot_buy(int32_t dispdir,char *base,char *rel,double maxprice,doubl jaddnum(retjson,"txfees",dstr(txfees)); shortfall = (relvolume + dstr(txfees)) - dstr(balance); jaddnum(retjson,"shortfall",shortfall); - if ( (balance= LP_RTsmartbalance(relcoin)) > abalance+SATOSHIDEN*(shortfall+relvolume/777.) ) + if ( relcoin->electrum != 0 ) + balance = LP_unspents_load(relcoin->symbol,relcoin->smartaddr); + else balance = LP_RTsmartbalance(relcoin); + if ( balance > abalance+SATOSHIDEN*(shortfall+relvolume/777.) ) { char *withdrawstr; cJSON *outputjson,*withdrawjson,*outputs,*item; outputjson = cJSON_CreateObject(); From 82735661798beee0a77c676475b3a5e4aac04119 Mon Sep 17 00:00:00 2001 From: jl777 Date: Wed, 8 Nov 2017 03:38:44 +0200 Subject: [PATCH 0359/1664] Test --- iguana/exchanges/LP_coins.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/iguana/exchanges/LP_coins.c b/iguana/exchanges/LP_coins.c index fe9c20f34..38c62ac64 100644 --- a/iguana/exchanges/LP_coins.c +++ b/iguana/exchanges/LP_coins.c @@ -201,7 +201,9 @@ cJSON *LP_coinjson(struct iguana_info *coin,int32_t showwif) if ( coin->userpass[0] != 0 ) { jaddnum(item,"height",LP_getheight(coin)); - balance = LP_RTsmartbalance(coin); + if ( coin->electrum != 0 ) + balance = LP_unspents_load(coin->symbol,coin->smartaddr); + else balance = LP_RTsmartbalance(coin); jaddnum(item,"balance",dstr(balance)); jaddnum(item,"KMDvalue",dstr(LP_KMDvalue(coin,balance))); } From eb6db9acd1d5a5621f238b62633806139e5dbc03 Mon Sep 17 00:00:00 2001 From: jl777 Date: Wed, 8 Nov 2017 03:55:37 +0200 Subject: [PATCH 0360/1664] Test --- iguana/exchanges/LP_rpc.c | 2 +- iguana/exchanges/LP_tradebots.c | 9 +++++---- 2 files changed, 6 insertions(+), 5 deletions(-) diff --git a/iguana/exchanges/LP_rpc.c b/iguana/exchanges/LP_rpc.c index 975b25cd7..5b5791239 100644 --- a/iguana/exchanges/LP_rpc.c +++ b/iguana/exchanges/LP_rpc.c @@ -1040,7 +1040,7 @@ bits256 LP_getbestblockhash(struct iguana_info *coin) decode_hex(blockhash.bytes,sizeof(blockhash),retstr); free(retstr); } - } + } else printf("electrum mode doesnt support block level scanning\n"); return(blockhash); } diff --git a/iguana/exchanges/LP_tradebots.c b/iguana/exchanges/LP_tradebots.c index 83369a3b2..32db8dc62 100644 --- a/iguana/exchanges/LP_tradebots.c +++ b/iguana/exchanges/LP_tradebots.c @@ -438,17 +438,18 @@ char *LP_tradebot_buy(int32_t dispdir,char *base,char *rel,double maxprice,doubl if ( dstr(abalance) < relvolume + dstr(txfees) ) { retjson = cJSON_CreateObject(); + if ( relcoin->electrum != 0 ) + balance = LP_unspents_load(relcoin->symbol,relcoin->smartaddr); + else balance = LP_RTsmartbalance(relcoin); jaddstr(retjson,"error","not enough funds"); jaddstr(retjson,"coin",rel); + jaddnum(retjson,"abalance",dstr(abalance)); jaddnum(retjson,"balance",dstr(abalance)); jaddnum(retjson,"relvolume",relvolume); jaddnum(retjson,"txfees",dstr(txfees)); shortfall = (relvolume + dstr(txfees)) - dstr(balance); jaddnum(retjson,"shortfall",shortfall); - if ( relcoin->electrum != 0 ) - balance = LP_unspents_load(relcoin->symbol,relcoin->smartaddr); - else balance = LP_RTsmartbalance(relcoin); - if ( balance > abalance+SATOSHIDEN*(shortfall+relvolume/777.) ) + if ( balance > (relvolume + 10*relvolume/777.) ) { char *withdrawstr; cJSON *outputjson,*withdrawjson,*outputs,*item; outputjson = cJSON_CreateObject(); From 248cedd8f639a52b6340b3aa0cac33390dc9a77b Mon Sep 17 00:00:00 2001 From: jl777 Date: Wed, 8 Nov 2017 03:56:23 +0200 Subject: [PATCH 0361/1664] Test --- iguana/exchanges/LP_tradebots.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/iguana/exchanges/LP_tradebots.c b/iguana/exchanges/LP_tradebots.c index 32db8dc62..d58c870eb 100644 --- a/iguana/exchanges/LP_tradebots.c +++ b/iguana/exchanges/LP_tradebots.c @@ -444,7 +444,7 @@ char *LP_tradebot_buy(int32_t dispdir,char *base,char *rel,double maxprice,doubl jaddstr(retjson,"error","not enough funds"); jaddstr(retjson,"coin",rel); jaddnum(retjson,"abalance",dstr(abalance)); - jaddnum(retjson,"balance",dstr(abalance)); + jaddnum(retjson,"balance",dstr(balance)); jaddnum(retjson,"relvolume",relvolume); jaddnum(retjson,"txfees",dstr(txfees)); shortfall = (relvolume + dstr(txfees)) - dstr(balance); From 93eef2d96ce25455edf86d7ed78787559201c215 Mon Sep 17 00:00:00 2001 From: jl777 Date: Wed, 8 Nov 2017 04:16:39 +0200 Subject: [PATCH 0362/1664] Test --- iguana/exchanges/LP_nativeDEX.c | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/iguana/exchanges/LP_nativeDEX.c b/iguana/exchanges/LP_nativeDEX.c index a5a8677e9..31742b3f9 100644 --- a/iguana/exchanges/LP_nativeDEX.c +++ b/iguana/exchanges/LP_nativeDEX.c @@ -1197,11 +1197,19 @@ void LPinit(uint16_t myport,uint16_t mypullport,uint16_t mypubport,uint16_t mybu free(retstr); } else printf("issue_hello NULL return\n"); lasthello = (uint32_t)time(NULL); - if ( allgood == 0 ) + if ( (rand() % 10000) == 0 || allgood == 0 ) { printf("RPC port got stuck, close bindsocket\n"); LP_bindsock = -1; closesocket(sock); + LP_bindsock_reset++; + sleep(10); + printf("launch new rpcloop\n"); + if ( OS_thread_create(malloc(sizeof(pthread_t)),NULL,(void *)stats_rpcloop,(void *)&myport) != 0 ) + { + printf("error launching stats rpcloop for port.%u\n",myport); + exit(-1); + } } } } From 0a100562f7fe5f0b4fe0b2401dbb3aa6b656c0b6 Mon Sep 17 00:00:00 2001 From: jl777 Date: Wed, 8 Nov 2017 04:25:39 +0200 Subject: [PATCH 0363/1664] Test --- iguana/exchanges/LP_nativeDEX.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/iguana/exchanges/LP_nativeDEX.c b/iguana/exchanges/LP_nativeDEX.c index 31742b3f9..bbba34865 100644 --- a/iguana/exchanges/LP_nativeDEX.c +++ b/iguana/exchanges/LP_nativeDEX.c @@ -1197,7 +1197,7 @@ void LPinit(uint16_t myport,uint16_t mypullport,uint16_t mypubport,uint16_t mybu free(retstr); } else printf("issue_hello NULL return\n"); lasthello = (uint32_t)time(NULL); - if ( (rand() % 10000) == 0 || allgood == 0 ) + if ( LP_bindsock_reset == 0 || allgood == 0 ) { printf("RPC port got stuck, close bindsocket\n"); LP_bindsock = -1; From 4cddc89595e5c3516673e25ddac2a15dc6a10989 Mon Sep 17 00:00:00 2001 From: jl777 Date: Wed, 8 Nov 2017 04:30:21 +0200 Subject: [PATCH 0364/1664] Test --- iguana/exchanges/LP_nativeDEX.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/iguana/exchanges/LP_nativeDEX.c b/iguana/exchanges/LP_nativeDEX.c index bbba34865..9d90bfa7e 100644 --- a/iguana/exchanges/LP_nativeDEX.c +++ b/iguana/exchanges/LP_nativeDEX.c @@ -1197,7 +1197,7 @@ void LPinit(uint16_t myport,uint16_t mypullport,uint16_t mypubport,uint16_t mybu free(retstr); } else printf("issue_hello NULL return\n"); lasthello = (uint32_t)time(NULL); - if ( LP_bindsock_reset == 0 || allgood == 0 ) + if ( allgood == 0 ) { printf("RPC port got stuck, close bindsocket\n"); LP_bindsock = -1; From 7ce5a15bf27e374dc6bbffbddc2f033579074604 Mon Sep 17 00:00:00 2001 From: jl777 Date: Wed, 8 Nov 2017 10:24:56 +0200 Subject: [PATCH 0365/1664] Test --- iguana/exchanges/LP_include.h | 2 +- iguana/exchanges/LP_socket.c | 38 ++++++++++++++++++++++------------- 2 files changed, 25 insertions(+), 15 deletions(-) diff --git a/iguana/exchanges/LP_include.h b/iguana/exchanges/LP_include.h index 517786bc9..86430b461 100644 --- a/iguana/exchanges/LP_include.h +++ b/iguana/exchanges/LP_include.h @@ -41,7 +41,7 @@ void emscripten_usleep(int32_t x); // returns immediate, no sense for sleeping #define LP_AUTOTRADE_TIMEOUT 20 #define ELECTRUM_TIMEOUT 5 #define LP_ELECTRUM_KEEPALIVE 60 -#define LP_ELECTRUM_MAXERRORS 777 +#define LP_ELECTRUM_MAXERRORS 7 #define LP_MEMPOOL_TIMEINCR 10 #define LP_MIN_PEERS 8 diff --git a/iguana/exchanges/LP_socket.c b/iguana/exchanges/LP_socket.c index 2024d0deb..baeb85f58 100644 --- a/iguana/exchanges/LP_socket.c +++ b/iguana/exchanges/LP_socket.c @@ -389,6 +389,25 @@ void electrum_initial_requests(struct electrum_info *ep) electrum_sitem(ep,stratumreq,3,&retjson); } +int32_t electrum_kickstart(struct electrum_info *ep) +{ + closesocket(ep->sock), ep->sock = -1; + sleep(1); + if ( (ep->sock= LP_socket(0,ep->ipaddr,ep->port)) < 0 ) + { + printf("error RE-connecting to %s:%u\n",ep->ipaddr,ep->port); + return(-1); + } + else + { + ep->stratumid = 0; + electrum_initial_requests(ep); + printf("RECONNECT ep.%p %s numerrors.%d too big -> new %s:%u sock.%d\n",ep,ep->symbol,ep->numerrors,ep->ipaddr,ep->port,ep->sock); + ep->numerrors = 0; + } + return(0); +} + cJSON *electrum_submit(char *symbol,struct electrum_info *ep,cJSON **retjsonp,char *method,char *params,int32_t timeout) { // queue id and string and callback @@ -417,20 +436,9 @@ cJSON *electrum_submit(char *symbol,struct electrum_info *ep,cJSON **retjsonp,ch if ( *retjsonp == 0 || jobj(*retjsonp,"error") != 0 ) { if ( ++ep->numerrors >= LP_ELECTRUM_MAXERRORS ) - { - closesocket(ep->sock), ep->sock = -1; - if ( (ep->sock= LP_socket(0,ep->ipaddr,ep->port)) < 0 ) - printf("error RE-connecting to %s:%u\n",ep->ipaddr,ep->port); - else - { - ep->stratumid = 0; - electrum_initial_requests(ep); - printf("ep.%p %s numerrors.%d too big -> new %s:%u sock.%d\n",ep,ep->symbol,ep->numerrors,ep->ipaddr,ep->port,ep->sock); - ep->numerrors = 0; - } - } + electrum_kickstart(ep); } else if ( ep->numerrors > 0 ) - ep->numerrors++; + ep->numerrors--; if ( ep->prev == 0 ) { if ( *retjsonp == 0 ) @@ -1038,7 +1046,7 @@ void LP_dedicatedloop(void *arg) cJSON *LP_electrumserver(struct iguana_info *coin,char *ipaddr,uint16_t port) { - struct electrum_info *ep; int32_t already; cJSON *retjson; + struct electrum_info *ep; int32_t kickval,already; cJSON *retjson; if ( ipaddr == 0 || ipaddr[0] == 0 || port == 0 ) { //coin->electrum = 0; @@ -1070,8 +1078,10 @@ cJSON *LP_electrumserver(struct iguana_info *coin,char *ipaddr,uint16_t port) } else { + kickval = electrum_kickstart(ep); jaddstr(retjson,"result","success"); jaddstr(retjson,"status","already there"); + jaddstr(retjson,"restart",kickval); } //printf("(%s)\n",jprint(retjson,0)); return(retjson); From ac3a9649c9b2a1fb8f22c11efcfcfe0b9a82b636 Mon Sep 17 00:00:00 2001 From: jl777 Date: Wed, 8 Nov 2017 10:31:21 +0200 Subject: [PATCH 0366/1664] Test --- iguana/exchanges/LP_include.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/iguana/exchanges/LP_include.h b/iguana/exchanges/LP_include.h index 86430b461..517786bc9 100644 --- a/iguana/exchanges/LP_include.h +++ b/iguana/exchanges/LP_include.h @@ -41,7 +41,7 @@ void emscripten_usleep(int32_t x); // returns immediate, no sense for sleeping #define LP_AUTOTRADE_TIMEOUT 20 #define ELECTRUM_TIMEOUT 5 #define LP_ELECTRUM_KEEPALIVE 60 -#define LP_ELECTRUM_MAXERRORS 7 +#define LP_ELECTRUM_MAXERRORS 777 #define LP_MEMPOOL_TIMEINCR 10 #define LP_MIN_PEERS 8 From 5b590d984d150c23199533e1534c8299f40284e8 Mon Sep 17 00:00:00 2001 From: jl777 Date: Wed, 8 Nov 2017 10:31:54 +0200 Subject: [PATCH 0367/1664] Test --- iguana/exchanges/LP_socket.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/iguana/exchanges/LP_socket.c b/iguana/exchanges/LP_socket.c index baeb85f58..2afbef6b1 100644 --- a/iguana/exchanges/LP_socket.c +++ b/iguana/exchanges/LP_socket.c @@ -124,9 +124,9 @@ int32_t LP_socket(int32_t bindflag,char *hostname,uint16_t port) #endif if ( bindflag == 0 ) { - printf("call connect sock.%d\n",sock); + //printf("call connect sock.%d\n",sock); result = connect(sock,(struct sockaddr *)&saddr,addrlen); - printf("called connect result.%d\n",result); + //printf("called connect result.%d\n",result); timeout.tv_sec = 2; timeout.tv_usec = 0; setsockopt(sock,SOL_SOCKET,SO_RCVTIMEO,(void *)&timeout,sizeof(timeout)); From 6d7ede8652561db98e4f148d49f11a43e594f699 Mon Sep 17 00:00:00 2001 From: jl777 Date: Wed, 8 Nov 2017 13:28:29 +0200 Subject: [PATCH 0368/1664] Test --- iguana/exchanges/LP_socket.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/iguana/exchanges/LP_socket.c b/iguana/exchanges/LP_socket.c index 2afbef6b1..69c79217c 100644 --- a/iguana/exchanges/LP_socket.c +++ b/iguana/exchanges/LP_socket.c @@ -1081,7 +1081,7 @@ cJSON *LP_electrumserver(struct iguana_info *coin,char *ipaddr,uint16_t port) kickval = electrum_kickstart(ep); jaddstr(retjson,"result","success"); jaddstr(retjson,"status","already there"); - jaddstr(retjson,"restart",kickval); + jaddnum(retjson,"restart",kickval); } //printf("(%s)\n",jprint(retjson,0)); return(retjson); From aea6102369f1b4c60a71cc35876f1a9cef0abff8 Mon Sep 17 00:00:00 2001 From: jl777 Date: Wed, 8 Nov 2017 17:12:25 +0200 Subject: [PATCH 0369/1664] Test --- iguana/exchanges/LP_nativeDEX.c | 2 +- iguana/exchanges/LP_rpc.c | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/iguana/exchanges/LP_nativeDEX.c b/iguana/exchanges/LP_nativeDEX.c index 9d90bfa7e..e26ce29b5 100644 --- a/iguana/exchanges/LP_nativeDEX.c +++ b/iguana/exchanges/LP_nativeDEX.c @@ -1181,7 +1181,7 @@ void LPinit(uint16_t myport,uint16_t mypullport,uint16_t mypubport,uint16_t mybu usleep(1000); else if ( IAMLP == 0 ) usleep(1000); - if ( time(NULL) > lasthello+60 ) + if ( time(NULL) > lasthello+600 ) { char *hellostr,*retstr; cJSON *retjson; int32_t allgood,sock = LP_bindsock; allgood = 0; diff --git a/iguana/exchanges/LP_rpc.c b/iguana/exchanges/LP_rpc.c index 5b5791239..43dd88d52 100644 --- a/iguana/exchanges/LP_rpc.c +++ b/iguana/exchanges/LP_rpc.c @@ -98,7 +98,7 @@ char *issue_hello(uint16_t port) char url[512]; sprintf(url,"http://127.0.0.1:%u/api/stats/hello",port); //printf("getutxo.(%s)\n",url); - return(issue_curlt(url,60)); // might be starting a trade + return(issue_curlt(url,600)); // might be starting a trade } char *issue_LP_listunspent(char *destip,uint16_t destport,char *symbol,char *coinaddr) From c9dba66fe0a9451e4e285b2af6a6d5189b9d8917 Mon Sep 17 00:00:00 2001 From: jl777 Date: Wed, 8 Nov 2017 17:15:07 +0200 Subject: [PATCH 0370/1664] Test --- iguana/exchanges/LP_nativeDEX.c | 21 ++++++++++++--------- 1 file changed, 12 insertions(+), 9 deletions(-) diff --git a/iguana/exchanges/LP_nativeDEX.c b/iguana/exchanges/LP_nativeDEX.c index e26ce29b5..7ea525e43 100644 --- a/iguana/exchanges/LP_nativeDEX.c +++ b/iguana/exchanges/LP_nativeDEX.c @@ -1199,16 +1199,19 @@ void LPinit(uint16_t myport,uint16_t mypullport,uint16_t mypubport,uint16_t mybu lasthello = (uint32_t)time(NULL); if ( allgood == 0 ) { - printf("RPC port got stuck, close bindsocket\n"); - LP_bindsock = -1; - closesocket(sock); - LP_bindsock_reset++; - sleep(10); - printf("launch new rpcloop\n"); - if ( OS_thread_create(malloc(sizeof(pthread_t)),NULL,(void *)stats_rpcloop,(void *)&myport) != 0 ) + printf("RPC port got stuck, would have close bindsocket\n"); + if ( 0 ) { - printf("error launching stats rpcloop for port.%u\n",myport); - exit(-1); + LP_bindsock = -1; + closesocket(sock); + LP_bindsock_reset++; + sleep(10); + printf("launch new rpcloop\n"); + if ( OS_thread_create(malloc(sizeof(pthread_t)),NULL,(void *)stats_rpcloop,(void *)&myport) != 0 ) + { + printf("error launching stats rpcloop for port.%u\n",myport); + exit(-1); + } } } } From 68ea59584c988d41f5ccb29a3a143b2dea71bba4 Mon Sep 17 00:00:00 2001 From: jl777 Date: Wed, 8 Nov 2017 17:15:38 +0200 Subject: [PATCH 0371/1664] Test --- iguana/exchanges/LP_nativeDEX.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/iguana/exchanges/LP_nativeDEX.c b/iguana/exchanges/LP_nativeDEX.c index 7ea525e43..c43655e3e 100644 --- a/iguana/exchanges/LP_nativeDEX.c +++ b/iguana/exchanges/LP_nativeDEX.c @@ -1181,7 +1181,7 @@ void LPinit(uint16_t myport,uint16_t mypullport,uint16_t mypubport,uint16_t mybu usleep(1000); else if ( IAMLP == 0 ) usleep(1000); - if ( time(NULL) > lasthello+600 ) + if ( IAMLP != 0 && time(NULL) > lasthello+600 ) { char *hellostr,*retstr; cJSON *retjson; int32_t allgood,sock = LP_bindsock; allgood = 0; From 5869ad7d9762bbb9c96517d51b86efd0129c4f6b Mon Sep 17 00:00:00 2001 From: jl777 Date: Wed, 8 Nov 2017 17:33:57 +0200 Subject: [PATCH 0372/1664] Test --- iguana/exchanges/stats.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/iguana/exchanges/stats.c b/iguana/exchanges/stats.c index 872f7b332..fdb8de240 100644 --- a/iguana/exchanges/stats.c +++ b/iguana/exchanges/stats.c @@ -724,7 +724,7 @@ void LP_rpc_processreq(void *_ptr) remains -= numsent; i += numsent; if ( remains > 0 ) - printf("iguana sent.%d remains.%d of len.%d\n",numsent,remains,recvlen); + printf("iguana sent.%d remains.%d of recvlen.%d (%s)\n",numsent,remains,recvlen,jsonbuf); } } if ( retstr != space) From 37aef662bd030a6b824f754cc43dcd8b92b4da2e Mon Sep 17 00:00:00 2001 From: jl777 Date: Wed, 8 Nov 2017 17:35:09 +0200 Subject: [PATCH 0373/1664] Test --- iguana/exchanges/LP_nativeDEX.c | 2 +- iguana/exchanges/LP_network.c | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/iguana/exchanges/LP_nativeDEX.c b/iguana/exchanges/LP_nativeDEX.c index c43655e3e..bfb3b9bd2 100644 --- a/iguana/exchanges/LP_nativeDEX.c +++ b/iguana/exchanges/LP_nativeDEX.c @@ -448,7 +448,7 @@ void command_rpcloop(void *myipaddr) void utxosQ_loop(void *myipaddr) { strcpy(utxosQ_loop_stats.name,"utxosQ_loop"); - utxosQ_loop_stats.threshold = 150.; + utxosQ_loop_stats.threshold = 500.; while ( 1 ) { LP_millistats_update(&utxosQ_loop_stats); diff --git a/iguana/exchanges/LP_network.c b/iguana/exchanges/LP_network.c index 0a6812890..198e384c6 100644 --- a/iguana/exchanges/LP_network.c +++ b/iguana/exchanges/LP_network.c @@ -183,7 +183,7 @@ bits256 LP_calc_magic(uint8_t *msg,int32_t len) sum += (OS_milliseconds() - millis); nsum += n; counter++; - if ( n > maxn || (rand() % 100) == 0 ) + if ( n > maxn || (rand() % 10000) == 0 ) { if ( n > maxn ) { From 0b16aae6994c2ff96a37b9fa242c693fd76012af Mon Sep 17 00:00:00 2001 From: jl777 Date: Wed, 8 Nov 2017 17:51:47 +0200 Subject: [PATCH 0374/1664] Revert to blocking sockets --- iguana/exchanges/stats.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/iguana/exchanges/stats.c b/iguana/exchanges/stats.c index fdb8de240..65fcb0a24 100644 --- a/iguana/exchanges/stats.c +++ b/iguana/exchanges/stats.c @@ -758,7 +758,7 @@ void stats_rpcloop(void *args) while ( (LP_bindsock= iguana_socket(1,"0.0.0.0",port)) < 0 ) usleep(10000); #ifndef _WIN32 - fcntl(LP_bindsock, F_SETFL, fcntl(LP_bindsock, F_GETFL, 0) | O_NONBLOCK); + //fcntl(LP_bindsock, F_SETFL, fcntl(LP_bindsock, F_GETFL, 0) | O_NONBLOCK); #endif //if ( counter++ < 1 ) printf(">>>>>>>>>> DEX stats 127.0.0.1:%d bind sock.%d DEX stats API enabled <<<<<<<<<\n",port,LP_bindsock); @@ -766,7 +766,7 @@ void stats_rpcloop(void *args) //printf("after LP_bindsock.%d\n",LP_bindsock); clilen = sizeof(cli_addr); sock = accept(LP_bindsock,(struct sockaddr *)&cli_addr,&clilen); -#ifdef _WIN32 +//#ifdef _WIN32 if ( sock < 0 ) { printf("iguana_rpcloop ERROR on accept usock.%d errno %d %s\n",sock,errno,strerror(errno)); @@ -774,7 +774,7 @@ void stats_rpcloop(void *args) LP_bindsock = -1; continue; } -#else +/*#else if ( sock < 0 ) { //fprintf(stderr,"."); @@ -783,7 +783,7 @@ void stats_rpcloop(void *args) else usleep(2500); continue; } -#endif +#endif*/ memcpy(&ipbits,&cli_addr.sin_addr.s_addr,sizeof(ipbits)); req = calloc(1,sizeof(*req)); req->sock = sock; From e6f7f6ae036c56d639c0112f41ad8b4bb35562cf Mon Sep 17 00:00:00 2001 From: jl777 Date: Wed, 8 Nov 2017 18:04:23 +0200 Subject: [PATCH 0375/1664] Test --- iguana/exchanges/LP_nativeDEX.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/iguana/exchanges/LP_nativeDEX.c b/iguana/exchanges/LP_nativeDEX.c index bfb3b9bd2..652ed565a 100644 --- a/iguana/exchanges/LP_nativeDEX.c +++ b/iguana/exchanges/LP_nativeDEX.c @@ -707,8 +707,8 @@ int32_t LP_mainloop_iter(void *ctx,char *myipaddr,struct LP_peerinfo *mypeer,int { nonz++; LP_peersquery(mypeer,pubsock,peer->ipaddr,peer->port,myipaddr,myport); - peer->diduquery = 0; - LP_peer_pricesquery(peer); + if ( peer->diduquery == 0 ) + LP_peer_pricesquery(peer); LP_utxos_sync(peer); needpings++; } From b94d73f70c076a9d61875d2beb95307940731eef Mon Sep 17 00:00:00 2001 From: jl777 Date: Wed, 8 Nov 2017 18:20:08 +0200 Subject: [PATCH 0376/1664] Test --- iguana/exchanges/LP_include.h | 2 +- iguana/exchanges/LP_nativeDEX.c | 2 +- iguana/exchanges/stats.c | 4 ++-- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/iguana/exchanges/LP_include.h b/iguana/exchanges/LP_include.h index 517786bc9..2f03c6f75 100644 --- a/iguana/exchanges/LP_include.h +++ b/iguana/exchanges/LP_include.h @@ -59,7 +59,7 @@ void emscripten_usleep(int32_t x); // returns immediate, no sense for sleeping #define LP_COMMAND_RECVSOCK NN_PULL #define DPOW_MIN_ASSETCHAIN_SIGS 11 -#define LP_ENCRYPTED_MAXSIZE (4096 + 2 + crypto_box_NONCEBYTES + crypto_box_ZEROBYTES) +#define LP_ENCRYPTED_MAXSIZE (16384 + 2 + crypto_box_NONCEBYTES + crypto_box_ZEROBYTES) #define LP_MAXPUBKEY_ERRORS 10 #define PSOCK_KEEPALIVE 3600 diff --git a/iguana/exchanges/LP_nativeDEX.c b/iguana/exchanges/LP_nativeDEX.c index 652ed565a..0949429aa 100644 --- a/iguana/exchanges/LP_nativeDEX.c +++ b/iguana/exchanges/LP_nativeDEX.c @@ -883,7 +883,7 @@ void LP_swapsloop(void *ignore) //printf("LP_swapsloop %u\n",LP_counter); if ( (retstr= basilisk_swapentry(0,0)) != 0 ) free(retstr); - LP_millistats_update(0); + //LP_millistats_update(0); sleep(600); } } diff --git a/iguana/exchanges/stats.c b/iguana/exchanges/stats.c index 65fcb0a24..d3b286f22 100644 --- a/iguana/exchanges/stats.c +++ b/iguana/exchanges/stats.c @@ -668,9 +668,9 @@ void LP_rpc_processreq(void *_ptr) if ( recvlen > 0 ) { jsonflag = postflag = 0; - portable_mutex_lock(&LP_commandmutex); + //portable_mutex_lock(&LP_commandmutex); retstr = stats_rpcparse(space,size,&jsonflag,&postflag,jsonbuf,remoteaddr,filetype,RPC_port); - portable_mutex_unlock(&LP_commandmutex); + //portable_mutex_unlock(&LP_commandmutex); if ( filetype[0] != 0 ) { static cJSON *mimejson; char *tmp,*typestr=0; long tmpsize; From 10bb55f5fb993878ee3755b58de6c94935ba2f3c Mon Sep 17 00:00:00 2001 From: jl777 Date: Wed, 8 Nov 2017 18:22:17 +0200 Subject: [PATCH 0377/1664] Test --- iguana/exchanges/LP_ordermatch.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/iguana/exchanges/LP_ordermatch.c b/iguana/exchanges/LP_ordermatch.c index 8130706bf..30d3a8cb9 100644 --- a/iguana/exchanges/LP_ordermatch.c +++ b/iguana/exchanges/LP_ordermatch.c @@ -859,8 +859,8 @@ struct LP_utxoinfo *LP_buyutxo(double *ordermatchpricep,int64_t *bestsatoshisp,i item = jitem(asks,i); price = jdouble(item,"price"); if ( price/maxprice < .9 ) - price *= 1.025; - else price *= 1.001; + price *= 1.05; + else price *= 1.01; pubkey = jbits256(item,"pubkey"); if ( bits256_nonz(destpubkey) != 0 && bits256_cmp(destpubkey,pubkey) != 0 ) continue; From d4ed64211e977aa7bdc3a1f268e357f4fa7884e0 Mon Sep 17 00:00:00 2001 From: jl777 Date: Wed, 8 Nov 2017 18:27:37 +0200 Subject: [PATCH 0378/1664] Test --- iguana/exchanges/LP_transaction.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/iguana/exchanges/LP_transaction.c b/iguana/exchanges/LP_transaction.c index 3148e9f0f..dac30e51d 100644 --- a/iguana/exchanges/LP_transaction.c +++ b/iguana/exchanges/LP_transaction.c @@ -1053,7 +1053,7 @@ char *LP_createrawtransaction(cJSON **txobjp,int32_t *numvinsp,struct iguana_inf 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,utxotxid,utxovout,dustcombine); - if ( total < amount ) + if ( numvins <= 0 || total < amount ) { printf("change %.8f = total %.8f - amount %.8f, adjust %.8f numvouts.%d, txfee %.8f\n",dstr(change),dstr(total),dstr(amount),dstr(adjust),numvouts,dstr(txfee)); printf("not enough inputs for amount %.8f < %.8f txfee %.8f\n",dstr(total),dstr(amount),dstr(txfee)); From 23106b5044b6562d88d0538dace34e28d2b79f72 Mon Sep 17 00:00:00 2001 From: jl777 Date: Wed, 8 Nov 2017 18:29:38 +0200 Subject: [PATCH 0379/1664] Test --- iguana/exchanges/LP_transaction.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/iguana/exchanges/LP_transaction.c b/iguana/exchanges/LP_transaction.c index dac30e51d..ee42d08fb 100644 --- a/iguana/exchanges/LP_transaction.c +++ b/iguana/exchanges/LP_transaction.c @@ -922,7 +922,7 @@ int32_t LP_vins_select(void *ctx,struct iguana_info *coin,int64_t *totalp,int64_ if ( dustcombine >= 2 && min1 != 0 && min1->U.value < LP_DUSTCOMBINE_THRESHOLD && (coin->electrum == 0 || min1->SPV > 0) ) preselected[numpre++] = min1; else min1 = 0; - printf("dustcombine.%d numpre.%d min0.%p min1.%p numutxos.%d\n",dustcombine,numpre,min0,min1,numunspents); + printf("dustcombine.%d numpre.%d min0.%p min1.%p numutxos.%d amount %.8f\n",dustcombine,numpre,min0,min1,numunspents); for (i=0; ispendheight = 1; total += up->U.value; remains -= up->U.value; + interest = 0; if ( up->U.height < 7777777 && strcmp(coin->symbol,"KMD") == 0 ) { if ( (interest= LP_komodo_interest(up->U.txid,up->U.value)) > 0 ) @@ -970,6 +971,7 @@ int32_t LP_vins_select(void *ctx,struct iguana_info *coin,int64_t *totalp,int64_ char str[65]; printf("%s/%d %.8f interest %.8f -> sum %.8f\n",bits256_str(str,up->U.txid),up->U.vout,dstr(up->U.value),dstr(interest),dstr(interestsum)); } } + printf("vini.%d value %.8f, total %.8f remains %.8f interest %.8f sum %.8f\n",n,dstr(up->U.value),dstr(total),dstr(remains),dstr(interest),dstr(interestsum)); vp = &V[n++]; vp->N = vp->M = 1; vp->signers[0].privkey = privkey; From ab2d0ccd81821ee8de2e1eb462e998dadf1ae626 Mon Sep 17 00:00:00 2001 From: jl777 Date: Wed, 8 Nov 2017 18:30:55 +0200 Subject: [PATCH 0380/1664] Test --- iguana/exchanges/LP_transaction.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/iguana/exchanges/LP_transaction.c b/iguana/exchanges/LP_transaction.c index ee42d08fb..a2042aab3 100644 --- a/iguana/exchanges/LP_transaction.c +++ b/iguana/exchanges/LP_transaction.c @@ -922,7 +922,7 @@ int32_t LP_vins_select(void *ctx,struct iguana_info *coin,int64_t *totalp,int64_ if ( dustcombine >= 2 && min1 != 0 && min1->U.value < LP_DUSTCOMBINE_THRESHOLD && (coin->electrum == 0 || min1->SPV > 0) ) preselected[numpre++] = min1; else min1 = 0; - printf("dustcombine.%d numpre.%d min0.%p min1.%p numutxos.%d amount %.8f\n",dustcombine,numpre,min0,min1,numunspents); + printf("dustcombine.%d numpre.%d min0.%p min1.%p numutxos.%d amount %.8f\n",dustcombine,numpre,min0,min1,numunspents,dstr(amount)); for (i=0; i total %.8f\n",i,dstr(value),dstr(amount)); } else { From eec886520570e6a043e02c770c774ef6938ece1b Mon Sep 17 00:00:00 2001 From: jl777 Date: Wed, 8 Nov 2017 18:32:21 +0200 Subject: [PATCH 0381/1664] Test --- iguana/exchanges/stats.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/iguana/exchanges/stats.c b/iguana/exchanges/stats.c index d3b286f22..65fcb0a24 100644 --- a/iguana/exchanges/stats.c +++ b/iguana/exchanges/stats.c @@ -668,9 +668,9 @@ void LP_rpc_processreq(void *_ptr) if ( recvlen > 0 ) { jsonflag = postflag = 0; - //portable_mutex_lock(&LP_commandmutex); + portable_mutex_lock(&LP_commandmutex); retstr = stats_rpcparse(space,size,&jsonflag,&postflag,jsonbuf,remoteaddr,filetype,RPC_port); - //portable_mutex_unlock(&LP_commandmutex); + portable_mutex_unlock(&LP_commandmutex); if ( filetype[0] != 0 ) { static cJSON *mimejson; char *tmp,*typestr=0; long tmpsize; From f0b264da23b498c56d58ea18ad5d321311fdcefa Mon Sep 17 00:00:00 2001 From: jl777 Date: Wed, 8 Nov 2017 18:38:05 +0200 Subject: [PATCH 0382/1664] Test --- iguana/exchanges/LP_nativeDEX.c | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/iguana/exchanges/LP_nativeDEX.c b/iguana/exchanges/LP_nativeDEX.c index 0949429aa..36e903a3f 100644 --- a/iguana/exchanges/LP_nativeDEX.c +++ b/iguana/exchanges/LP_nativeDEX.c @@ -1115,6 +1115,12 @@ void LPinit(uint16_t myport,uint16_t mypullport,uint16_t mypubport,uint16_t mybu printf("error launching stats rpcloop for port.%u\n",myport); exit(-1); } + uint16_t myport2 = myport-1; + if ( OS_thread_create(malloc(sizeof(pthread_t)),NULL,(void *)stats_rpcloop,(void *)&myport2) != 0 ) + { + printf("error launching stats rpcloop for port.%u\n",myport); + exit(-1); + } if ( OS_thread_create(malloc(sizeof(pthread_t)),NULL,(void *)command_rpcloop,(void *)myipaddr) != 0 ) { printf("error launching command_rpcloop for port.%u\n",myport); From dbf2b9e9a6a5739063394cfa8d471f1a10c51933 Mon Sep 17 00:00:00 2001 From: jl777 Date: Wed, 8 Nov 2017 18:41:22 +0200 Subject: [PATCH 0383/1664] Test --- iguana/exchanges/LP_rpc.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/iguana/exchanges/LP_rpc.c b/iguana/exchanges/LP_rpc.c index 43dd88d52..e621ac0a6 100644 --- a/iguana/exchanges/LP_rpc.c +++ b/iguana/exchanges/LP_rpc.c @@ -22,6 +22,8 @@ char *LP_issue_curl(char *debugstr,char *destip,uint16_t port,char *url) { char *retstr = 0; int32_t maxerrs; struct LP_peerinfo *peer = 0; peer = LP_peerfind((uint32_t)calc_ipbits(destip),port); + if ( strcmp(destip,"127.0.0.1") != 0 ) + port--; maxerrs = LP_MAXPEER_ERRORS; if ( peer == 0 || (peer->errors < maxerrs || peer->good >= LP_MINPEER_GOOD) ) { From 3f081ad51a001d97a2e214055fa4ab4c65dd4389 Mon Sep 17 00:00:00 2001 From: jl777 Date: Wed, 8 Nov 2017 18:46:05 +0200 Subject: [PATCH 0384/1664] Test --- iguana/exchanges/LP_nativeDEX.c | 6 +++--- iguana/exchanges/stats.c | 29 +++++++++++++++-------------- 2 files changed, 18 insertions(+), 17 deletions(-) diff --git a/iguana/exchanges/LP_nativeDEX.c b/iguana/exchanges/LP_nativeDEX.c index 36e903a3f..307e2f682 100644 --- a/iguana/exchanges/LP_nativeDEX.c +++ b/iguana/exchanges/LP_nativeDEX.c @@ -1171,7 +1171,7 @@ void LPinit(uint16_t myport,uint16_t mypullport,uint16_t mypubport,uint16_t mybu printf("error launching LP_swapsloop for port.%u\n",myport); exit(-1); } - int32_t nonz; uint32_t lasthello = 0; + int32_t nonz; //uint32_t lasthello = 0; while ( 1 ) { nonz = 0; @@ -1187,7 +1187,7 @@ void LPinit(uint16_t myport,uint16_t mypullport,uint16_t mypubport,uint16_t mybu usleep(1000); else if ( IAMLP == 0 ) usleep(1000); - if ( IAMLP != 0 && time(NULL) > lasthello+600 ) + /*if ( IAMLP != 0 && time(NULL) > lasthello+600 ) { char *hellostr,*retstr; cJSON *retjson; int32_t allgood,sock = LP_bindsock; allgood = 0; @@ -1220,7 +1220,7 @@ void LPinit(uint16_t myport,uint16_t mypullport,uint16_t mypubport,uint16_t mybu } } } - } + }*/ } #endif } diff --git a/iguana/exchanges/stats.c b/iguana/exchanges/stats.c index 65fcb0a24..e066f87ca 100644 --- a/iguana/exchanges/stats.c +++ b/iguana/exchanges/stats.c @@ -740,38 +740,39 @@ void LP_rpc_processreq(void *_ptr) } extern int32_t IAMLP; -int32_t LP_bindsock_reset,LP_bindsock = -1; +//int32_t LP_bindsock_reset,LP_bindsock = -1; void stats_rpcloop(void *args) { - uint16_t port; int32_t retval,sock,initial_bindsock_reset; socklen_t clilen; struct sockaddr_in cli_addr; uint32_t ipbits,localhostbits; struct rpcrequest_info *req,*req2,*rtmp; + uint16_t port; int32_t retval,sock=-1; socklen_t clilen; struct sockaddr_in cli_addr; uint32_t ipbits,localhostbits; struct rpcrequest_info *req,*req2,*rtmp; if ( (port= *(uint16_t *)args) == 0 ) port = 7779; RPC_port = port; + printf("Start stats_rpcloop.%u\n",port); localhostbits = (uint32_t)calc_ipbits("127.0.0.1"); - initial_bindsock_reset = LP_bindsock_reset; - while ( LP_bindsock_reset == initial_bindsock_reset ) + //initial_bindsock_reset = LP_bindsock_reset; + while ( 1 )//LP_bindsock_reset == initial_bindsock_reset ) { //printf("LP_bindsock.%d\n",LP_bindsock); - if ( LP_bindsock < 0 ) + if ( sock < 0 ) { - while ( (LP_bindsock= iguana_socket(1,"0.0.0.0",port)) < 0 ) + while ( (sock= iguana_socket(1,"0.0.0.0",port)) < 0 ) usleep(10000); #ifndef _WIN32 - //fcntl(LP_bindsock, F_SETFL, fcntl(LP_bindsock, F_GETFL, 0) | O_NONBLOCK); + //fcntl(sock, F_SETFL, fcntl(sock, F_GETFL, 0) | O_NONBLOCK); #endif //if ( counter++ < 1 ) - printf(">>>>>>>>>> DEX stats 127.0.0.1:%d bind sock.%d DEX stats API enabled <<<<<<<<<\n",port,LP_bindsock); + printf(">>>>>>>>>> DEX stats 127.0.0.1:%d bind sock.%d DEX stats API enabled <<<<<<<<<\n",port,sock); } - //printf("after LP_bindsock.%d\n",LP_bindsock); + //printf("after sock.%d\n",sock); clilen = sizeof(cli_addr); - sock = accept(LP_bindsock,(struct sockaddr *)&cli_addr,&clilen); + sock = accept(sock,(struct sockaddr *)&cli_addr,&clilen); //#ifdef _WIN32 if ( sock < 0 ) { printf("iguana_rpcloop ERROR on accept usock.%d errno %d %s\n",sock,errno,strerror(errno)); - closesocket(LP_bindsock); - LP_bindsock = -1; + closesocket(sock); + sock = -1; continue; } /*#else @@ -794,8 +795,8 @@ continue; if ( (retval= OS_thread_create(&req->T,NULL,(void *)LP_rpc_processreq,req)) != 0 ) { printf("error launching rpc handler on port %d, retval.%d\n",port,retval); - closesocket(LP_bindsock); - LP_bindsock = -1; + closesocket(sock); + sock = -1; portable_mutex_lock(&LP_gcmutex); DL_FOREACH_SAFE(LP_garbage_collector,req2,rtmp) { From d02ad6a09e529527b4a02b0a21345352e93c9639 Mon Sep 17 00:00:00 2001 From: jl777 Date: Wed, 8 Nov 2017 18:50:27 +0200 Subject: [PATCH 0385/1664] Test --- iguana/exchanges/stats.c | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/iguana/exchanges/stats.c b/iguana/exchanges/stats.c index e066f87ca..6ec674426 100644 --- a/iguana/exchanges/stats.c +++ b/iguana/exchanges/stats.c @@ -744,7 +744,7 @@ extern int32_t IAMLP; void stats_rpcloop(void *args) { - uint16_t port; int32_t retval,sock=-1; socklen_t clilen; struct sockaddr_in cli_addr; uint32_t ipbits,localhostbits; struct rpcrequest_info *req,*req2,*rtmp; + uint16_t port; int32_t retval,sock=-1,bindsock=-1; socklen_t clilen; struct sockaddr_in cli_addr; uint32_t ipbits,localhostbits; struct rpcrequest_info *req,*req2,*rtmp; if ( (port= *(uint16_t *)args) == 0 ) port = 7779; RPC_port = port; @@ -754,25 +754,25 @@ void stats_rpcloop(void *args) while ( 1 )//LP_bindsock_reset == initial_bindsock_reset ) { //printf("LP_bindsock.%d\n",LP_bindsock); - if ( sock < 0 ) + if ( bindsock < 0 ) { - while ( (sock= iguana_socket(1,"0.0.0.0",port)) < 0 ) + while ( (bindsock= iguana_socket(1,"0.0.0.0",port)) < 0 ) usleep(10000); #ifndef _WIN32 - //fcntl(sock, F_SETFL, fcntl(sock, F_GETFL, 0) | O_NONBLOCK); + //fcntl(bindsock, F_SETFL, fcntl(bindsock, F_GETFL, 0) | O_NONBLOCK); #endif //if ( counter++ < 1 ) - printf(">>>>>>>>>> DEX stats 127.0.0.1:%d bind sock.%d DEX stats API enabled <<<<<<<<<\n",port,sock); + printf(">>>>>>>>>> DEX stats 127.0.0.1:%d bind sock.%d DEX stats API enabled <<<<<<<<<\n",port,bindsock); } //printf("after sock.%d\n",sock); clilen = sizeof(cli_addr); - sock = accept(sock,(struct sockaddr *)&cli_addr,&clilen); + sock = accept(bindsock,(struct sockaddr *)&cli_addr,&clilen); //#ifdef _WIN32 if ( sock < 0 ) { - printf("iguana_rpcloop ERROR on accept usock.%d errno %d %s\n",sock,errno,strerror(errno)); - closesocket(sock); - sock = -1; + printf("iguana_rpcloop ERROR on accept port.%u usock.%d errno %d %s\n",port,sock,errno,strerror(errno)); + closesocket(bindsock); + bindsock = -1; continue; } /*#else From df43263232730cee9d1571332376c30418f8ad61 Mon Sep 17 00:00:00 2001 From: jl777 Date: Wed, 8 Nov 2017 20:07:35 +0200 Subject: [PATCH 0386/1664] Test --- iguana/exchanges/LP_commands.c | 143 +++++++++++----------- iguana/exchanges/LP_include.h | 3 +- iguana/exchanges/LP_nativeDEX.c | 108 +++-------------- iguana/exchanges/LP_network.c | 9 -- iguana/exchanges/LP_peers.c | 29 ----- iguana/exchanges/LP_prices.c | 4 +- iguana/exchanges/LP_rpc.c | 82 +++++-------- iguana/exchanges/LP_statemachine.c | 185 +++++++++++++++++++++++++++++ iguana/exchanges/stats.c | 2 +- 9 files changed, 302 insertions(+), 263 deletions(-) diff --git a/iguana/exchanges/LP_commands.c b/iguana/exchanges/LP_commands.c index ddd95bc15..5a45d9ee8 100644 --- a/iguana/exchanges/LP_commands.c +++ b/iguana/exchanges/LP_commands.c @@ -74,7 +74,7 @@ char *stats_JSON(void *ctx,char *myipaddr,int32_t pubsock,cJSON *argjson,char *r //printf("got hello from %s:%u\n",ipaddr!=0?ipaddr:"",argport); return(clonestr("{\"result\":\"success\",\"status\":\"got hello\"}")); } - else if ( strcmp(method,"sendmessage") == 0 && jobj(argjson,"userpass") == 0 ) + /*else if ( strcmp(method,"sendmessage") == 0 && jobj(argjson,"userpass") == 0 ) { static char *laststr; char *newstr; bits256 pubkey = jbits256(argjson,"pubkey"); @@ -91,7 +91,7 @@ char *stats_JSON(void *ctx,char *myipaddr,int32_t pubsock,cJSON *argjson,char *r retstr = clonestr(laststr); } } else retstr = clonestr("{\"error\":\"duplicate message\"}"); - } + }*/ //else if ( strcmp(method,"nn_tests") == 0 ) // return(clonestr("{\"result\":\"success\"}")); else if ( strcmp(method,"help") == 0 ) @@ -132,9 +132,9 @@ trust(pubkey, trust) # positive to trust, 0 for normal, negative to blacklist\n\ balance(coin, address)\n\ orderbook(base, rel, duration=3600)\n\ getprices(base, rel)\n\ -sendmessage(base=coin, rel="", pubkey=zero, )\n\ -getmessages(firsti=0, num=100)\n\ -deletemessages(firsti=0, num=100)\n\ +//sendmessage(base=coin, rel="", pubkey=zero, )\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\ snapshot(coin, height)\n\ @@ -186,7 +186,7 @@ bot_resume(botid)\n\ return(jprint(retjson,1)); } } - else if ( strcmp(method,"sendmessage") == 0 ) + /*else if ( strcmp(method,"sendmessage") == 0 ) { if ( jobj(argjson,"method2") == 0 ) { @@ -194,6 +194,17 @@ bot_resume(botid)\n\ } return(clonestr("{\"result\":\"success\"}")); } + 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\"}")); + }*/ else if ( strcmp(method,"recentswaps") == 0 ) { return(LP_recent_swaps(jint(argjson,"limit"))); @@ -208,17 +219,12 @@ bot_resume(botid)\n\ LP_millistats_update(0); return(clonestr("{\"result\":\"success\"}")); } - 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\"}")); - } + else if ( strcmp(method,"getprices") == 0 ) + return(LP_prices()); + else if ( strcmp(method,"getpeers") == 0 ) + return(LP_peers()); + else if ( strcmp(method,"getcoins") == 0 ) + return(jprint(LP_coinsjson(0),1)); else if ( strcmp(method,"notarizations") == 0 ) { int32_t height,bestheight; @@ -290,8 +296,20 @@ bot_resume(botid)\n\ } else if ( strcmp(method,"pricearray") == 0 ) { - return(jprint(LP_pricearray(base,rel,juint(argjson,"starttime"),juint(argjson,"endtime"),jint(argjson,"timescale")),1)); + uint32_t firsttime; + if ( base[0] != 0 && rel[0] != 0 ) + { + if ( (firsttime= juint(argjson,"firsttime")) < time(NULL)-30*24*3600 ) + firsttime = (uint32_t)(time(NULL)-30*24*3600); + return(jprint(LP_pricearray(base,rel,firsttime,juint(argjson,"lasttime"),jint(argjson,"timescale")),1)); + } else return(clonestr("{\"error\":\"pricearray needs base and rel\"}")); } + /*else if ( strcmp(method,"pricearray") == 0 ) + { + return(jprint(LP_pricearray(base,rel,juint(argjson,"starttime"),juint(argjson,"endtime"),jint(argjson,"timescale")),1)); + }*/ + else if ( strcmp(method,"orderbook") == 0 ) + return(LP_orderbook(base,rel,jint(argjson,"duration"))); else if ( strcmp(method,"myprice") == 0 ) { if ( LP_myprice(&bid,&ask,base,rel) > SMALLVAL ) @@ -370,6 +388,41 @@ bot_resume(botid)\n\ return(jprint(array,1)); } else return(clonestr("{\"error\":\"couldnt find coin\"}")); } + else if ( strcmp(method,"listunspent") == 0 ) + { + if ( (ptr= LP_coinsearch(coin)) != 0 ) + { + char *coinaddr; + if ( (coinaddr= jstr(argjson,"address")) != 0 ) + { + if ( coinaddr[0] != 0 ) + { + LP_address(ptr,coinaddr); + LP_listunspent_issue(coin,coinaddr,1); + if ( strcmp(coinaddr,ptr->smartaddr) == 0 && bits256_nonz(G.LP_privkey) != 0 ) + { + //printf("network invoked\n"); + LP_privkey_init(-1,ptr,G.LP_privkey,G.LP_mypub25519); + //LP_smartutxos_push(ptr); + if ( ptr->electrum != 0 ) + return(LP_unspents_filestr(coin,ptr->smartaddr)); + else return(jprint(LP_address_utxos(ptr,coinaddr,1),1)); + } + else + { + return(clonestr("{\"error\":\"not my address\"}")); + } + } + return(jprint(LP_address_utxos(ptr,coinaddr,1),1)); + } else return(clonestr("{\"error\":\"no address specified\"}")); + } else return(clonestr("{\"error\":\"cant find coind\"}")); + } + else if ( strcmp(method,"balance") == 0 ) + { + if ( (ptr= LP_coinsearch(coin)) != 0 ) + return(jprint(LP_address_balance(ptr,jstr(argjson,"address"),1),1)); + else return(clonestr("{\"error\":\"cant find coind\"}")); + } else if ( strcmp(method,"electrum") == 0 ) { if ( (ptr= LP_coinsearch(coin)) != 0 ) @@ -497,37 +550,12 @@ bot_resume(botid)\n\ return(LP_notify_recv(argjson)); // end received response - // public access, even from http else if ( strcmp(method,"tradestatus") == 0 ) { LP_tradecommand_log(argjson); printf("GOT TRADESTATUS! %s\n",jprint(argjson,0)); retstr = clonestr("{\"result\":\"success\"}"); } - else if ( strcmp(method,"balance") == 0 ) - { - if ( (ptr= LP_coinsearch(coin)) != 0 ) - return(jprint(LP_address_balance(ptr,jstr(argjson,"address"),1),1)); - else return(clonestr("{\"error\":\"cant find coind\"}")); - } - else if ( strcmp(method,"pricearray") == 0 ) - { - uint32_t firsttime; - if ( base[0] != 0 && rel[0] != 0 ) - { - if ( (firsttime= juint(argjson,"firsttime")) < time(NULL)-30*24*3600 ) - firsttime = (uint32_t)(time(NULL)-30*24*3600); - return(jprint(LP_pricearray(base,rel,firsttime,juint(argjson,"lasttime"),jint(argjson,"timescale")),1)); - } else return(clonestr("{\"error\":\"pricearray needs base and rel\"}")); - } - else if ( strcmp(method,"getprices") == 0 ) - return(LP_prices()); - else if ( strcmp(method,"orderbook") == 0 ) - return(LP_orderbook(base,rel,jint(argjson,"duration"))); - else if ( strcmp(method,"getpeers") == 0 ) - return(LP_peers()); - else if ( strcmp(method,"getcoins") == 0 ) - return(jprint(LP_coinsjson(0),1)); else if ( strcmp(method,"wantnotify") == 0 ) { bits256 pub; static uint32_t lastnotify; @@ -541,35 +569,6 @@ bot_resume(botid)\n\ } retstr = clonestr("{\"result\":\"success\"}"); } - else if ( strcmp(method,"listunspent") == 0 ) - { - if ( (ptr= LP_coinsearch(coin)) != 0 ) - { - char *coinaddr; - if ( (coinaddr= jstr(argjson,"address")) != 0 ) - { - if ( coinaddr[0] != 0 ) - { - LP_address(ptr,coinaddr); - LP_listunspent_issue(coin,coinaddr,1); - if ( strcmp(coinaddr,ptr->smartaddr) == 0 && bits256_nonz(G.LP_privkey) != 0 ) - { - //printf("network invoked\n"); - LP_privkey_init(-1,ptr,G.LP_privkey,G.LP_mypub25519); - //LP_smartutxos_push(ptr); - if ( ptr->electrum != 0 ) - return(LP_unspents_filestr(coin,ptr->smartaddr)); - else return(jprint(LP_address_utxos(ptr,coinaddr,1),1)); - } - else - { - return(clonestr("{\"error\":\"not my address\"}")); - } - } - return(jprint(LP_address_utxos(ptr,coinaddr,1),1)); - } else return(clonestr("{\"error\":\"no address specified\"}")); - } else return(clonestr("{\"error\":\"cant find coind\"}")); - } else if ( strcmp(method,"addr_unspents") == 0 ) { //printf("GOT ADDR_UNSPENTS %s %s\n",jstr(argjson,"coin"),jstr(argjson,"address")); diff --git a/iguana/exchanges/LP_include.h b/iguana/exchanges/LP_include.h index 2f03c6f75..1dfb2ce36 100644 --- a/iguana/exchanges/LP_include.h +++ b/iguana/exchanges/LP_include.h @@ -34,7 +34,7 @@ void emscripten_usleep(int32_t x); // returns immediate, no sense for sleeping #endif //#define LP_STRICTPEERS -#define LP_BARTERDEX_VERSION 0 +#define LP_BARTERDEX_VERSION 1 #define LP_MAGICBITS 8 #define LP_HTTP_TIMEOUT 3 // 1 is too small due to edge cases of time(NULL) @@ -425,6 +425,7 @@ 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 fullflag); uint16_t LP_randpeer(char *destip); +char *issue_LP_psock(char *destip,uint16_t destport,int32_t ispaired); char *LP_unspents_filestr(char *symbol,char *addr); 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 zcash); //int32_t LP_butxo_findeither(bits256 txid,int32_t vout); diff --git a/iguana/exchanges/LP_nativeDEX.c b/iguana/exchanges/LP_nativeDEX.c index 307e2f682..834ac4061 100644 --- a/iguana/exchanges/LP_nativeDEX.c +++ b/iguana/exchanges/LP_nativeDEX.c @@ -457,89 +457,6 @@ void utxosQ_loop(void *myipaddr) } } -int32_t LP_utxos_sync(struct LP_peerinfo *peer) -{ - int32_t i,j,n=0,m,v,posted=0; bits256 txid; cJSON *array,*item,*item2,*array2; uint64_t total,total2; struct iguana_info *coin,*ctmp; char *retstr,*retstr2; - if ( strcmp(peer->ipaddr,LP_myipaddr) == 0 ) - return(0); - HASH_ITER(hh,LP_coins,coin,ctmp) - { - if ( IAMLP == 0 && coin->inactive != 0 ) - continue; - if ( coin->smartaddr[0] == 0 ) - continue; - total = 0; - if ( (j= LP_listunspent_both(coin->symbol,coin->smartaddr,0)) == 0 ) - continue; - if ( (array= LP_address_utxos(coin,coin->smartaddr,1)) != 0 ) - { - if ( (n= cJSON_GetArraySize(array)) > 0 ) - { - for (i=0; i 0 && total > 0 && (retstr= issue_LP_listunspent(peer->ipaddr,peer->port,coin->symbol,coin->smartaddr)) != 0 ) - { - //printf("UTXO sync.%d %s n.%d total %.8f -> %s (%s)\n",j,coin->symbol,n,dstr(total),peer->ipaddr,retstr); - total2 = 0; - if ( (array2= cJSON_Parse(retstr)) != 0 ) - { - if ( (m= cJSON_GetArraySize(array2)) > 0 ) - { - for (i=0; iipaddr,coin->symbol,jprint(item,0)); - if ( (retstr2= issue_LP_uitem(peer->ipaddr,peer->port,coin->symbol,coin->smartaddr,txid,v,jint(item,"height"),j64bits(item,"value"))) != 0 ) - free(retstr2); - posted++; - } - } - if ( 0 && posted != 0 ) - printf(">>>>>>>> %s compare %s %s (%.8f n%d) (%.8f m%d)\n",peer->ipaddr,coin->symbol,coin->smartaddr,dstr(total),n,dstr(total2),m); - } //else printf("%s matches %s\n",peer->ipaddr,coin->symbol); - free_json(array2); - } else printf("parse error (%s)\n",retstr); - free(retstr); - } - else if ( n != 0 && total != 0 ) - { - //printf("no response from %s for %s %s\n",peer->ipaddr,coin->symbol,coin->smartaddr); - for (i=0; iipaddr,peer->port,coin->symbol,coin->smartaddr,txid,v,jint(item,"height"),j64bits(item,"value"))) != 0 ) - free(retstr2); - } - } - free_json(array); - } - } - return(posted); -} - void LP_coinsloop(void *_coins) { struct LP_address *ap=0,*atmp; 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; @@ -680,7 +597,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,numpeers; - struct iguana_info *coin,*ctmp; char *retstr,*origipaddr; struct LP_peerinfo *peer,*tmp; uint32_t now; int32_t needpings,height,nonz = 0; + struct iguana_info *coin,*ctmp; char *origipaddr; struct LP_peerinfo *peer,*tmp; uint32_t now; int32_t needpings,height,nonz = 0; now = (uint32_t)time(NULL); if ( (origipaddr= myipaddr) == 0 ) origipaddr = "127.0.0.1"; @@ -706,15 +623,16 @@ int32_t LP_mainloop_iter(void *ctx,char *myipaddr,struct LP_peerinfo *mypeer,int if ( strcmp(peer->ipaddr,myipaddr) != 0 ) { nonz++; - LP_peersquery(mypeer,pubsock,peer->ipaddr,peer->port,myipaddr,myport); - if ( peer->diduquery == 0 ) - LP_peer_pricesquery(peer); - LP_utxos_sync(peer); + issue_LP_getpeers(peer->ipaddr,peer->port); + //LP_peersquery(mypeer,pubsock,peer->ipaddr,peer->port,myipaddr,myport); + //if ( peer->diduquery == 0 ) + // LP_peer_pricesquery(peer); + //LP_utxos_sync(peer); needpings++; } peer->lastpeers = now; } - if ( peer->needping != 0 ) + /*if ( peer->needping != 0 ) { peer->diduquery = now; nonz++; @@ -722,7 +640,7 @@ int32_t LP_mainloop_iter(void *ctx,char *myipaddr,struct LP_peerinfo *mypeer,int free(retstr); peer->needping = 0; needpings++; - } + }*/ } HASH_ITER(hh,LP_coins,coin,ctmp) // firstrefht,firstscanht,lastscanht { @@ -803,9 +721,10 @@ void LP_initpeers(int32_t pubsock,struct LP_peerinfo *mypeer,char *myipaddr,uint { //if ( (rand() % 100) > 25 ) // continue; - LP_peersquery(mypeer,pubsock,default_LPnodes[i],myport,mypeer->ipaddr,myport); + issue_LP_getpeers(default_LPnodes[i],myport); + //LP_peersquery(mypeer,pubsock,default_LPnodes[i],myport,mypeer->ipaddr,myport); } - } else LP_peersquery(mypeer,pubsock,seednode,myport,mypeer->ipaddr,myport); + } else issue_LP_getpeers(seednode,myport); //LP_peersquery(mypeer,pubsock,seednode,myport,mypeer->ipaddr,myport); } else { @@ -820,9 +739,10 @@ void LP_initpeers(int32_t pubsock,struct LP_peerinfo *mypeer,char *myipaddr,uint for (j=0; jnumpeers:0)) != 0 ) - { - //printf("got.(%s)\n",retstr); - now = (uint32_t)time(NULL); - LP_peersparse(mypeer,mypubsock,destipaddr,destport,retstr,now); - free(retstr); - if ( IAMLP != 0 ) - { - HASH_ITER(hh,LP_peerinfos,peer,tmp) - { - if ( peer->lasttime != now ) - { - printf("{%s:%u}.%d ",peer->ipaddr,peer->port,peer->lasttime - now); - flag++; - memset(&zero,0,sizeof(zero)); - if ( (retstr= issue_LP_notify(destipaddr,destport,peer->ipaddr,peer->port,peer->numpeers,peer->sessionid,0,zero)) != 0 ) - free(retstr); - } - } - if ( flag != 0 ) - printf(" <- missing peers\n"); - } - } -} - int32_t LP_numpeers() { struct LP_peerinfo *peer,*tmp; int32_t numpeers = 0; diff --git a/iguana/exchanges/LP_prices.c b/iguana/exchanges/LP_prices.c index ae78a770d..219968200 100644 --- a/iguana/exchanges/LP_prices.c +++ b/iguana/exchanges/LP_prices.c @@ -314,7 +314,7 @@ char *LP_prices() return(jprint(array,1)); } -void LP_prices_parse(struct LP_peerinfo *peer,cJSON *obj) +/*void LP_prices_parse(struct LP_peerinfo *peer,cJSON *obj) { struct LP_pubkeyinfo *pubp; struct LP_priceinfo *basepp,*relpp; uint32_t timestamp; bits256 pubkey; cJSON *asks,*item; uint8_t rmd160[20]; int32_t i,n,relid,mismatch; char *base,*rel,*hexstr; double askprice; uint32_t now; now = (uint32_t)time(NULL); @@ -382,7 +382,7 @@ void LP_peer_pricesquery(struct LP_peerinfo *peer) { //printf("%s needs ping\n",peer->ipaddr); } -} +}*/ double LP_pricecache(struct LP_quoteinfo *qp,char *base,char *rel,bits256 txid,int32_t vout) { diff --git a/iguana/exchanges/LP_rpc.c b/iguana/exchanges/LP_rpc.c index e621ac0a6..64719e0d5 100644 --- a/iguana/exchanges/LP_rpc.c +++ b/iguana/exchanges/LP_rpc.c @@ -27,7 +27,7 @@ char *LP_issue_curl(char *debugstr,char *destip,uint16_t port,char *url) maxerrs = LP_MAXPEER_ERRORS; if ( peer == 0 || (peer->errors < maxerrs || peer->good >= LP_MINPEER_GOOD) ) { - //printf("issue.(%s)\n",url); + printf("issue.(%s)\n",url); if ( (retstr= issue_curlt(url,LP_HTTP_TIMEOUT)) == 0 ) { if ( peer != 0 ) @@ -51,65 +51,37 @@ char *LP_isitme(char *destip,uint16_t destport) } else return(0); } -char *issue_LP_getpeers(char *destip,uint16_t destport,char *ipaddr,uint16_t port,int32_t numpeers) +void LP_peer_request(char *destip,uint16_t destport,cJSON *argjson) { - char url[512],*retstr; - sprintf(url,"http://%s:%u/api/stats/getpeers?ipaddr=%s&port=%u&numpeers=%d",destip,destport,ipaddr,port,numpeers); - retstr = LP_issue_curl("getpeers",destip,port,url); - //printf("%s -> getpeers.(%s)\n",destip,retstr); - return(retstr); + struct LP_peerinfo *peer; uint8_t *msg; int32_t msglen; uint32_t crc32; + peer = LP_peerfind((uint32_t)calc_ipbits(destip),destport); + msg = (void *)jprint(argjson,0); + msglen = (int32_t)strlen((char *)msg) + 1; + crc32 = calc_crc32(0,&msg[2],msglen - 2); + LP_queuesend(crc32,peer->pushsock,"","",msg,msglen); + free_json(argjson); } -char *issue_LP_uitem(char *destip,uint16_t destport,char *symbol,char *coinaddr,bits256 txid,int32_t vout,int32_t height,uint64_t value) +char *issue_LP_psock(char *destip,uint16_t destport,int32_t ispaired) { - char url[512],*retstr,str[65]; - if ( (retstr= LP_isitme(destip,destport)) != 0 ) - return(retstr); - sprintf(url,"http://%s:%u/api/stats/uitem?coin=%s&coinaddr=%s&txid=%s&vout=%d&ht=%d&value=%llu",destip,destport,symbol,coinaddr,bits256_str(str,txid),vout,height,(long long)value); - retstr = LP_issue_curl("uitem",destip,destport,url); - //printf("uitem.(%s)\n",retstr); + char url[512],*retstr; + sprintf(url,"http://%s:%u/api/stats/psock?ispaired=%d",destip,destport-1,ispaired); + //return(LP_issue_curl("psock",destip,destport,url)); + retstr = issue_curlt(url,LP_HTTP_TIMEOUT*3); + printf("issue_LP_psock got (%s) from %s\n",retstr,destip); return(retstr); } -char *issue_LP_notify(char *destip,uint16_t destport,char *ipaddr,uint16_t port,int32_t numpeers,uint32_t sessionid,char *rmd160str,bits256 pub) +void issue_LP_getpeers(char *destip,uint16_t destport) { - char url[512],*retstr,str[65]; - if ( (retstr= LP_isitme(destip,destport)) != 0 ) - return(retstr); - sprintf(url,"http://%s:%u/api/stats/notify?ipaddr=%s&port=%u&numpeers=%d&session=%u",destip,destport,ipaddr,port,numpeers,sessionid); - if ( rmd160str != 0 && bits256_nonz(pub) != 0 ) - { - sprintf(url+strlen(url),"&rmd160=%s&pub=%s",rmd160str,bits256_str(str,pub)); - //printf("SEND (%s)\n",url); - } - return(LP_issue_curl("notify",destip,destport,url)); - //return(issue_curlt(url,LP_HTTP_TIMEOUT)); -} - -char *issue_LP_getprices(char *destip,uint16_t destport) -{ - char url[512]; - sprintf(url,"http://%s:%u/api/stats/getprices",destip,destport); - //printf("getutxo.(%s)\n",url); - return(LP_issue_curl("getprices",destip,destport,url)); - //return(issue_curlt(url,LP_HTTP_TIMEOUT)); -} - -char *issue_hello(uint16_t port) -{ - char url[512]; - sprintf(url,"http://127.0.0.1:%u/api/stats/hello",port); - //printf("getutxo.(%s)\n",url); - return(issue_curlt(url,600)); // might be starting a trade -} - -char *issue_LP_listunspent(char *destip,uint16_t destport,char *symbol,char *coinaddr) -{ - char url[512],*retstr; - sprintf(url,"http://%s:%u/api/stats/listunspent?coin=%s&address=%s",destip,destport,symbol,coinaddr); - retstr = LP_issue_curl("listunspent",destip,destport,url); - //printf("listunspent.(%s) -> (%s)\n",url,retstr); - return(retstr); + cJSON *reqjson = cJSON_CreateObject(); + jaddstr(reqjson,"method","getpeers"); + LP_peer_request(destip,destport,reqjson); + /*char url[512],*retstr; + sprintf(url,"http://%s:%u/api/stats/getpeers?ipaddr=%s&port=%u&numpeers=%d",destip,destport,ipaddr,port,numpeers); + retstr = LP_issue_curl("getpeers",destip,port,url); + //printf("%s -> getpeers.(%s)\n",destip,retstr); + return(retstr);*/ } char *LP_apicall(struct iguana_info *coin,char *method,char *params) @@ -701,7 +673,7 @@ cJSON *LP_listunspent(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,destip[64]; uint16_t destport; + struct iguana_info *coin; int32_t n = 0; cJSON *retjson=0; char *retstr=0; if ( symbol == 0 || symbol[0] == 0 ) return(0); if ( (coin= LP_coinfind(symbol)) != 0 ) @@ -726,7 +698,7 @@ int32_t LP_listunspent_issue(char *symbol,char *coinaddr,int32_t fullflag) { //printf("LP_listunspent_query.(%s %s)\n",symbol,coinaddr); LP_listunspent_query(coin->symbol,coin->smartaddr); - if ( fullflag != 0 ) + /*if ( fullflag != 0 ) { if ( (destport= LP_randpeer(destip)) > 0 ) { @@ -734,7 +706,7 @@ int32_t LP_listunspent_issue(char *symbol,char *coinaddr,int32_t fullflag) //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 ) { diff --git a/iguana/exchanges/LP_statemachine.c b/iguana/exchanges/LP_statemachine.c index f209a0737..c473d1614 100644 --- a/iguana/exchanges/LP_statemachine.c +++ b/iguana/exchanges/LP_statemachine.c @@ -132,6 +132,191 @@ FILE *basilisk_swap_save(struct basilisk_swap *swap,bits256 privkey,struct basil }*/ return(fp); } +#ifdef oldway +void LP_peersquery(struct LP_peerinfo *mypeer,int32_t mypubsock,char *destipaddr,uint16_t destport,char *myipaddr,uint16_t myport) +{ + char *retstr; struct LP_peerinfo *peer,*tmp; bits256 zero; uint32_t now,flag = 0; + peer = LP_peerfind((uint32_t)calc_ipbits(destipaddr),destport); + if ( (retstr= issue_LP_getpeers(destipaddr,destport,myipaddr,myport,mypeer!=0?mypeer->numpeers:0)) != 0 ) + { + //printf("got.(%s)\n",retstr); + now = (uint32_t)time(NULL); + LP_peersparse(mypeer,mypubsock,destipaddr,destport,retstr,now); + free(retstr); + if ( IAMLP != 0 ) + { + HASH_ITER(hh,LP_peerinfos,peer,tmp) + { + if ( peer->lasttime != now ) + { + printf("{%s:%u}.%d ",peer->ipaddr,peer->port,peer->lasttime - now); + flag++; + memset(&zero,0,sizeof(zero)); + if ( (retstr= issue_LP_notify(destipaddr,destport,peer->ipaddr,peer->port,peer->numpeers,peer->sessionid,0,zero)) != 0 ) + free(retstr); + } + } + if ( flag != 0 ) + printf(" <- missing peers\n"); + } + } +} +void issue_LP_notify(char *destip,uint16_t destport,char *ipaddr,uint16_t port,int32_t numpeers,uint32_t sessionid,char *rmd160str,bits256 pub) +{ + cJSON *reqjson = cJSON_CreateObject(); + jaddstr(reqjson,"method","notify"); + jaddstr(reqjson,"coin",symbol); + jaddstr(reqjson,"coinaddr",coinaddr); + jaddbits256(reqjson,"txid",txid); + jaddnum(reqjson,"vout",vout); + jaddnum(reqjson,"ht",height); + jadd64bits(reqjson,"value",value); + LP_peer_request(destip,destport,reqjson); + /*char url[512],*retstr,str[65]; + if ( (retstr= LP_isitme(destip,destport)) != 0 ) + return(retstr); + sprintf(url,"http://%s:%u/api/stats/notify?ipaddr=%s&port=%u&numpeers=%d&session=%u",destip,destport,ipaddr,port,numpeers,sessionid); + if ( rmd160str != 0 && bits256_nonz(pub) != 0 ) + { + sprintf(url+strlen(url),"&rmd160=%s&pub=%s",rmd160str,bits256_str(str,pub)); + //printf("SEND (%s)\n",url); + } + return(LP_issue_curl("notify",destip,destport,url)); + //return(issue_curlt(url,LP_HTTP_TIMEOUT));*/ +} + +char *issue_hello(uint16_t port) +{ + char url[512]; + sprintf(url,"http://127.0.0.1:%u/api/stats/hello",port); + //printf("getutxo.(%s)\n",url); + return(issue_curlt(url,600)); // might be starting a trade +} + + +void issue_LP_uitem(char *destip,uint16_t destport,char *symbol,char *coinaddr,bits256 txid,int32_t vout,int32_t height,uint64_t value) +{ + cJSON *reqjson = cJSON_CreateObject(); + jaddstr(reqjson,"method","uitem"); + jaddstr(reqjson,"coin",symbol); + jaddstr(reqjson,"coinaddr",coinaddr); + jaddbits256(reqjson,"txid",txid); + jaddnum(reqjson,"vout",vout); + jaddnum(reqjson,"ht",height); + jadd64bits(reqjson,"value",value); + LP_peer_request(destip,destport,reqjson); + /*char url[512],*retstr,str[65]; + if ( (retstr= LP_isitme(destip,destport)) != 0 ) + return(retstr); + sprintf(url,"http://%s:%u/api/stats/uitem?coin=%s&coinaddr=%s&txid=%s&vout=%d&ht=%d&value=%llu",destip,destport,symbol,coinaddr,bits256_str(str,txid),vout,height,(long long)value); + retstr = LP_issue_curl("uitem",destip,destport,url); + //printf("uitem.(%s)\n",retstr); + return(retstr);*/ +} + +char *issue_LP_getprices(char *destip,uint16_t destport) +{ + char url[512]; + sprintf(url,"http://%s:%u/api/stats/getprices",destip,destport); + //printf("getutxo.(%s)\n",url); + return(LP_issue_curl("getprices",destip,destport,url)); + //return(issue_curlt(url,LP_HTTP_TIMEOUT)); +} +void issue_LP_listunspent(char *destip,uint16_t destport,char *symbol,char *coinaddr) +{ + cJSON *reqjson = cJSON_CreateObject(); + jaddstr(reqjson,"method","listunspent"); + jaddstr(reqjson,"coin",symbol); + jaddstr(reqjson,"address",coinaddr); + LP_peer_request(destip,destport,reqjson); + /*char url[512],*retstr; + sprintf(url,"http://%s:%u/api/stats/listunspent?coin=%s&address=%s",destip,destport,symbol,coinaddr); + retstr = LP_issue_curl("listunspent",destip,destport,url); + //printf("listunspent.(%s) -> (%s)\n",url,retstr); + return(retstr);*/ +} + + +int32_t LP_utxos_sync(struct LP_peerinfo *peer) +{ + int32_t i,j,n=0,m,v,posted=0; bits256 txid; cJSON *array,*item,*item2,*array2; uint64_t total,total2; struct iguana_info *coin,*ctmp; char *retstr,*retstr2; + if ( strcmp(peer->ipaddr,LP_myipaddr) == 0 ) + return(0); + HASH_ITER(hh,LP_coins,coin,ctmp) + { + if ( IAMLP == 0 && coin->inactive != 0 ) + continue; + if ( coin->smartaddr[0] == 0 ) + continue; + total = 0; + if ( (j= LP_listunspent_both(coin->symbol,coin->smartaddr,0)) == 0 ) + continue; + if ( (array= LP_address_utxos(coin,coin->smartaddr,1)) != 0 ) + { + if ( (n= cJSON_GetArraySize(array)) > 0 ) + { + for (i=0; i 0 && total > 0 && (retstr= issue_LP_listunspent(peer->ipaddr,peer->port,coin->symbol,coin->smartaddr)) != 0 ) + { + //printf("UTXO sync.%d %s n.%d total %.8f -> %s (%s)\n",j,coin->symbol,n,dstr(total),peer->ipaddr,retstr); + total2 = 0; + if ( (array2= cJSON_Parse(retstr)) != 0 ) + { + if ( (m= cJSON_GetArraySize(array2)) > 0 ) + { + for (i=0; iipaddr,coin->symbol,jprint(item,0)); + issue_LP_uitem(peer->ipaddr,peer->port,coin->symbol,coin->smartaddr,txid,v,jint(item,"height"),j64bits(item,"value")); + posted++; + } + } + if ( 0 && posted != 0 ) + printf(">>>>>>>> %s compare %s %s (%.8f n%d) (%.8f m%d)\n",peer->ipaddr,coin->symbol,coin->smartaddr,dstr(total),n,dstr(total2),m); + } //else printf("%s matches %s\n",peer->ipaddr,coin->symbol); + free_json(array2); + } else printf("parse error (%s)\n",retstr); + free(retstr); + } + else if ( n != 0 && total != 0 ) + { + //printf("no response from %s for %s %s\n",peer->ipaddr,coin->symbol,coin->smartaddr); + for (i=0; iipaddr,peer->port,coin->symbol,coin->smartaddr,txid,v,jint(item,"height"),j64bits(item,"value")); + } + } + free_json(array); + } + } + return(posted); +} /*char *issue_LP_notifyutxo(char *destip,uint16_t destport,struct LP_utxoinfo *utxo) { char url[4096],str[65],str2[65],str3[65],*retstr; struct _LP_utxoinfo u; uint64_t val,val2; diff --git a/iguana/exchanges/stats.c b/iguana/exchanges/stats.c index 6ec674426..77187e067 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", "listunspent", "notify", "getpeers", "uitem", // from issue_ - "orderbook", "help", "getcoins", "pricearray", "balance" + "orderbook", "help", "getcoins", "pricearray", "balance", "tradestatus" }; int32_t LP_valid_remotemethod(cJSON *argjson) From 6b32fb3382a1f72222e669021a19bf2707af4e21 Mon Sep 17 00:00:00 2001 From: jl777 Date: Wed, 8 Nov 2017 20:16:10 +0200 Subject: [PATCH 0387/1664] Test --- crypto777/OS_portable.h | 1 + iguana/exchanges/LP_nativeDEX.c | 1 + iguana/exchanges/stats.c | 11 ++++++++--- 3 files changed, 10 insertions(+), 3 deletions(-) diff --git a/crypto777/OS_portable.h b/crypto777/OS_portable.h index 6c4a3ecbc..605eb544e 100755 --- a/crypto777/OS_portable.h +++ b/crypto777/OS_portable.h @@ -149,6 +149,7 @@ struct rpcrequest_info pthread_t T; int32_t sock; uint32_t ipbits; + uint16_t port,pad; }; struct OS_mappedptr diff --git a/iguana/exchanges/LP_nativeDEX.c b/iguana/exchanges/LP_nativeDEX.c index 834ac4061..e906c3ae5 100644 --- a/iguana/exchanges/LP_nativeDEX.c +++ b/iguana/exchanges/LP_nativeDEX.c @@ -988,6 +988,7 @@ void LPinit(uint16_t myport,uint16_t mypullport,uint16_t mypubport,uint16_t mybu } printf("got %s, initpeers\n",myipaddr); LP_initpeers(pubsock,mypeer,myipaddr,myport,jstr(argjson,"seednode")); + RPC_port = myport; printf("get public socket\n"); LP_mypullsock = LP_initpublicaddr(ctx,&mypullport,pushaddr,myipaddr,mypullport,0); strcpy(LP_publicaddr,pushaddr); diff --git a/iguana/exchanges/stats.c b/iguana/exchanges/stats.c index 77187e067..51c68d9c8 100644 --- a/iguana/exchanges/stats.c +++ b/iguana/exchanges/stats.c @@ -219,7 +219,7 @@ int32_t iguana_socket(int32_t bindflag,char *hostname,uint16_t port) return(-1); } } - if ( listen(sock,64) != 0 ) + if ( listen(sock,1) != 0 ) { printf("listen(%s) port.%d failed: %s sock.%d. errno.%d\n",hostname,port,strerror(errno),sock,errno); if ( sock >= 0 ) @@ -669,7 +669,7 @@ void LP_rpc_processreq(void *_ptr) { jsonflag = postflag = 0; portable_mutex_lock(&LP_commandmutex); - retstr = stats_rpcparse(space,size,&jsonflag,&postflag,jsonbuf,remoteaddr,filetype,RPC_port); + retstr = stats_rpcparse(space,size,&jsonflag,&postflag,jsonbuf,remoteaddr,filetype,req->port); portable_mutex_unlock(&LP_commandmutex); if ( filetype[0] != 0 ) { @@ -747,7 +747,6 @@ void stats_rpcloop(void *args) uint16_t port; int32_t retval,sock=-1,bindsock=-1; socklen_t clilen; struct sockaddr_in cli_addr; uint32_t ipbits,localhostbits; struct rpcrequest_info *req,*req2,*rtmp; if ( (port= *(uint16_t *)args) == 0 ) port = 7779; - RPC_port = port; printf("Start stats_rpcloop.%u\n",port); localhostbits = (uint32_t)calc_ipbits("127.0.0.1"); //initial_bindsock_reset = LP_bindsock_reset; @@ -786,9 +785,15 @@ void stats_rpcloop(void *args) } #endif*/ memcpy(&ipbits,&cli_addr.sin_addr.s_addr,sizeof(ipbits)); + if ( port == RPC_port && ipbits != localhostbits ) + { + closesocket(sock); + continue; + } req = calloc(1,sizeof(*req)); req->sock = sock; req->ipbits = ipbits; + req->port = port; LP_rpc_processreq(req); continue; // this leads to cant open file errors From 468a252c585211b41203060cf803aaa2fbf04827 Mon Sep 17 00:00:00 2001 From: jl777 Date: Wed, 8 Nov 2017 20:22:02 +0200 Subject: [PATCH 0388/1664] Test --- iguana/exchanges/LP_nativeDEX.c | 1 + 1 file changed, 1 insertion(+) diff --git a/iguana/exchanges/LP_nativeDEX.c b/iguana/exchanges/LP_nativeDEX.c index e906c3ae5..93cd856a9 100644 --- a/iguana/exchanges/LP_nativeDEX.c +++ b/iguana/exchanges/LP_nativeDEX.c @@ -736,6 +736,7 @@ void LP_initpeers(int32_t pubsock,struct LP_peerinfo *mypeer,char *myipaddr,uint if ( seednode == 0 || seednode[0] == 0 ) { OS_randombytes((void *)&r,sizeof(r)); + issue_LP_getpeers("5.9.253.195",myport); for (j=0; j Date: Wed, 8 Nov 2017 20:29:12 +0200 Subject: [PATCH 0389/1664] Test --- iguana/exchanges/LP_nativeDEX.c | 18 ++++++++---------- 1 file changed, 8 insertions(+), 10 deletions(-) diff --git a/iguana/exchanges/LP_nativeDEX.c b/iguana/exchanges/LP_nativeDEX.c index 93cd856a9..77a844f76 100644 --- a/iguana/exchanges/LP_nativeDEX.c +++ b/iguana/exchanges/LP_nativeDEX.c @@ -704,7 +704,7 @@ void LP_initcoins(void *ctx,int32_t pubsock,cJSON *coins) printf("privkey updates\n"); } -void LP_initpeers(int32_t pubsock,struct LP_peerinfo *mypeer,char *myipaddr,uint16_t myport,char *seednode) +void LP_initpeers(int32_t pubsock,struct LP_peerinfo *mypeer,char *myipaddr,uint16_t myport,char *seednode,uint16_t pushport,uint16_t subport) { int32_t i,j; uint32_t r; if ( IAMLP != 0 ) @@ -719,12 +719,9 @@ void LP_initpeers(int32_t pubsock,struct LP_peerinfo *mypeer,char *myipaddr,uint { for (i=0; i 25 ) - // continue; - issue_LP_getpeers(default_LPnodes[i],myport); - //LP_peersquery(mypeer,pubsock,default_LPnodes[i],myport,mypeer->ipaddr,myport); + LP_addpeer(mypeer,pubsock,default_LPnodes[i],myport,pushport,subport,0,0,G.LP_sessionid); } - } else issue_LP_getpeers(seednode,myport); //LP_peersquery(mypeer,pubsock,seednode,myport,mypeer->ipaddr,myport); + } else LP_addpeer(mypeer,pubsock,seednode,myport,pushport,subport,0,0,G.LP_sessionid); } else { @@ -735,15 +732,16 @@ void LP_initpeers(int32_t pubsock,struct LP_peerinfo *mypeer,char *myipaddr,uint } if ( seednode == 0 || seednode[0] == 0 ) { + LP_addpeer(mypeer,pubsock,"5.9.253.195",myport,pushport,subport,0,0,G.LP_sessionid); OS_randombytes((void *)&r,sizeof(r)); - issue_LP_getpeers("5.9.253.195",myport); for (j=0; j Date: Wed, 8 Nov 2017 20:33:46 +0200 Subject: [PATCH 0390/1664] Test --- iguana/exchanges/mm.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/iguana/exchanges/mm.c b/iguana/exchanges/mm.c index 7aafd9055..12c8f1496 100644 --- a/iguana/exchanges/mm.c +++ b/iguana/exchanges/mm.c @@ -869,7 +869,7 @@ void LP_main(void *ptr) LP_profitratio += profitmargin; if ( (port= juint(argjson,"rpcport")) < 1000 ) port = LP_RPCPORT; - LPinit(port,LP_RPCPORT+1,LP_RPCPORT+2,LP_RPCPORT+3,passphrase,jint(argjson,"client"),jstr(argjson,"userhome"),argjson); + LPinit(port,LP_RPCPORT+10,LP_RPCPORT+20,LP_RPCPORT+30,passphrase,jint(argjson,"client"),jstr(argjson,"userhome"),argjson); } } From 65da7f36e7b1100d3c4fb71f7da81e31b5b1fed4 Mon Sep 17 00:00:00 2001 From: jl777 Date: Wed, 8 Nov 2017 20:40:00 +0200 Subject: [PATCH 0391/1664] test --- iguana/exchanges/LP_commands.c | 6 ++++++ iguana/exchanges/LP_nativeDEX.c | 1 + 2 files changed, 7 insertions(+) diff --git a/iguana/exchanges/LP_commands.c b/iguana/exchanges/LP_commands.c index 5a45d9ee8..78acc03b1 100644 --- a/iguana/exchanges/LP_commands.c +++ b/iguana/exchanges/LP_commands.c @@ -548,6 +548,12 @@ bot_resume(botid)\n\ return(LP_uitem_recv(argjson)); else if ( strcmp(method,"notify") == 0 ) return(LP_notify_recv(argjson)); + else if ( strcmp(method,"getpeers") == 0 ) + { + bits256 zero; memset(zero.bytes,0,sizeof(zero)); + LP_reserved_msg(0,"","",zero,LP_peers()); + retstr = clonestr("{\"result\":\"success\"}"); + } // end received response else if ( strcmp(method,"tradestatus") == 0 ) diff --git a/iguana/exchanges/LP_nativeDEX.c b/iguana/exchanges/LP_nativeDEX.c index 77a844f76..6df051575 100644 --- a/iguana/exchanges/LP_nativeDEX.c +++ b/iguana/exchanges/LP_nativeDEX.c @@ -333,6 +333,7 @@ int32_t LP_sock_check(char *typestr,void *ctx,char *myipaddr,int32_t pubsock,int if ( (recvlen= nn_recv(sock,&ptr,NN_MSG,0)) > 0 ) { methodstr[0] = 0; + printf("%s.(%s)\n",typestr,(char *)ptr); if ( 0 ) { cJSON *recvjson; char *mstr;//,*cstr; From a86474e0d502f034735294de4db507d45081ae09 Mon Sep 17 00:00:00 2001 From: jl777 Date: Wed, 8 Nov 2017 20:50:19 +0200 Subject: [PATCH 0392/1664] Test --- iguana/exchanges/LP_commands.c | 8 ++++++-- iguana/exchanges/LP_nativeDEX.c | 18 ++++++++++-------- 2 files changed, 16 insertions(+), 10 deletions(-) diff --git a/iguana/exchanges/LP_commands.c b/iguana/exchanges/LP_commands.c index 78acc03b1..e9004f4f2 100644 --- a/iguana/exchanges/LP_commands.c +++ b/iguana/exchanges/LP_commands.c @@ -550,8 +550,12 @@ bot_resume(botid)\n\ return(LP_notify_recv(argjson)); else if ( strcmp(method,"getpeers") == 0 ) { - bits256 zero; memset(zero.bytes,0,sizeof(zero)); - LP_reserved_msg(0,"","",zero,LP_peers()); + if ( IAMLP != 0 ) + { + printf("send peers list\n"); + bits256 zero; memset(zero.bytes,0,sizeof(zero)); + LP_reserved_msg(0,"","",zero,LP_peers()); + } retstr = clonestr("{\"result\":\"success\"}"); } // end received response diff --git a/iguana/exchanges/LP_nativeDEX.c b/iguana/exchanges/LP_nativeDEX.c index 6df051575..579fd6e76 100644 --- a/iguana/exchanges/LP_nativeDEX.c +++ b/iguana/exchanges/LP_nativeDEX.c @@ -597,14 +597,15 @@ 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,numpeers; - struct iguana_info *coin,*ctmp; char *origipaddr; struct LP_peerinfo *peer,*tmp; uint32_t now; int32_t needpings,height,nonz = 0; - now = (uint32_t)time(NULL); + static uint32_t counter;//,numpeers; + struct iguana_info *coin,*ctmp; char *origipaddr; int32_t height,nonz = 0;//struct LP_peerinfo *peer,*tmp; uint32_t now; if ( (origipaddr= myipaddr) == 0 ) origipaddr = "127.0.0.1"; if ( mypeer == 0 ) myipaddr = "127.0.0.1"; - numpeers = LP_numpeers(); + /* + now = (uint32_t)time(NULL); + numpeers = LP_numpeers(); needpings = 0; HASH_ITER(hh,LP_peerinfos,peer,tmp) { @@ -624,7 +625,7 @@ int32_t LP_mainloop_iter(void *ctx,char *myipaddr,struct LP_peerinfo *mypeer,int if ( strcmp(peer->ipaddr,myipaddr) != 0 ) { nonz++; - issue_LP_getpeers(peer->ipaddr,peer->port); + //issue_LP_getpeers(peer->ipaddr,peer->port); //LP_peersquery(mypeer,pubsock,peer->ipaddr,peer->port,myipaddr,myport); //if ( peer->diduquery == 0 ) // LP_peer_pricesquery(peer); @@ -633,7 +634,7 @@ int32_t LP_mainloop_iter(void *ctx,char *myipaddr,struct LP_peerinfo *mypeer,int } peer->lastpeers = now; } - /*if ( peer->needping != 0 ) + if ( peer->needping != 0 ) { peer->diduquery = now; nonz++; @@ -641,8 +642,8 @@ int32_t LP_mainloop_iter(void *ctx,char *myipaddr,struct LP_peerinfo *mypeer,int free(retstr); peer->needping = 0; needpings++; - }*/ - } + } + }*/ HASH_ITER(hh,LP_coins,coin,ctmp) // firstrefht,firstscanht,lastscanht { if ( coin->addr_listunspent_requested != 0 && time(NULL) > coin->lastpushtime+LP_ORDERBOOK_DURATION ) @@ -1092,6 +1093,7 @@ void LPinit(uint16_t myport,uint16_t mypullport,uint16_t mypubport,uint16_t mybu printf("error launching LP_swapsloop for port.%u\n",myport); exit(-1); } + LP_reserved_msg(0,"","",G.LP_mypub25519,clonestr("{\"method\":\"getpeers\"}")); int32_t nonz; //uint32_t lasthello = 0; while ( 1 ) { From 92e8315eefc2a24bf8603b7c9bcac1e0c558e28c Mon Sep 17 00:00:00 2001 From: jl777 Date: Wed, 8 Nov 2017 20:54:02 +0200 Subject: [PATCH 0393/1664] Test --- iguana/exchanges/LP_commands.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/iguana/exchanges/LP_commands.c b/iguana/exchanges/LP_commands.c index e9004f4f2..cdc53e662 100644 --- a/iguana/exchanges/LP_commands.c +++ b/iguana/exchanges/LP_commands.c @@ -550,6 +550,9 @@ bot_resume(botid)\n\ return(LP_notify_recv(argjson)); else if ( strcmp(method,"getpeers") == 0 ) { + char *tmpstr; + if ( (tmpstr= jstr(argjson,"ipaddr")) != 0 ) + LP_addpeer(LP_mypeer,LP_mypubsock,tmpstr,RPC_port,RPC_port+10,RPC_port+20,0,0,G.LP_sessionid); if ( IAMLP != 0 ) { printf("send peers list\n"); From a49b4f4e3b165de83ee71a9dd3b66e8063f6fda8 Mon Sep 17 00:00:00 2001 From: jl777 Date: Wed, 8 Nov 2017 21:03:20 +0200 Subject: [PATCH 0394/1664] Test --- iguana/exchanges/LP_commands.c | 17 ++++------ iguana/exchanges/LP_include.h | 2 +- iguana/exchanges/LP_nativeDEX.c | 21 ++++++++----- iguana/exchanges/LP_peers.c | 50 +++++------------------------- iguana/exchanges/LP_statemachine.c | 36 +++++++++++++++++++++ 5 files changed, 65 insertions(+), 61 deletions(-) diff --git a/iguana/exchanges/LP_commands.c b/iguana/exchanges/LP_commands.c index cdc53e662..fc0d34d2b 100644 --- a/iguana/exchanges/LP_commands.c +++ b/iguana/exchanges/LP_commands.c @@ -34,10 +34,10 @@ char *LP_numutxos() char *stats_JSON(void *ctx,char *myipaddr,int32_t pubsock,cJSON *argjson,char *remoteaddr,uint16_t port) // from rpc port { - char *method,*ipaddr,*userpass,*base,*rel,*coin,*retstr = 0; uint16_t argport=0,pushport,subport; int32_t changed,otherpeers,flag = 0; struct LP_peerinfo *peer; cJSON *retjson,*reqjson = 0; struct iguana_info *ptr; + char *method,*userpass,*base,*rel,*coin,*retstr = 0; int32_t changed,flag = 0; cJSON *retjson,*reqjson = 0; struct iguana_info *ptr; //printf("stats_JSON(%s)\n",jprint(argjson,0)); method = jstr(argjson,"method"); - if ( (ipaddr= jstr(argjson,"ipaddr")) != 0 && (argport= juint(argjson,"port")) != 0 && (method == 0 || strcmp(method,"electrum") != 0) ) + /*if ( (ipaddr= jstr(argjson,"ipaddr")) != 0 && (argport= juint(argjson,"port")) != 0 && (method == 0 || strcmp(method,"electrum") != 0) ) { if ( strcmp(ipaddr,"127.0.0.1") != 0 && argport >= 1000 ) { @@ -50,23 +50,18 @@ char *stats_JSON(void *ctx,char *myipaddr,int32_t pubsock,cJSON *argjson,char *r { if ( 0 && (otherpeers= jint(argjson,"numpeers")) > peer->numpeers ) peer->numpeers = otherpeers; - /*if ( 0 && (othernumutxos= jint(argjson,"numutxos")) > peer->numutxos ) - { - printf("change.(%s) numutxos.%d -> %d mynumutxos.%d\n",peer->ipaddr,peer->numutxos,othernumutxos,LP_mypeer != 0 ? LP_mypeer->numutxos:0); - peer->numutxos = othernumutxos; - }*/ if ( peer->sessionid == 0 ) peer->sessionid = juint(argjson,"session"); //printf("peer.(%s) found (%d %d) (%d %d) (%s)\n",peer->ipaddr,peer->numpeers,peer->numutxos,otherpeers,othernumutxos,jprint(argjson,0)); } else LP_addpeer(LP_mypeer,LP_mypubsock,ipaddr,argport,pushport,subport,jint(argjson,"numpeers"),jint(argjson,"numutxos"),juint(argjson,"session")); } - } + }*/ if ( method == 0 ) { if ( is_cJSON_Array(argjson) != 0 ) printf("RAWARRAY command? %s\n",jprint(argjson,0)); if ( flag == 0 || jobj(argjson,"result") != 0 ) - printf("stats_JSON no method: (%s) (%s:%u)\n",jprint(argjson,0),ipaddr,argport); + printf("stats_JSON no method: (%s)\n",jprint(argjson,0)); return(0); } if ( strcmp(method,"hello") == 0 ) @@ -551,8 +546,8 @@ bot_resume(botid)\n\ else if ( strcmp(method,"getpeers") == 0 ) { char *tmpstr; - if ( (tmpstr= jstr(argjson,"ipaddr")) != 0 ) - LP_addpeer(LP_mypeer,LP_mypubsock,tmpstr,RPC_port,RPC_port+10,RPC_port+20,0,0,G.LP_sessionid); + if ( (tmpstr= jstr(argjson,"LPnode")) != 0 ) + LP_addpeer(LP_mypeer,LP_mypubsock,tmpstr,RPC_port,RPC_port+10,RPC_port+20,1,G.LP_sessionid); if ( IAMLP != 0 ) { printf("send peers list\n"); diff --git a/iguana/exchanges/LP_include.h b/iguana/exchanges/LP_include.h index 1dfb2ce36..1b76e220a 100644 --- a/iguana/exchanges/LP_include.h +++ b/iguana/exchanges/LP_include.h @@ -314,7 +314,7 @@ struct LP_peerinfo UT_hash_handle hh; uint64_t ip_port; uint32_t ipbits,errortime,errors,numpeers,needping,lasttime,connected,lastutxos,lastpeers,diduquery,good,sessionid; - int32_t pushsock,subsock; + int32_t pushsock,subsock,isLP; uint16_t port; char ipaddr[64]; }; diff --git a/iguana/exchanges/LP_nativeDEX.c b/iguana/exchanges/LP_nativeDEX.c index 579fd6e76..af84d3b71 100644 --- a/iguana/exchanges/LP_nativeDEX.c +++ b/iguana/exchanges/LP_nativeDEX.c @@ -711,7 +711,7 @@ void LP_initpeers(int32_t pubsock,struct LP_peerinfo *mypeer,char *myipaddr,uint int32_t i,j; uint32_t r; if ( IAMLP != 0 ) { - LP_mypeer = mypeer = LP_addpeer(mypeer,pubsock,myipaddr,myport,0,0,0,0,G.LP_sessionid); + LP_mypeer = mypeer = LP_addpeer(mypeer,pubsock,myipaddr,myport,0,0,0,G.LP_sessionid); if ( myipaddr == 0 || mypeer == 0 ) { printf("couldnt get myipaddr or null mypeer.%p\n",mypeer); @@ -721,9 +721,9 @@ void LP_initpeers(int32_t pubsock,struct LP_peerinfo *mypeer,char *myipaddr,uint { for (i=0; iipaddr); + jaddstr(item,"isLP",peer->ipaddr); jaddnum(item,"port",peer->port); if ( strcmp(peer->ipaddr,LP_myipaddr) == 0 ) { @@ -49,12 +49,13 @@ char *LP_peers() HASH_ITER(hh,LP_peerinfos,peer,tmp) { //if ( peer->errors < LP_MAXPEER_ERRORS ) + if ( peer->isLP != 0 ) jaddi(peersjson,LP_peerjson(peer)); } return(jprint(peersjson,1)); } -struct LP_peerinfo *LP_addpeer(struct LP_peerinfo *mypeer,int32_t mypubsock,char *ipaddr,uint16_t port,uint16_t pushport,uint16_t subport,int32_t numpeers,int32_t numutxos,uint32_t sessionid) +struct LP_peerinfo *LP_addpeer(struct LP_peerinfo *mypeer,int32_t mypubsock,char *ipaddr,uint16_t port,uint16_t pushport,uint16_t subport,int32_t isLP,uint32_t sessionid) { uint32_t ipbits; int32_t valid,pushsock,subsock,timeout; char checkip[64],pushaddr[64],subaddr[64]; struct LP_peerinfo *peer = 0; printf("addpeer (%s:%u) pushport.%u subport.%u\n",ipaddr,port,pushport,subport); @@ -68,6 +69,7 @@ struct LP_peerinfo *LP_addpeer(struct LP_peerinfo *mypeer,int32_t mypubsock,char { if ( (peer= LP_peerfind(ipbits,port)) != 0 ) { + peer->isLP = isLP; /*if ( numpeers > peer->numpeers ) peer->numpeers = numpeers; if ( numutxos > peer->numutxos ) @@ -145,15 +147,15 @@ struct LP_peerinfo *LP_addpeer(struct LP_peerinfo *mypeer,int32_t mypubsock,char if ( mypeer != 0 ) { mypeer->numpeers++; - printf("_LPaddpeer %s -> numpeers.%d mypubsock.%d other.(%d %d)\n",ipaddr,mypeer->numpeers,mypubsock,numpeers,numutxos); + printf("_LPaddpeer %s -> numpeers.%d mypubsock.%d other.(%d)\n",ipaddr,mypeer->numpeers,mypubsock,isLP); } else peer->numpeers = 1; // will become mypeer portable_mutex_unlock(&LP_peermutex); if ( IAMLP != 0 && mypubsock >= 0 ) { - struct iguana_info *coin,*ctmp; bits256 zero; char busaddr[64]; - memset(zero.bytes,0,sizeof(zero)); + struct iguana_info *coin,*ctmp; char busaddr[64]; // + //memset(zero.bytes,0,sizeof(zero)); //LP_send(mypubsock,msg,(int32_t)strlen(msg)+1,1); - LP_reserved_msg(0,"","",zero,jprint(LP_peerjson(peer),1)); + //LP_reserved_msg(0,"","",zero,jprint(LP_peerjson(peer),1)); if ( 0 ) { HASH_ITER(hh,LP_coins,coin,ctmp) @@ -202,42 +204,6 @@ int32_t LP_coinbus(uint16_t coin_busport) return(bussock); } -int32_t LP_peersparse(struct LP_peerinfo *mypeer,int32_t mypubsock,char *destipaddr,uint16_t destport,char *retstr,uint32_t now) -{ - struct LP_peerinfo *peer; uint32_t argipbits; char *argipaddr; uint16_t argport,pushport,subport; cJSON *array,*item; int32_t numpeers,i,n=0; - if ( (array= cJSON_Parse(retstr)) != 0 ) - { - if ( (n= cJSON_GetArraySize(array)) > 0 ) - { - for (i=0; i numpeers) ) - peer = LP_addpeer(mypeer,mypubsock,argipaddr,argport,pushport,subport,jint(item,"numpeers"),jint(item,"numutxos"),juint(item,"session")); - } - if ( peer != 0 ) - { - peer->lasttime = now; - if ( strcmp(argipaddr,destipaddr) == 0 && destport == argport && peer->numpeers != n ) - peer->numpeers = n; - } - } - } - } - free_json(array); - } - return(n); -} int32_t LP_numpeers() { diff --git a/iguana/exchanges/LP_statemachine.c b/iguana/exchanges/LP_statemachine.c index c473d1614..d518e18c3 100644 --- a/iguana/exchanges/LP_statemachine.c +++ b/iguana/exchanges/LP_statemachine.c @@ -133,6 +133,42 @@ FILE *basilisk_swap_save(struct basilisk_swap *swap,bits256 privkey,struct basil return(fp); } #ifdef oldway +int32_t LP_peersparse(struct LP_peerinfo *mypeer,int32_t mypubsock,char *destipaddr,uint16_t destport,char *retstr,uint32_t now) +{ + struct LP_peerinfo *peer; uint32_t argipbits; char *argipaddr; uint16_t argport,pushport,subport; cJSON *array,*item; int32_t numpeers,i,n=0; + if ( (array= cJSON_Parse(retstr)) != 0 ) + { + if ( (n= cJSON_GetArraySize(array)) > 0 ) + { + for (i=0; i numpeers) ) + peer = LP_addpeer(mypeer,mypubsock,argipaddr,argport,pushport,subport,jint(item,"numpeers"),jint(item,"numutxos"),juint(item,"session")); + } + if ( peer != 0 ) + { + peer->lasttime = now; + if ( strcmp(argipaddr,destipaddr) == 0 && destport == argport && peer->numpeers != n ) + peer->numpeers = n; + } + } + } + } + free_json(array); + } + return(n); +} void LP_peersquery(struct LP_peerinfo *mypeer,int32_t mypubsock,char *destipaddr,uint16_t destport,char *myipaddr,uint16_t myport) { char *retstr; struct LP_peerinfo *peer,*tmp; bits256 zero; uint32_t now,flag = 0; From d32e024b4571644df08cfd0c22801c6fbf843722 Mon Sep 17 00:00:00 2001 From: jl777 Date: Wed, 8 Nov 2017 21:10:33 +0200 Subject: [PATCH 0395/1664] Test --- iguana/exchanges/LP_nativeDEX.c | 11 ++++------- 1 file changed, 4 insertions(+), 7 deletions(-) diff --git a/iguana/exchanges/LP_nativeDEX.c b/iguana/exchanges/LP_nativeDEX.c index af84d3b71..64fde8eb5 100644 --- a/iguana/exchanges/LP_nativeDEX.c +++ b/iguana/exchanges/LP_nativeDEX.c @@ -1093,14 +1093,11 @@ void LPinit(uint16_t myport,uint16_t mypullport,uint16_t mypubport,uint16_t mybu printf("error launching LP_swapsloop for port.%u\n",myport); exit(-1); } + char request[128]; if ( IAMLP == 0 ) - LP_reserved_msg(0,"","",G.LP_mypub25519,clonestr("{\"method\":\"getpeers\"}")); - else - { - char request[128]; - sprintf(request,"{\"method\":\"getpeers\",\"LPnode\":\"%s\"}",myipaddr); - LP_reserved_msg(0,"","",G.LP_mypub25519,clonestr(request)); - } + sprintf(request,"{\"method\":\"getpeers\",\"timestamp\":%u}",(uint32_t)time(NULL)); + else sprintf(request,"{\"method\":\"getpeers\",\"LPnode\":\"%s\",\"timestamp\":%u}",myipaddr,(uint32_t)time(NULL)); + LP_reserved_msg(0,"","",G.LP_mypub25519,clonestr(request)); int32_t nonz; //uint32_t lasthello = 0; while ( 1 ) { From d216542623d496053436aa064130f93c033b6ae3 Mon Sep 17 00:00:00 2001 From: jl777 Date: Wed, 8 Nov 2017 21:19:14 +0200 Subject: [PATCH 0396/1664] Test --- iguana/exchanges/LP_commands.c | 6 +++--- iguana/exchanges/LP_nativeDEX.c | 4 ++-- iguana/exchanges/LP_signatures.c | 7 ++++++- 3 files changed, 11 insertions(+), 6 deletions(-) diff --git a/iguana/exchanges/LP_commands.c b/iguana/exchanges/LP_commands.c index fc0d34d2b..03d262bbb 100644 --- a/iguana/exchanges/LP_commands.c +++ b/iguana/exchanges/LP_commands.c @@ -543,19 +543,19 @@ bot_resume(botid)\n\ return(LP_uitem_recv(argjson)); else if ( strcmp(method,"notify") == 0 ) return(LP_notify_recv(argjson)); - else if ( strcmp(method,"getpeers") == 0 ) + /*else if ( strcmp(method,"getpeers") == 0 ) { char *tmpstr; if ( (tmpstr= jstr(argjson,"LPnode")) != 0 ) LP_addpeer(LP_mypeer,LP_mypubsock,tmpstr,RPC_port,RPC_port+10,RPC_port+20,1,G.LP_sessionid); if ( IAMLP != 0 ) { - printf("send peers list\n"); + printf("send peers list %s\n",LP_peers()); bits256 zero; memset(zero.bytes,0,sizeof(zero)); LP_reserved_msg(0,"","",zero,LP_peers()); } retstr = clonestr("{\"result\":\"success\"}"); - } + }*/ // end received response else if ( strcmp(method,"tradestatus") == 0 ) diff --git a/iguana/exchanges/LP_nativeDEX.c b/iguana/exchanges/LP_nativeDEX.c index 64fde8eb5..33ea822ad 100644 --- a/iguana/exchanges/LP_nativeDEX.c +++ b/iguana/exchanges/LP_nativeDEX.c @@ -1093,11 +1093,11 @@ void LPinit(uint16_t myport,uint16_t mypullport,uint16_t mypubport,uint16_t mybu printf("error launching LP_swapsloop for port.%u\n",myport); exit(-1); } - char request[128]; + /*char request[128]; if ( IAMLP == 0 ) sprintf(request,"{\"method\":\"getpeers\",\"timestamp\":%u}",(uint32_t)time(NULL)); else sprintf(request,"{\"method\":\"getpeers\",\"LPnode\":\"%s\",\"timestamp\":%u}",myipaddr,(uint32_t)time(NULL)); - LP_reserved_msg(0,"","",G.LP_mypub25519,clonestr(request)); + LP_reserved_msg(0,"","",G.LP_mypub25519,clonestr(request)); */ int32_t nonz; //uint32_t lasthello = 0; while ( 1 ) { diff --git a/iguana/exchanges/LP_signatures.c b/iguana/exchanges/LP_signatures.c index 1933f50a3..bb15ecfd6 100644 --- a/iguana/exchanges/LP_signatures.c +++ b/iguana/exchanges/LP_signatures.c @@ -569,17 +569,22 @@ void LP_notify_pubkeys(void *ctx,int32_t pubsock) timestamp = (uint32_t)time(NULL); jaddnum(reqjson,"timestamp",timestamp); LP_pubkey_sigadd(reqjson,timestamp,G.LP_privkey,G.LP_mypub25519,G.LP_myrmd160,G.LP_pubsecp); + if ( IAMLP != 0 ) + jaddstr(reqjson,"isLP",LP_myipaddr); + jaddnum(reqjson,"session",G.LP_sessionid); LP_reserved_msg(0,"","",zero,jprint(reqjson,1)); } char *LP_notify_recv(cJSON *argjson) { - bits256 pub; struct LP_pubkeyinfo *pubp; + bits256 pub; struct LP_pubkeyinfo *pubp; char *ipaddr; pub = jbits256(argjson,"pub"); if ( bits256_nonz(pub) != 0 ) { if ( (pubp= LP_pubkeyadd(pub)) != 0 ) LP_pubkey_sigcheck(pubp,argjson); + if ( (ipaddr= jstr(argjson,"isLP")) != 0 ) + LP_addpeer(LP_mypeer,LP_mypubsock,ipaddr,RPC_port,RPC_port+10,RPC_port+20,1,juint(argjson,"session")); //char str[65]; printf("%.3f NOTIFIED pub %s rmd160 %s\n",OS_milliseconds()-millis,bits256_str(str,pub),rmd160str); } return(clonestr("{\"result\":\"success\",\"notify\":\"received\"}")); From a525e4e1b772117f8c1b136c24f00244faa2fb6b Mon Sep 17 00:00:00 2001 From: jl777 Date: Wed, 8 Nov 2017 21:28:13 +0200 Subject: [PATCH 0397/1664] Test --- iguana/exchanges/LP_nativeDEX.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/iguana/exchanges/LP_nativeDEX.c b/iguana/exchanges/LP_nativeDEX.c index 33ea822ad..a4fafcbe9 100644 --- a/iguana/exchanges/LP_nativeDEX.c +++ b/iguana/exchanges/LP_nativeDEX.c @@ -333,7 +333,7 @@ int32_t LP_sock_check(char *typestr,void *ctx,char *myipaddr,int32_t pubsock,int if ( (recvlen= nn_recv(sock,&ptr,NN_MSG,0)) > 0 ) { methodstr[0] = 0; - printf("%s.(%s)\n",typestr,(char *)ptr); + //printf("%s.(%s)\n",typestr,(char *)ptr); if ( 0 ) { cJSON *recvjson; char *mstr;//,*cstr; @@ -766,7 +766,7 @@ void LP_pubkeysloop(void *ctx) coin->lastunspent = (uint32_t)time(NULL); } } - if ( time(NULL) > lasttime+60 ) + if ( time(NULL) > lasttime+LP_ORDERBOOK_DURATION*0.5 ) { //printf("LP_pubkeysloop %u\n",(uint32_t)time(NULL)); LP_notify_pubkeys(ctx,LP_mypubsock); From bdffba76023589c934de39998e6a0dd8b8444b33 Mon Sep 17 00:00:00 2001 From: jl777 Date: Wed, 8 Nov 2017 21:31:57 +0200 Subject: [PATCH 0398/1664] Test --- iguana/exchanges/LP_commands.c | 2 ++ iguana/exchanges/LP_peers.c | 2 +- 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/iguana/exchanges/LP_commands.c b/iguana/exchanges/LP_commands.c index 03d262bbb..ae598dbfc 100644 --- a/iguana/exchanges/LP_commands.c +++ b/iguana/exchanges/LP_commands.c @@ -543,6 +543,8 @@ bot_resume(botid)\n\ return(LP_uitem_recv(argjson)); else if ( strcmp(method,"notify") == 0 ) return(LP_notify_recv(argjson)); + else if ( strcmp(method,"getpeers") == 0 ) + retstr = clonestr("{\"error\":\"deprecated\"}"); /*else if ( strcmp(method,"getpeers") == 0 ) { char *tmpstr; diff --git a/iguana/exchanges/LP_peers.c b/iguana/exchanges/LP_peers.c index 99f5b0da5..a7e2479b4 100644 --- a/iguana/exchanges/LP_peers.c +++ b/iguana/exchanges/LP_peers.c @@ -58,7 +58,6 @@ char *LP_peers() struct LP_peerinfo *LP_addpeer(struct LP_peerinfo *mypeer,int32_t mypubsock,char *ipaddr,uint16_t port,uint16_t pushport,uint16_t subport,int32_t isLP,uint32_t sessionid) { uint32_t ipbits; int32_t valid,pushsock,subsock,timeout; char checkip[64],pushaddr[64],subaddr[64]; struct LP_peerinfo *peer = 0; - printf("addpeer (%s:%u) pushport.%u subport.%u\n",ipaddr,port,pushport,subport); #ifdef LP_STRICTPEERS if ( strncmp("5.9.253",ipaddr,strlen("5.9.253")) != 0 ) return(0); @@ -79,6 +78,7 @@ struct LP_peerinfo *LP_addpeer(struct LP_peerinfo *mypeer,int32_t mypubsock,char } else { + printf("addpeer (%s:%u) pushport.%u subport.%u\n",ipaddr,port,pushport,subport); peer = calloc(1,sizeof(*peer)); if ( strcmp(peer->ipaddr,LP_myipaddr) == 0 ) peer->sessionid = G.LP_sessionid; From e0b06b3ba5a7956b549fdc349e877e120bfe2785 Mon Sep 17 00:00:00 2001 From: jl777 Date: Wed, 8 Nov 2017 21:33:23 +0200 Subject: [PATCH 0399/1664] Test --- iguana/exchanges/LP_nativeDEX.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/iguana/exchanges/LP_nativeDEX.c b/iguana/exchanges/LP_nativeDEX.c index a4fafcbe9..0a1457b7d 100644 --- a/iguana/exchanges/LP_nativeDEX.c +++ b/iguana/exchanges/LP_nativeDEX.c @@ -574,7 +574,7 @@ void LP_coinsloop(void *_coins) continue; } nonz++; - if ( coin->lastscanht < coin->longestchain-3 ) + if ( 0 && coin->lastscanht < coin->longestchain-3 ) printf("[%s]: %s ref.%d scan.%d to %d, longest.%d\n",coins,coin->symbol,coin->firstrefht,coin->firstscanht,coin->lastscanht,coin->longestchain); for (j=0; j<100; j++) { From 5af0a5181e0668b938f54c355a50e7a9a0a388ae Mon Sep 17 00:00:00 2001 From: jl777 Date: Wed, 8 Nov 2017 21:42:33 +0200 Subject: [PATCH 0400/1664] Test --- iguana/exchanges/LP_prices.c | 2 +- iguana/exchanges/LP_signatures.c | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/iguana/exchanges/LP_prices.c b/iguana/exchanges/LP_prices.c index 219968200..09904ce54 100644 --- a/iguana/exchanges/LP_prices.c +++ b/iguana/exchanges/LP_prices.c @@ -1030,7 +1030,7 @@ cJSON *LP_pricearray(char *base,char *rel,uint32_t firsttime,uint32_t lasttime,i void LP_pricefeedupdate(bits256 pubkey,char *base,char *rel,double price) { struct LP_priceinfo *basepp,*relpp; uint32_t now; uint64_t price64; struct LP_pubkeyinfo *pubp; char str[65],fname[512]; FILE *fp; - //printf("check PRICEFEED UPDATE.(%s/%s) %.8f %s\n",base,rel,price,bits256_str(str,pubkey)); + printf("check PRICEFEED UPDATE.(%s/%s) %.8f %s\n",base,rel,price,bits256_str(str,pubkey)); if ( LP_pricevalid(price) > 0 && (basepp= LP_priceinfofind(base)) != 0 && (relpp= LP_priceinfofind(rel)) != 0 ) { //if ( (fp= basepp->fps[relpp->ind]) == 0 ) diff --git a/iguana/exchanges/LP_signatures.c b/iguana/exchanges/LP_signatures.c index bb15ecfd6..22b8a2460 100644 --- a/iguana/exchanges/LP_signatures.c +++ b/iguana/exchanges/LP_signatures.c @@ -471,7 +471,7 @@ char *LP_pricepings(void *ctx,char *myipaddr,int32_t pubsock,char *base,char *re char *LP_postprice_recv(cJSON *argjson) { bits256 pubkey; double price; char *base,*rel; - //printf("PRICE POSTED.(%s)\n",jprint(argjson,0)); + printf("PRICE POSTED.(%s)\n",jprint(argjson,0)); if ( (base= jstr(argjson,"base")) != 0 && (rel= jstr(argjson,"rel")) != 0 && (price= jdouble(argjson,"price")) > SMALLVAL ) { pubkey = jbits256(argjson,"pubkey"); From c8a9d2ea4cebd4b1b8596b0ef9f493d1328704b4 Mon Sep 17 00:00:00 2001 From: jl777 Date: Wed, 8 Nov 2017 21:46:35 +0200 Subject: [PATCH 0401/1664] Test --- iguana/exchanges/LP_prices.c | 2 +- iguana/exchanges/LP_signatures.c | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/iguana/exchanges/LP_prices.c b/iguana/exchanges/LP_prices.c index 09904ce54..219968200 100644 --- a/iguana/exchanges/LP_prices.c +++ b/iguana/exchanges/LP_prices.c @@ -1030,7 +1030,7 @@ cJSON *LP_pricearray(char *base,char *rel,uint32_t firsttime,uint32_t lasttime,i void LP_pricefeedupdate(bits256 pubkey,char *base,char *rel,double price) { struct LP_priceinfo *basepp,*relpp; uint32_t now; uint64_t price64; struct LP_pubkeyinfo *pubp; char str[65],fname[512]; FILE *fp; - printf("check PRICEFEED UPDATE.(%s/%s) %.8f %s\n",base,rel,price,bits256_str(str,pubkey)); + //printf("check PRICEFEED UPDATE.(%s/%s) %.8f %s\n",base,rel,price,bits256_str(str,pubkey)); if ( LP_pricevalid(price) > 0 && (basepp= LP_priceinfofind(base)) != 0 && (relpp= LP_priceinfofind(rel)) != 0 ) { //if ( (fp= basepp->fps[relpp->ind]) == 0 ) diff --git a/iguana/exchanges/LP_signatures.c b/iguana/exchanges/LP_signatures.c index 22b8a2460..bb15ecfd6 100644 --- a/iguana/exchanges/LP_signatures.c +++ b/iguana/exchanges/LP_signatures.c @@ -471,7 +471,7 @@ char *LP_pricepings(void *ctx,char *myipaddr,int32_t pubsock,char *base,char *re char *LP_postprice_recv(cJSON *argjson) { bits256 pubkey; double price; char *base,*rel; - printf("PRICE POSTED.(%s)\n",jprint(argjson,0)); + //printf("PRICE POSTED.(%s)\n",jprint(argjson,0)); if ( (base= jstr(argjson,"base")) != 0 && (rel= jstr(argjson,"rel")) != 0 && (price= jdouble(argjson,"price")) > SMALLVAL ) { pubkey = jbits256(argjson,"pubkey"); From f26543502edf73d433d6462d3daf7b410b09e2f5 Mon Sep 17 00:00:00 2001 From: jl777 Date: Wed, 8 Nov 2017 22:04:37 +0200 Subject: [PATCH 0402/1664] Test --- iguana/exchanges/LP_include.h | 2 +- iguana/exchanges/LP_portfolio.c | 2 +- iguana/exchanges/LP_rpc.c | 23 ----------------------- iguana/exchanges/LP_statemachine.c | 23 ++++++++++++++++++++++- 4 files changed, 24 insertions(+), 26 deletions(-) diff --git a/iguana/exchanges/LP_include.h b/iguana/exchanges/LP_include.h index 1b76e220a..b1fd07fe9 100644 --- a/iguana/exchanges/LP_include.h +++ b/iguana/exchanges/LP_include.h @@ -38,7 +38,7 @@ void emscripten_usleep(int32_t x); // returns immediate, no sense for sleeping #define LP_MAGICBITS 8 #define LP_HTTP_TIMEOUT 3 // 1 is too small due to edge cases of time(NULL) -#define LP_AUTOTRADE_TIMEOUT 20 +#define LP_AUTOTRADE_TIMEOUT 30 #define ELECTRUM_TIMEOUT 5 #define LP_ELECTRUM_KEEPALIVE 60 #define LP_ELECTRUM_MAXERRORS 777 diff --git a/iguana/exchanges/LP_portfolio.c b/iguana/exchanges/LP_portfolio.c index 62b50d9d2..c36c64d67 100644 --- a/iguana/exchanges/LP_portfolio.c +++ b/iguana/exchanges/LP_portfolio.c @@ -641,7 +641,7 @@ void prices_loop(void *ctx) } free(retstr); } - sleep(60); + sleep(120); } } diff --git a/iguana/exchanges/LP_rpc.c b/iguana/exchanges/LP_rpc.c index 64719e0d5..6b843316d 100644 --- a/iguana/exchanges/LP_rpc.c +++ b/iguana/exchanges/LP_rpc.c @@ -51,17 +51,6 @@ char *LP_isitme(char *destip,uint16_t destport) } else return(0); } -void LP_peer_request(char *destip,uint16_t destport,cJSON *argjson) -{ - struct LP_peerinfo *peer; uint8_t *msg; int32_t msglen; uint32_t crc32; - peer = LP_peerfind((uint32_t)calc_ipbits(destip),destport); - msg = (void *)jprint(argjson,0); - msglen = (int32_t)strlen((char *)msg) + 1; - crc32 = calc_crc32(0,&msg[2],msglen - 2); - LP_queuesend(crc32,peer->pushsock,"","",msg,msglen); - free_json(argjson); -} - char *issue_LP_psock(char *destip,uint16_t destport,int32_t ispaired) { char url[512],*retstr; @@ -72,18 +61,6 @@ char *issue_LP_psock(char *destip,uint16_t destport,int32_t ispaired) return(retstr); } -void issue_LP_getpeers(char *destip,uint16_t destport) -{ - cJSON *reqjson = cJSON_CreateObject(); - jaddstr(reqjson,"method","getpeers"); - LP_peer_request(destip,destport,reqjson); - /*char url[512],*retstr; - sprintf(url,"http://%s:%u/api/stats/getpeers?ipaddr=%s&port=%u&numpeers=%d",destip,destport,ipaddr,port,numpeers); - retstr = LP_issue_curl("getpeers",destip,port,url); - //printf("%s -> getpeers.(%s)\n",destip,retstr); - return(retstr);*/ -} - char *LP_apicall(struct iguana_info *coin,char *method,char *params) { cJSON *retjson; char *retstr; diff --git a/iguana/exchanges/LP_statemachine.c b/iguana/exchanges/LP_statemachine.c index d518e18c3..e22b7890d 100644 --- a/iguana/exchanges/LP_statemachine.c +++ b/iguana/exchanges/LP_statemachine.c @@ -169,7 +169,28 @@ int32_t LP_peersparse(struct LP_peerinfo *mypeer,int32_t mypubsock,char *destipa } return(n); } -void LP_peersquery(struct LP_peerinfo *mypeer,int32_t mypubsock,char *destipaddr,uint16_t destport,char *myipaddr,uint16_t myport) +void issue_LP_getpeers(char *destip,uint16_t destport) +{ + cJSON *reqjson = cJSON_CreateObject(); + jaddstr(reqjson,"method","getpeers"); + LP_peer_request(destip,destport,reqjson); + /*char url[512],*retstr; + sprintf(url,"http://%s:%u/api/stats/getpeers?ipaddr=%s&port=%u&numpeers=%d",destip,destport,ipaddr,port,numpeers); + retstr = LP_issue_curl("getpeers",destip,port,url); + //printf("%s -> getpeers.(%s)\n",destip,retstr); + return(retstr);*/ +} + +void LP_peer_request(char *destip,uint16_t destport,cJSON *argjson) +{ + struct LP_peerinfo *peer; uint8_t *msg; int32_t msglen; uint32_t crc32; + peer = LP_peerfind((uint32_t)calc_ipbits(destip),destport); + msg = (void *)jprint(argjson,0); + msglen = (int32_t)strlen((char *)msg) + 1; + crc32 = calc_crc32(0,&msg[2],msglen - 2); + LP_queuesend(crc32,peer->pushsock,"","",msg,msglen); + free_json(argjson); +}void LP_peersquery(struct LP_peerinfo *mypeer,int32_t mypubsock,char *destipaddr,uint16_t destport,char *myipaddr,uint16_t myport) { char *retstr; struct LP_peerinfo *peer,*tmp; bits256 zero; uint32_t now,flag = 0; peer = LP_peerfind((uint32_t)calc_ipbits(destipaddr),destport); From a9763f0b7ef9ad4df662ba9b22379daf73768ffe Mon Sep 17 00:00:00 2001 From: jl777 Date: Wed, 8 Nov 2017 22:20:05 +0200 Subject: [PATCH 0403/1664] Test --- iguana/exchanges/LP_nativeDEX.c | 4 ++-- iguana/exchanges/LP_signatures.c | 3 +++ 2 files changed, 5 insertions(+), 2 deletions(-) diff --git a/iguana/exchanges/LP_nativeDEX.c b/iguana/exchanges/LP_nativeDEX.c index 0a1457b7d..f9d4893cd 100644 --- a/iguana/exchanges/LP_nativeDEX.c +++ b/iguana/exchanges/LP_nativeDEX.c @@ -711,7 +711,7 @@ void LP_initpeers(int32_t pubsock,struct LP_peerinfo *mypeer,char *myipaddr,uint int32_t i,j; uint32_t r; if ( IAMLP != 0 ) { - LP_mypeer = mypeer = LP_addpeer(mypeer,pubsock,myipaddr,myport,0,0,0,G.LP_sessionid); + LP_mypeer = mypeer = LP_addpeer(mypeer,pubsock,myipaddr,myport,0,0,1,G.LP_sessionid); if ( myipaddr == 0 || mypeer == 0 ) { printf("couldnt get myipaddr or null mypeer.%p\n",mypeer); @@ -768,7 +768,7 @@ void LP_pubkeysloop(void *ctx) } if ( time(NULL) > lasttime+LP_ORDERBOOK_DURATION*0.5 ) { - //printf("LP_pubkeysloop %u\n",(uint32_t)time(NULL)); + printf("LP_pubkeysloop %u\n",(uint32_t)time(NULL)); LP_notify_pubkeys(ctx,LP_mypubsock); lasttime = (uint32_t)time(NULL); } diff --git a/iguana/exchanges/LP_signatures.c b/iguana/exchanges/LP_signatures.c index bb15ecfd6..5c5ffdab4 100644 --- a/iguana/exchanges/LP_signatures.c +++ b/iguana/exchanges/LP_signatures.c @@ -584,7 +584,10 @@ char *LP_notify_recv(cJSON *argjson) if ( (pubp= LP_pubkeyadd(pub)) != 0 ) LP_pubkey_sigcheck(pubp,argjson); if ( (ipaddr= jstr(argjson,"isLP")) != 0 ) + { + printf("notify from isLP %s\n",ipaddr); LP_addpeer(LP_mypeer,LP_mypubsock,ipaddr,RPC_port,RPC_port+10,RPC_port+20,1,juint(argjson,"session")); + } //char str[65]; printf("%.3f NOTIFIED pub %s rmd160 %s\n",OS_milliseconds()-millis,bits256_str(str,pub),rmd160str); } return(clonestr("{\"result\":\"success\",\"notify\":\"received\"}")); From ea0aeee8ef9741168c2b3ee3536551f0c4c3a2a6 Mon Sep 17 00:00:00 2001 From: jl777 Date: Wed, 8 Nov 2017 22:21:22 +0200 Subject: [PATCH 0404/1664] Test --- iguana/exchanges/LP_nativeDEX.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/iguana/exchanges/LP_nativeDEX.c b/iguana/exchanges/LP_nativeDEX.c index f9d4893cd..43ea59640 100644 --- a/iguana/exchanges/LP_nativeDEX.c +++ b/iguana/exchanges/LP_nativeDEX.c @@ -659,7 +659,7 @@ int32_t LP_mainloop_iter(void *ctx,char *myipaddr,struct LP_peerinfo *mypeer,int if ( (height= LP_getheight(coin)) > coin->longestchain ) { coin->longestchain = height; - if ( coin->firstrefht != 0 ) + 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); coin->lastgetinfo = (uint32_t)time(NULL); From 55f8bfc35524565e44a9b01b134d9029dd69c4a4 Mon Sep 17 00:00:00 2001 From: jl777 Date: Wed, 8 Nov 2017 22:29:19 +0200 Subject: [PATCH 0405/1664] Test --- iguana/exchanges/LP_nativeDEX.c | 2 +- iguana/exchanges/LP_signatures.c | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/iguana/exchanges/LP_nativeDEX.c b/iguana/exchanges/LP_nativeDEX.c index 43ea59640..feb20b763 100644 --- a/iguana/exchanges/LP_nativeDEX.c +++ b/iguana/exchanges/LP_nativeDEX.c @@ -768,7 +768,7 @@ void LP_pubkeysloop(void *ctx) } if ( time(NULL) > lasttime+LP_ORDERBOOK_DURATION*0.5 ) { - printf("LP_pubkeysloop %u\n",(uint32_t)time(NULL)); + //printf("LP_pubkeysloop %u\n",(uint32_t)time(NULL)); LP_notify_pubkeys(ctx,LP_mypubsock); lasttime = (uint32_t)time(NULL); } diff --git a/iguana/exchanges/LP_signatures.c b/iguana/exchanges/LP_signatures.c index 5c5ffdab4..e28a1974f 100644 --- a/iguana/exchanges/LP_signatures.c +++ b/iguana/exchanges/LP_signatures.c @@ -585,7 +585,7 @@ char *LP_notify_recv(cJSON *argjson) LP_pubkey_sigcheck(pubp,argjson); if ( (ipaddr= jstr(argjson,"isLP")) != 0 ) { - printf("notify from isLP %s\n",ipaddr); + //printf("notify from isLP %s\n",ipaddr); LP_addpeer(LP_mypeer,LP_mypubsock,ipaddr,RPC_port,RPC_port+10,RPC_port+20,1,juint(argjson,"session")); } //char str[65]; printf("%.3f NOTIFIED pub %s rmd160 %s\n",OS_milliseconds()-millis,bits256_str(str,pub),rmd160str); From 7acc99a3c02bb5782c644ef785abf5b7c89ccacf Mon Sep 17 00:00:00 2001 From: jl777 Date: Wed, 8 Nov 2017 22:35:42 +0200 Subject: [PATCH 0406/1664] Test --- iguana/exchanges/LP_nativeDEX.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/iguana/exchanges/LP_nativeDEX.c b/iguana/exchanges/LP_nativeDEX.c index feb20b763..51c32dac8 100644 --- a/iguana/exchanges/LP_nativeDEX.c +++ b/iguana/exchanges/LP_nativeDEX.c @@ -93,7 +93,8 @@ char LP_myipaddr[64],LP_publicaddr[64],USERHOME[512] = { "/root" }; char LP_gui[16] = { "cli" }; char *default_LPnodes[] = { "5.9.253.195", "5.9.253.196", "5.9.253.197", "5.9.253.198", "5.9.253.199", "5.9.253.200", "5.9.253.201", "5.9.253.202", "5.9.253.203", - "24.54.206.138", "173.212.225.176", "136.243.45.140", "107.72.162.127", "72.50.16.86", "51.15.202.191", "173.228.198.88", + "51.15.86.136", + //"24.54.206.138", "173.212.225.176", "136.243.45.140", "107.72.162.127", "72.50.16.86", "51.15.202.191", "173.228.198.88", //"51.15.203.171", "51.15.86.136", "51.15.94.249", "51.15.80.18", "51.15.91.40", "51.15.54.2", "51.15.86.31", "51.15.82.29", "51.15.89.155", };//"5.9.253.204" }; // @@ -734,7 +735,7 @@ void LP_initpeers(int32_t pubsock,struct LP_peerinfo *mypeer,char *myipaddr,uint } if ( seednode == 0 || seednode[0] == 0 ) { - LP_addpeer(mypeer,pubsock,"5.9.253.195",myport,pushport,subport,0,G.LP_sessionid); + LP_addpeer(mypeer,pubsock,"51.15.86.136",myport,pushport,subport,0,G.LP_sessionid); OS_randombytes((void *)&r,sizeof(r)); for (j=0; j Date: Wed, 8 Nov 2017 22:36:06 +0200 Subject: [PATCH 0407/1664] Test --- iguana/exchanges/LP_signatures.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/iguana/exchanges/LP_signatures.c b/iguana/exchanges/LP_signatures.c index e28a1974f..5c5ffdab4 100644 --- a/iguana/exchanges/LP_signatures.c +++ b/iguana/exchanges/LP_signatures.c @@ -585,7 +585,7 @@ char *LP_notify_recv(cJSON *argjson) LP_pubkey_sigcheck(pubp,argjson); if ( (ipaddr= jstr(argjson,"isLP")) != 0 ) { - //printf("notify from isLP %s\n",ipaddr); + printf("notify from isLP %s\n",ipaddr); LP_addpeer(LP_mypeer,LP_mypubsock,ipaddr,RPC_port,RPC_port+10,RPC_port+20,1,juint(argjson,"session")); } //char str[65]; printf("%.3f NOTIFIED pub %s rmd160 %s\n",OS_milliseconds()-millis,bits256_str(str,pub),rmd160str); From 4f5e48ac87d525d9e8019787ed55b17ede1a081b Mon Sep 17 00:00:00 2001 From: jl777 Date: Wed, 8 Nov 2017 22:43:03 +0200 Subject: [PATCH 0408/1664] Test --- iguana/exchanges/LP_nativeDEX.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/iguana/exchanges/LP_nativeDEX.c b/iguana/exchanges/LP_nativeDEX.c index 51c32dac8..cc9d7d69a 100644 --- a/iguana/exchanges/LP_nativeDEX.c +++ b/iguana/exchanges/LP_nativeDEX.c @@ -93,9 +93,8 @@ char LP_myipaddr[64],LP_publicaddr[64],USERHOME[512] = { "/root" }; char LP_gui[16] = { "cli" }; char *default_LPnodes[] = { "5.9.253.195", "5.9.253.196", "5.9.253.197", "5.9.253.198", "5.9.253.199", "5.9.253.200", "5.9.253.201", "5.9.253.202", "5.9.253.203", - "51.15.86.136", //"24.54.206.138", "173.212.225.176", "136.243.45.140", "107.72.162.127", "72.50.16.86", "51.15.202.191", "173.228.198.88", - //"51.15.203.171", "51.15.86.136", "51.15.94.249", "51.15.80.18", "51.15.91.40", "51.15.54.2", "51.15.86.31", "51.15.82.29", "51.15.89.155", + "51.15.203.171", "51.15.86.136", "51.15.94.249", "51.15.80.18", "51.15.91.40", "51.15.54.2", "51.15.86.31", "51.15.82.29", "51.15.89.155", };//"5.9.253.204" }; // From bcdbcd121c1a570cc7c613e7df756271912e53b0 Mon Sep 17 00:00:00 2001 From: jl777 Date: Wed, 8 Nov 2017 22:53:13 +0200 Subject: [PATCH 0409/1664] Test --- iguana/exchanges/LP_nativeDEX.c | 2 ++ iguana/exchanges/LP_signatures.c | 2 +- 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/iguana/exchanges/LP_nativeDEX.c b/iguana/exchanges/LP_nativeDEX.c index cc9d7d69a..a0dbe10bf 100644 --- a/iguana/exchanges/LP_nativeDEX.c +++ b/iguana/exchanges/LP_nativeDEX.c @@ -18,6 +18,8 @@ // LP_nativeDEX.c // marketmaker // +// dynamic adding of new LP node +// withdraw too big // bot status 1600% ? // BCH signing // dPoW security -> 4: KMD notarized, 5: BTC notarized, after next notary elections diff --git a/iguana/exchanges/LP_signatures.c b/iguana/exchanges/LP_signatures.c index 5c5ffdab4..e28a1974f 100644 --- a/iguana/exchanges/LP_signatures.c +++ b/iguana/exchanges/LP_signatures.c @@ -585,7 +585,7 @@ char *LP_notify_recv(cJSON *argjson) LP_pubkey_sigcheck(pubp,argjson); if ( (ipaddr= jstr(argjson,"isLP")) != 0 ) { - printf("notify from isLP %s\n",ipaddr); + //printf("notify from isLP %s\n",ipaddr); LP_addpeer(LP_mypeer,LP_mypubsock,ipaddr,RPC_port,RPC_port+10,RPC_port+20,1,juint(argjson,"session")); } //char str[65]; printf("%.3f NOTIFIED pub %s rmd160 %s\n",OS_milliseconds()-millis,bits256_str(str,pub),rmd160str); From 7b8cb29c9414e89e12c3d89505bddd7fa48586da Mon Sep 17 00:00:00 2001 From: jl777 Date: Thu, 9 Nov 2017 02:17:21 +0200 Subject: [PATCH 0410/1664] Test --- iguana/exchanges/LP_nativeDEX.c | 2 ++ iguana/exchanges/LP_remember.c | 1 + iguana/exchanges/LP_socket.c | 4 ++-- 3 files changed, 5 insertions(+), 2 deletions(-) diff --git a/iguana/exchanges/LP_nativeDEX.c b/iguana/exchanges/LP_nativeDEX.c index a0dbe10bf..15d76c144 100644 --- a/iguana/exchanges/LP_nativeDEX.c +++ b/iguana/exchanges/LP_nativeDEX.c @@ -19,6 +19,8 @@ // marketmaker // // dynamic adding of new LP node +// swap started event for bot +// lack of full depth // withdraw too big // bot status 1600% ? // BCH signing diff --git a/iguana/exchanges/LP_remember.c b/iguana/exchanges/LP_remember.c index 927af1771..f26467d3e 100644 --- a/iguana/exchanges/LP_remember.c +++ b/iguana/exchanges/LP_remember.c @@ -1115,6 +1115,7 @@ cJSON *basilisk_remember(int64_t *KMDtotals,int64_t *BTCtotals,uint32_t requesti if ( (fp= fopen(fname,"wb")) != 0 ) { jaddstr(item,"method","tradestatus"); + jaddstr(item,"gui",G.gui); itemstr = jprint(item,0); fprintf(fp,"%s\n",itemstr); LP_tradecommand_log(item); diff --git a/iguana/exchanges/LP_socket.c b/iguana/exchanges/LP_socket.c index 69c79217c..9e8b9bbb8 100644 --- a/iguana/exchanges/LP_socket.c +++ b/iguana/exchanges/LP_socket.c @@ -1049,8 +1049,8 @@ cJSON *LP_electrumserver(struct iguana_info *coin,char *ipaddr,uint16_t port) struct electrum_info *ep; int32_t kickval,already; cJSON *retjson; if ( ipaddr == 0 || ipaddr[0] == 0 || port == 0 ) { - //coin->electrum = 0; - printf("would have disabled %s electrum here\n",coin->symbol); + coin->electrum = 0; + //printf("would have disabled %s electrum here\n",coin->symbol); return(cJSON_Parse("{\"result\":\"success\",\"status\":\"electrum mode disabled, now in native coin mode\"}")); } retjson = cJSON_CreateObject(); From 94dc2faa0a93e7837c3a81845c6697a3781e5f05 Mon Sep 17 00:00:00 2001 From: jl777 Date: Thu, 9 Nov 2017 10:33:52 +0200 Subject: [PATCH 0411/1664] Test --- iguana/exchanges/LP_nativeDEX.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/iguana/exchanges/LP_nativeDEX.c b/iguana/exchanges/LP_nativeDEX.c index 15d76c144..5fdaad251 100644 --- a/iguana/exchanges/LP_nativeDEX.c +++ b/iguana/exchanges/LP_nativeDEX.c @@ -19,6 +19,7 @@ // marketmaker // // dynamic adding of new LP node +// BTC swaps // swap started event for bot // lack of full depth // withdraw too big @@ -740,6 +741,7 @@ void LP_initpeers(int32_t pubsock,struct LP_peerinfo *mypeer,char *myipaddr,uint { LP_addpeer(mypeer,pubsock,"51.15.86.136",myport,pushport,subport,0,G.LP_sessionid); OS_randombytes((void *)&r,sizeof(r)); + r = 0; for (j=0; j Date: Thu, 9 Nov 2017 11:09:13 +0200 Subject: [PATCH 0412/1664] Test --- iguana/exchanges/LP_network.c | 10 ++++++++++ iguana/exchanges/LP_rpc.c | 14 ++------------ 2 files changed, 12 insertions(+), 12 deletions(-) diff --git a/iguana/exchanges/LP_network.c b/iguana/exchanges/LP_network.c index 9dd4ab2f6..a058f1aa6 100644 --- a/iguana/exchanges/LP_network.c +++ b/iguana/exchanges/LP_network.c @@ -764,6 +764,16 @@ char *LP_psock(char *myipaddr,int32_t ispaired) */ +char *issue_LP_psock(char *destip,uint16_t destport,int32_t ispaired) +{ + char url[512],*retstr; + sprintf(url,"http://%s:%u/api/stats/psock?ispaired=%d",destip,destport-1,ispaired); + //return(LP_issue_curl("psock",destip,destport,url)); + retstr = issue_curlt(url,LP_HTTP_TIMEOUT*3); + printf("issue_LP_psock got (%s) from %s\n",retstr,destip); + return(retstr); +} + uint16_t LP_psock_get(char *connectaddr,char *publicaddr,int32_t ispaired) { uint16_t publicport = 0; char *retstr,*addr; cJSON *retjson; struct LP_peerinfo *peer,*tmp; diff --git a/iguana/exchanges/LP_rpc.c b/iguana/exchanges/LP_rpc.c index 6b843316d..f7bf6a38f 100644 --- a/iguana/exchanges/LP_rpc.c +++ b/iguana/exchanges/LP_rpc.c @@ -18,7 +18,7 @@ // marketmaker // -char *LP_issue_curl(char *debugstr,char *destip,uint16_t port,char *url) +/*char *LP_issue_curl(char *debugstr,char *destip,uint16_t port,char *url) { char *retstr = 0; int32_t maxerrs; struct LP_peerinfo *peer = 0; peer = LP_peerfind((uint32_t)calc_ipbits(destip),port); @@ -40,7 +40,7 @@ char *LP_issue_curl(char *debugstr,char *destip,uint16_t port,char *url) peer->good++; } return(retstr); -} +}*/ char *LP_isitme(char *destip,uint16_t destport) { @@ -51,16 +51,6 @@ char *LP_isitme(char *destip,uint16_t destport) } else return(0); } -char *issue_LP_psock(char *destip,uint16_t destport,int32_t ispaired) -{ - char url[512],*retstr; - sprintf(url,"http://%s:%u/api/stats/psock?ispaired=%d",destip,destport-1,ispaired); - //return(LP_issue_curl("psock",destip,destport,url)); - retstr = issue_curlt(url,LP_HTTP_TIMEOUT*3); - printf("issue_LP_psock got (%s) from %s\n",retstr,destip); - return(retstr); -} - char *LP_apicall(struct iguana_info *coin,char *method,char *params) { cJSON *retjson; char *retstr; From dfbbc1d48fc393dde3ffe1543d84ea98e7418570 Mon Sep 17 00:00:00 2001 From: jl777 Date: Thu, 9 Nov 2017 11:46:14 +0200 Subject: [PATCH 0413/1664] Test --- iguana/exchanges/LP_peers.c | 20 +++++++++++--------- iguana/exchanges/LP_signatures.c | 7 +++++-- 2 files changed, 16 insertions(+), 11 deletions(-) diff --git a/iguana/exchanges/LP_peers.c b/iguana/exchanges/LP_peers.c index a7e2479b4..250fe68b2 100644 --- a/iguana/exchanges/LP_peers.c +++ b/iguana/exchanges/LP_peers.c @@ -210,7 +210,8 @@ int32_t LP_numpeers() struct LP_peerinfo *peer,*tmp; int32_t numpeers = 0; HASH_ITER(hh,LP_peerinfos,peer,tmp) { - numpeers++; + if ( peer->isLP != 0 ) + numpeers++; } return(numpeers); } @@ -218,21 +219,22 @@ int32_t LP_numpeers() uint16_t LP_randpeer(char *destip) { struct LP_peerinfo *peer,*tmp; uint16_t port = 0; int32_t n,r,numpeers = 0; - HASH_ITER(hh,LP_peerinfos,peer,tmp) - { - numpeers++; - } + destip[0] = 0; + numpeers = LP_numpeers(); if ( numpeers > 0 ) { r = rand() % numpeers; n = 0; HASH_ITER(hh,LP_peerinfos,peer,tmp) { - if ( n++ == r ) + if ( peer->isLP != 0 ) { - strcpy(destip,peer->ipaddr); - port = peer->port; - break; + if ( n++ == r ) + { + strcpy(destip,peer->ipaddr); + port = peer->port; + break; + } } } } diff --git a/iguana/exchanges/LP_signatures.c b/iguana/exchanges/LP_signatures.c index e28a1974f..72cbd6b43 100644 --- a/iguana/exchanges/LP_signatures.c +++ b/iguana/exchanges/LP_signatures.c @@ -559,7 +559,7 @@ int32_t LP_pubkey_sigcheck(struct LP_pubkeyinfo *pubp,cJSON *item) void LP_notify_pubkeys(void *ctx,int32_t pubsock) { - bits256 zero; uint32_t timestamp; char secpstr[67]; cJSON *reqjson = cJSON_CreateObject(); + bits256 zero; uint32_t timestamp; char LPipaddr[64],secpstr[67]; cJSON *reqjson = cJSON_CreateObject(); memset(zero.bytes,0,sizeof(zero)); jaddstr(reqjson,"method","notify"); jaddstr(reqjson,"rmd160",G.LP_myrmd160str); @@ -570,7 +570,10 @@ void LP_notify_pubkeys(void *ctx,int32_t pubsock) jaddnum(reqjson,"timestamp",timestamp); LP_pubkey_sigadd(reqjson,timestamp,G.LP_privkey,G.LP_mypub25519,G.LP_myrmd160,G.LP_pubsecp); if ( IAMLP != 0 ) - jaddstr(reqjson,"isLP",LP_myipaddr); + { + if ( LP_randpeer(LPipaddr) != 0 ) + jaddstr(reqjson,"isLP",LPipaddr); + } jaddnum(reqjson,"session",G.LP_sessionid); LP_reserved_msg(0,"","",zero,jprint(reqjson,1)); } From 811f01a3bad4b7c0ceea71412d44e5f5c4516609 Mon Sep 17 00:00:00 2001 From: jl777 Date: Thu, 9 Nov 2017 12:11:03 +0200 Subject: [PATCH 0414/1664] Test --- iguana/exchanges/LP_signatures.c | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/iguana/exchanges/LP_signatures.c b/iguana/exchanges/LP_signatures.c index 72cbd6b43..c1032b823 100644 --- a/iguana/exchanges/LP_signatures.c +++ b/iguana/exchanges/LP_signatures.c @@ -571,8 +571,12 @@ void LP_notify_pubkeys(void *ctx,int32_t pubsock) LP_pubkey_sigadd(reqjson,timestamp,G.LP_privkey,G.LP_mypub25519,G.LP_myrmd160,G.LP_pubsecp); if ( IAMLP != 0 ) { - if ( LP_randpeer(LPipaddr) != 0 ) - jaddstr(reqjson,"isLP",LPipaddr); + if ( (rand() % 2) == 0 ) + LP_randpeer(LPipaddr); + else strcpy(LPipaddr,LP_myipaddr); + if ( LPipaddr[0] == 0 ) + strcpy(LPipaddr,LP_myipaddr); + jaddstr(reqjson,"isLP",LPipaddr); } jaddnum(reqjson,"session",G.LP_sessionid); LP_reserved_msg(0,"","",zero,jprint(reqjson,1)); From 99195b78c4b106f40019e90de5542a350cde3ddc Mon Sep 17 00:00:00 2001 From: jl777 Date: Thu, 9 Nov 2017 12:12:31 +0200 Subject: [PATCH 0415/1664] Test --- iguana/exchanges/LP_peers.c | 1 + iguana/exchanges/LP_signatures.c | 9 +++------ 2 files changed, 4 insertions(+), 6 deletions(-) diff --git a/iguana/exchanges/LP_peers.c b/iguana/exchanges/LP_peers.c index 250fe68b2..bd38ebd22 100644 --- a/iguana/exchanges/LP_peers.c +++ b/iguana/exchanges/LP_peers.c @@ -87,6 +87,7 @@ struct LP_peerinfo *LP_addpeer(struct LP_peerinfo *mypeer,int32_t mypubsock,char strcpy(peer->ipaddr,ipaddr); //peer->profitmargin = profitmargin; peer->ipbits = ipbits; + peer->isLP = isLP; peer->port = port; peer->ip_port = ((uint64_t)port << 32) | ipbits; if ( pushport != 0 && subport != 0 && (pushsock= nn_socket(AF_SP,NN_PUSH)) >= 0 ) diff --git a/iguana/exchanges/LP_signatures.c b/iguana/exchanges/LP_signatures.c index c1032b823..c8552a02b 100644 --- a/iguana/exchanges/LP_signatures.c +++ b/iguana/exchanges/LP_signatures.c @@ -571,12 +571,9 @@ void LP_notify_pubkeys(void *ctx,int32_t pubsock) LP_pubkey_sigadd(reqjson,timestamp,G.LP_privkey,G.LP_mypub25519,G.LP_myrmd160,G.LP_pubsecp); if ( IAMLP != 0 ) { - if ( (rand() % 2) == 0 ) - LP_randpeer(LPipaddr); - else strcpy(LPipaddr,LP_myipaddr); - if ( LPipaddr[0] == 0 ) - strcpy(LPipaddr,LP_myipaddr); - jaddstr(reqjson,"isLP",LPipaddr); + if ( LP_randpeer(LPipaddr) != 0 ) + jaddstr(reqjson,"isLP",LPipaddr); + else printf("no LPipaddr\n"); } jaddnum(reqjson,"session",G.LP_sessionid); LP_reserved_msg(0,"","",zero,jprint(reqjson,1)); From 82789a2380febe0df4d7e3a7b2136abe12e7d67d Mon Sep 17 00:00:00 2001 From: jl777 Date: Thu, 9 Nov 2017 12:17:13 +0200 Subject: [PATCH 0416/1664] Test --- iguana/exchanges/LP_peers.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/iguana/exchanges/LP_peers.c b/iguana/exchanges/LP_peers.c index bd38ebd22..994880e1a 100644 --- a/iguana/exchanges/LP_peers.c +++ b/iguana/exchanges/LP_peers.c @@ -68,7 +68,8 @@ struct LP_peerinfo *LP_addpeer(struct LP_peerinfo *mypeer,int32_t mypubsock,char { if ( (peer= LP_peerfind(ipbits,port)) != 0 ) { - peer->isLP = isLP; + if ( isLP != 0 ) + peer->isLP = isLP; /*if ( numpeers > peer->numpeers ) peer->numpeers = numpeers; if ( numutxos > peer->numutxos ) From 6087ef3cabc3e877a61a5f53ecbc3fe44c05a42b Mon Sep 17 00:00:00 2001 From: jl777 Date: Thu, 9 Nov 2017 12:21:52 +0200 Subject: [PATCH 0417/1664] Test --- iguana/exchanges/LP_nativeDEX.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/iguana/exchanges/LP_nativeDEX.c b/iguana/exchanges/LP_nativeDEX.c index 5fdaad251..c5b941456 100644 --- a/iguana/exchanges/LP_nativeDEX.c +++ b/iguana/exchanges/LP_nativeDEX.c @@ -716,7 +716,7 @@ void LP_initpeers(int32_t pubsock,struct LP_peerinfo *mypeer,char *myipaddr,uint int32_t i,j; uint32_t r; if ( IAMLP != 0 ) { - LP_mypeer = mypeer = LP_addpeer(mypeer,pubsock,myipaddr,myport,0,0,1,G.LP_sessionid); + LP_mypeer = mypeer = LP_addpeer(mypeer,pubsock,myipaddr,myport,pushport,subport,1,G.LP_sessionid); if ( myipaddr == 0 || mypeer == 0 ) { printf("couldnt get myipaddr or null mypeer.%p\n",mypeer); @@ -739,9 +739,9 @@ void LP_initpeers(int32_t pubsock,struct LP_peerinfo *mypeer,char *myipaddr,uint } if ( seednode == 0 || seednode[0] == 0 ) { - LP_addpeer(mypeer,pubsock,"51.15.86.136",myport,pushport,subport,0,G.LP_sessionid); + //LP_addpeer(mypeer,pubsock,"51.15.86.136",myport,pushport,subport,0,G.LP_sessionid); OS_randombytes((void *)&r,sizeof(r)); - r = 0; + //r = 0; for (j=0; j Date: Thu, 9 Nov 2017 12:46:05 +0200 Subject: [PATCH 0418/1664] Test --- iguana/exchanges/LP_nativeDEX.c | 2 +- iguana/exchanges/LP_network.c | 2 +- iguana/exchanges/LP_signatures.c | 10 +++++++++- 3 files changed, 11 insertions(+), 3 deletions(-) diff --git a/iguana/exchanges/LP_nativeDEX.c b/iguana/exchanges/LP_nativeDEX.c index c5b941456..ae68703a5 100644 --- a/iguana/exchanges/LP_nativeDEX.c +++ b/iguana/exchanges/LP_nativeDEX.c @@ -121,7 +121,7 @@ struct LP_globals uint64_t LP_skipstatus[10000]; uint8_t LP_myrmd160[20],LP_pubsecp[33]; uint32_t LP_sessionid,counter; - int32_t LP_pendingswaps,USERPASS_COUNTER,LP_numprivkeys,initializing,waiting,LP_numskips; + int32_t LP_IAMLP,LP_pendingswaps,USERPASS_COUNTER,LP_numprivkeys,initializing,waiting,LP_numskips; char USERPASS[65],USERPASS_WIFSTR[64],LP_myrmd160str[41],gui[16]; struct LP_privkey LP_privkeys[100]; } G; diff --git a/iguana/exchanges/LP_network.c b/iguana/exchanges/LP_network.c index a058f1aa6..eca82ba3c 100644 --- a/iguana/exchanges/LP_network.c +++ b/iguana/exchanges/LP_network.c @@ -408,7 +408,7 @@ void LP_broadcast_finish(int32_t pubsock,char *base,char *rel,uint8_t *msg,cJSON msglen = (int32_t)strlen((char *)msg) + 1; if ( crc32 == 0 ) crc32 = calc_crc32(0,&msg[2],msglen - 2); - if ( IAMLP == 0 ) + if ( G.LP_IAMLP == 0 ) { free(msg); //printf("broadcast %s\n",jstr(argjson,"method")); diff --git a/iguana/exchanges/LP_signatures.c b/iguana/exchanges/LP_signatures.c index c8552a02b..515ead03b 100644 --- a/iguana/exchanges/LP_signatures.c +++ b/iguana/exchanges/LP_signatures.c @@ -589,7 +589,15 @@ char *LP_notify_recv(cJSON *argjson) LP_pubkey_sigcheck(pubp,argjson); if ( (ipaddr= jstr(argjson,"isLP")) != 0 ) { - //printf("notify from isLP %s\n",ipaddr); + printf("notify got isLP %s\n",ipaddr); + if ( strcmp(ipaddr,LP_myipaddr) == 0 ) + { + if ( bits256_cmp(pub,G.LP_mypub25519) != 0 ) + { + char str[65]; printf("that's me! and it is from %s which isnt me\n",bits256_str(str,pub)); + G.LP_IAMLP = 1; + } + } LP_addpeer(LP_mypeer,LP_mypubsock,ipaddr,RPC_port,RPC_port+10,RPC_port+20,1,juint(argjson,"session")); } //char str[65]; printf("%.3f NOTIFIED pub %s rmd160 %s\n",OS_milliseconds()-millis,bits256_str(str,pub),rmd160str); From ceef97e9d57cf53469ef8cd129c8b76df6347717 Mon Sep 17 00:00:00 2001 From: jl777 Date: Thu, 9 Nov 2017 12:49:51 +0200 Subject: [PATCH 0419/1664] Test --- iguana/exchanges/LP_nativeDEX.c | 25 +++++++++++++------------ 1 file changed, 13 insertions(+), 12 deletions(-) diff --git a/iguana/exchanges/LP_nativeDEX.c b/iguana/exchanges/LP_nativeDEX.c index ae68703a5..0750000e9 100644 --- a/iguana/exchanges/LP_nativeDEX.c +++ b/iguana/exchanges/LP_nativeDEX.c @@ -90,18 +90,6 @@ struct iguana_info *LP_coins; struct LP_pubkeyinfo *LP_pubkeyinfos; struct rpcrequest_info *LP_garbage_collector; -#include "LP_network.c" - -char *activecoins[] = { "BTC", "KMD" }; -char GLOBAL_DBDIR[] = { "DB" }; -char LP_myipaddr[64],LP_publicaddr[64],USERHOME[512] = { "/root" }; -char LP_gui[16] = { "cli" }; - -char *default_LPnodes[] = { "5.9.253.195", "5.9.253.196", "5.9.253.197", "5.9.253.198", "5.9.253.199", "5.9.253.200", "5.9.253.201", "5.9.253.202", "5.9.253.203", - //"24.54.206.138", "173.212.225.176", "136.243.45.140", "107.72.162.127", "72.50.16.86", "51.15.202.191", "173.228.198.88", - "51.15.203.171", "51.15.86.136", "51.15.94.249", "51.15.80.18", "51.15.91.40", "51.15.54.2", "51.15.86.31", "51.15.82.29", "51.15.89.155", -};//"5.9.253.204" }; // - //uint32_t LP_deadman_switch; uint16_t LP_fixed_pairport,LP_publicport; @@ -126,6 +114,19 @@ struct LP_globals struct LP_privkey LP_privkeys[100]; } G; +#include "LP_network.c" + +char *activecoins[] = { "BTC", "KMD" }; +char GLOBAL_DBDIR[] = { "DB" }; +char LP_myipaddr[64],LP_publicaddr[64],USERHOME[512] = { "/root" }; +char LP_gui[16] = { "cli" }; + +char *default_LPnodes[] = { "5.9.253.195", "5.9.253.196", "5.9.253.197", "5.9.253.198", "5.9.253.199", "5.9.253.200", "5.9.253.201", "5.9.253.202", "5.9.253.203", + //"24.54.206.138", "173.212.225.176", "136.243.45.140", "107.72.162.127", "72.50.16.86", "51.15.202.191", "173.228.198.88", + "51.15.203.171", "51.15.86.136", "51.15.94.249", "51.15.80.18", "51.15.91.40", "51.15.54.2", "51.15.86.31", "51.15.82.29", "51.15.89.155", +};//"5.9.253.204" }; // + + // stubs void tradebot_swap_balancingtrade(struct basilisk_swap *swap,int32_t iambob) From 559338a0bbd1a254f816ea7fd8af21d23f53f60e Mon Sep 17 00:00:00 2001 From: jl777 Date: Thu, 9 Nov 2017 13:10:12 +0200 Subject: [PATCH 0420/1664] Test --- iguana/exchanges/LP_include.h | 2 +- iguana/exchanges/LP_nativeDEX.c | 44 ++---------------------------- iguana/exchanges/LP_peers.c | 25 +++++++++++++++++ iguana/exchanges/LP_signatures.c | 7 +++-- iguana/exchanges/LP_statemachine.c | 35 ++++++++++++++++++++++++ 5 files changed, 68 insertions(+), 45 deletions(-) diff --git a/iguana/exchanges/LP_include.h b/iguana/exchanges/LP_include.h index b1fd07fe9..8c006a01a 100644 --- a/iguana/exchanges/LP_include.h +++ b/iguana/exchanges/LP_include.h @@ -313,7 +313,7 @@ struct LP_peerinfo { UT_hash_handle hh; uint64_t ip_port; - uint32_t ipbits,errortime,errors,numpeers,needping,lasttime,connected,lastutxos,lastpeers,diduquery,good,sessionid; + uint32_t numrecv,ipbits,errortime,errors,numpeers,needping,lasttime,connected,lastutxos,lastpeers,diduquery,good,sessionid; int32_t pushsock,subsock,isLP; uint16_t port; char ipaddr[64]; diff --git a/iguana/exchanges/LP_nativeDEX.c b/iguana/exchanges/LP_nativeDEX.c index 0750000e9..3cd010478 100644 --- a/iguana/exchanges/LP_nativeDEX.c +++ b/iguana/exchanges/LP_nativeDEX.c @@ -18,8 +18,9 @@ // LP_nativeDEX.c // marketmaker // -// dynamic adding of new LP node +// detecting new deposits in inventory // BTC swaps +// bot progress // swap started event for bot // lack of full depth // withdraw too big @@ -1100,12 +1101,7 @@ void LPinit(uint16_t myport,uint16_t mypullport,uint16_t mypubport,uint16_t mybu printf("error launching LP_swapsloop for port.%u\n",myport); exit(-1); } - /*char request[128]; - if ( IAMLP == 0 ) - sprintf(request,"{\"method\":\"getpeers\",\"timestamp\":%u}",(uint32_t)time(NULL)); - else sprintf(request,"{\"method\":\"getpeers\",\"LPnode\":\"%s\",\"timestamp\":%u}",myipaddr,(uint32_t)time(NULL)); - LP_reserved_msg(0,"","",G.LP_mypub25519,clonestr(request)); */ - int32_t nonz; //uint32_t lasthello = 0; + int32_t nonz; while ( 1 ) { nonz = 0; @@ -1121,40 +1117,6 @@ void LPinit(uint16_t myport,uint16_t mypullport,uint16_t mypubport,uint16_t mybu usleep(1000); else if ( IAMLP == 0 ) usleep(1000); - /*if ( IAMLP != 0 && time(NULL) > lasthello+600 ) - { - char *hellostr,*retstr; cJSON *retjson; int32_t allgood,sock = LP_bindsock; - allgood = 0; - if ( (retstr= issue_hello(myport)) != 0 ) - { - if ( (retjson= cJSON_Parse(retstr)) != 0 ) - { - if ( (hellostr= jstr(retjson,"status")) != 0 && strcmp(hellostr,"got hello") == 0 ) - allgood = 1; - else printf("strange return.(%s)\n",jprint(retjson,0)); - free_json(retjson); - } else printf("couldnt parse hello return.(%s)\n",retstr); - free(retstr); - } else printf("issue_hello NULL return\n"); - lasthello = (uint32_t)time(NULL); - if ( allgood == 0 ) - { - printf("RPC port got stuck, would have close bindsocket\n"); - if ( 0 ) - { - LP_bindsock = -1; - closesocket(sock); - LP_bindsock_reset++; - sleep(10); - printf("launch new rpcloop\n"); - if ( OS_thread_create(malloc(sizeof(pthread_t)),NULL,(void *)stats_rpcloop,(void *)&myport) != 0 ) - { - printf("error launching stats rpcloop for port.%u\n",myport); - exit(-1); - } - } - } - }*/ } #endif } diff --git a/iguana/exchanges/LP_peers.c b/iguana/exchanges/LP_peers.c index 994880e1a..369b7618d 100644 --- a/iguana/exchanges/LP_peers.c +++ b/iguana/exchanges/LP_peers.c @@ -206,6 +206,12 @@ int32_t LP_coinbus(uint16_t coin_busport) return(bussock); } +void LP_peer_recv(char *ipaddr) +{ + struct LP_peerinfo *peer; + if ( (peer= LP_peerfind((uint32_t)calc_ipbits(ipaddr),RPC_port)) != 0 ) + peer->numrecv++; +} int32_t LP_numpeers() { @@ -242,3 +248,22 @@ uint16_t LP_randpeer(char *destip) } return(port); } + +uint16_t LP_rarestpeer(char *destip) +{ + struct LP_peerinfo *peer,*tmp,*rarest = 0; + destip[0] = 0; + HASH_ITER(hh,LP_peerinfos,peer,tmp) + { + if ( peer->isLP != 0 ) + { + if ( rarest == 0 || peer->numrecv < rarest->numrecv ) + rarest = peer; + } + } + if ( rarest == 0 ) + LP_randpeer(destip); + else strcpy(destip,rarest->ipaddr); + return(rarest != 0 ? rarest->port : RPC_port); +} + diff --git a/iguana/exchanges/LP_signatures.c b/iguana/exchanges/LP_signatures.c index 515ead03b..b399fd8a9 100644 --- a/iguana/exchanges/LP_signatures.c +++ b/iguana/exchanges/LP_signatures.c @@ -571,7 +571,7 @@ void LP_notify_pubkeys(void *ctx,int32_t pubsock) LP_pubkey_sigadd(reqjson,timestamp,G.LP_privkey,G.LP_mypub25519,G.LP_myrmd160,G.LP_pubsecp); if ( IAMLP != 0 ) { - if ( LP_randpeer(LPipaddr) != 0 ) + if ( LP_rarestpeer(LPipaddr) != 0 ) jaddstr(reqjson,"isLP",LPipaddr); else printf("no LPipaddr\n"); } @@ -589,8 +589,9 @@ char *LP_notify_recv(cJSON *argjson) LP_pubkey_sigcheck(pubp,argjson); if ( (ipaddr= jstr(argjson,"isLP")) != 0 ) { - printf("notify got isLP %s\n",ipaddr); - if ( strcmp(ipaddr,LP_myipaddr) == 0 ) + //printf("notify got isLP %s\n",ipaddr); + LP_peer_recv(ipaddr); + if ( IAMLP != 0 && G.LP_IAMLP == 0 && strcmp(ipaddr,LP_myipaddr) == 0 ) { if ( bits256_cmp(pub,G.LP_mypub25519) != 0 ) { diff --git a/iguana/exchanges/LP_statemachine.c b/iguana/exchanges/LP_statemachine.c index e22b7890d..5f598052d 100644 --- a/iguana/exchanges/LP_statemachine.c +++ b/iguana/exchanges/LP_statemachine.c @@ -132,6 +132,41 @@ FILE *basilisk_swap_save(struct basilisk_swap *swap,bits256 privkey,struct basil }*/ return(fp); } +/*if ( IAMLP != 0 && time(NULL) > lasthello+600 ) + { + char *hellostr,*retstr; cJSON *retjson; int32_t allgood,sock = LP_bindsock; + allgood = 0; + if ( (retstr= issue_hello(myport)) != 0 ) + { + if ( (retjson= cJSON_Parse(retstr)) != 0 ) + { + if ( (hellostr= jstr(retjson,"status")) != 0 && strcmp(hellostr,"got hello") == 0 ) + allgood = 1; + else printf("strange return.(%s)\n",jprint(retjson,0)); + free_json(retjson); + } else printf("couldnt parse hello return.(%s)\n",retstr); + free(retstr); + } else printf("issue_hello NULL return\n"); + lasthello = (uint32_t)time(NULL); + if ( allgood == 0 ) + { + printf("RPC port got stuck, would have close bindsocket\n"); + if ( 0 ) + { + LP_bindsock = -1; + closesocket(sock); + LP_bindsock_reset++; + sleep(10); + printf("launch new rpcloop\n"); + if ( OS_thread_create(malloc(sizeof(pthread_t)),NULL,(void *)stats_rpcloop,(void *)&myport) != 0 ) + { + printf("error launching stats rpcloop for port.%u\n",myport); + exit(-1); + } + } + } + }*/ + #ifdef oldway int32_t LP_peersparse(struct LP_peerinfo *mypeer,int32_t mypubsock,char *destipaddr,uint16_t destport,char *retstr,uint32_t now) { From a9ed99e47fbe0eb4d6f2324fd15603052cc15906 Mon Sep 17 00:00:00 2001 From: jl777 Date: Thu, 9 Nov 2017 13:17:05 +0200 Subject: [PATCH 0421/1664] Test --- iguana/exchanges/LP_nativeDEX.c | 45 ++---------------------------- iguana/exchanges/LP_statemachine.c | 41 +++++++++++++++++++++++++++ 2 files changed, 43 insertions(+), 43 deletions(-) diff --git a/iguana/exchanges/LP_nativeDEX.c b/iguana/exchanges/LP_nativeDEX.c index 3cd010478..1b0aa2220 100644 --- a/iguana/exchanges/LP_nativeDEX.c +++ b/iguana/exchanges/LP_nativeDEX.c @@ -122,9 +122,9 @@ char GLOBAL_DBDIR[] = { "DB" }; char LP_myipaddr[64],LP_publicaddr[64],USERHOME[512] = { "/root" }; char LP_gui[16] = { "cli" }; -char *default_LPnodes[] = { "5.9.253.195", "5.9.253.196", "5.9.253.197", "5.9.253.198", "5.9.253.199", "5.9.253.200", "5.9.253.201", "5.9.253.202", "5.9.253.203", +char *default_LPnodes[] = { "5.9.253.195", "5.9.253.196", "5.9.253.197", "5.9.253.198", //"5.9.253.199", "5.9.253.200", "5.9.253.201", "5.9.253.202", "5.9.253.203", //"24.54.206.138", "173.212.225.176", "136.243.45.140", "107.72.162.127", "72.50.16.86", "51.15.202.191", "173.228.198.88", - "51.15.203.171", "51.15.86.136", "51.15.94.249", "51.15.80.18", "51.15.91.40", "51.15.54.2", "51.15.86.31", "51.15.82.29", "51.15.89.155", + "51.15.203.171", "51.15.86.136", //"51.15.94.249", "51.15.80.18", "51.15.91.40", "51.15.54.2", "51.15.86.31", "51.15.82.29", "51.15.89.155", };//"5.9.253.204" }; // @@ -610,47 +610,6 @@ int32_t LP_mainloop_iter(void *ctx,char *myipaddr,struct LP_peerinfo *mypeer,int origipaddr = "127.0.0.1"; if ( mypeer == 0 ) myipaddr = "127.0.0.1"; - /* - now = (uint32_t)time(NULL); - numpeers = LP_numpeers(); - needpings = 0; - HASH_ITER(hh,LP_peerinfos,peer,tmp) - { - if ( peer->errors >= LP_MAXPEER_ERRORS ) - { - if ( (rand() % 10000) == 0 ) - { - peer->errors--; - if ( peer->errors < LP_MAXPEER_ERRORS ) - peer->diduquery = 0; - } - if ( IAMLP == 0 ) - continue; - } - if ( now > peer->lastpeers+LP_ORDERBOOK_DURATION*.777 || (rand() % 100000) == 0 ) - { - if ( strcmp(peer->ipaddr,myipaddr) != 0 ) - { - nonz++; - //issue_LP_getpeers(peer->ipaddr,peer->port); - //LP_peersquery(mypeer,pubsock,peer->ipaddr,peer->port,myipaddr,myport); - //if ( peer->diduquery == 0 ) - // LP_peer_pricesquery(peer); - //LP_utxos_sync(peer); - needpings++; - } - peer->lastpeers = now; - } - if ( peer->needping != 0 ) - { - peer->diduquery = now; - nonz++; - if ( (retstr= issue_LP_notify(peer->ipaddr,peer->port,"127.0.0.1",0,numpeers,G.LP_sessionid,G.LP_myrmd160str,G.LP_mypub25519)) != 0 ) - free(retstr); - peer->needping = 0; - needpings++; - } - }*/ HASH_ITER(hh,LP_coins,coin,ctmp) // firstrefht,firstscanht,lastscanht { if ( coin->addr_listunspent_requested != 0 && time(NULL) > coin->lastpushtime+LP_ORDERBOOK_DURATION ) diff --git a/iguana/exchanges/LP_statemachine.c b/iguana/exchanges/LP_statemachine.c index 5f598052d..6bb33ffcc 100644 --- a/iguana/exchanges/LP_statemachine.c +++ b/iguana/exchanges/LP_statemachine.c @@ -166,6 +166,47 @@ FILE *basilisk_swap_save(struct basilisk_swap *swap,bits256 privkey,struct basil } } }*/ +/* + now = (uint32_t)time(NULL); + numpeers = LP_numpeers(); + needpings = 0; + HASH_ITER(hh,LP_peerinfos,peer,tmp) + { + if ( peer->errors >= LP_MAXPEER_ERRORS ) + { + if ( (rand() % 10000) == 0 ) + { + peer->errors--; + if ( peer->errors < LP_MAXPEER_ERRORS ) + peer->diduquery = 0; + } + if ( IAMLP == 0 ) + continue; + } + if ( now > peer->lastpeers+LP_ORDERBOOK_DURATION*.777 || (rand() % 100000) == 0 ) + { + if ( strcmp(peer->ipaddr,myipaddr) != 0 ) + { + nonz++; + //issue_LP_getpeers(peer->ipaddr,peer->port); + //LP_peersquery(mypeer,pubsock,peer->ipaddr,peer->port,myipaddr,myport); + //if ( peer->diduquery == 0 ) + // LP_peer_pricesquery(peer); + //LP_utxos_sync(peer); + needpings++; + } + peer->lastpeers = now; + } + if ( peer->needping != 0 ) + { + peer->diduquery = now; + nonz++; + if ( (retstr= issue_LP_notify(peer->ipaddr,peer->port,"127.0.0.1",0,numpeers,G.LP_sessionid,G.LP_myrmd160str,G.LP_mypub25519)) != 0 ) + free(retstr); + peer->needping = 0; + needpings++; + } + }*/ #ifdef oldway int32_t LP_peersparse(struct LP_peerinfo *mypeer,int32_t mypubsock,char *destipaddr,uint16_t destport,char *retstr,uint32_t now) From bce640911609585ca8da9dc52bb46e16876a3187 Mon Sep 17 00:00:00 2001 From: jl777 Date: Thu, 9 Nov 2017 13:46:22 +0200 Subject: [PATCH 0422/1664] Test --- iguana/exchanges/LP_include.h | 2 +- iguana/exchanges/LP_nativeDEX.c | 1 + iguana/exchanges/LP_ordermatch.c | 2 +- iguana/exchanges/LP_peers.c | 24 ++++++++++++++++++------ iguana/exchanges/LP_signatures.c | 6 +++++- 5 files changed, 26 insertions(+), 9 deletions(-) diff --git a/iguana/exchanges/LP_include.h b/iguana/exchanges/LP_include.h index 8c006a01a..12e801063 100644 --- a/iguana/exchanges/LP_include.h +++ b/iguana/exchanges/LP_include.h @@ -313,7 +313,7 @@ struct LP_peerinfo { UT_hash_handle hh; uint64_t ip_port; - uint32_t numrecv,ipbits,errortime,errors,numpeers,needping,lasttime,connected,lastutxos,lastpeers,diduquery,good,sessionid; + uint32_t recvtime,numrecv,ipbits,errortime,errors,numpeers,needping,lasttime,connected,lastutxos,lastpeers,diduquery,good,sessionid; int32_t pushsock,subsock,isLP; uint16_t port; char ipaddr[64]; diff --git a/iguana/exchanges/LP_nativeDEX.c b/iguana/exchanges/LP_nativeDEX.c index 1b0aa2220..afee51f50 100644 --- a/iguana/exchanges/LP_nativeDEX.c +++ b/iguana/exchanges/LP_nativeDEX.c @@ -21,6 +21,7 @@ // detecting new deposits in inventory // BTC swaps // bot progress +// will stale peers ever die? // swap started event for bot // lack of full depth // withdraw too big diff --git a/iguana/exchanges/LP_ordermatch.c b/iguana/exchanges/LP_ordermatch.c index 30d3a8cb9..68f113732 100644 --- a/iguana/exchanges/LP_ordermatch.c +++ b/iguana/exchanges/LP_ordermatch.c @@ -453,7 +453,7 @@ void LP_reserved(void *ctx,char *myipaddr,int32_t mypubsock,struct LP_quoteinfo Alice_expiration = 0; LP_query(ctx,myipaddr,mypubsock,"connect",qp); } - } else printf("reject reserved due to not eligible.%d or mismatched quote price %.8f vs maxprice %.8f\n",LP_alice_eligible(),price,maxprice); + } else printf("probably a timeout, reject reserved due to not eligible.%d or mismatched quote price %.8f vs maxprice %.8f\n",LP_alice_eligible(),price,maxprice); } char *LP_connectedalice(cJSON *argjson) // alice diff --git a/iguana/exchanges/LP_peers.c b/iguana/exchanges/LP_peers.c index 369b7618d..f7549a6a6 100644 --- a/iguana/exchanges/LP_peers.c +++ b/iguana/exchanges/LP_peers.c @@ -206,11 +206,15 @@ int32_t LP_coinbus(uint16_t coin_busport) return(bussock); } -void LP_peer_recv(char *ipaddr) +void LP_peer_recv(char *ipaddr,int32_t ismine) { struct LP_peerinfo *peer; if ( (peer= LP_peerfind((uint32_t)calc_ipbits(ipaddr),RPC_port)) != 0 ) + { peer->numrecv++; + if ( ismine != 0 ) + peer->recvtime = (uint32_t)time(NULL); + } } int32_t LP_numpeers() @@ -251,15 +255,23 @@ uint16_t LP_randpeer(char *destip) uint16_t LP_rarestpeer(char *destip) { - struct LP_peerinfo *peer,*tmp,*rarest = 0; + struct LP_peerinfo *peer,*tmp,*rarest = 0; int32_t iter; uint32_t now; + now = (uint32_t)time(NULL); destip[0] = 0; - HASH_ITER(hh,LP_peerinfos,peer,tmp) + for (iter=0; iter<2; iter++) { - if ( peer->isLP != 0 ) + HASH_ITER(hh,LP_peerinfos,peer,tmp) { - if ( rarest == 0 || peer->numrecv < rarest->numrecv ) - rarest = peer; + if ( iter == 0 && peer->recvtime < now-3600 ) + continue; + if ( peer->isLP != 0 ) + { + if ( rarest == 0 || peer->numrecv < rarest->numrecv ) + rarest = peer; + } } + if ( rarest != 0 ) + break; } if ( rarest == 0 ) LP_randpeer(destip); diff --git a/iguana/exchanges/LP_signatures.c b/iguana/exchanges/LP_signatures.c index b399fd8a9..dd099c919 100644 --- a/iguana/exchanges/LP_signatures.c +++ b/iguana/exchanges/LP_signatures.c @@ -572,7 +572,11 @@ void LP_notify_pubkeys(void *ctx,int32_t pubsock) if ( IAMLP != 0 ) { if ( LP_rarestpeer(LPipaddr) != 0 ) + { jaddstr(reqjson,"isLP",LPipaddr); + if ( strcmp(LPipaddr,LP_myipaddr) == 0 ) + jaddnum(reqjson,"ismine",1); + } else printf("no LPipaddr\n"); } jaddnum(reqjson,"session",G.LP_sessionid); @@ -590,7 +594,7 @@ char *LP_notify_recv(cJSON *argjson) if ( (ipaddr= jstr(argjson,"isLP")) != 0 ) { //printf("notify got isLP %s\n",ipaddr); - LP_peer_recv(ipaddr); + LP_peer_recv(ipaddr,jint(argjson,ismine)); if ( IAMLP != 0 && G.LP_IAMLP == 0 && strcmp(ipaddr,LP_myipaddr) == 0 ) { if ( bits256_cmp(pub,G.LP_mypub25519) != 0 ) From f485a93851b6c15607d78f586fd18bb225b35605 Mon Sep 17 00:00:00 2001 From: jl777 Date: Thu, 9 Nov 2017 13:49:35 +0200 Subject: [PATCH 0423/1664] Test --- iguana/exchanges/LP_peers.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/iguana/exchanges/LP_peers.c b/iguana/exchanges/LP_peers.c index f7549a6a6..f73ade5ec 100644 --- a/iguana/exchanges/LP_peers.c +++ b/iguana/exchanges/LP_peers.c @@ -262,7 +262,7 @@ uint16_t LP_rarestpeer(char *destip) { HASH_ITER(hh,LP_peerinfos,peer,tmp) { - if ( iter == 0 && peer->recvtime < now-3600 ) + if ( iter == 0 && peer->recvtime < now-3600*24 ) continue; if ( peer->isLP != 0 ) { From 5bfa0fb4225327fe3e434f4630ba96af975c0f6a Mon Sep 17 00:00:00 2001 From: jl777 Date: Thu, 9 Nov 2017 13:51:22 +0200 Subject: [PATCH 0424/1664] Test --- iguana/exchanges/LP_signatures.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/iguana/exchanges/LP_signatures.c b/iguana/exchanges/LP_signatures.c index dd099c919..9e9e00520 100644 --- a/iguana/exchanges/LP_signatures.c +++ b/iguana/exchanges/LP_signatures.c @@ -593,8 +593,8 @@ char *LP_notify_recv(cJSON *argjson) LP_pubkey_sigcheck(pubp,argjson); if ( (ipaddr= jstr(argjson,"isLP")) != 0 ) { - //printf("notify got isLP %s\n",ipaddr); - LP_peer_recv(ipaddr,jint(argjson,ismine)); + //printf("notify got isLP %s %d\n",ipaddr,jint(argjson,"isming")); + LP_peer_recv(ipaddr,jint(argjson,"ismine")); if ( IAMLP != 0 && G.LP_IAMLP == 0 && strcmp(ipaddr,LP_myipaddr) == 0 ) { if ( bits256_cmp(pub,G.LP_mypub25519) != 0 ) From 01d2480c37a6f970c4bcb4b029b82dc8769c5c0f Mon Sep 17 00:00:00 2001 From: jl777 Date: Thu, 9 Nov 2017 13:52:02 +0200 Subject: [PATCH 0425/1664] Test --- iguana/exchanges/LP_signatures.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/iguana/exchanges/LP_signatures.c b/iguana/exchanges/LP_signatures.c index 9e9e00520..0182b6777 100644 --- a/iguana/exchanges/LP_signatures.c +++ b/iguana/exchanges/LP_signatures.c @@ -593,7 +593,7 @@ char *LP_notify_recv(cJSON *argjson) LP_pubkey_sigcheck(pubp,argjson); if ( (ipaddr= jstr(argjson,"isLP")) != 0 ) { - //printf("notify got isLP %s %d\n",ipaddr,jint(argjson,"isming")); + printf("notify got isLP %s %d\n",ipaddr,jint(argjson,"isming")); LP_peer_recv(ipaddr,jint(argjson,"ismine")); if ( IAMLP != 0 && G.LP_IAMLP == 0 && strcmp(ipaddr,LP_myipaddr) == 0 ) { From 1981dd5e00a0e5877052658a81adfbd740884ce3 Mon Sep 17 00:00:00 2001 From: jl777 Date: Thu, 9 Nov 2017 14:03:57 +0200 Subject: [PATCH 0426/1664] Test --- iguana/exchanges/LP_nativeDEX.c | 3 +-- iguana/exchanges/LP_signatures.c | 2 +- 2 files changed, 2 insertions(+), 3 deletions(-) diff --git a/iguana/exchanges/LP_nativeDEX.c b/iguana/exchanges/LP_nativeDEX.c index afee51f50..16a1123ed 100644 --- a/iguana/exchanges/LP_nativeDEX.c +++ b/iguana/exchanges/LP_nativeDEX.c @@ -21,9 +21,8 @@ // detecting new deposits in inventory // BTC swaps // bot progress -// will stale peers ever die? +// will stale peers ever die? <- after a day it should // swap started event for bot -// lack of full depth // withdraw too big // bot status 1600% ? // BCH signing diff --git a/iguana/exchanges/LP_signatures.c b/iguana/exchanges/LP_signatures.c index 0182b6777..da0279b57 100644 --- a/iguana/exchanges/LP_signatures.c +++ b/iguana/exchanges/LP_signatures.c @@ -593,7 +593,7 @@ char *LP_notify_recv(cJSON *argjson) LP_pubkey_sigcheck(pubp,argjson); if ( (ipaddr= jstr(argjson,"isLP")) != 0 ) { - printf("notify got isLP %s %d\n",ipaddr,jint(argjson,"isming")); + printf("notify got isLP %s %d\n",ipaddr,jint(argjson,"ismine")); LP_peer_recv(ipaddr,jint(argjson,"ismine")); if ( IAMLP != 0 && G.LP_IAMLP == 0 && strcmp(ipaddr,LP_myipaddr) == 0 ) { From ec01d0a02ec19c18e8b976859cb74f97cbe0656b Mon Sep 17 00:00:00 2001 From: jl777 Date: Thu, 9 Nov 2017 14:08:48 +0200 Subject: [PATCH 0427/1664] Test --- iguana/exchanges/LP_signatures.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/iguana/exchanges/LP_signatures.c b/iguana/exchanges/LP_signatures.c index da0279b57..58590cae7 100644 --- a/iguana/exchanges/LP_signatures.c +++ b/iguana/exchanges/LP_signatures.c @@ -593,7 +593,7 @@ char *LP_notify_recv(cJSON *argjson) LP_pubkey_sigcheck(pubp,argjson); if ( (ipaddr= jstr(argjson,"isLP")) != 0 ) { - printf("notify got isLP %s %d\n",ipaddr,jint(argjson,"ismine")); + //printf("notify got isLP %s %d\n",ipaddr,jint(argjson,"ismine")); LP_peer_recv(ipaddr,jint(argjson,"ismine")); if ( IAMLP != 0 && G.LP_IAMLP == 0 && strcmp(ipaddr,LP_myipaddr) == 0 ) { From d0941cd6a4f5e3814569208bae21dfbd40d95f5b Mon Sep 17 00:00:00 2001 From: jl777 Date: Thu, 9 Nov 2017 14:11:42 +0200 Subject: [PATCH 0428/1664] Test --- iguana/exchanges/LP_nativeDEX.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/iguana/exchanges/LP_nativeDEX.c b/iguana/exchanges/LP_nativeDEX.c index 16a1123ed..cc83f34a5 100644 --- a/iguana/exchanges/LP_nativeDEX.c +++ b/iguana/exchanges/LP_nativeDEX.c @@ -124,7 +124,7 @@ char LP_gui[16] = { "cli" }; char *default_LPnodes[] = { "5.9.253.195", "5.9.253.196", "5.9.253.197", "5.9.253.198", //"5.9.253.199", "5.9.253.200", "5.9.253.201", "5.9.253.202", "5.9.253.203", //"24.54.206.138", "173.212.225.176", "136.243.45.140", "107.72.162.127", "72.50.16.86", "51.15.202.191", "173.228.198.88", - "51.15.203.171", "51.15.86.136", //"51.15.94.249", "51.15.80.18", "51.15.91.40", "51.15.54.2", "51.15.86.31", "51.15.82.29", "51.15.89.155", + "51.15.203.171", "51.15.86.136", "51.15.94.249", "51.15.80.18", "51.15.91.40", "51.15.54.2", "51.15.86.31", "51.15.82.29", "51.15.89.155", };//"5.9.253.204" }; // From 76d202bc3e9f0d0e4e873ac9a4023061b9239bd2 Mon Sep 17 00:00:00 2001 From: jl777 Date: Thu, 9 Nov 2017 14:58:37 +0200 Subject: [PATCH 0429/1664] Test --- iguana/exchanges/LP_transaction.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/iguana/exchanges/LP_transaction.c b/iguana/exchanges/LP_transaction.c index a2042aab3..424925b2e 100644 --- a/iguana/exchanges/LP_transaction.c +++ b/iguana/exchanges/LP_transaction.c @@ -965,7 +965,7 @@ int32_t LP_vins_select(void *ctx,struct iguana_info *coin,int64_t *totalp,int64_ interest = 0; if ( up->U.height < 7777777 && strcmp(coin->symbol,"KMD") == 0 ) { - if ( (interest= LP_komodo_interest(up->U.txid,up->U.value)) > 0 ) + if ( 0 && (interest= LP_komodo_interest(up->U.txid,up->U.value)) > 0 ) { interestsum += interest; char str[65]; printf("%s/%d %.8f interest %.8f -> sum %.8f\n",bits256_str(str,up->U.txid),up->U.vout,dstr(up->U.value),dstr(interest),dstr(interestsum)); From 4d47ff29eaa7003f36e2112a91e174661876665f Mon Sep 17 00:00:00 2001 From: jl777 Date: Thu, 9 Nov 2017 15:16:21 +0200 Subject: [PATCH 0430/1664] Test --- iguana/exchanges/LP_tradebots.c | 16 +++++++++------- 1 file changed, 9 insertions(+), 7 deletions(-) diff --git a/iguana/exchanges/LP_tradebots.c b/iguana/exchanges/LP_tradebots.c index d58c870eb..0d574756f 100644 --- a/iguana/exchanges/LP_tradebots.c +++ b/iguana/exchanges/LP_tradebots.c @@ -414,7 +414,7 @@ char *LP_tradebot_statuslist(void *ctx,int32_t pubsock,cJSON *argjson) char *LP_tradebot_buy(int32_t dispdir,char *base,char *rel,double maxprice,double relvolume) { - struct LP_tradebot *bot; char *retstr; double shortfall; int32_t i,n; cJSON *array,*item,*retjson; uint64_t txfees,balance=0,abalance=0; struct iguana_info *basecoin,*relcoin; + struct LP_tradebot *bot; char *retstr; double shortfall; int32_t i,n; cJSON *array,*item,*retjson; uint64_t sum,txfee,txfees,balance=0,abalance=0; struct iguana_info *basecoin,*relcoin; basecoin = LP_coinfind(base); relcoin = LP_coinfind(rel); if ( basecoin == 0 || relcoin == 0 || basecoin->inactive != 0 || relcoin->inactive != 0 ) @@ -433,7 +433,8 @@ char *LP_tradebot_buy(int32_t dispdir,char *base,char *rel,double maxprice,doubl } if ( (retstr= LP_orderbook(base,rel,0)) != 0 ) free(retstr); - txfees = 10 * relcoin->txfee; + txfee = LP_txfeecalc(relcoin,0,0); + txfees = 10 * txfee; printf("%s inventory balance %.8f, relvolume %.8f + txfees %.8f\n",rel,dstr(abalance),relvolume,dstr(txfees)); if ( dstr(abalance) < relvolume + dstr(txfees) ) { @@ -449,22 +450,23 @@ char *LP_tradebot_buy(int32_t dispdir,char *base,char *rel,double maxprice,doubl jaddnum(retjson,"txfees",dstr(txfees)); shortfall = (relvolume + dstr(txfees)) - dstr(balance); jaddnum(retjson,"shortfall",shortfall); - if ( balance > (relvolume + 10*relvolume/777.) ) + sum = (relvolume+2*dstr(txfees)) + 3 * ((relvolume+2*dstr(txfees))/777); + if ( balance >= sum+txfee ) { char *withdrawstr; cJSON *outputjson,*withdrawjson,*outputs,*item; outputjson = cJSON_CreateObject(); outputs = cJSON_CreateArray(); item = cJSON_CreateObject(); - jaddnum(item,relcoin->smartaddr,relvolume+dstr(txfees)); + jaddnum(item,relcoin->smartaddr,relvolume+2*dstr(txfees)); jaddi(outputs,item); item = cJSON_CreateObject(); - jaddnum(item,relcoin->smartaddr,(relvolume+dstr(txfees))/777); + jaddnum(item,relcoin->smartaddr,(relvolume+2*dstr(txfees))/777); jaddi(outputs,item); item = cJSON_CreateObject(); - jaddnum(item,relcoin->smartaddr,(relvolume+dstr(txfees))/777); + jaddnum(item,relcoin->smartaddr,(relvolume+2*dstr(txfees))/777); jaddi(outputs,item); item = cJSON_CreateObject(); - jaddnum(item,relcoin->smartaddr,(relvolume+dstr(txfees))/777); + jaddnum(item,relcoin->smartaddr,(relvolume+2*dstr(txfees))/777); jaddi(outputs,item); jadd(outputjson,"outputs",outputs); if ( (withdrawstr= LP_withdraw(relcoin,outputjson)) != 0 ) From bdc01eb1336c6b3ad88ebf2f9f0335bbef6b161a Mon Sep 17 00:00:00 2001 From: jl777 Date: Thu, 9 Nov 2017 15:41:49 +0200 Subject: [PATCH 0431/1664] Test --- iguana/exchanges/LP_nativeDEX.c | 2 -- iguana/exchanges/LP_portfolio.c | 9 +++++++-- iguana/exchanges/install | 2 +- 3 files changed, 8 insertions(+), 5 deletions(-) diff --git a/iguana/exchanges/LP_nativeDEX.c b/iguana/exchanges/LP_nativeDEX.c index cc83f34a5..a76bd882c 100644 --- a/iguana/exchanges/LP_nativeDEX.c +++ b/iguana/exchanges/LP_nativeDEX.c @@ -21,9 +21,7 @@ // detecting new deposits in inventory // BTC swaps // bot progress -// will stale peers ever die? <- after a day it should // swap started event for bot -// withdraw too big // bot status 1600% ? // BCH signing // dPoW security -> 4: KMD notarized, 5: BTC notarized, after next notary elections diff --git a/iguana/exchanges/LP_portfolio.c b/iguana/exchanges/LP_portfolio.c index c36c64d67..87b50f474 100644 --- a/iguana/exchanges/LP_portfolio.c +++ b/iguana/exchanges/LP_portfolio.c @@ -222,7 +222,7 @@ struct LP_autoprice_ref int32_t LP_autoprice(char *base,char *rel,cJSON *argjson) { //curl --url "http://127.0.0.1:7783" --data "{\"userpass\":\"$userpass\",\"method\":\"autoprice\",\"base\":\"MNZ\",\"rel\":\"KMD\",\"offset\":0.1,\"refbase\":\"KMD\",\refrel\":\"BTC\",\"factor\":15000,\"margin\":0.01}" - struct LP_priceinfo *basepp,*relpp; int32_t i; char *refbase,*refrel; double minprice,margin,offset,factor,fixedprice; + struct LP_priceinfo *basepp,*relpp; int32_t i; char *refbase="",*refrel=""; double minprice,margin,offset,factor,fixedprice; //printf("autoprice.(%s %s) %s\n",base,rel,jprint(argjson,0)); if ( (basepp= LP_priceinfofind(base)) != 0 && (relpp= LP_priceinfofind(rel)) != 0 ) { @@ -238,8 +238,13 @@ int32_t LP_autoprice(char *base,char *rel,cJSON *argjson) basepp->margins[relpp->ind] = margin; basepp->offsets[relpp->ind] = offset; basepp->factors[relpp->ind] = factor; - if ( (refbase= jstr(argjson,"refbase")) != 0 && (refrel= jstr(argjson,"refrel")) != 0 ) + if ( fixedprice > SMALLVAL || ((refbase= jstr(argjson,"refbase")) != 0 && (refrel= jstr(argjson,"refrel")) != 0) ) { + if ( fixedprice > SMALLVAL ) + { + refbase = base; + refrel = rel; + } for (i=0; i Date: Thu, 9 Nov 2017 15:48:48 +0200 Subject: [PATCH 0432/1664] Test --- iguana/exchanges/LP_portfolio.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/iguana/exchanges/LP_portfolio.c b/iguana/exchanges/LP_portfolio.c index 87b50f474..dcbd52962 100644 --- a/iguana/exchanges/LP_portfolio.c +++ b/iguana/exchanges/LP_portfolio.c @@ -481,7 +481,7 @@ void LP_autoprice_iter(void *ctx,struct LP_priceinfo *btcpp) relpp = LP_priceinfofind(LP_autorefs[i].rel); if ( basepp != 0 && relpp != 0 ) { - //printf("check ref-autoprice %s/%s\n",LP_autorefs[i].refbase,LP_autorefs[i].refrel); + printf("check ref-autoprice %s/%s\n",LP_autorefs[i].refbase,LP_autorefs[i].refrel); LP_autopriceset(ctx,1,basepp,relpp,0.,LP_autorefs[i].refbase,LP_autorefs[i].refrel); } } @@ -646,7 +646,7 @@ void prices_loop(void *ctx) } free(retstr); } - sleep(120); + sleep(10); } } From 8b9d96dbca2cb26e472c5764aaecf4df98960e2a Mon Sep 17 00:00:00 2001 From: jl777 Date: Thu, 9 Nov 2017 15:53:43 +0200 Subject: [PATCH 0433/1664] Test --- iguana/exchanges/LP_portfolio.c | 1 + 1 file changed, 1 insertion(+) diff --git a/iguana/exchanges/LP_portfolio.c b/iguana/exchanges/LP_portfolio.c index dcbd52962..f73b8f290 100644 --- a/iguana/exchanges/LP_portfolio.c +++ b/iguana/exchanges/LP_portfolio.c @@ -608,6 +608,7 @@ void prices_loop(void *ctx) prices_loop_stats.threshold = 91000.; while ( 1 ) { + printf("prices loop autoprices.%d autorefs.%d\n",LP_autoprices,num_LP_autorefs); LP_millistats_update(&prices_loop_stats); LP_tradebots_timeslice(ctx); if ( (btcpp= LP_priceinfofind("BTC")) == 0 ) From 51ab35521bab983c70ffce4ddd05938fdbf1f079 Mon Sep 17 00:00:00 2001 From: jl777 Date: Thu, 9 Nov 2017 15:58:39 +0200 Subject: [PATCH 0434/1664] Test --- iguana/exchanges/LP_nativeDEX.c | 6 +++--- iguana/exchanges/LP_peers.c | 4 ++-- iguana/exchanges/LP_portfolio.c | 2 +- 3 files changed, 6 insertions(+), 6 deletions(-) diff --git a/iguana/exchanges/LP_nativeDEX.c b/iguana/exchanges/LP_nativeDEX.c index a76bd882c..df1033766 100644 --- a/iguana/exchanges/LP_nativeDEX.c +++ b/iguana/exchanges/LP_nativeDEX.c @@ -469,17 +469,17 @@ void LP_coinsloop(void *_coins) if ( strcmp("BTC",coins) == 0 ) { strcpy(LP_coinsloopBTC_stats.name,"BTC coin loop"); - LP_coinsloopBTC_stats.threshold = 2000.; + LP_coinsloopBTC_stats.threshold = 20000.; } else if ( strcmp("KMD",coins) == 0 ) { strcpy(LP_coinsloopKMD_stats.name,"KMD coin loop"); - LP_coinsloopKMD_stats.threshold = 1000.; + LP_coinsloopKMD_stats.threshold = 10000.; } else { strcpy(LP_coinsloop_stats.name,"other coins loop"); - LP_coinsloop_stats.threshold = 500.; + LP_coinsloop_stats.threshold = 5000.; } while ( 1 ) { diff --git a/iguana/exchanges/LP_peers.c b/iguana/exchanges/LP_peers.c index f73ade5ec..d4fcc603a 100644 --- a/iguana/exchanges/LP_peers.c +++ b/iguana/exchanges/LP_peers.c @@ -79,7 +79,7 @@ struct LP_peerinfo *LP_addpeer(struct LP_peerinfo *mypeer,int32_t mypubsock,char } else { - printf("addpeer (%s:%u) pushport.%u subport.%u\n",ipaddr,port,pushport,subport); + //printf("addpeer (%s:%u) pushport.%u subport.%u\n",ipaddr,port,pushport,subport); peer = calloc(1,sizeof(*peer)); if ( strcmp(peer->ipaddr,LP_myipaddr) == 0 ) peer->sessionid = G.LP_sessionid; @@ -143,7 +143,7 @@ struct LP_peerinfo *LP_addpeer(struct LP_peerinfo *mypeer,int32_t mypubsock,char } else printf("%s pushport.%u subport.%u pushsock.%d\n",ipaddr,pushport,subport,pushsock); if ( peer->pushsock >= 0 && peer->subsock >= 0 ) { - printf("add peer %s\n",peer->ipaddr); + //printf("add peer %s\n",peer->ipaddr); portable_mutex_lock(&LP_peermutex); HASH_ADD(hh,LP_peerinfos,ip_port,sizeof(peer->ip_port),peer); if ( mypeer != 0 ) diff --git a/iguana/exchanges/LP_portfolio.c b/iguana/exchanges/LP_portfolio.c index f73b8f290..60a69b860 100644 --- a/iguana/exchanges/LP_portfolio.c +++ b/iguana/exchanges/LP_portfolio.c @@ -481,7 +481,7 @@ void LP_autoprice_iter(void *ctx,struct LP_priceinfo *btcpp) relpp = LP_priceinfofind(LP_autorefs[i].rel); if ( basepp != 0 && relpp != 0 ) { - printf("check ref-autoprice %s/%s\n",LP_autorefs[i].refbase,LP_autorefs[i].refrel); + printf("check ref-autoprice %s/%s %f\n",LP_autorefs[i].refbase,LP_autorefs[i].refrel,relpp->fixedprices[basepp->ind]); LP_autopriceset(ctx,1,basepp,relpp,0.,LP_autorefs[i].refbase,LP_autorefs[i].refrel); } } From 94d2507f19954c95c4d99a2ecb0e977793d349d7 Mon Sep 17 00:00:00 2001 From: jl777 Date: Thu, 9 Nov 2017 16:04:37 +0200 Subject: [PATCH 0435/1664] Test --- iguana/exchanges/LP_nativeDEX.c | 2 +- iguana/exchanges/LP_portfolio.c | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/iguana/exchanges/LP_nativeDEX.c b/iguana/exchanges/LP_nativeDEX.c index df1033766..fa233ec68 100644 --- a/iguana/exchanges/LP_nativeDEX.c +++ b/iguana/exchanges/LP_nativeDEX.c @@ -716,7 +716,7 @@ void LP_pubkeysloop(void *ctx) { static uint32_t lasttime; cJSON *retjson; struct iguana_info *coin,*tmp; strcpy(LP_pubkeysloop_stats.name,"LP_pubkeysloop"); - LP_pubkeysloop_stats.threshold = 5000.; + LP_pubkeysloop_stats.threshold = 15000.; sleep(10); while ( 1 ) { diff --git a/iguana/exchanges/LP_portfolio.c b/iguana/exchanges/LP_portfolio.c index 60a69b860..3a98c01ee 100644 --- a/iguana/exchanges/LP_portfolio.c +++ b/iguana/exchanges/LP_portfolio.c @@ -481,7 +481,7 @@ void LP_autoprice_iter(void *ctx,struct LP_priceinfo *btcpp) relpp = LP_priceinfofind(LP_autorefs[i].rel); if ( basepp != 0 && relpp != 0 ) { - printf("check ref-autoprice %s/%s %f\n",LP_autorefs[i].refbase,LP_autorefs[i].refrel,relpp->fixedprices[basepp->ind]); + printf("check ref-autoprice %s/%s %f %f\n",LP_autorefs[i].refbase,LP_autorefs[i].refrel,relpp->fixedprices[basepp->ind],basepp->fixedprices[relpp->ind]); LP_autopriceset(ctx,1,basepp,relpp,0.,LP_autorefs[i].refbase,LP_autorefs[i].refrel); } } From e9b7dbb57177eae68094af08f2d073c1424987d5 Mon Sep 17 00:00:00 2001 From: jl777 Date: Thu, 9 Nov 2017 16:11:50 +0200 Subject: [PATCH 0436/1664] Test --- iguana/exchanges/LP_peers.c | 2 +- iguana/exchanges/LP_portfolio.c | 6 +++--- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/iguana/exchanges/LP_peers.c b/iguana/exchanges/LP_peers.c index d4fcc603a..e65d4806a 100644 --- a/iguana/exchanges/LP_peers.c +++ b/iguana/exchanges/LP_peers.c @@ -106,7 +106,7 @@ struct LP_peerinfo *LP_addpeer(struct LP_peerinfo *mypeer,int32_t mypubsock,char nn_setsockopt(pushsock,NN_SOL_SOCKET,NN_SNDTIMEO,&timeout,sizeof(timeout)); //maxsize = 2 * 1024 * 1024; //nn_setsockopt(pushsock,NN_SOL_SOCKET,NN_SNDBUF,&maxsize,sizeof(maxsize)); - printf("connected to push.(%s) pushsock.%d valid.%d\n",pushaddr,pushsock,valid); + printf("connected to push.(%s) pushsock.%d valid.%d | ",pushaddr,pushsock,valid); peer->connected = (uint32_t)time(NULL); peer->pushsock = pushsock; if ( (subsock= nn_socket(AF_SP,NN_SUB)) >= 0 ) diff --git a/iguana/exchanges/LP_portfolio.c b/iguana/exchanges/LP_portfolio.c index 3a98c01ee..a6fb61d34 100644 --- a/iguana/exchanges/LP_portfolio.c +++ b/iguana/exchanges/LP_portfolio.c @@ -242,8 +242,8 @@ int32_t LP_autoprice(char *base,char *rel,cJSON *argjson) { if ( fixedprice > SMALLVAL ) { - refbase = base; - refrel = rel; + refbase = rel; + refrel = base; } for (i=0; i Date: Thu, 9 Nov 2017 16:18:09 +0200 Subject: [PATCH 0437/1664] Test --- iguana/exchanges/LP_network.c | 2 +- iguana/exchanges/LP_portfolio.c | 7 +++++++ 2 files changed, 8 insertions(+), 1 deletion(-) diff --git a/iguana/exchanges/LP_network.c b/iguana/exchanges/LP_network.c index eca82ba3c..1112532ab 100644 --- a/iguana/exchanges/LP_network.c +++ b/iguana/exchanges/LP_network.c @@ -187,7 +187,7 @@ bits256 LP_calc_magic(uint8_t *msg,int32_t len) { if ( n > maxn ) { - printf("LP_calc_magic maxn.%d <- %d\n",maxn,n); + printf("LP_calc_magic maxn.%d <- %d | ",maxn,n); maxn = n; } printf("millis %.3f ave %.3f, aveiters %.1f\n",OS_milliseconds() - millis,sum/counter,(double)nsum/counter); diff --git a/iguana/exchanges/LP_portfolio.c b/iguana/exchanges/LP_portfolio.c index a6fb61d34..607853dea 100644 --- a/iguana/exchanges/LP_portfolio.c +++ b/iguana/exchanges/LP_portfolio.c @@ -284,6 +284,13 @@ void LP_autopriceset(void *ctx,int32_t dir,struct LP_priceinfo *basepp,struct LP LP_pricepings(ctx,LP_myipaddr,LP_mypubsock,relpp->symbol,basepp->symbol,fixedprice); return; } + else if ( (fixedprice= basepp->fixedprices[relpp->ind]) > SMALLVAL ) + { + LP_mypriceset(&changed,basepp->symbol,relpp->symbol,fixedprice); + printf("autoprice FIXED %s/%s <- %.8f\n",basepp->symbol,relpp->symbol,fixedprice); + LP_pricepings(ctx,LP_myipaddr,LP_mypubsock,basepp->symbol,relpp->symbol,fixedprice); + return; + } if ( margin != 0. || oppomargin != 0. ) { offset = basepp->offsets[relpp->ind]; From 836a2ce6ba5fe801ddd94d1894f94305133737ea Mon Sep 17 00:00:00 2001 From: jl777 Date: Thu, 9 Nov 2017 16:22:01 +0200 Subject: [PATCH 0438/1664] Test --- iguana/exchanges/LP_portfolio.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/iguana/exchanges/LP_portfolio.c b/iguana/exchanges/LP_portfolio.c index 607853dea..cd9ccab14 100644 --- a/iguana/exchanges/LP_portfolio.c +++ b/iguana/exchanges/LP_portfolio.c @@ -242,8 +242,8 @@ int32_t LP_autoprice(char *base,char *rel,cJSON *argjson) { if ( fixedprice > SMALLVAL ) { - refbase = rel; - refrel = base; + refbase = base; + refrel = rel; } for (i=0; ifixedprices[relpp->ind]) > SMALLVAL ) { LP_mypriceset(&changed,basepp->symbol,relpp->symbol,fixedprice); - printf("autoprice FIXED %s/%s <- %.8f\n",basepp->symbol,relpp->symbol,fixedprice); + printf("autoprice FIXED2 %s/%s <- %.8f\n",basepp->symbol,relpp->symbol,fixedprice); LP_pricepings(ctx,LP_myipaddr,LP_mypubsock,basepp->symbol,relpp->symbol,fixedprice); return; } From 34edbfc270ae42fca27d1d3793324f285fe92adc Mon Sep 17 00:00:00 2001 From: jl777 Date: Thu, 9 Nov 2017 16:27:51 +0200 Subject: [PATCH 0439/1664] Test --- iguana/exchanges/LP_portfolio.c | 9 +-------- 1 file changed, 1 insertion(+), 8 deletions(-) diff --git a/iguana/exchanges/LP_portfolio.c b/iguana/exchanges/LP_portfolio.c index cd9ccab14..ff6e7709a 100644 --- a/iguana/exchanges/LP_portfolio.c +++ b/iguana/exchanges/LP_portfolio.c @@ -277,20 +277,13 @@ void LP_autopriceset(void *ctx,int32_t dir,struct LP_priceinfo *basepp,struct LP double margin,minprice,newprice,oppomargin,fixedprice,factor,offset; double bid,ask; int32_t changed; margin = basepp->margins[relpp->ind]; oppomargin = relpp->margins[basepp->ind]; - if ( (fixedprice= relpp->fixedprices[basepp->ind]) > SMALLVAL ) + if ( (fixedprice= basepp->fixedprices[relpp->ind]) > SMALLVAL ) { LP_mypriceset(&changed,relpp->symbol,basepp->symbol,fixedprice); printf("autoprice FIXED %s/%s <- %.8f\n",basepp->symbol,relpp->symbol,fixedprice); LP_pricepings(ctx,LP_myipaddr,LP_mypubsock,relpp->symbol,basepp->symbol,fixedprice); return; } - else if ( (fixedprice= basepp->fixedprices[relpp->ind]) > SMALLVAL ) - { - LP_mypriceset(&changed,basepp->symbol,relpp->symbol,fixedprice); - printf("autoprice FIXED2 %s/%s <- %.8f\n",basepp->symbol,relpp->symbol,fixedprice); - LP_pricepings(ctx,LP_myipaddr,LP_mypubsock,basepp->symbol,relpp->symbol,fixedprice); - return; - } if ( margin != 0. || oppomargin != 0. ) { offset = basepp->offsets[relpp->ind]; From 698f3a76b1d835b19a339fd17c4c83fced11f38f Mon Sep 17 00:00:00 2001 From: jl777 Date: Thu, 9 Nov 2017 16:42:08 +0200 Subject: [PATCH 0440/1664] Test --- iguana/exchanges/LP_signatures.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/iguana/exchanges/LP_signatures.c b/iguana/exchanges/LP_signatures.c index 58590cae7..b20a26c85 100644 --- a/iguana/exchanges/LP_signatures.c +++ b/iguana/exchanges/LP_signatures.c @@ -448,7 +448,8 @@ char *LP_pricepings(void *ctx,char *myipaddr,int32_t pubsock,char *base,char *re { struct iguana_info *basecoin,*relcoin; char pubsecpstr[67]; uint32_t timestamp; uint64_t price64; bits256 zero; cJSON *reqjson = cJSON_CreateObject(); // LP_addsig - if ( (basecoin= LP_coinfind(base)) != 0 && (relcoin= LP_coinfind(rel)) != 0 && basecoin->electrum == 0 && relcoin->electrum == 0 ) + printf("base %s, rel %s %.8f\n",base,rel,price); + if ( (basecoin= LP_coinfind(base)) != 0 && (relcoin= LP_coinfind(rel)) != 0 && relcoin->electrum == 0 )//&& basecoin->electrum == 0 ) { memset(zero.bytes,0,sizeof(zero)); jaddbits256(reqjson,"pubkey",G.LP_mypub25519); From 1410a8c285d77fe3b053a988f606f45a1f2790b7 Mon Sep 17 00:00:00 2001 From: jl777 Date: Thu, 9 Nov 2017 16:47:08 +0200 Subject: [PATCH 0441/1664] Test --- iguana/exchanges/LP_portfolio.c | 4 ++-- iguana/exchanges/LP_signatures.c | 3 +-- 2 files changed, 3 insertions(+), 4 deletions(-) diff --git a/iguana/exchanges/LP_portfolio.c b/iguana/exchanges/LP_portfolio.c index ff6e7709a..2c4fad44a 100644 --- a/iguana/exchanges/LP_portfolio.c +++ b/iguana/exchanges/LP_portfolio.c @@ -481,7 +481,7 @@ void LP_autoprice_iter(void *ctx,struct LP_priceinfo *btcpp) relpp = LP_priceinfofind(LP_autorefs[i].rel); if ( basepp != 0 && relpp != 0 ) { - printf("check ref-autoprice %s/%s %f %f\n",LP_autorefs[i].refbase,LP_autorefs[i].refrel,relpp->fixedprices[basepp->ind],basepp->fixedprices[relpp->ind]); + //printf("check ref-autoprice %s/%s %f %f\n",LP_autorefs[i].refbase,LP_autorefs[i].refrel,relpp->fixedprices[basepp->ind],basepp->fixedprices[relpp->ind]); LP_autopriceset(ctx,1,basepp,relpp,0.,LP_autorefs[i].refbase,LP_autorefs[i].refrel); } } @@ -608,7 +608,7 @@ void prices_loop(void *ctx) prices_loop_stats.threshold = 91000.; while ( 1 ) { - printf("prices loop autoprices.%d autorefs.%d\n",LP_autoprices,num_LP_autorefs); + //printf("prices loop autoprices.%d autorefs.%d\n",LP_autoprices,num_LP_autorefs); LP_millistats_update(&prices_loop_stats); LP_tradebots_timeslice(ctx); if ( (btcpp= LP_priceinfofind("BTC")) == 0 ) diff --git a/iguana/exchanges/LP_signatures.c b/iguana/exchanges/LP_signatures.c index b20a26c85..909e6bd74 100644 --- a/iguana/exchanges/LP_signatures.c +++ b/iguana/exchanges/LP_signatures.c @@ -448,8 +448,7 @@ char *LP_pricepings(void *ctx,char *myipaddr,int32_t pubsock,char *base,char *re { struct iguana_info *basecoin,*relcoin; char pubsecpstr[67]; uint32_t timestamp; uint64_t price64; bits256 zero; cJSON *reqjson = cJSON_CreateObject(); // LP_addsig - printf("base %s, rel %s %.8f\n",base,rel,price); - if ( (basecoin= LP_coinfind(base)) != 0 && (relcoin= LP_coinfind(rel)) != 0 && relcoin->electrum == 0 )//&& basecoin->electrum == 0 ) + if ( (basecoin= LP_coinfind(base)) != 0 && (relcoin= LP_coinfind(rel)) != 0 && basecoin->electrum == 0 )//&& relcoin->electrum == 0 ) { memset(zero.bytes,0,sizeof(zero)); jaddbits256(reqjson,"pubkey",G.LP_mypub25519); From cf677af942d6f00e12c35745500c9f64454cc18c Mon Sep 17 00:00:00 2001 From: jl777 Date: Thu, 9 Nov 2017 17:21:09 +0200 Subject: [PATCH 0442/1664] Test --- iguana/exchanges/LP_nativeDEX.c | 2 +- iguana/exchanges/LP_portfolio.c | 2 +- iguana/exchanges/LP_utxo.c | 8 ++++---- iguana/exchanges/LP_utxos.c | 1 - 4 files changed, 6 insertions(+), 7 deletions(-) diff --git a/iguana/exchanges/LP_nativeDEX.c b/iguana/exchanges/LP_nativeDEX.c index fa233ec68..ea330bf64 100644 --- a/iguana/exchanges/LP_nativeDEX.c +++ b/iguana/exchanges/LP_nativeDEX.c @@ -120,7 +120,7 @@ char GLOBAL_DBDIR[] = { "DB" }; char LP_myipaddr[64],LP_publicaddr[64],USERHOME[512] = { "/root" }; char LP_gui[16] = { "cli" }; -char *default_LPnodes[] = { "5.9.253.195", "5.9.253.196", "5.9.253.197", "5.9.253.198", //"5.9.253.199", "5.9.253.200", "5.9.253.201", "5.9.253.202", "5.9.253.203", +char *default_LPnodes[] = { "5.9.253.195", "5.9.253.196", //"5.9.253.197", "5.9.253.198", "5.9.253.199", "5.9.253.200", "5.9.253.201", "5.9.253.202", "5.9.253.203", //"24.54.206.138", "173.212.225.176", "136.243.45.140", "107.72.162.127", "72.50.16.86", "51.15.202.191", "173.228.198.88", "51.15.203.171", "51.15.86.136", "51.15.94.249", "51.15.80.18", "51.15.91.40", "51.15.54.2", "51.15.86.31", "51.15.82.29", "51.15.89.155", };//"5.9.253.204" }; // diff --git a/iguana/exchanges/LP_portfolio.c b/iguana/exchanges/LP_portfolio.c index 2c4fad44a..a5b9ac1c8 100644 --- a/iguana/exchanges/LP_portfolio.c +++ b/iguana/exchanges/LP_portfolio.c @@ -280,7 +280,7 @@ void LP_autopriceset(void *ctx,int32_t dir,struct LP_priceinfo *basepp,struct LP if ( (fixedprice= basepp->fixedprices[relpp->ind]) > SMALLVAL ) { LP_mypriceset(&changed,relpp->symbol,basepp->symbol,fixedprice); - printf("autoprice FIXED %s/%s <- %.8f\n",basepp->symbol,relpp->symbol,fixedprice); + //printf("autoprice FIXED %s/%s <- %.8f\n",basepp->symbol,relpp->symbol,fixedprice); LP_pricepings(ctx,LP_myipaddr,LP_mypubsock,relpp->symbol,basepp->symbol,fixedprice); return; } diff --git a/iguana/exchanges/LP_utxo.c b/iguana/exchanges/LP_utxo.c index 161e19502..f2a1ed020 100644 --- a/iguana/exchanges/LP_utxo.c +++ b/iguana/exchanges/LP_utxo.c @@ -912,22 +912,22 @@ int32_t LP_iseligible(uint64_t *valp,uint64_t *val2p,int32_t iambob,char *symbol { if ( (tx= LP_transactionfind(coin,txid)) != 0 && vout < tx->numvouts && tx->outpoints[vout].spendheight > 0 ) { - printf("txid spent\n"); + //printf("txid spent\n"); return(0); } if ( (tx= LP_transactionfind(coin,txid2)) != 0 && vout2 < tx->numvouts && tx->outpoints[vout2].spendheight > 0 ) { - printf("txid2 spent\n"); + //printf("txid2 spent\n"); return(0); } if ( (up= LP_address_utxofind(coin,destaddr,txid,vout)) != 0 && up->spendheight > 0 ) { - printf("txid %s spentB\n",destaddr); + //printf("txid %s spentB\n",destaddr); return(0); } if ( (up= LP_address_utxofind(coin,destaddr,txid2,vout2)) != 0 && up->spendheight > 0 ) { - printf("txid2 %s spentB\n",destaddr); + //printf("txid2 %s spentB\n",destaddr); return(0); } } diff --git a/iguana/exchanges/LP_utxos.c b/iguana/exchanges/LP_utxos.c index a162aab5a..86837cc81 100644 --- a/iguana/exchanges/LP_utxos.c +++ b/iguana/exchanges/LP_utxos.c @@ -268,7 +268,6 @@ struct LP_utxoinfo *LP_utxo_bestfit(char *symbol,uint64_t destsatoshis) { if ( LP_iseligible(&srcvalue,&srcvalue2,utxo->iambob,symbol,utxo->payment.txid,utxo->payment.vout,utxo->S.satoshis,utxo->fee.txid,utxo->fee.vout) == 0 ) { - printf("not elibible\n"); //if ( utxo->T.spentflag == 0 ) // utxo->T.spentflag = (uint32_t)time(NULL); continue; From 702cc4f9065cb54c9fd969ac90e606ffef3e2d3d Mon Sep 17 00:00:00 2001 From: jl777 Date: Thu, 9 Nov 2017 17:25:15 +0200 Subject: [PATCH 0443/1664] Test --- iguana/exchanges/LP_tradebots.c | 1 + 1 file changed, 1 insertion(+) diff --git a/iguana/exchanges/LP_tradebots.c b/iguana/exchanges/LP_tradebots.c index 0d574756f..24769dbdf 100644 --- a/iguana/exchanges/LP_tradebots.c +++ b/iguana/exchanges/LP_tradebots.c @@ -611,6 +611,7 @@ char *LP_tradebot_resume(void *ctx,int32_t pubsock,cJSON *argjson,uint32_t botid char *LP_istradebots_command(void *ctx,int32_t pubsock,char *method,cJSON *argjson) { uint32_t botid; + printf("LP_istradebots_command check %s\n",method); if ( strncmp("bot_",method,strlen("bot_")) != 0 ) return(0); if ( strcmp(method,"bot_list") == 0 ) From c6c0b0f0afa3be718dd082df6cdb47a7370ba3c3 Mon Sep 17 00:00:00 2001 From: jl777 Date: Thu, 9 Nov 2017 17:44:57 +0200 Subject: [PATCH 0444/1664] Test --- iguana/exchanges/LP_include.h | 2 +- iguana/exchanges/LP_portfolio.c | 2 +- iguana/exchanges/LP_tradebots.c | 2 +- iguana/exchanges/LP_transaction.c | 2 +- 4 files changed, 4 insertions(+), 4 deletions(-) diff --git a/iguana/exchanges/LP_include.h b/iguana/exchanges/LP_include.h index 12e801063..b81a0460e 100644 --- a/iguana/exchanges/LP_include.h +++ b/iguana/exchanges/LP_include.h @@ -39,7 +39,7 @@ void emscripten_usleep(int32_t x); // returns immediate, no sense for sleeping #define LP_HTTP_TIMEOUT 3 // 1 is too small due to edge cases of time(NULL) #define LP_AUTOTRADE_TIMEOUT 30 -#define ELECTRUM_TIMEOUT 5 +#define ELECTRUM_TIMEOUT 15 #define LP_ELECTRUM_KEEPALIVE 60 #define LP_ELECTRUM_MAXERRORS 777 #define LP_MEMPOOL_TIMEINCR 10 diff --git a/iguana/exchanges/LP_portfolio.c b/iguana/exchanges/LP_portfolio.c index a5b9ac1c8..43fd77c89 100644 --- a/iguana/exchanges/LP_portfolio.c +++ b/iguana/exchanges/LP_portfolio.c @@ -647,7 +647,7 @@ void prices_loop(void *ctx) } free(retstr); } - sleep(10); + sleep(30); } } diff --git a/iguana/exchanges/LP_tradebots.c b/iguana/exchanges/LP_tradebots.c index 24769dbdf..e42fc369c 100644 --- a/iguana/exchanges/LP_tradebots.c +++ b/iguana/exchanges/LP_tradebots.c @@ -611,7 +611,7 @@ char *LP_tradebot_resume(void *ctx,int32_t pubsock,cJSON *argjson,uint32_t botid char *LP_istradebots_command(void *ctx,int32_t pubsock,char *method,cJSON *argjson) { uint32_t botid; - printf("LP_istradebots_command check %s\n",method); + //printf("LP_istradebots_command check %s\n",method); if ( strncmp("bot_",method,strlen("bot_")) != 0 ) return(0); if ( strcmp(method,"bot_list") == 0 ) diff --git a/iguana/exchanges/LP_transaction.c b/iguana/exchanges/LP_transaction.c index 424925b2e..5fe90e841 100644 --- a/iguana/exchanges/LP_transaction.c +++ b/iguana/exchanges/LP_transaction.c @@ -1059,7 +1059,7 @@ char *LP_createrawtransaction(cJSON **txobjp,int32_t *numvinsp,struct iguana_inf if ( numvins <= 0 || total < amount ) { printf("change %.8f = total %.8f - amount %.8f, adjust %.8f numvouts.%d, txfee %.8f\n",dstr(change),dstr(total),dstr(amount),dstr(adjust),numvouts,dstr(txfee)); - printf("not enough inputs for amount %.8f < %.8f txfee %.8f\n",dstr(total),dstr(amount),dstr(txfee)); + printf("not enough inputs %.8f < for amount %.8f txfee %.8f\n",dstr(total),dstr(amount),dstr(txfee)); return(0); } change = (total - amount); From ce9d4cbf1faaf83e0e4878e11e13b2b471cbcb02 Mon Sep 17 00:00:00 2001 From: jl777 Date: Thu, 9 Nov 2017 17:58:07 +0200 Subject: [PATCH 0445/1664] Test --- iguana/exchanges/LP_nativeDEX.c | 1 + iguana/exchanges/LP_socket.c | 4 ++-- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/iguana/exchanges/LP_nativeDEX.c b/iguana/exchanges/LP_nativeDEX.c index ea330bf64..21e85027f 100644 --- a/iguana/exchanges/LP_nativeDEX.c +++ b/iguana/exchanges/LP_nativeDEX.c @@ -23,6 +23,7 @@ // bot progress // swap started event for bot // bot status 1600% ? + // BCH signing // dPoW security -> 4: KMD notarized, 5: BTC notarized, after next notary elections // bigendian architectures need to use little endian for sighash calcs diff --git a/iguana/exchanges/LP_socket.c b/iguana/exchanges/LP_socket.c index 9e8b9bbb8..8f9f899e9 100644 --- a/iguana/exchanges/LP_socket.c +++ b/iguana/exchanges/LP_socket.c @@ -427,12 +427,12 @@ cJSON *electrum_submit(char *symbol,struct electrum_info *ep,cJSON **retjsonp,ch sitem->expiration = timeout; sitem->DL.type = ep->stratumid++; sitem->retptrp = (void **)retjsonp;*/ - //portable_mutex_lock(&ep->mutex); + portable_mutex_lock(&ep->mutex); //queue_enqueue("sendQ",&ep->sendQ,&sitem->DL); expiration = (uint32_t)time(NULL) + timeout + 1; while ( *retjsonp == 0 && time(NULL) <= expiration ) usleep(5000); - //portable_mutex_unlock(&ep->mutex); + portable_mutex_unlock(&ep->mutex); if ( *retjsonp == 0 || jobj(*retjsonp,"error") != 0 ) { if ( ++ep->numerrors >= LP_ELECTRUM_MAXERRORS ) From 55af1952d244524739c2d5ee165682eaeb761698 Mon Sep 17 00:00:00 2001 From: jl777 Date: Thu, 9 Nov 2017 18:07:20 +0200 Subject: [PATCH 0446/1664] Allow clients to auto price inactive coins --- iguana/exchanges/LP_commands.c | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/iguana/exchanges/LP_commands.c b/iguana/exchanges/LP_commands.c index ae598dbfc..09d50622d 100644 --- a/iguana/exchanges/LP_commands.c +++ b/iguana/exchanges/LP_commands.c @@ -272,6 +272,12 @@ bot_resume(botid)\n\ if ( base[0] != 0 && rel[0] != 0 ) { double price,bid,ask; + if ( strcmp(method,"autoprice") == 0 ) + { + if ( LP_autoprice(base,rel,argjson) < 0 ) + return(clonestr("{\"error\":\"couldnt set autoprice\"}")); + else return(clonestr("{\"result\":\"success\"}")); + } if ( IAMLP == 0 && LP_isdisabled(base,rel) != 0 ) return(clonestr("{\"error\":\"at least one of coins disabled\"}")); price = jdouble(argjson,"price"); @@ -283,12 +289,6 @@ bot_resume(botid)\n\ // return(clonestr("{\"error\":\"couldnt set price\"}")); else return(LP_pricepings(ctx,myipaddr,LP_mypubsock,base,rel,price * LP_profitratio)); } - else if ( strcmp(method,"autoprice") == 0 ) - { - if ( LP_autoprice(base,rel,argjson) < 0 ) - return(clonestr("{\"error\":\"couldnt set autoprice\"}")); - else return(clonestr("{\"result\":\"success\"}")); - } else if ( strcmp(method,"pricearray") == 0 ) { uint32_t firsttime; From ddded08d9fce22a202243a5d4821cc12c2e736e4 Mon Sep 17 00:00:00 2001 From: jl777 Date: Thu, 9 Nov 2017 19:22:32 +0200 Subject: [PATCH 0447/1664] Test --- iguana/exchanges/LP_utxos.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/iguana/exchanges/LP_utxos.c b/iguana/exchanges/LP_utxos.c index 86837cc81..d743fafde 100644 --- a/iguana/exchanges/LP_utxos.c +++ b/iguana/exchanges/LP_utxos.c @@ -537,11 +537,11 @@ int32_t LP_privkey_init(int32_t mypubsock,struct iguana_info *coin,bits256 mypri height = jint(item,"height"); } satoshis = LP_txvalue(destaddr,coin->symbol,txid,vout); - if ( satoshis != 0 && satoshis != value ) - printf("%s %s unexpected privkey_init value mismatch %.8f vs %.8f (%s) %.8f %.8f\n",coin->symbol,coin->smartaddr,dstr(satoshis),dstr(value),jprint(item,0),jdouble(item,"amount"),jdouble(item,"interest")); + //if ( satoshis != 0 && satoshis != value ) + printf("%s %s privkey_init value %.8f vs %.8f (%s) %.8f %.8f\n",coin->symbol,coin->smartaddr,dstr(satoshis),dstr(value),jprint(item,0),jdouble(item,"amount"),jdouble(item,"interest")); if ( LP_inventory_prevent(iambob,coin->symbol,txid,vout) == 0 && height > 0 ) { - //printf("%s\n",jprint(item,0)); + printf("PREVENT %s\n",jprint(item,0)); values[i] = satoshis; //flag += LP_address_utxoadd(coin,destaddr,txid,vout,satoshis,height,-1); } else used++; From e2e686ce41be2d4d3df9b45ea7de4c6349bf6e93 Mon Sep 17 00:00:00 2001 From: jl777 Date: Thu, 9 Nov 2017 19:33:09 +0200 Subject: [PATCH 0448/1664] Test --- iguana/exchanges/LP_utxo.c | 2 +- iguana/exchanges/LP_utxos.c | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/iguana/exchanges/LP_utxo.c b/iguana/exchanges/LP_utxo.c index f2a1ed020..8993db4d0 100644 --- a/iguana/exchanges/LP_utxo.c +++ b/iguana/exchanges/LP_utxo.c @@ -987,7 +987,7 @@ int32_t LP_inventory_prevent(int32_t iambob,char *symbol,bits256 txid,int32_t vo } if ( utxo->T.spentflag != 0 ) { - //char str[65]; printf("prevent adding iambob.%d %s/v%d to inventory\n",iambob,bits256_str(str,txid),vout); + char str[65]; printf("prevent adding iambob.%d %s/v%d to inventory\n",iambob,bits256_str(str,txid),vout); return(1); } } diff --git a/iguana/exchanges/LP_utxos.c b/iguana/exchanges/LP_utxos.c index d743fafde..2b96fcca4 100644 --- a/iguana/exchanges/LP_utxos.c +++ b/iguana/exchanges/LP_utxos.c @@ -537,7 +537,7 @@ int32_t LP_privkey_init(int32_t mypubsock,struct iguana_info *coin,bits256 mypri height = jint(item,"height"); } satoshis = LP_txvalue(destaddr,coin->symbol,txid,vout); - //if ( satoshis != 0 && satoshis != value ) + if ( satoshis != 0 && satoshis != value ) printf("%s %s privkey_init value %.8f vs %.8f (%s) %.8f %.8f\n",coin->symbol,coin->smartaddr,dstr(satoshis),dstr(value),jprint(item,0),jdouble(item,"amount"),jdouble(item,"interest")); if ( LP_inventory_prevent(iambob,coin->symbol,txid,vout) == 0 && height > 0 ) { From 828b19046c4dc8d766a97354719444049d4f3744 Mon Sep 17 00:00:00 2001 From: jl777 Date: Thu, 9 Nov 2017 19:36:30 +0200 Subject: [PATCH 0449/1664] Test --- iguana/exchanges/LP_utxo.c | 2 +- iguana/exchanges/LP_utxos.c | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/iguana/exchanges/LP_utxo.c b/iguana/exchanges/LP_utxo.c index 8993db4d0..f2a1ed020 100644 --- a/iguana/exchanges/LP_utxo.c +++ b/iguana/exchanges/LP_utxo.c @@ -987,7 +987,7 @@ int32_t LP_inventory_prevent(int32_t iambob,char *symbol,bits256 txid,int32_t vo } if ( utxo->T.spentflag != 0 ) { - char str[65]; printf("prevent adding iambob.%d %s/v%d to inventory\n",iambob,bits256_str(str,txid),vout); + //char str[65]; printf("prevent adding iambob.%d %s/v%d to inventory\n",iambob,bits256_str(str,txid),vout); return(1); } } diff --git a/iguana/exchanges/LP_utxos.c b/iguana/exchanges/LP_utxos.c index 2b96fcca4..67919c2ac 100644 --- a/iguana/exchanges/LP_utxos.c +++ b/iguana/exchanges/LP_utxos.c @@ -539,7 +539,7 @@ int32_t LP_privkey_init(int32_t mypubsock,struct iguana_info *coin,bits256 mypri satoshis = LP_txvalue(destaddr,coin->symbol,txid,vout); if ( satoshis != 0 && satoshis != value ) printf("%s %s privkey_init value %.8f vs %.8f (%s) %.8f %.8f\n",coin->symbol,coin->smartaddr,dstr(satoshis),dstr(value),jprint(item,0),jdouble(item,"amount"),jdouble(item,"interest")); - if ( LP_inventory_prevent(iambob,coin->symbol,txid,vout) == 0 && height > 0 ) + if ( LP_inventory_prevent(iambob,coin->symbol,txid,vout) != 0 )//&& height > 0 ) { printf("PREVENT %s\n",jprint(item,0)); values[i] = satoshis; From 040cc18eabd4c8cf75cb5c231e7bda51ac7c57fb Mon Sep 17 00:00:00 2001 From: jl777 Date: Thu, 9 Nov 2017 19:40:12 +0200 Subject: [PATCH 0450/1664] Test --- iguana/exchanges/LP_include.h | 2 +- iguana/exchanges/LP_utxos.c | 5 ++--- 2 files changed, 3 insertions(+), 4 deletions(-) diff --git a/iguana/exchanges/LP_include.h b/iguana/exchanges/LP_include.h index b81a0460e..3265b648f 100644 --- a/iguana/exchanges/LP_include.h +++ b/iguana/exchanges/LP_include.h @@ -77,7 +77,7 @@ void emscripten_usleep(int32_t x); // returns immediate, no sense for sleeping #define LP_MIN_TXFEE 10000 #define LP_MINVOL 20 #define LP_MINCLIENTVOL 1000 -#define LP_MINSIZE_TXFEEMULT 10 +#define LP_MINSIZE_TXFEEMULT 3 #define LP_REQUIRED_TXFEE 0.8 #define LP_DEXFEE(destsatoshis) ((destsatoshis) / INSTANTDEX_INSURANCEDIV) diff --git a/iguana/exchanges/LP_utxos.c b/iguana/exchanges/LP_utxos.c index 67919c2ac..5df269146 100644 --- a/iguana/exchanges/LP_utxos.c +++ b/iguana/exchanges/LP_utxos.c @@ -539,9 +539,8 @@ int32_t LP_privkey_init(int32_t mypubsock,struct iguana_info *coin,bits256 mypri satoshis = LP_txvalue(destaddr,coin->symbol,txid,vout); if ( satoshis != 0 && satoshis != value ) printf("%s %s privkey_init value %.8f vs %.8f (%s) %.8f %.8f\n",coin->symbol,coin->smartaddr,dstr(satoshis),dstr(value),jprint(item,0),jdouble(item,"amount"),jdouble(item,"interest")); - if ( LP_inventory_prevent(iambob,coin->symbol,txid,vout) != 0 )//&& height > 0 ) + if ( LP_inventory_prevent(iambob,coin->symbol,txid,vout) == 0 )//&& height > 0 ) { - printf("PREVENT %s\n",jprint(item,0)); values[i] = satoshis; //flag += LP_address_utxoadd(coin,destaddr,txid,vout,satoshis,height,-1); } else used++; @@ -574,7 +573,7 @@ int32_t LP_privkey_init(int32_t mypubsock,struct iguana_info *coin,bits256 mypri else targetval = (depositval / 9) * 8 + 2*txfee; if ( targetval < txfee*2 ) targetval = txfee*2; - //printf("iambob.%d i.%d deposit %.8f min %.8f target %.8f\n",iambob,i,dstr(depositval),dstr((1+LP_MINSIZE_TXFEEMULT)*txfee),dstr(targetval)); + printf("iambob.%d i.%d deposit %.8f min %.8f target %.8f\n",iambob,i,dstr(depositval),dstr((1+LP_MINSIZE_TXFEEMULT)*txfee),dstr(targetval)); if ( depositval < (1+LP_MINSIZE_TXFEEMULT)*txfee ) continue; i = -1; From 06dd41964cd772d0900f8afb98a2cde92b5a32e3 Mon Sep 17 00:00:00 2001 From: jl777 Date: Thu, 9 Nov 2017 19:50:01 +0200 Subject: [PATCH 0451/1664] Test --- iguana/exchanges/LP_utxos.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/iguana/exchanges/LP_utxos.c b/iguana/exchanges/LP_utxos.c index 5df269146..ea7d36b52 100644 --- a/iguana/exchanges/LP_utxos.c +++ b/iguana/exchanges/LP_utxos.c @@ -573,7 +573,7 @@ int32_t LP_privkey_init(int32_t mypubsock,struct iguana_info *coin,bits256 mypri else targetval = (depositval / 9) * 8 + 2*txfee; if ( targetval < txfee*2 ) targetval = txfee*2; - printf("iambob.%d i.%d deposit %.8f min %.8f target %.8f\n",iambob,i,dstr(depositval),dstr((1+LP_MINSIZE_TXFEEMULT)*txfee),dstr(targetval)); + //printf("iambob.%d i.%d deposit %.8f min %.8f target %.8f\n",iambob,i,dstr(depositval),dstr((1+LP_MINSIZE_TXFEEMULT)*txfee),dstr(targetval)); if ( depositval < (1+LP_MINSIZE_TXFEEMULT)*txfee ) continue; i = -1; From edd6cc25ad67c93fa5ce2fde9d3496286298f60a Mon Sep 17 00:00:00 2001 From: jl777 Date: Thu, 9 Nov 2017 20:22:12 +0200 Subject: [PATCH 0452/1664] Test --- iguana/exchanges/LP_commands.c | 2 +- iguana/exchanges/LP_ordermatch.c | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/iguana/exchanges/LP_commands.c b/iguana/exchanges/LP_commands.c index 09d50622d..05065beea 100644 --- a/iguana/exchanges/LP_commands.c +++ b/iguana/exchanges/LP_commands.c @@ -592,7 +592,7 @@ bot_resume(botid)\n\ LP_address(ptr,coinaddr); if ( strcmp(coinaddr,ptr->smartaddr) == 0 && bits256_nonz(G.LP_privkey) != 0 ) { - //printf("ADDR_UNSPENTS %s %s is my address being asked for!\n",ptr->symbol,coinaddr); + printf("ADDR_UNSPENTS %s %s is my address being asked for!\n",ptr->symbol,coinaddr); ptr->addr_listunspent_requested = (uint32_t)time(NULL); } } diff --git a/iguana/exchanges/LP_ordermatch.c b/iguana/exchanges/LP_ordermatch.c index 68f113732..7943e27ee 100644 --- a/iguana/exchanges/LP_ordermatch.c +++ b/iguana/exchanges/LP_ordermatch.c @@ -866,7 +866,7 @@ struct LP_utxoinfo *LP_buyutxo(double *ordermatchpricep,int64_t *bestsatoshisp,i continue; if ( LP_RTmetrics_blacklisted(pubkey) >= 0 ) continue; - //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 ) { if ( bits256_nonz(destpubkey) == 0 ) @@ -887,7 +887,7 @@ struct LP_utxoinfo *LP_buyutxo(double *ordermatchpricep,int64_t *bestsatoshisp,i { if ( (bestutxo= LP_ordermatch_iter(utxos,max,ordermatchpricep,bestsatoshisp,bestdestsatoshisp,basecoin,coinaddr,asatoshis,price,txfee,desttxfee,pubp->pubkey,gui)) != 0 ) { - //printf("j.%d/%d ordermatch %.8f best satoshis %.8f destsatoshis %.8f txfees (%.8f %.8f)\n",j,maxiters,price,dstr(*bestsatoshisp),dstr(*bestdestsatoshisp),dstr(txfee),dstr(desttxfee)); + printf("j.%d/%d ordermatch %.8f best satoshis %.8f destsatoshis %.8f txfees (%.8f %.8f)\n",j,maxiters,price,dstr(*bestsatoshisp),dstr(*bestdestsatoshisp),dstr(txfee),dstr(desttxfee)); break; } asatoshis = (asatoshis / 64) * 63; From 2536b867d55ecec7404bf7e84e381c04d65d0241 Mon Sep 17 00:00:00 2001 From: jl777 Date: Thu, 9 Nov 2017 20:29:06 +0200 Subject: [PATCH 0453/1664] Test --- iguana/exchanges/LP_ordermatch.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/iguana/exchanges/LP_ordermatch.c b/iguana/exchanges/LP_ordermatch.c index 7943e27ee..2078f6cb0 100644 --- a/iguana/exchanges/LP_ordermatch.c +++ b/iguana/exchanges/LP_ordermatch.c @@ -275,7 +275,7 @@ struct LP_utxoinfo *LP_address_utxopair(int32_t iambob,struct LP_address_utxo ** if ( (m= LP_address_utxo_ptrs(coin,iambob,utxos,max,ap,coinaddr)) > 1 ) { targetval = LP_basesatoshis(relvolume,price,txfee,desttxfee); - if ( 0 ) + if ( 1 ) { int32_t i; for (i=0; i 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 ) { From d2aea4882215cf96e3c74d7c038491cf348850bc Mon Sep 17 00:00:00 2001 From: jl777 Date: Thu, 9 Nov 2017 20:37:10 +0200 Subject: [PATCH 0454/1664] Test --- iguana/exchanges/LP_ordermatch.c | 3 ++- iguana/exchanges/LP_utxo.c | 2 +- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/iguana/exchanges/LP_ordermatch.c b/iguana/exchanges/LP_ordermatch.c index 2078f6cb0..87df64790 100644 --- a/iguana/exchanges/LP_ordermatch.c +++ b/iguana/exchanges/LP_ordermatch.c @@ -817,6 +817,7 @@ struct LP_utxoinfo *LP_ordermatch_iter(struct LP_address_utxo **utxos,int32_t ma { uint64_t basesatoshis; struct LP_utxoinfo *bestutxo; basesatoshis = LP_basesatoshis(dstr(asatoshis),price,txfee,desttxfee); + printf("basesatoshis %.8f price %.8f txfee %.8f desttxfee %.8f\n",dstr(basesatoshis),price,dstr(txfee),dstr(desttxfee)); if ( basesatoshis != 0 && (bestutxo= LP_address_utxopair(0,utxos,max,basecoin,coinaddr,txfee,dstr(basesatoshis)*price,price,desttxfee)) != 0 ) { bestutxo->pubkey = pubkey; @@ -866,7 +867,7 @@ struct LP_utxoinfo *LP_buyutxo(double *ordermatchpricep,int64_t *bestsatoshisp,i continue; if ( LP_RTmetrics_blacklisted(pubkey) >= 0 ) continue; -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 asatoshis %.8f\n",i,numasks,jprint(item,0),bits256_cmp(pubkey,G.LP_mypub25519),price,maxprice,dstr(autxo->S.satoshis)); if ( LP_pricevalid(price) > 0 && price <= maxprice ) { if ( bits256_nonz(destpubkey) == 0 ) diff --git a/iguana/exchanges/LP_utxo.c b/iguana/exchanges/LP_utxo.c index f2a1ed020..17814f4be 100644 --- a/iguana/exchanges/LP_utxo.c +++ b/iguana/exchanges/LP_utxo.c @@ -179,7 +179,7 @@ int32_t LP_address_utxo_ptrs(struct iguana_info *coin,int32_t iambob,struct LP_a { if ( up->SPV < 0 || up->U.height == 0 ) { - //printf("LP_address_utxo_ptrs skips %s/v%u due to SPV.%d ht.%d\n",bits256_str(str,up->U.txid),up->U.vout,up->SPV,up->U.height); +printf("LP_address_utxo_ptrs skips %s/v%u due to SPV.%d ht.%d\n",bits256_str(str,up->U.txid),up->U.vout,up->SPV,up->U.height); if ( (tx= LP_transactionfind(coin,up->U.txid)) != 0 && up->U.vout < tx->numvouts ) tx->outpoints[up->U.vout].spendheight = 1; continue; From 01a3df50368105623aa2e8619fe33226efa268be Mon Sep 17 00:00:00 2001 From: jl777 Date: Thu, 9 Nov 2017 21:09:44 +0200 Subject: [PATCH 0455/1664] Test --- iguana/exchanges/LP_include.h | 6 +++--- iguana/exchanges/LP_ordermatch.c | 2 +- iguana/exchanges/LP_swap.c | 22 +++++++++++++++++++--- 3 files changed, 23 insertions(+), 7 deletions(-) diff --git a/iguana/exchanges/LP_include.h b/iguana/exchanges/LP_include.h index 3265b648f..e273515a6 100644 --- a/iguana/exchanges/LP_include.h +++ b/iguana/exchanges/LP_include.h @@ -163,7 +163,7 @@ struct basilisk_rawtxinfo { char destaddr[64],coinstr[16]; bits256 txid,signedtxid,actualtxid; - uint64_t amount,change,inputsum; + int64_t amount,change,inputsum; int32_t redeemlen,datalen,completed,vintype,vouttype,numconfirms,spendlen,secretstart,suppress_pubkeys; uint32_t locktime,crcs[2]; uint8_t addrtype,pubkey33[33],rmd160[20]; @@ -172,7 +172,7 @@ struct basilisk_rawtxinfo struct basilisk_request { uint32_t requestid,timestamp,quoteid,quotetime; // 0 to 15 - uint64_t srcamount,unused; // 16 to 31 + int64_t srcamount,unused; // 16 to 31 bits256 srchash; // 32 to 63 bits256 desthash; char src[8],dest[8]; @@ -199,7 +199,7 @@ struct basilisk_swapinfo bits256 myhash,otherhash,orderhash; uint32_t statebits,otherstatebits,started,expiration,finished,dead,reftime,putduration,callduration; int32_t bobconfirms,aliceconfirms,iambob,reclaimed,bobspent,alicespent,pad,aliceistrusted,bobistrusted,otheristrusted,otherstrust,alicemaxconfirms,bobmaxconfirms; - uint64_t alicesatoshis,bobsatoshis,bobinsurance,aliceinsurance,Atxfee,Btxfee; + int64_t alicesatoshis,bobsatoshis,bobinsurance,aliceinsurance,Atxfee,Btxfee; bits256 myprivs[2],mypubs[2],otherpubs[2],pubA0,pubA1,pubB0,pubB1,privAm,pubAm,privBn,pubBn; uint32_t crcs_mypub[2],crcs_mychoosei[2],crcs_myprivs[2],crcs_mypriv[2]; diff --git a/iguana/exchanges/LP_ordermatch.c b/iguana/exchanges/LP_ordermatch.c index 87df64790..8002c9420 100644 --- a/iguana/exchanges/LP_ordermatch.c +++ b/iguana/exchanges/LP_ordermatch.c @@ -509,7 +509,7 @@ char *LP_connectedalice(cJSON *argjson) // alice //timeout = 1; //nn_setsockopt(pairsock,NN_SOL_SOCKET,NN_SNDTIMEO,&timeout,sizeof(timeout)); //nn_setsockopt(pairsock,NN_SOL_SOCKET,NN_RCVTIMEO,&timeout,sizeof(timeout)); - 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); + LP_requestinit(&Q.R,Q.srchash,Q.desthash,Q.srccoin,Q.satoshis-Q.txfee,Q.destcoin,Q.destsatoshis-Q.desttxfee,Q.timestamp,Q.quotetime,DEXselector); swap = LP_swapinit(0,0,Q.privkey,&Q.R,&Q); swap->tradeid = Q.tradeid; swap->N.pair = pairsock; diff --git a/iguana/exchanges/LP_swap.c b/iguana/exchanges/LP_swap.c index b631f22e6..68fdea1ae 100644 --- a/iguana/exchanges/LP_swap.c +++ b/iguana/exchanges/LP_swap.c @@ -996,15 +996,31 @@ struct basilisk_swap *bitcoin_swapinit(bits256 privkey,uint8_t *pubkey33,bits256 { //FILE *fp; char fname[512]; 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; + if ( (swap->I.Atxfee= qp->desttxfee) < 0 ) + { + printf("bitcoin_swapinit %s Atxfee %.8f rejected\n",swap->I.req.dest,dstr(swap->I.Atxfee)); + return(0); + } + if ( (swap->I.Btxfee= qp->txfee) < 0 ) + { + printf("bitcoin_swapinit %s Btxfee %.8f rejected\n",swap->I.req.src,dstr(swap->I.Btxfee)); + return(0); + } swap->I.putduration = swap->I.callduration = INSTANTDEX_LOCKTIME; if ( optionduration < 0 ) swap->I.putduration -= optionduration; else if ( optionduration > 0 ) swap->I.callduration += optionduration; - swap->I.bobsatoshis = swap->I.req.srcamount; + if ( (swap->I.bobsatoshis= swap->I.req.srcamount) <= 0 ) + { + printf("bitcoin_swapinit %s bobsatoshis %.8f rejected\n",swap->I.req.src,dstr(swap->I.bobsatoshis)); + return(0); + } swap->I.alicesatoshis = swap->I.req.destamount; + { + printf("bitcoin_swapinit %s alicesatoshis %.8f rejected\n",swap->I.req.dest,dstr(swap->I.alicesatoshis)); + return(0); + } if ( (swap->I.bobinsurance= (swap->I.bobsatoshis / INSTANTDEX_INSURANCEDIV)) < LP_MIN_TXFEE ) swap->I.bobinsurance = LP_MIN_TXFEE; if ( (swap->I.aliceinsurance= (swap->I.alicesatoshis / INSTANTDEX_INSURANCEDIV)) < LP_MIN_TXFEE ) From 53ee3c842dc1f60e696902893815c6f538458539 Mon Sep 17 00:00:00 2001 From: jl777 Date: Thu, 9 Nov 2017 21:10:40 +0200 Subject: [PATCH 0456/1664] Test --- iguana/exchanges/LP_ordermatch.c | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) diff --git a/iguana/exchanges/LP_ordermatch.c b/iguana/exchanges/LP_ordermatch.c index 8002c9420..050c0d1b5 100644 --- a/iguana/exchanges/LP_ordermatch.c +++ b/iguana/exchanges/LP_ordermatch.c @@ -275,7 +275,7 @@ struct LP_utxoinfo *LP_address_utxopair(int32_t iambob,struct LP_address_utxo ** if ( (m= LP_address_utxo_ptrs(coin,iambob,utxos,max,ap,coinaddr)) > 1 ) { targetval = LP_basesatoshis(relvolume,price,txfee,desttxfee); - if ( 1 ) + if ( 0 ) { int32_t i; for (i=0; i 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 ) { @@ -817,7 +817,7 @@ struct LP_utxoinfo *LP_ordermatch_iter(struct LP_address_utxo **utxos,int32_t ma { uint64_t basesatoshis; struct LP_utxoinfo *bestutxo; basesatoshis = LP_basesatoshis(dstr(asatoshis),price,txfee,desttxfee); - printf("basesatoshis %.8f price %.8f txfee %.8f desttxfee %.8f\n",dstr(basesatoshis),price,dstr(txfee),dstr(desttxfee)); + //printf("basesatoshis %.8f price %.8f txfee %.8f desttxfee %.8f\n",dstr(basesatoshis),price,dstr(txfee),dstr(desttxfee)); if ( basesatoshis != 0 && (bestutxo= LP_address_utxopair(0,utxos,max,basecoin,coinaddr,txfee,dstr(basesatoshis)*price,price,desttxfee)) != 0 ) { bestutxo->pubkey = pubkey; @@ -883,12 +883,11 @@ printf("[%d/%d] %s pubcmp %d price %.8f vs maxprice %.8f asatoshis %.8f\n",i,num bitcoin_address(coinaddr,basecoin->taddr,basecoin->pubtype,pubp->rmd160,sizeof(pubp->rmd160)); asatoshis = autxo->S.satoshis; LP_listunspent_query(base,coinaddr); - //LP_listunspent_both(base,coinaddr,1); for (j=0; jpubkey,gui)) != 0 ) { - printf("j.%d/%d ordermatch %.8f best satoshis %.8f destsatoshis %.8f txfees (%.8f %.8f)\n",j,maxiters,price,dstr(*bestsatoshisp),dstr(*bestdestsatoshisp),dstr(txfee),dstr(desttxfee)); + //printf("j.%d/%d ordermatch %.8f best satoshis %.8f destsatoshis %.8f txfees (%.8f %.8f)\n",j,maxiters,price,dstr(*bestsatoshisp),dstr(*bestdestsatoshisp),dstr(txfee),dstr(desttxfee)); break; } asatoshis = (asatoshis / 64) * 63; From f553f6f39a59608f0aa117dcabe5db1c0732e6d4 Mon Sep 17 00:00:00 2001 From: jl777 Date: Thu, 9 Nov 2017 21:14:12 +0200 Subject: [PATCH 0457/1664] Test --- iguana/exchanges/LP_ordermatch.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/iguana/exchanges/LP_ordermatch.c b/iguana/exchanges/LP_ordermatch.c index 050c0d1b5..ae1358942 100644 --- a/iguana/exchanges/LP_ordermatch.c +++ b/iguana/exchanges/LP_ordermatch.c @@ -509,7 +509,7 @@ char *LP_connectedalice(cJSON *argjson) // alice //timeout = 1; //nn_setsockopt(pairsock,NN_SOL_SOCKET,NN_SNDTIMEO,&timeout,sizeof(timeout)); //nn_setsockopt(pairsock,NN_SOL_SOCKET,NN_RCVTIMEO,&timeout,sizeof(timeout)); - LP_requestinit(&Q.R,Q.srchash,Q.desthash,Q.srccoin,Q.satoshis-Q.txfee,Q.destcoin,Q.destsatoshis-Q.desttxfee,Q.timestamp,Q.quotetime,DEXselector); + 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); swap = LP_swapinit(0,0,Q.privkey,&Q.R,&Q); swap->tradeid = Q.tradeid; swap->N.pair = pairsock; From c75deee24607003f5d86cb120a06ab82ae8c50b7 Mon Sep 17 00:00:00 2001 From: jl777 Date: Thu, 9 Nov 2017 21:19:24 +0200 Subject: [PATCH 0458/1664] Test --- iguana/exchanges/LP_ordermatch.c | 2 +- iguana/exchanges/LP_prices.c | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/iguana/exchanges/LP_ordermatch.c b/iguana/exchanges/LP_ordermatch.c index ae1358942..a94ed096c 100644 --- a/iguana/exchanges/LP_ordermatch.c +++ b/iguana/exchanges/LP_ordermatch.c @@ -867,7 +867,7 @@ struct LP_utxoinfo *LP_buyutxo(double *ordermatchpricep,int64_t *bestsatoshisp,i continue; if ( LP_RTmetrics_blacklisted(pubkey) >= 0 ) continue; -printf("[%d/%d] %s pubcmp %d price %.8f vs maxprice %.8f asatoshis %.8f\n",i,numasks,jprint(item,0),bits256_cmp(pubkey,G.LP_mypub25519),price,maxprice,dstr(autxo->S.satoshis)); +//printf("[%d/%d] %s pubcmp %d price %.8f vs maxprice %.8f asatoshis %.8f\n",i,numasks,jprint(item,0),bits256_cmp(pubkey,G.LP_mypub25519),price,maxprice,dstr(autxo->S.satoshis)); if ( LP_pricevalid(price) > 0 && price <= maxprice ) { if ( bits256_nonz(destpubkey) == 0 ) diff --git a/iguana/exchanges/LP_prices.c b/iguana/exchanges/LP_prices.c index 219968200..ed2a52b8f 100644 --- a/iguana/exchanges/LP_prices.c +++ b/iguana/exchanges/LP_prices.c @@ -813,7 +813,7 @@ char *LP_orderbook(char *base,char *rel,int32_t duration) for (i=n=0; inumutxos == 0 ) + if ( suppress_prefetch == 0 && n < 7 && bids[i]->numutxos < 3 ) { //printf("bid ping %s %s\n",rel,bids[i]->coinaddr); LP_address(relcoin,bids[i]->coinaddr); @@ -833,7 +833,7 @@ char *LP_orderbook(char *base,char *rel,int32_t duration) for (i=n=0; inumutxos == 0 ) + if ( suppress_prefetch == 0 && n < 7 && asks[i]->numutxos < 3 ) { //printf("ask ping %s %s\n",base,asks[i]->coinaddr); LP_address(basecoin,asks[i]->coinaddr); From b3342b33223cc6f2bd2a9f7ced4ce560abc45013 Mon Sep 17 00:00:00 2001 From: jl777 Date: Thu, 9 Nov 2017 21:39:12 +0200 Subject: [PATCH 0459/1664] Test --- iguana/exchanges/LP_commands.c | 2 ++ iguana/exchanges/LP_nativeDEX.c | 13 +++++++------ iguana/exchanges/LP_signatures.c | 12 ------------ 3 files changed, 9 insertions(+), 18 deletions(-) diff --git a/iguana/exchanges/LP_commands.c b/iguana/exchanges/LP_commands.c index 05065beea..0d9508a18 100644 --- a/iguana/exchanges/LP_commands.c +++ b/iguana/exchanges/LP_commands.c @@ -593,6 +593,8 @@ bot_resume(botid)\n\ if ( strcmp(coinaddr,ptr->smartaddr) == 0 && bits256_nonz(G.LP_privkey) != 0 ) { printf("ADDR_UNSPENTS %s %s is my address being asked for!\n",ptr->symbol,coinaddr); + if ( ptr->lastpushtime > 0 && ptr->addr_listunspent_requested > (uint32_t)time(NULL)-10 ) + ptr->lastpushtime -= LP_ORDERBOOK_DURATION*0.1; ptr->addr_listunspent_requested = (uint32_t)time(NULL); } } diff --git a/iguana/exchanges/LP_nativeDEX.c b/iguana/exchanges/LP_nativeDEX.c index 21e85027f..28be65d12 100644 --- a/iguana/exchanges/LP_nativeDEX.c +++ b/iguana/exchanges/LP_nativeDEX.c @@ -603,22 +603,23 @@ 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;//,numpeers; - struct iguana_info *coin,*ctmp; char *origipaddr; int32_t height,nonz = 0;//struct LP_peerinfo *peer,*tmp; uint32_t now; + static uint32_t counter; + struct iguana_info *coin,*ctmp; char *origipaddr; uint32_t now; int32_t height,nonz = 0; if ( (origipaddr= myipaddr) == 0 ) origipaddr = "127.0.0.1"; if ( mypeer == 0 ) myipaddr = "127.0.0.1"; HASH_ITER(hh,LP_coins,coin,ctmp) // firstrefht,firstscanht,lastscanht { - if ( coin->addr_listunspent_requested != 0 && time(NULL) > coin->lastpushtime+LP_ORDERBOOK_DURATION ) + now = (uint32_t)time(NULL); + 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)time(NULL); + coin->lastpushtime = (uint32_t)now; LP_smartutxos_push(coin); coin->addr_listunspent_requested = 0; } - if ( coin->electrum == 0 && coin->inactive == 0 && time(NULL) > coin->lastgetinfo+LP_GETINFO_INCR ) + if ( coin->electrum == 0 && coin->inactive == 0 && now > coin->lastgetinfo+LP_GETINFO_INCR ) { nonz++; if ( (height= LP_getheight(coin)) > coin->longestchain ) @@ -627,7 +628,7 @@ int32_t LP_mainloop_iter(void *ctx,char *myipaddr,struct LP_peerinfo *mypeer,int 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); - coin->lastgetinfo = (uint32_t)time(NULL); + coin->lastgetinfo = (uint32_t)now; } } counter++; diff --git a/iguana/exchanges/LP_signatures.c b/iguana/exchanges/LP_signatures.c index 909e6bd74..1ac171c03 100644 --- a/iguana/exchanges/LP_signatures.c +++ b/iguana/exchanges/LP_signatures.c @@ -629,17 +629,6 @@ void LP_smartutxos_push(struct iguana_info *coin) vout = jint(item,"tx_pos"); value = j64bits(item,"value"); height = jint(item,"height"); -#ifdef FROM_JS - //if ( 0 && (rand() % 100) == 0 && IAMLP == 0 ) - { - struct LP_peerinfo *peer,*tmp; char *retstr; - HASH_ITER(hh,LP_peerinfos,peer,tmp) - { - if ( (retstr= issue_LP_uitem(peer->ipaddr,peer->port,coin->symbol,coin->smartaddr,txid,vout,height,value)) != 0 ) - free(retstr); - } - } -#else req = cJSON_CreateObject(); jaddstr(req,"method","uitem"); jaddstr(req,"coin",coin->symbol); @@ -650,7 +639,6 @@ void LP_smartutxos_push(struct iguana_info *coin) jadd64bits(req,"value",value); //printf("ADDR_UNSPENTS[] <- %s\n",jprint(req,0)); LP_reserved_msg(0,"","",zero,jprint(req,1)); -#endif } } free_json(array); From aa991bb70b1aaf55f6e762ad4e68d8d31d793e3b Mon Sep 17 00:00:00 2001 From: jl777 Date: Thu, 9 Nov 2017 21:42:36 +0200 Subject: [PATCH 0460/1664] Test --- iguana/exchanges/LP_ordermatch.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/iguana/exchanges/LP_ordermatch.c b/iguana/exchanges/LP_ordermatch.c index a94ed096c..137216143 100644 --- a/iguana/exchanges/LP_ordermatch.c +++ b/iguana/exchanges/LP_ordermatch.c @@ -968,15 +968,15 @@ char *LP_autobuy(void *ctx,char *myipaddr,int32_t mypubsock,char *base,char *rel destsatoshis = SATOSHIDEN * relvolume; if ( (autxo= LP_utxo_bestfit(rel,destsatoshis + 2*desttxfee)) == 0 ) return(clonestr("{\"error\":\"cant find alice utxo that is big enough\"}")); - if ( destsatoshis - 2*desttxfee < autxo->S.satoshis ) + if ( destsatoshis - 0*desttxfee < autxo->S.satoshis ) { - destsatoshis -= 2*desttxfee; + //destsatoshis -= 2*desttxfee; autxo->S.satoshis = destsatoshis; //printf("first path dest %.8f from %.8f\n",dstr(destsatoshis),dstr(autxo->S.satoshis)); } - else if ( autxo->S.satoshis - 2*desttxfee < destsatoshis ) + else if ( autxo->S.satoshis - 0*desttxfee < destsatoshis ) { - autxo->S.satoshis -= 2*desttxfee; + autxo->S.satoshis -= 0*desttxfee; destsatoshis = autxo->S.satoshis; printf("second path dest %.8f from %.8f\n",dstr(destsatoshis),dstr(autxo->S.satoshis)); } From 74654150792480f968612554a66cc2338b47a970 Mon Sep 17 00:00:00 2001 From: jl777 Date: Thu, 9 Nov 2017 21:47:14 +0200 Subject: [PATCH 0461/1664] Test --- iguana/exchanges/LP_ordermatch.c | 17 +++++++++++++---- 1 file changed, 13 insertions(+), 4 deletions(-) diff --git a/iguana/exchanges/LP_ordermatch.c b/iguana/exchanges/LP_ordermatch.c index 137216143..9f815a585 100644 --- a/iguana/exchanges/LP_ordermatch.c +++ b/iguana/exchanges/LP_ordermatch.c @@ -359,10 +359,14 @@ int32_t LP_connectstartbob(void *ctx,int32_t pubsock,struct LP_utxoinfo *utxo,cJ privkey = LP_privkey(utxo->coinaddr,coin->taddr); if ( bits256_nonz(privkey) != 0 && bits256_cmp(G.LP_mypub25519,qp->srchash) == 0 ) //qp->quotetime >= qp->timestamp-3 && qp->quotetime <= utxo->T.swappending && { + 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); + if ( (swap= LP_swapinit(1,0,privkey,&qp->R,qp)) == 0 ) + { + printf("cant initialize swap\n"); + return(-1); + } 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); - swap = LP_swapinit(1,0,privkey,&qp->R,qp); swap->N.pair = pair; utxo->S.swap = swap; swap->utxo = utxo; @@ -502,6 +506,13 @@ char *LP_connectedalice(cJSON *argjson) // alice if ( bits256_nonz(Q.privkey) != 0 )//&& Q.quotetime >= Q.timestamp-3 ) { retjson = cJSON_CreateObject(); + 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); + if ( (swap= LP_swapinit(0,0,Q.privkey,&Q.R,&Q)) == 0 ) + { + jaddstr(retjson,"error","couldnt swapinit"); + LP_availableset(autxo); + return(jprint(retjson,1)); + } if ( (pairstr= jstr(argjson,"pair")) == 0 || (pairsock= nn_socket(AF_SP,NN_PAIR)) < 0 ) jaddstr(retjson,"error","couldnt create pairsock"); else if ( nn_connect(pairsock,pairstr) >= 0 ) @@ -509,8 +520,6 @@ char *LP_connectedalice(cJSON *argjson) // alice //timeout = 1; //nn_setsockopt(pairsock,NN_SOL_SOCKET,NN_SNDTIMEO,&timeout,sizeof(timeout)); //nn_setsockopt(pairsock,NN_SOL_SOCKET,NN_RCVTIMEO,&timeout,sizeof(timeout)); - 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); - swap = LP_swapinit(0,0,Q.privkey,&Q.R,&Q); swap->tradeid = Q.tradeid; swap->N.pair = pairsock; autxo->S.swap = swap; From 2d8702cf8f169cb5c456236d833aae345d2baaa0 Mon Sep 17 00:00:00 2001 From: jl777 Date: Thu, 9 Nov 2017 22:02:39 +0200 Subject: [PATCH 0462/1664] Test --- iguana/exchanges/LP_swap.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/iguana/exchanges/LP_swap.c b/iguana/exchanges/LP_swap.c index 68fdea1ae..8671759fc 100644 --- a/iguana/exchanges/LP_swap.c +++ b/iguana/exchanges/LP_swap.c @@ -1016,7 +1016,7 @@ struct basilisk_swap *bitcoin_swapinit(bits256 privkey,uint8_t *pubkey33,bits256 printf("bitcoin_swapinit %s bobsatoshis %.8f rejected\n",swap->I.req.src,dstr(swap->I.bobsatoshis)); return(0); } - swap->I.alicesatoshis = swap->I.req.destamount; + if ( (swap->I.alicesatoshis= swap->I.req.destamount) <= 0 ) { printf("bitcoin_swapinit %s alicesatoshis %.8f rejected\n",swap->I.req.dest,dstr(swap->I.alicesatoshis)); return(0); From 9e15bbcfc4c0cca57639cfdf2776a9fbcc1973a9 Mon Sep 17 00:00:00 2001 From: jl777 Date: Thu, 9 Nov 2017 22:30:42 +0200 Subject: [PATCH 0463/1664] Test --- iguana/exchanges/LP_include.h | 2 +- iguana/exchanges/LP_remember.c | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/iguana/exchanges/LP_include.h b/iguana/exchanges/LP_include.h index e273515a6..314cf975a 100644 --- a/iguana/exchanges/LP_include.h +++ b/iguana/exchanges/LP_include.h @@ -77,7 +77,7 @@ void emscripten_usleep(int32_t x); // returns immediate, no sense for sleeping #define LP_MIN_TXFEE 10000 #define LP_MINVOL 20 #define LP_MINCLIENTVOL 1000 -#define LP_MINSIZE_TXFEEMULT 3 +#define LP_MINSIZE_TXFEEMULT 10 #define LP_REQUIRED_TXFEE 0.8 #define LP_DEXFEE(destsatoshis) ((destsatoshis) / INSTANTDEX_INSURANCEDIV) diff --git a/iguana/exchanges/LP_remember.c b/iguana/exchanges/LP_remember.c index f26467d3e..f8bc1a227 100644 --- a/iguana/exchanges/LP_remember.c +++ b/iguana/exchanges/LP_remember.c @@ -839,7 +839,7 @@ cJSON *basilisk_remember(int64_t *KMDtotals,int64_t *BTCtotals,uint32_t requesti 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("legacy DB SWAPS.(%u %u) %llu files BOB.(%s) Alice.(%s) src.(%s) dest.(%s)\n",rswap.requestid,rswap.quoteid,(long long)rswap.aliceid,rswap.bobcoin,rswap.alicecoin,rswap.src,rswap.dest); + //printf("legacy DB SWAPS.(%u %u) %llu files BOB.(%s) Alice.(%s) src.(%s) dest.(%s)\n",rswap.requestid,rswap.quoteid,(long long)rswap.aliceid,rswap.bobcoin,rswap.alicecoin,rswap.src,rswap.dest); return(cJSON_Parse("{\"error\":\"mismatched bob/alice vs src/dest coins??\"}")); } alice = LP_coinfind(rswap.alicecoin); From 8f4ab8a4d633f6f51cc627e79e27c64c99d9f051 Mon Sep 17 00:00:00 2001 From: jl777 Date: Thu, 9 Nov 2017 22:40:40 +0200 Subject: [PATCH 0464/1664] Test --- iguana/exchanges/LP_network.c | 1 + 1 file changed, 1 insertion(+) diff --git a/iguana/exchanges/LP_network.c b/iguana/exchanges/LP_network.c index 1112532ab..f553aca6c 100644 --- a/iguana/exchanges/LP_network.c +++ b/iguana/exchanges/LP_network.c @@ -356,6 +356,7 @@ void queue_loop(void *arg) portable_mutex_unlock(&LP_networkmutex); free(ptr); ptr = 0; + break; } } if ( arg == 0 ) From e655f82bfb434533aef90923bca05944d2250165 Mon Sep 17 00:00:00 2001 From: jl777 Date: Thu, 9 Nov 2017 23:02:44 +0200 Subject: [PATCH 0465/1664] Bot status --- iguana/exchanges/LP_include.h | 1 + iguana/exchanges/LP_nativeDEX.c | 1 - iguana/exchanges/LP_ordermatch.c | 37 ++++++++++++++++++++++++++++++-- iguana/exchanges/LP_tradebots.c | 28 +++++++++++++++++++++++- 4 files changed, 63 insertions(+), 4 deletions(-) diff --git a/iguana/exchanges/LP_include.h b/iguana/exchanges/LP_include.h index 314cf975a..e5a045e33 100644 --- a/iguana/exchanges/LP_include.h +++ b/iguana/exchanges/LP_include.h @@ -392,6 +392,7 @@ 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); +void LP_aliceid(uint32_t tradeid,uint64_t aliceid,char *event,uint32_t requestid,uint32_t quoteid); uint64_t LP_RTsmartbalance(struct iguana_info *coin); int32_t LP_getheight(struct iguana_info *coin); int32_t LP_reserved_msg(int32_t priority,char *base,char *rel,bits256 pubkey,char *msg); diff --git a/iguana/exchanges/LP_nativeDEX.c b/iguana/exchanges/LP_nativeDEX.c index 28be65d12..13b14f8ee 100644 --- a/iguana/exchanges/LP_nativeDEX.c +++ b/iguana/exchanges/LP_nativeDEX.c @@ -19,7 +19,6 @@ // marketmaker // // detecting new deposits in inventory -// BTC swaps // bot progress // swap started event for bot // bot status 1600% ? diff --git a/iguana/exchanges/LP_ordermatch.c b/iguana/exchanges/LP_ordermatch.c index 9f815a585..f6e1f325f 100644 --- a/iguana/exchanges/LP_ordermatch.c +++ b/iguana/exchanges/LP_ordermatch.c @@ -464,9 +464,15 @@ char *LP_connectedalice(cJSON *argjson) // alice { cJSON *retjson; double bid,ask,price,qprice; int32_t pairsock = -1; char *pairstr; int32_t DEXselector = 0; struct LP_utxoinfo *autxo,B,*butxo; struct LP_quoteinfo Q; struct basilisk_swap *swap; struct iguana_info *coin; //uint64_t value,value2; if ( LP_quoteparse(&Q,argjson) < 0 ) + { + LP_aliceid(Q.tradeid,Q.aliceid,"error0",0,0); clonestr("{\"error\":\"cant parse quote\"}"); + } if ( bits256_cmp(Q.desthash,G.LP_mypub25519) != 0 ) + { + LP_aliceid(Q.tradeid,Q.aliceid,"error1",0,0); return(clonestr("{\"result\",\"update stats\"}")); + } printf("CONNECTED.(%s) numpending.%d tradeid.%u\n",jprint(argjson,0),G.LP_pendingswaps,Q.tradeid); /*if ( LP_alice_eligible() == 0 || LP_quotecmp(&Q,&LP_Alicequery) != 0 ) { @@ -479,16 +485,22 @@ char *LP_connectedalice(cJSON *argjson) // alice if ( (autxo= LP_utxopairfind(0,Q.desttxid,Q.destvout,Q.feetxid,Q.feevout)) == 0 ) { printf("cant find autxo\n"); + LP_aliceid(Q.tradeid,Q.aliceid,"error2",0,0); return(clonestr("{\"error\":\"cant find autxo\"}")); } if ( autxo->S.swap != 0 ) + { + LP_aliceid(Q.tradeid,Q.aliceid,"error3",0,0); return(clonestr("{\"error\":\"ignore duplicate swap\"}")); + } + LP_aliceid(Q.tradeid,Q.aliceid,"connected",Q.R.requestid,Q.R.quoteid); butxo = &B; memset(butxo,0,sizeof(*butxo)); LP_abutxo_set(0,butxo,&Q); if ( (qprice= LP_quote_validate(autxo,butxo,&Q,0)) <= SMALLVAL ) { LP_availableset(autxo); + LP_aliceid(Q.tradeid,Q.aliceid,"error4",0,0); printf("quote validate error %.0f\n",qprice); return(clonestr("{\"error\":\"quote validation error\"}")); } @@ -496,12 +508,16 @@ char *LP_connectedalice(cJSON *argjson) // alice { printf("this node has no price for %s/%s (%.8f %.8f)\n",Q.destcoin,Q.srccoin,bid,ask); LP_availableset(autxo); + LP_aliceid(Q.tradeid,Q.aliceid,"error5",0,0); return(clonestr("{\"error\":\"no price set\"}")); } printf("%s/%s bid %.8f ask %.8f values %.8f %.8f\n",Q.srccoin,Q.destcoin,bid,ask,dstr(butxo->payment.value),dstr(butxo->deposit.value)); price = bid; if ( (coin= LP_coinfind(Q.destcoin)) == 0 ) + { + LP_aliceid(Q.tradeid,Q.aliceid,"error6",0,0); 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 ) { @@ -511,10 +527,14 @@ char *LP_connectedalice(cJSON *argjson) // alice { jaddstr(retjson,"error","couldnt swapinit"); LP_availableset(autxo); + LP_aliceid(Q.tradeid,Q.aliceid,"error7",Q.R.requestid,Q.R.quoteid); return(jprint(retjson,1)); } if ( (pairstr= jstr(argjson,"pair")) == 0 || (pairsock= nn_socket(AF_SP,NN_PAIR)) < 0 ) + { + LP_aliceid(Q.tradeid,Q.aliceid,"error8",Q.R.requestid,Q.R.quoteid); jaddstr(retjson,"error","couldnt create pairsock"); + } else if ( nn_connect(pairsock,pairstr) >= 0 ) { //timeout = 1; @@ -524,6 +544,7 @@ char *LP_connectedalice(cJSON *argjson) // alice swap->N.pair = pairsock; autxo->S.swap = swap; swap->utxo = autxo; + LP_aliceid(Q.tradeid,Q.aliceid,"started",Q.R.requestid,Q.R.quoteid); printf("alice pairstr.(%s) pairsock.%d\n",pairstr,pairsock); if ( OS_thread_create(malloc(sizeof(pthread_t)),NULL,(void *)LP_aliceloop,(void *)swap) == 0 ) { @@ -531,8 +552,18 @@ char *LP_connectedalice(cJSON *argjson) // alice jaddstr(retjson,"result","success"); //jaddnum(retjson,"requestid",Q.R.requestid); //jaddnum(retjson,"quoteid",Q.R.quoteid); - } else jaddstr(retjson,"error","couldnt aliceloop"); - } else printf("connect error %s\n",nn_strerror(nn_errno())); + } + else + { + LP_aliceid(Q.tradeid,Q.aliceid,"error9",Q.R.requestid,Q.R.quoteid); + jaddstr(retjson,"error","couldnt aliceloop"); + } + } + else + { + LP_aliceid(Q.tradeid,Q.aliceid,"error10",Q.R.requestid,Q.R.quoteid); + printf("connect error %s\n",nn_strerror(nn_errno())); + } printf("connected result.(%s)\n",jprint(retjson,0)); if ( jobj(retjson,"error") != 0 ) LP_availableset(autxo); @@ -541,6 +572,7 @@ char *LP_connectedalice(cJSON *argjson) // alice else { LP_availableset(autxo); + LP_aliceid(Q.tradeid,Q.aliceid,"error11",0,0); printf("no privkey found coin.%s %s taddr.%u\n",Q.destcoin,Q.destaddr,coin->taddr); return(clonestr("{\"error\",\"no privkey\"}")); } @@ -658,6 +690,7 @@ int32_t LP_tradecommand(void *ctx,char *myipaddr,int32_t pubsock,cJSON *argjson, } if ( bits256_cmp(G.LP_mypub25519,Q.desthash) == 0 && bits256_cmp(G.LP_mypub25519,Q.srchash) != 0 && LP_alice_eligible() > 0 ) { + LP_aliceid(Q.tradeid,Q.aliceid,"reserved",0,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); diff --git a/iguana/exchanges/LP_tradebots.c b/iguana/exchanges/LP_tradebots.c index e42fc369c..862d68883 100644 --- a/iguana/exchanges/LP_tradebots.c +++ b/iguana/exchanges/LP_tradebots.c @@ -27,7 +27,7 @@ struct LP_tradebot_trade uint64_t aliceid; int32_t dispdir; uint32_t started,finished,requestid,quoteid,tradeid; - char base[32],rel[32]; + char base[32],rel[32],event[32]; }; struct LP_tradebot @@ -100,11 +100,15 @@ cJSON *LP_tradebot_tradejson(struct LP_tradebot_trade *tp,int32_t dispflag) double price,basevol; cJSON *item = cJSON_CreateObject(); if ( tp == 0 ) return(cJSON_Parse("{}")); + if ( tp->event[0] != 0 ) + jaddstr(item,"status",tp->event); if ( tp->requestid != 0 && tp->quoteid != 0 ) { jaddnum(item,"requestid",tp->requestid); jaddnum(item,"quoteid",tp->quoteid); } else jaddnum(item,"tradeid",tp->tradeid); + if ( tp->aliceid != 0 ) + jadd64bits(item,"aliceid",tp->aliceid); if ( tp->basevol > SMALLVAL && tp->relvol > SMALLVAL ) { if ( dispflag > 0 ) @@ -338,6 +342,28 @@ void LP_tradebot_timeslice(void *ctx,struct LP_tradebot *bot) bot->pause = (uint32_t)time(NULL); } +void LP_aliceid(uint32_t tradeid,uint64_t aliceid,char *event,uint32_t requestid,uint32_t quoteid) +{ + struct LP_tradebot *bot,*tmp; int32_t i; struct LP_tradebot_trade *tp; + DL_FOREACH_SAFE(LP_tradebots,bot,tmp) + { + for (i=0; inumtrades; i++) + { + if ( (tp= bot->trades[i]) != 0 && tp->finished == 0 && tp->tradeid == tradeid ) + { + tp->aliceid = aliceid; + if ( requestid != 0 && quoteid != 0 ) + { + tp->requestid = requestid; + tp->quoteid = quoteid; + } + strcpy(tp->event,event); + break; + } + } + } +} + void LP_tradebot_finished(uint32_t tradeid,uint32_t requestid,uint32_t quoteid) { struct LP_tradebot *bot,*tmp; int32_t i; struct LP_tradebot_trade *tp; From 76dcacdbe483d64dbbba7898745bc5f2b755b9b9 Mon Sep 17 00:00:00 2001 From: jl777 Date: Thu, 9 Nov 2017 23:24:05 +0200 Subject: [PATCH 0466/1664] Test --- iguana/exchanges/LP_utxo.c | 18 ++++++++++++------ 1 file changed, 12 insertions(+), 6 deletions(-) diff --git a/iguana/exchanges/LP_utxo.c b/iguana/exchanges/LP_utxo.c index 17814f4be..076e6729d 100644 --- a/iguana/exchanges/LP_utxo.c +++ b/iguana/exchanges/LP_utxo.c @@ -118,22 +118,22 @@ struct LP_utxoinfo *LP_allocated(bits256 txid,int32_t vout) struct LP_utxoinfo *utxo; if ( (utxo= _LP_utxofind(0,txid,vout)) != 0 && LP_isavailable(utxo) == 0 ) { - char str[65]; printf("%s/v%d not available\n",bits256_str(str,txid),vout); + //char str[65]; printf("%s/v%d not available\n",bits256_str(str,txid),vout); return(utxo); } if ( (utxo= _LP_utxo2find(0,txid,vout)) != 0 && LP_isavailable(utxo) == 0 ) { - char str[65]; printf("%s/v%d not available2\n",bits256_str(str,txid),vout); + //char str[65]; printf("%s/v%d not available2\n",bits256_str(str,txid),vout); return(utxo); } if ( (utxo= _LP_utxofind(1,txid,vout)) != 0 && LP_isavailable(utxo) == 0 ) { - char str[65]; printf("%s/v%d not available\n",bits256_str(str,txid),vout); + //char str[65]; printf("%s/v%d not available\n",bits256_str(str,txid),vout); return(utxo); } if ( (utxo= _LP_utxo2find(1,txid,vout)) != 0 && LP_isavailable(utxo) == 0 ) { - char str[65]; printf("%s/v%d not available2\n",bits256_str(str,txid),vout); + //char str[65]; printf("%s/v%d not available2\n",bits256_str(str,txid),vout); return(utxo); } return(0); @@ -976,10 +976,14 @@ int32_t LP_iseligible(uint64_t *valp,uint64_t *val2p,int32_t iambob,char *symbol int32_t LP_inventory_prevent(int32_t iambob,char *symbol,bits256 txid,int32_t vout) { - struct LP_utxoinfo *utxo; struct LP_transaction *tx; struct iguana_info *coin; + struct LP_address_utxo *up; struct LP_utxoinfo *utxo; struct LP_transaction *tx; struct iguana_info *coin; + if ( (coin= LP_coinfind(symbol)) == 0 ) + return(1); + if ( LP_allocated(txid,vout) != 0 ) + return(1); if ( (utxo= LP_utxofind(iambob,txid,vout)) != 0 || (utxo= LP_utxo2find(iambob,txid,vout)) != 0 ) { - if ( (coin= LP_coinfind(symbol)) != 0 && (tx= LP_transactionfind(coin,txid)) != 0 ) + if ( coin != 0 && (tx= LP_transactionfind(coin,txid)) != 0 ) { if ( tx->outpoints[vout].spendheight > 0 ) utxo->T.spentflag = tx->outpoints[vout].spendheight; @@ -991,6 +995,8 @@ int32_t LP_inventory_prevent(int32_t iambob,char *symbol,bits256 txid,int32_t vo return(1); } } + if ( (up= LP_address_utxofind(coin,coin->smartaddr,txid,vout)) != 0 && up->spendheight > 0 ) + return(1); return(0); } From 58548ead1062c3d924ed411c5ba5925b8ec88b90 Mon Sep 17 00:00:00 2001 From: jl777 Date: Thu, 9 Nov 2017 23:41:59 +0200 Subject: [PATCH 0467/1664] Test --- iguana/exchanges/LP_rpc.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/iguana/exchanges/LP_rpc.c b/iguana/exchanges/LP_rpc.c index f7bf6a38f..661c476e6 100644 --- a/iguana/exchanges/LP_rpc.c +++ b/iguana/exchanges/LP_rpc.c @@ -635,7 +635,7 @@ cJSON *LP_listunspent(char *symbol,char *coinaddr) sprintf(buf,"[%d, 99999999, [\"%s\"]]",numconfs,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,2)); + } else return(electrum_address_listunspent(symbol,coin->electrum,&retjson,coinaddr,1)); } int32_t LP_listunspent_issue(char *symbol,char *coinaddr,int32_t fullflag) From cd5f624e73ae7490cf7c0865740a233d217233e6 Mon Sep 17 00:00:00 2001 From: jl777 Date: Fri, 10 Nov 2017 00:30:27 +0200 Subject: [PATCH 0468/1664] Test --- iguana/exchanges/LP_nativeDEX.c | 3 --- iguana/exchanges/LP_ordermatch.c | 8 ++++---- 2 files changed, 4 insertions(+), 7 deletions(-) diff --git a/iguana/exchanges/LP_nativeDEX.c b/iguana/exchanges/LP_nativeDEX.c index 13b14f8ee..b51741787 100644 --- a/iguana/exchanges/LP_nativeDEX.c +++ b/iguana/exchanges/LP_nativeDEX.c @@ -18,9 +18,6 @@ // LP_nativeDEX.c // marketmaker // -// detecting new deposits in inventory -// bot progress -// swap started event for bot // bot status 1600% ? // BCH signing diff --git a/iguana/exchanges/LP_ordermatch.c b/iguana/exchanges/LP_ordermatch.c index f6e1f325f..cf4560de3 100644 --- a/iguana/exchanges/LP_ordermatch.c +++ b/iguana/exchanges/LP_ordermatch.c @@ -1010,15 +1010,15 @@ char *LP_autobuy(void *ctx,char *myipaddr,int32_t mypubsock,char *base,char *rel destsatoshis = SATOSHIDEN * relvolume; if ( (autxo= LP_utxo_bestfit(rel,destsatoshis + 2*desttxfee)) == 0 ) return(clonestr("{\"error\":\"cant find alice utxo that is big enough\"}")); - if ( destsatoshis - 0*desttxfee < autxo->S.satoshis ) + if ( destsatoshis - desttxfee < autxo->S.satoshis ) { - //destsatoshis -= 2*desttxfee; + destsatoshis -= desttxfee; autxo->S.satoshis = destsatoshis; //printf("first path dest %.8f from %.8f\n",dstr(destsatoshis),dstr(autxo->S.satoshis)); } - else if ( autxo->S.satoshis - 0*desttxfee < destsatoshis ) + else if ( autxo->S.satoshis - desttxfee < destsatoshis ) { - autxo->S.satoshis -= 0*desttxfee; + autxo->S.satoshis -= desttxfee; destsatoshis = autxo->S.satoshis; printf("second path dest %.8f from %.8f\n",dstr(destsatoshis),dstr(autxo->S.satoshis)); } From eb3d403d0c97f4d25e92d5ce2b42996d16e8ad37 Mon Sep 17 00:00:00 2001 From: jl777 Date: Fri, 10 Nov 2017 00:44:26 +0200 Subject: [PATCH 0469/1664] Test --- iguana/exchanges/LP_ordermatch.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/iguana/exchanges/LP_ordermatch.c b/iguana/exchanges/LP_ordermatch.c index cf4560de3..f6e1f325f 100644 --- a/iguana/exchanges/LP_ordermatch.c +++ b/iguana/exchanges/LP_ordermatch.c @@ -1010,15 +1010,15 @@ char *LP_autobuy(void *ctx,char *myipaddr,int32_t mypubsock,char *base,char *rel destsatoshis = SATOSHIDEN * relvolume; if ( (autxo= LP_utxo_bestfit(rel,destsatoshis + 2*desttxfee)) == 0 ) return(clonestr("{\"error\":\"cant find alice utxo that is big enough\"}")); - if ( destsatoshis - desttxfee < autxo->S.satoshis ) + if ( destsatoshis - 0*desttxfee < autxo->S.satoshis ) { - destsatoshis -= desttxfee; + //destsatoshis -= 2*desttxfee; autxo->S.satoshis = destsatoshis; //printf("first path dest %.8f from %.8f\n",dstr(destsatoshis),dstr(autxo->S.satoshis)); } - else if ( autxo->S.satoshis - desttxfee < destsatoshis ) + else if ( autxo->S.satoshis - 0*desttxfee < destsatoshis ) { - autxo->S.satoshis -= desttxfee; + autxo->S.satoshis -= 0*desttxfee; destsatoshis = autxo->S.satoshis; printf("second path dest %.8f from %.8f\n",dstr(destsatoshis),dstr(autxo->S.satoshis)); } From 2308f7fb197da0cc1a74e95f0cbeb29ee78e617d Mon Sep 17 00:00:00 2001 From: jl777 Date: Fri, 10 Nov 2017 05:21:11 +0200 Subject: [PATCH 0470/1664] Avoid bot pause --- iguana/exchanges/LP_tradebots.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/iguana/exchanges/LP_tradebots.c b/iguana/exchanges/LP_tradebots.c index 862d68883..55d1ddabe 100644 --- a/iguana/exchanges/LP_tradebots.c +++ b/iguana/exchanges/LP_tradebots.c @@ -291,7 +291,7 @@ double LP_orderbook_maxrel(char *base,char *rel,double maxprice) void LP_tradebot_timeslice(void *ctx,struct LP_tradebot *bot) { - double remaining,maxrel; int32_t i,maxiters = 10; uint32_t tradeid; bits256 destpubkey; char *retstr,*liststr; cJSON *retjson,*retjson2,*pending; + double remaining,maxrel; struct LP_tradebot_trade *tp; int32_t i,maxiters = 10; uint32_t tradeid; bits256 destpubkey; char *retstr,*liststr; cJSON *retjson,*retjson2,*pending; memset(destpubkey.bytes,0,sizeof(destpubkey)); if ( bot->dead == 0 && bot->pause == 0 && bot->numtrades < sizeof(bot->trades)/sizeof(*bot->trades) ) { @@ -317,10 +317,10 @@ void LP_tradebot_timeslice(void *ctx,struct LP_tradebot *bot) { if ( (pending= jobj(retjson2,"pending")) != 0 && juint(pending,"tradeid") == tradeid ) { - bot->trades[bot->numtrades++] = LP_tradebot_pending(bot,pending,tradeid); + bot->trades[bot->numtrades++] = tp = LP_tradebot_pending(bot,pending,tradeid); if ( bot->relsum >= 0.99*bot->totalrelvolume-SMALLVAL || bot->basesum >= 0.99*bot->totalbasevolume-SMALLVAL ) bot->dead = (uint32_t)time(NULL); - else if ( (bot->pendrelsum+bot->relsum) >= 0.99*bot->totalrelvolume-SMALLVAL || (bot->basesum+bot->pendbasesum) >= 0.99*bot->totalbasevolume-SMALLVAL ) + else if ( tp->requestid != 0 && ((bot->pendrelsum+bot->relsum) >= 0.99*bot->totalrelvolume-SMALLVAL || (bot->basesum+bot->pendbasesum) >= 0.99*bot->totalbasevolume-SMALLVAL) ) bot->pause = (uint32_t)time(NULL); printf("issued bot trade.%u %s\n",tradeid,retstr); free_json(retjson2); From 752d4fa637043fa43fe826f171e2eb06df963e52 Mon Sep 17 00:00:00 2001 From: jl777 Date: Fri, 10 Nov 2017 05:23:44 +0200 Subject: [PATCH 0471/1664] Test --- iguana/exchanges/LP_tradebots.c | 1 + 1 file changed, 1 insertion(+) diff --git a/iguana/exchanges/LP_tradebots.c b/iguana/exchanges/LP_tradebots.c index 55d1ddabe..144786a77 100644 --- a/iguana/exchanges/LP_tradebots.c +++ b/iguana/exchanges/LP_tradebots.c @@ -318,6 +318,7 @@ void LP_tradebot_timeslice(void *ctx,struct LP_tradebot *bot) if ( (pending= jobj(retjson2,"pending")) != 0 && juint(pending,"tradeid") == tradeid ) { bot->trades[bot->numtrades++] = tp = LP_tradebot_pending(bot,pending,tradeid); + sleep(3); if ( bot->relsum >= 0.99*bot->totalrelvolume-SMALLVAL || bot->basesum >= 0.99*bot->totalbasevolume-SMALLVAL ) bot->dead = (uint32_t)time(NULL); else if ( tp->requestid != 0 && ((bot->pendrelsum+bot->relsum) >= 0.99*bot->totalrelvolume-SMALLVAL || (bot->basesum+bot->pendbasesum) >= 0.99*bot->totalbasevolume-SMALLVAL) ) From 0374147cc0d3c5e0fdba07dcda83fb82f92eeaa5 Mon Sep 17 00:00:00 2001 From: jl777 Date: Fri, 10 Nov 2017 06:07:59 +0200 Subject: [PATCH 0472/1664] Test --- iguana/exchanges/LP_tradebots.c | 57 +++++++++++++++++++++------------ 1 file changed, 36 insertions(+), 21 deletions(-) diff --git a/iguana/exchanges/LP_tradebots.c b/iguana/exchanges/LP_tradebots.c index 144786a77..f9ae94852 100644 --- a/iguana/exchanges/LP_tradebots.c +++ b/iguana/exchanges/LP_tradebots.c @@ -26,7 +26,7 @@ struct LP_tradebot_trade double maxprice,totalrelvolume,basevol,relvol; uint64_t aliceid; int32_t dispdir; - uint32_t started,finished,requestid,quoteid,tradeid; + uint32_t started,finished,requestid,quoteid,tradeid,completed; char base[32],rel[32],event[32]; }; @@ -255,9 +255,9 @@ struct LP_tradebot_trade *LP_tradebot_pending(struct LP_tradebot *bot,cJSON *pen tp->basevol = jdouble(pending,"basevalue"); tp->relvol = jdouble(pending,"relvalue"); printf("tradebot pending basevol %.8f relvol %.8f\n",tp->basevol,tp->relvol); - bot->pendrelsum += tp->relvol; - bot->pendbasesum += tp->basevol; - bot->numpending++; + //bot->pendrelsum += tp->relvol; + //bot->pendbasesum += tp->basevol; + //bot->numpending++; return(tp); } @@ -318,11 +318,6 @@ void LP_tradebot_timeslice(void *ctx,struct LP_tradebot *bot) if ( (pending= jobj(retjson2,"pending")) != 0 && juint(pending,"tradeid") == tradeid ) { bot->trades[bot->numtrades++] = tp = LP_tradebot_pending(bot,pending,tradeid); - sleep(3); - if ( bot->relsum >= 0.99*bot->totalrelvolume-SMALLVAL || bot->basesum >= 0.99*bot->totalbasevolume-SMALLVAL ) - bot->dead = (uint32_t)time(NULL); - else if ( tp->requestid != 0 && ((bot->pendrelsum+bot->relsum) >= 0.99*bot->totalrelvolume-SMALLVAL || (bot->basesum+bot->pendbasesum) >= 0.99*bot->totalbasevolume-SMALLVAL) ) - bot->pause = (uint32_t)time(NULL); printf("issued bot trade.%u %s\n",tradeid,retstr); free_json(retjson2); free(retstr); @@ -376,11 +371,11 @@ void LP_tradebot_finished(uint32_t tradeid,uint32_t requestid,uint32_t quoteid) { tp->requestid = requestid; tp->quoteid = quoteid; - bot->pendbasesum -= tp->basevol, bot->basesum += tp->basevol; - bot->pendrelsum -= tp->relvol, bot->relsum += tp->relvol; - bot->numpending--, bot->completed++; + //bot->pendbasesum -= tp->basevol, bot->basesum += tp->basevol; + //bot->pendrelsum -= tp->relvol, bot->relsum += tp->relvol; + //bot->numpending--, bot->completed++; printf("bot.%u detected completion tradeid.%u aliceid.%llx r.%u q.%u, numpending.%d completed.%d\n",bot->id,tp->tradeid,(long long)tp->aliceid,tp->requestid,tp->quoteid,bot->numpending,bot->completed); - tp->finished = (uint32_t)time(NULL); + tp->completed = tp->finished = (uint32_t)time(NULL); break; } } @@ -398,22 +393,42 @@ void LP_tradebots_timeslice(void *ctx) if ( bot->numpending > 0 && LP_numfinished > lastnumfinished ) { // expire pending trades and see if any still need their requestid/quoteid + bot->basesum = bot->pendbasesum = 0.;//-= tp->basevol; + bot->relsum = bot->pendrelsum = 0.;//-= tp->relvol; + bot->completed = bot->numpending = 0;//--; for (i=0; inumtrades; i++) { - if ( (tp= bot->trades[i]) != 0 && tp->finished == 0 ) + if ( (tp= bot->trades[i]) != 0 ) { - if ( time(NULL) > tp->started+INSTANTDEX_LOCKTIME*2 ) + if (tp->finished == 0 ) { - bot->pendbasesum -= tp->basevol; - bot->pendrelsum -= tp->relvol; - bot->numpending--; - tp->finished = (uint32_t)time(NULL); - printf("%s trade.%d of %d expired\n",bot->name,i,bot->numtrades); + if ( time(NULL) > tp->started+INSTANTDEX_LOCKTIME*2 ) + { + tp->finished = (uint32_t)time(NULL); + printf("%s trade.%d of %d expired\n",bot->name,i,bot->numtrades); + } + } + if ( tp->finished != 0 && tp->completed != 0 ) + { + bot->basesum += tp->basevol; + bot->relsum += tp->relvol; + bot->completed++; + } + else if ( tp->finished == 0 && tp->requestid != 0 && tp->quoteid != 0 ) + { + bot->pendbasesum += tp->basevol; + bot->pendrelsum += tp->relvol; + bot->numpending++; } } } } - else if ( bot->numpending == 0 ) + if ( bot->relsum >= 0.99*bot->totalrelvolume-SMALLVAL || bot->basesum >= 0.99*bot->totalbasevolume-SMALLVAL ) + bot->dead = (uint32_t)time(NULL); + else if ( (bot->pendrelsum+bot->relsum) >= 0.99*bot->totalrelvolume-SMALLVAL || (bot->basesum+bot->pendbasesum) >= 0.99*bot->totalbasevolume-SMALLVAL ) + bot->pause = (uint32_t)time(NULL); + else bot->pause = 0; + if ( bot->numpending == 0 ) LP_tradebot_timeslice(ctx,bot); } lastnumfinished = LP_numfinished; From bdf651e6f8a727f1e02c7ea8ee631514840aab31 Mon Sep 17 00:00:00 2001 From: jl777 Date: Fri, 10 Nov 2017 06:15:03 +0200 Subject: [PATCH 0473/1664] Test --- iguana/exchanges/LP_tradebots.c | 17 +++++++++-------- 1 file changed, 9 insertions(+), 8 deletions(-) diff --git a/iguana/exchanges/LP_tradebots.c b/iguana/exchanges/LP_tradebots.c index f9ae94852..e80eac6e1 100644 --- a/iguana/exchanges/LP_tradebots.c +++ b/iguana/exchanges/LP_tradebots.c @@ -36,7 +36,7 @@ struct LP_tradebot char name[128],base[32],rel[32]; int32_t numtrades,numpending,completed,dispdir; double maxprice,totalrelvolume,totalbasevolume,basesum,relsum,pendbasesum,pendrelsum; - uint32_t dead,pause,started,id; + uint32_t dead,pause,userpause,started,id; struct LP_tradebot_trade *trades[LP_TRADEBOTS_MAXTRADES]; } *LP_tradebots; @@ -134,8 +134,8 @@ cJSON *LP_tradebot_json(struct LP_tradebot *bot) jaddstr(json,"name",bot->name); jaddnum(json,"botid",bot->id); jaddnum(json,"started",bot->started); - if ( bot->pause != 0 ) - jaddnum(json,"paused",bot->pause); + if ( bot->pause != 0 || bot->userpause != 0 ) + jaddnum(json,"paused",bot->userpause != 0 ? bot->userpause : bot->pause); if ( bot->dead != 0 ) jaddnum(json,"stopped",bot->dead); if ( bot->dispdir > 0 ) @@ -293,7 +293,7 @@ void LP_tradebot_timeslice(void *ctx,struct LP_tradebot *bot) { double remaining,maxrel; struct LP_tradebot_trade *tp; int32_t i,maxiters = 10; uint32_t tradeid; bits256 destpubkey; char *retstr,*liststr; cJSON *retjson,*retjson2,*pending; memset(destpubkey.bytes,0,sizeof(destpubkey)); - if ( bot->dead == 0 && bot->pause == 0 && bot->numtrades < sizeof(bot->trades)/sizeof(*bot->trades) ) + if ( bot->dead == 0 && bot->pause == 0 && bot->userpause == 0 && bot->numtrades < sizeof(bot->trades)/sizeof(*bot->trades) ) { if ( (liststr= LP_recent_swaps(0)) != 0 ) { @@ -427,7 +427,8 @@ void LP_tradebots_timeslice(void *ctx) bot->dead = (uint32_t)time(NULL); else if ( (bot->pendrelsum+bot->relsum) >= 0.99*bot->totalrelvolume-SMALLVAL || (bot->basesum+bot->pendbasesum) >= 0.99*bot->totalbasevolume-SMALLVAL ) bot->pause = (uint32_t)time(NULL); - else bot->pause = 0; + else if ( bot->userpause == 0 ) + bot->pause = 0; if ( bot->numpending == 0 ) LP_tradebot_timeslice(ctx,bot); } @@ -629,7 +630,7 @@ char *LP_tradebot_pause(void *ctx,int32_t pubsock,cJSON *argjson,uint32_t botid) { if ( bot->dead != 0 ) return(clonestr("{\"error\":\"botid aleady stopped\"}")); - bot->pause = (uint32_t)time(NULL); + bot->userpause = (uint32_t)time(NULL); return(clonestr("{\"result\":\"success\"}")); } return(clonestr("{\"error\":\"couldnt find botid\"}")); @@ -642,9 +643,9 @@ char *LP_tradebot_resume(void *ctx,int32_t pubsock,cJSON *argjson,uint32_t botid { if ( bot->dead != 0 ) return(clonestr("{\"error\":\"botid aleady stopped\"}")); - if ( bot->pause == 0 ) + if ( bot->userpause == 0 ) return(clonestr("{\"result\":\"success\",\"status\":\"botid not paused\"}")); - bot->pause = 0; + bot->userpause = 0; return(clonestr("{\"result\":\"success\"}")); } return(clonestr("{\"error\":\"couldnt find botid\"}")); From b985f7988409490777755eca8b958c7cde0525d5 Mon Sep 17 00:00:00 2001 From: jl777 Date: Fri, 10 Nov 2017 06:23:50 +0200 Subject: [PATCH 0474/1664] Test --- iguana/exchanges/LP_tradebots.c | 1 + 1 file changed, 1 insertion(+) diff --git a/iguana/exchanges/LP_tradebots.c b/iguana/exchanges/LP_tradebots.c index e80eac6e1..5894009dc 100644 --- a/iguana/exchanges/LP_tradebots.c +++ b/iguana/exchanges/LP_tradebots.c @@ -348,6 +348,7 @@ void LP_aliceid(uint32_t tradeid,uint64_t aliceid,char *event,uint32_t requestid if ( (tp= bot->trades[i]) != 0 && tp->finished == 0 && tp->tradeid == tradeid ) { tp->aliceid = aliceid; + printf("bot event tradeid.%u aliceid.%llu %s r.%u q.%u\n",tradeid,(long long)aliceid,event,requestid,quoteid); if ( requestid != 0 && quoteid != 0 ) { tp->requestid = requestid; From 33dc83ecbcd1a1ef9cf9157f0a8f2858b24283fb Mon Sep 17 00:00:00 2001 From: jl777 Date: Fri, 10 Nov 2017 06:32:53 +0200 Subject: [PATCH 0475/1664] Test --- iguana/exchanges/LP_network.c | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/iguana/exchanges/LP_network.c b/iguana/exchanges/LP_network.c index f553aca6c..101313348 100644 --- a/iguana/exchanges/LP_network.c +++ b/iguana/exchanges/LP_network.c @@ -409,7 +409,11 @@ void LP_broadcast_finish(int32_t pubsock,char *base,char *rel,uint8_t *msg,cJSON msglen = (int32_t)strlen((char *)msg) + 1; if ( crc32 == 0 ) crc32 = calc_crc32(0,&msg[2],msglen - 2); +#ifdef FROM_MARKETMAKER if ( G.LP_IAMLP == 0 ) +#else + if ( IAMLP == 0 ) +#endif { free(msg); //printf("broadcast %s\n",jstr(argjson,"method")); From cf9c06843be53d1ac1af8b8a62510bf4db8fb095 Mon Sep 17 00:00:00 2001 From: jl777 Date: Fri, 10 Nov 2017 06:35:50 +0200 Subject: [PATCH 0476/1664] Test --- iguana/exchanges/stats.c | 1 + 1 file changed, 1 insertion(+) diff --git a/iguana/exchanges/stats.c b/iguana/exchanges/stats.c index 51c68d9c8..4fbe699d1 100644 --- a/iguana/exchanges/stats.c +++ b/iguana/exchanges/stats.c @@ -822,6 +822,7 @@ continue; #ifndef FROM_MARKETMAKER portable_mutex_t LP_commandmutex; +uint16_t LP_RPCPORT; void stats_kvjson(FILE *logfp,int32_t height,int32_t savedheight,uint32_t timestamp,char *key,cJSON *kvjson,bits256 pubkey,bits256 sigprev) { From 53358d03c037e8fbcc3d275abee087921f59f93f Mon Sep 17 00:00:00 2001 From: jl777 Date: Fri, 10 Nov 2017 06:38:19 +0200 Subject: [PATCH 0477/1664] Test --- iguana/exchanges/stats.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/iguana/exchanges/stats.c b/iguana/exchanges/stats.c index 4fbe699d1..6453b85d5 100644 --- a/iguana/exchanges/stats.c +++ b/iguana/exchanges/stats.c @@ -1134,6 +1134,7 @@ char *stats_update(FILE *logfp,char *destdir,char *statefname,char *komodofname) return(jprint(retjson,1)); } +#ifndef FROM_PRIVATEBET int main(int argc, const char * argv[]) { struct tai T; uint32_t timestamp; struct DEXstats_disp prices[365]; int32_t i,n,seconds,leftdatenum; FILE *fp,*logfp; char *filestr,*retstr,*statefname,logfname[512],komodofile[512]; uint16_t port = LP_RPCPORT; @@ -1184,3 +1185,4 @@ int main(int argc, const char * argv[]) return 0; } #endif +#endif From 4dd934982b5d11cad28cdcbdf0a38ce9d35625ab Mon Sep 17 00:00:00 2001 From: jl777 Date: Fri, 10 Nov 2017 06:42:32 +0200 Subject: [PATCH 0478/1664] Test --- iguana/exchanges/DEXstats.h | 2 ++ 1 file changed, 2 insertions(+) diff --git a/iguana/exchanges/DEXstats.h b/iguana/exchanges/DEXstats.h index e31ff68e3..edf2157cb 100644 --- a/iguana/exchanges/DEXstats.h +++ b/iguana/exchanges/DEXstats.h @@ -927,6 +927,7 @@ char *stats_prices(char *symbol,char *dest,struct DEXstats_disp *prices,int32_t } #ifndef FROM_MARKETMAKER +#ifndef FROM_PRIVATEBET char *stats_JSON(void *ctx,char *myipaddr,int32_t mypubsock,cJSON *argjson,char *remoteaddr,uint16_t port) { char *method,*agent,*retstr,*source,*dest; struct tai T; uint32_t endtimestamp; struct DEXstats_disp prices[365]; int32_t leftdatenum,seconds,numdates; @@ -953,5 +954,6 @@ char *stats_JSON(void *ctx,char *myipaddr,int32_t mypubsock,cJSON *argjson,char return(clonestr(jprint(argjson,0))); } #endif +#endif #endif /* DEXstats_h */ From 6e53f5adee3bc844d597d98388e7a9140ade8686 Mon Sep 17 00:00:00 2001 From: jl777 Date: Fri, 10 Nov 2017 07:03:09 +0200 Subject: [PATCH 0479/1664] Test --- iguana/exchanges/LP_ordermatch.c | 4 ++-- iguana/exchanges/bot_settings | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/iguana/exchanges/LP_ordermatch.c b/iguana/exchanges/LP_ordermatch.c index f6e1f325f..e220291eb 100644 --- a/iguana/exchanges/LP_ordermatch.c +++ b/iguana/exchanges/LP_ordermatch.c @@ -146,12 +146,12 @@ double LP_quote_validate(struct LP_utxoinfo *autxo,struct LP_utxoinfo *butxo,str if ( strcmp(autxo->coinaddr,qp->destaddr) != 0 ) return(-10); } - if ( autxo != 0 && destvalue < 2*qp->desttxfee+qp->destsatoshis ) + if ( autxo != 0 && destvalue < qp->desttxfee+qp->destsatoshis ) { printf("destvalue %.8f destsatoshis %.8f is too small txfee %.8f?\n",dstr(destvalue),dstr(qp->destsatoshis),dstr(qp->desttxfee)); return(-11); } - if ( butxo != 0 && srcvalue < 2*qp->txfee+qp->satoshis ) + if ( butxo != 0 && srcvalue < qp->txfee+qp->satoshis ) { printf("srcvalue %.8f [%.8f] satoshis %.8f is too small txfee %.8f?\n",dstr(srcvalue),dstr(srcvalue) - dstr(qp->txfee+qp->satoshis),dstr(qp->satoshis),dstr(qp->txfee)); return(-33); diff --git a/iguana/exchanges/bot_settings b/iguana/exchanges/bot_settings index f619f92e3..f02ca3016 100755 --- a/iguana/exchanges/bot_settings +++ b/iguana/exchanges/bot_settings @@ -1,3 +1,3 @@ #!/bin/bash source userpass -curl --url "http://127.0.0.1:7783" --data "{\"userpass\":\"$userpass\",\"method\":\"bot_settings\",\"botid\":$1,\"newprice\":$1,\"newvolume\":$2}" +curl --url "http://127.0.0.1:7783" --data "{\"userpass\":\"$userpass\",\"method\":\"bot_settings\",\"botid\":$1,\"newprice\":$2,\"newvolume\":$3}" From 3f397e22fbd88b77e883d3288d9695c9414d4420 Mon Sep 17 00:00:00 2001 From: jl777 Date: Fri, 10 Nov 2017 07:09:47 +0200 Subject: [PATCH 0480/1664] Test --- iguana/exchanges/LP_tradebots.c | 1 + 1 file changed, 1 insertion(+) diff --git a/iguana/exchanges/LP_tradebots.c b/iguana/exchanges/LP_tradebots.c index 5894009dc..8a0ad850b 100644 --- a/iguana/exchanges/LP_tradebots.c +++ b/iguana/exchanges/LP_tradebots.c @@ -377,6 +377,7 @@ void LP_tradebot_finished(uint32_t tradeid,uint32_t requestid,uint32_t quoteid) //bot->numpending--, bot->completed++; printf("bot.%u detected completion tradeid.%u aliceid.%llx r.%u q.%u, numpending.%d completed.%d\n",bot->id,tp->tradeid,(long long)tp->aliceid,tp->requestid,tp->quoteid,bot->numpending,bot->completed); tp->completed = tp->finished = (uint32_t)time(NULL); + strcpy(tp->event,"finished"); break; } } From b072b80191492b1c6460875a78749df8902c44b7 Mon Sep 17 00:00:00 2001 From: jl777 Date: Fri, 10 Nov 2017 07:16:15 +0200 Subject: [PATCH 0481/1664] Test --- iguana/exchanges/LP_tradebots.c | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/iguana/exchanges/LP_tradebots.c b/iguana/exchanges/LP_tradebots.c index 8a0ad850b..710c9367a 100644 --- a/iguana/exchanges/LP_tradebots.c +++ b/iguana/exchanges/LP_tradebots.c @@ -340,7 +340,7 @@ void LP_tradebot_timeslice(void *ctx,struct LP_tradebot *bot) void LP_aliceid(uint32_t tradeid,uint64_t aliceid,char *event,uint32_t requestid,uint32_t quoteid) { - struct LP_tradebot *bot,*tmp; int32_t i; struct LP_tradebot_trade *tp; + struct LP_tradebot *bot,*tmp; int32_t i,matched = 0; struct LP_tradebot_trade *tp; DL_FOREACH_SAFE(LP_tradebots,bot,tmp) { for (i=0; inumtrades; i++) @@ -348,17 +348,22 @@ void LP_aliceid(uint32_t tradeid,uint64_t aliceid,char *event,uint32_t requestid if ( (tp= bot->trades[i]) != 0 && tp->finished == 0 && tp->tradeid == tradeid ) { tp->aliceid = aliceid; - printf("bot event tradeid.%u aliceid.%llu %s r.%u q.%u\n",tradeid,(long long)aliceid,event,requestid,quoteid); + printf("bot event tradeid.%u aliceid.%llu (%s) r.%u q.%u\n",tradeid,(long long)aliceid,event,requestid,quoteid); if ( requestid != 0 && quoteid != 0 ) { tp->requestid = requestid; tp->quoteid = quoteid; } strcpy(tp->event,event); + matched = 0; break; } } + if ( matched != 0 ) + break; } + if ( matched == 0 ) + printf("NO MATCH: bot event tradeid.%u aliceid.%llu (%s) r.%u q.%u\n",tradeid,(long long)aliceid,event,requestid,quoteid); } void LP_tradebot_finished(uint32_t tradeid,uint32_t requestid,uint32_t quoteid) From cd02831a0e54734a88c1d6ddb837368eba16540f Mon Sep 17 00:00:00 2001 From: jl777 Date: Fri, 10 Nov 2017 07:17:38 +0200 Subject: [PATCH 0482/1664] Test --- iguana/exchanges/LP_tradebots.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/iguana/exchanges/LP_tradebots.c b/iguana/exchanges/LP_tradebots.c index 710c9367a..02672eaca 100644 --- a/iguana/exchanges/LP_tradebots.c +++ b/iguana/exchanges/LP_tradebots.c @@ -341,6 +341,8 @@ void LP_tradebot_timeslice(void *ctx,struct LP_tradebot *bot) void LP_aliceid(uint32_t tradeid,uint64_t aliceid,char *event,uint32_t requestid,uint32_t quoteid) { struct LP_tradebot *bot,*tmp; int32_t i,matched = 0; struct LP_tradebot_trade *tp; + if ( tradeid == 0 ) + return; DL_FOREACH_SAFE(LP_tradebots,bot,tmp) { for (i=0; inumtrades; i++) From b53fde0c239e1ea77459ec3889d299a2d9135d29 Mon Sep 17 00:00:00 2001 From: jl777 Date: Fri, 10 Nov 2017 12:05:27 +0200 Subject: [PATCH 0483/1664] Test --- iguana/exchanges/LP_nativeDEX.c | 7 +++++-- iguana/exchanges/LP_tradebots.c | 11 +++++++---- 2 files changed, 12 insertions(+), 6 deletions(-) diff --git a/iguana/exchanges/LP_nativeDEX.c b/iguana/exchanges/LP_nativeDEX.c index b51741787..c8950c7c7 100644 --- a/iguana/exchanges/LP_nativeDEX.c +++ b/iguana/exchanges/LP_nativeDEX.c @@ -18,8 +18,11 @@ // LP_nativeDEX.c // marketmaker // -// bot status 1600% ? - +// swap started, pending, locked, finished, ... +// aliceid +//there is still a pending one with `-1 wait for bobpayment bYoNxkfvwQ42Yufry8J5y8BYi6mQxokvW9 numconfs.1 MNZ c0ea4aa808a653222a15122d96692fecf734dbbacfb9a54cb4711306ea0c3cef`, but that tx is already spent including 6 confirmation +// bot safe to exit? +// // BCH signing // dPoW security -> 4: KMD notarized, 5: BTC notarized, after next notary elections // bigendian architectures need to use little endian for sighash calcs diff --git a/iguana/exchanges/LP_tradebots.c b/iguana/exchanges/LP_tradebots.c index 02672eaca..424909766 100644 --- a/iguana/exchanges/LP_tradebots.c +++ b/iguana/exchanges/LP_tradebots.c @@ -18,8 +18,8 @@ // marketmaker // -#define TRADEBOTS_GAPTIME 60 -#define LP_TRADEBOTS_MAXTRADES 100 +#define TRADEBOTS_GAPTIME 120 +#define LP_TRADEBOTS_MAXTRADES 10 struct LP_tradebot_trade { @@ -36,7 +36,7 @@ struct LP_tradebot char name[128],base[32],rel[32]; int32_t numtrades,numpending,completed,dispdir; double maxprice,totalrelvolume,totalbasevolume,basesum,relsum,pendbasesum,pendrelsum; - uint32_t dead,pause,userpause,started,id; + uint32_t lasttime,dead,pause,userpause,started,id; struct LP_tradebot_trade *trades[LP_TRADEBOTS_MAXTRADES]; } *LP_tradebots; @@ -438,8 +438,11 @@ void LP_tradebots_timeslice(void *ctx) bot->pause = (uint32_t)time(NULL); else if ( bot->userpause == 0 ) bot->pause = 0; - if ( bot->numpending == 0 ) + if ( bot->numpending == 0 && time(NULL) > bot->lasttime+TRADEBOTS_GAPTIME ) + { LP_tradebot_timeslice(ctx,bot); + bot->lasttime = (uint32_t)time(NULL); + } } lastnumfinished = LP_numfinished; } From 63d89d4d0a916b6adef08f9a3924c7e365993f61 Mon Sep 17 00:00:00 2001 From: jl777 Date: Fri, 10 Nov 2017 12:21:11 +0200 Subject: [PATCH 0484/1664] Test --- iguana/exchanges/LP_rpc.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/iguana/exchanges/LP_rpc.c b/iguana/exchanges/LP_rpc.c index 661c476e6..f7bf6a38f 100644 --- a/iguana/exchanges/LP_rpc.c +++ b/iguana/exchanges/LP_rpc.c @@ -635,7 +635,7 @@ cJSON *LP_listunspent(char *symbol,char *coinaddr) sprintf(buf,"[%d, 99999999, [\"%s\"]]",numconfs,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,1)); + } else return(electrum_address_listunspent(symbol,coin->electrum,&retjson,coinaddr,2)); } int32_t LP_listunspent_issue(char *symbol,char *coinaddr,int32_t fullflag) From 0bf0a7e981679dce41984990db55ebfd6994edc5 Mon Sep 17 00:00:00 2001 From: jl777 Date: Fri, 10 Nov 2017 12:26:04 +0200 Subject: [PATCH 0485/1664] Test --- iguana/exchanges/LP_socket.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/iguana/exchanges/LP_socket.c b/iguana/exchanges/LP_socket.c index 8f9f899e9..8faaedaaf 100644 --- a/iguana/exchanges/LP_socket.c +++ b/iguana/exchanges/LP_socket.c @@ -605,7 +605,7 @@ cJSON *electrum_address_listunspent(char *symbol,struct electrum_info *ep,cJSON { if ( jobj(retjson,"error") == 0 && is_cJSON_Array(retjson) != 0 ) { - if ( 0 && electrumflag > 1 ) + if ( 1 && electrumflag > 1 ) printf("%s.%d u.%u/%d t.%ld %s LISTUNSPENT.(%d)\n",coin->symbol,height,ap->unspenttime,ap->unspentheight,time(NULL),addr,(int32_t)strlen(jprint(retjson,0))); updatedflag = 0; if ( electrum_process_array(coin,ep,addr,retjson,electrumflag) != 0 ) From 4211a33565957792d7c8234651c69b266b97d6bf Mon Sep 17 00:00:00 2001 From: jl777 Date: Fri, 10 Nov 2017 12:37:33 +0200 Subject: [PATCH 0486/1664] Test --- iguana/exchanges/LP_socket.c | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/iguana/exchanges/LP_socket.c b/iguana/exchanges/LP_socket.c index 8faaedaaf..bbf31294e 100644 --- a/iguana/exchanges/LP_socket.c +++ b/iguana/exchanges/LP_socket.c @@ -408,6 +408,8 @@ int32_t electrum_kickstart(struct electrum_info *ep) return(0); } +int32_t zeroval() { return(0); } + cJSON *electrum_submit(char *symbol,struct electrum_info *ep,cJSON **retjsonp,char *method,char *params,int32_t timeout) { // queue id and string and callback @@ -416,6 +418,12 @@ cJSON *electrum_submit(char *symbol,struct electrum_info *ep,cJSON **retjsonp,ch ep = electrum_server(symbol,0); while ( ep != 0 ) { + if ( strcmp(ep->symbol,symbol) != 0 ) + { + printf("ep.%p %s %s:%u called for [%s]???\n",ep,ep->symbol,ep->ipaddr,ep->port,symbol); + int32_t i = 1 / zeroval(); + printf("it should be dead already.%d\n",i); + } if ( ep != 0 && ep->sock >= 0 && retjsonp != 0 ) { *retjsonp = 0; From 84febf8028e9362ba8162f2df21647153e1ece9a Mon Sep 17 00:00:00 2001 From: jl777 Date: Fri, 10 Nov 2017 13:00:49 +0200 Subject: [PATCH 0487/1664] Test --- iguana/exchanges/LP_socket.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/iguana/exchanges/LP_socket.c b/iguana/exchanges/LP_socket.c index bbf31294e..b40c74ccb 100644 --- a/iguana/exchanges/LP_socket.c +++ b/iguana/exchanges/LP_socket.c @@ -391,8 +391,7 @@ void electrum_initial_requests(struct electrum_info *ep) int32_t electrum_kickstart(struct electrum_info *ep) { - closesocket(ep->sock), ep->sock = -1; - sleep(1); + closesocket(ep->sock);//, ep->sock = -1; if ( (ep->sock= LP_socket(0,ep->ipaddr,ep->port)) < 0 ) { printf("error RE-connecting to %s:%u\n",ep->ipaddr,ep->port); From 13cdad3437c30be673361dbb5493f7285669316f Mon Sep 17 00:00:00 2001 From: jl777 Date: Fri, 10 Nov 2017 13:03:45 +0200 Subject: [PATCH 0488/1664] Test --- iguana/exchanges/LP_rpc.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/iguana/exchanges/LP_rpc.c b/iguana/exchanges/LP_rpc.c index f7bf6a38f..661c476e6 100644 --- a/iguana/exchanges/LP_rpc.c +++ b/iguana/exchanges/LP_rpc.c @@ -635,7 +635,7 @@ cJSON *LP_listunspent(char *symbol,char *coinaddr) sprintf(buf,"[%d, 99999999, [\"%s\"]]",numconfs,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,2)); + } else return(electrum_address_listunspent(symbol,coin->electrum,&retjson,coinaddr,1)); } int32_t LP_listunspent_issue(char *symbol,char *coinaddr,int32_t fullflag) From dec6f9d515de46db83b8c25e57f0a03db9428a1f Mon Sep 17 00:00:00 2001 From: jl777 Date: Fri, 10 Nov 2017 13:05:47 +0200 Subject: [PATCH 0489/1664] Test --- iguana/exchanges/LP_socket.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/iguana/exchanges/LP_socket.c b/iguana/exchanges/LP_socket.c index b40c74ccb..584c7216a 100644 --- a/iguana/exchanges/LP_socket.c +++ b/iguana/exchanges/LP_socket.c @@ -612,7 +612,7 @@ cJSON *electrum_address_listunspent(char *symbol,struct electrum_info *ep,cJSON { if ( jobj(retjson,"error") == 0 && is_cJSON_Array(retjson) != 0 ) { - if ( 1 && electrumflag > 1 ) + if ( 0 && electrumflag > 1 ) printf("%s.%d u.%u/%d t.%ld %s LISTUNSPENT.(%d)\n",coin->symbol,height,ap->unspenttime,ap->unspentheight,time(NULL),addr,(int32_t)strlen(jprint(retjson,0))); updatedflag = 0; if ( electrum_process_array(coin,ep,addr,retjson,electrumflag) != 0 ) From 6ac91582a0c75de53fb61a4ba661faea74a3884c Mon Sep 17 00:00:00 2001 From: jl777 Date: Fri, 10 Nov 2017 13:23:40 +0200 Subject: [PATCH 0490/1664] Test --- iguana/exchanges/LP_socket.c | 6 +----- iguana/exchanges/LP_transaction.c | 7 ++++--- 2 files changed, 5 insertions(+), 8 deletions(-) diff --git a/iguana/exchanges/LP_socket.c b/iguana/exchanges/LP_socket.c index 584c7216a..3d76b24b9 100644 --- a/iguana/exchanges/LP_socket.c +++ b/iguana/exchanges/LP_socket.c @@ -407,8 +407,6 @@ int32_t electrum_kickstart(struct electrum_info *ep) return(0); } -int32_t zeroval() { return(0); } - cJSON *electrum_submit(char *symbol,struct electrum_info *ep,cJSON **retjsonp,char *method,char *params,int32_t timeout) { // queue id and string and callback @@ -419,9 +417,7 @@ cJSON *electrum_submit(char *symbol,struct electrum_info *ep,cJSON **retjsonp,ch { if ( strcmp(ep->symbol,symbol) != 0 ) { - printf("ep.%p %s %s:%u called for [%s]???\n",ep,ep->symbol,ep->ipaddr,ep->port,symbol); - int32_t i = 1 / zeroval(); - printf("it should be dead already.%d\n",i); + printf("electrum_submit ep.%p %s %s:%u called for [%s]???\n",ep,ep->symbol,ep->ipaddr,ep->port,symbol); } if ( ep != 0 && ep->sock >= 0 && retjsonp != 0 ) { diff --git a/iguana/exchanges/LP_transaction.c b/iguana/exchanges/LP_transaction.c index 5fe90e841..171981a0c 100644 --- a/iguana/exchanges/LP_transaction.c +++ b/iguana/exchanges/LP_transaction.c @@ -854,7 +854,7 @@ int64_t LP_komodo_interest(bits256 txid,int64_t value) 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,bits256 utxotxid,int32_t utxovout,int32_t dustcombine) { - char wifstr[128],spendscriptstr[128],str[65]; int32_t i,j,n,numpre,ind,abovei,belowi,maxmode=0; struct vin_info *vp; cJSON *txobj; struct LP_address_utxo *up,*min0,*min1,*preselected[3]; int64_t value,interest,interestsum,above,below,remains = amount,total = 0; + char wifstr[128],spendscriptstr[128],str[65]; int32_t i,j,maxiters,n,numpre,ind,abovei,belowi,maxmode=0; struct vin_info *vp; cJSON *txobj; struct LP_address_utxo *up,*min0,*min1,*preselected[3]; int64_t value,interest,interestsum,above,below,remains = amount,total = 0; *totalp = 0; interestsum = 0; init_hexbytes_noT(spendscriptstr,script,scriptlen); @@ -923,7 +923,8 @@ int32_t LP_vins_select(void *ctx,struct iguana_info *coin,int64_t *totalp,int64_ preselected[numpre++] = min1; else min1 = 0; printf("dustcombine.%d numpre.%d min0.%p min1.%p numutxos.%d amount %.8f\n",dustcombine,numpre,min0,min1,numunspents,dstr(amount)); - for (i=0; i sum %.8f\n",bits256_str(str,up->U.txid),up->U.vout,dstr(up->U.value),dstr(interest),dstr(interestsum)); } } - printf("vini.%d value %.8f, total %.8f remains %.8f interest %.8f sum %.8f\n",n,dstr(up->U.value),dstr(total),dstr(remains),dstr(interest),dstr(interestsum)); + printf("numunspents.%d vini.%d value %.8f, total %.8f remains %.8f interest %.8f sum %.8f\n",numunspents,n,dstr(up->U.value),dstr(total),dstr(remains),dstr(interest),dstr(interestsum)); vp = &V[n++]; vp->N = vp->M = 1; vp->signers[0].privkey = privkey; From 366f0dfecb1b4ce72d1b99503b84a5a6385981f4 Mon Sep 17 00:00:00 2001 From: jl777 Date: Fri, 10 Nov 2017 13:32:24 +0200 Subject: [PATCH 0491/1664] Test --- iguana/exchanges/LP_socket.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/iguana/exchanges/LP_socket.c b/iguana/exchanges/LP_socket.c index 3d76b24b9..527aefd61 100644 --- a/iguana/exchanges/LP_socket.c +++ b/iguana/exchanges/LP_socket.c @@ -430,12 +430,12 @@ cJSON *electrum_submit(char *symbol,struct electrum_info *ep,cJSON **retjsonp,ch sitem->expiration = timeout; sitem->DL.type = ep->stratumid++; sitem->retptrp = (void **)retjsonp;*/ - portable_mutex_lock(&ep->mutex); + //portable_mutex_lock(&ep->mutex); //queue_enqueue("sendQ",&ep->sendQ,&sitem->DL); expiration = (uint32_t)time(NULL) + timeout + 1; while ( *retjsonp == 0 && time(NULL) <= expiration ) usleep(5000); - portable_mutex_unlock(&ep->mutex); + //portable_mutex_unlock(&ep->mutex); if ( *retjsonp == 0 || jobj(*retjsonp,"error") != 0 ) { if ( ++ep->numerrors >= LP_ELECTRUM_MAXERRORS ) From fa67ddfde59a2d2ddfcc782dcd761669032e3145 Mon Sep 17 00:00:00 2001 From: jl777 Date: Fri, 10 Nov 2017 13:42:12 +0200 Subject: [PATCH 0492/1664] Test --- iguana/exchanges/LP_socket.c | 4 ++-- iguana/exchanges/LP_utxo.c | 1 + 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/iguana/exchanges/LP_socket.c b/iguana/exchanges/LP_socket.c index 527aefd61..33b2467e4 100644 --- a/iguana/exchanges/LP_socket.c +++ b/iguana/exchanges/LP_socket.c @@ -430,12 +430,12 @@ cJSON *electrum_submit(char *symbol,struct electrum_info *ep,cJSON **retjsonp,ch sitem->expiration = timeout; sitem->DL.type = ep->stratumid++; sitem->retptrp = (void **)retjsonp;*/ - //portable_mutex_lock(&ep->mutex); +//portable_mutex_lock(&ep->mutex); //queue_enqueue("sendQ",&ep->sendQ,&sitem->DL); expiration = (uint32_t)time(NULL) + timeout + 1; while ( *retjsonp == 0 && time(NULL) <= expiration ) usleep(5000); - //portable_mutex_unlock(&ep->mutex); +//portable_mutex_unlock(&ep->mutex); if ( *retjsonp == 0 || jobj(*retjsonp,"error") != 0 ) { if ( ++ep->numerrors >= LP_ELECTRUM_MAXERRORS ) diff --git a/iguana/exchanges/LP_utxo.c b/iguana/exchanges/LP_utxo.c index 076e6729d..293798c56 100644 --- a/iguana/exchanges/LP_utxo.c +++ b/iguana/exchanges/LP_utxo.c @@ -1082,6 +1082,7 @@ void LP_unspents_cache(char *symbol,char *addr,char *arraystr,int32_t updatedfla { char fname[1024]; FILE *fp=0; sprintf(fname,"%s/UNSPENTS/%s_%s",GLOBAL_DBDIR,symbol,addr), OS_portable_path(fname); + printf("unspents cache.(%s)\n",fname); if ( updatedflag == 0 && (fp= fopen(fname,"rb")) == 0 ) updatedflag = 1; else if ( fp != 0 ) From 8b8b7808734e3e41086060401642d315e1d00085 Mon Sep 17 00:00:00 2001 From: jl777 Date: Fri, 10 Nov 2017 13:43:17 +0200 Subject: [PATCH 0493/1664] Test --- iguana/exchanges/LP_utxo.c | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/iguana/exchanges/LP_utxo.c b/iguana/exchanges/LP_utxo.c index 293798c56..0ad4c3251 100644 --- a/iguana/exchanges/LP_utxo.c +++ b/iguana/exchanges/LP_utxo.c @@ -1078,11 +1078,18 @@ int32_t LP_undospends(struct iguana_info *coin,int32_t lastheight) return(num); } +char *LP_unspents_filestr(char *symbol,char *addr) +{ + char fname[1024]; long fsize; + sprintf(fname,"%s/UNSPENTS/%s_%s",GLOBAL_DBDIR,symbol,addr), OS_portable_path(fname); + return(OS_filestr(&fsize,fname)); +} + void LP_unspents_cache(char *symbol,char *addr,char *arraystr,int32_t updatedflag) { char fname[1024]; FILE *fp=0; sprintf(fname,"%s/UNSPENTS/%s_%s",GLOBAL_DBDIR,symbol,addr), OS_portable_path(fname); - printf("unspents cache.(%s)\n",fname); + printf("unspents cache.(%s) for %s %s\n",fname,symbol,addr); if ( updatedflag == 0 && (fp= fopen(fname,"rb")) == 0 ) updatedflag = 1; else if ( fp != 0 ) @@ -1094,13 +1101,6 @@ void LP_unspents_cache(char *symbol,char *addr,char *arraystr,int32_t updatedfla } } -char *LP_unspents_filestr(char *symbol,char *addr) -{ - char fname[1024]; long fsize; - sprintf(fname,"%s/UNSPENTS/%s_%s",GLOBAL_DBDIR,symbol,addr), OS_portable_path(fname); - return(OS_filestr(&fsize,fname)); -} - uint64_t LP_unspents_load(char *symbol,char *addr) { char *arraystr; uint64_t balance = 0; int32_t i,n; cJSON *retjson,*item; struct iguana_info *coin; From 3281cc3cfeb7905532ffc6bb1a248c1660175d06 Mon Sep 17 00:00:00 2001 From: jl777 Date: Fri, 10 Nov 2017 13:44:03 +0200 Subject: [PATCH 0494/1664] Test --- iguana/exchanges/LP_utxo.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/iguana/exchanges/LP_utxo.c b/iguana/exchanges/LP_utxo.c index 0ad4c3251..2f1908771 100644 --- a/iguana/exchanges/LP_utxo.c +++ b/iguana/exchanges/LP_utxo.c @@ -1089,7 +1089,7 @@ void LP_unspents_cache(char *symbol,char *addr,char *arraystr,int32_t updatedfla { char fname[1024]; FILE *fp=0; sprintf(fname,"%s/UNSPENTS/%s_%s",GLOBAL_DBDIR,symbol,addr), OS_portable_path(fname); - printf("unspents cache.(%s) for %s %s\n",fname,symbol,addr); + printf("unspents cache.(%s) for %s %s, updated.%d\n",fname,symbol,addr,updatedflag); if ( updatedflag == 0 && (fp= fopen(fname,"rb")) == 0 ) updatedflag = 1; else if ( fp != 0 ) From 9511fd7ad11663f4c6b099b9fd9b3cdf5d7107f6 Mon Sep 17 00:00:00 2001 From: jl777 Date: Fri, 10 Nov 2017 14:23:47 +0200 Subject: [PATCH 0495/1664] Test --- iguana/exchanges/LP_nativeDEX.c | 1 + iguana/exchanges/LP_ordermatch.c | 6 +++--- 2 files changed, 4 insertions(+), 3 deletions(-) diff --git a/iguana/exchanges/LP_nativeDEX.c b/iguana/exchanges/LP_nativeDEX.c index c8950c7c7..8023a8727 100644 --- a/iguana/exchanges/LP_nativeDEX.c +++ b/iguana/exchanges/LP_nativeDEX.c @@ -18,6 +18,7 @@ // LP_nativeDEX.c // marketmaker // +// previously, it used to show amount, kmd equiv, perc // swap started, pending, locked, finished, ... // aliceid //there is still a pending one with `-1 wait for bobpayment bYoNxkfvwQ42Yufry8J5y8BYi6mQxokvW9 numconfs.1 MNZ c0ea4aa808a653222a15122d96692fecf734dbbacfb9a54cb4711306ea0c3cef`, but that tx is already spent including 6 confirmation diff --git a/iguana/exchanges/LP_ordermatch.c b/iguana/exchanges/LP_ordermatch.c index e220291eb..d088e712a 100644 --- a/iguana/exchanges/LP_ordermatch.c +++ b/iguana/exchanges/LP_ordermatch.c @@ -901,9 +901,9 @@ struct LP_utxoinfo *LP_buyutxo(double *ordermatchpricep,int64_t *bestsatoshisp,i { item = jitem(asks,i); price = jdouble(item,"price"); - if ( price/maxprice < .9 ) - price *= 1.05; - else price *= 1.01; + if ( price < maxprice && price > maxprice*0.8) + price = price * 0.9 + 0.1 * maxprice; + else price *= 1.005; pubkey = jbits256(item,"pubkey"); if ( bits256_nonz(destpubkey) != 0 && bits256_cmp(destpubkey,pubkey) != 0 ) continue; From aaf3b87668d62b66cfb2fd951b9fa4a98f7db589 Mon Sep 17 00:00:00 2001 From: jl777 Date: Fri, 10 Nov 2017 15:25:26 +0200 Subject: [PATCH 0496/1664] Test --- iguana/exchanges/LP_utxo.c | 2 +- iguana/exchanges/LP_utxos.c | 8 ++++---- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/iguana/exchanges/LP_utxo.c b/iguana/exchanges/LP_utxo.c index 2f1908771..575aff00c 100644 --- a/iguana/exchanges/LP_utxo.c +++ b/iguana/exchanges/LP_utxo.c @@ -1089,7 +1089,7 @@ void LP_unspents_cache(char *symbol,char *addr,char *arraystr,int32_t updatedfla { char fname[1024]; FILE *fp=0; sprintf(fname,"%s/UNSPENTS/%s_%s",GLOBAL_DBDIR,symbol,addr), OS_portable_path(fname); - printf("unspents cache.(%s) for %s %s, updated.%d\n",fname,symbol,addr,updatedflag); + //printf("unspents cache.(%s) for %s %s, updated.%d\n",fname,symbol,addr,updatedflag); if ( updatedflag == 0 && (fp= fopen(fname,"rb")) == 0 ) updatedflag = 1; else if ( fp != 0 ) diff --git a/iguana/exchanges/LP_utxos.c b/iguana/exchanges/LP_utxos.c index ea7d36b52..fdbef7e6f 100644 --- a/iguana/exchanges/LP_utxos.c +++ b/iguana/exchanges/LP_utxos.c @@ -548,9 +548,9 @@ int32_t LP_privkey_init(int32_t mypubsock,struct iguana_info *coin,bits256 mypri //printf("array.%d\n",n); while ( used < n-1 ) { - //for (i=0; i= 0 ) { item = jitem(array,i); @@ -573,7 +573,7 @@ int32_t LP_privkey_init(int32_t mypubsock,struct iguana_info *coin,bits256 mypri else targetval = (depositval / 9) * 8 + 2*txfee; if ( targetval < txfee*2 ) targetval = txfee*2; - //printf("iambob.%d i.%d deposit %.8f min %.8f target %.8f\n",iambob,i,dstr(depositval),dstr((1+LP_MINSIZE_TXFEEMULT)*txfee),dstr(targetval)); + printf("iambob.%d i.%d deposit %.8f min %.8f target %.8f\n",iambob,i,dstr(depositval),dstr((1+LP_MINSIZE_TXFEEMULT)*txfee),dstr(targetval)); if ( depositval < (1+LP_MINSIZE_TXFEEMULT)*txfee ) continue; i = -1; From 7dd4a4492ee5fb38a5935e8c7c3c6288cf7bf8e9 Mon Sep 17 00:00:00 2001 From: jl777 Date: Fri, 10 Nov 2017 15:30:02 +0200 Subject: [PATCH 0497/1664] Test --- iguana/exchanges/LP_transaction.c | 4 ++-- iguana/exchanges/LP_utxos.c | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/iguana/exchanges/LP_transaction.c b/iguana/exchanges/LP_transaction.c index 171981a0c..ea09a5bb3 100644 --- a/iguana/exchanges/LP_transaction.c +++ b/iguana/exchanges/LP_transaction.c @@ -996,7 +996,7 @@ int32_t LP_vins_select(void *ctx,struct iguana_info *coin,int64_t *totalp,int64_ 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,bits256 utxotxid,int32_t utxovout,uint32_t locktime) { static void *ctx; - cJSON *txobj,*item; uint8_t addrtype,rmd160[20],script[64],spendscript[256]; char *coinaddr,*rawtxbytes; bits256 txid; uint32_t timestamp; int64_t change=0,adjust=0,total,value,amount = 0; int32_t i,dustcombine,scriptlen,spendlen,suppress_pubkeys,ignore_cltverr,numvouts=0,numvins=0,numutxos=0; struct LP_address_utxo *utxos[256]; struct LP_address *ap; + cJSON *txobj,*item; uint8_t addrtype,rmd160[20],script[64],spendscript[256]; char *coinaddr,*rawtxbytes; bits256 txid; uint32_t timestamp; int64_t change=0,adjust=0,total,value,amount = 0; int32_t i,dustcombine,scriptlen,spendlen,suppress_pubkeys,ignore_cltverr,numvouts=0,numvins=0,numutxos=0; struct LP_address_utxo *utxos[1024]; struct LP_address *ap; if ( ctx == 0 ) ctx = bitcoin_ctx(); *numvinsp = 0; @@ -1135,7 +1135,7 @@ char *LP_withdraw(struct iguana_info *coin,cJSON *argjson) safecopy(changeaddr,coin->smartaddr,sizeof(changeaddr)); safecopy(vinaddr,coin->smartaddr,sizeof(vinaddr)); privkey = LP_privkey(vinaddr,coin->taddr); - maxV = 256; + maxV = 1024; V = malloc(maxV * sizeof(*V)); for (iter=0; iter<2; iter++) { diff --git a/iguana/exchanges/LP_utxos.c b/iguana/exchanges/LP_utxos.c index fdbef7e6f..37498c0b4 100644 --- a/iguana/exchanges/LP_utxos.c +++ b/iguana/exchanges/LP_utxos.c @@ -512,7 +512,7 @@ int32_t LP_privkey_init(int32_t mypubsock,struct iguana_info *coin,bits256 mypri if ( is_cJSON_Array(array) != 0 && (n= cJSON_GetArraySize(array)) > 0 ) { coin->numutxos = n; - //printf("LP_privkey_init %s %s\n",coin->symbol,jprint(array,0)); + printf("LP_privkey_init %s %d\n",coin->symbol,n); for (iambob=0; iambob<=1; iambob++) { if ( iambob == 0 ) @@ -537,7 +537,7 @@ int32_t LP_privkey_init(int32_t mypubsock,struct iguana_info *coin,bits256 mypri height = jint(item,"height"); } satoshis = LP_txvalue(destaddr,coin->symbol,txid,vout); - if ( satoshis != 0 && satoshis != value ) + //if ( satoshis != 0 && satoshis != value ) printf("%s %s privkey_init value %.8f vs %.8f (%s) %.8f %.8f\n",coin->symbol,coin->smartaddr,dstr(satoshis),dstr(value),jprint(item,0),jdouble(item,"amount"),jdouble(item,"interest")); if ( LP_inventory_prevent(iambob,coin->symbol,txid,vout) == 0 )//&& height > 0 ) { From 02d3afbee2d8bd2a2c0324e93dd6a11c371b8ef5 Mon Sep 17 00:00:00 2001 From: jl777 Date: Fri, 10 Nov 2017 15:34:20 +0200 Subject: [PATCH 0498/1664] Test --- iguana/exchanges/LP_socket.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/iguana/exchanges/LP_socket.c b/iguana/exchanges/LP_socket.c index 33b2467e4..0844b4769 100644 --- a/iguana/exchanges/LP_socket.c +++ b/iguana/exchanges/LP_socket.c @@ -430,12 +430,12 @@ cJSON *electrum_submit(char *symbol,struct electrum_info *ep,cJSON **retjsonp,ch sitem->expiration = timeout; sitem->DL.type = ep->stratumid++; sitem->retptrp = (void **)retjsonp;*/ -//portable_mutex_lock(&ep->mutex); +portable_mutex_lock(&ep->mutex); //queue_enqueue("sendQ",&ep->sendQ,&sitem->DL); expiration = (uint32_t)time(NULL) + timeout + 1; while ( *retjsonp == 0 && time(NULL) <= expiration ) usleep(5000); -//portable_mutex_unlock(&ep->mutex); +portable_mutex_unlock(&ep->mutex); if ( *retjsonp == 0 || jobj(*retjsonp,"error") != 0 ) { if ( ++ep->numerrors >= LP_ELECTRUM_MAXERRORS ) @@ -608,7 +608,7 @@ cJSON *electrum_address_listunspent(char *symbol,struct electrum_info *ep,cJSON { if ( jobj(retjson,"error") == 0 && is_cJSON_Array(retjson) != 0 ) { - if ( 0 && electrumflag > 1 ) + //if ( 0 && electrumflag > 1 ) printf("%s.%d u.%u/%d t.%ld %s LISTUNSPENT.(%d)\n",coin->symbol,height,ap->unspenttime,ap->unspentheight,time(NULL),addr,(int32_t)strlen(jprint(retjson,0))); updatedflag = 0; if ( electrum_process_array(coin,ep,addr,retjson,electrumflag) != 0 ) From 3b4fca07aca62c0b02bfe279f8f5e1c23e5bc12d Mon Sep 17 00:00:00 2001 From: jl777 Date: Fri, 10 Nov 2017 15:55:34 +0200 Subject: [PATCH 0499/1664] Test --- iguana/exchanges/LP_commands.c | 2 +- iguana/exchanges/LP_utxos.c | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/iguana/exchanges/LP_commands.c b/iguana/exchanges/LP_commands.c index 0d9508a18..35387d845 100644 --- a/iguana/exchanges/LP_commands.c +++ b/iguana/exchanges/LP_commands.c @@ -592,7 +592,7 @@ bot_resume(botid)\n\ LP_address(ptr,coinaddr); if ( strcmp(coinaddr,ptr->smartaddr) == 0 && bits256_nonz(G.LP_privkey) != 0 ) { - printf("ADDR_UNSPENTS %s %s is my address being asked for!\n",ptr->symbol,coinaddr); + //printf("ADDR_UNSPENTS %s %s is my address being asked for!\n",ptr->symbol,coinaddr); if ( ptr->lastpushtime > 0 && ptr->addr_listunspent_requested > (uint32_t)time(NULL)-10 ) ptr->lastpushtime -= LP_ORDERBOOK_DURATION*0.1; ptr->addr_listunspent_requested = (uint32_t)time(NULL); diff --git a/iguana/exchanges/LP_utxos.c b/iguana/exchanges/LP_utxos.c index 37498c0b4..5343e1051 100644 --- a/iguana/exchanges/LP_utxos.c +++ b/iguana/exchanges/LP_utxos.c @@ -502,7 +502,7 @@ int32_t LP_privkey_init(int32_t mypubsock,struct iguana_info *coin,bits256 mypri //printf("coin not active\n"); return(0); } - //printf("privkey init.(%s) %s\n",coin->symbol,coin->smartaddr); + printf("privkey init.(%s) %s\n",coin->symbol,coin->smartaddr); if ( coin->inactive == 0 ) LP_listunspent_issue(coin->symbol,coin->smartaddr,0); LP_address(coin,coin->smartaddr); From af3f152c7186d5fb95171f4b93a3abbe1c9923d4 Mon Sep 17 00:00:00 2001 From: jl777 Date: Fri, 10 Nov 2017 16:02:16 +0200 Subject: [PATCH 0500/1664] Test --- iguana/exchanges/LP_include.h | 1 + iguana/exchanges/LP_utxos.c | 8 +++++++- 2 files changed, 8 insertions(+), 1 deletion(-) diff --git a/iguana/exchanges/LP_include.h b/iguana/exchanges/LP_include.h index e5a045e33..c175de995 100644 --- a/iguana/exchanges/LP_include.h +++ b/iguana/exchanges/LP_include.h @@ -263,6 +263,7 @@ struct iguana_info void *electrum; void *ctx; uint64_t maxamount,kmd_equiv,balanceA,balanceB,valuesumA,valuesumB; uint8_t pubkey33[33],zcash; + bits256 lastprivkey; uint32_t lastprivkeytime; bits256 cachedtxid; uint8_t *cachedtxiddata; int32_t cachedtxidlen; bits256 cachedmerkle; int32_t cachedmerkleheight; }; diff --git a/iguana/exchanges/LP_utxos.c b/iguana/exchanges/LP_utxos.c index 5343e1051..380783b2e 100644 --- a/iguana/exchanges/LP_utxos.c +++ b/iguana/exchanges/LP_utxos.c @@ -502,11 +502,17 @@ int32_t LP_privkey_init(int32_t mypubsock,struct iguana_info *coin,bits256 mypri //printf("coin not active\n"); return(0); } + if ( bits256_cmp(myprivkey,coin->lastprivkey) == 0 && time(NULL) < coin->lastprivkeytime+60 ) + return(0); + coin->lastprivkey = myprivkey; + coin->lastprivkeytime = (uint32_t)time(NULL); printf("privkey init.(%s) %s\n",coin->symbol,coin->smartaddr); if ( coin->inactive == 0 ) LP_listunspent_issue(coin->symbol,coin->smartaddr,0); + array = LP_listunspent(coin->symbol,coin->smartaddr); + printf("unspent array %ld\n",strlen(jprint(array,0))); LP_address(coin,coin->smartaddr); - if ( coin->inactive == 0 && (array= LP_listunspent(coin->symbol,coin->smartaddr)) != 0 ) + if ( array != 0 ) { txfee = LP_txfeecalc(coin,0,0); if ( is_cJSON_Array(array) != 0 && (n= cJSON_GetArraySize(array)) > 0 ) From 01441181890ee57ca4d6d0af16e93437ae2dabe6 Mon Sep 17 00:00:00 2001 From: jl777 Date: Fri, 10 Nov 2017 16:10:04 +0200 Subject: [PATCH 0501/1664] Test --- iguana/exchanges/LP_socket.c | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/iguana/exchanges/LP_socket.c b/iguana/exchanges/LP_socket.c index 0844b4769..6452f4087 100644 --- a/iguana/exchanges/LP_socket.c +++ b/iguana/exchanges/LP_socket.c @@ -598,10 +598,9 @@ cJSON *electrum_address_listunspent(char *symbol,struct electrum_info *ep,cJSON usecache = 0; else if ( ap->unspentheight < height ) usecache = 0; - else if ( G.LP_pendingswaps != 0 && time(NULL) > ap->unspenttime+20 ) + else if ( G.LP_pendingswaps != 0 && time(NULL) > ap->unspenttime+30 ) usecache = 0; } - //printf("electrum.%s/%s listunspent last.(%s lag %d)\n",ep->symbol,coin->symbol,coin->lastunspent,(int32_t)(time(NULL) - coin->unspenttime)); if ( usecache == 0 || electrumflag > 1 ) { if ( (retjson= electrum_strarg(symbol,ep,retjsonp,"blockchain.address.listunspent",addr,ELECTRUM_TIMEOUT)) != 0 ) @@ -636,7 +635,7 @@ cJSON *electrum_address_listunspent(char *symbol,struct electrum_info *ep,cJSON { if ( strcmp(addr,coin->smartaddr) == 0 && (retstr= LP_unspents_filestr(symbol,coin->smartaddr)) != 0 ) { - retjson = LP_address_utxos(coin,addr,1); + retjson = cJSON_Parse(retstr); free(retstr); } else retjson = LP_address_utxos(coin,addr,1); } From cbc557f2a48b15d6fd000dcd1529ef6de23fdfa8 Mon Sep 17 00:00:00 2001 From: jl777 Date: Fri, 10 Nov 2017 16:18:36 +0200 Subject: [PATCH 0502/1664] Test --- iguana/exchanges/LP_include.h | 2 +- iguana/exchanges/LP_socket.c | 17 +++++------------ iguana/exchanges/LP_utxos.c | 17 +++++++++++------ 3 files changed, 17 insertions(+), 19 deletions(-) diff --git a/iguana/exchanges/LP_include.h b/iguana/exchanges/LP_include.h index c175de995..aad96236c 100644 --- a/iguana/exchanges/LP_include.h +++ b/iguana/exchanges/LP_include.h @@ -263,7 +263,7 @@ struct iguana_info void *electrum; void *ctx; uint64_t maxamount,kmd_equiv,balanceA,balanceB,valuesumA,valuesumB; uint8_t pubkey33[33],zcash; - bits256 lastprivkey; uint32_t lastprivkeytime; + bits256 lastprivkey; uint32_t lastprivkeytime; int32_t privkeydepth; bits256 cachedtxid; uint8_t *cachedtxiddata; int32_t cachedtxidlen; bits256 cachedmerkle; int32_t cachedmerkleheight; }; diff --git a/iguana/exchanges/LP_socket.c b/iguana/exchanges/LP_socket.c index 6452f4087..547d67926 100644 --- a/iguana/exchanges/LP_socket.c +++ b/iguana/exchanges/LP_socket.c @@ -423,19 +423,19 @@ cJSON *electrum_submit(char *symbol,struct electrum_info *ep,cJSON **retjsonp,ch { *retjsonp = 0; sprintf(stratumreq,"{ \"jsonrpc\":\"2.0\", \"id\": %u, \"method\":\"%s\", \"params\": %s }\n",ep->stratumid,method,params); -//printf("%s %s",symbol,stratumreq); +printf("%s %s",symbol,stratumreq); memset(ep->buf,0,ep->bufsize); sitem = electrum_sitem(ep,stratumreq,timeout,retjsonp); /*sitem = (struct stritem *)queueitem(stratumreq); sitem->expiration = timeout; sitem->DL.type = ep->stratumid++; sitem->retptrp = (void **)retjsonp;*/ -portable_mutex_lock(&ep->mutex); +//portable_mutex_lock(&ep->mutex); //queue_enqueue("sendQ",&ep->sendQ,&sitem->DL); expiration = (uint32_t)time(NULL) + timeout + 1; while ( *retjsonp == 0 && time(NULL) <= expiration ) - usleep(5000); -portable_mutex_unlock(&ep->mutex); + usleep(15000); +//portable_mutex_unlock(&ep->mutex); if ( *retjsonp == 0 || jobj(*retjsonp,"error") != 0 ) { if ( ++ep->numerrors >= LP_ELECTRUM_MAXERRORS ) @@ -897,15 +897,8 @@ int32_t LP_recvfunc(struct electrum_info *ep,char *str,int32_t len) cJSON *strjson,*errjson,*resultjson,*paramsjson; char *method; int32_t i,n,height; uint32_t idnum=0; struct stritem *stritem; struct iguana_info *coin; struct queueitem *tmp,*item = 0; if ( str == 0 || len == 0 ) return(-1); + printf("RECV.(%s)\n",str); ep->lasttime = (uint32_t)time(NULL); - /*if ( (strjson= cJSON_Parse(str)) == 0 ) - { - strjson = cJSON_CreateObject(); - resitem = cJSON_CreateObject(); - jaddstr(resitem,"string",str); - jadd(strjson,"result",resitem); - printf("mapped.(%s) -> %s\n",str,jprint(strjson,0)); - }*/ if ( (strjson= cJSON_Parse(str)) != 0 ) { resultjson = jobj(strjson,"result"); diff --git a/iguana/exchanges/LP_utxos.c b/iguana/exchanges/LP_utxos.c index 380783b2e..40e4e2ae0 100644 --- a/iguana/exchanges/LP_utxos.c +++ b/iguana/exchanges/LP_utxos.c @@ -506,7 +506,10 @@ int32_t LP_privkey_init(int32_t mypubsock,struct iguana_info *coin,bits256 mypri return(0); coin->lastprivkey = myprivkey; coin->lastprivkeytime = (uint32_t)time(NULL); - printf("privkey init.(%s) %s\n",coin->symbol,coin->smartaddr); + if ( coin->privkeydepth > 0 ) + return(0); + coin->privkeydepth++; + printf("privkey init.(%s) %s depth.%d\n",coin->symbol,coin->smartaddr,coin->privkeydepth); if ( coin->inactive == 0 ) LP_listunspent_issue(coin->symbol,coin->smartaddr,0); array = LP_listunspent(coin->symbol,coin->smartaddr); @@ -543,9 +546,9 @@ int32_t LP_privkey_init(int32_t mypubsock,struct iguana_info *coin,bits256 mypri height = jint(item,"height"); } satoshis = LP_txvalue(destaddr,coin->symbol,txid,vout); - //if ( satoshis != 0 && satoshis != value ) + if ( satoshis != 0 && satoshis != value ) printf("%s %s privkey_init value %.8f vs %.8f (%s) %.8f %.8f\n",coin->symbol,coin->smartaddr,dstr(satoshis),dstr(value),jprint(item,0),jdouble(item,"amount"),jdouble(item,"interest")); - if ( LP_inventory_prevent(iambob,coin->symbol,txid,vout) == 0 )//&& height > 0 ) + if ( coin->electrum != 0 || LP_inventory_prevent(iambob,coin->symbol,txid,vout) == 0 )//&& height > 0 ) { values[i] = satoshis; //flag += LP_address_utxoadd(coin,destaddr,txid,vout,satoshis,height,-1); @@ -554,9 +557,9 @@ int32_t LP_privkey_init(int32_t mypubsock,struct iguana_info *coin,bits256 mypri //printf("array.%d\n",n); while ( used < n-1 ) { - for (i=0; i= 0 ) { item = jitem(array,i); @@ -642,6 +645,8 @@ int32_t LP_privkey_init(int32_t mypubsock,struct iguana_info *coin,bits256 mypri } if ( values != 0 ) free(values); + if ( coin->privkeydepth > 0 ) + coin->privkeydepth--; //printf("privkey.%s %.8f\n",symbol,dstr(total)); return(flag); } From 542d459cda26222066239b1a02f23cd8fd06db8a Mon Sep 17 00:00:00 2001 From: jl777 Date: Fri, 10 Nov 2017 16:23:38 +0200 Subject: [PATCH 0503/1664] Test --- iguana/exchanges/LP_ordermatch.c | 8 ++++---- iguana/exchanges/LP_socket.c | 2 +- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/iguana/exchanges/LP_ordermatch.c b/iguana/exchanges/LP_ordermatch.c index d088e712a..c04beef58 100644 --- a/iguana/exchanges/LP_ordermatch.c +++ b/iguana/exchanges/LP_ordermatch.c @@ -1010,15 +1010,15 @@ char *LP_autobuy(void *ctx,char *myipaddr,int32_t mypubsock,char *base,char *rel destsatoshis = SATOSHIDEN * relvolume; if ( (autxo= LP_utxo_bestfit(rel,destsatoshis + 2*desttxfee)) == 0 ) return(clonestr("{\"error\":\"cant find alice utxo that is big enough\"}")); - if ( destsatoshis - 0*desttxfee < autxo->S.satoshis ) + if ( destsatoshis - desttxfee < autxo->S.satoshis ) { - //destsatoshis -= 2*desttxfee; + destsatoshis -= desttxfee; autxo->S.satoshis = destsatoshis; //printf("first path dest %.8f from %.8f\n",dstr(destsatoshis),dstr(autxo->S.satoshis)); } - else if ( autxo->S.satoshis - 0*desttxfee < destsatoshis ) + else if ( autxo->S.satoshis - desttxfee < destsatoshis ) { - autxo->S.satoshis -= 0*desttxfee; + autxo->S.satoshis -= desttxfee; destsatoshis = autxo->S.satoshis; printf("second path dest %.8f from %.8f\n",dstr(destsatoshis),dstr(autxo->S.satoshis)); } diff --git a/iguana/exchanges/LP_socket.c b/iguana/exchanges/LP_socket.c index 547d67926..8abbb6a3c 100644 --- a/iguana/exchanges/LP_socket.c +++ b/iguana/exchanges/LP_socket.c @@ -897,10 +897,10 @@ int32_t LP_recvfunc(struct electrum_info *ep,char *str,int32_t len) cJSON *strjson,*errjson,*resultjson,*paramsjson; char *method; int32_t i,n,height; uint32_t idnum=0; struct stritem *stritem; struct iguana_info *coin; struct queueitem *tmp,*item = 0; if ( str == 0 || len == 0 ) return(-1); - printf("RECV.(%s)\n",str); ep->lasttime = (uint32_t)time(NULL); if ( (strjson= cJSON_Parse(str)) != 0 ) { + printf("%s RECV.(%ld) id.%d\n",ep->symbol,strlen(str),jint(strjson,"id")); resultjson = jobj(strjson,"result"); //printf("strjson.(%s)\n",jprint(strjson,0)); if ( (method= jstr(strjson,"method")) != 0 ) From 984e266e16bd3397467adda854d13d6cb4ef3a24 Mon Sep 17 00:00:00 2001 From: jl777 Date: Fri, 10 Nov 2017 16:28:05 +0200 Subject: [PATCH 0504/1664] Test --- iguana/exchanges/LP_socket.c | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/iguana/exchanges/LP_socket.c b/iguana/exchanges/LP_socket.c index 8abbb6a3c..efcee767f 100644 --- a/iguana/exchanges/LP_socket.c +++ b/iguana/exchanges/LP_socket.c @@ -1073,10 +1073,13 @@ cJSON *LP_electrumserver(struct iguana_info *coin,char *ipaddr,uint16_t port) } else { - kickval = electrum_kickstart(ep); jaddstr(retjson,"result","success"); jaddstr(retjson,"status","already there"); - jaddnum(retjson,"restart",kickval); + if ( ep->numerrors > 0 ) + { + kickval = electrum_kickstart(ep); + jaddnum(retjson,"restart",kickval); + } } //printf("(%s)\n",jprint(retjson,0)); return(retjson); From a8cc2a898bb8773d0c6df7d859211578f15e4fd0 Mon Sep 17 00:00:00 2001 From: jl777 Date: Fri, 10 Nov 2017 16:47:51 +0200 Subject: [PATCH 0505/1664] Test --- iguana/exchanges/LP_utxos.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/iguana/exchanges/LP_utxos.c b/iguana/exchanges/LP_utxos.c index 40e4e2ae0..8b7313630 100644 --- a/iguana/exchanges/LP_utxos.c +++ b/iguana/exchanges/LP_utxos.c @@ -509,11 +509,11 @@ int32_t LP_privkey_init(int32_t mypubsock,struct iguana_info *coin,bits256 mypri if ( coin->privkeydepth > 0 ) return(0); coin->privkeydepth++; - printf("privkey init.(%s) %s depth.%d\n",coin->symbol,coin->smartaddr,coin->privkeydepth); + //printf("privkey init.(%s) %s depth.%d\n",coin->symbol,coin->smartaddr,coin->privkeydepth); if ( coin->inactive == 0 ) LP_listunspent_issue(coin->symbol,coin->smartaddr,0); array = LP_listunspent(coin->symbol,coin->smartaddr); - printf("unspent array %ld\n",strlen(jprint(array,0))); + //printf("unspent array %ld\n",strlen(jprint(array,0))); LP_address(coin,coin->smartaddr); if ( array != 0 ) { @@ -521,7 +521,7 @@ int32_t LP_privkey_init(int32_t mypubsock,struct iguana_info *coin,bits256 mypri if ( is_cJSON_Array(array) != 0 && (n= cJSON_GetArraySize(array)) > 0 ) { coin->numutxos = n; - printf("LP_privkey_init %s %d\n",coin->symbol,n); + //printf("LP_privkey_init %s %d\n",coin->symbol,n); for (iambob=0; iambob<=1; iambob++) { if ( iambob == 0 ) @@ -582,7 +582,7 @@ int32_t LP_privkey_init(int32_t mypubsock,struct iguana_info *coin,bits256 mypri else targetval = (depositval / 9) * 8 + 2*txfee; if ( targetval < txfee*2 ) targetval = txfee*2; - printf("iambob.%d i.%d deposit %.8f min %.8f target %.8f\n",iambob,i,dstr(depositval),dstr((1+LP_MINSIZE_TXFEEMULT)*txfee),dstr(targetval)); + //printf("iambob.%d i.%d deposit %.8f min %.8f target %.8f\n",iambob,i,dstr(depositval),dstr((1+LP_MINSIZE_TXFEEMULT)*txfee),dstr(targetval)); if ( depositval < (1+LP_MINSIZE_TXFEEMULT)*txfee ) continue; i = -1; From 16eabe18d4490159b5d41e3d01384b3dc81f62be Mon Sep 17 00:00:00 2001 From: jl777 Date: Fri, 10 Nov 2017 17:09:42 +0200 Subject: [PATCH 0506/1664] Test --- iguana/exchanges/LP_include.h | 2 +- iguana/exchanges/LP_socket.c | 4 +- iguana/exchanges/LP_tradebots.c | 118 ++++++++++++++------------------ 3 files changed, 55 insertions(+), 69 deletions(-) diff --git a/iguana/exchanges/LP_include.h b/iguana/exchanges/LP_include.h index aad96236c..84430761c 100644 --- a/iguana/exchanges/LP_include.h +++ b/iguana/exchanges/LP_include.h @@ -39,7 +39,7 @@ void emscripten_usleep(int32_t x); // returns immediate, no sense for sleeping #define LP_HTTP_TIMEOUT 3 // 1 is too small due to edge cases of time(NULL) #define LP_AUTOTRADE_TIMEOUT 30 -#define ELECTRUM_TIMEOUT 15 +#define ELECTRUM_TIMEOUT 7 #define LP_ELECTRUM_KEEPALIVE 60 #define LP_ELECTRUM_MAXERRORS 777 #define LP_MEMPOOL_TIMEINCR 10 diff --git a/iguana/exchanges/LP_socket.c b/iguana/exchanges/LP_socket.c index efcee767f..c7fa3a076 100644 --- a/iguana/exchanges/LP_socket.c +++ b/iguana/exchanges/LP_socket.c @@ -423,7 +423,7 @@ cJSON *electrum_submit(char *symbol,struct electrum_info *ep,cJSON **retjsonp,ch { *retjsonp = 0; sprintf(stratumreq,"{ \"jsonrpc\":\"2.0\", \"id\": %u, \"method\":\"%s\", \"params\": %s }\n",ep->stratumid,method,params); -printf("%s %s",symbol,stratumreq); +//printf("%s %s",symbol,stratumreq); memset(ep->buf,0,ep->bufsize); sitem = electrum_sitem(ep,stratumreq,timeout,retjsonp); /*sitem = (struct stritem *)queueitem(stratumreq); @@ -900,7 +900,7 @@ int32_t LP_recvfunc(struct electrum_info *ep,char *str,int32_t len) ep->lasttime = (uint32_t)time(NULL); if ( (strjson= cJSON_Parse(str)) != 0 ) { - printf("%s RECV.(%ld) id.%d\n",ep->symbol,strlen(str),jint(strjson,"id")); + //printf("%s RECV.(%ld) id.%d\n",ep->symbol,strlen(str),jint(strjson,"id")); resultjson = jobj(strjson,"result"); //printf("strjson.(%s)\n",jprint(strjson,0)); if ( (method= jstr(strjson,"method")) != 0 ) diff --git a/iguana/exchanges/LP_tradebots.c b/iguana/exchanges/LP_tradebots.c index 424909766..efbf047e4 100644 --- a/iguana/exchanges/LP_tradebots.c +++ b/iguana/exchanges/LP_tradebots.c @@ -26,7 +26,7 @@ struct LP_tradebot_trade double maxprice,totalrelvolume,basevol,relvol; uint64_t aliceid; int32_t dispdir; - uint32_t started,finished,requestid,quoteid,tradeid,completed; + uint32_t started,finished,requestid,quoteid,tradeid,expired; char base[32],rel[32],event[32]; }; @@ -55,18 +55,10 @@ void LP_tradebot_updatestats(struct LP_tradebot *bot,struct LP_tradebot_trade *t { if ( strcmp(status,"finished") == 0 ) { - flag = 1; - bot->completed++; - bot->basesum += tp->basevol; - bot->relsum += tp->relvol; + if ( tp->finished == 0 ) + tp->finished = (uint32_t)time(NULL); } } - if ( flag == 0 ) - { - bot->numpending++; - bot->pendbasesum += tp->basevol; - bot->pendrelsum += tp->relvol; - } free_json(swapjson); } free(swapstr); @@ -75,11 +67,39 @@ void LP_tradebot_updatestats(struct LP_tradebot *bot,struct LP_tradebot_trade *t void LP_tradebot_calcstats(struct LP_tradebot *bot) { - int32_t i; + int32_t i; struct LP_tradebot_trade *tp; bot->basesum = bot->relsum = bot->pendbasesum = bot->pendrelsum = 0.; bot->numpending = bot->completed = 0; for (i=0; inumtrades; i++) - LP_tradebot_updatestats(bot,bot->trades[i]); + { + if ( (tp= bot->trades[i]) == 0 ) + continue; + if ( tp->finished == 0 && time(NULL) > tp->started+INSTANTDEX_LOCKTIME*2 ) + { + tp->expired = tp->finished = (uint32_t)time(NULL); + printf("tradeid.%u expired\n",tp->tradeid); + } + if ( tp->finished != 0 ) + { + if ( tp->expired == 0 ) + { + bot->basesum += tp->basevol; + bot->relsum += tp->relvol; + bot->completed++; + } + } + else + { + if ( tp->requestid != 0 && tp->quoteid != 0 ) + { + bot->pendbasesum += tp->basevol; + bot->pendrelsum += tp->relvol; + bot->numpending++; + } + } + //LP_tradebot_updatestats(bot,bot->trades[i]); + } + printf("completed.%d (%.8f / %.8f) pending.%d (%.8f / %.8f)\n",bot->completed,bot->basesum,bot->relsum,bot->numpending,bot->pendbasesum,bot->pendrelsum); } double LP_pricevol_invert(double *basevolumep,double maxprice,double relvolume) @@ -129,6 +149,7 @@ cJSON *LP_tradebot_tradejson(struct LP_tradebot_trade *tp,int32_t dispflag) cJSON *LP_tradebot_json(struct LP_tradebot *bot) { int32_t i; double aveprice,basevolume,vol; cJSON *json,*array; + LP_tradebot_calcstats(bot); json = cJSON_CreateObject(); jaddstr(json,"result","success"); jaddstr(json,"name",bot->name); @@ -169,7 +190,6 @@ cJSON *LP_tradebot_json(struct LP_tradebot *bot) } } array = cJSON_CreateArray(); - LP_tradebot_calcstats(bot); for (i=0; inumtrades; i++) jaddi(array,LP_tradebot_tradejson(bot->trades[i],bot->dispdir)); jadd(json,"trades",array); @@ -255,9 +275,6 @@ struct LP_tradebot_trade *LP_tradebot_pending(struct LP_tradebot *bot,cJSON *pen tp->basevol = jdouble(pending,"basevalue"); tp->relvol = jdouble(pending,"relvalue"); printf("tradebot pending basevol %.8f relvol %.8f\n",tp->basevol,tp->relvol); - //bot->pendrelsum += tp->relvol; - //bot->pendbasesum += tp->basevol; - //bot->numpending++; return(tp); } @@ -293,6 +310,7 @@ void LP_tradebot_timeslice(void *ctx,struct LP_tradebot *bot) { double remaining,maxrel; struct LP_tradebot_trade *tp; int32_t i,maxiters = 10; uint32_t tradeid; bits256 destpubkey; char *retstr,*liststr; cJSON *retjson,*retjson2,*pending; memset(destpubkey.bytes,0,sizeof(destpubkey)); + LP_tradebot_calcstats(bot); if ( bot->dead == 0 && bot->pause == 0 && bot->userpause == 0 && bot->numtrades < sizeof(bot->trades)/sizeof(*bot->trades) ) { if ( (liststr= LP_recent_swaps(0)) != 0 ) @@ -328,6 +346,7 @@ void LP_tradebot_timeslice(void *ctx,struct LP_tradebot *bot) free(retstr); } } + LP_tradebot_calcstats(bot); } free_json(retjson); } @@ -347,18 +366,21 @@ void LP_aliceid(uint32_t tradeid,uint64_t aliceid,char *event,uint32_t requestid { for (i=0; inumtrades; i++) { - if ( (tp= bot->trades[i]) != 0 && tp->finished == 0 && tp->tradeid == tradeid ) + if ( (tp= bot->trades[i]) != 0 ) { - tp->aliceid = aliceid; - printf("bot event tradeid.%u aliceid.%llu (%s) r.%u q.%u\n",tradeid,(long long)aliceid,event,requestid,quoteid); - if ( requestid != 0 && quoteid != 0 ) + if ( tp->finished == 0 && tp->tradeid == tradeid ) { - tp->requestid = requestid; - tp->quoteid = quoteid; - } - strcpy(tp->event,event); - matched = 0; - break; + tp->aliceid = aliceid; + printf("bot event tradeid.%u aliceid.%llu (%s) r.%u q.%u\n",tradeid,(long long)aliceid,event,requestid,quoteid); + if ( requestid != 0 && quoteid != 0 ) + { + tp->requestid = requestid; + tp->quoteid = quoteid; + } + strcpy(tp->event,event); + matched = 1; + break; + } else printf("tradeid.%u finished.%u\n",tp->tradeid,tp->finished); } } if ( matched != 0 ) @@ -379,11 +401,8 @@ void LP_tradebot_finished(uint32_t tradeid,uint32_t requestid,uint32_t quoteid) { tp->requestid = requestid; tp->quoteid = quoteid; - //bot->pendbasesum -= tp->basevol, bot->basesum += tp->basevol; - //bot->pendrelsum -= tp->relvol, bot->relsum += tp->relvol; - //bot->numpending--, bot->completed++; - printf("bot.%u detected completion tradeid.%u aliceid.%llx r.%u q.%u, numpending.%d completed.%d\n",bot->id,tp->tradeid,(long long)tp->aliceid,tp->requestid,tp->quoteid,bot->numpending,bot->completed); - tp->completed = tp->finished = (uint32_t)time(NULL); + printf("bot.%u detected completion tradeid.%u aliceid.%llu r.%u q.%u, numpending.%d completed.%d\n",bot->id,tp->tradeid,(long long)tp->aliceid,tp->requestid,tp->quoteid,bot->numpending,bot->completed); + tp->finished = (uint32_t)time(NULL); strcpy(tp->event,"finished"); break; } @@ -394,44 +413,11 @@ void LP_tradebot_finished(uint32_t tradeid,uint32_t requestid,uint32_t quoteid) void LP_tradebots_timeslice(void *ctx) { static uint32_t lastnumfinished = 0; - struct LP_tradebot_trade *tp; struct iguana_info *relcoin; struct LP_tradebot *bot,*tmp; int32_t i; + struct iguana_info *relcoin; struct LP_tradebot *bot,*tmp; DL_FOREACH_SAFE(LP_tradebots,bot,tmp) { if ( (relcoin= LP_coinfind(bot->rel)) != 0 ) LP_listunspent_issue(bot->rel,relcoin->smartaddr,1); - if ( bot->numpending > 0 && LP_numfinished > lastnumfinished ) - { - // expire pending trades and see if any still need their requestid/quoteid - bot->basesum = bot->pendbasesum = 0.;//-= tp->basevol; - bot->relsum = bot->pendrelsum = 0.;//-= tp->relvol; - bot->completed = bot->numpending = 0;//--; - for (i=0; inumtrades; i++) - { - if ( (tp= bot->trades[i]) != 0 ) - { - if (tp->finished == 0 ) - { - if ( time(NULL) > tp->started+INSTANTDEX_LOCKTIME*2 ) - { - tp->finished = (uint32_t)time(NULL); - printf("%s trade.%d of %d expired\n",bot->name,i,bot->numtrades); - } - } - if ( tp->finished != 0 && tp->completed != 0 ) - { - bot->basesum += tp->basevol; - bot->relsum += tp->relvol; - bot->completed++; - } - else if ( tp->finished == 0 && tp->requestid != 0 && tp->quoteid != 0 ) - { - bot->pendbasesum += tp->basevol; - bot->pendrelsum += tp->relvol; - bot->numpending++; - } - } - } - } if ( bot->relsum >= 0.99*bot->totalrelvolume-SMALLVAL || bot->basesum >= 0.99*bot->totalbasevolume-SMALLVAL ) bot->dead = (uint32_t)time(NULL); else if ( (bot->pendrelsum+bot->relsum) >= 0.99*bot->totalrelvolume-SMALLVAL || (bot->basesum+bot->pendbasesum) >= 0.99*bot->totalbasevolume-SMALLVAL ) From 55b1a1e4d6336dc7063a13e01d57437a3d4eced5 Mon Sep 17 00:00:00 2001 From: jl777 Date: Fri, 10 Nov 2017 17:22:19 +0200 Subject: [PATCH 0507/1664] Test --- iguana/exchanges/LP_commands.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/iguana/exchanges/LP_commands.c b/iguana/exchanges/LP_commands.c index 35387d845..9d0f4ff47 100644 --- a/iguana/exchanges/LP_commands.c +++ b/iguana/exchanges/LP_commands.c @@ -393,10 +393,9 @@ bot_resume(botid)\n\ if ( coinaddr[0] != 0 ) { LP_address(ptr,coinaddr); - LP_listunspent_issue(coin,coinaddr,1); if ( strcmp(coinaddr,ptr->smartaddr) == 0 && bits256_nonz(G.LP_privkey) != 0 ) { - //printf("network invoked\n"); + LP_listunspent_issue(coin,coinaddr,2); LP_privkey_init(-1,ptr,G.LP_privkey,G.LP_mypub25519); //LP_smartutxos_push(ptr); if ( ptr->electrum != 0 ) @@ -487,6 +486,8 @@ bot_resume(botid)\n\ { //privkey = LP_privkeycalc(ctx,pubkey33,&pubkey,ptr,"",USERPASS_WIFSTR); //LP_utxopurge(0); + LP_address(ptr,ptr->smartaddr); + LP_listunspent_issue(coin,ptr->smartaddr,2); if ( bits256_nonz(G.LP_privkey) != 0 ) LP_privkey_init(-1,ptr,G.LP_privkey,G.LP_mypub25519); else printf("no LP_privkey\n"); From 2b3c25f9b0a0bf39519f41e95aea1562d4e272cf Mon Sep 17 00:00:00 2001 From: jl777 Date: Fri, 10 Nov 2017 17:24:59 +0200 Subject: [PATCH 0508/1664] Test --- iguana/exchanges/LP_socket.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/iguana/exchanges/LP_socket.c b/iguana/exchanges/LP_socket.c index c7fa3a076..efcee767f 100644 --- a/iguana/exchanges/LP_socket.c +++ b/iguana/exchanges/LP_socket.c @@ -423,7 +423,7 @@ cJSON *electrum_submit(char *symbol,struct electrum_info *ep,cJSON **retjsonp,ch { *retjsonp = 0; sprintf(stratumreq,"{ \"jsonrpc\":\"2.0\", \"id\": %u, \"method\":\"%s\", \"params\": %s }\n",ep->stratumid,method,params); -//printf("%s %s",symbol,stratumreq); +printf("%s %s",symbol,stratumreq); memset(ep->buf,0,ep->bufsize); sitem = electrum_sitem(ep,stratumreq,timeout,retjsonp); /*sitem = (struct stritem *)queueitem(stratumreq); @@ -900,7 +900,7 @@ int32_t LP_recvfunc(struct electrum_info *ep,char *str,int32_t len) ep->lasttime = (uint32_t)time(NULL); if ( (strjson= cJSON_Parse(str)) != 0 ) { - //printf("%s RECV.(%ld) id.%d\n",ep->symbol,strlen(str),jint(strjson,"id")); + printf("%s RECV.(%ld) id.%d\n",ep->symbol,strlen(str),jint(strjson,"id")); resultjson = jobj(strjson,"result"); //printf("strjson.(%s)\n",jprint(strjson,0)); if ( (method= jstr(strjson,"method")) != 0 ) From 23a4df10fdda6ea8a2963b32bd2c4d411f7dc86d Mon Sep 17 00:00:00 2001 From: DeckerSU Date: Fri, 10 Nov 2017 19:33:26 +0400 Subject: [PATCH 0509/1664] changes needed to build win32 marketmaker with MSVC 2015 --- OSlibs/win/mingw.h | 19 ++++++++++++------- marketmaker.vcxproj | 1 + 2 files changed, 13 insertions(+), 7 deletions(-) diff --git a/OSlibs/win/mingw.h b/OSlibs/win/mingw.h index 76802c56e..2c35aa78c 100755 --- a/OSlibs/win/mingw.h +++ b/OSlibs/win/mingw.h @@ -61,13 +61,18 @@ * @remarks - #if (defined(_M_X64) || defined(__amd64__)) && defined(WIN32) * is equivalent to #if defined(_M_X64) as _M_X64 is defined for MSVC only */ -#if !defined(_M_X64) -struct pollfd { - SOCKET fd; /* file descriptor */ - short events; /* requested events */ - short revents; /* returned events */ -}; -#endif + + +// [Decker] pollfs is already defined in winsock2.h + +//#if !defined(_M_X64) +//struct pollfd { + //SOCKET fd; /* file descriptor */ + //short events; /* requested events */ + //short revents; /* returned events */ +//}; +//#endif + #if defined(_M_X64) /* diff --git a/marketmaker.vcxproj b/marketmaker.vcxproj index b441d6ab4..0dbe62279 100644 --- a/marketmaker.vcxproj +++ b/marketmaker.vcxproj @@ -130,6 +130,7 @@ Console true true + Ws2_32.lib;Advapi32.lib;$(SolutionDir)OSlibs\win\release\pthreadVC2.lib;libcurl.lib;nanomsg.lib;%(AdditionalDependencies) From c8d75a2ab590bdb82ead7de32866d22731c987d2 Mon Sep 17 00:00:00 2001 From: jl777 Date: Fri, 10 Nov 2017 18:09:14 +0200 Subject: [PATCH 0510/1664] Test --- iguana/exchanges/LP_cache.c | 232 +++++++++++++++++++++++++++++++ iguana/exchanges/LP_include.h | 2 + iguana/exchanges/LP_nativeDEX.c | 5 +- iguana/exchanges/LP_ordermatch.c | 2 +- iguana/exchanges/LP_socket.c | 38 +---- iguana/exchanges/LP_utxo.c | 154 -------------------- 6 files changed, 239 insertions(+), 194 deletions(-) create mode 100644 iguana/exchanges/LP_cache.c diff --git a/iguana/exchanges/LP_cache.c b/iguana/exchanges/LP_cache.c new file mode 100644 index 000000000..ed0626a2b --- /dev/null +++ b/iguana/exchanges/LP_cache.c @@ -0,0 +1,232 @@ + +/****************************************************************************** + * Copyright © 2014-2017 The SuperNET Developers. * + * * + * See the AUTHORS, DEVELOPER-AGREEMENT and LICENSE files at * + * the top-level directory of this distribution for the individual copyright * + * holder information and the developer policies on copyright and licensing. * + * * + * Unless otherwise agreed in a custom licensing agreement, no part of the * + * SuperNET software, including this file may be copied, modified, propagated * + * or distributed except according to the terms contained in the LICENSE file * + * * + * Removal or modification of this copyright notice is prohibited. * + * * + ******************************************************************************/ +// +// LP_cache.c +// marketmaker +// + +cJSON *LP_transaction_fromdata(struct iguana_info *coin,bits256 txid,uint8_t *serialized,int32_t len) +{ + uint8_t *extraspace; cJSON *txobj; char str[65],str2[65]; struct iguana_msgtx msgtx; bits256 checktxid; + extraspace = calloc(1,4000000); + memset(&msgtx,0,sizeof(msgtx)); + txobj = bitcoin_data2json(coin->taddr,coin->pubtype,coin->p2shtype,coin->isPoS,coin->height,&checktxid,&msgtx,extraspace,4000000,serialized,len,0,0,coin->zcash); + //printf("TX.(%s) match.%d\n",jprint(txobj,0),bits256_cmp(txid,checktxid)); + free(extraspace); + if ( bits256_cmp(txid,checktxid) != 0 ) + { + printf("%s LP_transaction_fromdata mismatched txid %s vs %s\n",coin->symbol,bits256_str(str,txid),bits256_str(str2,checktxid)); + free_json(txobj); + txobj = 0; + } + return(txobj); +} + +cJSON *LP_cache_transaction(struct iguana_info *coin,bits256 txid,uint8_t *serialized,int32_t len) +{ + cJSON *txobj; struct LP_transaction *tx; + if ( (txobj= LP_transaction_fromdata(coin,txid,serialized,len)) != 0 ) + { + if ( (tx= LP_transactionfind(coin,txid)) == 0 || tx->serialized == 0 ) + { + txobj = LP_transactioninit(coin,txid,0,txobj); + LP_transactioninit(coin,txid,1,txobj); + tx = LP_transactionfind(coin,txid); + } + if ( tx != 0 ) + { + tx->serialized = serialized; + tx->len = len; + } + else + { + char str[65]; printf("unexpected couldnt find tx %s %s\n",coin->symbol,bits256_str(str,txid)); + free(serialized); + } + } + return(txobj); +} + +int32_t LP_SPV_load(struct iguana_info *coin,bits256 txid,int32_t height) +{ + return(-1); +} + +void LP_SPV_store(struct iguana_info *coin,char *coinaddr,bits256 txid,int32_t height) +{ + struct LP_transaction *tx = 0; + if ( strcmp(coin->smartaddr,coinaddr) == 0 && (tx= LP_transactionfind(coin,txid)) != 0 && tx->serialized != 0 ) + { + char str[65]; printf("store %s %s.[%d]\n",coin->symbol,bits256_str(str,txid),tx->len); + } else printf("skip SPV store for (%s) tx.%p\n",coinaddr,tx); +} + +bits256 iguana_merkle(bits256 *tree,int32_t txn_count) +{ + int32_t i,n=0,prev; uint8_t serialized[sizeof(bits256) * 2]; + if ( txn_count == 1 ) + return(tree[0]); + prev = 0; + while ( txn_count > 1 ) + { + if ( (txn_count & 1) != 0 ) + tree[prev + txn_count] = tree[prev + txn_count-1], txn_count++; + n += txn_count; + for (i=0; i> 1)] = bits256_doublesha256(0,serialized,sizeof(serialized)); + } + prev = n; + txn_count >>= 1; + } + return(tree[n]); +} + +bits256 validate_merkle(int32_t pos,bits256 txid,cJSON *proofarray,int32_t proofsize) +{ + int32_t i; uint8_t serialized[sizeof(bits256) * 2]; bits256 hash,proof; + hash = txid; + for (i=0; i>= 1; + } + return(hash); +} + +bits256 LP_merkleroot(struct iguana_info *coin,struct electrum_info *ep,int32_t height) +{ + cJSON *hdrobj; bits256 merkleroot; + memset(merkleroot.bytes,0,sizeof(merkleroot)); + if ( coin->cachedmerkleheight == height ) + return(coin->cachedmerkle); + if ( (hdrobj= electrum_getheader(coin->symbol,ep,&hdrobj,height)) != 0 ) + { + if ( jobj(hdrobj,"merkle_root") != 0 ) + { + merkleroot = jbits256(hdrobj,"merkle_root"); + if ( bits256_nonz(merkleroot) != 0 ) + { + coin->cachedmerkle = merkleroot; + coin->cachedmerkleheight = height; + } + } + free_json(hdrobj); + } else printf("couldnt get header for ht.%d\n",height); + return(merkleroot); +} + +int32_t LP_merkleproof(struct iguana_info *coin,char *coinaddr,struct electrum_info *ep,bits256 txid,int32_t height) +{ + cJSON *merkobj,*merkles; bits256 roothash,merkleroot; int32_t retval,m,SPV = 0; + if ( strcmp(coin->smartaddr,coinaddr) == 0 && (retval= LP_SPV_load(coin,txid,height)) > 0 ) + return(retval); + if ( (merkobj= electrum_getmerkle(coin->symbol,ep,&merkobj,txid,height)) != 0 ) + { + char str[65],str2[65],str3[65]; + SPV = -1; + memset(roothash.bytes,0,sizeof(roothash)); + if ( (merkles= jarray(&m,merkobj,"merkle")) != 0 ) + { + roothash = validate_merkle(jint(merkobj,"pos"),txid,merkles,m); + merkleroot = LP_merkleroot(coin,ep,height); + if ( bits256_nonz(merkleroot) != 0 ) + { + if ( bits256_cmp(merkleroot,roothash) == 0 ) + { + SPV = height; + LP_SPV_store(coin,coinaddr,txid,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)); + } else SPV = 0; + } + if ( SPV < 0 ) + { + printf("MERKLE DIDNT VERIFY.%s %s ht.%d (%s)\n",coin->symbol,bits256_str(str,txid),height,jprint(merkobj,0)); + if ( jobj(merkobj,"error") != 0 ) + SPV = 0; // try again later + } + free_json(merkobj); + } + return(SPV); +} + +char *LP_unspents_filestr(char *symbol,char *addr) +{ + char fname[1024]; long fsize; + sprintf(fname,"%s/UNSPENTS/%s_%s",GLOBAL_DBDIR,symbol,addr), OS_portable_path(fname); + return(OS_filestr(&fsize,fname)); +} + +void LP_unspents_cache(char *symbol,char *addr,char *arraystr,int32_t updatedflag) +{ + char fname[1024]; FILE *fp=0; + sprintf(fname,"%s/UNSPENTS/%s_%s",GLOBAL_DBDIR,symbol,addr), OS_portable_path(fname); + //printf("unspents cache.(%s) for %s %s, updated.%d\n",fname,symbol,addr,updatedflag); + if ( updatedflag == 0 && (fp= fopen(fname,"rb")) == 0 ) + updatedflag = 1; + else if ( fp != 0 ) + fclose(fp); + if ( updatedflag != 0 && (fp= fopen(fname,"wb")) != 0 ) + { + fwrite(arraystr,1,strlen(arraystr),fp); + fclose(fp); + } +} + +uint64_t LP_unspents_load(char *symbol,char *addr) +{ + char *arraystr; uint64_t balance = 0; int32_t i,n; cJSON *retjson,*item; struct iguana_info *coin; + if ( (coin= LP_coinfind(symbol)) != 0 ) + { + if ( (arraystr= LP_unspents_filestr(symbol,addr)) != 0 ) + { + if ( (retjson= cJSON_Parse(arraystr)) != 0 ) + { + //printf("PROCESS UNSPENTS %s\n",arraystr); + if ( (n= cJSON_GetArraySize(retjson)) > 0 ) + { + for (i=0; ielectrum,coin->smartaddr,retjson,1); + free_json(retjson); + } + free(arraystr); + } + } + return(balance); +} + + + diff --git a/iguana/exchanges/LP_include.h b/iguana/exchanges/LP_include.h index 84430761c..f19aafc3c 100644 --- a/iguana/exchanges/LP_include.h +++ b/iguana/exchanges/LP_include.h @@ -394,6 +394,8 @@ uint16_t LP_psock_get(char *connectaddr,char *publicaddr,int32_t ispaired); int32_t LP_coinbus(uint16_t coin_busport); int32_t LP_nanomsg_recvs(void *ctx); void LP_aliceid(uint32_t tradeid,uint64_t aliceid,char *event,uint32_t requestid,uint32_t quoteid); +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_reserved_msg(int32_t priority,char *base,char *rel,bits256 pubkey,char *msg); diff --git a/iguana/exchanges/LP_nativeDEX.c b/iguana/exchanges/LP_nativeDEX.c index 8023a8727..fdd337b42 100644 --- a/iguana/exchanges/LP_nativeDEX.c +++ b/iguana/exchanges/LP_nativeDEX.c @@ -154,6 +154,7 @@ char *blocktrail_listtransactions(char *symbol,char *coinaddr,int32_t num,int32_ #include "LP_bitcoin.c" #include "LP_coins.c" #include "LP_rpc.c" +#include "LP_cache.c" #include "LP_RTmetrics.c" #include "LP_utxo.c" #include "LP_prices.c" @@ -524,7 +525,7 @@ void LP_coinsloop(void *_coins) if ( up->SPV == 0 ) { nonz++; - up->SPV = LP_merkleproof(coin,backupep,up->U.txid,up->U.height); + up->SPV = LP_merkleproof(coin,ap->coinaddr,backupep,up->U.txid,up->U.height); if ( 0 && up->SPV > 0 ) printf("%s %s: SPV.%d\n",coin->symbol,bits256_str(str,up->U.txid),up->SPV); } @@ -535,7 +536,7 @@ void LP_coinsloop(void *_coins) oldht = up->U.height; LP_txheight_check(coin,ap->coinaddr,up); if ( oldht != up->U.height ) - up->SPV = LP_merkleproof(coin,backupep,up->U.txid,up->U.height); + up->SPV = LP_merkleproof(coin,ap->coinaddr,backupep,up->U.txid,up->U.height); if ( up->SPV <= 0 ) up->SPV = -2; else printf("%s %s: corrected SPV.%d\n",coin->symbol,bits256_str(str,up->U.txid),up->SPV); diff --git a/iguana/exchanges/LP_ordermatch.c b/iguana/exchanges/LP_ordermatch.c index c04beef58..fb5761d86 100644 --- a/iguana/exchanges/LP_ordermatch.c +++ b/iguana/exchanges/LP_ordermatch.c @@ -647,7 +647,7 @@ int32_t LP_validSPV(char *symbol,char *coinaddr,bits256 txid,int32_t vout) return(-1); if ( (backupep= ep->prev) == 0 ) backupep = ep; - up->SPV = LP_merkleproof(coin,backupep,up->U.txid,up->U.height); + up->SPV = LP_merkleproof(coin,coinaddr,backupep,up->U.txid,up->U.height); if ( up->SPV <= 0 ) return(-1); } diff --git a/iguana/exchanges/LP_socket.c b/iguana/exchanges/LP_socket.c index efcee767f..77f790c53 100644 --- a/iguana/exchanges/LP_socket.c +++ b/iguana/exchanges/LP_socket.c @@ -662,23 +662,6 @@ cJSON *electrum_getheader(char *symbol,struct electrum_info *ep,cJSON **retjsonp return(electrum_intarg(symbol,ep,retjsonp,"blockchain.block.get_header",n,ELECTRUM_TIMEOUT)); } -cJSON *LP_transaction_fromdata(struct iguana_info *coin,bits256 txid,uint8_t *serialized,int32_t len) -{ - uint8_t *extraspace; cJSON *txobj; char str[65],str2[65]; struct iguana_msgtx msgtx; bits256 checktxid; - extraspace = calloc(1,4000000); - memset(&msgtx,0,sizeof(msgtx)); - txobj = bitcoin_data2json(coin->taddr,coin->pubtype,coin->p2shtype,coin->isPoS,coin->height,&checktxid,&msgtx,extraspace,4000000,serialized,len,0,0,coin->zcash); - //printf("TX.(%s) match.%d\n",jprint(txobj,0),bits256_cmp(txid,checktxid)); - free(extraspace); - if ( bits256_cmp(txid,checktxid) != 0 ) - { - printf("%s LP_transaction_fromdata mismatched txid %s vs %s\n",coin->symbol,bits256_str(str,txid),bits256_str(str2,checktxid)); - free_json(txobj); - txobj = 0; - } - return(txobj); -} - cJSON *_electrum_transaction(char *symbol,struct electrum_info *ep,cJSON **retjsonp,bits256 txid) { char *hexstr,str[65]; int32_t len; cJSON *hexjson,*txobj=0; struct iguana_info *coin; uint8_t *serialized; struct LP_transaction *tx; @@ -728,26 +711,7 @@ cJSON *_electrum_transaction(char *symbol,struct electrum_info *ep,cJSON **retjs memcpy(coin->cachedtxiddata,serialized,len); free(hexstr); //printf("DATA.(%s) from (%s)\n",hexstr+1,jprint(hexjson,0)); - if ( (txobj= LP_transaction_fromdata(coin,txid,serialized,len)) != 0 ) - { - if ( (tx= LP_transactionfind(coin,txid)) == 0 || tx->serialized == 0 ) - { - txobj = LP_transactioninit(coin,txid,0,txobj); - LP_transactioninit(coin,txid,1,txobj); - tx = LP_transactionfind(coin,txid); - } - if ( tx != 0 ) - { - tx->serialized = serialized; - tx->len = len; - } - else - { - printf("unexpected couldnt find tx %s %s\n",coin->symbol,bits256_str(str,txid)); - free(serialized); - } - } - *retjsonp = txobj; + *retjsonp = LP_cache_transaction(coin,txid,serialized,len); // eats serialized free_json(hexjson); //printf("return from electrum_transaction\n"); return(*retjsonp); diff --git a/iguana/exchanges/LP_utxo.c b/iguana/exchanges/LP_utxo.c index 575aff00c..ce98ac396 100644 --- a/iguana/exchanges/LP_utxo.c +++ b/iguana/exchanges/LP_utxo.c @@ -316,107 +316,6 @@ cJSON *LP_address_item(struct iguana_info *coin,struct LP_address_utxo *up,int32 uint64_t _LP_unspents_metric(uint64_t total,int32_t n) { return((total<<16) | (n & 0xffff)); } -bits256 iguana_merkle(bits256 *tree,int32_t txn_count) -{ - int32_t i,n=0,prev; uint8_t serialized[sizeof(bits256) * 2]; - if ( txn_count == 1 ) - return(tree[0]); - prev = 0; - while ( txn_count > 1 ) - { - if ( (txn_count & 1) != 0 ) - tree[prev + txn_count] = tree[prev + txn_count-1], txn_count++; - n += txn_count; - for (i=0; i> 1)] = bits256_doublesha256(0,serialized,sizeof(serialized)); - } - prev = n; - txn_count >>= 1; - } - return(tree[n]); -} - -bits256 validate_merkle(int32_t pos,bits256 txid,cJSON *proofarray,int32_t proofsize) -{ - int32_t i; uint8_t serialized[sizeof(bits256) * 2]; bits256 hash,proof; - hash = txid; - for (i=0; i>= 1; - } - return(hash); -} - -bits256 LP_merkleroot(struct iguana_info *coin,struct electrum_info *ep,int32_t height) -{ - cJSON *hdrobj; bits256 merkleroot; - memset(merkleroot.bytes,0,sizeof(merkleroot)); - if ( coin->cachedmerkleheight == height ) - return(coin->cachedmerkle); - if ( (hdrobj= electrum_getheader(coin->symbol,ep,&hdrobj,height)) != 0 ) - { - if ( jobj(hdrobj,"merkle_root") != 0 ) - { - merkleroot = jbits256(hdrobj,"merkle_root"); - if ( bits256_nonz(merkleroot) != 0 ) - { - coin->cachedmerkle = merkleroot; - coin->cachedmerkleheight = height; - } - } - free_json(hdrobj); - } else printf("couldnt get header for ht.%d\n",height); - return(merkleroot); -} - -int32_t LP_merkleproof(struct iguana_info *coin,struct electrum_info *ep,bits256 txid,int32_t height) -{ - cJSON *merkobj,*merkles; bits256 roothash,merkleroot; int32_t m,SPV = 0; - if ( (merkobj= electrum_getmerkle(coin->symbol,ep,&merkobj,txid,height)) != 0 ) - { - char str[65],str2[65],str3[65]; - SPV = -1; - memset(roothash.bytes,0,sizeof(roothash)); - if ( (merkles= jarray(&m,merkobj,"merkle")) != 0 ) - { - roothash = validate_merkle(jint(merkobj,"pos"),txid,merkles,m); - merkleroot = LP_merkleroot(coin,ep,height); - if ( bits256_nonz(merkleroot) != 0 ) - { - 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\n",bits256_str(str,txid),height,jprint(merkobj,0),bits256_str(str2,roothash),bits256_str(str3,merkleroot)); - } else SPV = 0; - } - if ( SPV < 0 ) - { - printf("MERKLE DIDNT VERIFY.%s %s ht.%d (%s)\n",coin->symbol,bits256_str(str,txid),height,jprint(merkobj,0)); - if ( jobj(merkobj,"error") != 0 ) - SPV = 0; // try again later - } - free_json(merkobj); - } - return(SPV); -} - cJSON *LP_address_utxos(struct iguana_info *coin,char *coinaddr,int32_t electrumret) { cJSON *array,*item; int32_t n; uint64_t total; struct LP_address *ap=0,*atmp; struct LP_address_utxo *up,*tmp; cJSON *txobj; @@ -1077,56 +976,3 @@ int32_t LP_undospends(struct iguana_info *coin,int32_t lastheight) } return(num); } - -char *LP_unspents_filestr(char *symbol,char *addr) -{ - char fname[1024]; long fsize; - sprintf(fname,"%s/UNSPENTS/%s_%s",GLOBAL_DBDIR,symbol,addr), OS_portable_path(fname); - return(OS_filestr(&fsize,fname)); -} - -void LP_unspents_cache(char *symbol,char *addr,char *arraystr,int32_t updatedflag) -{ - char fname[1024]; FILE *fp=0; - sprintf(fname,"%s/UNSPENTS/%s_%s",GLOBAL_DBDIR,symbol,addr), OS_portable_path(fname); - //printf("unspents cache.(%s) for %s %s, updated.%d\n",fname,symbol,addr,updatedflag); - if ( updatedflag == 0 && (fp= fopen(fname,"rb")) == 0 ) - updatedflag = 1; - else if ( fp != 0 ) - fclose(fp); - if ( updatedflag != 0 && (fp= fopen(fname,"wb")) != 0 ) - { - fwrite(arraystr,1,strlen(arraystr),fp); - fclose(fp); - } -} - -uint64_t LP_unspents_load(char *symbol,char *addr) -{ - char *arraystr; uint64_t balance = 0; int32_t i,n; cJSON *retjson,*item; struct iguana_info *coin; - if ( (coin= LP_coinfind(symbol)) != 0 ) - { - if ( (arraystr= LP_unspents_filestr(symbol,addr)) != 0 ) - { - if ( (retjson= cJSON_Parse(arraystr)) != 0 ) - { - //printf("PROCESS UNSPENTS %s\n",arraystr); - if ( (n= cJSON_GetArraySize(retjson)) > 0 ) - { - for (i=0; ielectrum,coin->smartaddr,retjson,1); - free_json(retjson); - } - free(arraystr); - } - } - return(balance); -} - - - From 5268f5d71c391ecd7068a6d28f1bef5d9c63d58c Mon Sep 17 00:00:00 2001 From: jl777 Date: Fri, 10 Nov 2017 18:15:52 +0200 Subject: [PATCH 0511/1664] Test --- iguana/exchanges/LP_nativeDEX.c | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/iguana/exchanges/LP_nativeDEX.c b/iguana/exchanges/LP_nativeDEX.c index fdd337b42..9ab94a382 100644 --- a/iguana/exchanges/LP_nativeDEX.c +++ b/iguana/exchanges/LP_nativeDEX.c @@ -467,7 +467,7 @@ void utxosQ_loop(void *myipaddr) void LP_coinsloop(void *_coins) { - struct LP_address *ap=0,*atmp; 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; 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; if ( strcmp("BTC",coins) == 0 ) { strcpy(LP_coinsloopBTC_stats.name,"BTC coin loop"); @@ -515,9 +515,8 @@ void LP_coinsloop(void *_coins) { if ( (backupep= ep->prev) == 0 ) backupep = ep; - HASH_ITER(hh,coin->addresses,ap,atmp) + if ( (ap= LP_addressfind(coin,coin->smartaddr)) != 0 ) { - break; // causes timeouts probably due to too much usage, SPV validation done on tx spending DL_FOREACH_SAFE(ap->utxos,up,tmp) { if ( up->U.height > 0 && up->spendheight < 0 ) From 13349dbaf68a94daf0e0925b741cdf840548ae19 Mon Sep 17 00:00:00 2001 From: jl777 Date: Fri, 10 Nov 2017 18:23:40 +0200 Subject: [PATCH 0512/1664] Test --- iguana/exchanges/LP_cache.c | 4 ++-- iguana/exchanges/LP_socket.c | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/iguana/exchanges/LP_cache.c b/iguana/exchanges/LP_cache.c index ed0626a2b..80b7d33c7 100644 --- a/iguana/exchanges/LP_cache.c +++ b/iguana/exchanges/LP_cache.c @@ -70,8 +70,8 @@ void LP_SPV_store(struct iguana_info *coin,char *coinaddr,bits256 txid,int32_t h struct LP_transaction *tx = 0; if ( strcmp(coin->smartaddr,coinaddr) == 0 && (tx= LP_transactionfind(coin,txid)) != 0 && tx->serialized != 0 ) { - char str[65]; printf("store %s %s.[%d]\n",coin->symbol,bits256_str(str,txid),tx->len); - } else printf("skip SPV store for (%s) tx.%p\n",coinaddr,tx); + //char str[65]; printf("store %s %s.[%d]\n",coin->symbol,bits256_str(str,txid),tx->len); + } //else printf("skip SPV store for (%s) tx.%p\n",coinaddr,tx); } bits256 iguana_merkle(bits256 *tree,int32_t txn_count) diff --git a/iguana/exchanges/LP_socket.c b/iguana/exchanges/LP_socket.c index 77f790c53..c64c1330f 100644 --- a/iguana/exchanges/LP_socket.c +++ b/iguana/exchanges/LP_socket.c @@ -423,7 +423,7 @@ cJSON *electrum_submit(char *symbol,struct electrum_info *ep,cJSON **retjsonp,ch { *retjsonp = 0; sprintf(stratumreq,"{ \"jsonrpc\":\"2.0\", \"id\": %u, \"method\":\"%s\", \"params\": %s }\n",ep->stratumid,method,params); -printf("%s %s",symbol,stratumreq); +//printf("%s %s",symbol,stratumreq); memset(ep->buf,0,ep->bufsize); sitem = electrum_sitem(ep,stratumreq,timeout,retjsonp); /*sitem = (struct stritem *)queueitem(stratumreq); @@ -864,7 +864,7 @@ int32_t LP_recvfunc(struct electrum_info *ep,char *str,int32_t len) ep->lasttime = (uint32_t)time(NULL); if ( (strjson= cJSON_Parse(str)) != 0 ) { - printf("%s RECV.(%ld) id.%d\n",ep->symbol,strlen(str),jint(strjson,"id")); + //printf("%s RECV.(%ld) id.%d\n",ep->symbol,strlen(str),jint(strjson,"id")); resultjson = jobj(strjson,"result"); //printf("strjson.(%s)\n",jprint(strjson,0)); if ( (method= jstr(strjson,"method")) != 0 ) From 54a7c61f2fb8a9f6ec106fa13c04093313d3dfa9 Mon Sep 17 00:00:00 2001 From: jl777 Date: Fri, 10 Nov 2017 19:48:32 +0200 Subject: [PATCH 0513/1664] privkeys[] overflow --- iguana/exchanges/LP_cache.c | 68 +++++++++++++++++++++++++++---- iguana/exchanges/LP_include.h | 5 ++- iguana/exchanges/LP_tradebots.c | 2 +- iguana/exchanges/LP_transaction.c | 2 +- 4 files changed, 66 insertions(+), 11 deletions(-) diff --git a/iguana/exchanges/LP_cache.c b/iguana/exchanges/LP_cache.c index 80b7d33c7..3c3f32b1b 100644 --- a/iguana/exchanges/LP_cache.c +++ b/iguana/exchanges/LP_cache.c @@ -60,18 +60,72 @@ cJSON *LP_cache_transaction(struct iguana_info *coin,bits256 txid,uint8_t *seria return(txobj); } +struct LP_transaction +{ + UT_hash_handle hh; + bits256 txid; + int32_t height,numvouts,numvins,len,SPV; + uint8_t *serialized; + struct LP_outpoint outpoints[]; +}; + +int32_t LP_cacheitem(uint8_t *ptr,long remains) +{ + +} + +void *LP_cacheptr(FILE **wfp,long *fsizep,struct iguana_info *coin) +{ + char fname[1024]; long n,len = 0; uint8_t *ptr = 0; + sprintf(fname,"%s/UNSPENTS/%s.SPV",GLOBAL_DBDIR,coin->symbol), OS_portable_path(fname); + if ( ((*wfp)= OS_appendfile(fname)) != 0 ) + { + ptr = OS_portable_mapfile(fname,fsizep,0); + while ( len < *fsizep ) + { + if ( (n= LP_cacheitem(coin,&ptr[len],*fsizep - len)) < 0 ) + { + printf("cacheitem error at %s offset.%ld when fsize.%ld\n",coin->symbol,len,*fsizep); + fseek(*wfp,len,SEEK_SET); + break; + } + len += n; + } + } + return(ptr); +} + int32_t LP_SPV_load(struct iguana_info *coin,bits256 txid,int32_t height) { + struct LP_transaction *tp; + HASH_FIND(hh,coin->SPVcache,&txid,sizeof(txid),cp) return(-1); } +struct LP_transaction +{ + UT_hash_handle hh; + bits256 txid; + int32_t height,numvouts,numvins,len,SPV; + uint8_t *serialized; + struct LP_outpoint outpoints[]; +}; + void LP_SPV_store(struct iguana_info *coin,char *coinaddr,bits256 txid,int32_t height) { - struct LP_transaction *tx = 0; - if ( strcmp(coin->smartaddr,coinaddr) == 0 && (tx= LP_transactionfind(coin,txid)) != 0 && tx->serialized != 0 ) + struct LP_transaction TX; struct LP_transaction *tx = 0; + if ( coin->cachefp != 0 && (tx= LP_transactionfind(coin,txid)) != 0 && tx->serialized != 0 && tx->len > 0 ) //strcmp(coin->smartaddr,coinaddr) == 0 && { - //char str[65]; printf("store %s %s.[%d]\n",coin->symbol,bits256_str(str,txid),tx->len); - } //else printf("skip SPV store for (%s) tx.%p\n",coinaddr,tx); + char str[65]; printf("store %s %s.[%d]\n",coin->symbol,bits256_str(str,txid),tx->len); + TX = *tx; + memset(&TX.hh,0,sizeof(TX.hh)); + TX.serialized = 0; + fwrite(&TX,1,sizeof(TX),coin->cachefp); + if ( tx->numvouts > 0 ) + fwrite(TX.outpoints,tx->numvouts,sizeof(*TX.outpoints),coin->cachefp); + fwrite(tx->serialized,1,tx->len,coin->cachefp); + fflush(coin->cachefp); + } } bits256 iguana_merkle(bits256 *tree,int32_t txn_count) @@ -144,9 +198,9 @@ 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) { - cJSON *merkobj,*merkles; bits256 roothash,merkleroot; int32_t retval,m,SPV = 0; - if ( strcmp(coin->smartaddr,coinaddr) == 0 && (retval= LP_SPV_load(coin,txid,height)) > 0 ) - return(retval); + struct LP_transaction *tx; cJSON *merkobj,*merkles; bits256 roothash,merkleroot; int32_t retval,m,SPV = 0; + if ( (tx= LP_transactionfind(coin,txid)) != 0 && tx->height == height && tx->SPV > 0 ) + return(tx->SPV); if ( (merkobj= electrum_getmerkle(coin->symbol,ep,&merkobj,txid,height)) != 0 ) { char str[65],str2[65],str3[65]; diff --git a/iguana/exchanges/LP_include.h b/iguana/exchanges/LP_include.h index f19aafc3c..6101c6681 100644 --- a/iguana/exchanges/LP_include.h +++ b/iguana/exchanges/LP_include.h @@ -244,7 +244,8 @@ struct LP_outpoint { bits256 spendtxid; uint64_t value,interest; int32_t spendvi struct LP_transaction { UT_hash_handle hh; - bits256 txid; int32_t height,numvouts,numvins,len; //uint32_t timestamp; + bits256 txid; + int32_t height,numvouts,numvins,len,SPV; uint8_t *serialized; struct LP_outpoint outpoints[]; }; @@ -260,7 +261,7 @@ struct iguana_info char symbol[16],smartaddr[64],userpass[1024],serverport[128]; // portfolio double price_kmd,force,perc,goal,goalperc,relvolume,rate; - void *electrum; void *ctx; + void *electrum; void *ctx; FILE *cachefp; uint64_t maxamount,kmd_equiv,balanceA,balanceB,valuesumA,valuesumB; uint8_t pubkey33[33],zcash; bits256 lastprivkey; uint32_t lastprivkeytime; int32_t privkeydepth; diff --git a/iguana/exchanges/LP_tradebots.c b/iguana/exchanges/LP_tradebots.c index efbf047e4..9f7a94b4e 100644 --- a/iguana/exchanges/LP_tradebots.c +++ b/iguana/exchanges/LP_tradebots.c @@ -99,7 +99,7 @@ void LP_tradebot_calcstats(struct LP_tradebot *bot) } //LP_tradebot_updatestats(bot,bot->trades[i]); } - printf("completed.%d (%.8f / %.8f) pending.%d (%.8f / %.8f)\n",bot->completed,bot->basesum,bot->relsum,bot->numpending,bot->pendbasesum,bot->pendrelsum); + //printf("completed.%d (%.8f / %.8f) pending.%d (%.8f / %.8f)\n",bot->completed,bot->basesum,bot->relsum,bot->numpending,bot->pendbasesum,bot->pendrelsum); } double LP_pricevol_invert(double *basevolumep,double maxprice,double relvolume) diff --git a/iguana/exchanges/LP_transaction.c b/iguana/exchanges/LP_transaction.c index ea09a5bb3..81a7e7b3b 100644 --- a/iguana/exchanges/LP_transaction.c +++ b/iguana/exchanges/LP_transaction.c @@ -475,7 +475,7 @@ int64_t iguana_lockval(int32_t finalized,int64_t locktime) int32_t iguana_signrawtransaction(void *ctx,char *symbol,uint8_t wiftaddr,uint8_t taddr,uint8_t pubtype,uint8_t p2shtype,uint8_t isPoS,int32_t height,struct iguana_msgtx *msgtx,char **signedtxp,bits256 *signedtxidp,struct vin_info *V,int32_t numinputs,char *rawtx,cJSON *vins,cJSON *privkeysjson,int32_t zcash) { - uint8_t *serialized,*serialized2,*serialized3,*serialized4,*extraspace,pubkeys[64][33]; int32_t finalized,i,len,n,z,plen,maxsize,complete = 0,extralen = 100000; char *privkeystr,*signedtx = 0; bits256 privkeys[64],privkey,txid; cJSON *item; cJSON *txobj = 0; + uint8_t *serialized,*serialized2,*serialized3,*serialized4,*extraspace,pubkeys[64][33]; int32_t finalized,i,len,n,z,plen,maxsize,complete = 0,extralen = 100000; char *privkeystr,*signedtx = 0; bits256 privkeys[1024],privkey,txid; cJSON *item; cJSON *txobj = 0; maxsize = 1000000; memset(privkey.bytes,0,sizeof(privkey)); if ( rawtx != 0 && rawtx[0] != 0 && (len= (int32_t)strlen(rawtx)>>1) < maxsize ) From d262d03ee6687d061838bbb5381cd8eec9f34d0e Mon Sep 17 00:00:00 2001 From: jl777 Date: Fri, 10 Nov 2017 19:50:55 +0200 Subject: [PATCH 0514/1664] Test --- iguana/exchanges/LP_cache.c | 21 ++++++--------------- 1 file changed, 6 insertions(+), 15 deletions(-) diff --git a/iguana/exchanges/LP_cache.c b/iguana/exchanges/LP_cache.c index 3c3f32b1b..dcdbf777b 100644 --- a/iguana/exchanges/LP_cache.c +++ b/iguana/exchanges/LP_cache.c @@ -60,18 +60,18 @@ cJSON *LP_cache_transaction(struct iguana_info *coin,bits256 txid,uint8_t *seria return(txobj); } -struct LP_transaction +/*struct LP_transaction { UT_hash_handle hh; bits256 txid; int32_t height,numvouts,numvins,len,SPV; uint8_t *serialized; struct LP_outpoint outpoints[]; -}; +};*/ -int32_t LP_cacheitem(uint8_t *ptr,long remains) +int32_t LP_cacheitem(struct iguana_info *coin,uint8_t *ptr,long remains) { - + return(-1); } void *LP_cacheptr(FILE **wfp,long *fsizep,struct iguana_info *coin) @@ -97,19 +97,10 @@ void *LP_cacheptr(FILE **wfp,long *fsizep,struct iguana_info *coin) int32_t LP_SPV_load(struct iguana_info *coin,bits256 txid,int32_t height) { - struct LP_transaction *tp; - HASH_FIND(hh,coin->SPVcache,&txid,sizeof(txid),cp) + // struct LP_transaction *tp; return(-1); } -struct LP_transaction -{ - UT_hash_handle hh; - bits256 txid; - int32_t height,numvouts,numvins,len,SPV; - uint8_t *serialized; - struct LP_outpoint outpoints[]; -}; void LP_SPV_store(struct iguana_info *coin,char *coinaddr,bits256 txid,int32_t height) { @@ -198,7 +189,7 @@ 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; cJSON *merkobj,*merkles; bits256 roothash,merkleroot; int32_t retval,m,SPV = 0; + struct LP_transaction *tx; cJSON *merkobj,*merkles; bits256 roothash,merkleroot; int32_t m,SPV = 0; if ( (tx= LP_transactionfind(coin,txid)) != 0 && tx->height == height && tx->SPV > 0 ) return(tx->SPV); if ( (merkobj= electrum_getmerkle(coin->symbol,ep,&merkobj,txid,height)) != 0 ) From 456ede8d700cee6cb02ed3bb2136061f5273bbe5 Mon Sep 17 00:00:00 2001 From: jl777 Date: Fri, 10 Nov 2017 20:01:40 +0200 Subject: [PATCH 0515/1664] Test --- iguana/exchanges/LP_cache.c | 62 +++++++++++++++---------------- iguana/exchanges/LP_transaction.c | 4 +- 2 files changed, 32 insertions(+), 34 deletions(-) diff --git a/iguana/exchanges/LP_cache.c b/iguana/exchanges/LP_cache.c index dcdbf777b..4423aa7e5 100644 --- a/iguana/exchanges/LP_cache.c +++ b/iguana/exchanges/LP_cache.c @@ -60,21 +60,39 @@ cJSON *LP_cache_transaction(struct iguana_info *coin,bits256 txid,uint8_t *seria return(txobj); } -/*struct LP_transaction +void LP_SPV_store(struct iguana_info *coin,char *coinaddr,bits256 txid,int32_t height) { - UT_hash_handle hh; - bits256 txid; - int32_t height,numvouts,numvins,len,SPV; - uint8_t *serialized; - struct LP_outpoint outpoints[]; -};*/ + struct LP_transaction TX; struct LP_transaction *tx = 0; + if ( coin->cachefp != 0 && (tx= LP_transactionfind(coin,txid)) != 0 && tx->serialized != 0 && tx->len > 0 ) //strcmp(coin->smartaddr,coinaddr) == 0 && + { + char str[65]; printf("store %s %s.[%d]\n",coin->symbol,bits256_str(str,txid),tx->len); + TX = *tx; + memset(&TX.hh,0,sizeof(TX.hh)); + TX.serialized = 0; + TX.SPV = height; + fwrite(&TX,1,sizeof(TX),coin->cachefp); + if ( tx->numvouts > 0 ) + fwrite(TX.outpoints,tx->numvouts,sizeof(*TX.outpoints),coin->cachefp); + fwrite(tx->serialized,1,tx->len,coin->cachefp); + fflush(coin->cachefp); + } +} + +/*struct LP_transaction + { + UT_hash_handle hh; + bits256 txid; + int32_t height,numvouts,numvins,len,SPV; + uint8_t *serialized; + struct LP_outpoint outpoints[]; + };*/ int32_t LP_cacheitem(struct iguana_info *coin,uint8_t *ptr,long remains) { return(-1); } -void *LP_cacheptr(FILE **wfp,long *fsizep,struct iguana_info *coin) +void *LP_cacheptrs_init(FILE **wfp,long *fsizep,struct iguana_info *coin) { char fname[1024]; long n,len = 0; uint8_t *ptr = 0; sprintf(fname,"%s/UNSPENTS/%s.SPV",GLOBAL_DBDIR,coin->symbol), OS_portable_path(fname); @@ -95,30 +113,6 @@ void *LP_cacheptr(FILE **wfp,long *fsizep,struct iguana_info *coin) return(ptr); } -int32_t LP_SPV_load(struct iguana_info *coin,bits256 txid,int32_t height) -{ - // struct LP_transaction *tp; - return(-1); -} - - -void LP_SPV_store(struct iguana_info *coin,char *coinaddr,bits256 txid,int32_t height) -{ - struct LP_transaction TX; struct LP_transaction *tx = 0; - if ( coin->cachefp != 0 && (tx= LP_transactionfind(coin,txid)) != 0 && tx->serialized != 0 && tx->len > 0 ) //strcmp(coin->smartaddr,coinaddr) == 0 && - { - char str[65]; printf("store %s %s.[%d]\n",coin->symbol,bits256_str(str,txid),tx->len); - TX = *tx; - memset(&TX.hh,0,sizeof(TX.hh)); - TX.serialized = 0; - fwrite(&TX,1,sizeof(TX),coin->cachefp); - if ( tx->numvouts > 0 ) - fwrite(TX.outpoints,tx->numvouts,sizeof(*TX.outpoints),coin->cachefp); - fwrite(tx->serialized,1,tx->len,coin->cachefp); - fflush(coin->cachefp); - } -} - bits256 iguana_merkle(bits256 *tree,int32_t txn_count) { int32_t i,n=0,prev; uint8_t serialized[sizeof(bits256) * 2]; @@ -189,7 +183,7 @@ 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; cJSON *merkobj,*merkles; bits256 roothash,merkleroot; int32_t m,SPV = 0; + struct LP_transaction *tx=0; cJSON *merkobj,*merkles; bits256 roothash,merkleroot; int32_t m,SPV = 0; if ( (tx= LP_transactionfind(coin,txid)) != 0 && tx->height == height && tx->SPV > 0 ) return(tx->SPV); if ( (merkobj= electrum_getmerkle(coin->symbol,ep,&merkobj,txid,height)) != 0 ) @@ -206,6 +200,8 @@ int32_t LP_merkleproof(struct iguana_info *coin,char *coinaddr,struct electrum_i if ( bits256_cmp(merkleroot,roothash) == 0 ) { SPV = height; + if ( tx != 0 ) + tx->SPV = height; LP_SPV_store(coin,coinaddr,txid,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)); } diff --git a/iguana/exchanges/LP_transaction.c b/iguana/exchanges/LP_transaction.c index 81a7e7b3b..50e8b2c69 100644 --- a/iguana/exchanges/LP_transaction.c +++ b/iguana/exchanges/LP_transaction.c @@ -475,11 +475,12 @@ int64_t iguana_lockval(int32_t finalized,int64_t locktime) int32_t iguana_signrawtransaction(void *ctx,char *symbol,uint8_t wiftaddr,uint8_t taddr,uint8_t pubtype,uint8_t p2shtype,uint8_t isPoS,int32_t height,struct iguana_msgtx *msgtx,char **signedtxp,bits256 *signedtxidp,struct vin_info *V,int32_t numinputs,char *rawtx,cJSON *vins,cJSON *privkeysjson,int32_t zcash) { - uint8_t *serialized,*serialized2,*serialized3,*serialized4,*extraspace,pubkeys[64][33]; int32_t finalized,i,len,n,z,plen,maxsize,complete = 0,extralen = 100000; char *privkeystr,*signedtx = 0; bits256 privkeys[1024],privkey,txid; cJSON *item; cJSON *txobj = 0; + uint8_t *serialized,*serialized2,*serialized3,*serialized4,*extraspace,pubkeys[64][33]; int32_t finalized,i,len,n,z,plen,maxsize,complete = 0,extralen = 100000; char *privkeystr,*signedtx = 0; bits256 *privkeys,privkey,txid; cJSON *item; cJSON *txobj = 0; maxsize = 1000000; memset(privkey.bytes,0,sizeof(privkey)); if ( rawtx != 0 && rawtx[0] != 0 && (len= (int32_t)strlen(rawtx)>>1) < maxsize ) { + privkeys = calloc(numinputs,sizeof(*privkeys)); serialized = malloc(maxsize); serialized2 = malloc(maxsize); serialized3 = malloc(maxsize); @@ -595,6 +596,7 @@ int32_t iguana_signrawtransaction(void *ctx,char *symbol,uint8_t wiftaddr,uint8_ } else printf("rwmsgtx error\n"); } else printf("no inputs in vins.(%s)\n",vins!=0?jprint(vins,0):"null"); free(extraspace); + free(privkeys); free(serialized), free(serialized2), free(serialized3), free(serialized4); } else return(-1); if ( txobj != 0 ) From df16a10457b2ac2d88cd4dfe15e73ae256044a59 Mon Sep 17 00:00:00 2001 From: jl777 Date: Fri, 10 Nov 2017 20:23:50 +0200 Subject: [PATCH 0516/1664] Test --- iguana/exchanges/LP_cache.c | 8 ++++++-- iguana/exchanges/LP_include.h | 11 +++++++++-- iguana/exchanges/LP_transaction.c | 2 +- 3 files changed, 16 insertions(+), 5 deletions(-) diff --git a/iguana/exchanges/LP_cache.c b/iguana/exchanges/LP_cache.c index 4423aa7e5..f741bd24f 100644 --- a/iguana/exchanges/LP_cache.c +++ b/iguana/exchanges/LP_cache.c @@ -87,8 +87,10 @@ void LP_SPV_store(struct iguana_info *coin,char *coinaddr,bits256 txid,int32_t h struct LP_outpoint outpoints[]; };*/ -int32_t LP_cacheitem(struct iguana_info *coin,uint8_t *ptr,long remains) +int32_t LP_cacheitem(struct iguana_info *coin,struct LP_transaction *tx,long remains) { + int32_t offset; + return(-1); } @@ -101,13 +103,15 @@ void *LP_cacheptrs_init(FILE **wfp,long *fsizep,struct iguana_info *coin) ptr = OS_portable_mapfile(fname,fsizep,0); while ( len < *fsizep ) { - if ( (n= LP_cacheitem(coin,&ptr[len],*fsizep - len)) < 0 ) + if ( (n= LP_cacheitem(coin,(struct LP_transaction *)&ptr[len],*fsizep - len)) < 0 ) { printf("cacheitem error at %s offset.%ld when fsize.%ld\n",coin->symbol,len,*fsizep); fseek(*wfp,len,SEEK_SET); break; } len += n; + if ( (len & 1) != 0 ) + printf("odd offset at %ld\n",len); } } return(ptr); diff --git a/iguana/exchanges/LP_include.h b/iguana/exchanges/LP_include.h index 6101c6681..a1b7e98ca 100644 --- a/iguana/exchanges/LP_include.h +++ b/iguana/exchanges/LP_include.h @@ -239,13 +239,20 @@ struct LP_swap_remember 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)]; }; -struct LP_outpoint { bits256 spendtxid; uint64_t value,interest; int32_t spendvini,spendheight; char coinaddr[64]; }; +struct LP_outpoint +{ + bits256 spendtxid; + uint64_t value,interest; + int32_t spendvini,spendheight; + char coinaddr[56]; +}; struct LP_transaction { UT_hash_handle hh; bits256 txid; - int32_t height,numvouts,numvins,len,SPV; + int32_t height,len,SPV; + uint16_t numvouts,numvins; uint8_t *serialized; struct LP_outpoint outpoints[]; }; diff --git a/iguana/exchanges/LP_transaction.c b/iguana/exchanges/LP_transaction.c index 50e8b2c69..33946846e 100644 --- a/iguana/exchanges/LP_transaction.c +++ b/iguana/exchanges/LP_transaction.c @@ -500,7 +500,7 @@ int32_t iguana_signrawtransaction(void *ctx,char *symbol,uint8_t wiftaddr,uint8_ if ( iguana_rwmsgtx(taddr,pubtype,p2shtype,isPoS,height,0,0,serialized,maxsize,msgtx,&txid,"",extraspace,extralen,vins,V->suppress_pubkeys,zcash) > 0 && numinputs == msgtx->tx_in ) { memset(pubkeys,0,sizeof(pubkeys)); - memset(privkeys,0,sizeof(privkeys)); + memset(privkeys,0,sizeof(*privkeys)*numinputs); if ( (n= cJSON_GetArraySize(privkeysjson)) > 0 ) { for (i=0; i Date: Fri, 10 Nov 2017 20:25:38 +0200 Subject: [PATCH 0517/1664] Test --- iguana/exchanges/LP_transaction.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/iguana/exchanges/LP_transaction.c b/iguana/exchanges/LP_transaction.c index 33946846e..e6ec2e565 100644 --- a/iguana/exchanges/LP_transaction.c +++ b/iguana/exchanges/LP_transaction.c @@ -480,7 +480,7 @@ int32_t iguana_signrawtransaction(void *ctx,char *symbol,uint8_t wiftaddr,uint8_ memset(privkey.bytes,0,sizeof(privkey)); if ( rawtx != 0 && rawtx[0] != 0 && (len= (int32_t)strlen(rawtx)>>1) < maxsize ) { - privkeys = calloc(numinputs,sizeof(*privkeys)); + privkeys = calloc(numinputs+1024,sizeof(*privkeys)); serialized = malloc(maxsize); serialized2 = malloc(maxsize); serialized3 = malloc(maxsize); From 6badbe8d33dab00725132f37b2798ff168384969 Mon Sep 17 00:00:00 2001 From: jl777 Date: Fri, 10 Nov 2017 20:32:05 +0200 Subject: [PATCH 0518/1664] Test --- iguana/exchanges/LP_include.h | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/iguana/exchanges/LP_include.h b/iguana/exchanges/LP_include.h index a1b7e98ca..c87c181ba 100644 --- a/iguana/exchanges/LP_include.h +++ b/iguana/exchanges/LP_include.h @@ -244,15 +244,14 @@ struct LP_outpoint bits256 spendtxid; uint64_t value,interest; int32_t spendvini,spendheight; - char coinaddr[56]; + char coinaddr[64]; }; struct LP_transaction { UT_hash_handle hh; bits256 txid; - int32_t height,len,SPV; - uint16_t numvouts,numvins; + int32_t height,numvouts,numvins,len,SPV; uint8_t *serialized; struct LP_outpoint outpoints[]; }; From b1450a1670d4f6e294cd62bde5d2dc3e6d06974f Mon Sep 17 00:00:00 2001 From: jl777 Date: Fri, 10 Nov 2017 20:41:15 +0200 Subject: [PATCH 0519/1664] Test --- iguana/exchanges/LP_cache.c | 6 +++++- iguana/exchanges/LP_transaction.c | 8 +++++++- 2 files changed, 12 insertions(+), 2 deletions(-) diff --git a/iguana/exchanges/LP_cache.c b/iguana/exchanges/LP_cache.c index f741bd24f..f79f23175 100644 --- a/iguana/exchanges/LP_cache.c +++ b/iguana/exchanges/LP_cache.c @@ -90,7 +90,11 @@ void LP_SPV_store(struct iguana_info *coin,char *coinaddr,bits256 txid,int32_t h int32_t LP_cacheitem(struct iguana_info *coin,struct LP_transaction *tx,long remains) { int32_t offset; - + offset = sizeof(*tx) + tx->numvouts*sizeof(*tx->outpoints); + if ( offset+tx->len <= remains ) + { + return(0); + } return(-1); } diff --git a/iguana/exchanges/LP_transaction.c b/iguana/exchanges/LP_transaction.c index e6ec2e565..6fe266200 100644 --- a/iguana/exchanges/LP_transaction.c +++ b/iguana/exchanges/LP_transaction.c @@ -247,7 +247,10 @@ int32_t iguana_msgtx_Vset(uint8_t *serialized,int32_t maxlen,struct iguana_msgtx int32_t iguana_interpreter(struct iguana_info *coin,cJSON *logarray,int64_t nLockTime,struct vin_info *V,int32_t numvins) { - uint8_t script[IGUANA_MAXSCRIPTSIZE],*activescript,savescript[IGUANA_MAXSCRIPTSIZE]; char str[IGUANA_MAXSCRIPTSIZE*2+1]; int32_t vini,scriptlen,activescriptlen,savelen,errs = 0; cJSON *spendscript,*item=0; + uint8_t *script,*activescript,*savescript; char *str; int32_t vini,scriptlen,activescriptlen,savelen,errs = 0; cJSON *spendscript,*item=0; + script = calloc(1,IGUANA_MAXSCRIPTSIZE); + savescript = calloc(1,IGUANA_MAXSCRIPTSIZE); + str = calloc(1,IGUANA_MAXSCRIPTSIZE*2+1); for (vini=0; vini Date: Fri, 10 Nov 2017 20:54:19 +0200 Subject: [PATCH 0520/1664] Test --- iguana/exchanges/LP_cache.c | 15 ++++++++++++--- iguana/exchanges/LP_include.h | 1 + iguana/exchanges/LP_transaction.c | 10 ++++------ 3 files changed, 17 insertions(+), 9 deletions(-) diff --git a/iguana/exchanges/LP_cache.c b/iguana/exchanges/LP_cache.c index f79f23175..faa0ba9a6 100644 --- a/iguana/exchanges/LP_cache.c +++ b/iguana/exchanges/LP_cache.c @@ -62,7 +62,7 @@ cJSON *LP_cache_transaction(struct iguana_info *coin,bits256 txid,uint8_t *seria void LP_SPV_store(struct iguana_info *coin,char *coinaddr,bits256 txid,int32_t height) { - struct LP_transaction TX; struct LP_transaction *tx = 0; + struct LP_transaction TX; int32_t n; struct LP_transaction *tx = 0; if ( coin->cachefp != 0 && (tx= LP_transactionfind(coin,txid)) != 0 && tx->serialized != 0 && tx->len > 0 ) //strcmp(coin->smartaddr,coinaddr) == 0 && { char str[65]; printf("store %s %s.[%d]\n",coin->symbol,bits256_str(str,txid),tx->len); @@ -74,6 +74,9 @@ void LP_SPV_store(struct iguana_info *coin,char *coinaddr,bits256 txid,int32_t h if ( tx->numvouts > 0 ) fwrite(TX.outpoints,tx->numvouts,sizeof(*TX.outpoints),coin->cachefp); fwrite(tx->serialized,1,tx->len,coin->cachefp); + n = tx->len; + while ( (n & 7) != 0 ) + fputc(0,coin->cachefp), n++; fflush(coin->cachefp); } } @@ -89,11 +92,17 @@ void LP_SPV_store(struct iguana_info *coin,char *coinaddr,bits256 txid,int32_t h int32_t LP_cacheitem(struct iguana_info *coin,struct LP_transaction *tx,long remains) { - int32_t offset; + int32_t offset; bits256 hash; char str[65],str2[65]; offset = sizeof(*tx) + tx->numvouts*sizeof(*tx->outpoints); if ( offset+tx->len <= remains ) { - return(0); + hash = bits256_doublesha256(0,&((uint8_t *)tx)[offset],tx->len); + if ( bits256_cmp(hash,tx->txid) == 0 ) + { + printf("%s validated in cache\n",bits256_str(str,hash)); + return(0); + } + printf("%s vs %s did not validated in cache\n",bits256_str(str,hash),bits256_str(str2,tx->txid)); } return(-1); } diff --git a/iguana/exchanges/LP_include.h b/iguana/exchanges/LP_include.h index c87c181ba..ec308800d 100644 --- a/iguana/exchanges/LP_include.h +++ b/iguana/exchanges/LP_include.h @@ -37,6 +37,7 @@ void emscripten_usleep(int32_t x); // returns immediate, no sense for sleeping #define LP_BARTERDEX_VERSION 1 #define LP_MAGICBITS 8 +#define LP_MAXVINS 64 #define LP_HTTP_TIMEOUT 3 // 1 is too small due to edge cases of time(NULL) #define LP_AUTOTRADE_TIMEOUT 30 #define ELECTRUM_TIMEOUT 7 diff --git a/iguana/exchanges/LP_transaction.c b/iguana/exchanges/LP_transaction.c index 6fe266200..91bdb2f2d 100644 --- a/iguana/exchanges/LP_transaction.c +++ b/iguana/exchanges/LP_transaction.c @@ -481,12 +481,11 @@ int64_t iguana_lockval(int32_t finalized,int64_t locktime) int32_t iguana_signrawtransaction(void *ctx,char *symbol,uint8_t wiftaddr,uint8_t taddr,uint8_t pubtype,uint8_t p2shtype,uint8_t isPoS,int32_t height,struct iguana_msgtx *msgtx,char **signedtxp,bits256 *signedtxidp,struct vin_info *V,int32_t numinputs,char *rawtx,cJSON *vins,cJSON *privkeysjson,int32_t zcash) { - uint8_t *serialized,*serialized2,*serialized3,*serialized4,*extraspace,pubkeys[64][33]; int32_t finalized,i,len,n,z,plen,maxsize,complete = 0,extralen = 100000; char *privkeystr,*signedtx = 0; bits256 *privkeys,privkey,txid; cJSON *item; cJSON *txobj = 0; + uint8_t *serialized,*serialized2,*serialized3,*serialized4,*extraspace,pubkeys[64][33]; int32_t finalized,i,len,n,z,plen,maxsize,complete = 0,extralen = 100000; char *privkeystr,*signedtx = 0; bits256 privkeys[LP_MAXVINS],privkey,txid; cJSON *item; cJSON *txobj = 0; maxsize = 1000000; memset(privkey.bytes,0,sizeof(privkey)); if ( rawtx != 0 && rawtx[0] != 0 && (len= (int32_t)strlen(rawtx)>>1) < maxsize ) { - privkeys = calloc(numinputs+1024,sizeof(*privkeys)); serialized = malloc(maxsize); serialized2 = malloc(maxsize); serialized3 = malloc(maxsize); @@ -506,7 +505,7 @@ int32_t iguana_signrawtransaction(void *ctx,char *symbol,uint8_t wiftaddr,uint8_ if ( iguana_rwmsgtx(taddr,pubtype,p2shtype,isPoS,height,0,0,serialized,maxsize,msgtx,&txid,"",extraspace,extralen,vins,V->suppress_pubkeys,zcash) > 0 && numinputs == msgtx->tx_in ) { memset(pubkeys,0,sizeof(pubkeys)); - memset(privkeys,0,sizeof(*privkeys)*numinputs); + memset(privkeys,0,sizeof(privkeys)); if ( (n= cJSON_GetArraySize(privkeysjson)) > 0 ) { for (i=0; ismartaddr,sizeof(changeaddr)); safecopy(vinaddr,coin->smartaddr,sizeof(vinaddr)); privkey = LP_privkey(vinaddr,coin->taddr); - maxV = 1024; + maxV = LP_MAXVINS; V = malloc(maxV * sizeof(*V)); for (iter=0; iter<2; iter++) { From 98e9e24087435dc669567ce1f7fca3d6d70ab729 Mon Sep 17 00:00:00 2001 From: jl777 Date: Fri, 10 Nov 2017 21:08:55 +0200 Subject: [PATCH 0521/1664] Test --- iguana/exchanges/LP_cache.c | 35 ++++++++++++++++------------------- iguana/exchanges/LP_coins.c | 1 + iguana/exchanges/LP_include.h | 3 ++- 3 files changed, 19 insertions(+), 20 deletions(-) diff --git a/iguana/exchanges/LP_cache.c b/iguana/exchanges/LP_cache.c index faa0ba9a6..ab02bfbcb 100644 --- a/iguana/exchanges/LP_cache.c +++ b/iguana/exchanges/LP_cache.c @@ -81,44 +81,41 @@ void LP_SPV_store(struct iguana_info *coin,char *coinaddr,bits256 txid,int32_t h } } -/*struct LP_transaction - { - UT_hash_handle hh; - bits256 txid; - int32_t height,numvouts,numvins,len,SPV; - uint8_t *serialized; - struct LP_outpoint outpoints[]; - };*/ - int32_t LP_cacheitem(struct iguana_info *coin,struct LP_transaction *tx,long remains) { - int32_t offset; bits256 hash; char str[65],str2[65]; + int32_t offset,n; bits256 hash; cJSON *txobj; char str[65],str2[65]; offset = sizeof(*tx) + tx->numvouts*sizeof(*tx->outpoints); if ( offset+tx->len <= remains ) { - hash = bits256_doublesha256(0,&((uint8_t *)tx)[offset],tx->len); + tx->serialized = &((uint8_t *)tx)[offset]; + hash = bits256_doublesha256(0,tx->serialized,tx->len); if ( bits256_cmp(hash,tx->txid) == 0 ) { printf("%s validated in cache\n",bits256_str(str,hash)); - return(0); + n = tx->len; + while ( (n & 7) != 0 ) + n++; + if ( (txobj= LP_cache_transaction(coin,tx->txid,tx->serialized,tx->len)) != 0 ) + free_json(txobj); + return(offset + n); } printf("%s vs %s did not validated in cache\n",bits256_str(str,hash),bits256_str(str2,tx->txid)); } return(-1); } -void *LP_cacheptrs_init(FILE **wfp,long *fsizep,struct iguana_info *coin) +long LP_cacheptrs_init(FILE **wfp,struct iguana_info *coin) { - char fname[1024]; long n,len = 0; uint8_t *ptr = 0; + char fname[1024]; long n,fsize=0,len = 0; uint8_t *ptr = 0; sprintf(fname,"%s/UNSPENTS/%s.SPV",GLOBAL_DBDIR,coin->symbol), OS_portable_path(fname); if ( ((*wfp)= OS_appendfile(fname)) != 0 ) { - ptr = OS_portable_mapfile(fname,fsizep,0); - while ( len < *fsizep ) + ptr = OS_portable_mapfile(fname,&fsize,0); + while ( len < fsize ) { - if ( (n= LP_cacheitem(coin,(struct LP_transaction *)&ptr[len],*fsizep - len)) < 0 ) + if ( (n= LP_cacheitem(coin,(struct LP_transaction *)&ptr[len],fsize - len)) < 0 ) { - printf("cacheitem error at %s offset.%ld when fsize.%ld\n",coin->symbol,len,*fsizep); + printf("cacheitem error at %s offset.%ld when fsize.%ld\n",coin->symbol,len,fsize); fseek(*wfp,len,SEEK_SET); break; } @@ -127,7 +124,7 @@ void *LP_cacheptrs_init(FILE **wfp,long *fsizep,struct iguana_info *coin) printf("odd offset at %ld\n",len); } } - return(ptr); + return(fsize); } bits256 iguana_merkle(bits256 *tree,int32_t txn_count) diff --git a/iguana/exchanges/LP_coins.c b/iguana/exchanges/LP_coins.c index 38c62ac64..afd5a8129 100644 --- a/iguana/exchanges/LP_coins.c +++ b/iguana/exchanges/LP_coins.c @@ -353,6 +353,7 @@ uint16_t LP_coininit(struct iguana_info *coin,char *symbol,char *name,char *asse coin->zcash = LP_IS_BITCOINCASH; //printf("set coin.%s <- LP_IS_BITCOINCASH %d\n",symbol,coin->zcash); } + coin->cachesize = LP_cacheptrs_init(&coin->cachefp,coin); return(port); } diff --git a/iguana/exchanges/LP_include.h b/iguana/exchanges/LP_include.h index ec308800d..c5608a125 100644 --- a/iguana/exchanges/LP_include.h +++ b/iguana/exchanges/LP_include.h @@ -268,7 +268,7 @@ struct iguana_info char symbol[16],smartaddr[64],userpass[1024],serverport[128]; // portfolio double price_kmd,force,perc,goal,goalperc,relvolume,rate; - void *electrum; void *ctx; FILE *cachefp; + void *electrum; void *ctx; FILE *cachefp; long cachesize; uint64_t maxamount,kmd_equiv,balanceA,balanceB,valuesumA,valuesumB; uint8_t pubkey33[33],zcash; bits256 lastprivkey; uint32_t lastprivkeytime; int32_t privkeydepth; @@ -432,6 +432,7 @@ char *basilisk_swapentry(uint32_t requestid,uint32_t quoteid); uint64_t LP_KMDvalue(struct iguana_info *coin,uint64_t balance); int32_t LP_address_utxoadd(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); +long LP_cacheptrs_init(FILE **wfp,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); From d47fbfc716b54b7a3e62a58b467f373c418af27a Mon Sep 17 00:00:00 2001 From: jl777 Date: Fri, 10 Nov 2017 21:10:41 +0200 Subject: [PATCH 0522/1664] Test --- iguana/exchanges/LP_cache.c | 25 +++++++++++++++---------- 1 file changed, 15 insertions(+), 10 deletions(-) diff --git a/iguana/exchanges/LP_cache.c b/iguana/exchanges/LP_cache.c index ab02bfbcb..a6134e813 100644 --- a/iguana/exchanges/LP_cache.c +++ b/iguana/exchanges/LP_cache.c @@ -106,22 +106,27 @@ int32_t LP_cacheitem(struct iguana_info *coin,struct LP_transaction *tx,long rem long LP_cacheptrs_init(FILE **wfp,struct iguana_info *coin) { - char fname[1024]; long n,fsize=0,len = 0; uint8_t *ptr = 0; + char fname[1024]; FILE *fp; long n,fsize=0,len = 0; uint8_t *ptr = 0; sprintf(fname,"%s/UNSPENTS/%s.SPV",GLOBAL_DBDIR,coin->symbol), OS_portable_path(fname); + fp = fopen(fname,"rb"); if ( ((*wfp)= OS_appendfile(fname)) != 0 ) { - ptr = OS_portable_mapfile(fname,&fsize,0); - while ( len < fsize ) + if ( fp != 0 ) { - if ( (n= LP_cacheitem(coin,(struct LP_transaction *)&ptr[len],fsize - len)) < 0 ) + fclose(fp); + ptr = OS_portable_mapfile(fname,&fsize,0); + while ( len < fsize ) { - printf("cacheitem error at %s offset.%ld when fsize.%ld\n",coin->symbol,len,fsize); - fseek(*wfp,len,SEEK_SET); - break; + if ( (n= LP_cacheitem(coin,(struct LP_transaction *)&ptr[len],fsize - len)) < 0 ) + { + printf("cacheitem error at %s offset.%ld when fsize.%ld\n",coin->symbol,len,fsize); + fseek(*wfp,len,SEEK_SET); + break; + } + len += n; + if ( (len & 1) != 0 ) + printf("odd offset at %ld\n",len); } - len += n; - if ( (len & 1) != 0 ) - printf("odd offset at %ld\n",len); } } return(fsize); From 2cd41e6a4372581a2564149b9f6a459651e19b92 Mon Sep 17 00:00:00 2001 From: jl777 Date: Fri, 10 Nov 2017 21:13:55 +0200 Subject: [PATCH 0523/1664] Test --- iguana/exchanges/LP_cache.c | 26 ++++++++++++++++---------- 1 file changed, 16 insertions(+), 10 deletions(-) diff --git a/iguana/exchanges/LP_cache.c b/iguana/exchanges/LP_cache.c index a6134e813..4967a8692 100644 --- a/iguana/exchanges/LP_cache.c +++ b/iguana/exchanges/LP_cache.c @@ -106,26 +106,32 @@ int32_t LP_cacheitem(struct iguana_info *coin,struct LP_transaction *tx,long rem long LP_cacheptrs_init(FILE **wfp,struct iguana_info *coin) { - char fname[1024]; FILE *fp; long n,fsize=0,len = 0; uint8_t *ptr = 0; + char fname[1024]; FILE *fp; int32_t flag = 0; long n,fsize=0,len = 0; uint8_t *ptr = 0; sprintf(fname,"%s/UNSPENTS/%s.SPV",GLOBAL_DBDIR,coin->symbol), OS_portable_path(fname); fp = fopen(fname,"rb"); if ( ((*wfp)= OS_appendfile(fname)) != 0 ) { if ( fp != 0 ) { + fseek(fp,0,SEEK_END); + if ( ftell(fp) > sizeof(struct LP_transaction) ) + flag = 1; fclose(fp); - ptr = OS_portable_mapfile(fname,&fsize,0); - while ( len < fsize ) + if ( flag != 0 ) { - if ( (n= LP_cacheitem(coin,(struct LP_transaction *)&ptr[len],fsize - len)) < 0 ) + ptr = OS_portable_mapfile(fname,&fsize,0); + while ( len < fsize ) { - printf("cacheitem error at %s offset.%ld when fsize.%ld\n",coin->symbol,len,fsize); - fseek(*wfp,len,SEEK_SET); - break; + if ( (n= LP_cacheitem(coin,(struct LP_transaction *)&ptr[len],fsize - len)) < 0 ) + { + printf("cacheitem error at %s offset.%ld when fsize.%ld\n",coin->symbol,len,fsize); + fseek(*wfp,len,SEEK_SET); + break; + } + len += n; + if ( (len & 1) != 0 ) + printf("odd offset at %ld\n",len); } - len += n; - if ( (len & 1) != 0 ) - printf("odd offset at %ld\n",len); } } } From 96c50ce02f5c0fda48ba7506ba0c771f71bc810e Mon Sep 17 00:00:00 2001 From: jl777 Date: Fri, 10 Nov 2017 21:15:27 +0200 Subject: [PATCH 0524/1664] Test --- iguana/exchanges/LP_socket.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/iguana/exchanges/LP_socket.c b/iguana/exchanges/LP_socket.c index c64c1330f..77f790c53 100644 --- a/iguana/exchanges/LP_socket.c +++ b/iguana/exchanges/LP_socket.c @@ -423,7 +423,7 @@ cJSON *electrum_submit(char *symbol,struct electrum_info *ep,cJSON **retjsonp,ch { *retjsonp = 0; sprintf(stratumreq,"{ \"jsonrpc\":\"2.0\", \"id\": %u, \"method\":\"%s\", \"params\": %s }\n",ep->stratumid,method,params); -//printf("%s %s",symbol,stratumreq); +printf("%s %s",symbol,stratumreq); memset(ep->buf,0,ep->bufsize); sitem = electrum_sitem(ep,stratumreq,timeout,retjsonp); /*sitem = (struct stritem *)queueitem(stratumreq); @@ -864,7 +864,7 @@ int32_t LP_recvfunc(struct electrum_info *ep,char *str,int32_t len) ep->lasttime = (uint32_t)time(NULL); if ( (strjson= cJSON_Parse(str)) != 0 ) { - //printf("%s RECV.(%ld) id.%d\n",ep->symbol,strlen(str),jint(strjson,"id")); + printf("%s RECV.(%ld) id.%d\n",ep->symbol,strlen(str),jint(strjson,"id")); resultjson = jobj(strjson,"result"); //printf("strjson.(%s)\n",jprint(strjson,0)); if ( (method= jstr(strjson,"method")) != 0 ) From 0dda4d18a0281d1dd8ef155cf9a64e89dcee5b81 Mon Sep 17 00:00:00 2001 From: jl777 Date: Fri, 10 Nov 2017 21:22:16 +0200 Subject: [PATCH 0525/1664] Test --- iguana/exchanges/LP_cache.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/iguana/exchanges/LP_cache.c b/iguana/exchanges/LP_cache.c index 4967a8692..ae9626eb6 100644 --- a/iguana/exchanges/LP_cache.c +++ b/iguana/exchanges/LP_cache.c @@ -87,6 +87,7 @@ int32_t LP_cacheitem(struct iguana_info *coin,struct LP_transaction *tx,long rem offset = sizeof(*tx) + tx->numvouts*sizeof(*tx->outpoints); if ( offset+tx->len <= remains ) { + printf("offset.%d txlen.%d remains.%ld\n",offset,tx->len,remains); tx->serialized = &((uint8_t *)tx)[offset]; hash = bits256_doublesha256(0,tx->serialized,tx->len); if ( bits256_cmp(hash,tx->txid) == 0 ) @@ -129,7 +130,7 @@ long LP_cacheptrs_init(FILE **wfp,struct iguana_info *coin) break; } len += n; - if ( (len & 1) != 0 ) + if ( (len & 7) != 0 ) printf("odd offset at %ld\n",len); } } From 6b11505dad4b1bd577936f29d7233818fe29bfb7 Mon Sep 17 00:00:00 2001 From: jl777 Date: Fri, 10 Nov 2017 21:26:08 +0200 Subject: [PATCH 0526/1664] Test --- iguana/exchanges/LP_cache.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/iguana/exchanges/LP_cache.c b/iguana/exchanges/LP_cache.c index ae9626eb6..ddc519209 100644 --- a/iguana/exchanges/LP_cache.c +++ b/iguana/exchanges/LP_cache.c @@ -83,12 +83,12 @@ void LP_SPV_store(struct iguana_info *coin,char *coinaddr,bits256 txid,int32_t h int32_t LP_cacheitem(struct iguana_info *coin,struct LP_transaction *tx,long remains) { - int32_t offset,n; bits256 hash; cJSON *txobj; char str[65],str2[65]; + int32_t offset,n; uint8_t *serialized; bits256 hash; cJSON *txobj; char str[65],str2[65]; offset = sizeof(*tx) + tx->numvouts*sizeof(*tx->outpoints); if ( offset+tx->len <= remains ) { printf("offset.%d txlen.%d remains.%ld\n",offset,tx->len,remains); - tx->serialized = &((uint8_t *)tx)[offset]; + serialized = &((uint8_t *)tx)[offset]; hash = bits256_doublesha256(0,tx->serialized,tx->len); if ( bits256_cmp(hash,tx->txid) == 0 ) { From 8a537d788caa7290fb9ebc157373f3e5acba49c5 Mon Sep 17 00:00:00 2001 From: jl777 Date: Fri, 10 Nov 2017 21:27:30 +0200 Subject: [PATCH 0527/1664] Test --- iguana/exchanges/LP_cache.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/iguana/exchanges/LP_cache.c b/iguana/exchanges/LP_cache.c index ddc519209..6179b3fe1 100644 --- a/iguana/exchanges/LP_cache.c +++ b/iguana/exchanges/LP_cache.c @@ -89,14 +89,14 @@ int32_t LP_cacheitem(struct iguana_info *coin,struct LP_transaction *tx,long rem { printf("offset.%d txlen.%d remains.%ld\n",offset,tx->len,remains); serialized = &((uint8_t *)tx)[offset]; - hash = bits256_doublesha256(0,tx->serialized,tx->len); + hash = bits256_doublesha256(0,serialized,tx->len); if ( bits256_cmp(hash,tx->txid) == 0 ) { printf("%s validated in cache\n",bits256_str(str,hash)); n = tx->len; while ( (n & 7) != 0 ) n++; - if ( (txobj= LP_cache_transaction(coin,tx->txid,tx->serialized,tx->len)) != 0 ) + if ( (txobj= LP_cache_transaction(coin,tx->txid,serialized,tx->len)) != 0 ) free_json(txobj); return(offset + n); } From d72f025e730b814bbf686a05168725b5834d5569 Mon Sep 17 00:00:00 2001 From: jl777 Date: Fri, 10 Nov 2017 21:42:20 +0200 Subject: [PATCH 0528/1664] test --- iguana/exchanges/LP_cache.c | 52 +++++++++++++++++++++++++---------- iguana/exchanges/LP_include.h | 1 + iguana/exchanges/LP_socket.c | 25 +++++++++++++++++ 3 files changed, 63 insertions(+), 15 deletions(-) diff --git a/iguana/exchanges/LP_cache.c b/iguana/exchanges/LP_cache.c index 6179b3fe1..924f839d5 100644 --- a/iguana/exchanges/LP_cache.c +++ b/iguana/exchanges/LP_cache.c @@ -35,26 +35,48 @@ cJSON *LP_transaction_fromdata(struct iguana_info *coin,bits256 txid,uint8_t *se return(txobj); } -cJSON *LP_cache_transaction(struct iguana_info *coin,bits256 txid,uint8_t *serialized,int32_t len) +cJSON *LP_create_transaction(struct iguana_info *coin,bits256 txid,uint8_t *serialized,int32_t len,int32_t height) { - cJSON *txobj; struct LP_transaction *tx; + cJSON *txobj; bits256 spenttxid; int32_t i,spentvout,numvins,numvouts; cJSON *vout,*vin,*vins,*vouts; struct LP_transaction *tx; char str[65]; if ( (txobj= LP_transaction_fromdata(coin,txid,serialized,len)) != 0 ) { - if ( (tx= LP_transactionfind(coin,txid)) == 0 || tx->serialized == 0 ) + vins = jarray(&numvins,txobj,"vin"); + vouts = jarray(&numvouts,txobj,"vout"); + tx = LP_transactionadd(coin,txid,height,numvouts,numvins); + printf("tx.%p vins.(%s) vouts.(%s)\n",tx,jprint(vins,0),jprint(vouts,0)); + for (i=0; ioutpoints[i].value = LP_value_extract(vout,0); + tx->outpoints[i].interest = SATOSHIDEN * jdouble(vout,"interest"); + LP_destaddr(tx->outpoints[i].coinaddr,vout); + printf("from transaction init %s %s %s/v%d <- %.8f\n",coin->symbol,tx->outpoints[i].coinaddr,bits256_str(str,txid),i,dstr(tx->outpoints[i].value)); + LP_address_utxoadd("LP_transactioninit iter0",coin,tx->outpoints[i].coinaddr,txid,i,tx->outpoints[i].value,height,-1); } - if ( tx != 0 ) + for (i=0; iserialized = serialized; - tx->len = len; - } - else - { - char str[65]; printf("unexpected couldnt find tx %s %s\n",coin->symbol,bits256_str(str,txid)); - free(serialized); + vin = jitem(vins,i); + spenttxid = jbits256(vin,"txid"); + spentvout = jint(vin,"vout"); + if ( i == 0 && bits256_nonz(spenttxid) == 0 ) + continue; + if ( (tx= LP_transactionfind(coin,spenttxid)) != 0 ) + { + if ( spentvout < tx->numvouts ) + { + if ( tx->outpoints[spentvout].spendheight <= 0 ) + { + tx->outpoints[spentvout].spendtxid = txid; + tx->outpoints[spentvout].spendvini = i; + tx->outpoints[spentvout].spendheight = height > 0 ? height : 1; + LP_address_utxoadd("LP_transactioninit iter1",coin,tx->outpoints[spentvout].coinaddr,spenttxid,spentvout,tx->outpoints[spentvout].value,-1,height>0?height:1); + if ( 0 && strcmp(coin->symbol,"REVS") == 0 ) + printf("spend %s %s/v%d at ht.%d\n",coin->symbol,bits256_str(str,tx->txid),spentvout,height); + } + } else printf("LP_transactioninit: %s spentvout.%d < numvouts.%d spendheight.%d\n",bits256_str(str,spenttxid),spentvout,tx->numvouts,tx->outpoints[spentvout].spendheight); + } //else printf("LP_transactioninit: couldnt find (%s) ht.%d %s\n",bits256_str(str,spenttxid),height,jprint(vin,0)); + if ( bits256_cmp(spenttxid,txid) == 0 ) + printf("spending same tx's %p vout ht.%d %s.[%d] s%d\n",tx,height,bits256_str(str,txid),tx!=0?tx->numvouts:0,spentvout); } } return(txobj); @@ -96,7 +118,7 @@ int32_t LP_cacheitem(struct iguana_info *coin,struct LP_transaction *tx,long rem n = tx->len; while ( (n & 7) != 0 ) n++; - if ( (txobj= LP_cache_transaction(coin,tx->txid,serialized,tx->len)) != 0 ) + if ( (txobj= LP_create_transaction(coin,tx->txid,serialized,tx->len,tx->height)) != 0 ) free_json(txobj); return(offset + n); } diff --git a/iguana/exchanges/LP_include.h b/iguana/exchanges/LP_include.h index c5608a125..b5f98b3d1 100644 --- a/iguana/exchanges/LP_include.h +++ b/iguana/exchanges/LP_include.h @@ -410,6 +410,7 @@ int32_t LP_reserved_msg(int32_t priority,char *base,char *rel,bits256 pubkey,cha 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); +struct LP_transaction *LP_transactionadd(struct iguana_info *coin,bits256 txid,int32_t height,int32_t numvouts,int32_t numvins); void LP_tradebot_finished(uint32_t tradeid,uint32_t requestid,uint32_t quoteid); 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); diff --git a/iguana/exchanges/LP_socket.c b/iguana/exchanges/LP_socket.c index 77f790c53..c34c04ee7 100644 --- a/iguana/exchanges/LP_socket.c +++ b/iguana/exchanges/LP_socket.c @@ -662,6 +662,31 @@ cJSON *electrum_getheader(char *symbol,struct electrum_info *ep,cJSON **retjsonp return(electrum_intarg(symbol,ep,retjsonp,"blockchain.block.get_header",n,ELECTRUM_TIMEOUT)); } +cJSON *LP_cache_transaction(struct iguana_info *coin,bits256 txid,uint8_t *serialized,int32_t len) +{ + cJSON *txobj; struct LP_transaction *tx; + if ( (txobj= LP_transaction_fromdata(coin,txid,serialized,len)) != 0 ) + { + if ( (tx= LP_transactionfind(coin,txid)) == 0 || tx->serialized == 0 ) + { + txobj = LP_transactioninit(coin,txid,0,txobj); + LP_transactioninit(coin,txid,1,txobj); + tx = LP_transactionfind(coin,txid); + } + if ( tx != 0 ) + { + tx->serialized = serialized; + tx->len = len; + } + else + { + char str[65]; printf("unexpected couldnt find tx %s %s\n",coin->symbol,bits256_str(str,txid)); + free(serialized); + } + } + return(txobj); +} + cJSON *_electrum_transaction(char *symbol,struct electrum_info *ep,cJSON **retjsonp,bits256 txid) { char *hexstr,str[65]; int32_t len; cJSON *hexjson,*txobj=0; struct iguana_info *coin; uint8_t *serialized; struct LP_transaction *tx; From 8a31dd2721acdc1a1c605a8fb3503757bad2875d Mon Sep 17 00:00:00 2001 From: jl777 Date: Fri, 10 Nov 2017 21:44:36 +0200 Subject: [PATCH 0529/1664] Test --- iguana/exchanges/LP_cache.c | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/iguana/exchanges/LP_cache.c b/iguana/exchanges/LP_cache.c index 924f839d5..24500e53f 100644 --- a/iguana/exchanges/LP_cache.c +++ b/iguana/exchanges/LP_cache.c @@ -43,15 +43,18 @@ cJSON *LP_create_transaction(struct iguana_info *coin,bits256 txid,uint8_t *seri vins = jarray(&numvins,txobj,"vin"); vouts = jarray(&numvouts,txobj,"vout"); tx = LP_transactionadd(coin,txid,height,numvouts,numvins); - printf("tx.%p vins.(%s) vouts.(%s)\n",tx,jprint(vins,0),jprint(vouts,0)); + tx->serialized = serialized; + tx->len = len; + tx->height = height; + //printf("tx.%p vins.(%s) vouts.(%s)\n",tx,jprint(vins,0),jprint(vouts,0)); for (i=0; ioutpoints[i].value = LP_value_extract(vout,0); tx->outpoints[i].interest = SATOSHIDEN * jdouble(vout,"interest"); LP_destaddr(tx->outpoints[i].coinaddr,vout); - printf("from transaction init %s %s %s/v%d <- %.8f\n",coin->symbol,tx->outpoints[i].coinaddr,bits256_str(str,txid),i,dstr(tx->outpoints[i].value)); - LP_address_utxoadd("LP_transactioninit iter0",coin,tx->outpoints[i].coinaddr,txid,i,tx->outpoints[i].value,height,-1); + //printf("from transaction init %s %s %s/v%d <- %.8f\n",coin->symbol,tx->outpoints[i].coinaddr,bits256_str(str,txid),i,dstr(tx->outpoints[i].value)); + LP_address_utxoadd("LP_create_transaction",coin,tx->outpoints[i].coinaddr,txid,i,tx->outpoints[i].value,height,-1); } for (i=0; i Date: Fri, 10 Nov 2017 21:55:30 +0200 Subject: [PATCH 0530/1664] Test --- iguana/exchanges/LP_cache.c | 75 ++++++++++++++++++----------------- iguana/exchanges/LP_coins.c | 2 +- iguana/exchanges/LP_include.h | 4 +- 3 files changed, 42 insertions(+), 39 deletions(-) diff --git a/iguana/exchanges/LP_cache.c b/iguana/exchanges/LP_cache.c index 24500e53f..9af599b21 100644 --- a/iguana/exchanges/LP_cache.c +++ b/iguana/exchanges/LP_cache.c @@ -87,22 +87,26 @@ cJSON *LP_create_transaction(struct iguana_info *coin,bits256 txid,uint8_t *seri void LP_SPV_store(struct iguana_info *coin,char *coinaddr,bits256 txid,int32_t height) { - struct LP_transaction TX; int32_t n; struct LP_transaction *tx = 0; - if ( coin->cachefp != 0 && (tx= LP_transactionfind(coin,txid)) != 0 && tx->serialized != 0 && tx->len > 0 ) //strcmp(coin->smartaddr,coinaddr) == 0 && + FILE *fp; char fname[512]; struct LP_transaction TX; int32_t n; struct LP_transaction *tx = 0; + if ( (tx= LP_transactionfind(coin,txid)) != 0 && tx->serialized != 0 && tx->len > 0 ) { - char str[65]; printf("store %s %s.[%d]\n",coin->symbol,bits256_str(str,txid),tx->len); - TX = *tx; - memset(&TX.hh,0,sizeof(TX.hh)); - TX.serialized = 0; - TX.SPV = height; - fwrite(&TX,1,sizeof(TX),coin->cachefp); - if ( tx->numvouts > 0 ) - fwrite(TX.outpoints,tx->numvouts,sizeof(*TX.outpoints),coin->cachefp); - fwrite(tx->serialized,1,tx->len,coin->cachefp); - n = tx->len; - while ( (n & 7) != 0 ) - fputc(0,coin->cachefp), n++; - fflush(coin->cachefp); + sprintf(fname,"%s/UNSPENTS/%s.SPV",GLOBAL_DBDIR,coin->symbol), OS_portable_path(fname); + if ( (fp= OS_appendfile(fname)) != 0 ) + { + char str[65]; printf("store %s %s.[%d]\n",coin->symbol,bits256_str(str,txid),tx->len); + TX = *tx; + memset(&TX.hh,0,sizeof(TX.hh)); + TX.serialized = 0; + TX.SPV = height; + fwrite(&TX,1,sizeof(TX),fp); + if ( tx->numvouts > 0 ) + fwrite(TX.outpoints,tx->numvouts,sizeof(*TX.outpoints),fp); + fwrite(tx->serialized,1,tx->len,fp); + n = tx->len; + while ( (n & 7) != 0 ) + fputc(0,fp), n++; + fclose(fp); + } } } @@ -130,38 +134,37 @@ int32_t LP_cacheitem(struct iguana_info *coin,struct LP_transaction *tx,long rem return(-1); } -long LP_cacheptrs_init(FILE **wfp,struct iguana_info *coin) +void LP_cacheptrs_init(struct iguana_info *coin) { - char fname[1024]; FILE *fp; int32_t flag = 0; long n,fsize=0,len = 0; uint8_t *ptr = 0; + char fname[1024]; FILE *fp; int32_t tflag=0,flag = 0; long n,fsize=0,len = 0; uint8_t *ptr = 0; sprintf(fname,"%s/UNSPENTS/%s.SPV",GLOBAL_DBDIR,coin->symbol), OS_portable_path(fname); fp = fopen(fname,"rb"); - if ( ((*wfp)= OS_appendfile(fname)) != 0 ) + if ( fp != 0 ) { - if ( fp != 0 ) + fseek(fp,0,SEEK_END); + if ( ftell(fp) > sizeof(struct LP_transaction) ) + flag = 1; + fclose(fp); + if ( flag != 0 ) { - fseek(fp,0,SEEK_END); - if ( ftell(fp) > sizeof(struct LP_transaction) ) - flag = 1; - fclose(fp); - if ( flag != 0 ) + ptr = OS_portable_mapfile(fname,&fsize,0); + while ( len < fsize ) { - ptr = OS_portable_mapfile(fname,&fsize,0); - while ( len < fsize ) + if ( (n= LP_cacheitem(coin,(struct LP_transaction *)&ptr[len],fsize - len)) < 0 ) { - if ( (n= LP_cacheitem(coin,(struct LP_transaction *)&ptr[len],fsize - len)) < 0 ) - { - printf("cacheitem error at %s offset.%ld when fsize.%ld\n",coin->symbol,len,fsize); - fseek(*wfp,len,SEEK_SET); - break; - } - len += n; - if ( (len & 7) != 0 ) - printf("odd offset at %ld\n",len); + printf("cacheitem error at %s offset.%ld when fsize.%ld\n",coin->symbol,len,fsize); + tflag = 1; + break; } + len += n; + if ( (len & 7) != 0 ) + printf("odd offset at %ld\n",len); } + OS_releasemap(ptr,fsize); } } - return(fsize); + if ( tflag != 0 ) + OS_truncate(fname,len); } bits256 iguana_merkle(bits256 *tree,int32_t txn_count) diff --git a/iguana/exchanges/LP_coins.c b/iguana/exchanges/LP_coins.c index afd5a8129..69bf86302 100644 --- a/iguana/exchanges/LP_coins.c +++ b/iguana/exchanges/LP_coins.c @@ -353,7 +353,7 @@ uint16_t LP_coininit(struct iguana_info *coin,char *symbol,char *name,char *asse coin->zcash = LP_IS_BITCOINCASH; //printf("set coin.%s <- LP_IS_BITCOINCASH %d\n",symbol,coin->zcash); } - coin->cachesize = LP_cacheptrs_init(&coin->cachefp,coin); + LP_cacheptrs_init(coin); return(port); } diff --git a/iguana/exchanges/LP_include.h b/iguana/exchanges/LP_include.h index b5f98b3d1..61749e7ff 100644 --- a/iguana/exchanges/LP_include.h +++ b/iguana/exchanges/LP_include.h @@ -268,7 +268,7 @@ struct iguana_info char symbol[16],smartaddr[64],userpass[1024],serverport[128]; // portfolio double price_kmd,force,perc,goal,goalperc,relvolume,rate; - void *electrum; void *ctx; FILE *cachefp; long cachesize; + void *electrum; void *ctx; uint64_t maxamount,kmd_equiv,balanceA,balanceB,valuesumA,valuesumB; uint8_t pubkey33[33],zcash; bits256 lastprivkey; uint32_t lastprivkeytime; int32_t privkeydepth; @@ -433,7 +433,7 @@ char *basilisk_swapentry(uint32_t requestid,uint32_t quoteid); uint64_t LP_KMDvalue(struct iguana_info *coin,uint64_t balance); int32_t LP_address_utxoadd(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); -long LP_cacheptrs_init(FILE **wfp,struct iguana_info *coin); +void LP_cacheptrs_init(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); From 252351a8aeabb8acad49d4069a05488d49e600fa Mon Sep 17 00:00:00 2001 From: jl777 Date: Fri, 10 Nov 2017 22:02:49 +0200 Subject: [PATCH 0531/1664] Test --- iguana/exchanges/LP_cache.c | 15 ++++++++------- 1 file changed, 8 insertions(+), 7 deletions(-) diff --git a/iguana/exchanges/LP_cache.c b/iguana/exchanges/LP_cache.c index 9af599b21..c7a507250 100644 --- a/iguana/exchanges/LP_cache.c +++ b/iguana/exchanges/LP_cache.c @@ -110,14 +110,15 @@ void LP_SPV_store(struct iguana_info *coin,char *coinaddr,bits256 txid,int32_t h } } -int32_t LP_cacheitem(struct iguana_info *coin,struct LP_transaction *tx,long remains) +long LP_cacheitem(struct iguana_info *coin,void *ptr,long fpos,long remains) { - int32_t offset,n; uint8_t *serialized; bits256 hash; cJSON *txobj; char str[65],str2[65]; - offset = sizeof(*tx) + tx->numvouts*sizeof(*tx->outpoints); + struct LP_transaction *tx; long offset; int32_t n; uint8_t *serialized; bits256 hash; cJSON *txobj; char str[65],str2[65]; + tx = ptr; + offset = fpos + sizeof(*tx) + tx->numvouts*sizeof(*tx->outpoints); if ( offset+tx->len <= remains ) { - printf("offset.%d txlen.%d remains.%ld\n",offset,tx->len,remains); - serialized = &((uint8_t *)tx)[offset]; + printf("offset.%ld txlen.%d remains.%ld\n",offset,tx->len,remains); + serialized = &((uint8_t *)ptr)[offset]; hash = bits256_doublesha256(0,serialized,tx->len); if ( bits256_cmp(hash,tx->txid) == 0 ) { @@ -150,13 +151,13 @@ void LP_cacheptrs_init(struct iguana_info *coin) ptr = OS_portable_mapfile(fname,&fsize,0); while ( len < fsize ) { - if ( (n= LP_cacheitem(coin,(struct LP_transaction *)&ptr[len],fsize - len)) < 0 ) + if ( (n= LP_cacheitem(coin,ptr,len,fsize - len)) < 0 ) { printf("cacheitem error at %s offset.%ld when fsize.%ld\n",coin->symbol,len,fsize); tflag = 1; break; } - len += n; + len = n; if ( (len & 7) != 0 ) printf("odd offset at %ld\n",len); } From 75c162e52b7ce693220824383568afc0cb01e6ba Mon Sep 17 00:00:00 2001 From: jl777 Date: Fri, 10 Nov 2017 22:11:19 +0200 Subject: [PATCH 0532/1664] Test --- iguana/exchanges/LP_cache.c | 1 + 1 file changed, 1 insertion(+) diff --git a/iguana/exchanges/LP_cache.c b/iguana/exchanges/LP_cache.c index c7a507250..fb7b822b9 100644 --- a/iguana/exchanges/LP_cache.c +++ b/iguana/exchanges/LP_cache.c @@ -128,6 +128,7 @@ long LP_cacheitem(struct iguana_info *coin,void *ptr,long fpos,long remains) n++; if ( (txobj= LP_create_transaction(coin,tx->txid,serialized,tx->len,tx->height)) != 0 ) free_json(txobj); + printf("return offset.%ld + tx->len %d -> %d\n",offset,tx->len,n); return(offset + n); } printf("%s vs %s did not validated in cache\n",bits256_str(str,hash),bits256_str(str2,tx->txid)); From 4964952dc9d85f2ec2f9c40f5da8e46819142e2a Mon Sep 17 00:00:00 2001 From: jl777 Date: Fri, 10 Nov 2017 22:32:26 +0200 Subject: [PATCH 0533/1664] Test --- iguana/exchanges/LP_cache.c | 75 +++++++++++++------------------------ 1 file changed, 27 insertions(+), 48 deletions(-) diff --git a/iguana/exchanges/LP_cache.c b/iguana/exchanges/LP_cache.c index fb7b822b9..8b4d705b1 100644 --- a/iguana/exchanges/LP_cache.c +++ b/iguana/exchanges/LP_cache.c @@ -87,82 +87,61 @@ cJSON *LP_create_transaction(struct iguana_info *coin,bits256 txid,uint8_t *seri void LP_SPV_store(struct iguana_info *coin,char *coinaddr,bits256 txid,int32_t height) { - FILE *fp; char fname[512]; struct LP_transaction TX; int32_t n; struct LP_transaction *tx = 0; + FILE *fp; char fname[512]; struct LP_transaction *tx = 0; if ( (tx= LP_transactionfind(coin,txid)) != 0 && tx->serialized != 0 && tx->len > 0 ) { sprintf(fname,"%s/UNSPENTS/%s.SPV",GLOBAL_DBDIR,coin->symbol), OS_portable_path(fname); if ( (fp= OS_appendfile(fname)) != 0 ) { char str[65]; printf("store %s %s.[%d]\n",coin->symbol,bits256_str(str,txid),tx->len); - TX = *tx; - memset(&TX.hh,0,sizeof(TX.hh)); - TX.serialized = 0; - TX.SPV = height; - fwrite(&TX,1,sizeof(TX),fp); - if ( tx->numvouts > 0 ) - fwrite(TX.outpoints,tx->numvouts,sizeof(*TX.outpoints),fp); - fwrite(tx->serialized,1,tx->len,fp); - n = tx->len; - while ( (n & 7) != 0 ) - fputc(0,fp), n++; + fwrite(&tx->txid,1,sizeof(tx->txid),fp); + fwrite(&tx->len,1,sizeof(tx->len),fp); + fwrite(&tx->height,1,sizeof(tx->height),fp); + fwrite(&tx->serialized,1,tx->len,fp); fclose(fp); } } } -long LP_cacheitem(struct iguana_info *coin,void *ptr,long fpos,long remains) +long LP_cacheitem(struct iguana_info *coin,FILE *fp) { - struct LP_transaction *tx; long offset; int32_t n; uint8_t *serialized; bits256 hash; cJSON *txobj; char str[65],str2[65]; - tx = ptr; - offset = fpos + sizeof(*tx) + tx->numvouts*sizeof(*tx->outpoints); - if ( offset+tx->len <= remains ) + bits256 txid,hash; int32_t height,len; uint8_t *serialized; cJSON *txobj; char str[65],str2[65]; + if ( fread(&txid,1,sizeof(txid),fp) == sizeof(txid) && fread(&len,1,sizeof(len),fp) == sizeof(len) && fread(&height,1,sizeof(height),fp) == sizeof(height) && len < 100000 ) { - printf("offset.%ld txlen.%d remains.%ld\n",offset,tx->len,remains); - serialized = &((uint8_t *)ptr)[offset]; - hash = bits256_doublesha256(0,serialized,tx->len); - if ( bits256_cmp(hash,tx->txid) == 0 ) + serialized = malloc(len); + if ( fread(serialized,1,len,fp) == len ) { - printf("%s validated in cache\n",bits256_str(str,hash)); - n = tx->len; - while ( (n & 7) != 0 ) - n++; - if ( (txobj= LP_create_transaction(coin,tx->txid,serialized,tx->len,tx->height)) != 0 ) - free_json(txobj); - printf("return offset.%ld + tx->len %d -> %d\n",offset,tx->len,n); - return(offset + n); + hash = bits256_doublesha256(0,serialized,len); + if ( bits256_cmp(hash,txid) == 0 ) + { + printf("%s validated in cache\n",bits256_str(str,hash)); + if ( (txobj= LP_create_transaction(coin,txid,serialized,len,height)) != 0 ) + free_json(txobj); + return(ftell(fp)); + } + printf("%s vs %s did not validated in cache\n",bits256_str(str,hash),bits256_str(str2,txid)); } - printf("%s vs %s did not validated in cache\n",bits256_str(str,hash),bits256_str(str2,tx->txid)); } return(-1); } void LP_cacheptrs_init(struct iguana_info *coin) { - char fname[1024]; FILE *fp; int32_t tflag=0,flag = 0; long n,fsize=0,len = 0; uint8_t *ptr = 0; + char fname[1024]; FILE *fp; int32_t tflag=0; long n,fsize=0,len = 0; sprintf(fname,"%s/UNSPENTS/%s.SPV",GLOBAL_DBDIR,coin->symbol), OS_portable_path(fname); fp = fopen(fname,"rb"); if ( fp != 0 ) { - fseek(fp,0,SEEK_END); - if ( ftell(fp) > sizeof(struct LP_transaction) ) - flag = 1; - fclose(fp); - if ( flag != 0 ) + while ( len < fsize ) { - ptr = OS_portable_mapfile(fname,&fsize,0); - while ( len < fsize ) + if ( (n= LP_cacheitem(coin,fp)) < 0 ) { - if ( (n= LP_cacheitem(coin,ptr,len,fsize - len)) < 0 ) - { - printf("cacheitem error at %s offset.%ld when fsize.%ld\n",coin->symbol,len,fsize); - tflag = 1; - break; - } - len = n; - if ( (len & 7) != 0 ) - printf("odd offset at %ld\n",len); + printf("cacheitem error at %s offset.%ld when fsize.%ld\n",coin->symbol,len,fsize); + tflag = 1; + break; } - OS_releasemap(ptr,fsize); + len = n; + printf("len.%ld\n",len); } } if ( tflag != 0 ) From 10badb29e7a639bc635e62f4c527a4e7da844394 Mon Sep 17 00:00:00 2001 From: jl777 Date: Fri, 10 Nov 2017 22:43:03 +0200 Subject: [PATCH 0534/1664] Test --- iguana/exchanges/LP_cache.c | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/iguana/exchanges/LP_cache.c b/iguana/exchanges/LP_cache.c index 8b4d705b1..3a28cd241 100644 --- a/iguana/exchanges/LP_cache.c +++ b/iguana/exchanges/LP_cache.c @@ -105,11 +105,12 @@ void LP_SPV_store(struct iguana_info *coin,char *coinaddr,bits256 txid,int32_t h long LP_cacheitem(struct iguana_info *coin,FILE *fp) { - bits256 txid,hash; int32_t height,len; uint8_t *serialized; cJSON *txobj; char str[65],str2[65]; + bits256 txid,hash; int32_t retval,height,len; uint8_t *serialized; cJSON *txobj; char str[65],str2[65]; if ( fread(&txid,1,sizeof(txid),fp) == sizeof(txid) && fread(&len,1,sizeof(len),fp) == sizeof(len) && fread(&height,1,sizeof(height),fp) == sizeof(height) && len < 100000 ) { serialized = malloc(len); - if ( fread(serialized,1,len,fp) == len ) + printf("read len.%d\n",len); + if ( (retval= (int32_t)fread(serialized,1,len,fp)) == len ) { hash = bits256_doublesha256(0,serialized,len); if ( bits256_cmp(hash,txid) == 0 ) @@ -120,8 +121,8 @@ long LP_cacheitem(struct iguana_info *coin,FILE *fp) return(ftell(fp)); } printf("%s vs %s did not validated in cache\n",bits256_str(str,hash),bits256_str(str2,txid)); - } - } + } else printf("retval.%d vs len.%d\n",retval,len); + } else printf("fread error\n"); return(-1); } @@ -143,7 +144,7 @@ void LP_cacheptrs_init(struct iguana_info *coin) len = n; printf("len.%ld\n",len); } - } + } else printf("couldnt find.(%s)\n",fname); if ( tflag != 0 ) OS_truncate(fname,len); } From 6421c45df086b19cba5595ecebdfe3bf47aaec95 Mon Sep 17 00:00:00 2001 From: jl777 Date: Fri, 10 Nov 2017 22:46:39 +0200 Subject: [PATCH 0535/1664] Test --- iguana/exchanges/LP_cache.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/iguana/exchanges/LP_cache.c b/iguana/exchanges/LP_cache.c index 3a28cd241..bf4a909c3 100644 --- a/iguana/exchanges/LP_cache.c +++ b/iguana/exchanges/LP_cache.c @@ -133,6 +133,9 @@ void LP_cacheptrs_init(struct iguana_info *coin) fp = fopen(fname,"rb"); if ( fp != 0 ) { + fseek(fp,0,SEEK_END); + fsize = ftell(fp); + rewind(fp); while ( len < fsize ) { if ( (n= LP_cacheitem(coin,fp)) < 0 ) From 14fdcee45e7b8db49dcd0e12fb4e50e0fd8bab7b Mon Sep 17 00:00:00 2001 From: jl777 Date: Fri, 10 Nov 2017 22:51:14 +0200 Subject: [PATCH 0536/1664] Test --- iguana/exchanges/LP_cache.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/iguana/exchanges/LP_cache.c b/iguana/exchanges/LP_cache.c index bf4a909c3..5044702ea 100644 --- a/iguana/exchanges/LP_cache.c +++ b/iguana/exchanges/LP_cache.c @@ -97,7 +97,7 @@ void LP_SPV_store(struct iguana_info *coin,char *coinaddr,bits256 txid,int32_t h fwrite(&tx->txid,1,sizeof(tx->txid),fp); fwrite(&tx->len,1,sizeof(tx->len),fp); fwrite(&tx->height,1,sizeof(tx->height),fp); - fwrite(&tx->serialized,1,tx->len,fp); + fwrite(tx->serialized,1,tx->len,fp); fclose(fp); } } From 7d5ca7ab122752b08c566827426d38b73b6167fc Mon Sep 17 00:00:00 2001 From: jl777 Date: Fri, 10 Nov 2017 22:56:13 +0200 Subject: [PATCH 0537/1664] Test --- iguana/exchanges/LP_cache.c | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/iguana/exchanges/LP_cache.c b/iguana/exchanges/LP_cache.c index 5044702ea..2fa3f6d69 100644 --- a/iguana/exchanges/LP_cache.c +++ b/iguana/exchanges/LP_cache.c @@ -103,13 +103,13 @@ void LP_SPV_store(struct iguana_info *coin,char *coinaddr,bits256 txid,int32_t h } } -long LP_cacheitem(struct iguana_info *coin,FILE *fp) +int32_t LP_cacheitem(struct iguana_info *coin,FILE *fp) { - bits256 txid,hash; int32_t retval,height,len; uint8_t *serialized; cJSON *txobj; char str[65],str2[65]; + bits256 txid,hash; long fpos; int32_t retval,height,len; uint8_t *serialized; cJSON *txobj; char str[65],str2[65]; + fpos = ftell(fp); if ( fread(&txid,1,sizeof(txid),fp) == sizeof(txid) && fread(&len,1,sizeof(len),fp) == sizeof(len) && fread(&height,1,sizeof(height),fp) == sizeof(height) && len < 100000 ) { serialized = malloc(len); - printf("read len.%d\n",len); if ( (retval= (int32_t)fread(serialized,1,len,fp)) == len ) { hash = bits256_doublesha256(0,serialized,len); @@ -118,7 +118,7 @@ long LP_cacheitem(struct iguana_info *coin,FILE *fp) printf("%s validated in cache\n",bits256_str(str,hash)); if ( (txobj= LP_create_transaction(coin,txid,serialized,len,height)) != 0 ) free_json(txobj); - return(ftell(fp)); + return((int32_t)(ftell(fp) - fpos)); } printf("%s vs %s did not validated in cache\n",bits256_str(str,hash),bits256_str(str2,txid)); } else printf("retval.%d vs len.%d\n",retval,len); @@ -144,8 +144,8 @@ void LP_cacheptrs_init(struct iguana_info *coin) tflag = 1; break; } - len = n; - printf("len.%ld\n",len); + len += n; + printf("len.%ld n.%ld\n",len,n); } } else printf("couldnt find.(%s)\n",fname); if ( tflag != 0 ) From 9fc67c9b2493f775f98a27fe12ca727331a4c354 Mon Sep 17 00:00:00 2001 From: jl777 Date: Fri, 10 Nov 2017 23:03:22 +0200 Subject: [PATCH 0538/1664] Test --- iguana/exchanges/LP_cache.c | 4 +++- iguana/exchanges/LP_coins.c | 1 - iguana/exchanges/LP_socket.c | 3 ++- 3 files changed, 5 insertions(+), 3 deletions(-) diff --git a/iguana/exchanges/LP_cache.c b/iguana/exchanges/LP_cache.c index 2fa3f6d69..bcca92a86 100644 --- a/iguana/exchanges/LP_cache.c +++ b/iguana/exchanges/LP_cache.c @@ -131,6 +131,7 @@ void LP_cacheptrs_init(struct iguana_info *coin) char fname[1024]; FILE *fp; int32_t tflag=0; long n,fsize=0,len = 0; sprintf(fname,"%s/UNSPENTS/%s.SPV",GLOBAL_DBDIR,coin->symbol), OS_portable_path(fname); fp = fopen(fname,"rb"); + printf("load %s\n",fname); if ( fp != 0 ) { fseek(fp,0,SEEK_END); @@ -145,8 +146,9 @@ void LP_cacheptrs_init(struct iguana_info *coin) break; } len += n; - printf("len.%ld n.%ld\n",len,n); + printf("%s len.%ld n.%ld\n",fname,len,n); } + fclose(fp); } else printf("couldnt find.(%s)\n",fname); if ( tflag != 0 ) OS_truncate(fname,len); diff --git a/iguana/exchanges/LP_coins.c b/iguana/exchanges/LP_coins.c index 69bf86302..38c62ac64 100644 --- a/iguana/exchanges/LP_coins.c +++ b/iguana/exchanges/LP_coins.c @@ -353,7 +353,6 @@ uint16_t LP_coininit(struct iguana_info *coin,char *symbol,char *name,char *asse coin->zcash = LP_IS_BITCOINCASH; //printf("set coin.%s <- LP_IS_BITCOINCASH %d\n",symbol,coin->zcash); } - LP_cacheptrs_init(coin); return(port); } diff --git a/iguana/exchanges/LP_socket.c b/iguana/exchanges/LP_socket.c index c34c04ee7..8435aa6df 100644 --- a/iguana/exchanges/LP_socket.c +++ b/iguana/exchanges/LP_socket.c @@ -1056,7 +1056,8 @@ cJSON *LP_electrumserver(struct iguana_info *coin,char *ipaddr,uint16_t port) { printf("launched %s electrum.(%s:%u)\n",coin->symbol,ep->ipaddr,ep->port); jaddstr(retjson,"result","success"); - ep->prev = coin->electrum; + if ( (ep->prev= coin->electrum) == 0 ) + LP_cacheptrs_init(coin); coin->electrum = ep; } } From 9777a4e933d6a83c664e408527a642295247c78f Mon Sep 17 00:00:00 2001 From: jl777 Date: Fri, 10 Nov 2017 23:08:14 +0200 Subject: [PATCH 0539/1664] Test --- iguana/exchanges/LP_cache.c | 9 +++++---- iguana/exchanges/LP_include.h | 2 +- iguana/exchanges/LP_socket.c | 8 ++++++-- 3 files changed, 12 insertions(+), 7 deletions(-) diff --git a/iguana/exchanges/LP_cache.c b/iguana/exchanges/LP_cache.c index bcca92a86..660ff107c 100644 --- a/iguana/exchanges/LP_cache.c +++ b/iguana/exchanges/LP_cache.c @@ -115,7 +115,7 @@ int32_t LP_cacheitem(struct iguana_info *coin,FILE *fp) hash = bits256_doublesha256(0,serialized,len); if ( bits256_cmp(hash,txid) == 0 ) { - printf("%s validated in cache\n",bits256_str(str,hash)); + //printf("%s validated in cache\n",bits256_str(str,hash)); if ( (txobj= LP_create_transaction(coin,txid,serialized,len,height)) != 0 ) free_json(txobj); return((int32_t)(ftell(fp) - fpos)); @@ -128,10 +128,10 @@ int32_t LP_cacheitem(struct iguana_info *coin,FILE *fp) void LP_cacheptrs_init(struct iguana_info *coin) { - char fname[1024]; FILE *fp; int32_t tflag=0; long n,fsize=0,len = 0; + char fname[1024]; FILE *fp; int32_t count,tflag=0; long n,fsize=0,len = 0; sprintf(fname,"%s/UNSPENTS/%s.SPV",GLOBAL_DBDIR,coin->symbol), OS_portable_path(fname); fp = fopen(fname,"rb"); - printf("load %s\n",fname); + count = 0; if ( fp != 0 ) { fseek(fp,0,SEEK_END); @@ -145,9 +145,10 @@ void LP_cacheptrs_init(struct iguana_info *coin) tflag = 1; break; } + count++; len += n; - printf("%s len.%ld n.%ld\n",fname,len,n); } + printf("loaded %s %d entries total len.%ld\n",fname,count,len); fclose(fp); } else printf("couldnt find.(%s)\n",fname); if ( tflag != 0 ) diff --git a/iguana/exchanges/LP_include.h b/iguana/exchanges/LP_include.h index 61749e7ff..08f82f182 100644 --- a/iguana/exchanges/LP_include.h +++ b/iguana/exchanges/LP_include.h @@ -263,7 +263,7 @@ struct iguana_info 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 electrumlist,lastunspent,importedprivkey,lastpushtime,lastutxosync,addr_listunspent_requested,lastutxos,updaterate,counter,inactive,lastmempool,lastgetinfo,ratetime,heighttime,lastmonitor,obooktime; + uint32_t 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[16],smartaddr[64],userpass[1024],serverport[128]; // portfolio diff --git a/iguana/exchanges/LP_socket.c b/iguana/exchanges/LP_socket.c index 8435aa6df..9c816046a 100644 --- a/iguana/exchanges/LP_socket.c +++ b/iguana/exchanges/LP_socket.c @@ -1056,9 +1056,13 @@ cJSON *LP_electrumserver(struct iguana_info *coin,char *ipaddr,uint16_t port) { printf("launched %s electrum.(%s:%u)\n",coin->symbol,ep->ipaddr,ep->port); jaddstr(retjson,"result","success"); - if ( (ep->prev= coin->electrum) == 0 ) - LP_cacheptrs_init(coin); + ep->prev = coin->electrum; coin->electrum = ep; + if ( coin->loadedcache == 0 ) + { + LP_cacheptrs_init(coin); + coin->loadedcache = (uint32_t)time(NULL); + } } } else From c2ea6b6b16fa69558945262fd969930b7fd27a24 Mon Sep 17 00:00:00 2001 From: jl777 Date: Fri, 10 Nov 2017 23:11:28 +0200 Subject: [PATCH 0540/1664] Test --- iguana/exchanges/LP_cache.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/iguana/exchanges/LP_cache.c b/iguana/exchanges/LP_cache.c index 660ff107c..18ed73f16 100644 --- a/iguana/exchanges/LP_cache.c +++ b/iguana/exchanges/LP_cache.c @@ -45,7 +45,7 @@ cJSON *LP_create_transaction(struct iguana_info *coin,bits256 txid,uint8_t *seri tx = LP_transactionadd(coin,txid,height,numvouts,numvins); tx->serialized = serialized; tx->len = len; - tx->height = height; + tx->SPV = tx->height = height; //printf("tx.%p vins.(%s) vouts.(%s)\n",tx,jprint(vins,0),jprint(vouts,0)); for (i=0; i Date: Fri, 10 Nov 2017 23:19:31 +0200 Subject: [PATCH 0541/1664] Test --- iguana/exchanges/LP_cache.c | 6 +++--- iguana/exchanges/LP_include.h | 14 ++++++++++++++ iguana/exchanges/LP_nativeDEX.c | 4 ++-- iguana/exchanges/LP_ordermatch.c | 2 +- iguana/exchanges/LP_socket.c | 20 +++++++------------- 5 files changed, 27 insertions(+), 19 deletions(-) diff --git a/iguana/exchanges/LP_cache.c b/iguana/exchanges/LP_cache.c index 18ed73f16..c66957bd1 100644 --- a/iguana/exchanges/LP_cache.c +++ b/iguana/exchanges/LP_cache.c @@ -85,7 +85,7 @@ cJSON *LP_create_transaction(struct iguana_info *coin,bits256 txid,uint8_t *seri return(txobj); } -void LP_SPV_store(struct iguana_info *coin,char *coinaddr,bits256 txid,int32_t height) +void LP_SPV_store(struct iguana_info *coin,bits256 txid,int32_t height) { FILE *fp; char fname[512]; struct LP_transaction *tx = 0; if ( (tx= LP_transactionfind(coin,txid)) != 0 && tx->serialized != 0 && tx->len > 0 ) @@ -223,7 +223,7 @@ bits256 LP_merkleroot(struct iguana_info *coin,struct electrum_info *ep,int32_t return(merkleroot); } -int32_t LP_merkleproof(struct iguana_info *coin,char *coinaddr,struct electrum_info *ep,bits256 txid,int32_t height) +int32_t LP_merkleproof(struct iguana_info *coin,struct electrum_info *ep,bits256 txid,int32_t height) { struct LP_transaction *tx=0; cJSON *merkobj,*merkles; bits256 roothash,merkleroot; int32_t m,SPV = 0; if ( (tx= LP_transactionfind(coin,txid)) != 0 && tx->height == height && tx->SPV > 0 ) @@ -244,7 +244,7 @@ int32_t LP_merkleproof(struct iguana_info *coin,char *coinaddr,struct electrum_i SPV = height; if ( tx != 0 ) tx->SPV = height; - LP_SPV_store(coin,coinaddr,txid,height); + LP_SPV_store(coin,txid,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)); diff --git a/iguana/exchanges/LP_include.h b/iguana/exchanges/LP_include.h index 08f82f182..2003f3a06 100644 --- a/iguana/exchanges/LP_include.h +++ b/iguana/exchanges/LP_include.h @@ -371,6 +371,19 @@ struct LP_pubkeyinfo uint8_t rmd160[20],sig[65],pubsecp[33],siglen; }; +struct electrum_info +{ + queue_t sendQ,pendingQ; + portable_mutex_t mutex,txmutex; + struct electrum_info *prev; + int32_t bufsize,sock,*heightp,numerrors; + struct iguana_info *coin; + uint32_t stratumid,lasttime,keepalive,pending,*heighttimep; + char ipaddr[64],symbol[16]; + uint16_t port; + uint8_t buf[]; +}; + int32_t LP_pubkey_sigcheck(struct LP_pubkeyinfo *pubp,cJSON *item); int32_t LP_pubkey_sigadd(cJSON *item,uint32_t timestamp,bits256 priv,bits256 pub,uint8_t *rmd160,uint8_t *pubsecp); int32_t LP_quoteparse(struct LP_quoteinfo *qp,cJSON *argjson); @@ -410,6 +423,7 @@ int32_t LP_reserved_msg(int32_t priority,char *base,char *rel,bits256 pubkey,cha 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,struct electrum_info *ep,bits256 txid,int32_t height); struct LP_transaction *LP_transactionadd(struct iguana_info *coin,bits256 txid,int32_t height,int32_t numvouts,int32_t numvins); void LP_tradebot_finished(uint32_t tradeid,uint32_t requestid,uint32_t quoteid); uint64_t LP_txfeecalc(struct iguana_info *coin,uint64_t txfee,int32_t txlen); diff --git a/iguana/exchanges/LP_nativeDEX.c b/iguana/exchanges/LP_nativeDEX.c index 9ab94a382..49eca0745 100644 --- a/iguana/exchanges/LP_nativeDEX.c +++ b/iguana/exchanges/LP_nativeDEX.c @@ -524,7 +524,7 @@ void LP_coinsloop(void *_coins) if ( up->SPV == 0 ) { nonz++; - up->SPV = LP_merkleproof(coin,ap->coinaddr,backupep,up->U.txid,up->U.height); + up->SPV = LP_merkleproof(coin,backupep,up->U.txid,up->U.height); if ( 0 && up->SPV > 0 ) printf("%s %s: SPV.%d\n",coin->symbol,bits256_str(str,up->U.txid),up->SPV); } @@ -535,7 +535,7 @@ void LP_coinsloop(void *_coins) oldht = up->U.height; LP_txheight_check(coin,ap->coinaddr,up); if ( oldht != up->U.height ) - up->SPV = LP_merkleproof(coin,ap->coinaddr,backupep,up->U.txid,up->U.height); + up->SPV = LP_merkleproof(coin,backupep,up->U.txid,up->U.height); if ( up->SPV <= 0 ) up->SPV = -2; else printf("%s %s: corrected SPV.%d\n",coin->symbol,bits256_str(str,up->U.txid),up->SPV); diff --git a/iguana/exchanges/LP_ordermatch.c b/iguana/exchanges/LP_ordermatch.c index fb5761d86..c04beef58 100644 --- a/iguana/exchanges/LP_ordermatch.c +++ b/iguana/exchanges/LP_ordermatch.c @@ -647,7 +647,7 @@ int32_t LP_validSPV(char *symbol,char *coinaddr,bits256 txid,int32_t vout) return(-1); if ( (backupep= ep->prev) == 0 ) backupep = ep; - up->SPV = LP_merkleproof(coin,coinaddr,backupep,up->U.txid,up->U.height); + up->SPV = LP_merkleproof(coin,backupep,up->U.txid,up->U.height); if ( up->SPV <= 0 ) return(-1); } diff --git a/iguana/exchanges/LP_socket.c b/iguana/exchanges/LP_socket.c index 9c816046a..c06101f1a 100644 --- a/iguana/exchanges/LP_socket.c +++ b/iguana/exchanges/LP_socket.c @@ -238,18 +238,7 @@ int32_t LP_socketrecv(int32_t sock,uint8_t *recvbuf,int32_t maxlen) return(recvlen); } -struct electrum_info -{ - queue_t sendQ,pendingQ; - portable_mutex_t mutex,txmutex; - struct electrum_info *prev; - int32_t bufsize,sock,*heightp,numerrors; - struct iguana_info *coin; - uint32_t stratumid,lasttime,keepalive,pending,*heighttimep; - char ipaddr[64],symbol[16]; - uint16_t port; - uint8_t buf[]; -} *Electrums[8192]; +struct electrum_info *Electrums[8192]; int32_t Num_electrums; struct electrum_info *electrum_server(char *symbol,struct electrum_info *ep) @@ -750,12 +739,17 @@ cJSON *_electrum_transaction(char *symbol,struct electrum_info *ep,cJSON **retjs cJSON *electrum_transaction(char *symbol,struct electrum_info *ep,cJSON **retjsonp,bits256 txid) { - cJSON *retjson; + cJSON *retjson; struct iguana_info *coin; struct LP_transaction *tx; if ( ep != 0 ) portable_mutex_lock(&ep->txmutex); retjson = _electrum_transaction(symbol,ep,retjsonp,txid); if ( ep != 0 ) portable_mutex_unlock(&ep->txmutex); + if ( ep != 0 && (coin= LP_coinfind(symbol)) != 0 && (tx= LP_transactionfind(coin,txid)) != 0 && tx->height > 0 && tx->SPV <= 0 ) + { + LP_merkleproof(coin,ep,txid,tx->height); + printf("extra merkle\n"); + } return(retjson); } From 72cb226ac19b2e797840b9627dcbbd33214dcbe2 Mon Sep 17 00:00:00 2001 From: jl777 Date: Fri, 10 Nov 2017 23:29:22 +0200 Subject: [PATCH 0542/1664] Test --- iguana/exchanges/LP_socket.c | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/iguana/exchanges/LP_socket.c b/iguana/exchanges/LP_socket.c index c06101f1a..e6bc5ad02 100644 --- a/iguana/exchanges/LP_socket.c +++ b/iguana/exchanges/LP_socket.c @@ -739,17 +739,19 @@ cJSON *_electrum_transaction(char *symbol,struct electrum_info *ep,cJSON **retjs cJSON *electrum_transaction(char *symbol,struct electrum_info *ep,cJSON **retjsonp,bits256 txid) { - cJSON *retjson; struct iguana_info *coin; struct LP_transaction *tx; + cJSON *retjson; //struct iguana_info *coin; struct LP_transaction *tx; if ( ep != 0 ) portable_mutex_lock(&ep->txmutex); retjson = _electrum_transaction(symbol,ep,retjsonp,txid); if ( ep != 0 ) portable_mutex_unlock(&ep->txmutex); - if ( ep != 0 && (coin= LP_coinfind(symbol)) != 0 && (tx= LP_transactionfind(coin,txid)) != 0 && tx->height > 0 && tx->SPV <= 0 ) + /*if ( ep != 0 && (coin= LP_coinfind(symbol)) != 0 && (tx= LP_transactionfind(coin,txid)) != 0 && tx->SPV <= 0 ) // we just dont have height! { + if ( tx->height == 0 ) + tx->height = LP_gettxheight(coin,txid); LP_merkleproof(coin,ep,txid,tx->height); printf("extra merkle\n"); - } + }*/ return(retjson); } From 408f2e4d5d5fa1982e69004d0df6b026ee4c27c2 Mon Sep 17 00:00:00 2001 From: jl777 Date: Fri, 10 Nov 2017 23:32:16 +0200 Subject: [PATCH 0543/1664] Test --- iguana/exchanges/LP_socket.c | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/iguana/exchanges/LP_socket.c b/iguana/exchanges/LP_socket.c index e6bc5ad02..74a9bb364 100644 --- a/iguana/exchanges/LP_socket.c +++ b/iguana/exchanges/LP_socket.c @@ -327,7 +327,11 @@ int32_t electrum_process_array(struct iguana_info *coin,struct electrum_info *ep if (tx->height <= 0 ) { tx->height = ht; - //printf("%s %s >>>>>>>>>> set %s <- height %d\n",coin->symbol,coinaddr,bits256_str(str,txid),tx->height); + if ( ep != 0 && coin != 0 && tx->SPV == 0 ) + { + tx->SPV = LP_merkleproof(coin,ep,txid,tx->height); + printf("%s %s >>>>>>>>>> set %s <- height %d\n",coin->symbol,coinaddr,bits256_str(str,txid),tx->height); + } } if ( v >= 0 && v < tx->numvouts ) { From 3a6f78c6a9f49235b33f20717eb1ccb054bab3ee Mon Sep 17 00:00:00 2001 From: jl777 Date: Fri, 10 Nov 2017 23:40:25 +0200 Subject: [PATCH 0544/1664] Test --- iguana/exchanges/LP_cache.c | 2 +- iguana/exchanges/LP_socket.c | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/iguana/exchanges/LP_cache.c b/iguana/exchanges/LP_cache.c index c66957bd1..b0c59611f 100644 --- a/iguana/exchanges/LP_cache.c +++ b/iguana/exchanges/LP_cache.c @@ -93,7 +93,7 @@ void LP_SPV_store(struct iguana_info *coin,bits256 txid,int32_t height) sprintf(fname,"%s/UNSPENTS/%s.SPV",GLOBAL_DBDIR,coin->symbol), OS_portable_path(fname); if ( (fp= OS_appendfile(fname)) != 0 ) { - char str[65]; printf("store %s %s.[%d]\n",coin->symbol,bits256_str(str,txid),tx->len); + //char str[65]; printf("store %s %s.[%d]\n",coin->symbol,bits256_str(str,txid),tx->len); fwrite(&tx->txid,1,sizeof(tx->txid),fp); fwrite(&tx->len,1,sizeof(tx->len),fp); fwrite(&tx->height,1,sizeof(tx->height),fp); diff --git a/iguana/exchanges/LP_socket.c b/iguana/exchanges/LP_socket.c index 74a9bb364..00eea5c12 100644 --- a/iguana/exchanges/LP_socket.c +++ b/iguana/exchanges/LP_socket.c @@ -416,7 +416,7 @@ cJSON *electrum_submit(char *symbol,struct electrum_info *ep,cJSON **retjsonp,ch { *retjsonp = 0; sprintf(stratumreq,"{ \"jsonrpc\":\"2.0\", \"id\": %u, \"method\":\"%s\", \"params\": %s }\n",ep->stratumid,method,params); -printf("%s %s",symbol,stratumreq); +//printf("%s %s",symbol,stratumreq); memset(ep->buf,0,ep->bufsize); sitem = electrum_sitem(ep,stratumreq,timeout,retjsonp); /*sitem = (struct stritem *)queueitem(stratumreq); @@ -889,7 +889,7 @@ int32_t LP_recvfunc(struct electrum_info *ep,char *str,int32_t len) ep->lasttime = (uint32_t)time(NULL); if ( (strjson= cJSON_Parse(str)) != 0 ) { - printf("%s RECV.(%ld) id.%d\n",ep->symbol,strlen(str),jint(strjson,"id")); + //printf("%s RECV.(%ld) id.%d\n",ep->symbol,strlen(str),jint(strjson,"id")); resultjson = jobj(strjson,"result"); //printf("strjson.(%s)\n",jprint(strjson,0)); if ( (method= jstr(strjson,"method")) != 0 ) From c0970054ecba149e8b863909902eb1a1313396a5 Mon Sep 17 00:00:00 2001 From: jl777 Date: Fri, 10 Nov 2017 23:44:31 +0200 Subject: [PATCH 0545/1664] Test --- iguana/exchanges/LP_socket.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/iguana/exchanges/LP_socket.c b/iguana/exchanges/LP_socket.c index 00eea5c12..7b4bac8f4 100644 --- a/iguana/exchanges/LP_socket.c +++ b/iguana/exchanges/LP_socket.c @@ -600,7 +600,7 @@ cJSON *electrum_address_listunspent(char *symbol,struct electrum_info *ep,cJSON { if ( jobj(retjson,"error") == 0 && is_cJSON_Array(retjson) != 0 ) { - //if ( 0 && electrumflag > 1 ) + if ( 0 && electrumflag > 1 ) printf("%s.%d u.%u/%d t.%ld %s LISTUNSPENT.(%d)\n",coin->symbol,height,ap->unspenttime,ap->unspentheight,time(NULL),addr,(int32_t)strlen(jprint(retjson,0))); updatedflag = 0; if ( electrum_process_array(coin,ep,addr,retjson,electrumflag) != 0 ) From de8c4145d80a0f7fcce3e1348a68dc748dc2dc96 Mon Sep 17 00:00:00 2001 From: jl777 Date: Fri, 10 Nov 2017 23:48:45 +0200 Subject: [PATCH 0546/1664] Test --- iguana/exchanges/LP_cache.c | 2 +- iguana/exchanges/LP_nativeDEX.c | 5 +++-- iguana/exchanges/LP_socket.c | 2 +- 3 files changed, 5 insertions(+), 4 deletions(-) diff --git a/iguana/exchanges/LP_cache.c b/iguana/exchanges/LP_cache.c index b0c59611f..c66957bd1 100644 --- a/iguana/exchanges/LP_cache.c +++ b/iguana/exchanges/LP_cache.c @@ -93,7 +93,7 @@ void LP_SPV_store(struct iguana_info *coin,bits256 txid,int32_t height) sprintf(fname,"%s/UNSPENTS/%s.SPV",GLOBAL_DBDIR,coin->symbol), OS_portable_path(fname); if ( (fp= OS_appendfile(fname)) != 0 ) { - //char str[65]; printf("store %s %s.[%d]\n",coin->symbol,bits256_str(str,txid),tx->len); + char str[65]; printf("store %s %s.[%d]\n",coin->symbol,bits256_str(str,txid),tx->len); fwrite(&tx->txid,1,sizeof(tx->txid),fp); fwrite(&tx->len,1,sizeof(tx->len),fp); fwrite(&tx->height,1,sizeof(tx->height),fp); diff --git a/iguana/exchanges/LP_nativeDEX.c b/iguana/exchanges/LP_nativeDEX.c index 49eca0745..f6f1725d4 100644 --- a/iguana/exchanges/LP_nativeDEX.c +++ b/iguana/exchanges/LP_nativeDEX.c @@ -467,7 +467,7 @@ void utxosQ_loop(void *myipaddr) void LP_coinsloop(void *_coins) { - struct LP_address *ap=0; 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; 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; if ( strcmp("BTC",coins) == 0 ) { strcpy(LP_coinsloopBTC_stats.name,"BTC coin loop"); @@ -515,7 +515,8 @@ void LP_coinsloop(void *_coins) { if ( (backupep= ep->prev) == 0 ) backupep = ep; - if ( (ap= LP_addressfind(coin,coin->smartaddr)) != 0 ) + HASH_ITER(hh,coin->addresses,ap,atmp) + //if ( (ap= LP_addressfind(coin,coin->smartaddr)) != 0 ) { DL_FOREACH_SAFE(ap->utxos,up,tmp) { diff --git a/iguana/exchanges/LP_socket.c b/iguana/exchanges/LP_socket.c index 7b4bac8f4..52dc27212 100644 --- a/iguana/exchanges/LP_socket.c +++ b/iguana/exchanges/LP_socket.c @@ -416,7 +416,7 @@ cJSON *electrum_submit(char *symbol,struct electrum_info *ep,cJSON **retjsonp,ch { *retjsonp = 0; sprintf(stratumreq,"{ \"jsonrpc\":\"2.0\", \"id\": %u, \"method\":\"%s\", \"params\": %s }\n",ep->stratumid,method,params); -//printf("%s %s",symbol,stratumreq); +printf("%s %s",symbol,stratumreq); memset(ep->buf,0,ep->bufsize); sitem = electrum_sitem(ep,stratumreq,timeout,retjsonp); /*sitem = (struct stritem *)queueitem(stratumreq); From 017ac281a2086ef688cfa632ed7f09984e482e82 Mon Sep 17 00:00:00 2001 From: jl777 Date: Fri, 10 Nov 2017 23:53:43 +0200 Subject: [PATCH 0547/1664] Test --- iguana/exchanges/LP_cache.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/iguana/exchanges/LP_cache.c b/iguana/exchanges/LP_cache.c index c66957bd1..4be0a5fc5 100644 --- a/iguana/exchanges/LP_cache.c +++ b/iguana/exchanges/LP_cache.c @@ -100,7 +100,7 @@ void LP_SPV_store(struct iguana_info *coin,bits256 txid,int32_t height) fwrite(tx->serialized,1,tx->len,fp); fclose(fp); } - } + } else printf("cant store tx.%p len.%d\n",tx,tx!=0?tx->len:0); } int32_t LP_cacheitem(struct iguana_info *coin,FILE *fp) @@ -245,7 +245,7 @@ int32_t LP_merkleproof(struct iguana_info *coin,struct electrum_info *ep,bits256 if ( tx != 0 ) tx->SPV = height; LP_SPV_store(coin,txid,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)); + printf("validated MERK %s ht.%d -> %s root.(%s)\n",bits256_str(str,txid),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)); } else SPV = 0; From 96b6a1fc505db4233325a47e7bc22824e2713010 Mon Sep 17 00:00:00 2001 From: jl777 Date: Fri, 10 Nov 2017 23:58:18 +0200 Subject: [PATCH 0548/1664] Test --- iguana/exchanges/LP_cache.c | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/iguana/exchanges/LP_cache.c b/iguana/exchanges/LP_cache.c index 4be0a5fc5..f95b1bb28 100644 --- a/iguana/exchanges/LP_cache.c +++ b/iguana/exchanges/LP_cache.c @@ -225,8 +225,13 @@ bits256 LP_merkleroot(struct iguana_info *coin,struct electrum_info *ep,int32_t int32_t LP_merkleproof(struct iguana_info *coin,struct electrum_info *ep,bits256 txid,int32_t height) { - struct LP_transaction *tx=0; cJSON *merkobj,*merkles; bits256 roothash,merkleroot; int32_t m,SPV = 0; - if ( (tx= LP_transactionfind(coin,txid)) != 0 && tx->height == height && tx->SPV > 0 ) + struct LP_transaction *tx=0; cJSON *merkobj,*merkles,*retjson; bits256 roothash,merkleroot; int32_t m,SPV = 0; + if ( (tx= LP_transactionfind(coin,txid)) == 0) + { + if ( (retjson= electrum_transaction(coin->symbol,ep,&retjson,txid)) != 0 ) + free_json(retjson); + } + if ( tx != 0 && tx->height == height && tx->SPV > 0 ) return(tx->SPV); if ( (merkobj= electrum_getmerkle(coin->symbol,ep,&merkobj,txid,height)) != 0 ) { From 6a8ec0cda2071c1cbd6bbdcca0c0a0357bf40c5c Mon Sep 17 00:00:00 2001 From: jl777 Date: Sat, 11 Nov 2017 00:01:43 +0200 Subject: [PATCH 0549/1664] Test --- iguana/exchanges/LP_cache.c | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/iguana/exchanges/LP_cache.c b/iguana/exchanges/LP_cache.c index f95b1bb28..14c7b178d 100644 --- a/iguana/exchanges/LP_cache.c +++ b/iguana/exchanges/LP_cache.c @@ -87,20 +87,19 @@ cJSON *LP_create_transaction(struct iguana_info *coin,bits256 txid,uint8_t *seri void LP_SPV_store(struct iguana_info *coin,bits256 txid,int32_t height) { - FILE *fp; char fname[512]; struct LP_transaction *tx = 0; + FILE *fp; char fname[512],str[65]; struct LP_transaction *tx = 0; if ( (tx= LP_transactionfind(coin,txid)) != 0 && tx->serialized != 0 && tx->len > 0 ) { sprintf(fname,"%s/UNSPENTS/%s.SPV",GLOBAL_DBDIR,coin->symbol), OS_portable_path(fname); if ( (fp= OS_appendfile(fname)) != 0 ) { - char str[65]; printf("store %s %s.[%d]\n",coin->symbol,bits256_str(str,txid),tx->len); fwrite(&tx->txid,1,sizeof(tx->txid),fp); fwrite(&tx->len,1,sizeof(tx->len),fp); fwrite(&tx->height,1,sizeof(tx->height),fp); fwrite(tx->serialized,1,tx->len,fp); fclose(fp); } - } else printf("cant store tx.%p len.%d\n",tx,tx!=0?tx->len:0); + } else printf("cant store %s %s tx.%p [%d]\n",coin->symbol,bits256_str(str,txid),tx,tx!=0?tx->len:-1); } int32_t LP_cacheitem(struct iguana_info *coin,FILE *fp) From f0115d14148f285012679902534e34e6b0f0ade9 Mon Sep 17 00:00:00 2001 From: jl777 Date: Sat, 11 Nov 2017 00:02:12 +0200 Subject: [PATCH 0550/1664] Test --- iguana/exchanges/LP_cache.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/iguana/exchanges/LP_cache.c b/iguana/exchanges/LP_cache.c index 14c7b178d..81f2592ec 100644 --- a/iguana/exchanges/LP_cache.c +++ b/iguana/exchanges/LP_cache.c @@ -249,7 +249,7 @@ int32_t LP_merkleproof(struct iguana_info *coin,struct electrum_info *ep,bits256 if ( tx != 0 ) tx->SPV = height; LP_SPV_store(coin,txid,height); - printf("validated MERK %s ht.%d -> %s root.(%s)\n",bits256_str(str,txid),height,jprint(merkobj,0),bits256_str(str2,roothash)); + //printf("validated MERK %s ht.%d -> %s root.(%s)\n",bits256_str(str,txid),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)); } else SPV = 0; From 890b5fe5a05223ae06dfe0ffac2cc14113efb00e Mon Sep 17 00:00:00 2001 From: jl777 Date: Sat, 11 Nov 2017 00:06:13 +0200 Subject: [PATCH 0551/1664] Test --- iguana/exchanges/LP_socket.c | 11 ++--------- 1 file changed, 2 insertions(+), 9 deletions(-) diff --git a/iguana/exchanges/LP_socket.c b/iguana/exchanges/LP_socket.c index 52dc27212..92e0e5589 100644 --- a/iguana/exchanges/LP_socket.c +++ b/iguana/exchanges/LP_socket.c @@ -416,7 +416,7 @@ cJSON *electrum_submit(char *symbol,struct electrum_info *ep,cJSON **retjsonp,ch { *retjsonp = 0; sprintf(stratumreq,"{ \"jsonrpc\":\"2.0\", \"id\": %u, \"method\":\"%s\", \"params\": %s }\n",ep->stratumid,method,params); -printf("%s %s",symbol,stratumreq); +//printf("%s %s",symbol,stratumreq); memset(ep->buf,0,ep->bufsize); sitem = electrum_sitem(ep,stratumreq,timeout,retjsonp); /*sitem = (struct stritem *)queueitem(stratumreq); @@ -743,19 +743,12 @@ cJSON *_electrum_transaction(char *symbol,struct electrum_info *ep,cJSON **retjs cJSON *electrum_transaction(char *symbol,struct electrum_info *ep,cJSON **retjsonp,bits256 txid) { - cJSON *retjson; //struct iguana_info *coin; struct LP_transaction *tx; + cJSON *retjson; if ( ep != 0 ) portable_mutex_lock(&ep->txmutex); retjson = _electrum_transaction(symbol,ep,retjsonp,txid); if ( ep != 0 ) portable_mutex_unlock(&ep->txmutex); - /*if ( ep != 0 && (coin= LP_coinfind(symbol)) != 0 && (tx= LP_transactionfind(coin,txid)) != 0 && tx->SPV <= 0 ) // we just dont have height! - { - if ( tx->height == 0 ) - tx->height = LP_gettxheight(coin,txid); - LP_merkleproof(coin,ep,txid,tx->height); - printf("extra merkle\n"); - }*/ return(retjson); } From 8867693aa0e908dc6db2cae330c77e67e0d81eb1 Mon Sep 17 00:00:00 2001 From: jl777 Date: Sat, 11 Nov 2017 00:12:06 +0200 Subject: [PATCH 0552/1664] Test --- iguana/exchanges/LP_nativeDEX.c | 12 +++++++++--- iguana/exchanges/LP_utxo.c | 7 +++++-- 2 files changed, 14 insertions(+), 5 deletions(-) diff --git a/iguana/exchanges/LP_nativeDEX.c b/iguana/exchanges/LP_nativeDEX.c index f6f1725d4..8af912800 100644 --- a/iguana/exchanges/LP_nativeDEX.c +++ b/iguana/exchanges/LP_nativeDEX.c @@ -467,7 +467,7 @@ void utxosQ_loop(void *myipaddr) void LP_coinsloop(void *_coins) { - struct LP_address *ap=0,*atmp; 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 oldht,j,nonz; char *coins = _coins; if ( strcmp("BTC",coins) == 0 ) { strcpy(LP_coinsloopBTC_stats.name,"BTC coin loop"); @@ -526,8 +526,14 @@ void LP_coinsloop(void *_coins) { nonz++; up->SPV = LP_merkleproof(coin,backupep,up->U.txid,up->U.height); - if ( 0 && up->SPV > 0 ) - printf("%s %s: SPV.%d\n",coin->symbol,bits256_str(str,up->U.txid),up->SPV); + if ( up->SPV > 0 ) + { + if ( (tx= LP_transactionfind(coin,up->U.txid)) != 0 && tx->SPV == 0 ) + { + tx->SPV = up->SPV; + printf("%s %s: SPV.%d\n",coin->symbol,bits256_str(str,up->U.txid),up->SPV); + } + } } else if ( up->SPV == -1 ) { diff --git a/iguana/exchanges/LP_utxo.c b/iguana/exchanges/LP_utxo.c index ce98ac396..9674cece5 100644 --- a/iguana/exchanges/LP_utxo.c +++ b/iguana/exchanges/LP_utxo.c @@ -237,7 +237,7 @@ void LP_mark_spent(char *symbol,bits256 txid,int32_t vout) int32_t LP_address_utxoadd(char *debug,struct iguana_info *coin,char *coinaddr,bits256 txid,int32_t vout,uint64_t value,int32_t height,int32_t spendheight) { - struct LP_address *ap; cJSON *txobj; struct LP_address_utxo *up,*tmp; int32_t flag,retval = 0; char str[65]; + struct LP_address *ap; cJSON *txobj; struct LP_transaction *tx; struct LP_address_utxo *up,*tmp; int32_t flag,retval = 0; char str[65]; if ( coin == 0 ) return(0); if ( spendheight > 0 ) // dont autocreate entries for spends we dont care about @@ -282,8 +282,11 @@ int32_t LP_address_utxoadd(char *debug,struct iguana_info *coin,char *coinaddr,b DL_APPEND(ap->utxos,up); portable_mutex_unlock(&coin->addrmutex); retval = 1; - if ( value == 0 ) + if ( (tx= LP_transactionfind(coin,txid)) != 0 && tx->SPV > 0 ) + { + up->SPV = tx->SPV; printf("%s ADD UTXO >> %s %s %s/v%d ht.%d %.8f\n",debug,coin->symbol,coinaddr,bits256_str(str,txid),vout,height,dstr(value)); + } } } // else printf("cant get ap %s %s\n",coin->symbol,coinaddr); //printf("done %s add addr.%s ht.%d\n",coin->symbol,coinaddr,height); From f20efd48adae1aa1a28b660cd9f6b0b247707471 Mon Sep 17 00:00:00 2001 From: jl777 Date: Sat, 11 Nov 2017 00:16:27 +0200 Subject: [PATCH 0553/1664] Test --- iguana/exchanges/LP_cache.c | 2 ++ iguana/exchanges/LP_nativeDEX.c | 2 +- 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/iguana/exchanges/LP_cache.c b/iguana/exchanges/LP_cache.c index 81f2592ec..5230bc9cd 100644 --- a/iguana/exchanges/LP_cache.c +++ b/iguana/exchanges/LP_cache.c @@ -225,6 +225,8 @@ bits256 LP_merkleroot(struct iguana_info *coin,struct electrum_info *ep,int32_t int32_t LP_merkleproof(struct iguana_info *coin,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; + if ( height < 0 ) + return(0); if ( (tx= LP_transactionfind(coin,txid)) == 0) { if ( (retjson= electrum_transaction(coin->symbol,ep,&retjson,txid)) != 0 ) diff --git a/iguana/exchanges/LP_nativeDEX.c b/iguana/exchanges/LP_nativeDEX.c index 8af912800..36e98a96a 100644 --- a/iguana/exchanges/LP_nativeDEX.c +++ b/iguana/exchanges/LP_nativeDEX.c @@ -531,7 +531,7 @@ void LP_coinsloop(void *_coins) if ( (tx= LP_transactionfind(coin,up->U.txid)) != 0 && tx->SPV == 0 ) { tx->SPV = up->SPV; - printf("%s %s: SPV.%d\n",coin->symbol,bits256_str(str,up->U.txid),up->SPV); + //printf("%s %s: SPV.%d\n",coin->symbol,bits256_str(str,up->U.txid),up->SPV); } } } From bf0c22ea0e22e246c7372a67784ac43678c30d14 Mon Sep 17 00:00:00 2001 From: jl777 Date: Sat, 11 Nov 2017 00:16:54 +0200 Subject: [PATCH 0554/1664] Test --- iguana/exchanges/LP_utxo.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/iguana/exchanges/LP_utxo.c b/iguana/exchanges/LP_utxo.c index 9674cece5..b76413ee5 100644 --- a/iguana/exchanges/LP_utxo.c +++ b/iguana/exchanges/LP_utxo.c @@ -285,7 +285,7 @@ int32_t LP_address_utxoadd(char *debug,struct iguana_info *coin,char *coinaddr,b if ( (tx= LP_transactionfind(coin,txid)) != 0 && tx->SPV > 0 ) { up->SPV = tx->SPV; - printf("%s ADD UTXO >> %s %s %s/v%d ht.%d %.8f\n",debug,coin->symbol,coinaddr,bits256_str(str,txid),vout,height,dstr(value)); + //printf("%s ADD UTXO >> %s %s %s/v%d ht.%d %.8f\n",debug,coin->symbol,coinaddr,bits256_str(str,txid),vout,height,dstr(value)); } } } // else printf("cant get ap %s %s\n",coin->symbol,coinaddr); From 907de285bf3f5f14a1ccaa66784bd1f2964be0d9 Mon Sep 17 00:00:00 2001 From: jl777 Date: Sat, 11 Nov 2017 00:22:46 +0200 Subject: [PATCH 0555/1664] Test --- iguana/exchanges/LP_cache.c | 2 +- iguana/exchanges/LP_ordermatch.c | 2 +- iguana/exchanges/LP_socket.c | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/iguana/exchanges/LP_cache.c b/iguana/exchanges/LP_cache.c index 5230bc9cd..999f2c0cd 100644 --- a/iguana/exchanges/LP_cache.c +++ b/iguana/exchanges/LP_cache.c @@ -149,7 +149,7 @@ void LP_cacheptrs_init(struct iguana_info *coin) } printf("loaded %s %d entries total len.%ld\n",fname,count,len); fclose(fp); - } else printf("couldnt find.(%s)\n",fname); + } //else printf("couldnt find.(%s)\n",fname); if ( tflag != 0 ) OS_truncate(fname,len); } diff --git a/iguana/exchanges/LP_ordermatch.c b/iguana/exchanges/LP_ordermatch.c index c04beef58..9cd07e134 100644 --- a/iguana/exchanges/LP_ordermatch.c +++ b/iguana/exchanges/LP_ordermatch.c @@ -649,7 +649,7 @@ int32_t LP_validSPV(char *symbol,char *coinaddr,bits256 txid,int32_t vout) backupep = ep; up->SPV = LP_merkleproof(coin,backupep,up->U.txid,up->U.height); if ( up->SPV <= 0 ) - return(-1); + return(up->SPV); } } return(0); diff --git a/iguana/exchanges/LP_socket.c b/iguana/exchanges/LP_socket.c index 92e0e5589..7e3a9e22c 100644 --- a/iguana/exchanges/LP_socket.c +++ b/iguana/exchanges/LP_socket.c @@ -1047,7 +1047,7 @@ cJSON *LP_electrumserver(struct iguana_info *coin,char *ipaddr,uint16_t port) } else { - printf("launched %s electrum.(%s:%u)\n",coin->symbol,ep->ipaddr,ep->port); + //printf("launched %s electrum.(%s:%u)\n",coin->symbol,ep->ipaddr,ep->port); jaddstr(retjson,"result","success"); ep->prev = coin->electrum; coin->electrum = ep; From 61d48edc8b5bd711a9935ad22eb95ad8e761e18d Mon Sep 17 00:00:00 2001 From: jl777 Date: Sat, 11 Nov 2017 00:24:03 +0200 Subject: [PATCH 0556/1664] Test --- iguana/exchanges/LP_ordermatch.c | 42 ++++++++++++++++---------------- 1 file changed, 21 insertions(+), 21 deletions(-) diff --git a/iguana/exchanges/LP_ordermatch.c b/iguana/exchanges/LP_ordermatch.c index 9cd07e134..17dc752ef 100644 --- a/iguana/exchanges/LP_ordermatch.c +++ b/iguana/exchanges/LP_ordermatch.c @@ -649,7 +649,7 @@ int32_t LP_validSPV(char *symbol,char *coinaddr,bits256 txid,int32_t vout) backupep = ep; up->SPV = LP_merkleproof(coin,backupep,up->U.txid,up->U.height); if ( up->SPV <= 0 ) - return(up->SPV); + return(-1); } } return(0); @@ -666,30 +666,20 @@ int32_t LP_tradecommand(void *ctx,char *myipaddr,int32_t pubsock,cJSON *argjson, LP_tradecommand_log(argjson); //printf("LP_tradecommand: check received method %s aliceid.%llx\n",method,(long long)Q.aliceid); retval = 1; - if ( LP_validSPV(Q.destcoin,Q.destaddr,Q.desttxid,Q.destvout) < 0 ) - { - printf("%s dest %s failed SPV check\n",Q.destcoin,bits256_str(str,Q.desttxid)); - return(retval); - } - else if (LP_validSPV(Q.destcoin,Q.destaddr,Q.feetxid,Q.feevout) < 0 ) - { - printf("%s dexfee %s failed SPV check\n",Q.destcoin,bits256_str(str,Q.feetxid)); - return(retval); - } if ( strcmp(method,"reserved") == 0 ) { - if ( LP_validSPV(Q.srccoin,Q.coinaddr,Q.txid,Q.vout) < 0 ) - { - printf("%s src %s failed SPV check\n",Q.srccoin,bits256_str(str,Q.txid)); - return(retval); - } - else if (LP_validSPV(Q.srccoin,Q.coinaddr,Q.txid2,Q.vout2) < 0 ) - { - printf("%s src2 %s failed SPV check\n",Q.srccoin,bits256_str(str,Q.txid2)); - return(retval); - } if ( bits256_cmp(G.LP_mypub25519,Q.desthash) == 0 && bits256_cmp(G.LP_mypub25519,Q.srchash) != 0 && LP_alice_eligible() > 0 ) { + if ( LP_validSPV(Q.srccoin,Q.coinaddr,Q.txid,Q.vout) < 0 ) + { + printf("%s src %s failed SPV check\n",Q.srccoin,bits256_str(str,Q.txid)); + return(retval); + } + else if (LP_validSPV(Q.srccoin,Q.coinaddr,Q.txid2,Q.vout2) < 0 ) + { + printf("%s src2 %s failed SPV check\n",Q.srccoin,bits256_str(str,Q.txid2)); + return(retval); + } LP_aliceid(Q.tradeid,Q.aliceid,"reserved",0,0); printf("alice %s received RESERVED.(%s)\n",bits256_str(str,G.LP_mypub25519),jprint(argjson,0)); if ( (retstr= LP_quotereceived(argjson)) != 0 ) @@ -725,6 +715,16 @@ int32_t LP_tradecommand(void *ctx,char *myipaddr,int32_t pubsock,cJSON *argjson, printf("this node has no price for %s/%s\n",Q.srccoin,Q.destcoin); return(retval); } + if ( LP_validSPV(Q.destcoin,Q.destaddr,Q.desttxid,Q.destvout) < 0 ) + { + printf("%s dest %s failed SPV check\n",Q.destcoin,bits256_str(str,Q.desttxid)); + return(retval); + } + else if (LP_validSPV(Q.destcoin,Q.destaddr,Q.feetxid,Q.feevout) < 0 ) + { + printf("%s dexfee %s failed SPV check\n",Q.destcoin,bits256_str(str,Q.feetxid)); + return(retval); + } price = ask; /*if ( coin->electrum != 0 ) { From 41d03240ce12864c70753f52d7143b6776c9624a Mon Sep 17 00:00:00 2001 From: jl777 Date: Sat, 11 Nov 2017 11:07:06 +0200 Subject: [PATCH 0557/1664] Test --- iguana/exchanges/LP_cache.c | 17 ++++++++++++++--- 1 file changed, 14 insertions(+), 3 deletions(-) diff --git a/iguana/exchanges/LP_cache.c b/iguana/exchanges/LP_cache.c index 999f2c0cd..3da97708d 100644 --- a/iguana/exchanges/LP_cache.c +++ b/iguana/exchanges/LP_cache.c @@ -43,8 +43,9 @@ cJSON *LP_create_transaction(struct iguana_info *coin,bits256 txid,uint8_t *seri vins = jarray(&numvins,txobj,"vin"); vouts = jarray(&numvouts,txobj,"vout"); tx = LP_transactionadd(coin,txid,height,numvouts,numvins); - tx->serialized = serialized; - tx->len = len; + tx->serialized = 0; + free(serialized); + tx->len = 0; tx->SPV = tx->height = height; //printf("tx.%p vins.(%s) vouts.(%s)\n",tx,jprint(vins,0),jprint(vouts,0)); for (i=0; i Date: Sat, 11 Nov 2017 11:12:43 +0200 Subject: [PATCH 0558/1664] Test --- iguana/exchanges/LP_cache.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/iguana/exchanges/LP_cache.c b/iguana/exchanges/LP_cache.c index 3da97708d..caad5d3aa 100644 --- a/iguana/exchanges/LP_cache.c +++ b/iguana/exchanges/LP_cache.c @@ -45,7 +45,7 @@ cJSON *LP_create_transaction(struct iguana_info *coin,bits256 txid,uint8_t *seri tx = LP_transactionadd(coin,txid,height,numvouts,numvins); tx->serialized = 0; free(serialized); - tx->len = 0; + tx->len = -tx->len; tx->SPV = tx->height = height; //printf("tx.%p vins.(%s) vouts.(%s)\n",tx,jprint(vins,0),jprint(vouts,0)); for (i=0; iSPV = height; + printf("tx len.%d ht.%d %d\n",tx->len,tx->height,height); + } LP_SPV_store(coin,txid,height); //printf("validated MERK %s ht.%d -> %s root.(%s)\n",bits256_str(str,txid),height,jprint(merkobj,0),bits256_str(str2,roothash)); } From eae2f9da52a546106de70cceb7c34ad642d6cfd3 Mon Sep 17 00:00:00 2001 From: jl777 Date: Sat, 11 Nov 2017 11:16:44 +0200 Subject: [PATCH 0559/1664] Test --- iguana/exchanges/LP_cache.c | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/iguana/exchanges/LP_cache.c b/iguana/exchanges/LP_cache.c index caad5d3aa..c27129bbc 100644 --- a/iguana/exchanges/LP_cache.c +++ b/iguana/exchanges/LP_cache.c @@ -109,8 +109,6 @@ int32_t LP_cacheitem(struct iguana_info *coin,FILE *fp) fpos = ftell(fp); if ( fread(&txid,1,sizeof(txid),fp) == sizeof(txid) && fread(&len,1,sizeof(len),fp) == sizeof(len) && fread(&height,1,sizeof(height),fp) == sizeof(height) && len < 100000 ) { - if ( len < 4096 ) - { serialized = malloc(len); if ( (retval= (int32_t)fread(serialized,1,len,fp)) == len ) { @@ -124,14 +122,14 @@ int32_t LP_cacheitem(struct iguana_info *coin,FILE *fp) } printf("%s vs %s did not validated in cache\n",bits256_str(str,hash),bits256_str(str2,txid)); } else printf("retval.%d vs len.%d\n",retval,len); - } + /*} else { printf("warning: big cachelen.%d\n",len); for (i=0; isymbol,ep,&retjson,txid)) != 0 ) free_json(retjson); } + tx->height = height; if ( tx != 0 && tx->height == height && tx->SPV > 0 ) return(tx->SPV); if ( (merkobj= electrum_getmerkle(coin->symbol,ep,&merkobj,txid,height)) != 0 ) From ed728730f507ed03d5c924c1dc32da2952ecefbf Mon Sep 17 00:00:00 2001 From: jl777 Date: Sat, 11 Nov 2017 11:22:58 +0200 Subject: [PATCH 0560/1664] Test --- iguana/exchanges/LP_cache.c | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) diff --git a/iguana/exchanges/LP_cache.c b/iguana/exchanges/LP_cache.c index c27129bbc..f460d7b2f 100644 --- a/iguana/exchanges/LP_cache.c +++ b/iguana/exchanges/LP_cache.c @@ -105,7 +105,7 @@ void LP_SPV_store(struct iguana_info *coin,bits256 txid,int32_t height) int32_t LP_cacheitem(struct iguana_info *coin,FILE *fp) { - bits256 txid,hash; long fpos; int32_t i,retval,height,len; uint8_t *serialized; cJSON *txobj; char str[65],str2[65]; + bits256 txid,hash; long fpos; int32_t retval,height,len; uint8_t *serialized; cJSON *txobj; char str[65],str2[65]; fpos = ftell(fp); if ( fread(&txid,1,sizeof(txid),fp) == sizeof(txid) && fread(&len,1,sizeof(len),fp) == sizeof(len) && fread(&height,1,sizeof(height),fp) == sizeof(height) && len < 100000 ) { @@ -241,9 +241,12 @@ int32_t LP_merkleproof(struct iguana_info *coin,struct electrum_info *ep,bits256 if ( (retjson= electrum_transaction(coin->symbol,ep,&retjson,txid)) != 0 ) free_json(retjson); } - tx->height = height; - if ( tx != 0 && tx->height == height && tx->SPV > 0 ) - return(tx->SPV); + if ( tx != 0 ) + { + tx->height = height; + if ( tx->SPV > 0 ) + return(tx->SPV); + } if ( (merkobj= electrum_getmerkle(coin->symbol,ep,&merkobj,txid,height)) != 0 ) { char str[65],str2[65],str3[65]; From 7027afa6bc06162ae19785fe779a64526ec08fdf Mon Sep 17 00:00:00 2001 From: jl777 Date: Sat, 11 Nov 2017 11:33:01 +0200 Subject: [PATCH 0561/1664] Test --- iguana/exchanges/LP_cache.c | 22 +++++++++------------- iguana/exchanges/LP_include.h | 1 + 2 files changed, 10 insertions(+), 13 deletions(-) diff --git a/iguana/exchanges/LP_cache.c b/iguana/exchanges/LP_cache.c index f460d7b2f..f9cc747a2 100644 --- a/iguana/exchanges/LP_cache.c +++ b/iguana/exchanges/LP_cache.c @@ -35,7 +35,7 @@ cJSON *LP_transaction_fromdata(struct iguana_info *coin,bits256 txid,uint8_t *se return(txobj); } -cJSON *LP_create_transaction(struct iguana_info *coin,bits256 txid,uint8_t *serialized,int32_t len,int32_t height) +cJSON *LP_create_transaction(struct iguana_info *coin,bits256 txid,uint8_t *serialized,int32_t len,int32_t height,long fpos) { cJSON *txobj; bits256 spenttxid; int32_t i,spentvout,numvins,numvouts; cJSON *vout,*vin,*vins,*vouts; struct LP_transaction *tx; char str[65]; if ( (txobj= LP_transaction_fromdata(coin,txid,serialized,len)) != 0 ) @@ -44,8 +44,9 @@ cJSON *LP_create_transaction(struct iguana_info *coin,bits256 txid,uint8_t *seri vouts = jarray(&numvouts,txobj,"vout"); tx = LP_transactionadd(coin,txid,height,numvouts,numvins); tx->serialized = 0; + tx->fpos = fpos; free(serialized); - tx->len = -tx->len; + tx->len = tx->len; tx->SPV = tx->height = height; //printf("tx.%p vins.(%s) vouts.(%s)\n",tx,jprint(vins,0),jprint(vouts,0)); for (i=0; itxid,1,sizeof(tx->txid),fp); fwrite(&tx->len,1,sizeof(tx->len),fp); fwrite(&tx->height,1,sizeof(tx->height),fp); + tx->fpos = ftell(fp); fwrite(tx->serialized,1,tx->len,fp); fclose(fp); } - } else printf("cant store %s %s tx.%p [%d]\n",coin->symbol,bits256_str(str,txid),tx,tx!=0?tx->len:-1); + } + else printf("cant store %s %s tx.%p [%d] fpos.%ld\n",coin->symbol,bits256_str(str,txid),tx,tx!=0?tx->len:-1,tx!=0?tx->fpos:-1); } int32_t LP_cacheitem(struct iguana_info *coin,FILE *fp) { - bits256 txid,hash; long fpos; int32_t retval,height,len; uint8_t *serialized; cJSON *txobj; char str[65],str2[65]; + bits256 txid,hash; long fpos; int32_t offset,retval,height,len; uint8_t *serialized; cJSON *txobj; char str[65],str2[65]; fpos = ftell(fp); if ( fread(&txid,1,sizeof(txid),fp) == sizeof(txid) && fread(&len,1,sizeof(len),fp) == sizeof(len) && fread(&height,1,sizeof(height),fp) == sizeof(height) && len < 100000 ) { + offset = (int32_t)(sizeof(txid) + sizeof(len) + sizeof(height)); serialized = malloc(len); if ( (retval= (int32_t)fread(serialized,1,len,fp)) == len ) { @@ -116,20 +120,12 @@ int32_t LP_cacheitem(struct iguana_info *coin,FILE *fp) if ( bits256_cmp(hash,txid) == 0 ) { //printf("%s validated in cache\n",bits256_str(str,hash)); - if ( (txobj= LP_create_transaction(coin,txid,serialized,len,height)) != 0 ) + if ( (txobj= LP_create_transaction(coin,txid,serialized,len,height,fpos+offset)) != 0 ) free_json(txobj); return((int32_t)(ftell(fp) - fpos)); } printf("%s vs %s did not validated in cache\n",bits256_str(str,hash),bits256_str(str2,txid)); } else printf("retval.%d vs len.%d\n",retval,len); - /*} - else - { - printf("warning: big cachelen.%d\n",len); - for (i=0; i Date: Sat, 11 Nov 2017 11:35:00 +0200 Subject: [PATCH 0562/1664] Test --- iguana/exchanges/LP_cache.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/iguana/exchanges/LP_cache.c b/iguana/exchanges/LP_cache.c index f9cc747a2..b7231c95d 100644 --- a/iguana/exchanges/LP_cache.c +++ b/iguana/exchanges/LP_cache.c @@ -103,7 +103,7 @@ void LP_SPV_store(struct iguana_info *coin,bits256 txid,int32_t height) fclose(fp); } } - else printf("cant store %s %s tx.%p [%d] fpos.%ld\n",coin->symbol,bits256_str(str,txid),tx,tx!=0?tx->len:-1,tx!=0?tx->fpos:-1); + else printf("cant store %s %s tx.%p [%d] fpos.%ld SPV.%d\n",coin->symbol,bits256_str(str,txid),tx,tx!=0?tx->len:-1,tx!=0?tx->fpos:-1,tx!=0?tx->SPV:-1); } int32_t LP_cacheitem(struct iguana_info *coin,FILE *fp) From 721dd9c23dca50202eaf987ef8980ecb537ad87f Mon Sep 17 00:00:00 2001 From: jl777 Date: Sat, 11 Nov 2017 11:37:01 +0200 Subject: [PATCH 0563/1664] Test --- iguana/exchanges/LP_cache.c | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/iguana/exchanges/LP_cache.c b/iguana/exchanges/LP_cache.c index b7231c95d..1c38e1edc 100644 --- a/iguana/exchanges/LP_cache.c +++ b/iguana/exchanges/LP_cache.c @@ -257,12 +257,9 @@ int32_t LP_merkleproof(struct iguana_info *coin,struct electrum_info *ep,bits256 if ( bits256_cmp(merkleroot,roothash) == 0 ) { SPV = height; + LP_SPV_store(coin,txid,height); if ( tx != 0 ) - { tx->SPV = height; - printf("tx len.%d ht.%d %d\n",tx->len,tx->height,height); - } - LP_SPV_store(coin,txid,height); //printf("validated MERK %s ht.%d -> %s root.(%s)\n",bits256_str(str,txid),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)); From e34415eed0e28015d195f6307485e07df1eea0d3 Mon Sep 17 00:00:00 2001 From: jl777 Date: Sat, 11 Nov 2017 11:40:48 +0200 Subject: [PATCH 0564/1664] Test --- iguana/exchanges/LP_nativeDEX.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/iguana/exchanges/LP_nativeDEX.c b/iguana/exchanges/LP_nativeDEX.c index 36e98a96a..989d3d384 100644 --- a/iguana/exchanges/LP_nativeDEX.c +++ b/iguana/exchanges/LP_nativeDEX.c @@ -515,8 +515,8 @@ void LP_coinsloop(void *_coins) { if ( (backupep= ep->prev) == 0 ) backupep = ep; - HASH_ITER(hh,coin->addresses,ap,atmp) - //if ( (ap= LP_addressfind(coin,coin->smartaddr)) != 0 ) + //HASH_ITER(hh,coin->addresses,ap,atmp) + if ( (ap= LP_addressfind(coin,coin->smartaddr)) != 0 ) { DL_FOREACH_SAFE(ap->utxos,up,tmp) { From e66a42da1b4f10a6dd2af329e13b5e6b208778e3 Mon Sep 17 00:00:00 2001 From: jl777 Date: Sat, 11 Nov 2017 11:44:41 +0200 Subject: [PATCH 0565/1664] Test --- iguana/exchanges/LP_nativeDEX.c | 4 ++-- iguana/exchanges/LP_utxo.c | 6 ++++-- 2 files changed, 6 insertions(+), 4 deletions(-) diff --git a/iguana/exchanges/LP_nativeDEX.c b/iguana/exchanges/LP_nativeDEX.c index 989d3d384..36e98a96a 100644 --- a/iguana/exchanges/LP_nativeDEX.c +++ b/iguana/exchanges/LP_nativeDEX.c @@ -515,8 +515,8 @@ void LP_coinsloop(void *_coins) { if ( (backupep= ep->prev) == 0 ) backupep = ep; - //HASH_ITER(hh,coin->addresses,ap,atmp) - if ( (ap= LP_addressfind(coin,coin->smartaddr)) != 0 ) + HASH_ITER(hh,coin->addresses,ap,atmp) + //if ( (ap= LP_addressfind(coin,coin->smartaddr)) != 0 ) { DL_FOREACH_SAFE(ap->utxos,up,tmp) { diff --git a/iguana/exchanges/LP_utxo.c b/iguana/exchanges/LP_utxo.c index b76413ee5..b2263c87e 100644 --- a/iguana/exchanges/LP_utxo.c +++ b/iguana/exchanges/LP_utxo.c @@ -237,7 +237,7 @@ void LP_mark_spent(char *symbol,bits256 txid,int32_t vout) int32_t LP_address_utxoadd(char *debug,struct iguana_info *coin,char *coinaddr,bits256 txid,int32_t vout,uint64_t value,int32_t height,int32_t spendheight) { - struct LP_address *ap; cJSON *txobj; struct LP_transaction *tx; struct LP_address_utxo *up,*tmp; int32_t flag,retval = 0; char str[65]; + struct LP_address *ap; cJSON *txobj; struct LP_transaction *tx; struct LP_address_utxo *up,*tmp; int32_t flag,retval = 0; //char str[65]; if ( coin == 0 ) return(0); if ( spendheight > 0 ) // dont autocreate entries for spends we dont care about @@ -532,13 +532,15 @@ struct LP_transaction *LP_transactionfind(struct iguana_info *coin,bits256 txid) struct LP_transaction *LP_transactionadd(struct iguana_info *coin,bits256 txid,int32_t height,int32_t numvouts,int32_t numvins) { + static long totalsize; struct LP_transaction *tx; int32_t i; if ( (tx= LP_transactionfind(coin,txid)) == 0 ) { - //char str[65]; printf("%s ht.%d u.%u NEW TXID.(%s) vouts.[%d]\n",coin->symbol,height,timestamp,bits256_str(str,txid),numvouts); //if ( bits256_nonz(txid) == 0 && tx->height == 0 ) // getchar(); tx = calloc(1,sizeof(*tx) + (sizeof(*tx->outpoints) * numvouts)); + totalsize += sizeof(*tx) + (sizeof(*tx->outpoints) * numvouts); + char str[65]; printf("%s ht.%d NEW TXID.(%s) vouts.[%d] size.%ld total %ld\n",coin->symbol,height,bits256_str(str,txid),numvouts,sizeof(*tx) + (sizeof(*tx->outpoints) * numvouts),totalsize); for (i=0; ioutpoints[i].spendvini = -1; tx->height = height; From 94723ece6b26d3babe9d8c3480234e60466397af Mon Sep 17 00:00:00 2001 From: jl777 Date: Sat, 11 Nov 2017 11:49:01 +0200 Subject: [PATCH 0566/1664] Test --- iguana/exchanges/LP_cache.c | 2 +- iguana/exchanges/LP_utxo.c | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/iguana/exchanges/LP_cache.c b/iguana/exchanges/LP_cache.c index 1c38e1edc..ee093db2c 100644 --- a/iguana/exchanges/LP_cache.c +++ b/iguana/exchanges/LP_cache.c @@ -48,7 +48,7 @@ cJSON *LP_create_transaction(struct iguana_info *coin,bits256 txid,uint8_t *seri free(serialized); tx->len = tx->len; tx->SPV = tx->height = height; - //printf("tx.%p vins.(%s) vouts.(%s)\n",tx,jprint(vins,0),jprint(vouts,0)); + printf("tx.%s numvins.%d numvouts.%d\n",bits256_str(str,txid),numvins,numvouts); for (i=0; iheight == 0 ) @@ -551,7 +551,7 @@ struct LP_transaction *LP_transactionadd(struct iguana_info *coin,bits256 txid,i portable_mutex_lock(&coin->txmutex); HASH_ADD_KEYPTR(hh,coin->transactions,tx->txid.bytes,sizeof(tx->txid),tx); portable_mutex_unlock(&coin->txmutex); - } // else printf("warning adding already existing txid %s\n",bits256_str(str,tx->txid)); + } else printf("warning adding already existing txid %s\n",bits256_str(str,tx->txid)); return(tx); } From 2b19e9ec44584c472e570bc45b7ce0d77d2a461f Mon Sep 17 00:00:00 2001 From: jl777 Date: Sat, 11 Nov 2017 11:52:11 +0200 Subject: [PATCH 0567/1664] Test --- iguana/exchanges/LP_cache.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/iguana/exchanges/LP_cache.c b/iguana/exchanges/LP_cache.c index ee093db2c..596bc725b 100644 --- a/iguana/exchanges/LP_cache.c +++ b/iguana/exchanges/LP_cache.c @@ -90,7 +90,7 @@ cJSON *LP_create_transaction(struct iguana_info *coin,bits256 txid,uint8_t *seri void LP_SPV_store(struct iguana_info *coin,bits256 txid,int32_t height) { FILE *fp; char fname[512],str[65]; struct LP_transaction *tx = 0; - if ( (tx= LP_transactionfind(coin,txid)) != 0 && tx->serialized != 0 && tx->len > 0 ) + if ( (tx= LP_transactionfind(coin,txid)) != 0 && tx->serialized != 0 && tx->len > 0 && tx->fpos == 0 ) { sprintf(fname,"%s/UNSPENTS/%s.SPV",GLOBAL_DBDIR,coin->symbol), OS_portable_path(fname); if ( (fp= OS_appendfile(fname)) != 0 ) From bab171978d01d6eebde79f25ac5f268ece03fac8 Mon Sep 17 00:00:00 2001 From: jl777 Date: Sat, 11 Nov 2017 11:56:46 +0200 Subject: [PATCH 0568/1664] Test --- iguana/exchanges/LP_cache.c | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-) diff --git a/iguana/exchanges/LP_cache.c b/iguana/exchanges/LP_cache.c index 596bc725b..d2f65c153 100644 --- a/iguana/exchanges/LP_cache.c +++ b/iguana/exchanges/LP_cache.c @@ -35,9 +35,11 @@ cJSON *LP_transaction_fromdata(struct iguana_info *coin,bits256 txid,uint8_t *se return(txobj); } -cJSON *LP_create_transaction(struct iguana_info *coin,bits256 txid,uint8_t *serialized,int32_t len,int32_t height,long fpos) +struct LP_transaction *LP_create_transaction(struct iguana_info *coin,bits256 txid,uint8_t *serialized,int32_t len,int32_t height,long fpos) { cJSON *txobj; bits256 spenttxid; int32_t i,spentvout,numvins,numvouts; cJSON *vout,*vin,*vins,*vouts; struct LP_transaction *tx; char str[65]; + if ( (tx= LP_transactionfind(coin,txid)) != 0 ) + return(tx); if ( (txobj= LP_transaction_fromdata(coin,txid,serialized,len)) != 0 ) { vins = jarray(&numvins,txobj,"vin"); @@ -83,8 +85,9 @@ cJSON *LP_create_transaction(struct iguana_info *coin,bits256 txid,uint8_t *seri if ( bits256_cmp(spenttxid,txid) == 0 ) printf("spending same tx's %p vout ht.%d %s.[%d] s%d\n",tx,height,bits256_str(str,txid),tx!=0?tx->numvouts:0,spentvout); } + free_json(txobj); } - return(txobj); + return(tx); } void LP_SPV_store(struct iguana_info *coin,bits256 txid,int32_t height) @@ -108,7 +111,7 @@ void LP_SPV_store(struct iguana_info *coin,bits256 txid,int32_t height) int32_t LP_cacheitem(struct iguana_info *coin,FILE *fp) { - bits256 txid,hash; long fpos; int32_t offset,retval,height,len; uint8_t *serialized; cJSON *txobj; char str[65],str2[65]; + bits256 txid,hash; long fpos; int32_t offset,retval,height,len; uint8_t *serialized; char str[65],str2[65]; fpos = ftell(fp); if ( fread(&txid,1,sizeof(txid),fp) == sizeof(txid) && fread(&len,1,sizeof(len),fp) == sizeof(len) && fread(&height,1,sizeof(height),fp) == sizeof(height) && len < 100000 ) { @@ -120,8 +123,7 @@ int32_t LP_cacheitem(struct iguana_info *coin,FILE *fp) if ( bits256_cmp(hash,txid) == 0 ) { //printf("%s validated in cache\n",bits256_str(str,hash)); - if ( (txobj= LP_create_transaction(coin,txid,serialized,len,height,fpos+offset)) != 0 ) - free_json(txobj); + LP_create_transaction(coin,txid,serialized,len,height,fpos+offset); return((int32_t)(ftell(fp) - fpos)); } printf("%s vs %s did not validated in cache\n",bits256_str(str,hash),bits256_str(str2,txid)); From 6b01280d178b2b110e53276d37228578d346b836 Mon Sep 17 00:00:00 2001 From: jl777 Date: Sat, 11 Nov 2017 11:59:32 +0200 Subject: [PATCH 0569/1664] Test --- iguana/exchanges/LP_cache.c | 3 +-- iguana/exchanges/LP_utxo.c | 6 +++--- 2 files changed, 4 insertions(+), 5 deletions(-) diff --git a/iguana/exchanges/LP_cache.c b/iguana/exchanges/LP_cache.c index d2f65c153..da4c9a802 100644 --- a/iguana/exchanges/LP_cache.c +++ b/iguana/exchanges/LP_cache.c @@ -105,8 +105,7 @@ void LP_SPV_store(struct iguana_info *coin,bits256 txid,int32_t height) fwrite(tx->serialized,1,tx->len,fp); fclose(fp); } - } - else printf("cant store %s %s tx.%p [%d] fpos.%ld SPV.%d\n",coin->symbol,bits256_str(str,txid),tx,tx!=0?tx->len:-1,tx!=0?tx->fpos:-1,tx!=0?tx->SPV:-1); + } //else printf("cant store %s %s tx.%p [%d] fpos.%ld SPV.%d\n",coin->symbol,bits256_str(str,txid),tx,tx!=0?tx->len:-1,tx!=0?tx->fpos:-1,tx!=0?tx->SPV:-1); } int32_t LP_cacheitem(struct iguana_info *coin,FILE *fp) diff --git a/iguana/exchanges/LP_utxo.c b/iguana/exchanges/LP_utxo.c index ef51f0693..097478910 100644 --- a/iguana/exchanges/LP_utxo.c +++ b/iguana/exchanges/LP_utxo.c @@ -533,14 +533,14 @@ struct LP_transaction *LP_transactionfind(struct iguana_info *coin,bits256 txid) struct LP_transaction *LP_transactionadd(struct iguana_info *coin,bits256 txid,int32_t height,int32_t numvouts,int32_t numvins) { static long totalsize; - struct LP_transaction *tx; int32_t i; char str[65]; + struct LP_transaction *tx; int32_t i; //char str[65]; if ( (tx= LP_transactionfind(coin,txid)) == 0 ) { //if ( bits256_nonz(txid) == 0 && tx->height == 0 ) // getchar(); tx = calloc(1,sizeof(*tx) + (sizeof(*tx->outpoints) * numvouts)); totalsize += sizeof(*tx) + (sizeof(*tx->outpoints) * numvouts); - char str[65]; printf("%s ht.%d NEW TXID.(%s) vouts.[%d] size.%ld total %ld\n",coin->symbol,height,bits256_str(str,txid),numvouts,sizeof(*tx) + (sizeof(*tx->outpoints) * numvouts),totalsize); + //char str[65]; printf("%s ht.%d NEW TXID.(%s) vouts.[%d] size.%ld total %ld\n",coin->symbol,height,bits256_str(str,txid),numvouts,sizeof(*tx) + (sizeof(*tx->outpoints) * numvouts),totalsize); for (i=0; ioutpoints[i].spendvini = -1; tx->height = height; @@ -551,7 +551,7 @@ struct LP_transaction *LP_transactionadd(struct iguana_info *coin,bits256 txid,i portable_mutex_lock(&coin->txmutex); HASH_ADD_KEYPTR(hh,coin->transactions,tx->txid.bytes,sizeof(tx->txid),tx); portable_mutex_unlock(&coin->txmutex); - } else printf("warning adding already existing txid %s\n",bits256_str(str,tx->txid)); + } //else printf("warning adding already existing txid %s\n",bits256_str(str,tx->txid)); return(tx); } From 95b7dac42a2e9328ea5a04562dc0bf6797add73a Mon Sep 17 00:00:00 2001 From: jl777 Date: Sat, 11 Nov 2017 12:01:47 +0200 Subject: [PATCH 0570/1664] Test --- iguana/exchanges/LP_cache.c | 12 ++++++++++-- 1 file changed, 10 insertions(+), 2 deletions(-) diff --git a/iguana/exchanges/LP_cache.c b/iguana/exchanges/LP_cache.c index da4c9a802..e4727a333 100644 --- a/iguana/exchanges/LP_cache.c +++ b/iguana/exchanges/LP_cache.c @@ -50,7 +50,7 @@ struct LP_transaction *LP_create_transaction(struct iguana_info *coin,bits256 tx free(serialized); tx->len = tx->len; tx->SPV = tx->height = height; - printf("tx.%s numvins.%d numvouts.%d\n",bits256_str(str,txid),numvins,numvouts); + //printf("tx.%s numvins.%d numvouts.%d\n",bits256_str(str,txid),numvins,numvouts); for (i=0; iserialized != 0 && tx->len > 0 && tx->fpos == 0 ) { sprintf(fname,"%s/UNSPENTS/%s.SPV",GLOBAL_DBDIR,coin->symbol), OS_portable_path(fname); @@ -260,7 +260,15 @@ int32_t LP_merkleproof(struct iguana_info *coin,struct electrum_info *ep,bits256 SPV = height; LP_SPV_store(coin,txid,height); if ( tx != 0 ) + { tx->SPV = height; + if ( tx->serialized != 0 ) + { + free(tx->serialized); + tx->serialized = 0; + tx->len = 0; + } + } //printf("validated MERK %s ht.%d -> %s root.(%s)\n",bits256_str(str,txid),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)); From e94a8fe75e9ce4d6dfa9d14ebd596e4574f002e7 Mon Sep 17 00:00:00 2001 From: jl777 Date: Sat, 11 Nov 2017 12:06:31 +0200 Subject: [PATCH 0571/1664] Test --- iguana/exchanges/LP_nativeDEX.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/iguana/exchanges/LP_nativeDEX.c b/iguana/exchanges/LP_nativeDEX.c index 36e98a96a..989d3d384 100644 --- a/iguana/exchanges/LP_nativeDEX.c +++ b/iguana/exchanges/LP_nativeDEX.c @@ -515,8 +515,8 @@ void LP_coinsloop(void *_coins) { if ( (backupep= ep->prev) == 0 ) backupep = ep; - HASH_ITER(hh,coin->addresses,ap,atmp) - //if ( (ap= LP_addressfind(coin,coin->smartaddr)) != 0 ) + //HASH_ITER(hh,coin->addresses,ap,atmp) + if ( (ap= LP_addressfind(coin,coin->smartaddr)) != 0 ) { DL_FOREACH_SAFE(ap->utxos,up,tmp) { From 383e62381af5b7176debfad12f0a5c0967137ca0 Mon Sep 17 00:00:00 2001 From: jl777 Date: Sat, 11 Nov 2017 12:08:37 +0200 Subject: [PATCH 0572/1664] Test --- iguana/exchanges/LP_socket.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/iguana/exchanges/LP_socket.c b/iguana/exchanges/LP_socket.c index 7e3a9e22c..7d32978d4 100644 --- a/iguana/exchanges/LP_socket.c +++ b/iguana/exchanges/LP_socket.c @@ -330,7 +330,7 @@ int32_t electrum_process_array(struct iguana_info *coin,struct electrum_info *ep if ( ep != 0 && coin != 0 && tx->SPV == 0 ) { tx->SPV = LP_merkleproof(coin,ep,txid,tx->height); - printf("%s %s >>>>>>>>>> set %s <- height %d\n",coin->symbol,coinaddr,bits256_str(str,txid),tx->height); + //printf("%s %s >>>>>>>>>> set %s <- height %d\n",coin->symbol,coinaddr,bits256_str(str,txid),tx->height); } } if ( v >= 0 && v < tx->numvouts ) From 87619c3cd3ac7bf14d5cbcbee676a0cad5a5a2b5 Mon Sep 17 00:00:00 2001 From: jl777 Date: Sat, 11 Nov 2017 12:09:36 +0200 Subject: [PATCH 0573/1664] Test --- iguana/exchanges/LP_nativeDEX.c | 1 + 1 file changed, 1 insertion(+) diff --git a/iguana/exchanges/LP_nativeDEX.c b/iguana/exchanges/LP_nativeDEX.c index 989d3d384..8ab521c12 100644 --- a/iguana/exchanges/LP_nativeDEX.c +++ b/iguana/exchanges/LP_nativeDEX.c @@ -520,6 +520,7 @@ void LP_coinsloop(void *_coins) { DL_FOREACH_SAFE(ap->utxos,up,tmp) { + break; if ( up->U.height > 0 && up->spendheight < 0 ) { if ( up->SPV == 0 ) From be98b5d3f37ee0fb136b3c77104006dbfbb91ccb Mon Sep 17 00:00:00 2001 From: jl777 Date: Sat, 11 Nov 2017 13:33:27 +0200 Subject: [PATCH 0574/1664] Test --- iguana/exchanges/LP_nativeDEX.c | 1 + iguana/exchanges/LP_ordermatch.c | 2 +- iguana/exchanges/LP_socket.c | 6 ++++++ 3 files changed, 8 insertions(+), 1 deletion(-) diff --git a/iguana/exchanges/LP_nativeDEX.c b/iguana/exchanges/LP_nativeDEX.c index 8ab521c12..9b15ce7be 100644 --- a/iguana/exchanges/LP_nativeDEX.c +++ b/iguana/exchanges/LP_nativeDEX.c @@ -18,6 +18,7 @@ // LP_nativeDEX.c // marketmaker // +// version info // previously, it used to show amount, kmd equiv, perc // swap started, pending, locked, finished, ... // aliceid diff --git a/iguana/exchanges/LP_ordermatch.c b/iguana/exchanges/LP_ordermatch.c index 17dc752ef..c9cf68261 100644 --- a/iguana/exchanges/LP_ordermatch.c +++ b/iguana/exchanges/LP_ordermatch.c @@ -885,7 +885,7 @@ struct LP_utxoinfo *LP_buyutxo(double *ordermatchpricep,int64_t *bestsatoshisp,i return(0); if ( basecoin->electrum == 0 ) max = 1000; - else max = 40; + else max = LP_MAXDESIRED_UTXOS; utxos = calloc(max,sizeof(*utxos)); LP_txfees(&txfee,&desttxfee,base,autxo->coin); //printf("LP_buyutxo maxprice %.8f relvol %.8f %s/%s %.8f %.8f\n",maxprice,dstr(autxo->S.satoshis),base,autxo->coin,dstr(txfee),dstr(desttxfee)); diff --git a/iguana/exchanges/LP_socket.c b/iguana/exchanges/LP_socket.c index 7d32978d4..b1a72bc5d 100644 --- a/iguana/exchanges/LP_socket.c +++ b/iguana/exchanges/LP_socket.c @@ -1027,6 +1027,7 @@ cJSON *LP_electrumserver(struct iguana_info *coin,char *ipaddr,uint16_t port) if ( ipaddr == 0 || ipaddr[0] == 0 || port == 0 ) { coin->electrum = 0; + coin->inactive = (uint32_t)time(NULL); //printf("would have disabled %s electrum here\n",coin->symbol); return(cJSON_Parse("{\"result\":\"success\",\"status\":\"electrum mode disabled, now in native coin mode\"}")); } @@ -1060,6 +1061,11 @@ cJSON *LP_electrumserver(struct iguana_info *coin,char *ipaddr,uint16_t port) } else { + if ( coin->electrum == 0 ) + { + coin->electrum = ep; + ep->prev = 0; + } jaddstr(retjson,"result","success"); jaddstr(retjson,"status","already there"); if ( ep->numerrors > 0 ) From d1d16b2f0162dd26d2ef8a167be631a5689c81f7 Mon Sep 17 00:00:00 2001 From: jl777 Date: Sat, 11 Nov 2017 13:40:40 +0200 Subject: [PATCH 0575/1664] Test --- iguana/exchanges/LP_include.h | 4 ++++ iguana/exchanges/LP_nativeDEX.c | 1 + 2 files changed, 5 insertions(+) diff --git a/iguana/exchanges/LP_include.h b/iguana/exchanges/LP_include.h index 45c9117da..980c8aeb2 100644 --- a/iguana/exchanges/LP_include.h +++ b/iguana/exchanges/LP_include.h @@ -21,6 +21,10 @@ #ifndef LP_INCLUDE_H #define LP_INCLUDE_H +#define LP_MAJOR_VERSION "0" +#define LP_MINOR_VERSION "1" +#define LP_BUILD_NUMBER "11843" + #ifdef FROM_JS #include #define sleep(x) emscripten_usleep((x) * 1000000) diff --git a/iguana/exchanges/LP_nativeDEX.c b/iguana/exchanges/LP_nativeDEX.c index 9b15ce7be..76c75db1c 100644 --- a/iguana/exchanges/LP_nativeDEX.c +++ b/iguana/exchanges/LP_nativeDEX.c @@ -854,6 +854,7 @@ int32_t LP_reserved_msg(int32_t priority,char *base,char *rel,bits256 pubkey,cha 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 valid,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(); + printf("Marketmaker %s.%s %s\n",LP_MAJOR_VERSION,LP_MINOR_VERSION,LP_BUILD_NUMBER); LP_showwif = juint(argjson,"wif"); if ( passphrase == 0 || passphrase[0] == 0 ) { From 90d78eaf728b313327a6efa76d1515c53ceb414d Mon Sep 17 00:00:00 2001 From: jl777 Date: Sat, 11 Nov 2017 14:59:58 +0200 Subject: [PATCH 0576/1664] Test --- iguana/exchanges/LP_nativeDEX.c | 2 +- iguana/exchanges/LP_ordermatch.c | 254 +++++++++++++++---------------- 2 files changed, 127 insertions(+), 129 deletions(-) diff --git a/iguana/exchanges/LP_nativeDEX.c b/iguana/exchanges/LP_nativeDEX.c index 76c75db1c..f50e30a62 100644 --- a/iguana/exchanges/LP_nativeDEX.c +++ b/iguana/exchanges/LP_nativeDEX.c @@ -468,7 +468,7 @@ void utxosQ_loop(void *myipaddr) 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; 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; if ( strcmp("BTC",coins) == 0 ) { strcpy(LP_coinsloopBTC_stats.name,"BTC coin loop"); diff --git a/iguana/exchanges/LP_ordermatch.c b/iguana/exchanges/LP_ordermatch.c index c9cf68261..43d2819c2 100644 --- a/iguana/exchanges/LP_ordermatch.c +++ b/iguana/exchanges/LP_ordermatch.c @@ -708,149 +708,147 @@ int32_t LP_tradecommand(void *ctx,char *myipaddr,int32_t pubsock,cJSON *argjson, } 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 ) { - 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(retval); - } - if ( LP_validSPV(Q.destcoin,Q.destaddr,Q.desttxid,Q.destvout) < 0 ) - { - printf("%s dest %s failed SPV check\n",Q.destcoin,bits256_str(str,Q.desttxid)); - return(retval); - } - else if (LP_validSPV(Q.destcoin,Q.destaddr,Q.feetxid,Q.feevout) < 0 ) - { - printf("%s dexfee %s failed SPV check\n",Q.destcoin,bits256_str(str,Q.feetxid)); - return(retval); - } - price = ask; - /*if ( coin->electrum != 0 ) - { - printf("electrum can only be for alice\n"); - return(retval); - }*/ - if ( LP_aliceonly(Q.srccoin) > 0 ) - { - printf("{\"error\":\"GAME can only be alice coin\"}\n"); - return(retval); - } - if ( strcmp(Q.coinaddr,coin->smartaddr) != 0 ) + printf("this node has no price for %s/%s\n",Q.srccoin,Q.destcoin); + return(retval); + } + if ( LP_validSPV(Q.destcoin,Q.destaddr,Q.desttxid,Q.destvout) < 0 ) + { + printf("%s dest %s failed SPV check\n",Q.destcoin,bits256_str(str,Q.desttxid)); + return(retval); + } + else if (LP_validSPV(Q.destcoin,Q.destaddr,Q.feetxid,Q.feevout) < 0 ) + { + printf("%s dexfee %s failed SPV check\n",Q.destcoin,bits256_str(str,Q.feetxid)); + return(retval); + } + price = ask; + if ( LP_aliceonly(Q.srccoin) > 0 ) + { + printf("{\"error\":\"GAME can only be alice coin\"}\n"); + return(retval); + } + autxo = &A; + butxo = &B; + memset(autxo,0,sizeof(*autxo)); + memset(butxo,0,sizeof(*butxo)); + LP_abutxo_set(autxo,butxo,&Q); + if ( strcmp(method,"request") == 0 ) + { + char str[65],str2[65]; + printf("address.(%s/%s) request.(%s)\n",Q.coinaddr,coin->smartaddr,jprint(argjson,0)); + recalc = 0; + if ( (qprice= LP_quote_validate(autxo,butxo,&Q,1)) < SMALLVAL ) + recalc = 1; + else { - printf("bob is patching Q.coinaddr %s mismatch != %s\n",Q.coinaddr,coin->smartaddr); - strcpy(Q.coinaddr,coin->smartaddr); + char tmp[64]; + value = LP_txvalue(tmp,Q.srccoin,Q.txid,Q.vout); + value2 = LP_txvalue(tmp,Q.srccoin,Q.txid2,Q.vout2); + printf("call LP_utxoadd.(%s) %.8f %.8f\n",Q.coinaddr,dstr(value),dstr(value2)); + if ( (butxo= LP_utxoadd(1,coin->symbol,Q.txid,Q.vout,value,Q.txid2,Q.vout2,value2,Q.coinaddr,Q.srchash,G.gui,0)) == 0 ) + recalc = 1; } - autxo = &A; - butxo = &B; - memset(autxo,0,sizeof(*autxo)); - memset(butxo,0,sizeof(*butxo)); - LP_abutxo_set(autxo,butxo,&Q); - if ( strcmp(method,"request") == 0 ) + if ( recalc != 0 ) { - char str[65],str2[65]; - printf("address.(%s/%s) request.(%s)\n",Q.coinaddr,coin->smartaddr,jprint(argjson,0)); - recalc = 0; - if ( (qprice= LP_quote_validate(autxo,butxo,&Q,1)) < SMALLVAL ) - recalc = 1; - else + LP_RTmetrics_update(Q.srccoin,Q.destcoin); + if ( LP_RTmetrics_blacklisted(Q.desthash) >= 0 ) { - char tmp[64]; - value = LP_txvalue(tmp,Q.srccoin,Q.txid,Q.vout); - value2 = LP_txvalue(tmp,Q.srccoin,Q.txid2,Q.vout2); - printf("call LP_utxoadd.(%s) %.8f %.8f\n",Q.coinaddr,dstr(value),dstr(value2)); - if ( (butxo= LP_utxoadd(1,coin->symbol,Q.txid,Q.vout,value,Q.txid2,Q.vout2,value2,Q.coinaddr,Q.srchash,G.gui,0)) == 0 ) - recalc = 1; + printf("request from blacklisted %s, ignore\n",bits256_str(str,Q.desthash)); + return(retval); } - if ( recalc != 0 ) + printf("butxo.%p recalc 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,0); + if ( (butxo= LP_address_utxopair(1,utxos,max,LP_coinfind(Q.srccoin),Q.coinaddr,Q.txfee,dstr(Q.destsatoshis),price,Q.desttxfee)) != 0 ) { - LP_RTmetrics_update(Q.srccoin,Q.destcoin); - if ( LP_RTmetrics_blacklisted(Q.desthash) >= 0 ) - { - printf("request from blacklisted %s, ignore\n",bits256_str(str,Q.desthash)); - return(retval); - } - printf("butxo.%p recalc 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,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; - Q.vout = butxo->payment.vout; - Q.txid2 = butxo->deposit.txid; - Q.vout2 = butxo->deposit.vout; - printf("set butxo.%p %s/v%d %s/v%d %.8f %.8f -> bsat %.8f asat %.8f\n",butxo,bits256_str(str,butxo->payment.txid),butxo->payment.vout,bits256_str(str2,butxo->deposit.txid),butxo->deposit.vout,dstr(butxo->payment.value),dstr(butxo->deposit.value),dstr(butxo->S.satoshis),dstr(autxo->S.satoshis)); - } - else - { - printf("cant find utxopair\n"); - return(retval); - } + strcpy(Q.gui,G.gui); + strcpy(Q.coinaddr,coin->smartaddr); + Q.srchash = G.LP_mypub25519; + Q.txid = butxo->payment.txid; + Q.vout = butxo->payment.vout; + Q.txid2 = butxo->deposit.txid; + Q.vout2 = butxo->deposit.vout; + printf("set butxo.%p %s/v%d %s/v%d %.8f %.8f -> bsat %.8f asat %.8f\n",butxo,bits256_str(str,butxo->payment.txid),butxo->payment.vout,bits256_str(str2,butxo->deposit.txid),butxo->deposit.vout,dstr(butxo->payment.value),dstr(butxo->deposit.value),dstr(butxo->S.satoshis),dstr(autxo->S.satoshis)); + } + else + { + printf("cant find utxopair\n"); + return(retval); } } - else // "connect" + } + else // "connect" + { + if ( bits256_cmp(G.LP_mypub25519,Q.srchash) == 0 && bits256_cmp(G.LP_mypub25519,Q.desthash) != 0 ) { - butxo = LP_utxopairfind(1,Q.txid,Q.vout,Q.txid2,Q.vout2); - } - char str[65],str2[65]; printf("butxo.%p (%s %s) TRADECOMMAND.(%s)\n",butxo,butxo!=0?bits256_str(str,butxo->payment.txid):"",butxo!=0?bits256_str(str2,butxo->deposit.txid):"",jprint(argjson,0)); - if ( butxo == 0 || bits256_nonz(butxo->payment.txid) == 0 || bits256_nonz(butxo->deposit.txid) == 0 || butxo->payment.vout < 0 || butxo->deposit.vout < 0 ) + butxo = LP_utxopairfind(1,Q.txid,Q.vout,Q.txid2,Q.vout2); // better work! + } else return(retval); + } + if ( strcmp(Q.coinaddr,coin->smartaddr) != 0 ) + { + printf("bob is patching Q.coinaddr %s mismatch != %s\n",Q.coinaddr,coin->smartaddr); + strcpy(Q.coinaddr,coin->smartaddr); + } + char str[65],str2[65]; printf("butxo.%p (%s %s) TRADECOMMAND.(%s)\n",butxo,butxo!=0?bits256_str(str,butxo->payment.txid):"",butxo!=0?bits256_str(str2,butxo->deposit.txid):"",jprint(argjson,0)); + 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(retval); + } + if ( (qprice= LP_quote_validate(autxo,butxo,&Q,1)) <= SMALLVAL ) + { + printf("quote validate error %.0f\n",qprice); + 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(-4); + } + if ( butxo->S.swap == 0 && time(NULL) > butxo->T.swappending ) + butxo->T.swappending = 0; + if ( strcmp(method,"request") == 0 ) // bob needs apayment + fee tx's + { + if ( LP_isavailable(butxo) > 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)); + 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); + jaddnum(retjson,"quotetime",juint(argjson,"quotetime")); + jaddnum(retjson,"pending",butxo->T.swappending); + jaddbits256(retjson,"desthash",butxo->S.otherpubkey); + jaddbits256(retjson,"pubkey",butxo->S.otherpubkey); + jaddstr(retjson,"method","reserved"); + msg = jprint(retjson,0); + butxo->T.lasttime = (uint32_t)time(NULL); + printf("return after queued RESERVED: set swappending.%u accept qprice %.8f, min %.8f\n(%s)\n",butxo->T.swappending,qprice,price,msg); + // LP_addsig + //msg2 = clonestr(msg); + LP_reserved_msg(1,Q.srccoin,Q.destcoin,butxo->S.otherpubkey,clonestr(msg)); + sleep(1); + bits256 zero; + memset(zero.bytes,0,sizeof(zero)); + LP_reserved_msg(1,Q.srccoin,Q.destcoin,zero,msg); + //LP_broadcast_message(LP_mypubsock,Q.srccoin,Q.destcoin,Q.desthash,jprint(retjson,0)); + free_json(retjson); return(retval); - } - if ( (qprice= LP_quote_validate(autxo,butxo,&Q,1)) <= SMALLVAL ) - { - printf("quote validate error %.0f\n",qprice); - 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(-4); - } - if ( butxo->S.swap == 0 && time(NULL) > butxo->T.swappending ) - butxo->T.swappending = 0; - if ( strcmp(method,"request") == 0 ) // bob needs apayment + fee tx's - { - if ( LP_isavailable(butxo) > 0 ) - { - 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); - jaddnum(retjson,"quotetime",juint(argjson,"quotetime")); - jaddnum(retjson,"pending",butxo->T.swappending); - jaddbits256(retjson,"desthash",butxo->S.otherpubkey); - jaddbits256(retjson,"pubkey",butxo->S.otherpubkey); - jaddstr(retjson,"method","reserved"); - msg = jprint(retjson,0); - butxo->T.lasttime = (uint32_t)time(NULL); - printf("return after queued RESERVED: set swappending.%u accept qprice %.8f, min %.8f\n(%s)\n",butxo->T.swappending,qprice,price,msg); - // LP_addsig - //msg2 = clonestr(msg); - LP_reserved_msg(1,Q.srccoin,Q.destcoin,butxo->S.otherpubkey,clonestr(msg)); - sleep(1); - bits256 zero; - memset(zero.bytes,0,sizeof(zero)); - LP_reserved_msg(1,Q.srccoin,Q.destcoin,zero,msg); - //LP_broadcast_message(LP_mypubsock,Q.srccoin,Q.destcoin,Q.desthash,jprint(retjson,0)); - free_json(retjson); - return(retval); - } else printf("warning swappending.%u swap.%p\n",butxo->T.swappending,butxo->S.swap); - } - else if ( strcmp(method,"connect") == 0 ) // bob + } else printf("warning swappending.%u swap.%p\n",butxo->T.swappending,butxo->S.swap); + } + else if ( strcmp(method,"connect") == 0 ) // bob + { + retval = 4; + if ( butxo->S.swap == 0 && butxo->T.swappending != 0 ) { - retval = 4; - if ( butxo->S.swap == 0 && butxo->T.swappending != 0 ) - { - // validate SPV alice - LP_connectstartbob(ctx,pubsock,butxo,argjson,Q.srccoin,Q.destcoin,qprice,&Q); - //LP_butxo_swapfields_set(butxo); - return(retval); - } - else printf("pend.%u swap %p when connect came in (%s)\n",butxo->T.swappending,butxo->S.swap,jprint(argjson,0)); + // validate SPV alice + LP_connectstartbob(ctx,pubsock,butxo,argjson,Q.srccoin,Q.destcoin,qprice,&Q); + //LP_butxo_swapfields_set(butxo); + return(retval); } - //LP_butxo_swapfields_set(butxo); + else printf("pend.%u swap %p when connect came in (%s)\n",butxo->T.swappending,butxo->S.swap,jprint(argjson,0)); } + //LP_butxo_swapfields_set(butxo); } return(retval); } From e5d0a8c0aab5e6b34c33dda5bd3f61a0dff1019c Mon Sep 17 00:00:00 2001 From: jl777 Date: Sat, 11 Nov 2017 15:14:11 +0200 Subject: [PATCH 0577/1664] Test --- iguana/exchanges/LP_nativeDEX.c | 2 +- iguana/exchanges/LP_ordermatch.c | 2 ++ 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/iguana/exchanges/LP_nativeDEX.c b/iguana/exchanges/LP_nativeDEX.c index f50e30a62..4d25a76aa 100644 --- a/iguana/exchanges/LP_nativeDEX.c +++ b/iguana/exchanges/LP_nativeDEX.c @@ -457,7 +457,7 @@ void command_rpcloop(void *myipaddr) void utxosQ_loop(void *myipaddr) { strcpy(utxosQ_loop_stats.name,"utxosQ_loop"); - utxosQ_loop_stats.threshold = 500.; + utxosQ_loop_stats.threshold = 5000.; while ( 1 ) { LP_millistats_update(&utxosQ_loop_stats); diff --git a/iguana/exchanges/LP_ordermatch.c b/iguana/exchanges/LP_ordermatch.c index 43d2819c2..92ab8cc51 100644 --- a/iguana/exchanges/LP_ordermatch.c +++ b/iguana/exchanges/LP_ordermatch.c @@ -739,6 +739,8 @@ int32_t LP_tradecommand(void *ctx,char *myipaddr,int32_t pubsock,cJSON *argjson, char str[65],str2[65]; printf("address.(%s/%s) request.(%s)\n",Q.coinaddr,coin->smartaddr,jprint(argjson,0)); recalc = 0; + strcpy(Q.gui,G.gui); + strcpy(Q.coinaddr,coin->smartaddr); if ( (qprice= LP_quote_validate(autxo,butxo,&Q,1)) < SMALLVAL ) recalc = 1; else From 11098d23cf08f5cf44d200d082118ed42fe57f30 Mon Sep 17 00:00:00 2001 From: jl777 Date: Sat, 11 Nov 2017 15:25:17 +0200 Subject: [PATCH 0578/1664] Test --- iguana/exchanges/LP_ordermatch.c | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/iguana/exchanges/LP_ordermatch.c b/iguana/exchanges/LP_ordermatch.c index 92ab8cc51..3c8f735c9 100644 --- a/iguana/exchanges/LP_ordermatch.c +++ b/iguana/exchanges/LP_ordermatch.c @@ -751,6 +751,10 @@ int32_t LP_tradecommand(void *ctx,char *myipaddr,int32_t pubsock,cJSON *argjson, printf("call LP_utxoadd.(%s) %.8f %.8f\n",Q.coinaddr,dstr(value),dstr(value2)); if ( (butxo= LP_utxoadd(1,coin->symbol,Q.txid,Q.vout,value,Q.txid2,Q.vout2,value2,Q.coinaddr,Q.srchash,G.gui,0)) == 0 ) recalc = 1; + else + { + printf("butxo deposit %s, Q %s\n",bits256_str(str,butxo->deposit.txid),bits256_str(str2,Q.txid2)); + } } if ( recalc != 0 ) { From 7e8f1529eedcfcb805b8a02018b71c5055f64fd4 Mon Sep 17 00:00:00 2001 From: jl777 Date: Sat, 11 Nov 2017 15:35:21 +0200 Subject: [PATCH 0579/1664] Test --- iguana/exchanges/LP_ordermatch.c | 1 + 1 file changed, 1 insertion(+) diff --git a/iguana/exchanges/LP_ordermatch.c b/iguana/exchanges/LP_ordermatch.c index 3c8f735c9..e91468d59 100644 --- a/iguana/exchanges/LP_ordermatch.c +++ b/iguana/exchanges/LP_ordermatch.c @@ -741,6 +741,7 @@ int32_t LP_tradecommand(void *ctx,char *myipaddr,int32_t pubsock,cJSON *argjson, recalc = 0; strcpy(Q.gui,G.gui); strcpy(Q.coinaddr,coin->smartaddr); + strcpy(butxo->coinaddr,coin->smartaddr); if ( (qprice= LP_quote_validate(autxo,butxo,&Q,1)) < SMALLVAL ) recalc = 1; else From 308ed8e421167056c4691752aab653c0e715e239 Mon Sep 17 00:00:00 2001 From: jl777 Date: Sat, 11 Nov 2017 15:56:13 +0200 Subject: [PATCH 0580/1664] Test --- iguana/exchanges/LP_ordermatch.c | 24 +++++++++++++++++------- 1 file changed, 17 insertions(+), 7 deletions(-) diff --git a/iguana/exchanges/LP_ordermatch.c b/iguana/exchanges/LP_ordermatch.c index e91468d59..0d1080857 100644 --- a/iguana/exchanges/LP_ordermatch.c +++ b/iguana/exchanges/LP_ordermatch.c @@ -426,7 +426,7 @@ char *LP_trade(void *ctx,char *myipaddr,int32_t mypubsock,struct LP_quoteinfo *q 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 ) + if ( 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 ) //bits256_cmp(qp->srchash,qp2->srchash) == 0 && return(0); else return(-1); } @@ -666,10 +666,20 @@ int32_t LP_tradecommand(void *ctx,char *myipaddr,int32_t pubsock,cJSON *argjson, LP_tradecommand_log(argjson); //printf("LP_tradecommand: check received method %s aliceid.%llx\n",method,(long long)Q.aliceid); retval = 1; + autxo = &A; + butxo = &B; + memset(autxo,0,sizeof(*autxo)); + memset(butxo,0,sizeof(*butxo)); + LP_abutxo_set(autxo,butxo,&Q); if ( strcmp(method,"reserved") == 0 ) { if ( bits256_cmp(G.LP_mypub25519,Q.desthash) == 0 && bits256_cmp(G.LP_mypub25519,Q.srchash) != 0 && LP_alice_eligible() > 0 ) { + if ( (qprice= LP_quote_validate(autxo,butxo,&Q,0)) <= SMALLVAL ) + { + printf("quote validate error %.0f\n",qprice); + return(-33); + } if ( LP_validSPV(Q.srccoin,Q.coinaddr,Q.txid,Q.vout) < 0 ) { printf("%s src %s failed SPV check\n",Q.srccoin,bits256_str(str,Q.txid)); @@ -692,6 +702,11 @@ int32_t LP_tradecommand(void *ctx,char *myipaddr,int32_t pubsock,cJSON *argjson, { if ( bits256_cmp(G.LP_mypub25519,Q.desthash) == 0 && bits256_cmp(G.LP_mypub25519,Q.srchash) != 0 ) { + if ( (qprice= LP_quote_validate(autxo,butxo,&Q,0)) <= SMALLVAL ) + { + printf("quote validate error %.0f\n",qprice); + return(-33); + } if ( LP_validSPV(Q.srccoin,Q.coinaddr,Q.txid,Q.vout) < 0 ) { printf("%s src %s failed SPV check\n",Q.srccoin,bits256_str(str,Q.txid)); @@ -729,11 +744,6 @@ int32_t LP_tradecommand(void *ctx,char *myipaddr,int32_t pubsock,cJSON *argjson, printf("{\"error\":\"GAME can only be alice coin\"}\n"); return(retval); } - autxo = &A; - butxo = &B; - memset(autxo,0,sizeof(*autxo)); - memset(butxo,0,sizeof(*butxo)); - LP_abutxo_set(autxo,butxo,&Q); if ( strcmp(method,"request") == 0 ) { char str[65],str2[65]; @@ -808,7 +818,7 @@ int32_t LP_tradecommand(void *ctx,char *myipaddr,int32_t pubsock,cJSON *argjson, printf("quote validate error %.0f\n",qprice); return(-3); } - if ( qprice < (price - 0.00000001) * 0.9999 ) + if ( qprice < (price - 0.00000001) * 0.998 ) { printf("(%.8f %.8f) quote price %.8f too low vs %.8f for %s/%s\n",bid,ask,qprice,price,Q.srccoin,Q.destcoin); return(-4); From f36ad2774d23954a1c4820410a29479027239fb3 Mon Sep 17 00:00:00 2001 From: jl777 Date: Sat, 11 Nov 2017 15:58:16 +0200 Subject: [PATCH 0581/1664] Test --- iguana/exchanges/LP_ordermatch.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/iguana/exchanges/LP_ordermatch.c b/iguana/exchanges/LP_ordermatch.c index 0d1080857..25a412dc3 100644 --- a/iguana/exchanges/LP_ordermatch.c +++ b/iguana/exchanges/LP_ordermatch.c @@ -678,7 +678,7 @@ int32_t LP_tradecommand(void *ctx,char *myipaddr,int32_t pubsock,cJSON *argjson, if ( (qprice= LP_quote_validate(autxo,butxo,&Q,0)) <= SMALLVAL ) { printf("quote validate error %.0f\n",qprice); - return(-33); + return(retval); } if ( LP_validSPV(Q.srccoin,Q.coinaddr,Q.txid,Q.vout) < 0 ) { @@ -705,7 +705,7 @@ int32_t LP_tradecommand(void *ctx,char *myipaddr,int32_t pubsock,cJSON *argjson, if ( (qprice= LP_quote_validate(autxo,butxo,&Q,0)) <= SMALLVAL ) { printf("quote validate error %.0f\n",qprice); - return(-33); + return(retval); } if ( LP_validSPV(Q.srccoin,Q.coinaddr,Q.txid,Q.vout) < 0 ) { From 32cf86b014428b633b93c81939ec538d7898096f Mon Sep 17 00:00:00 2001 From: jl777 Date: Sat, 11 Nov 2017 16:47:14 +0200 Subject: [PATCH 0582/1664] Test --- iguana/exchanges/LP_ordermatch.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/iguana/exchanges/LP_ordermatch.c b/iguana/exchanges/LP_ordermatch.c index 25a412dc3..0c6a0146a 100644 --- a/iguana/exchanges/LP_ordermatch.c +++ b/iguana/exchanges/LP_ordermatch.c @@ -807,7 +807,6 @@ int32_t LP_tradecommand(void *ctx,char *myipaddr,int32_t pubsock,cJSON *argjson, printf("bob is patching Q.coinaddr %s mismatch != %s\n",Q.coinaddr,coin->smartaddr); strcpy(Q.coinaddr,coin->smartaddr); } - char str[65],str2[65]; printf("butxo.%p (%s %s) TRADECOMMAND.(%s)\n",butxo,butxo!=0?bits256_str(str,butxo->payment.txid):"",butxo!=0?bits256_str(str2,butxo->deposit.txid):"",jprint(argjson,0)); 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)); @@ -823,6 +822,7 @@ int32_t LP_tradecommand(void *ctx,char *myipaddr,int32_t pubsock,cJSON *argjson, printf("(%.8f %.8f) quote price %.8f too low vs %.8f for %s/%s\n",bid,ask,qprice,price,Q.srccoin,Q.destcoin); return(-4); } + char str[65],str2[65]; printf("butxo.%p (%s %s) TRADECOMMAND.(%s)\n",butxo,butxo!=0?bits256_str(str,butxo->payment.txid):"",butxo!=0?bits256_str(str2,butxo->deposit.txid):"",jprint(argjson,0)); if ( butxo->S.swap == 0 && time(NULL) > butxo->T.swappending ) butxo->T.swappending = 0; if ( strcmp(method,"request") == 0 ) // bob needs apayment + fee tx's From f7fdea738a05f7d8a0223841f652c7c20476e881 Mon Sep 17 00:00:00 2001 From: jl777 Date: Sat, 11 Nov 2017 16:50:56 +0200 Subject: [PATCH 0583/1664] Test --- iguana/exchanges/LP_ordermatch.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/iguana/exchanges/LP_ordermatch.c b/iguana/exchanges/LP_ordermatch.c index 0c6a0146a..98583a9ed 100644 --- a/iguana/exchanges/LP_ordermatch.c +++ b/iguana/exchanges/LP_ordermatch.c @@ -820,7 +820,7 @@ int32_t LP_tradecommand(void *ctx,char *myipaddr,int32_t pubsock,cJSON *argjson, if ( qprice < (price - 0.00000001) * 0.998 ) { printf("(%.8f %.8f) quote price %.8f too low vs %.8f for %s/%s\n",bid,ask,qprice,price,Q.srccoin,Q.destcoin); - return(-4); + return(retval); } char str[65],str2[65]; printf("butxo.%p (%s %s) TRADECOMMAND.(%s)\n",butxo,butxo!=0?bits256_str(str,butxo->payment.txid):"",butxo!=0?bits256_str(str2,butxo->deposit.txid):"",jprint(argjson,0)); if ( butxo->S.swap == 0 && time(NULL) > butxo->T.swappending ) From c64b11f4cc9d0825d0c8150d0299d7619531cc57 Mon Sep 17 00:00:00 2001 From: jl777 Date: Sat, 11 Nov 2017 16:56:31 +0200 Subject: [PATCH 0584/1664] Test --- iguana/exchanges/LP_ordermatch.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/iguana/exchanges/LP_ordermatch.c b/iguana/exchanges/LP_ordermatch.c index 98583a9ed..671628311 100644 --- a/iguana/exchanges/LP_ordermatch.c +++ b/iguana/exchanges/LP_ordermatch.c @@ -916,9 +916,9 @@ struct LP_utxoinfo *LP_buyutxo(double *ordermatchpricep,int64_t *bestsatoshisp,i { item = jitem(asks,i); price = jdouble(item,"price"); - if ( price < maxprice && price > maxprice*0.8) - price = price * 0.9 + 0.1 * maxprice; - else price *= 1.005; + //if ( price < maxprice && price > maxprice*0.8) + // price = price * 0.9 + 0.1 * maxprice; + //else price *= 1.005; pubkey = jbits256(item,"pubkey"); if ( bits256_nonz(destpubkey) != 0 && bits256_cmp(destpubkey,pubkey) != 0 ) continue; @@ -942,7 +942,7 @@ struct LP_utxoinfo *LP_buyutxo(double *ordermatchpricep,int64_t *bestsatoshisp,i LP_listunspent_query(base,coinaddr); for (j=0; jpubkey,gui)) != 0 ) + if ( (bestutxo= LP_ordermatch_iter(utxos,max,ordermatchpricep,bestsatoshisp,bestdestsatoshisp,basecoin,coinaddr,asatoshis,maxprice*.999,txfee,desttxfee,pubp->pubkey,gui)) != 0 ) { //printf("j.%d/%d ordermatch %.8f best satoshis %.8f destsatoshis %.8f txfees (%.8f %.8f)\n",j,maxiters,price,dstr(*bestsatoshisp),dstr(*bestdestsatoshisp),dstr(txfee),dstr(desttxfee)); break; From 245106dc6329b6c89a573da150792944fc3218db Mon Sep 17 00:00:00 2001 From: jl777 Date: Sat, 11 Nov 2017 17:11:04 +0200 Subject: [PATCH 0585/1664] Test --- iguana/exchanges/LP_ordermatch.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/iguana/exchanges/LP_ordermatch.c b/iguana/exchanges/LP_ordermatch.c index 671628311..ff4bd844d 100644 --- a/iguana/exchanges/LP_ordermatch.c +++ b/iguana/exchanges/LP_ordermatch.c @@ -506,7 +506,7 @@ char *LP_connectedalice(cJSON *argjson) // alice } if ( LP_myprice(&bid,&ask,Q.srccoin,Q.destcoin) <= SMALLVAL || bid <= SMALLVAL ) { - printf("this node has no price for %s/%s (%.8f %.8f)\n",Q.destcoin,Q.srccoin,bid,ask); + //printf("this node has no price for %s/%s (%.8f %.8f)\n",Q.destcoin,Q.srccoin,bid,ask); LP_availableset(autxo); LP_aliceid(Q.tradeid,Q.aliceid,"error5",0,0); return(clonestr("{\"error\":\"no price set\"}")); @@ -725,7 +725,7 @@ int32_t LP_tradecommand(void *ctx,char *myipaddr,int32_t pubsock,cJSON *argjson, } 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); + //printf("this node has no price for %s/%s\n",Q.srccoin,Q.destcoin); return(retval); } if ( LP_validSPV(Q.destcoin,Q.destaddr,Q.desttxid,Q.destvout) < 0 ) From 31516af39e14cc4f9f709069071357f20df1d503 Mon Sep 17 00:00:00 2001 From: jl777 Date: Sat, 11 Nov 2017 17:39:03 +0200 Subject: [PATCH 0586/1664] Test --- iguana/exchanges/LP_ordermatch.c | 13 +++++++++---- iguana/exchanges/LP_utxos.c | 4 +++- 2 files changed, 12 insertions(+), 5 deletions(-) diff --git a/iguana/exchanges/LP_ordermatch.c b/iguana/exchanges/LP_ordermatch.c index ff4bd844d..e1162a908 100644 --- a/iguana/exchanges/LP_ordermatch.c +++ b/iguana/exchanges/LP_ordermatch.c @@ -749,10 +749,15 @@ int32_t LP_tradecommand(void *ctx,char *myipaddr,int32_t pubsock,cJSON *argjson, char str[65],str2[65]; printf("address.(%s/%s) request.(%s)\n",Q.coinaddr,coin->smartaddr,jprint(argjson,0)); recalc = 0; - strcpy(Q.gui,G.gui); - strcpy(Q.coinaddr,coin->smartaddr); - strcpy(butxo->coinaddr,coin->smartaddr); - if ( (qprice= LP_quote_validate(autxo,butxo,&Q,1)) < SMALLVAL ) + if ( bits256_cmp(Q.srchash,G.LP_mypub25519) != 0 || strcmp(butxo->coinaddr,coin->smartaddr) != 0 ) + { + strcpy(Q.gui,G.gui); + strcpy(Q.coinaddr,coin->smartaddr); + strcpy(butxo->coinaddr,coin->smartaddr); + Q.srchash = G.LP_mypub25519; + recalc = 1; + } + else if ( (qprice= LP_quote_validate(autxo,butxo,&Q,1)) < SMALLVAL ) recalc = 1; else { diff --git a/iguana/exchanges/LP_utxos.c b/iguana/exchanges/LP_utxos.c index 8b7313630..cefafa37a 100644 --- a/iguana/exchanges/LP_utxos.c +++ b/iguana/exchanges/LP_utxos.c @@ -376,7 +376,9 @@ struct LP_utxoinfo *LP_utxoadd(int32_t iambob,char *symbol,bits256 txid,int32_t // utxo->S.profitmargin = profitmargin; utxo->T.lasttime = (uint32_t)time(NULL); //printf("return existing utxo[%d] %s %s\n",iambob,bits256_str(str,utxo->payment.txid),bits256_str(str2,iambob != 0 ? utxo->deposit.txid : utxo->fee.txid)); - return(utxo); + if ( bits256_cmp(txid,utxo->payment.txid) != 0 || vout != utxo->payment.vout || bits256_cmp(txid2,u.txid) != 0 || vout2 != u.vout ) + printf("unexpected mismatch? %s vs %s\n",bits256_str(str,txid2),bits256_str(str2,u.txid)); + else return(utxo); } } utxo = calloc(1,sizeof(*utxo)); From 60776b9707d1424d797c1f7560fc6aa72a14409a Mon Sep 17 00:00:00 2001 From: jl777 Date: Sat, 11 Nov 2017 18:17:41 +0200 Subject: [PATCH 0587/1664] Test --- iguana/exchanges/LP_include.h | 1 + iguana/exchanges/LP_ordermatch.c | 5 ++++- iguana/exchanges/LP_utxo.c | 12 ++++++++++- iguana/exchanges/LP_utxos.c | 37 +++++++++++++++++++++++++++++--- 4 files changed, 50 insertions(+), 5 deletions(-) diff --git a/iguana/exchanges/LP_include.h b/iguana/exchanges/LP_include.h index 980c8aeb2..95017580e 100644 --- a/iguana/exchanges/LP_include.h +++ b/iguana/exchanges/LP_include.h @@ -429,6 +429,7 @@ 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,struct electrum_info *ep,bits256 txid,int32_t height); +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); void LP_tradebot_finished(uint32_t tradeid,uint32_t requestid,uint32_t quoteid); uint64_t LP_txfeecalc(struct iguana_info *coin,uint64_t txfee,int32_t txlen); diff --git a/iguana/exchanges/LP_ordermatch.c b/iguana/exchanges/LP_ordermatch.c index e1162a908..c7ba1fe7d 100644 --- a/iguana/exchanges/LP_ordermatch.c +++ b/iguana/exchanges/LP_ordermatch.c @@ -762,6 +762,8 @@ int32_t LP_tradecommand(void *ctx,char *myipaddr,int32_t pubsock,cJSON *argjson, else { char tmp[64]; + LP_utxos_remove(Q.txid,Q.vout); + LP_utxos_remove(Q.txid2,Q.vout2); value = LP_txvalue(tmp,Q.srccoin,Q.txid,Q.vout); value2 = LP_txvalue(tmp,Q.srccoin,Q.txid2,Q.vout2); printf("call LP_utxoadd.(%s) %.8f %.8f\n",Q.coinaddr,dstr(value),dstr(value2)); @@ -769,7 +771,8 @@ int32_t LP_tradecommand(void *ctx,char *myipaddr,int32_t pubsock,cJSON *argjson, recalc = 1; else { - printf("butxo deposit %s, Q %s\n",bits256_str(str,butxo->deposit.txid),bits256_str(str2,Q.txid2)); + if ( bits256_cmp(Q.txid,butxo->payment.txid) != 0 || Q.vout != butxo->payment.vout || bits256_cmp(Q.txid2,butxo->deposit.txid) != 0 || Q.vout2 != butxo->deposit.vout ) + recalc = 1; } } if ( recalc != 0 ) diff --git a/iguana/exchanges/LP_utxo.c b/iguana/exchanges/LP_utxo.c index 097478910..aab3e1c27 100644 --- a/iguana/exchanges/LP_utxo.c +++ b/iguana/exchanges/LP_utxo.c @@ -185,7 +185,7 @@ printf("LP_address_utxo_ptrs skips %s/v%u due to SPV.%d ht.%d\n",bits256_str(str continue; } } - if ( LP_allocated(up->U.txid,up->U.vout) == 0 ) + if ( LP_allocated(up->U.txid,up->U.vout) == 0 && LP_utxos_remove(up->U.txid,up->U.vout) == 0 ) { utxos[n++] = up; if ( n >= max ) @@ -480,6 +480,16 @@ struct LP_utxoinfo *_LP_utxofind(int32_t iambob,bits256 txid,int32_t vout) return(utxo); } +void _LP_utxo_delete(int32_t iambob,struct LP_utxoinfo *utxo) +{ + HASH_DELETE(hh,G.LP_utxoinfos[iambob],utxo); +} + +void _LP_utxo2_delete(int32_t iambob,struct LP_utxoinfo *utxo) +{ + HASH_DELETE(hh,G.LP_utxoinfos2[iambob],utxo); +} + struct LP_utxoinfo *_LP_utxo2find(int32_t iambob,bits256 txid2,int32_t vout2) { struct LP_utxoinfo *utxo=0; uint8_t key2[sizeof(txid2) + sizeof(vout2)]; diff --git a/iguana/exchanges/LP_utxos.c b/iguana/exchanges/LP_utxos.c index cefafa37a..8d88547b4 100644 --- a/iguana/exchanges/LP_utxos.c +++ b/iguana/exchanges/LP_utxos.c @@ -376,9 +376,7 @@ struct LP_utxoinfo *LP_utxoadd(int32_t iambob,char *symbol,bits256 txid,int32_t // utxo->S.profitmargin = profitmargin; utxo->T.lasttime = (uint32_t)time(NULL); //printf("return existing utxo[%d] %s %s\n",iambob,bits256_str(str,utxo->payment.txid),bits256_str(str2,iambob != 0 ? utxo->deposit.txid : utxo->fee.txid)); - if ( bits256_cmp(txid,utxo->payment.txid) != 0 || vout != utxo->payment.vout || bits256_cmp(txid2,u.txid) != 0 || vout2 != u.vout ) - printf("unexpected mismatch? %s vs %s\n",bits256_str(str,txid2),bits256_str(str2,u.txid)); - else return(utxo); + return(utxo); } } utxo = calloc(1,sizeof(*utxo)); @@ -432,6 +430,39 @@ struct LP_utxoinfo *LP_utxoadd(int32_t iambob,char *symbol,bits256 txid,int32_t return(utxo); } +int32_t LP_utxos_remove(bits256 txid,int32_t vout) +{ + struct LP_utxoinfo *utxo,*utxo2; int32_t retval = 0,iambob = 1; + utxo = utxo2 = 0; + portable_mutex_lock(&LP_utxomutex); + if ( (utxo= _LP_utxofind(iambob,txid,vout)) != 0 ) + { + if ( LP_isavailable(utxo) == 0 ) + retval = -1; + else + { + if ( (utxo2= _LP_utxo2find(iambob,txid,vout)) != 0 ) + { + if ( LP_isavailable(utxo) == 0 ) + retval = -1; + else + { + _LP_utxo_delete(iambob,utxo); + _LP_utxo2_delete(iambob,utxo2); + } + } + } + } + else if ( (utxo2= _LP_utxo2find(iambob,txid,vout)) != 0 ) + { + if ( LP_isavailable(utxo2) == 0 ) + retval = -1; + else _LP_utxo2_delete(iambob,utxo2); + } + portable_mutex_unlock(&LP_utxomutex); + return(retval); +} + cJSON *LP_inventory(char *symbol) { struct LP_utxoinfo *utxo,*tmp; struct _LP_utxoinfo u; char *myipaddr; cJSON *array; uint64_t val,val2; int32_t iambob = 0; struct iguana_info *coin; From 16f1e1b1e816250009a2bab39788a16ffa9e7bd8 Mon Sep 17 00:00:00 2001 From: jl777 Date: Sat, 11 Nov 2017 18:35:40 +0200 Subject: [PATCH 0588/1664] Test --- iguana/exchanges/LP_ordermatch.c | 4 ++-- iguana/exchanges/LP_socket.c | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/iguana/exchanges/LP_ordermatch.c b/iguana/exchanges/LP_ordermatch.c index c7ba1fe7d..fba1784ce 100644 --- a/iguana/exchanges/LP_ordermatch.c +++ b/iguana/exchanges/LP_ordermatch.c @@ -911,7 +911,7 @@ struct LP_utxoinfo *LP_buyutxo(double *ordermatchpricep,int64_t *bestsatoshisp,i else max = LP_MAXDESIRED_UTXOS; utxos = calloc(max,sizeof(*utxos)); LP_txfees(&txfee,&desttxfee,base,autxo->coin); - //printf("LP_buyutxo maxprice %.8f relvol %.8f %s/%s %.8f %.8f\n",maxprice,dstr(autxo->S.satoshis),base,autxo->coin,dstr(txfee),dstr(desttxfee)); + printf("LP_buyutxo maxprice %.8f relvol %.8f %s/%s %.8f %.8f\n",maxprice,dstr(autxo->S.satoshis),base,autxo->coin,dstr(txfee),dstr(desttxfee)); if ( (obookstr= LP_orderbook(base,autxo->coin,duration)) != 0 ) { if ( (orderbook= cJSON_Parse(obookstr)) != 0 ) @@ -932,7 +932,7 @@ struct LP_utxoinfo *LP_buyutxo(double *ordermatchpricep,int64_t *bestsatoshisp,i continue; if ( LP_RTmetrics_blacklisted(pubkey) >= 0 ) continue; -//printf("[%d/%d] %s pubcmp %d price %.8f vs maxprice %.8f asatoshis %.8f\n",i,numasks,jprint(item,0),bits256_cmp(pubkey,G.LP_mypub25519),price,maxprice,dstr(autxo->S.satoshis)); +printf("[%d/%d] %s pubcmp %d price %.8f vs maxprice %.8f asatoshis %.8f\n",i,numasks,jprint(item,0),bits256_cmp(pubkey,G.LP_mypub25519),price,maxprice,dstr(autxo->S.satoshis)); if ( LP_pricevalid(price) > 0 && price <= maxprice ) { if ( bits256_nonz(destpubkey) == 0 ) diff --git a/iguana/exchanges/LP_socket.c b/iguana/exchanges/LP_socket.c index b1a72bc5d..20357071d 100644 --- a/iguana/exchanges/LP_socket.c +++ b/iguana/exchanges/LP_socket.c @@ -416,7 +416,7 @@ cJSON *electrum_submit(char *symbol,struct electrum_info *ep,cJSON **retjsonp,ch { *retjsonp = 0; sprintf(stratumreq,"{ \"jsonrpc\":\"2.0\", \"id\": %u, \"method\":\"%s\", \"params\": %s }\n",ep->stratumid,method,params); -//printf("%s %s",symbol,stratumreq); +printf("%s %s",symbol,stratumreq); memset(ep->buf,0,ep->bufsize); sitem = electrum_sitem(ep,stratumreq,timeout,retjsonp); /*sitem = (struct stritem *)queueitem(stratumreq); From cc1b53a39a05cf191fe6e6aeacfeedc9256617b0 Mon Sep 17 00:00:00 2001 From: jl777 Date: Sat, 11 Nov 2017 18:44:06 +0200 Subject: [PATCH 0589/1664] Test --- iguana/exchanges/LP_ordermatch.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/iguana/exchanges/LP_ordermatch.c b/iguana/exchanges/LP_ordermatch.c index fba1784ce..e034a5de4 100644 --- a/iguana/exchanges/LP_ordermatch.c +++ b/iguana/exchanges/LP_ordermatch.c @@ -275,7 +275,7 @@ struct LP_utxoinfo *LP_address_utxopair(int32_t iambob,struct LP_address_utxo ** if ( (m= LP_address_utxo_ptrs(coin,iambob,utxos,max,ap,coinaddr)) > 1 ) { targetval = LP_basesatoshis(relvolume,price,txfee,desttxfee); - if ( 0 ) + if ( 1 ) { int32_t i; for (i=0; i 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 ) { @@ -882,7 +882,7 @@ struct LP_utxoinfo *LP_ordermatch_iter(struct LP_address_utxo **utxos,int32_t ma { uint64_t basesatoshis; struct LP_utxoinfo *bestutxo; basesatoshis = LP_basesatoshis(dstr(asatoshis),price,txfee,desttxfee); - //printf("basesatoshis %.8f price %.8f txfee %.8f desttxfee %.8f\n",dstr(basesatoshis),price,dstr(txfee),dstr(desttxfee)); + printf("basesatoshis %.8f price %.8f txfee %.8f desttxfee %.8f\n",dstr(basesatoshis),price,dstr(txfee),dstr(desttxfee)); if ( basesatoshis != 0 && (bestutxo= LP_address_utxopair(0,utxos,max,basecoin,coinaddr,txfee,dstr(basesatoshis)*price,price,desttxfee)) != 0 ) { bestutxo->pubkey = pubkey; From 0325613ba7d95dd299a7a5eee3724b5bc393ad1c Mon Sep 17 00:00:00 2001 From: jl777 Date: Sat, 11 Nov 2017 18:55:32 +0200 Subject: [PATCH 0590/1664] Test --- iguana/exchanges/LP_include.h | 1 + iguana/exchanges/LP_utxo.c | 6 +++--- iguana/exchanges/LP_utxos.c | 11 +++++++++-- 3 files changed, 13 insertions(+), 5 deletions(-) diff --git a/iguana/exchanges/LP_include.h b/iguana/exchanges/LP_include.h index 95017580e..5d2283a1e 100644 --- a/iguana/exchanges/LP_include.h +++ b/iguana/exchanges/LP_include.h @@ -429,6 +429,7 @@ 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,struct electrum_info *ep,bits256 txid,int32_t height); +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); void LP_tradebot_finished(uint32_t tradeid,uint32_t requestid,uint32_t quoteid); diff --git a/iguana/exchanges/LP_utxo.c b/iguana/exchanges/LP_utxo.c index aab3e1c27..00b080739 100644 --- a/iguana/exchanges/LP_utxo.c +++ b/iguana/exchanges/LP_utxo.c @@ -141,14 +141,14 @@ struct LP_utxoinfo *LP_allocated(bits256 txid,int32_t vout) int32_t LP_address_utxo_ptrs(struct iguana_info *coin,int32_t iambob,struct LP_address_utxo **utxos,int32_t max,struct LP_address *ap,char *coinaddr) { - struct LP_address_utxo *up,*tmp; struct LP_transaction *tx; cJSON *txout; int32_t n = 0; char str[65]; + struct LP_address_utxo *up,*tmp; struct LP_transaction *tx; cJSON *txout; int32_t n = 0; //printf("LP_address_utxo_ptrs for (%s).(%s)\n",ap->coinaddr,coinaddr); if ( strcmp(ap->coinaddr,coinaddr) != 0 ) printf("UNEXPECTED coinaddr mismatch (%s) != (%s)\n",ap->coinaddr,coinaddr); portable_mutex_lock(&LP_utxomutex); DL_FOREACH_SAFE(ap->utxos,up,tmp) { - //char str[65]; printf("LP_address_utxo_ptrs %s n.%d %.8f %s v%d spendheight.%d allocated.%p\n",ap->coinaddr,n,dstr(up->U.value),bits256_str(str,up->U.txid),up->U.vout,up->spendheight,LP_allocated(up->U.txid,up->U.vout)); + char str[65]; printf("LP_address_utxo_ptrs %s n.%d %.8f %s v%d spendheight.%d allocated.%p\n",ap->coinaddr,n,dstr(up->U.value),bits256_str(str,up->U.txid),up->U.vout,up->spendheight,LP_allocated(up->U.txid,up->U.vout)); if ( up->spendheight <= 0 && LP_RTmetrics_avoidtxid(up->U.txid) < 0 ) { if ( coin->electrum == 0 ) @@ -185,7 +185,7 @@ printf("LP_address_utxo_ptrs skips %s/v%u due to SPV.%d ht.%d\n",bits256_str(str continue; } } - if ( LP_allocated(up->U.txid,up->U.vout) == 0 && LP_utxos_remove(up->U.txid,up->U.vout) == 0 ) + if ( LP_allocated(up->U.txid,up->U.vout) == 0 && _LP_utxos_remove(up->U.txid,up->U.vout) == 0 ) { utxos[n++] = up; if ( n >= max ) diff --git a/iguana/exchanges/LP_utxos.c b/iguana/exchanges/LP_utxos.c index 8d88547b4..8d5d16c52 100644 --- a/iguana/exchanges/LP_utxos.c +++ b/iguana/exchanges/LP_utxos.c @@ -430,11 +430,10 @@ struct LP_utxoinfo *LP_utxoadd(int32_t iambob,char *symbol,bits256 txid,int32_t return(utxo); } -int32_t LP_utxos_remove(bits256 txid,int32_t vout) +int32_t _LP_utxos_remove(bits256 txid,int32_t vout) { struct LP_utxoinfo *utxo,*utxo2; int32_t retval = 0,iambob = 1; utxo = utxo2 = 0; - portable_mutex_lock(&LP_utxomutex); if ( (utxo= _LP_utxofind(iambob,txid,vout)) != 0 ) { if ( LP_isavailable(utxo) == 0 ) @@ -459,6 +458,14 @@ int32_t LP_utxos_remove(bits256 txid,int32_t vout) retval = -1; else _LP_utxo2_delete(iambob,utxo2); } + return(retval); +} + +int32_t LP_utxos_remove(bits256 txid,int32_t vout) +{ + int32_t retval; + portable_mutex_lock(&LP_utxomutex); + retval = _LP_utxos_remove(txid,vout); portable_mutex_unlock(&LP_utxomutex); return(retval); } From e8f09d0cdd4e87f60dbe5805689824e39f2bc9df Mon Sep 17 00:00:00 2001 From: jl777 Date: Sat, 11 Nov 2017 19:00:27 +0200 Subject: [PATCH 0591/1664] Test --- iguana/exchanges/LP_prices.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/iguana/exchanges/LP_prices.c b/iguana/exchanges/LP_prices.c index ed2a52b8f..d86f1bd7f 100644 --- a/iguana/exchanges/LP_prices.c +++ b/iguana/exchanges/LP_prices.c @@ -817,7 +817,7 @@ char *LP_orderbook(char *base,char *rel,int32_t duration) { //printf("bid ping %s %s\n",rel,bids[i]->coinaddr); LP_address(relcoin,bids[i]->coinaddr); - if ( relcoin->electrum == 0 ) + //if ( relcoin->electrum == 0 ) LP_listunspent_issue(rel,bids[i]->coinaddr,0); LP_listunspent_query(rel,bids[i]->coinaddr); n++; @@ -837,7 +837,7 @@ char *LP_orderbook(char *base,char *rel,int32_t duration) { //printf("ask ping %s %s\n",base,asks[i]->coinaddr); LP_address(basecoin,asks[i]->coinaddr); - if ( basecoin->electrum == 0 ) + //if ( basecoin->electrum == 0 ) LP_listunspent_issue(base,asks[i]->coinaddr,0); LP_listunspent_query(base,asks[i]->coinaddr); n++; From 10884a398eed21503f9b1fd971b8952d317237c9 Mon Sep 17 00:00:00 2001 From: jl777 Date: Sat, 11 Nov 2017 19:10:54 +0200 Subject: [PATCH 0592/1664] Test --- iguana/exchanges/LP_prices.c | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/iguana/exchanges/LP_prices.c b/iguana/exchanges/LP_prices.c index d86f1bd7f..868975735 100644 --- a/iguana/exchanges/LP_prices.c +++ b/iguana/exchanges/LP_prices.c @@ -765,7 +765,7 @@ int32_t LP_orderbook_utxoentries(uint32_t now,int32_t polarity,char *base,char * char *LP_orderbook(char *base,char *rel,int32_t duration) { - uint32_t now,i; uint64_t depth; struct LP_priceinfo *basepp=0,*relpp=0; struct LP_orderbookentry **bids = 0,**asks = 0; cJSON *retjson,*array; struct iguana_info *basecoin,*relcoin; int32_t n,numbids=0,numasks=0,cachenumbids,cachenumasks,baseid,relid,suppress_prefetch=0; + uint32_t now,i; uint64_t depth; struct LP_priceinfo *basepp=0,*relpp=0; struct LP_orderbookentry **bids = 0,**asks = 0; cJSON *retjson,*tmpjson,*array; struct iguana_info *basecoin,*relcoin; int32_t n,numbids=0,numasks=0,cachenumbids,cachenumasks,baseid,relid,suppress_prefetch=0; basecoin = LP_coinfind(base); relcoin = LP_coinfind(rel); if ( basecoin == 0 || relcoin == 0 ) @@ -817,8 +817,10 @@ char *LP_orderbook(char *base,char *rel,int32_t duration) { //printf("bid ping %s %s\n",rel,bids[i]->coinaddr); LP_address(relcoin,bids[i]->coinaddr); - //if ( relcoin->electrum == 0 ) + if ( relcoin->electrum == 0 ) LP_listunspent_issue(rel,bids[i]->coinaddr,0); + else if ( (tmpjson= LP_listunspent(rel,bids[i]->coinaddr)) != 0 ) + free_json(tmpjson); LP_listunspent_query(rel,bids[i]->coinaddr); n++; } @@ -837,8 +839,10 @@ char *LP_orderbook(char *base,char *rel,int32_t duration) { //printf("ask ping %s %s\n",base,asks[i]->coinaddr); LP_address(basecoin,asks[i]->coinaddr); - //if ( basecoin->electrum == 0 ) + if ( basecoin->electrum == 0 ) LP_listunspent_issue(base,asks[i]->coinaddr,0); + else if ( (tmpjson= LP_listunspent(base,asks[i]->coinaddr)) != 0 ) + free_json(tmpjson); LP_listunspent_query(base,asks[i]->coinaddr); n++; } From ea8aab324b7afa0538a2b5c405e5a82cfb5655e3 Mon Sep 17 00:00:00 2001 From: jl777 Date: Sat, 11 Nov 2017 19:27:58 +0200 Subject: [PATCH 0593/1664] Test --- iguana/exchanges/LP_cache.c | 4 ++-- iguana/exchanges/LP_include.h | 2 +- iguana/exchanges/LP_nativeDEX.c | 4 ++-- iguana/exchanges/LP_ordermatch.c | 2 +- iguana/exchanges/LP_socket.c | 3 ++- 5 files changed, 8 insertions(+), 7 deletions(-) diff --git a/iguana/exchanges/LP_cache.c b/iguana/exchanges/LP_cache.c index e4727a333..d061b0b2a 100644 --- a/iguana/exchanges/LP_cache.c +++ b/iguana/exchanges/LP_cache.c @@ -228,12 +228,12 @@ bits256 LP_merkleroot(struct iguana_info *coin,struct electrum_info *ep,int32_t return(merkleroot); } -int32_t LP_merkleproof(struct iguana_info *coin,struct electrum_info *ep,bits256 txid,int32_t height) +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; if ( height < 0 ) return(0); - if ( (tx= LP_transactionfind(coin,txid)) == 0) + if ( (tx= LP_transactionfind(coin,txid)) == 0 && strcmp(coinaddr,coin->smartaddr) == 0 ) { if ( (retjson= electrum_transaction(coin->symbol,ep,&retjson,txid)) != 0 ) free_json(retjson); diff --git a/iguana/exchanges/LP_include.h b/iguana/exchanges/LP_include.h index 5d2283a1e..273625a41 100644 --- a/iguana/exchanges/LP_include.h +++ b/iguana/exchanges/LP_include.h @@ -428,7 +428,7 @@ int32_t LP_reserved_msg(int32_t priority,char *base,char *rel,bits256 pubkey,cha 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,struct electrum_info *ep,bits256 txid,int32_t height); +int32_t LP_merkleproof(struct iguana_info *coin,char *coinaddr,struct electrum_info *ep,bits256 txid,int32_t height); 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); diff --git a/iguana/exchanges/LP_nativeDEX.c b/iguana/exchanges/LP_nativeDEX.c index 4d25a76aa..e536875e8 100644 --- a/iguana/exchanges/LP_nativeDEX.c +++ b/iguana/exchanges/LP_nativeDEX.c @@ -527,7 +527,7 @@ void LP_coinsloop(void *_coins) if ( up->SPV == 0 ) { nonz++; - up->SPV = LP_merkleproof(coin,backupep,up->U.txid,up->U.height); + up->SPV = LP_merkleproof(coin,coin->smartaddr,backupep,up->U.txid,up->U.height); if ( up->SPV > 0 ) { if ( (tx= LP_transactionfind(coin,up->U.txid)) != 0 && tx->SPV == 0 ) @@ -544,7 +544,7 @@ void LP_coinsloop(void *_coins) oldht = up->U.height; LP_txheight_check(coin,ap->coinaddr,up); if ( oldht != up->U.height ) - up->SPV = LP_merkleproof(coin,backupep,up->U.txid,up->U.height); + up->SPV = LP_merkleproof(coin,coin->smartaddr,backupep,up->U.txid,up->U.height); if ( up->SPV <= 0 ) up->SPV = -2; else printf("%s %s: corrected SPV.%d\n",coin->symbol,bits256_str(str,up->U.txid),up->SPV); diff --git a/iguana/exchanges/LP_ordermatch.c b/iguana/exchanges/LP_ordermatch.c index e034a5de4..617a7af3f 100644 --- a/iguana/exchanges/LP_ordermatch.c +++ b/iguana/exchanges/LP_ordermatch.c @@ -647,7 +647,7 @@ int32_t LP_validSPV(char *symbol,char *coinaddr,bits256 txid,int32_t vout) return(-1); if ( (backupep= ep->prev) == 0 ) backupep = ep; - up->SPV = LP_merkleproof(coin,backupep,up->U.txid,up->U.height); + up->SPV = LP_merkleproof(coin,coinaddr,backupep,up->U.txid,up->U.height); if ( up->SPV <= 0 ) return(-1); } diff --git a/iguana/exchanges/LP_socket.c b/iguana/exchanges/LP_socket.c index 20357071d..e9ba0388b 100644 --- a/iguana/exchanges/LP_socket.c +++ b/iguana/exchanges/LP_socket.c @@ -329,7 +329,8 @@ int32_t electrum_process_array(struct iguana_info *coin,struct electrum_info *ep tx->height = ht; if ( ep != 0 && coin != 0 && tx->SPV == 0 ) { - tx->SPV = LP_merkleproof(coin,ep,txid,tx->height); + if ( strcmp(coinaddr,coin->smartaddr) == 0 ) + tx->SPV = LP_merkleproof(coin,coin->smartaddr,ep,txid,tx->height); //printf("%s %s >>>>>>>>>> set %s <- height %d\n",coin->symbol,coinaddr,bits256_str(str,txid),tx->height); } } From c097611934053087126ff5ab4c27451b10d97040 Mon Sep 17 00:00:00 2001 From: jl777 Date: Sat, 11 Nov 2017 19:32:07 +0200 Subject: [PATCH 0594/1664] Test --- iguana/exchanges/LP_socket.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/iguana/exchanges/LP_socket.c b/iguana/exchanges/LP_socket.c index e9ba0388b..60a7a3835 100644 --- a/iguana/exchanges/LP_socket.c +++ b/iguana/exchanges/LP_socket.c @@ -417,7 +417,7 @@ cJSON *electrum_submit(char *symbol,struct electrum_info *ep,cJSON **retjsonp,ch { *retjsonp = 0; sprintf(stratumreq,"{ \"jsonrpc\":\"2.0\", \"id\": %u, \"method\":\"%s\", \"params\": %s }\n",ep->stratumid,method,params); -printf("%s %s",symbol,stratumreq); +//printf("%s %s",symbol,stratumreq); memset(ep->buf,0,ep->bufsize); sitem = electrum_sitem(ep,stratumreq,timeout,retjsonp); /*sitem = (struct stritem *)queueitem(stratumreq); From 95b25f9072245b226eb03af7f228b6b9f275db73 Mon Sep 17 00:00:00 2001 From: jl777 Date: Sat, 11 Nov 2017 19:35:19 +0200 Subject: [PATCH 0595/1664] Test --- iguana/exchanges/LP_cache.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/iguana/exchanges/LP_cache.c b/iguana/exchanges/LP_cache.c index d061b0b2a..2e06711f4 100644 --- a/iguana/exchanges/LP_cache.c +++ b/iguana/exchanges/LP_cache.c @@ -45,9 +45,9 @@ struct LP_transaction *LP_create_transaction(struct iguana_info *coin,bits256 tx vins = jarray(&numvins,txobj,"vin"); vouts = jarray(&numvouts,txobj,"vout"); tx = LP_transactionadd(coin,txid,height,numvouts,numvins); - tx->serialized = 0; + tx->serialized = serialized; + //free(serialized); tx->fpos = fpos; - free(serialized); tx->len = tx->len; tx->SPV = tx->height = height; //printf("tx.%s numvins.%d numvouts.%d\n",bits256_str(str,txid),numvins,numvouts); From 8265ba228657a399d2363b8b02f0131e9424cc40 Mon Sep 17 00:00:00 2001 From: jl777 Date: Sat, 11 Nov 2017 19:42:28 +0200 Subject: [PATCH 0596/1664] Test --- iguana/exchanges/LP_ordermatch.c | 1 + 1 file changed, 1 insertion(+) diff --git a/iguana/exchanges/LP_ordermatch.c b/iguana/exchanges/LP_ordermatch.c index 617a7af3f..bab638c5c 100644 --- a/iguana/exchanges/LP_ordermatch.c +++ b/iguana/exchanges/LP_ordermatch.c @@ -762,6 +762,7 @@ int32_t LP_tradecommand(void *ctx,char *myipaddr,int32_t pubsock,cJSON *argjson, else { char tmp[64]; + price = (qprice * 0.5) + (0.5 * price); LP_utxos_remove(Q.txid,Q.vout); LP_utxos_remove(Q.txid2,Q.vout2); value = LP_txvalue(tmp,Q.srccoin,Q.txid,Q.vout); From 16721bf44bfd89af67ef523fa1370d611ed6d2a6 Mon Sep 17 00:00:00 2001 From: jl777 Date: Sat, 11 Nov 2017 19:55:26 +0200 Subject: [PATCH 0597/1664] Test --- iguana/exchanges/LP_ordermatch.c | 24 +++++++++++++++++------- 1 file changed, 17 insertions(+), 7 deletions(-) diff --git a/iguana/exchanges/LP_ordermatch.c b/iguana/exchanges/LP_ordermatch.c index bab638c5c..abcc1528c 100644 --- a/iguana/exchanges/LP_ordermatch.c +++ b/iguana/exchanges/LP_ordermatch.c @@ -755,6 +755,9 @@ int32_t LP_tradecommand(void *ctx,char *myipaddr,int32_t pubsock,cJSON *argjson, strcpy(Q.coinaddr,coin->smartaddr); strcpy(butxo->coinaddr,coin->smartaddr); Q.srchash = G.LP_mypub25519; + memset(&Q.txid,0,sizeof(Q.txid)); + memset(&Q.txid2,0,sizeof(Q.txid2)); + Q.vout = Q.vout2 = -1; recalc = 1; } else if ( (qprice= LP_quote_validate(autxo,butxo,&Q,1)) < SMALLVAL ) @@ -763,13 +766,20 @@ int32_t LP_tradecommand(void *ctx,char *myipaddr,int32_t pubsock,cJSON *argjson, { char tmp[64]; price = (qprice * 0.5) + (0.5 * price); - LP_utxos_remove(Q.txid,Q.vout); - LP_utxos_remove(Q.txid2,Q.vout2); - value = LP_txvalue(tmp,Q.srccoin,Q.txid,Q.vout); - value2 = LP_txvalue(tmp,Q.srccoin,Q.txid2,Q.vout2); - printf("call LP_utxoadd.(%s) %.8f %.8f\n",Q.coinaddr,dstr(value),dstr(value2)); - if ( (butxo= LP_utxoadd(1,coin->symbol,Q.txid,Q.vout,value,Q.txid2,Q.vout2,value2,Q.coinaddr,Q.srchash,G.gui,0)) == 0 ) - recalc = 1; + if ( bits256_nonz(Q.txid) != 0 ) + LP_utxos_remove(Q.txid,Q.vout); + else recalc = 1; + if ( bits256_nonz(Q.txid2) != 0 ) + LP_utxos_remove(Q.txid2,Q.vout2); + else recalc = 1; + if ( recalc == 0 ) + { + value = LP_txvalue(tmp,Q.srccoin,Q.txid,Q.vout); + value2 = LP_txvalue(tmp,Q.srccoin,Q.txid2,Q.vout2); + printf("call LP_utxoadd.(%s) %.8f %.8f\n",Q.coinaddr,dstr(value),dstr(value2)); + if ( (butxo= LP_utxoadd(1,coin->symbol,Q.txid,Q.vout,value,Q.txid2,Q.vout2,value2,Q.coinaddr,Q.srchash,G.gui,0)) == 0 ) + recalc = 1; + } else { if ( bits256_cmp(Q.txid,butxo->payment.txid) != 0 || Q.vout != butxo->payment.vout || bits256_cmp(Q.txid2,butxo->deposit.txid) != 0 || Q.vout2 != butxo->deposit.vout ) From e0b10b8144a7194f36555665b657890231b43280 Mon Sep 17 00:00:00 2001 From: jl777 Date: Sat, 11 Nov 2017 20:07:38 +0200 Subject: [PATCH 0598/1664] Test --- iguana/exchanges/LP_utxo.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/iguana/exchanges/LP_utxo.c b/iguana/exchanges/LP_utxo.c index 00b080739..07ffa159b 100644 --- a/iguana/exchanges/LP_utxo.c +++ b/iguana/exchanges/LP_utxo.c @@ -148,7 +148,7 @@ int32_t LP_address_utxo_ptrs(struct iguana_info *coin,int32_t iambob,struct LP_a portable_mutex_lock(&LP_utxomutex); DL_FOREACH_SAFE(ap->utxos,up,tmp) { - char str[65]; printf("LP_address_utxo_ptrs %s n.%d %.8f %s v%d spendheight.%d allocated.%p\n",ap->coinaddr,n,dstr(up->U.value),bits256_str(str,up->U.txid),up->U.vout,up->spendheight,LP_allocated(up->U.txid,up->U.vout)); + //char str[65]; printf("LP_address_utxo_ptrs %s n.%d %.8f %s v%d spendheight.%d allocated.%p\n",ap->coinaddr,n,dstr(up->U.value),bits256_str(str,up->U.txid),up->U.vout,up->spendheight,LP_allocated(up->U.txid,up->U.vout)); if ( up->spendheight <= 0 && LP_RTmetrics_avoidtxid(up->U.txid) < 0 ) { if ( coin->electrum == 0 ) @@ -157,7 +157,7 @@ int32_t LP_address_utxo_ptrs(struct iguana_info *coin,int32_t iambob,struct LP_a { if ( LP_value_extract(txout,0) == 0 ) { - printf("LP_address_utxo_ptrs skip zero value %s/v%d\n",bits256_str(str,up->U.txid),up->U.vout); + //printf("LP_address_utxo_ptrs skip zero value %s/v%d\n",bits256_str(str,up->U.txid),up->U.vout); free_json(txout); up->spendheight = 1; if ( (tx= LP_transactionfind(coin,up->U.txid)) != 0 && up->U.vout < tx->numvouts ) From 331c0c95f1e299e65bb4d0aacd36ef83b18de980 Mon Sep 17 00:00:00 2001 From: jl777 Date: Sat, 11 Nov 2017 20:10:41 +0200 Subject: [PATCH 0599/1664] Test --- iguana/exchanges/LP_utxo.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/iguana/exchanges/LP_utxo.c b/iguana/exchanges/LP_utxo.c index 07ffa159b..2b762ab97 100644 --- a/iguana/exchanges/LP_utxo.c +++ b/iguana/exchanges/LP_utxo.c @@ -179,7 +179,7 @@ int32_t LP_address_utxo_ptrs(struct iguana_info *coin,int32_t iambob,struct LP_a { if ( up->SPV < 0 || up->U.height == 0 ) { -printf("LP_address_utxo_ptrs skips %s/v%u due to SPV.%d ht.%d\n",bits256_str(str,up->U.txid),up->U.vout,up->SPV,up->U.height); +//printf("LP_address_utxo_ptrs skips %s/v%u due to SPV.%d ht.%d\n",bits256_str(str,up->U.txid),up->U.vout,up->SPV,up->U.height); if ( (tx= LP_transactionfind(coin,up->U.txid)) != 0 && up->U.vout < tx->numvouts ) tx->outpoints[up->U.vout].spendheight = 1; continue; From ad9c343cf388b53f522fadbb57e4b3d4b6e55191 Mon Sep 17 00:00:00 2001 From: jl777 Date: Sat, 11 Nov 2017 20:53:45 +0200 Subject: [PATCH 0600/1664] Test --- iguana/exchanges/LP_ordermatch.c | 22 +++++++++++++++------- iguana/exchanges/LP_utxo.c | 16 ++-------------- 2 files changed, 17 insertions(+), 21 deletions(-) diff --git a/iguana/exchanges/LP_ordermatch.c b/iguana/exchanges/LP_ordermatch.c index abcc1528c..179a763a5 100644 --- a/iguana/exchanges/LP_ordermatch.c +++ b/iguana/exchanges/LP_ordermatch.c @@ -269,12 +269,13 @@ uint64_t LP_basesatoshis(double relvolume,double price,uint64_t txfee,uint64_t d struct LP_utxoinfo *LP_address_utxopair(int32_t iambob,struct LP_address_utxo **utxos,int32_t max,struct iguana_info *coin,char *coinaddr,uint64_t txfee,double relvolume,double price,uint64_t desttxfee) { - struct LP_address *ap; uint64_t targetval,targetval2; int32_t m,mini; struct LP_address_utxo *up,*up2; struct LP_utxoinfo *utxo = 0; + struct LP_address *ap; uint64_t targetval,targetval2; int32_t m,mini; struct LP_address_utxo *up,*up2; struct LP_utxoinfo *utxo = 0,*utmp; + targetval = LP_basesatoshis(relvolume,price,txfee,desttxfee); + targetval2 = (targetval / 8) * 9 + 2*txfee; if ( coin != 0 && (ap= LP_addressfind(coin,coinaddr)) != 0 ) { if ( (m= LP_address_utxo_ptrs(coin,iambob,utxos,max,ap,coinaddr)) > 1 ) { - targetval = LP_basesatoshis(relvolume,price,txfee,desttxfee); if ( 1 ) { int32_t i; @@ -287,7 +288,6 @@ 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); if ( (double)up->U.value/targetval < LP_MINVOL-1 ) @@ -309,6 +309,14 @@ struct LP_utxoinfo *LP_address_utxopair(int32_t iambob,struct LP_address_utxo ** printf("targetval %.8f mini.%d\n",dstr(targetval),mini); } //else printf("no %s utxos pass LP_address_utxo_ptrs filter\n",coinaddr); } else printf("couldnt find %s %s\n",coin->symbol,coinaddr); + HASH_ITER(hh,G.LP_utxoinfos[iambob],utxo,utmp) + { + if ( LP_isavailable(utxo) != 0 && utxo->payment.value >= targetval && targetval >= utxo->payment.value/2 && utxo->deposit.value >= targetval2 ) + { + printf("backup method found utxo!\n"); + return(utxo); + } + } return(0); } @@ -359,7 +367,7 @@ int32_t LP_connectstartbob(void *ctx,int32_t pubsock,struct LP_utxoinfo *utxo,cJ privkey = LP_privkey(utxo->coinaddr,coin->taddr); if ( bits256_nonz(privkey) != 0 && bits256_cmp(G.LP_mypub25519,qp->srchash) == 0 ) //qp->quotetime >= qp->timestamp-3 && qp->quotetime <= utxo->T.swappending && { - 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); + LP_requestinit(&qp->R,qp->srchash,qp->desthash,base,qp->satoshis-qp->txfee,rel,qp->destsatoshis-qp->desttxfee,qp->timestamp,qp->quotetime,DEXselector); if ( (swap= LP_swapinit(1,0,privkey,&qp->R,qp)) == 0 ) { printf("cant initialize swap\n"); @@ -522,7 +530,7 @@ char *LP_connectedalice(cJSON *argjson) // alice if ( bits256_nonz(Q.privkey) != 0 )//&& Q.quotetime >= Q.timestamp-3 ) { retjson = cJSON_CreateObject(); - 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); + LP_requestinit(&Q.R,Q.srchash,Q.desthash,Q.srccoin,Q.satoshis-Q.txfee,Q.destcoin,Q.destsatoshis-Q.desttxfee,Q.timestamp,Q.quotetime,DEXselector); if ( (swap= LP_swapinit(0,0,Q.privkey,&Q.R,&Q)) == 0 ) { jaddstr(retjson,"error","couldnt swapinit"); @@ -662,7 +670,7 @@ int32_t LP_tradecommand(void *ctx,char *myipaddr,int32_t pubsock,cJSON *argjson, { // LP_checksig 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); + LP_requestinit(&Q.R,Q.srchash,Q.desthash,Q.srccoin,Q.satoshis-Q.txfee,Q.destcoin,Q.destsatoshis-Q.desttxfee,Q.timestamp,Q.quotetime,DEXselector); LP_tradecommand_log(argjson); //printf("LP_tradecommand: check received method %s aliceid.%llx\n",method,(long long)Q.aliceid); retval = 1; @@ -794,7 +802,7 @@ int32_t LP_tradecommand(void *ctx,char *myipaddr,int32_t pubsock,cJSON *argjson, printf("request from blacklisted %s, ignore\n",bits256_str(str,Q.desthash)); return(retval); } - printf("butxo.%p recalc 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)); + //printf("butxo.%p recalc 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,0); if ( (butxo= LP_address_utxopair(1,utxos,max,LP_coinfind(Q.srccoin),Q.coinaddr,Q.txfee,dstr(Q.destsatoshis),price,Q.desttxfee)) != 0 ) { diff --git a/iguana/exchanges/LP_utxo.c b/iguana/exchanges/LP_utxo.c index 2b762ab97..473e66b7d 100644 --- a/iguana/exchanges/LP_utxo.c +++ b/iguana/exchanges/LP_utxo.c @@ -185,7 +185,7 @@ int32_t LP_address_utxo_ptrs(struct iguana_info *coin,int32_t iambob,struct LP_a continue; } } - if ( LP_allocated(up->U.txid,up->U.vout) == 0 && _LP_utxos_remove(up->U.txid,up->U.vout) == 0 ) + if ( LP_allocated(up->U.txid,up->U.vout) == 0 && _LP_utxofind(iambob,up->U.txid,up->U.vout) == 0 && _LP_utxo2find(iambob,up->U.txid,up->U.vout) == 0 ) { utxos[n++] = up; if ( n >= max ) @@ -468,15 +468,8 @@ void LP_utxosetkey(uint8_t *key,bits256 txid,int32_t vout) struct LP_utxoinfo *_LP_utxofind(int32_t iambob,bits256 txid,int32_t vout) { struct LP_utxoinfo *utxo=0; uint8_t key[sizeof(txid) + sizeof(vout)]; - /*if ( iambob != 0 ) - { - static uint32_t counter; - if ( counter++ < 3 ) - printf("_LP_utxofind deprecated iambob\n"); - return(0); - }*/ LP_utxosetkey(key,txid,vout); - HASH_FIND(hh,G.LP_utxoinfos[iambob],key,sizeof(key),utxo); + HASH_FIND(hh,G.LP_utxoinfos[iambob!=0],key,sizeof(key),utxo); return(utxo); } @@ -493,11 +486,6 @@ void _LP_utxo2_delete(int32_t iambob,struct LP_utxoinfo *utxo) struct LP_utxoinfo *_LP_utxo2find(int32_t iambob,bits256 txid2,int32_t vout2) { struct LP_utxoinfo *utxo=0; uint8_t key2[sizeof(txid2) + sizeof(vout2)]; - /*if ( iambob != 0 ) - { - printf("_LP_utxo2find deprecated iambob\n"); - return(0); - }*/ LP_utxosetkey(key2,txid2,vout2); HASH_FIND(hh2,G.LP_utxoinfos2[iambob],key2,sizeof(key2),utxo); return(utxo); From 448c0a5a0f29a4deb3323d3b225797eb347b17b5 Mon Sep 17 00:00:00 2001 From: jl777 Date: Sat, 11 Nov 2017 21:09:22 +0200 Subject: [PATCH 0601/1664] Test --- iguana/exchanges/LP_ordermatch.c | 1 + iguana/exchanges/LP_utxo.c | 39 +++++++++++++++++++------------- 2 files changed, 24 insertions(+), 16 deletions(-) diff --git a/iguana/exchanges/LP_ordermatch.c b/iguana/exchanges/LP_ordermatch.c index 179a763a5..229ffba74 100644 --- a/iguana/exchanges/LP_ordermatch.c +++ b/iguana/exchanges/LP_ordermatch.c @@ -813,6 +813,7 @@ int32_t LP_tradecommand(void *ctx,char *myipaddr,int32_t pubsock,cJSON *argjson, Q.vout = butxo->payment.vout; Q.txid2 = butxo->deposit.txid; Q.vout2 = butxo->deposit.vout; + butxo->S.satoshis = Q.satoshis; printf("set butxo.%p %s/v%d %s/v%d %.8f %.8f -> bsat %.8f asat %.8f\n",butxo,bits256_str(str,butxo->payment.txid),butxo->payment.vout,bits256_str(str2,butxo->deposit.txid),butxo->deposit.vout,dstr(butxo->payment.value),dstr(butxo->deposit.value),dstr(butxo->S.satoshis),dstr(autxo->S.satoshis)); } else diff --git a/iguana/exchanges/LP_utxo.c b/iguana/exchanges/LP_utxo.c index 473e66b7d..4a46e48e3 100644 --- a/iguana/exchanges/LP_utxo.c +++ b/iguana/exchanges/LP_utxo.c @@ -812,25 +812,32 @@ int32_t LP_iseligible(uint64_t *valp,uint64_t *val2p,int32_t iambob,char *symbol strcpy(destaddr,destaddr2); if ( coin != 0 ) { - if ( (tx= LP_transactionfind(coin,txid)) != 0 && vout < tx->numvouts && tx->outpoints[vout].spendheight > 0 ) + if ( coin->electrum != 0 ) { - //printf("txid spent\n"); - return(0); - } - if ( (tx= LP_transactionfind(coin,txid2)) != 0 && vout2 < tx->numvouts && tx->outpoints[vout2].spendheight > 0 ) - { - //printf("txid2 spent\n"); - return(0); - } - if ( (up= LP_address_utxofind(coin,destaddr,txid,vout)) != 0 && up->spendheight > 0 ) - { - //printf("txid %s spentB\n",destaddr); - return(0); + if ( (tx= LP_transactionfind(coin,txid)) != 0 && vout < tx->numvouts && tx->outpoints[vout].spendheight > 0 ) + { + //printf("txid spent\n"); + return(0); + } + if ( (tx= LP_transactionfind(coin,txid2)) != 0 && vout2 < tx->numvouts && tx->outpoints[vout2].spendheight > 0 ) + { + //printf("txid2 spent\n"); + return(0); + } + if ( (up= LP_address_utxofind(coin,destaddr,txid,vout)) != 0 && up->spendheight > 0 ) + { + //printf("txid %s spentB\n",destaddr); + return(0); + } + if ( (up= LP_address_utxofind(coin,destaddr,txid2,vout2)) != 0 && up->spendheight > 0 ) + { + //printf("txid2 %s spentB\n",destaddr); + return(0); + } } - if ( (up= LP_address_utxofind(coin,destaddr,txid2,vout2)) != 0 && up->spendheight > 0 ) + else { - //printf("txid2 %s spentB\n",destaddr); - return(0); + } } return(1); From 2a33b0903a2db88913fac8018c5d3b0f06061f00 Mon Sep 17 00:00:00 2001 From: jl777 Date: Sat, 11 Nov 2017 21:32:32 +0200 Subject: [PATCH 0602/1664] Test --- iguana/exchanges/LP_ordermatch.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/iguana/exchanges/LP_ordermatch.c b/iguana/exchanges/LP_ordermatch.c index 229ffba74..4561f816d 100644 --- a/iguana/exchanges/LP_ordermatch.c +++ b/iguana/exchanges/LP_ordermatch.c @@ -276,7 +276,7 @@ struct LP_utxoinfo *LP_address_utxopair(int32_t iambob,struct LP_address_utxo ** { if ( (m= LP_address_utxo_ptrs(coin,iambob,utxos,max,ap,coinaddr)) > 1 ) { - if ( 1 ) + if ( 0 ) { int32_t i; for (i=0; i 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 ) { From 00ebd4731f233af33417cf95a84859eaf6f0bdfe Mon Sep 17 00:00:00 2001 From: jl777 Date: Sat, 11 Nov 2017 21:34:34 +0200 Subject: [PATCH 0603/1664] Test --- iguana/exchanges/LP_ordermatch.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/iguana/exchanges/LP_ordermatch.c b/iguana/exchanges/LP_ordermatch.c index 4561f816d..09e779bee 100644 --- a/iguana/exchanges/LP_ordermatch.c +++ b/iguana/exchanges/LP_ordermatch.c @@ -755,7 +755,7 @@ int32_t LP_tradecommand(void *ctx,char *myipaddr,int32_t pubsock,cJSON *argjson, if ( strcmp(method,"request") == 0 ) { char str[65],str2[65]; - printf("address.(%s/%s) request.(%s)\n",Q.coinaddr,coin->smartaddr,jprint(argjson,0)); + //printf("address.(%s/%s) request.(%s)\n",Q.coinaddr,coin->smartaddr,jprint(argjson,0)); recalc = 0; if ( bits256_cmp(Q.srchash,G.LP_mypub25519) != 0 || strcmp(butxo->coinaddr,coin->smartaddr) != 0 ) { @@ -784,7 +784,7 @@ int32_t LP_tradecommand(void *ctx,char *myipaddr,int32_t pubsock,cJSON *argjson, { value = LP_txvalue(tmp,Q.srccoin,Q.txid,Q.vout); value2 = LP_txvalue(tmp,Q.srccoin,Q.txid2,Q.vout2); - printf("call LP_utxoadd.(%s) %.8f %.8f\n",Q.coinaddr,dstr(value),dstr(value2)); + //printf("call LP_utxoadd.(%s) %.8f %.8f\n",Q.coinaddr,dstr(value),dstr(value2)); if ( (butxo= LP_utxoadd(1,coin->symbol,Q.txid,Q.vout,value,Q.txid2,Q.vout2,value2,Q.coinaddr,Q.srchash,G.gui,0)) == 0 ) recalc = 1; } @@ -818,7 +818,7 @@ int32_t LP_tradecommand(void *ctx,char *myipaddr,int32_t pubsock,cJSON *argjson, } else { - printf("cant find utxopair\n"); + //printf("cant find utxopair\n"); return(retval); } } From 3e00def8443cdf6353a829f8fc056ad66bcb204d Mon Sep 17 00:00:00 2001 From: jl777 Date: Sat, 11 Nov 2017 21:55:11 +0200 Subject: [PATCH 0604/1664] Test --- iguana/exchanges/LP_ordermatch.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/iguana/exchanges/LP_ordermatch.c b/iguana/exchanges/LP_ordermatch.c index 09e779bee..c85731001 100644 --- a/iguana/exchanges/LP_ordermatch.c +++ b/iguana/exchanges/LP_ordermatch.c @@ -424,6 +424,8 @@ char *LP_trade(void *ctx,char *myipaddr,int32_t mypubsock,struct LP_quoteinfo *q return(clonestr("{\"error\":\"cant find alice utxopair\"}")); } price = 0.; + memset(qp->txid.bytes,0,sizeof(qp->txid)); + qp->txid2 = qp->txid; qp->aliceid = LP_aliceid_calc(qp->desttxid,qp->destvout,qp->feetxid,qp->feevout); qp->tradeid = tradeid; LP_query(ctx,myipaddr,mypubsock,"request",qp); @@ -1071,6 +1073,7 @@ char *LP_autobuy(void *ctx,char *myipaddr,int32_t mypubsock,char *base,char *rel return(clonestr("{\"error\":\"cant find alice utxo that is small enough\"}")); } LP_RTmetrics_update(base,rel); + return(LP_trade(ctx,myipaddr,mypubsock,&Q,maxprice,timeout,duration,tradeid)); while ( 1 ) { if ( (bestutxo= LP_buyutxo(&ordermatchprice,&bestsatoshis,&bestdestsatoshis,autxo,base,maxprice,duration,txfee,desttxfee,gui,pubkeys,numpubs,destpubkey)) == 0 || ordermatchprice == 0. || bestdestsatoshis == 0 ) From a4e4bef43ac2e01b6282bd4f4ca3af9bf89f844b Mon Sep 17 00:00:00 2001 From: jl777 Date: Sat, 11 Nov 2017 22:04:58 +0200 Subject: [PATCH 0605/1664] Test --- iguana/exchanges/LP_socket.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/iguana/exchanges/LP_socket.c b/iguana/exchanges/LP_socket.c index 60a7a3835..6890371db 100644 --- a/iguana/exchanges/LP_socket.c +++ b/iguana/exchanges/LP_socket.c @@ -424,12 +424,12 @@ cJSON *electrum_submit(char *symbol,struct electrum_info *ep,cJSON **retjsonp,ch sitem->expiration = timeout; sitem->DL.type = ep->stratumid++; sitem->retptrp = (void **)retjsonp;*/ -//portable_mutex_lock(&ep->mutex); +portable_mutex_lock(&ep->mutex); //queue_enqueue("sendQ",&ep->sendQ,&sitem->DL); expiration = (uint32_t)time(NULL) + timeout + 1; while ( *retjsonp == 0 && time(NULL) <= expiration ) usleep(15000); -//portable_mutex_unlock(&ep->mutex); +portable_mutex_unlock(&ep->mutex); if ( *retjsonp == 0 || jobj(*retjsonp,"error") != 0 ) { if ( ++ep->numerrors >= LP_ELECTRUM_MAXERRORS ) From af148d931ab197dc7ba6d27dc9767af6e3283e3e Mon Sep 17 00:00:00 2001 From: jl777 Date: Sat, 11 Nov 2017 22:09:35 +0200 Subject: [PATCH 0606/1664] Test --- iguana/exchanges/LP_prices.c | 22 +++++++++++++--------- iguana/exchanges/LP_socket.c | 9 ++------- 2 files changed, 15 insertions(+), 16 deletions(-) diff --git a/iguana/exchanges/LP_prices.c b/iguana/exchanges/LP_prices.c index 868975735..66bb2fdc3 100644 --- a/iguana/exchanges/LP_prices.c +++ b/iguana/exchanges/LP_prices.c @@ -765,7 +765,7 @@ int32_t LP_orderbook_utxoentries(uint32_t now,int32_t polarity,char *base,char * char *LP_orderbook(char *base,char *rel,int32_t duration) { - uint32_t now,i; uint64_t depth; struct LP_priceinfo *basepp=0,*relpp=0; struct LP_orderbookentry **bids = 0,**asks = 0; cJSON *retjson,*tmpjson,*array; struct iguana_info *basecoin,*relcoin; int32_t n,numbids=0,numasks=0,cachenumbids,cachenumasks,baseid,relid,suppress_prefetch=0; + uint32_t now,i; uint64_t depth; struct LP_priceinfo *basepp=0,*relpp=0; struct LP_orderbookentry **bids = 0,**asks = 0; cJSON *retjson,*array; struct iguana_info *basecoin,*relcoin; int32_t n,numbids=0,numasks=0,cachenumbids,cachenumasks,baseid,relid,suppress_prefetch=0; basecoin = LP_coinfind(base); relcoin = LP_coinfind(rel); if ( basecoin == 0 || relcoin == 0 ) @@ -813,15 +813,17 @@ char *LP_orderbook(char *base,char *rel,int32_t duration) for (i=n=0; inumutxos < 3 ) + if ( suppress_prefetch == 0 && n < 3 && bids[i]->numutxos == 0 ) { //printf("bid ping %s %s\n",rel,bids[i]->coinaddr); LP_address(relcoin,bids[i]->coinaddr); if ( relcoin->electrum == 0 ) + { LP_listunspent_issue(rel,bids[i]->coinaddr,0); - else if ( (tmpjson= LP_listunspent(rel,bids[i]->coinaddr)) != 0 ) - free_json(tmpjson); - LP_listunspent_query(rel,bids[i]->coinaddr); + //else if ( (tmpjson= LP_listunspent(rel,bids[i]->coinaddr)) != 0 ) + // free_json(tmpjson); + LP_listunspent_query(rel,bids[i]->coinaddr); + } n++; } free(bids[i]); @@ -835,15 +837,17 @@ char *LP_orderbook(char *base,char *rel,int32_t duration) for (i=n=0; inumutxos < 3 ) + if ( suppress_prefetch == 0 && n < 3 && asks[i]->numutxos == 0 ) { //printf("ask ping %s %s\n",base,asks[i]->coinaddr); LP_address(basecoin,asks[i]->coinaddr); if ( basecoin->electrum == 0 ) + { LP_listunspent_issue(base,asks[i]->coinaddr,0); - else if ( (tmpjson= LP_listunspent(base,asks[i]->coinaddr)) != 0 ) - free_json(tmpjson); - LP_listunspent_query(base,asks[i]->coinaddr); + //else if ( (tmpjson= LP_listunspent(base,asks[i]->coinaddr)) != 0 ) + // free_json(tmpjson); + LP_listunspent_query(base,asks[i]->coinaddr); + } n++; } free(asks[i]); diff --git a/iguana/exchanges/LP_socket.c b/iguana/exchanges/LP_socket.c index 6890371db..5be93ba33 100644 --- a/iguana/exchanges/LP_socket.c +++ b/iguana/exchanges/LP_socket.c @@ -420,16 +420,11 @@ cJSON *electrum_submit(char *symbol,struct electrum_info *ep,cJSON **retjsonp,ch //printf("%s %s",symbol,stratumreq); memset(ep->buf,0,ep->bufsize); sitem = electrum_sitem(ep,stratumreq,timeout,retjsonp); - /*sitem = (struct stritem *)queueitem(stratumreq); - sitem->expiration = timeout; - sitem->DL.type = ep->stratumid++; - sitem->retptrp = (void **)retjsonp;*/ -portable_mutex_lock(&ep->mutex); - //queue_enqueue("sendQ",&ep->sendQ,&sitem->DL); + portable_mutex_lock(&ep->mutex); // this helps performance! expiration = (uint32_t)time(NULL) + timeout + 1; while ( *retjsonp == 0 && time(NULL) <= expiration ) usleep(15000); -portable_mutex_unlock(&ep->mutex); + portable_mutex_unlock(&ep->mutex); if ( *retjsonp == 0 || jobj(*retjsonp,"error") != 0 ) { if ( ++ep->numerrors >= LP_ELECTRUM_MAXERRORS ) From 789df311533c65c77aeafc1af26a05c6f02d9af8 Mon Sep 17 00:00:00 2001 From: jl777 Date: Sat, 11 Nov 2017 22:13:54 +0200 Subject: [PATCH 0607/1664] Test --- iguana/exchanges/LP_ordermatch.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/iguana/exchanges/LP_ordermatch.c b/iguana/exchanges/LP_ordermatch.c index c85731001..cf65a2b8e 100644 --- a/iguana/exchanges/LP_ordermatch.c +++ b/iguana/exchanges/LP_ordermatch.c @@ -1073,7 +1073,7 @@ char *LP_autobuy(void *ctx,char *myipaddr,int32_t mypubsock,char *base,char *rel return(clonestr("{\"error\":\"cant find alice utxo that is small enough\"}")); } LP_RTmetrics_update(base,rel); - return(LP_trade(ctx,myipaddr,mypubsock,&Q,maxprice,timeout,duration,tradeid)); + //return(LP_trade(ctx,myipaddr,mypubsock,&Q,maxprice,timeout,duration,tradeid)); while ( 1 ) { if ( (bestutxo= LP_buyutxo(&ordermatchprice,&bestsatoshis,&bestdestsatoshis,autxo,base,maxprice,duration,txfee,desttxfee,gui,pubkeys,numpubs,destpubkey)) == 0 || ordermatchprice == 0. || bestdestsatoshis == 0 ) From 4700d321feb9688cbe7ffba5912fef13bc88175b Mon Sep 17 00:00:00 2001 From: jl777 Date: Sat, 11 Nov 2017 22:20:05 +0200 Subject: [PATCH 0608/1664] Test --- iguana/exchanges/LP_include.h | 2 +- iguana/exchanges/LP_ordermatch.c | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/iguana/exchanges/LP_include.h b/iguana/exchanges/LP_include.h index 273625a41..787d6c57f 100644 --- a/iguana/exchanges/LP_include.h +++ b/iguana/exchanges/LP_include.h @@ -43,7 +43,7 @@ void emscripten_usleep(int32_t x); // returns immediate, no sense for sleeping #define LP_MAXVINS 64 #define LP_HTTP_TIMEOUT 3 // 1 is too small due to edge cases of time(NULL) -#define LP_AUTOTRADE_TIMEOUT 30 +#define LP_AUTOTRADE_TIMEOUT 40 #define ELECTRUM_TIMEOUT 7 #define LP_ELECTRUM_KEEPALIVE 60 #define LP_ELECTRUM_MAXERRORS 777 diff --git a/iguana/exchanges/LP_ordermatch.c b/iguana/exchanges/LP_ordermatch.c index cf65a2b8e..ed736ed3a 100644 --- a/iguana/exchanges/LP_ordermatch.c +++ b/iguana/exchanges/LP_ordermatch.c @@ -459,7 +459,7 @@ void LP_reserved(void *ctx,char *myipaddr,int32_t mypubsock,struct LP_quoteinfo if ( LP_alice_eligible() > 0 && 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 ) + if ( LP_pricevalid(price) > 0 && maxprice > SMALLVAL && price <= maxprice*1.005 ) { qp->tradeid = LP_Alicequery.tradeid; memset(&LP_Alicequery,0,sizeof(LP_Alicequery)); @@ -904,7 +904,7 @@ struct LP_utxoinfo *LP_ordermatch_iter(struct LP_address_utxo **utxos,int32_t ma { uint64_t basesatoshis; struct LP_utxoinfo *bestutxo; basesatoshis = LP_basesatoshis(dstr(asatoshis),price,txfee,desttxfee); - printf("basesatoshis %.8f price %.8f txfee %.8f desttxfee %.8f\n",dstr(basesatoshis),price,dstr(txfee),dstr(desttxfee)); + //printf("basesatoshis %.8f price %.8f txfee %.8f desttxfee %.8f\n",dstr(basesatoshis),price,dstr(txfee),dstr(desttxfee)); if ( basesatoshis != 0 && (bestutxo= LP_address_utxopair(0,utxos,max,basecoin,coinaddr,txfee,dstr(basesatoshis)*price,price,desttxfee)) != 0 ) { bestutxo->pubkey = pubkey; From dcb5fdec1827983e368d6db9cccbb304f0e77ffc Mon Sep 17 00:00:00 2001 From: jl777 Date: Sat, 11 Nov 2017 22:27:22 +0200 Subject: [PATCH 0609/1664] Test --- iguana/exchanges/LP_nativeDEX.c | 2 ++ iguana/exchanges/LP_transaction.c | 2 +- 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/iguana/exchanges/LP_nativeDEX.c b/iguana/exchanges/LP_nativeDEX.c index e536875e8..9bed33bbc 100644 --- a/iguana/exchanges/LP_nativeDEX.c +++ b/iguana/exchanges/LP_nativeDEX.c @@ -519,6 +519,8 @@ void LP_coinsloop(void *_coins) //HASH_ITER(hh,coin->addresses,ap,atmp) if ( (ap= LP_addressfind(coin,coin->smartaddr)) != 0 ) { + if ( (retjson= electrum_address_listunspent(coin->symbol,ep,&retjson,ap->coinaddr,1)) != 0 ) + free_json(retjson); DL_FOREACH_SAFE(ap->utxos,up,tmp) { break; diff --git a/iguana/exchanges/LP_transaction.c b/iguana/exchanges/LP_transaction.c index 91bdb2f2d..abeaf8ff0 100644 --- a/iguana/exchanges/LP_transaction.c +++ b/iguana/exchanges/LP_transaction.c @@ -1820,7 +1820,7 @@ int32_t LP_verify_otherfee(struct basilisk_swap *swap,uint8_t *data,int32_t data diff = swap->otherfee.I.locktime - (swap->I.started+1); if ( diff < 0 ) diff = -diff; - if ( diff == 0 ) + if ( diff < 10 ) printf("dexfee verified\n"); else printf("locktime mismatch in otherfee, reject %u vs %u\n",swap->otherfee.I.locktime,swap->I.started+1); return(0); From 9e43fe980907627e60f2fe7621a5446c2aabfc89 Mon Sep 17 00:00:00 2001 From: jl777 Date: Sat, 11 Nov 2017 22:55:36 +0200 Subject: [PATCH 0610/1664] Test --- iguana/exchanges/LP_ordermatch.c | 3 ++- iguana/exchanges/LP_swap.c | 2 +- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/iguana/exchanges/LP_ordermatch.c b/iguana/exchanges/LP_ordermatch.c index ed736ed3a..8a4962afe 100644 --- a/iguana/exchanges/LP_ordermatch.c +++ b/iguana/exchanges/LP_ordermatch.c @@ -313,6 +313,7 @@ struct LP_utxoinfo *LP_address_utxopair(int32_t iambob,struct LP_address_utxo ** { if ( LP_isavailable(utxo) != 0 && utxo->payment.value >= targetval && targetval >= utxo->payment.value/2 && utxo->deposit.value >= targetval2 ) { + utxo->S.satoshis = targetval; printf("backup method found utxo!\n"); return(utxo); } @@ -954,7 +955,7 @@ struct LP_utxoinfo *LP_buyutxo(double *ordermatchpricep,int64_t *bestsatoshisp,i continue; if ( LP_RTmetrics_blacklisted(pubkey) >= 0 ) continue; -printf("[%d/%d] %s pubcmp %d price %.8f vs maxprice %.8f asatoshis %.8f\n",i,numasks,jprint(item,0),bits256_cmp(pubkey,G.LP_mypub25519),price,maxprice,dstr(autxo->S.satoshis)); +//printf("[%d/%d] %s pubcmp %d price %.8f vs maxprice %.8f asatoshis %.8f\n",i,numasks,jprint(item,0),bits256_cmp(pubkey,G.LP_mypub25519),price,maxprice,dstr(autxo->S.satoshis)); if ( LP_pricevalid(price) > 0 && price <= maxprice ) { if ( bits256_nonz(destpubkey) == 0 ) diff --git a/iguana/exchanges/LP_swap.c b/iguana/exchanges/LP_swap.c index 8671759fc..c7d3c4033 100644 --- a/iguana/exchanges/LP_swap.c +++ b/iguana/exchanges/LP_swap.c @@ -626,7 +626,7 @@ int32_t LP_rawtx_spendscript(struct basilisk_swap *swap,int32_t height,struct ba txfee = swap->I.Atxfee; else txfee = LP_MIN_TXFEE; } - if ( j64bits(vout,"satoshis") >= rawtx->I.amount-txfee && (skey= jobj(vout,"scriptPubKey")) != 0 && (hexstr= jstr(skey,"hex")) != 0 ) + if ( j64bits(vout,"satoshis") >= rawtx->I.amount-2*txfee && (skey= jobj(vout,"scriptPubKey")) != 0 && (hexstr= jstr(skey,"hex")) != 0 ) { if ( (hexlen= (int32_t)strlen(hexstr) >> 1) < sizeof(rawtx->spendscript) ) { From 961f70103083c5dc874e2fcc658efaca78736221 Mon Sep 17 00:00:00 2001 From: jl777 Date: Sat, 11 Nov 2017 23:10:18 +0200 Subject: [PATCH 0611/1664] Test --- iguana/exchanges/LP_ordermatch.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/iguana/exchanges/LP_ordermatch.c b/iguana/exchanges/LP_ordermatch.c index 8a4962afe..c28343b32 100644 --- a/iguana/exchanges/LP_ordermatch.c +++ b/iguana/exchanges/LP_ordermatch.c @@ -309,7 +309,7 @@ struct LP_utxoinfo *LP_address_utxopair(int32_t iambob,struct LP_address_utxo ** printf("targetval %.8f mini.%d\n",dstr(targetval),mini); } //else printf("no %s utxos pass LP_address_utxo_ptrs filter\n",coinaddr); } else printf("couldnt find %s %s\n",coin->symbol,coinaddr); - HASH_ITER(hh,G.LP_utxoinfos[iambob],utxo,utmp) + /*HASH_ITER(hh,G.LP_utxoinfos[iambob],utxo,utmp) { if ( LP_isavailable(utxo) != 0 && utxo->payment.value >= targetval && targetval >= utxo->payment.value/2 && utxo->deposit.value >= targetval2 ) { @@ -317,7 +317,7 @@ struct LP_utxoinfo *LP_address_utxopair(int32_t iambob,struct LP_address_utxo ** printf("backup method found utxo!\n"); return(utxo); } - } + }*/ return(0); } From 712e8a4c265aac9318128c391283d72df17eccf5 Mon Sep 17 00:00:00 2001 From: jl777 Date: Sat, 11 Nov 2017 23:52:11 +0200 Subject: [PATCH 0612/1664] Test --- iguana/exchanges/LP_utxo.c | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/iguana/exchanges/LP_utxo.c b/iguana/exchanges/LP_utxo.c index 4a46e48e3..e76b74a54 100644 --- a/iguana/exchanges/LP_utxo.c +++ b/iguana/exchanges/LP_utxo.c @@ -779,7 +779,7 @@ uint64_t LP_txvalue(char *coinaddr,char *symbol,bits256 txid,int32_t vout) 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) { - uint64_t val,val2=0,txfee,threshold=0; int32_t bypass = 0; char destaddr[64],destaddr2[64]; struct LP_transaction *tx; struct LP_address_utxo *up; struct iguana_info *coin = LP_coinfind(symbol); + uint64_t val,val2=0,txfee,threshold=0; cJSON *txobj; int32_t bypass = 0; char destaddr[64],destaddr2[64]; struct LP_transaction *tx; struct LP_address_utxo *up; struct iguana_info *coin = LP_coinfind(symbol); if ( bits256_nonz(txid) == 0 || bits256_nonz(txid2) == 0 ) { printf("null txid not eligible\n"); @@ -837,7 +837,12 @@ int32_t LP_iseligible(uint64_t *valp,uint64_t *val2p,int32_t iambob,char *symbol } else { - + if ( (txobj= LP_gettxout(coin->symbol,destaddr,txid,vout)) == 0 ) + return(0); + else free_json(txobj); + if ( (txobj= LP_gettxout(coin->symbol,destaddr,txid2,vout2)) == 0 ) + return(0); + else free_json(txobj); } } return(1); From 9c9d4dbabfa6e963908ff6b2f0685266a99b4113 Mon Sep 17 00:00:00 2001 From: jl777 Date: Sat, 11 Nov 2017 23:54:54 +0200 Subject: [PATCH 0613/1664] Test --- iguana/exchanges/LP_ordermatch.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/iguana/exchanges/LP_ordermatch.c b/iguana/exchanges/LP_ordermatch.c index c28343b32..1b080de14 100644 --- a/iguana/exchanges/LP_ordermatch.c +++ b/iguana/exchanges/LP_ordermatch.c @@ -115,7 +115,7 @@ double LP_quote_validate(struct LP_utxoinfo *autxo,struct LP_utxoinfo *butxo,str { if ( LP_iseligible(&destvalue,&destvalue2,0,qp->destcoin,qp->desttxid,qp->destvout,qp->destsatoshis,qp->feetxid,qp->feevout) == 0 ) { - char str[65]; printf("alice not eligible (%.8f %.8f) %s/v%d\n",dstr(destvalue),dstr(destvalue2),bits256_str(str,qp->feetxid),qp->feevout); + char str[65]; printf("alice not eligible destsatoshis %.8f (%.8f %.8f) %s/v%d\n",dstr(qp->destsatoshis),dstr(destvalue),dstr(destvalue2),bits256_str(str,qp->feetxid),qp->feevout); return(-3); } if ( (txout= LP_gettxout(qp->destcoin,qp->destaddr,qp->desttxid,qp->destvout)) != 0 ) @@ -269,7 +269,7 @@ uint64_t LP_basesatoshis(double relvolume,double price,uint64_t txfee,uint64_t d struct LP_utxoinfo *LP_address_utxopair(int32_t iambob,struct LP_address_utxo **utxos,int32_t max,struct iguana_info *coin,char *coinaddr,uint64_t txfee,double relvolume,double price,uint64_t desttxfee) { - struct LP_address *ap; uint64_t targetval,targetval2; int32_t m,mini; struct LP_address_utxo *up,*up2; struct LP_utxoinfo *utxo = 0,*utmp; + struct LP_address *ap; uint64_t targetval,targetval2; int32_t m,mini; struct LP_address_utxo *up,*up2; struct LP_utxoinfo *utxo = 0;//,*utmp; targetval = LP_basesatoshis(relvolume,price,txfee,desttxfee); targetval2 = (targetval / 8) * 9 + 2*txfee; if ( coin != 0 && (ap= LP_addressfind(coin,coinaddr)) != 0 ) From 13af7a3da3cec40fc80dc6dd3240947db73626c7 Mon Sep 17 00:00:00 2001 From: jl777 Date: Sun, 12 Nov 2017 00:17:36 +0200 Subject: [PATCH 0614/1664] Test --- iguana/exchanges/LP_ordermatch.c | 6 +++--- iguana/exchanges/LP_utxos.c | 24 ++++++++++++------------ 2 files changed, 15 insertions(+), 15 deletions(-) diff --git a/iguana/exchanges/LP_ordermatch.c b/iguana/exchanges/LP_ordermatch.c index 1b080de14..4cb3e0bfc 100644 --- a/iguana/exchanges/LP_ordermatch.c +++ b/iguana/exchanges/LP_ordermatch.c @@ -296,7 +296,7 @@ struct LP_utxoinfo *LP_address_utxopair(int32_t iambob,struct LP_address_utxo ** { if ( up != 0 && (up2= utxos[mini]) != 0 ) { - if ( (utxo= LP_utxoadd(1,coin->symbol,up->U.txid,up->U.vout,up->U.value,up2->U.txid,up2->U.vout,up2->U.value,coinaddr,ap->pubkey,G.gui,0)) != 0 ) + if ( (utxo= LP_utxoadd(1,coin->symbol,up->U.txid,up->U.vout,up->U.value,up2->U.txid,up2->U.vout,up2->U.value,coinaddr,ap->pubkey,G.gui,0,targetval)) != 0 ) { utxo->S.satoshis = targetval; char str[65],str2[65]; printf("butxo.%p targetval %.8f, found val %.8f %s | targetval2 %.8f val2 %.8f %s\n",utxo,dstr(targetval),dstr(up->U.value),bits256_str(str,utxo->payment.txid),dstr(targetval2),dstr(up2->U.value),bits256_str(str2,utxo->deposit.txid)); @@ -788,7 +788,7 @@ int32_t LP_tradecommand(void *ctx,char *myipaddr,int32_t pubsock,cJSON *argjson, value = LP_txvalue(tmp,Q.srccoin,Q.txid,Q.vout); value2 = LP_txvalue(tmp,Q.srccoin,Q.txid2,Q.vout2); //printf("call LP_utxoadd.(%s) %.8f %.8f\n",Q.coinaddr,dstr(value),dstr(value2)); - if ( (butxo= LP_utxoadd(1,coin->symbol,Q.txid,Q.vout,value,Q.txid2,Q.vout2,value2,Q.coinaddr,Q.srchash,G.gui,0)) == 0 ) + if ( (butxo= LP_utxoadd(1,coin->symbol,Q.txid,Q.vout,value,Q.txid2,Q.vout2,value2,Q.coinaddr,Q.srchash,G.gui,0,Q.satoshis)) == 0 ) recalc = 1; } else @@ -816,7 +816,7 @@ int32_t LP_tradecommand(void *ctx,char *myipaddr,int32_t pubsock,cJSON *argjson, Q.vout = butxo->payment.vout; Q.txid2 = butxo->deposit.txid; Q.vout2 = butxo->deposit.vout; - butxo->S.satoshis = Q.satoshis; + //butxo->S.satoshis = Q.satoshis; printf("set butxo.%p %s/v%d %s/v%d %.8f %.8f -> bsat %.8f asat %.8f\n",butxo,bits256_str(str,butxo->payment.txid),butxo->payment.vout,bits256_str(str2,butxo->deposit.txid),butxo->deposit.vout,dstr(butxo->payment.value),dstr(butxo->deposit.value),dstr(butxo->S.satoshis),dstr(autxo->S.satoshis)); } else diff --git a/iguana/exchanges/LP_utxos.c b/iguana/exchanges/LP_utxos.c index 8d5d16c52..e82541a63 100644 --- a/iguana/exchanges/LP_utxos.c +++ b/iguana/exchanges/LP_utxos.c @@ -286,9 +286,9 @@ void LP_spentnotify(struct LP_utxoinfo *utxo,int32_t selector) utxo->T.spentflag = (uint32_t)time(NULL); } -struct LP_utxoinfo *LP_utxoadd(int32_t iambob,char *symbol,bits256 txid,int32_t vout,int64_t value,bits256 txid2,int32_t vout2,int64_t value2,char *coinaddr,bits256 pubkey,char *gui,uint32_t sessionid) +struct LP_utxoinfo *LP_utxoadd(int32_t iambob,char *symbol,bits256 txid,int32_t vout,int64_t value,bits256 txid2,int32_t vout2,int64_t value2,char *coinaddr,bits256 pubkey,char *gui,uint32_t sessionid,uint64_t satoshis) { - uint64_t val,val2=0,tmpsatoshis,txfee; int32_t spendvini,numconfirms,selector; bits256 spendtxid; struct iguana_info *coin; struct _LP_utxoinfo u; struct LP_utxoinfo *utxo = 0; + uint64_t val,val2=0,txfee; int32_t spendvini,numconfirms,selector; bits256 spendtxid; struct iguana_info *coin; struct _LP_utxoinfo u; struct LP_utxoinfo *utxo = 0; if ( symbol == 0 || symbol[0] == 0 || coinaddr == 0 || coinaddr[0] == 0 || bits256_nonz(txid) == 0 || bits256_nonz(txid2) == 0 || vout < 0 || vout2 < 0 || value <= 0 || value2 <= 0 )//|| sessionid == 0 ) { char str[65],str2[65]; printf("REJECT (%s) iambob.%d %s utxoadd.(%.8f %.8f) %s/v%d %s/v%d\n",coinaddr,iambob,symbol,dstr(value),dstr(value2),bits256_str(str,txid),vout,bits256_str(str2,txid2),vout2); @@ -301,7 +301,7 @@ struct LP_utxoinfo *LP_utxoadd(int32_t iambob,char *symbol,bits256 txid,int32_t return(0); } txfee = LP_txfeecalc(coin,0,0); - if ( iambob != 0 && value2 < 9 * (value >> 3) + 2*txfee ) // big txfee padding + /*if ( iambob != 0 && value2 < 9 * (satoshis >> 3) + 2*txfee ) // big txfee padding { if ( value2 > 2*txfee ) tmpsatoshis = (((value2 - 2*txfee) / 9) << 3); @@ -310,7 +310,7 @@ struct LP_utxoinfo *LP_utxoadd(int32_t iambob,char *symbol,bits256 txid,int32_t printf("value2 %.8f <= 2 * %.8f\n",dstr(value2),dstr(txfee)); return(0); } - } else tmpsatoshis = (value - txfee); + } else tmpsatoshis = (satoshis - txfee);*/ char str[65],str2[65],dispflag = 0;//(iambob == 0); if ( iambob == 0 && bits256_cmp(pubkey,G.LP_mypub25519) != 0 ) { @@ -319,11 +319,11 @@ struct LP_utxoinfo *LP_utxoadd(int32_t iambob,char *symbol,bits256 txid,int32_t } if ( coin->inactive == 0 ) { - if ( LP_iseligible(&val,&val2,iambob,symbol,txid,vout,tmpsatoshis,txid2,vout2) <= 0 ) + if ( LP_iseligible(&val,&val2,iambob,symbol,txid,vout,satoshis,txid2,vout2) <= 0 ) { static uint32_t counter; if ( counter++ < 3 ) - printf("iambob.%d utxoadd %s inactive.%u got ineligible txid value %.8f:%.8f, value2 %.8f:%.8f, tmpsatoshis %.8f\n",iambob,symbol,coin->inactive,dstr(value),dstr(val),dstr(value2),dstr(val2),dstr(tmpsatoshis)); + printf("iambob.%d utxoadd %s inactive.%u got ineligible txid value %.8f:%.8f, value2 %.8f:%.8f, tmpsatoshis %.8f\n",iambob,symbol,coin->inactive,dstr(value),dstr(val),dstr(value2),dstr(val2),dstr(satoshis)); return(0); } if ( (numconfirms= LP_numconfirms(symbol,coinaddr,txid,vout,0)) <= 0 ) @@ -351,10 +351,10 @@ struct LP_utxoinfo *LP_utxoadd(int32_t iambob,char *symbol,bits256 txid,int32_t if ( 0 && LP_ismine(utxo) == 0 ) { char str2[65],str3[65]; printf("iambob.%d %s %s utxoadd.(%.8f %.8f) %s %s\n",iambob,bits256_str(str3,pubkey),symbol,dstr(value),dstr(value2),bits256_str(str,txid),bits256_str(str2,txid2)); - printf("duplicate %.8f %.8f %.8f vs utxo.(%.8f %.8f %.8f)\n",dstr(value),dstr(value2),dstr(tmpsatoshis),dstr(utxo->payment.value),dstr(utxo->deposit.value),dstr(utxo->S.satoshis)); + printf("duplicate %.8f %.8f %.8f vs utxo.(%.8f %.8f %.8f)\n",dstr(value),dstr(value2),dstr(satoshis),dstr(utxo->payment.value),dstr(utxo->deposit.value),dstr(utxo->S.satoshis)); } u = (utxo->iambob != 0) ? utxo->deposit : utxo->fee; - if ( bits256_cmp(txid,utxo->payment.txid) != 0 || bits256_cmp(txid2,u.txid) != 0 || vout != utxo->payment.vout || value != utxo->payment.value || tmpsatoshis != utxo->S.satoshis || vout2 != u.vout || value2 != u.value || strcmp(symbol,utxo->coin) != 0 || strcmp(coinaddr,utxo->coinaddr) != 0 || bits256_cmp(pubkey,utxo->pubkey) != 0 ) + if ( bits256_cmp(txid,utxo->payment.txid) != 0 || bits256_cmp(txid2,u.txid) != 0 || vout != utxo->payment.vout || value != utxo->payment.value || satoshis != utxo->S.satoshis || vout2 != u.vout || value2 != u.value || strcmp(symbol,utxo->coin) != 0 || strcmp(coinaddr,utxo->coinaddr) != 0 || bits256_cmp(pubkey,utxo->pubkey) != 0 ) { utxo->T.errors++; char str[65],str2[65],str3[65],str4[65],str5[65],str6[65]; @@ -364,7 +364,7 @@ struct LP_utxoinfo *LP_utxoadd(int32_t iambob,char *symbol,bits256 txid,int32_t // utxo->T.spentflag = (uint32_t)time(NULL); printf("original utxo pair not valid\n"); if ( dispflag != 0 ) - printf("error on subsequent utxo iambob.%d %.8f %.8f add.(%s %s) when.(%s %s) %d %d %d %d %d %d %d %d %d %d pubkeys.(%s vs %s)\n",iambob,dstr(val),dstr(val2),bits256_str(str,txid),bits256_str(str2,txid2),bits256_str(str3,utxo->payment.txid),bits256_str(str4,utxo->deposit.txid),bits256_cmp(txid,utxo->payment.txid) != 0,bits256_cmp(txid2,u.txid) != 0,vout != utxo->payment.vout,tmpsatoshis != utxo->S.satoshis,vout2 != u.vout,value2 != u.value,strcmp(symbol,utxo->coin) != 0,strcmp(coinaddr,utxo->coinaddr) != 0,bits256_cmp(pubkey,utxo->pubkey) != 0,value != utxo->payment.value,bits256_str(str5,pubkey),bits256_str(str6,utxo->pubkey)); + printf("error on subsequent utxo iambob.%d %.8f %.8f add.(%s %s) when.(%s %s) %d %d %d %d %d %d %d %d %d %d pubkeys.(%s vs %s)\n",iambob,dstr(val),dstr(val2),bits256_str(str,txid),bits256_str(str2,txid2),bits256_str(str3,utxo->payment.txid),bits256_str(str4,utxo->deposit.txid),bits256_cmp(txid,utxo->payment.txid) != 0,bits256_cmp(txid2,u.txid) != 0,vout != utxo->payment.vout,satoshis != utxo->S.satoshis,vout2 != u.vout,value2 != u.value,strcmp(symbol,utxo->coin) != 0,strcmp(coinaddr,utxo->coinaddr) != 0,bits256_cmp(pubkey,utxo->pubkey) != 0,value != utxo->payment.value,bits256_str(str5,pubkey),bits256_str(str6,utxo->pubkey)); utxo = 0; } } @@ -389,7 +389,7 @@ struct LP_utxoinfo *LP_utxoadd(int32_t iambob,char *symbol,bits256 txid,int32_t utxo->payment.txid = txid; utxo->payment.vout = vout; utxo->payment.value = value; - utxo->S.satoshis = tmpsatoshis; + utxo->S.satoshis = satoshis; if ( (utxo->iambob= iambob) != 0 ) { utxo->deposit.txid = txid2; @@ -658,14 +658,14 @@ int32_t LP_privkey_init(int32_t mypubsock,struct iguana_info *coin,bits256 mypri portable_mutex_lock(&LP_UTXOmutex); if ( iambob != 0 ) { - if ( (utxo= LP_utxoadd(1,coin->symbol,txid,vout,value,deposittxid,depositvout,depositval,coin->smartaddr,mypub,LP_gui,G.LP_sessionid)) != 0 ) + if ( (utxo= LP_utxoadd(1,coin->symbol,txid,vout,value,deposittxid,depositvout,depositval,coin->smartaddr,mypub,LP_gui,G.LP_sessionid,value)) != 0 ) { } } else { //printf("call utxoadd\n"); - if ( (utxo= LP_utxoadd(0,coin->symbol,deposittxid,depositvout,depositval,txid,vout,value,coin->smartaddr,mypub,LP_gui,G.LP_sessionid)) != 0 ) + if ( (utxo= LP_utxoadd(0,coin->symbol,deposittxid,depositvout,depositval,txid,vout,value,coin->smartaddr,mypub,LP_gui,G.LP_sessionid,value)) != 0 ) { } } From fcb3859b6d8bc27699296d780c900e1c86585204 Mon Sep 17 00:00:00 2001 From: jl777 Date: Sun, 12 Nov 2017 00:51:38 +0200 Subject: [PATCH 0615/1664] Test --- iguana/exchanges/LP_nativeDEX.c | 2 +- iguana/exchanges/LP_ordermatch.c | 3 ++- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/iguana/exchanges/LP_nativeDEX.c b/iguana/exchanges/LP_nativeDEX.c index 9bed33bbc..314cbe30a 100644 --- a/iguana/exchanges/LP_nativeDEX.c +++ b/iguana/exchanges/LP_nativeDEX.c @@ -18,7 +18,7 @@ // LP_nativeDEX.c // marketmaker // -// version info +// immediate "request" // previously, it used to show amount, kmd equiv, perc // swap started, pending, locked, finished, ... // aliceid diff --git a/iguana/exchanges/LP_ordermatch.c b/iguana/exchanges/LP_ordermatch.c index 4cb3e0bfc..562cff7ba 100644 --- a/iguana/exchanges/LP_ordermatch.c +++ b/iguana/exchanges/LP_ordermatch.c @@ -466,8 +466,9 @@ void LP_reserved(void *ctx,char *myipaddr,int32_t mypubsock,struct LP_quoteinfo memset(&LP_Alicequery,0,sizeof(LP_Alicequery)); LP_Alicemaxprice = 0.; Alice_expiration = 0; + printf("send CONNECT\n"); LP_query(ctx,myipaddr,mypubsock,"connect",qp); - } + } else printf("LP_reserved price %.8f vs maxprice %.8f\n",price,maxprice*1.005); } else printf("probably a timeout, reject reserved due to not eligible.%d or mismatched quote price %.8f vs maxprice %.8f\n",LP_alice_eligible(),price,maxprice); } From 36110b787e17e02d62493b58a513086a1801a010 Mon Sep 17 00:00:00 2001 From: jl777 Date: Sun, 12 Nov 2017 01:20:06 +0200 Subject: [PATCH 0616/1664] Test --- iguana/exchanges/LP_ordermatch.c | 6 +++--- iguana/exchanges/LP_utxos.c | 24 ++++++++++++------------ 2 files changed, 15 insertions(+), 15 deletions(-) diff --git a/iguana/exchanges/LP_ordermatch.c b/iguana/exchanges/LP_ordermatch.c index 562cff7ba..c4c902f13 100644 --- a/iguana/exchanges/LP_ordermatch.c +++ b/iguana/exchanges/LP_ordermatch.c @@ -296,7 +296,7 @@ struct LP_utxoinfo *LP_address_utxopair(int32_t iambob,struct LP_address_utxo ** { if ( up != 0 && (up2= utxos[mini]) != 0 ) { - if ( (utxo= LP_utxoadd(1,coin->symbol,up->U.txid,up->U.vout,up->U.value,up2->U.txid,up2->U.vout,up2->U.value,coinaddr,ap->pubkey,G.gui,0,targetval)) != 0 ) + if ( (utxo= LP_utxoadd(1,coin->symbol,up->U.txid,up->U.vout,up->U.value,up2->U.txid,up2->U.vout,up2->U.value,coinaddr,ap->pubkey,G.gui,0)) != 0 ) { utxo->S.satoshis = targetval; char str[65],str2[65]; printf("butxo.%p targetval %.8f, found val %.8f %s | targetval2 %.8f val2 %.8f %s\n",utxo,dstr(targetval),dstr(up->U.value),bits256_str(str,utxo->payment.txid),dstr(targetval2),dstr(up2->U.value),bits256_str(str2,utxo->deposit.txid)); @@ -789,7 +789,7 @@ int32_t LP_tradecommand(void *ctx,char *myipaddr,int32_t pubsock,cJSON *argjson, value = LP_txvalue(tmp,Q.srccoin,Q.txid,Q.vout); value2 = LP_txvalue(tmp,Q.srccoin,Q.txid2,Q.vout2); //printf("call LP_utxoadd.(%s) %.8f %.8f\n",Q.coinaddr,dstr(value),dstr(value2)); - if ( (butxo= LP_utxoadd(1,coin->symbol,Q.txid,Q.vout,value,Q.txid2,Q.vout2,value2,Q.coinaddr,Q.srchash,G.gui,0,Q.satoshis)) == 0 ) + if ( (butxo= LP_utxoadd(1,coin->symbol,Q.txid,Q.vout,value,Q.txid2,Q.vout2,value2,Q.coinaddr,Q.srchash,G.gui,0)) == 0 ) recalc = 1; } else @@ -817,7 +817,7 @@ int32_t LP_tradecommand(void *ctx,char *myipaddr,int32_t pubsock,cJSON *argjson, Q.vout = butxo->payment.vout; Q.txid2 = butxo->deposit.txid; Q.vout2 = butxo->deposit.vout; - //butxo->S.satoshis = Q.satoshis; + butxo->S.satoshis = Q.satoshis; printf("set butxo.%p %s/v%d %s/v%d %.8f %.8f -> bsat %.8f asat %.8f\n",butxo,bits256_str(str,butxo->payment.txid),butxo->payment.vout,bits256_str(str2,butxo->deposit.txid),butxo->deposit.vout,dstr(butxo->payment.value),dstr(butxo->deposit.value),dstr(butxo->S.satoshis),dstr(autxo->S.satoshis)); } else diff --git a/iguana/exchanges/LP_utxos.c b/iguana/exchanges/LP_utxos.c index e82541a63..8d5d16c52 100644 --- a/iguana/exchanges/LP_utxos.c +++ b/iguana/exchanges/LP_utxos.c @@ -286,9 +286,9 @@ void LP_spentnotify(struct LP_utxoinfo *utxo,int32_t selector) utxo->T.spentflag = (uint32_t)time(NULL); } -struct LP_utxoinfo *LP_utxoadd(int32_t iambob,char *symbol,bits256 txid,int32_t vout,int64_t value,bits256 txid2,int32_t vout2,int64_t value2,char *coinaddr,bits256 pubkey,char *gui,uint32_t sessionid,uint64_t satoshis) +struct LP_utxoinfo *LP_utxoadd(int32_t iambob,char *symbol,bits256 txid,int32_t vout,int64_t value,bits256 txid2,int32_t vout2,int64_t value2,char *coinaddr,bits256 pubkey,char *gui,uint32_t sessionid) { - uint64_t val,val2=0,txfee; int32_t spendvini,numconfirms,selector; bits256 spendtxid; struct iguana_info *coin; struct _LP_utxoinfo u; struct LP_utxoinfo *utxo = 0; + uint64_t val,val2=0,tmpsatoshis,txfee; int32_t spendvini,numconfirms,selector; bits256 spendtxid; struct iguana_info *coin; struct _LP_utxoinfo u; struct LP_utxoinfo *utxo = 0; if ( symbol == 0 || symbol[0] == 0 || coinaddr == 0 || coinaddr[0] == 0 || bits256_nonz(txid) == 0 || bits256_nonz(txid2) == 0 || vout < 0 || vout2 < 0 || value <= 0 || value2 <= 0 )//|| sessionid == 0 ) { char str[65],str2[65]; printf("REJECT (%s) iambob.%d %s utxoadd.(%.8f %.8f) %s/v%d %s/v%d\n",coinaddr,iambob,symbol,dstr(value),dstr(value2),bits256_str(str,txid),vout,bits256_str(str2,txid2),vout2); @@ -301,7 +301,7 @@ struct LP_utxoinfo *LP_utxoadd(int32_t iambob,char *symbol,bits256 txid,int32_t return(0); } txfee = LP_txfeecalc(coin,0,0); - /*if ( iambob != 0 && value2 < 9 * (satoshis >> 3) + 2*txfee ) // big txfee padding + if ( iambob != 0 && value2 < 9 * (value >> 3) + 2*txfee ) // big txfee padding { if ( value2 > 2*txfee ) tmpsatoshis = (((value2 - 2*txfee) / 9) << 3); @@ -310,7 +310,7 @@ struct LP_utxoinfo *LP_utxoadd(int32_t iambob,char *symbol,bits256 txid,int32_t printf("value2 %.8f <= 2 * %.8f\n",dstr(value2),dstr(txfee)); return(0); } - } else tmpsatoshis = (satoshis - txfee);*/ + } else tmpsatoshis = (value - txfee); char str[65],str2[65],dispflag = 0;//(iambob == 0); if ( iambob == 0 && bits256_cmp(pubkey,G.LP_mypub25519) != 0 ) { @@ -319,11 +319,11 @@ struct LP_utxoinfo *LP_utxoadd(int32_t iambob,char *symbol,bits256 txid,int32_t } if ( coin->inactive == 0 ) { - if ( LP_iseligible(&val,&val2,iambob,symbol,txid,vout,satoshis,txid2,vout2) <= 0 ) + if ( LP_iseligible(&val,&val2,iambob,symbol,txid,vout,tmpsatoshis,txid2,vout2) <= 0 ) { static uint32_t counter; if ( counter++ < 3 ) - printf("iambob.%d utxoadd %s inactive.%u got ineligible txid value %.8f:%.8f, value2 %.8f:%.8f, tmpsatoshis %.8f\n",iambob,symbol,coin->inactive,dstr(value),dstr(val),dstr(value2),dstr(val2),dstr(satoshis)); + printf("iambob.%d utxoadd %s inactive.%u got ineligible txid value %.8f:%.8f, value2 %.8f:%.8f, tmpsatoshis %.8f\n",iambob,symbol,coin->inactive,dstr(value),dstr(val),dstr(value2),dstr(val2),dstr(tmpsatoshis)); return(0); } if ( (numconfirms= LP_numconfirms(symbol,coinaddr,txid,vout,0)) <= 0 ) @@ -351,10 +351,10 @@ struct LP_utxoinfo *LP_utxoadd(int32_t iambob,char *symbol,bits256 txid,int32_t if ( 0 && LP_ismine(utxo) == 0 ) { char str2[65],str3[65]; printf("iambob.%d %s %s utxoadd.(%.8f %.8f) %s %s\n",iambob,bits256_str(str3,pubkey),symbol,dstr(value),dstr(value2),bits256_str(str,txid),bits256_str(str2,txid2)); - printf("duplicate %.8f %.8f %.8f vs utxo.(%.8f %.8f %.8f)\n",dstr(value),dstr(value2),dstr(satoshis),dstr(utxo->payment.value),dstr(utxo->deposit.value),dstr(utxo->S.satoshis)); + printf("duplicate %.8f %.8f %.8f vs utxo.(%.8f %.8f %.8f)\n",dstr(value),dstr(value2),dstr(tmpsatoshis),dstr(utxo->payment.value),dstr(utxo->deposit.value),dstr(utxo->S.satoshis)); } u = (utxo->iambob != 0) ? utxo->deposit : utxo->fee; - if ( bits256_cmp(txid,utxo->payment.txid) != 0 || bits256_cmp(txid2,u.txid) != 0 || vout != utxo->payment.vout || value != utxo->payment.value || satoshis != utxo->S.satoshis || vout2 != u.vout || value2 != u.value || strcmp(symbol,utxo->coin) != 0 || strcmp(coinaddr,utxo->coinaddr) != 0 || bits256_cmp(pubkey,utxo->pubkey) != 0 ) + if ( bits256_cmp(txid,utxo->payment.txid) != 0 || bits256_cmp(txid2,u.txid) != 0 || vout != utxo->payment.vout || value != utxo->payment.value || tmpsatoshis != utxo->S.satoshis || vout2 != u.vout || value2 != u.value || strcmp(symbol,utxo->coin) != 0 || strcmp(coinaddr,utxo->coinaddr) != 0 || bits256_cmp(pubkey,utxo->pubkey) != 0 ) { utxo->T.errors++; char str[65],str2[65],str3[65],str4[65],str5[65],str6[65]; @@ -364,7 +364,7 @@ struct LP_utxoinfo *LP_utxoadd(int32_t iambob,char *symbol,bits256 txid,int32_t // utxo->T.spentflag = (uint32_t)time(NULL); printf("original utxo pair not valid\n"); if ( dispflag != 0 ) - printf("error on subsequent utxo iambob.%d %.8f %.8f add.(%s %s) when.(%s %s) %d %d %d %d %d %d %d %d %d %d pubkeys.(%s vs %s)\n",iambob,dstr(val),dstr(val2),bits256_str(str,txid),bits256_str(str2,txid2),bits256_str(str3,utxo->payment.txid),bits256_str(str4,utxo->deposit.txid),bits256_cmp(txid,utxo->payment.txid) != 0,bits256_cmp(txid2,u.txid) != 0,vout != utxo->payment.vout,satoshis != utxo->S.satoshis,vout2 != u.vout,value2 != u.value,strcmp(symbol,utxo->coin) != 0,strcmp(coinaddr,utxo->coinaddr) != 0,bits256_cmp(pubkey,utxo->pubkey) != 0,value != utxo->payment.value,bits256_str(str5,pubkey),bits256_str(str6,utxo->pubkey)); + printf("error on subsequent utxo iambob.%d %.8f %.8f add.(%s %s) when.(%s %s) %d %d %d %d %d %d %d %d %d %d pubkeys.(%s vs %s)\n",iambob,dstr(val),dstr(val2),bits256_str(str,txid),bits256_str(str2,txid2),bits256_str(str3,utxo->payment.txid),bits256_str(str4,utxo->deposit.txid),bits256_cmp(txid,utxo->payment.txid) != 0,bits256_cmp(txid2,u.txid) != 0,vout != utxo->payment.vout,tmpsatoshis != utxo->S.satoshis,vout2 != u.vout,value2 != u.value,strcmp(symbol,utxo->coin) != 0,strcmp(coinaddr,utxo->coinaddr) != 0,bits256_cmp(pubkey,utxo->pubkey) != 0,value != utxo->payment.value,bits256_str(str5,pubkey),bits256_str(str6,utxo->pubkey)); utxo = 0; } } @@ -389,7 +389,7 @@ struct LP_utxoinfo *LP_utxoadd(int32_t iambob,char *symbol,bits256 txid,int32_t utxo->payment.txid = txid; utxo->payment.vout = vout; utxo->payment.value = value; - utxo->S.satoshis = satoshis; + utxo->S.satoshis = tmpsatoshis; if ( (utxo->iambob= iambob) != 0 ) { utxo->deposit.txid = txid2; @@ -658,14 +658,14 @@ int32_t LP_privkey_init(int32_t mypubsock,struct iguana_info *coin,bits256 mypri portable_mutex_lock(&LP_UTXOmutex); if ( iambob != 0 ) { - if ( (utxo= LP_utxoadd(1,coin->symbol,txid,vout,value,deposittxid,depositvout,depositval,coin->smartaddr,mypub,LP_gui,G.LP_sessionid,value)) != 0 ) + if ( (utxo= LP_utxoadd(1,coin->symbol,txid,vout,value,deposittxid,depositvout,depositval,coin->smartaddr,mypub,LP_gui,G.LP_sessionid)) != 0 ) { } } else { //printf("call utxoadd\n"); - if ( (utxo= LP_utxoadd(0,coin->symbol,deposittxid,depositvout,depositval,txid,vout,value,coin->smartaddr,mypub,LP_gui,G.LP_sessionid,value)) != 0 ) + if ( (utxo= LP_utxoadd(0,coin->symbol,deposittxid,depositvout,depositval,txid,vout,value,coin->smartaddr,mypub,LP_gui,G.LP_sessionid)) != 0 ) { } } From d0fbae5c3f85e1efeb57df325d5a5520f0e2aac4 Mon Sep 17 00:00:00 2001 From: jl777 Date: Sun, 12 Nov 2017 01:38:24 +0200 Subject: [PATCH 0617/1664] Test --- iguana/exchanges/LP_swap.c | 7 +++++-- iguana/exchanges/LP_transaction.c | 3 +++ 2 files changed, 8 insertions(+), 2 deletions(-) diff --git a/iguana/exchanges/LP_swap.c b/iguana/exchanges/LP_swap.c index c7d3c4033..f923ad161 100644 --- a/iguana/exchanges/LP_swap.c +++ b/iguana/exchanges/LP_swap.c @@ -556,7 +556,7 @@ struct basilisk_rawtx *LP_swapdata_rawtx(struct basilisk_swap *swap,uint8_t *dat int32_t LP_rawtx_spendscript(struct basilisk_swap *swap,int32_t height,struct basilisk_rawtx *rawtx,int32_t v,uint8_t *recvbuf,int32_t recvlen,int32_t suppress_pubkeys) { - bits256 otherhash,myhash,txid; int64_t txfee; int32_t i,offset=0,datalen=0,retval=-1,hexlen,n; uint8_t *data; cJSON *txobj,*skey,*vouts,*vout; char *hexstr,redeemaddr[64],checkaddr[64]; uint32_t quoteid,msgbits; + bits256 otherhash,myhash,txid; int64_t txfee,val; int32_t i,offset=0,datalen=0,retval=-1,hexlen,n; uint8_t *data; cJSON *txobj,*skey,*vouts,*vout; char *hexstr,redeemaddr[64],checkaddr[64]; uint32_t quoteid,msgbits; for (i=0; i<32; i++) otherhash.bytes[i] = recvbuf[offset++]; for (i=0; i<32; i++) @@ -626,7 +626,10 @@ int32_t LP_rawtx_spendscript(struct basilisk_swap *swap,int32_t height,struct ba txfee = swap->I.Atxfee; else txfee = LP_MIN_TXFEE; } - if ( j64bits(vout,"satoshis") >= rawtx->I.amount-2*txfee && (skey= jobj(vout,"scriptPubKey")) != 0 && (hexstr= jstr(skey,"hex")) != 0 ) + if ( rawtx->I.amount > 2*txfee) + val = rawtx->I.amount-2*txfee; + else val = 1; + if ( j64bits(vout,"satoshis") >= val && (skey= jobj(vout,"scriptPubKey")) != 0 && (hexstr= jstr(skey,"hex")) != 0 ) { if ( (hexlen= (int32_t)strlen(hexstr) >> 1) < sizeof(rawtx->spendscript) ) { diff --git a/iguana/exchanges/LP_transaction.c b/iguana/exchanges/LP_transaction.c index abeaf8ff0..d9939432d 100644 --- a/iguana/exchanges/LP_transaction.c +++ b/iguana/exchanges/LP_transaction.c @@ -1805,7 +1805,10 @@ int32_t basilisk_alicetxs(int32_t pairsock,struct basilisk_swap *swap,uint8_t *d } } if ( swap->alicepayment.I.datalen != 0 && swap->alicepayment.I.spendlen > 0 && swap->myfee.I.datalen != 0 && swap->myfee.I.spendlen > 0 ) + { + printf("fee sent\n"); return(0); + } return(-1); } From d7cd0235862fd73e77c3d987ca00e660caac1109 Mon Sep 17 00:00:00 2001 From: jl777 Date: Sun, 12 Nov 2017 01:43:46 +0200 Subject: [PATCH 0618/1664] Test --- iguana/exchanges/LP_ordermatch.c | 4 ++-- iguana/exchanges/LP_utxos.c | 24 ++++++++++++------------ 2 files changed, 14 insertions(+), 14 deletions(-) diff --git a/iguana/exchanges/LP_ordermatch.c b/iguana/exchanges/LP_ordermatch.c index c4c902f13..3f876861f 100644 --- a/iguana/exchanges/LP_ordermatch.c +++ b/iguana/exchanges/LP_ordermatch.c @@ -296,7 +296,7 @@ struct LP_utxoinfo *LP_address_utxopair(int32_t iambob,struct LP_address_utxo ** { if ( up != 0 && (up2= utxos[mini]) != 0 ) { - if ( (utxo= LP_utxoadd(1,coin->symbol,up->U.txid,up->U.vout,up->U.value,up2->U.txid,up2->U.vout,up2->U.value,coinaddr,ap->pubkey,G.gui,0)) != 0 ) + if ( (utxo= LP_utxoadd(1,coin->symbol,up->U.txid,up->U.vout,up->U.value,up2->U.txid,up2->U.vout,up2->U.value,coinaddr,ap->pubkey,G.gui,0,targetval)) != 0 ) { utxo->S.satoshis = targetval; char str[65],str2[65]; printf("butxo.%p targetval %.8f, found val %.8f %s | targetval2 %.8f val2 %.8f %s\n",utxo,dstr(targetval),dstr(up->U.value),bits256_str(str,utxo->payment.txid),dstr(targetval2),dstr(up2->U.value),bits256_str(str2,utxo->deposit.txid)); @@ -789,7 +789,7 @@ int32_t LP_tradecommand(void *ctx,char *myipaddr,int32_t pubsock,cJSON *argjson, value = LP_txvalue(tmp,Q.srccoin,Q.txid,Q.vout); value2 = LP_txvalue(tmp,Q.srccoin,Q.txid2,Q.vout2); //printf("call LP_utxoadd.(%s) %.8f %.8f\n",Q.coinaddr,dstr(value),dstr(value2)); - if ( (butxo= LP_utxoadd(1,coin->symbol,Q.txid,Q.vout,value,Q.txid2,Q.vout2,value2,Q.coinaddr,Q.srchash,G.gui,0)) == 0 ) + if ( (butxo= LP_utxoadd(1,coin->symbol,Q.txid,Q.vout,value,Q.txid2,Q.vout2,value2,Q.coinaddr,Q.srchash,G.gui,0,Q.satoshis)) == 0 ) recalc = 1; } else diff --git a/iguana/exchanges/LP_utxos.c b/iguana/exchanges/LP_utxos.c index 8d5d16c52..e82541a63 100644 --- a/iguana/exchanges/LP_utxos.c +++ b/iguana/exchanges/LP_utxos.c @@ -286,9 +286,9 @@ void LP_spentnotify(struct LP_utxoinfo *utxo,int32_t selector) utxo->T.spentflag = (uint32_t)time(NULL); } -struct LP_utxoinfo *LP_utxoadd(int32_t iambob,char *symbol,bits256 txid,int32_t vout,int64_t value,bits256 txid2,int32_t vout2,int64_t value2,char *coinaddr,bits256 pubkey,char *gui,uint32_t sessionid) +struct LP_utxoinfo *LP_utxoadd(int32_t iambob,char *symbol,bits256 txid,int32_t vout,int64_t value,bits256 txid2,int32_t vout2,int64_t value2,char *coinaddr,bits256 pubkey,char *gui,uint32_t sessionid,uint64_t satoshis) { - uint64_t val,val2=0,tmpsatoshis,txfee; int32_t spendvini,numconfirms,selector; bits256 spendtxid; struct iguana_info *coin; struct _LP_utxoinfo u; struct LP_utxoinfo *utxo = 0; + uint64_t val,val2=0,txfee; int32_t spendvini,numconfirms,selector; bits256 spendtxid; struct iguana_info *coin; struct _LP_utxoinfo u; struct LP_utxoinfo *utxo = 0; if ( symbol == 0 || symbol[0] == 0 || coinaddr == 0 || coinaddr[0] == 0 || bits256_nonz(txid) == 0 || bits256_nonz(txid2) == 0 || vout < 0 || vout2 < 0 || value <= 0 || value2 <= 0 )//|| sessionid == 0 ) { char str[65],str2[65]; printf("REJECT (%s) iambob.%d %s utxoadd.(%.8f %.8f) %s/v%d %s/v%d\n",coinaddr,iambob,symbol,dstr(value),dstr(value2),bits256_str(str,txid),vout,bits256_str(str2,txid2),vout2); @@ -301,7 +301,7 @@ struct LP_utxoinfo *LP_utxoadd(int32_t iambob,char *symbol,bits256 txid,int32_t return(0); } txfee = LP_txfeecalc(coin,0,0); - if ( iambob != 0 && value2 < 9 * (value >> 3) + 2*txfee ) // big txfee padding + /*if ( iambob != 0 && value2 < 9 * (satoshis >> 3) + 2*txfee ) // big txfee padding { if ( value2 > 2*txfee ) tmpsatoshis = (((value2 - 2*txfee) / 9) << 3); @@ -310,7 +310,7 @@ struct LP_utxoinfo *LP_utxoadd(int32_t iambob,char *symbol,bits256 txid,int32_t printf("value2 %.8f <= 2 * %.8f\n",dstr(value2),dstr(txfee)); return(0); } - } else tmpsatoshis = (value - txfee); + } else tmpsatoshis = (satoshis - txfee);*/ char str[65],str2[65],dispflag = 0;//(iambob == 0); if ( iambob == 0 && bits256_cmp(pubkey,G.LP_mypub25519) != 0 ) { @@ -319,11 +319,11 @@ struct LP_utxoinfo *LP_utxoadd(int32_t iambob,char *symbol,bits256 txid,int32_t } if ( coin->inactive == 0 ) { - if ( LP_iseligible(&val,&val2,iambob,symbol,txid,vout,tmpsatoshis,txid2,vout2) <= 0 ) + if ( LP_iseligible(&val,&val2,iambob,symbol,txid,vout,satoshis,txid2,vout2) <= 0 ) { static uint32_t counter; if ( counter++ < 3 ) - printf("iambob.%d utxoadd %s inactive.%u got ineligible txid value %.8f:%.8f, value2 %.8f:%.8f, tmpsatoshis %.8f\n",iambob,symbol,coin->inactive,dstr(value),dstr(val),dstr(value2),dstr(val2),dstr(tmpsatoshis)); + printf("iambob.%d utxoadd %s inactive.%u got ineligible txid value %.8f:%.8f, value2 %.8f:%.8f, tmpsatoshis %.8f\n",iambob,symbol,coin->inactive,dstr(value),dstr(val),dstr(value2),dstr(val2),dstr(satoshis)); return(0); } if ( (numconfirms= LP_numconfirms(symbol,coinaddr,txid,vout,0)) <= 0 ) @@ -351,10 +351,10 @@ struct LP_utxoinfo *LP_utxoadd(int32_t iambob,char *symbol,bits256 txid,int32_t if ( 0 && LP_ismine(utxo) == 0 ) { char str2[65],str3[65]; printf("iambob.%d %s %s utxoadd.(%.8f %.8f) %s %s\n",iambob,bits256_str(str3,pubkey),symbol,dstr(value),dstr(value2),bits256_str(str,txid),bits256_str(str2,txid2)); - printf("duplicate %.8f %.8f %.8f vs utxo.(%.8f %.8f %.8f)\n",dstr(value),dstr(value2),dstr(tmpsatoshis),dstr(utxo->payment.value),dstr(utxo->deposit.value),dstr(utxo->S.satoshis)); + printf("duplicate %.8f %.8f %.8f vs utxo.(%.8f %.8f %.8f)\n",dstr(value),dstr(value2),dstr(satoshis),dstr(utxo->payment.value),dstr(utxo->deposit.value),dstr(utxo->S.satoshis)); } u = (utxo->iambob != 0) ? utxo->deposit : utxo->fee; - if ( bits256_cmp(txid,utxo->payment.txid) != 0 || bits256_cmp(txid2,u.txid) != 0 || vout != utxo->payment.vout || value != utxo->payment.value || tmpsatoshis != utxo->S.satoshis || vout2 != u.vout || value2 != u.value || strcmp(symbol,utxo->coin) != 0 || strcmp(coinaddr,utxo->coinaddr) != 0 || bits256_cmp(pubkey,utxo->pubkey) != 0 ) + if ( bits256_cmp(txid,utxo->payment.txid) != 0 || bits256_cmp(txid2,u.txid) != 0 || vout != utxo->payment.vout || value != utxo->payment.value || satoshis != utxo->S.satoshis || vout2 != u.vout || value2 != u.value || strcmp(symbol,utxo->coin) != 0 || strcmp(coinaddr,utxo->coinaddr) != 0 || bits256_cmp(pubkey,utxo->pubkey) != 0 ) { utxo->T.errors++; char str[65],str2[65],str3[65],str4[65],str5[65],str6[65]; @@ -364,7 +364,7 @@ struct LP_utxoinfo *LP_utxoadd(int32_t iambob,char *symbol,bits256 txid,int32_t // utxo->T.spentflag = (uint32_t)time(NULL); printf("original utxo pair not valid\n"); if ( dispflag != 0 ) - printf("error on subsequent utxo iambob.%d %.8f %.8f add.(%s %s) when.(%s %s) %d %d %d %d %d %d %d %d %d %d pubkeys.(%s vs %s)\n",iambob,dstr(val),dstr(val2),bits256_str(str,txid),bits256_str(str2,txid2),bits256_str(str3,utxo->payment.txid),bits256_str(str4,utxo->deposit.txid),bits256_cmp(txid,utxo->payment.txid) != 0,bits256_cmp(txid2,u.txid) != 0,vout != utxo->payment.vout,tmpsatoshis != utxo->S.satoshis,vout2 != u.vout,value2 != u.value,strcmp(symbol,utxo->coin) != 0,strcmp(coinaddr,utxo->coinaddr) != 0,bits256_cmp(pubkey,utxo->pubkey) != 0,value != utxo->payment.value,bits256_str(str5,pubkey),bits256_str(str6,utxo->pubkey)); + printf("error on subsequent utxo iambob.%d %.8f %.8f add.(%s %s) when.(%s %s) %d %d %d %d %d %d %d %d %d %d pubkeys.(%s vs %s)\n",iambob,dstr(val),dstr(val2),bits256_str(str,txid),bits256_str(str2,txid2),bits256_str(str3,utxo->payment.txid),bits256_str(str4,utxo->deposit.txid),bits256_cmp(txid,utxo->payment.txid) != 0,bits256_cmp(txid2,u.txid) != 0,vout != utxo->payment.vout,satoshis != utxo->S.satoshis,vout2 != u.vout,value2 != u.value,strcmp(symbol,utxo->coin) != 0,strcmp(coinaddr,utxo->coinaddr) != 0,bits256_cmp(pubkey,utxo->pubkey) != 0,value != utxo->payment.value,bits256_str(str5,pubkey),bits256_str(str6,utxo->pubkey)); utxo = 0; } } @@ -389,7 +389,7 @@ struct LP_utxoinfo *LP_utxoadd(int32_t iambob,char *symbol,bits256 txid,int32_t utxo->payment.txid = txid; utxo->payment.vout = vout; utxo->payment.value = value; - utxo->S.satoshis = tmpsatoshis; + utxo->S.satoshis = satoshis; if ( (utxo->iambob= iambob) != 0 ) { utxo->deposit.txid = txid2; @@ -658,14 +658,14 @@ int32_t LP_privkey_init(int32_t mypubsock,struct iguana_info *coin,bits256 mypri portable_mutex_lock(&LP_UTXOmutex); if ( iambob != 0 ) { - if ( (utxo= LP_utxoadd(1,coin->symbol,txid,vout,value,deposittxid,depositvout,depositval,coin->smartaddr,mypub,LP_gui,G.LP_sessionid)) != 0 ) + if ( (utxo= LP_utxoadd(1,coin->symbol,txid,vout,value,deposittxid,depositvout,depositval,coin->smartaddr,mypub,LP_gui,G.LP_sessionid,value)) != 0 ) { } } else { //printf("call utxoadd\n"); - if ( (utxo= LP_utxoadd(0,coin->symbol,deposittxid,depositvout,depositval,txid,vout,value,coin->smartaddr,mypub,LP_gui,G.LP_sessionid)) != 0 ) + if ( (utxo= LP_utxoadd(0,coin->symbol,deposittxid,depositvout,depositval,txid,vout,value,coin->smartaddr,mypub,LP_gui,G.LP_sessionid,value)) != 0 ) { } } From bdcb4576fd38b030d4b5ad0bf708761157e7b6e0 Mon Sep 17 00:00:00 2001 From: jl777 Date: Sun, 12 Nov 2017 01:55:03 +0200 Subject: [PATCH 0619/1664] Test --- iguana/exchanges/LP_ordermatch.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/iguana/exchanges/LP_ordermatch.c b/iguana/exchanges/LP_ordermatch.c index 3f876861f..c2eba14fb 100644 --- a/iguana/exchanges/LP_ordermatch.c +++ b/iguana/exchanges/LP_ordermatch.c @@ -685,11 +685,13 @@ int32_t LP_tradecommand(void *ctx,char *myipaddr,int32_t pubsock,cJSON *argjson, LP_abutxo_set(autxo,butxo,&Q); if ( strcmp(method,"reserved") == 0 ) { + if ( LP_Alicemaxprice == 0. ) + return(retval); if ( bits256_cmp(G.LP_mypub25519,Q.desthash) == 0 && bits256_cmp(G.LP_mypub25519,Q.srchash) != 0 && LP_alice_eligible() > 0 ) { if ( (qprice= LP_quote_validate(autxo,butxo,&Q,0)) <= SMALLVAL ) { - printf("quote validate error %.0f\n",qprice); + printf("reserved quote validate error %.0f\n",qprice); return(retval); } if ( LP_validSPV(Q.srccoin,Q.coinaddr,Q.txid,Q.vout) < 0 ) From dcb4ea56b1fdff3b24288dc3718b4a53e98b8fc9 Mon Sep 17 00:00:00 2001 From: jl777 Date: Sun, 12 Nov 2017 02:00:22 +0200 Subject: [PATCH 0620/1664] Test --- iguana/exchanges/LP_cache.c | 2 +- iguana/exchanges/LP_include.h | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/iguana/exchanges/LP_cache.c b/iguana/exchanges/LP_cache.c index 2e06711f4..95fbe6f99 100644 --- a/iguana/exchanges/LP_cache.c +++ b/iguana/exchanges/LP_cache.c @@ -231,7 +231,7 @@ 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; - if ( height < 0 ) + if ( height <= 0 ) return(0); if ( (tx= LP_transactionfind(coin,txid)) == 0 && strcmp(coinaddr,coin->smartaddr) == 0 ) { diff --git a/iguana/exchanges/LP_include.h b/iguana/exchanges/LP_include.h index 787d6c57f..3922708ed 100644 --- a/iguana/exchanges/LP_include.h +++ b/iguana/exchanges/LP_include.h @@ -23,7 +23,7 @@ #define LP_MAJOR_VERSION "0" #define LP_MINOR_VERSION "1" -#define LP_BUILD_NUMBER "11843" +#define LP_BUILD_NUMBER "14288" #ifdef FROM_JS #include From 1651ff762f0b8b74f56d04d78e6a95dd37b58bda Mon Sep 17 00:00:00 2001 From: jl777 Date: Sun, 12 Nov 2017 10:41:46 +0200 Subject: [PATCH 0621/1664] Test --- iguana/exchanges/LP_nativeDEX.c | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/iguana/exchanges/LP_nativeDEX.c b/iguana/exchanges/LP_nativeDEX.c index 314cbe30a..279276789 100644 --- a/iguana/exchanges/LP_nativeDEX.c +++ b/iguana/exchanges/LP_nativeDEX.c @@ -18,10 +18,8 @@ // LP_nativeDEX.c // marketmaker // -// immediate "request" +// immediate "request", actual auction // previously, it used to show amount, kmd equiv, perc -// swap started, pending, locked, finished, ... -// aliceid //there is still a pending one with `-1 wait for bobpayment bYoNxkfvwQ42Yufry8J5y8BYi6mQxokvW9 numconfs.1 MNZ c0ea4aa808a653222a15122d96692fecf734dbbacfb9a54cb4711306ea0c3cef`, but that tx is already spent including 6 confirmation // bot safe to exit? // From 2db0f96ae53040688b8d4b001d5d2a49b0e9d447 Mon Sep 17 00:00:00 2001 From: jl777 Date: Sun, 12 Nov 2017 10:51:32 +0200 Subject: [PATCH 0622/1664] Timestamp in swapstatus --- iguana/exchanges/LP_ordermatch.c | 2 +- iguana/exchanges/LP_remember.c | 1 + 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/iguana/exchanges/LP_ordermatch.c b/iguana/exchanges/LP_ordermatch.c index c2eba14fb..08721bcaf 100644 --- a/iguana/exchanges/LP_ordermatch.c +++ b/iguana/exchanges/LP_ordermatch.c @@ -699,7 +699,7 @@ int32_t LP_tradecommand(void *ctx,char *myipaddr,int32_t pubsock,cJSON *argjson, printf("%s src %s failed SPV check\n",Q.srccoin,bits256_str(str,Q.txid)); return(retval); } - else if (LP_validSPV(Q.srccoin,Q.coinaddr,Q.txid2,Q.vout2) < 0 ) + else if ( LP_validSPV(Q.srccoin,Q.coinaddr,Q.txid2,Q.vout2) < 0 ) { printf("%s src2 %s failed SPV check\n",Q.srccoin,bits256_str(str,Q.txid2)); return(retval); diff --git a/iguana/exchanges/LP_remember.c b/iguana/exchanges/LP_remember.c index f8bc1a227..5b145da5c 100644 --- a/iguana/exchanges/LP_remember.c +++ b/iguana/exchanges/LP_remember.c @@ -450,6 +450,7 @@ cJSON *LP_swap_json(struct LP_swap_remember *rswap) { cJSON *item,*array; int32_t i; item = cJSON_CreateObject(); + jaddnum(item,"timestamp",rswap->expiration - INSTANTDEX_LOCKTIME*2); jaddnum(item,"tradeid",rswap->tradeid); jaddnum(item,"requestid",rswap->requestid); jaddnum(item,"quoteid",rswap->quoteid); From 1c5de221b88783ff4b520bc0b44b332722d1b38f Mon Sep 17 00:00:00 2001 From: jl777 Date: Sun, 12 Nov 2017 11:19:00 +0200 Subject: [PATCH 0623/1664] Finishtime in swapstatus --- iguana/exchanges/LP_include.h | 1 + iguana/exchanges/LP_remember.c | 5 ++++ iguana/exchanges/LP_rpc.c | 46 ++++++++++++++++++++++++++++++++++ 3 files changed, 52 insertions(+) diff --git a/iguana/exchanges/LP_include.h b/iguana/exchanges/LP_include.h index 3922708ed..5d07367d3 100644 --- a/iguana/exchanges/LP_include.h +++ b/iguana/exchanges/LP_include.h @@ -443,6 +443,7 @@ struct LP_address_utxo *LP_address_utxofind(struct iguana_info *coin,char *coina int32_t LP_destaddr(char *destaddr,cJSON *item); int32_t LP_waitmempool(char *symbol,char *coinaddr,bits256 txid,int32_t vout,int32_t duration); char *LP_statslog_disp(int32_t n,uint32_t starttime,uint32_t endtime,char *refgui,bits256 refpubkey); +uint32_t LP_heighttime(char *symbol,int32_t height); uint64_t LP_unspents_load(char *symbol,char *addr); int32_t LP_validSPV(char *symbol,char *coinaddr,bits256 txid,int32_t vout); struct LP_transaction *LP_transactionfind(struct iguana_info *coin,bits256 txid); diff --git a/iguana/exchanges/LP_remember.c b/iguana/exchanges/LP_remember.c index 5b145da5c..4d189f6d0 100644 --- a/iguana/exchanges/LP_remember.c +++ b/iguana/exchanges/LP_remember.c @@ -477,7 +477,12 @@ cJSON *LP_swap_json(struct LP_swap_remember *rswap) jadd(item,"values",array); jaddstr(item,"result","success"); if ( rswap->finishedflag != 0 ) + { jaddstr(item,"status","finished"); + if ( rswap->iambob == 0 ) + jaddnum(item,"finishtime",LP_txtime(rswap->dest,rswap->paymentspent)); + else jaddnum(item,"finishtime",LP_txtime(rswap->dest,rswap->depositspent)); + } else jaddstr(item,"status","pending"); jaddbits256(item,"bobdeposit",rswap->txids[BASILISK_BOBDEPOSIT]); jaddbits256(item,"alicepayment",rswap->txids[BASILISK_ALICEPAYMENT]); diff --git a/iguana/exchanges/LP_rpc.c b/iguana/exchanges/LP_rpc.c index 661c476e6..3b77916af 100644 --- a/iguana/exchanges/LP_rpc.c +++ b/iguana/exchanges/LP_rpc.c @@ -447,6 +447,22 @@ uint32_t LP_locktime(char *symbol,bits256 txid) return(locktime); } +uint32_t LP_txtime(char *symbol,bits256 txid) +{ + struct LP_transaction *tx; struct iguana_info *coin; int32_t timestamp=0,height = 0; + if ( (timestamp= LP_locktime(symbol,txid)) != 0 ) + return(timestamp); + if ( (coin= LP_coinfind(symbol)) != 0 ) + { + if ( (tx= LP_transactionfind(coin,txid)) != 0 ) + { + height = tx->height; + timestamp = LP_heighttime(symbol,height); + } + } + return(height); +} + cJSON *LP_gettxout_json(bits256 txid,int32_t vout,int32_t height,char *coinaddr,uint64_t value) { cJSON *retjson,*addresses,*sobj; @@ -1013,6 +1029,36 @@ cJSON *LP_getblockhashstr(char *symbol,char *blockhashstr) return(bitcoin_json(coin,"getblock",buf)); } +uint32_t LP_heighttime(char *symbol,int32_t height) +{ + struct electrum_info *ep; uint32_t timestamp = 0; cJSON *retjson; char *blockhashstr; struct iguana_info *coin = LP_coinfind(symbol); + if ( coin != 0 ) + { + if ( (ep= coin->electrum) == 0 ) + { + if ( (blockhashstr= LP_blockhashstr(symbol,height)) != 0 ) + { + if ( (retjson= cJSON_Parse(blockhashstr)) != 0 ) + { + timestamp = juint(retjson,"time"); + free_json(retjson); + } + free(blockhashstr); + } + } + else + { + if ( (retjson= electrum_getheader(coin->symbol,ep,&retjson,height)) != 0 ) + { + printf("%s\n",jprint(retjson,0)); + timestamp = juint(retjson,"timestamp"); + free_json(retjson); + } + } + } + return(timestamp); +} + cJSON *LP_blockjson(int32_t *heightp,char *symbol,char *blockhashstr,int32_t height) { cJSON *json = 0; int32_t flag = 0; struct iguana_info *coin; From d7ef7be5e21630bc7e4555d2a0bc0892b4cbb7d6 Mon Sep 17 00:00:00 2001 From: jl777 Date: Sun, 12 Nov 2017 11:35:43 +0200 Subject: [PATCH 0624/1664] Test --- iguana/exchanges/LP_commands.c | 3 +++ iguana/exchanges/LP_remember.c | 15 ++++++++++----- 2 files changed, 13 insertions(+), 5 deletions(-) diff --git a/iguana/exchanges/LP_commands.c b/iguana/exchanges/LP_commands.c index 9d0f4ff47..25bb1ee70 100644 --- a/iguana/exchanges/LP_commands.c +++ b/iguana/exchanges/LP_commands.c @@ -260,7 +260,10 @@ bot_resume(botid)\n\ { uint32_t requestid,quoteid; if ( (requestid= juint(argjson,"requestid")) != 0 && (quoteid= juint(argjson,"quoteid")) != 0 ) + { + printf("swapentry %u %u\n",requestid,quoteid); return(basilisk_swapentry(requestid,quoteid)); + } else if ( coin[0] != 0 ) return(basilisk_swapentries(coin,0,jint(argjson,"limit"))); else if ( base[0] != 0 && rel[0] != 0 ) diff --git a/iguana/exchanges/LP_remember.c b/iguana/exchanges/LP_remember.c index 4d189f6d0..a25325258 100644 --- a/iguana/exchanges/LP_remember.c +++ b/iguana/exchanges/LP_remember.c @@ -481,7 +481,7 @@ cJSON *LP_swap_json(struct LP_swap_remember *rswap) jaddstr(item,"status","finished"); if ( rswap->iambob == 0 ) jaddnum(item,"finishtime",LP_txtime(rswap->dest,rswap->paymentspent)); - else jaddnum(item,"finishtime",LP_txtime(rswap->dest,rswap->depositspent)); + else jaddnum(item,"finishtime",LP_txtime(rswap->src,rswap->depositspent)); } else jaddstr(item,"status","pending"); jaddbits256(item,"bobdeposit",rswap->txids[BASILISK_BOBDEPOSIT]); @@ -1137,7 +1137,7 @@ cJSON *basilisk_remember(int64_t *KMDtotals,int64_t *BTCtotals,uint32_t requesti char *basilisk_swaplist(uint32_t origrequestid,uint32_t origquoteid) { - uint64_t ridqids[4096],ridqid; char fname[512]; FILE *fp; cJSON *item,*retjson,*array,*totalsobj; uint32_t r,q,quoteid,requestid; int64_t KMDtotals[16],BTCtotals[16],Btotal,Ktotal; int32_t i,j,count=0; + 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); memset(ridqids,0,sizeof(ridqids)); memset(KMDtotals,0,sizeof(KMDtotals)); @@ -1229,8 +1229,13 @@ char *basilisk_swaplist(uint32_t origrequestid,uint32_t origquoteid) char *basilisk_swapentry(uint32_t requestid,uint32_t quoteid) { - char *liststr,*retstr = 0; cJSON *retjson,*array,*item; int32_t i,n; - if ( (liststr= basilisk_swaplist(requestid,quoteid)) != 0 ) + 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 ) + return(jprint(item,1)); + else return(clonestr("{\"error\":\"cant find requestid-quoteid\"}")); + /*if ( (liststr= basilisk_swaplist(requestid,quoteid)) != 0 ) { //printf("swapentry.(%s)\n",liststr); if ( (retjson= cJSON_Parse(liststr)) != 0 ) @@ -1252,7 +1257,7 @@ char *basilisk_swapentry(uint32_t requestid,uint32_t quoteid) } free(liststr); } - return(retstr); + return(retstr);*/ } extern struct LP_quoteinfo LP_Alicequery; From 011064ed3a7a89cd8461cf47a44700c179dca0e4 Mon Sep 17 00:00:00 2001 From: jl777 Date: Sun, 12 Nov 2017 11:42:19 +0200 Subject: [PATCH 0625/1664] Test --- iguana/exchanges/LP_rpc.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/iguana/exchanges/LP_rpc.c b/iguana/exchanges/LP_rpc.c index 3b77916af..5b2a654ee 100644 --- a/iguana/exchanges/LP_rpc.c +++ b/iguana/exchanges/LP_rpc.c @@ -450,6 +450,7 @@ uint32_t LP_locktime(char *symbol,bits256 txid) uint32_t LP_txtime(char *symbol,bits256 txid) { struct LP_transaction *tx; struct iguana_info *coin; int32_t timestamp=0,height = 0; + char str[65]; printf("LP_txtime (%s %s)\n",symbol,bits256_str(str,txid)); if ( (timestamp= LP_locktime(symbol,txid)) != 0 ) return(timestamp); if ( (coin= LP_coinfind(symbol)) != 0 ) @@ -1040,6 +1041,7 @@ uint32_t LP_heighttime(char *symbol,int32_t height) { if ( (retjson= cJSON_Parse(blockhashstr)) != 0 ) { + printf("height.(%s)\n",jprint(retjson,0)); timestamp = juint(retjson,"time"); free_json(retjson); } From b1e4171eb7bc4ae17003baa4955c0f2a3bd90d58 Mon Sep 17 00:00:00 2001 From: jl777 Date: Sun, 12 Nov 2017 11:45:43 +0200 Subject: [PATCH 0626/1664] Test --- iguana/exchanges/LP_remember.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/iguana/exchanges/LP_remember.c b/iguana/exchanges/LP_remember.c index a25325258..75e582bd0 100644 --- a/iguana/exchanges/LP_remember.c +++ b/iguana/exchanges/LP_remember.c @@ -480,7 +480,7 @@ cJSON *LP_swap_json(struct LP_swap_remember *rswap) { jaddstr(item,"status","finished"); if ( rswap->iambob == 0 ) - jaddnum(item,"finishtime",LP_txtime(rswap->dest,rswap->paymentspent)); + jaddnum(item,"finishtime",LP_txtime(rswap->src,rswap->paymentspent)); else jaddnum(item,"finishtime",LP_txtime(rswap->src,rswap->depositspent)); } else jaddstr(item,"status","pending"); From 88243c22f79d2bf7c6d31caaaa79e6573920934a Mon Sep 17 00:00:00 2001 From: jl777 Date: Sun, 12 Nov 2017 11:53:40 +0200 Subject: [PATCH 0627/1664] Test --- iguana/exchanges/LP_commands.c | 3 --- iguana/exchanges/LP_include.h | 2 +- iguana/exchanges/LP_remember.c | 6 +++--- iguana/exchanges/LP_rpc.c | 4 ++-- 4 files changed, 6 insertions(+), 9 deletions(-) diff --git a/iguana/exchanges/LP_commands.c b/iguana/exchanges/LP_commands.c index 25bb1ee70..9d0f4ff47 100644 --- a/iguana/exchanges/LP_commands.c +++ b/iguana/exchanges/LP_commands.c @@ -260,10 +260,7 @@ bot_resume(botid)\n\ { uint32_t requestid,quoteid; if ( (requestid= juint(argjson,"requestid")) != 0 && (quoteid= juint(argjson,"quoteid")) != 0 ) - { - printf("swapentry %u %u\n",requestid,quoteid); return(basilisk_swapentry(requestid,quoteid)); - } else if ( coin[0] != 0 ) return(basilisk_swapentries(coin,0,jint(argjson,"limit"))); else if ( base[0] != 0 && rel[0] != 0 ) diff --git a/iguana/exchanges/LP_include.h b/iguana/exchanges/LP_include.h index 5d07367d3..4e3a1e5f2 100644 --- a/iguana/exchanges/LP_include.h +++ b/iguana/exchanges/LP_include.h @@ -238,7 +238,7 @@ struct LP_swap_remember bits256 pubA0,pubB0,pubB1,privAm,privBn,paymentspent,Apaymentspent,depositspent,myprivs[2],txids[sizeof(txnames)/sizeof(*txnames)]; uint64_t Atxfee,Btxfee,srcamount,destamount,aliceid; int64_t values[sizeof(txnames)/sizeof(*txnames)]; - uint32_t tradeid,requestid,quoteid,plocktime,dlocktime,expiration,state,otherstate; + uint32_t finishtime,tradeid,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],Sdestaddr[64],alicepaymentaddr[64],bobpaymentaddr[64],bobdepositaddr[64],alicecoin[64],bobcoin[64],*txbytes[sizeof(txnames)/sizeof(*txnames)]; diff --git a/iguana/exchanges/LP_remember.c b/iguana/exchanges/LP_remember.c index 75e582bd0..b50caa432 100644 --- a/iguana/exchanges/LP_remember.c +++ b/iguana/exchanges/LP_remember.c @@ -479,9 +479,7 @@ cJSON *LP_swap_json(struct LP_swap_remember *rswap) if ( rswap->finishedflag != 0 ) { jaddstr(item,"status","finished"); - if ( rswap->iambob == 0 ) - jaddnum(item,"finishtime",LP_txtime(rswap->src,rswap->paymentspent)); - else jaddnum(item,"finishtime",LP_txtime(rswap->src,rswap->depositspent)); + jaddnum(item,"finishtime",rswap->finishtime); } else jaddstr(item,"status","pending"); jaddbits256(item,"bobdeposit",rswap->txids[BASILISK_BOBDEPOSIT]); @@ -663,6 +661,7 @@ 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; free_json(fileobj); } @@ -1121,6 +1120,7 @@ cJSON *basilisk_remember(int64_t *KMDtotals,int64_t *BTCtotals,uint32_t requesti if ( (fp= fopen(fname,"wb")) != 0 ) { jaddstr(item,"method","tradestatus"); + jaddnum(item,"finishtime",rswap.finishtime); jaddstr(item,"gui",G.gui); itemstr = jprint(item,0); fprintf(fp,"%s\n",itemstr); diff --git a/iguana/exchanges/LP_rpc.c b/iguana/exchanges/LP_rpc.c index 5b2a654ee..1d952ff6d 100644 --- a/iguana/exchanges/LP_rpc.c +++ b/iguana/exchanges/LP_rpc.c @@ -447,7 +447,7 @@ uint32_t LP_locktime(char *symbol,bits256 txid) return(locktime); } -uint32_t LP_txtime(char *symbol,bits256 txid) +/*uint32_t LP_txtime(char *symbol,bits256 txid) { struct LP_transaction *tx; struct iguana_info *coin; int32_t timestamp=0,height = 0; char str[65]; printf("LP_txtime (%s %s)\n",symbol,bits256_str(str,txid)); @@ -462,7 +462,7 @@ uint32_t LP_txtime(char *symbol,bits256 txid) } } return(height); -} +}*/ cJSON *LP_gettxout_json(bits256 txid,int32_t vout,int32_t height,char *coinaddr,uint64_t value) { From 4720157afd869030f8ec5d4b260bb40824406a6f Mon Sep 17 00:00:00 2001 From: jl777 Date: Sun, 12 Nov 2017 12:00:14 +0200 Subject: [PATCH 0628/1664] Test --- iguana/exchanges/LP_remember.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/iguana/exchanges/LP_remember.c b/iguana/exchanges/LP_remember.c index b50caa432..44d93a71a 100644 --- a/iguana/exchanges/LP_remember.c +++ b/iguana/exchanges/LP_remember.c @@ -450,7 +450,7 @@ cJSON *LP_swap_json(struct LP_swap_remember *rswap) { cJSON *item,*array; int32_t i; item = cJSON_CreateObject(); - jaddnum(item,"timestamp",rswap->expiration - INSTANTDEX_LOCKTIME*2); + jaddnum(item,"expiration",rswap->expiration);// - INSTANTDEX_LOCKTIME*2); jaddnum(item,"tradeid",rswap->tradeid); jaddnum(item,"requestid",rswap->requestid); jaddnum(item,"quoteid",rswap->quoteid); From acc7a27089f5ad01e937d982351a9a48f0dce09f Mon Sep 17 00:00:00 2001 From: jl777 Date: Sun, 12 Nov 2017 12:36:45 +0200 Subject: [PATCH 0629/1664] Test --- iguana/exchanges/LP_ordermatch.c | 12 ++++++++++-- 1 file changed, 10 insertions(+), 2 deletions(-) diff --git a/iguana/exchanges/LP_ordermatch.c b/iguana/exchanges/LP_ordermatch.c index 08721bcaf..ac4034a29 100644 --- a/iguana/exchanges/LP_ordermatch.c +++ b/iguana/exchanges/LP_ordermatch.c @@ -1011,7 +1011,7 @@ struct LP_utxoinfo *LP_buyutxo(double *ordermatchpricep,int64_t *bestsatoshisp,i 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,bits256 destpubkey,uint32_t tradeid) { - uint64_t desttxfee,txfee; uint32_t lastnonce; int32_t i,maxiters,numpubs = 0; int64_t bestsatoshis=0,destsatoshis,bestdestsatoshis=0; struct iguana_info *basecoin,*relcoin; struct LP_utxoinfo *autxo,*bestutxo = 0; double qprice,ordermatchprice=0.; struct LP_quoteinfo Q; bits256 pubkeys[100]; + uint64_t desttxfee,txfee; uint32_t lastnonce; int32_t i,maxiters,numpubs = 0; int64_t bestsatoshis=0,destsatoshis,bestdestsatoshis=0; struct iguana_info *basecoin,*relcoin; struct LP_utxoinfo *autxo,B,*bestutxo = 0; double qprice,ordermatchprice=0.; struct LP_quoteinfo Q; bits256 pubkeys[100]; basecoin = LP_coinfind(base); relcoin = LP_coinfind(rel); if ( gui == 0 ) @@ -1076,8 +1076,16 @@ char *LP_autobuy(void *ctx,char *myipaddr,int32_t mypubsock,char *base,char *rel printf("destsatoshis %.8f vs utxo %.8f this would have triggered an quote error -13\n",dstr(destsatoshis),dstr(autxo->payment.value)); return(clonestr("{\"error\":\"cant find alice utxo that is small enough\"}")); } + bestsatoshis = LP_basesatoshis(relvolume,maxprice,txfee,desttxfee); + memset(&B,0,sizeof(B)); + strcpy(B.coin,base); + if ( LP_quoteinfoinit(&Q,&B,rel,maxprice,bestsatoshis,destsatoshis) < 0 ) + 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\"}")); + return(LP_trade(ctx,myipaddr,mypubsock,&Q,maxprice,timeout,duration,tradeid)); + LP_RTmetrics_update(base,rel); - //return(LP_trade(ctx,myipaddr,mypubsock,&Q,maxprice,timeout,duration,tradeid)); while ( 1 ) { if ( (bestutxo= LP_buyutxo(&ordermatchprice,&bestsatoshis,&bestdestsatoshis,autxo,base,maxprice,duration,txfee,desttxfee,gui,pubkeys,numpubs,destpubkey)) == 0 || ordermatchprice == 0. || bestdestsatoshis == 0 ) From e428bc183f8afb7c7f9c856f4b9335d3767f9725 Mon Sep 17 00:00:00 2001 From: jl777 Date: Sun, 12 Nov 2017 13:07:42 +0200 Subject: [PATCH 0630/1664] Test --- iguana/exchanges/LP_commands.c | 1 - iguana/exchanges/LP_nativeDEX.c | 2 ++ iguana/exchanges/LP_socket.c | 4 ++-- iguana/exchanges/LP_utxo.c | 1 + iguana/exchanges/LP_utxos.c | 1 + 5 files changed, 6 insertions(+), 3 deletions(-) diff --git a/iguana/exchanges/LP_commands.c b/iguana/exchanges/LP_commands.c index 9d0f4ff47..1b25666c9 100644 --- a/iguana/exchanges/LP_commands.c +++ b/iguana/exchanges/LP_commands.c @@ -395,7 +395,6 @@ bot_resume(botid)\n\ LP_address(ptr,coinaddr); if ( strcmp(coinaddr,ptr->smartaddr) == 0 && bits256_nonz(G.LP_privkey) != 0 ) { - LP_listunspent_issue(coin,coinaddr,2); LP_privkey_init(-1,ptr,G.LP_privkey,G.LP_mypub25519); //LP_smartutxos_push(ptr); if ( ptr->electrum != 0 ) diff --git a/iguana/exchanges/LP_nativeDEX.c b/iguana/exchanges/LP_nativeDEX.c index 279276789..a3f9a648f 100644 --- a/iguana/exchanges/LP_nativeDEX.c +++ b/iguana/exchanges/LP_nativeDEX.c @@ -813,12 +813,14 @@ void LP_reserved_msgs(void *ignore) if ( num_Reserved_msgs[1] > 0 ) { num_Reserved_msgs[1]--; + printf("PRIORITY BROADCAST.(%s)\n",Reserved_msgs[1][num_Reserved_msgs[1]]); LP_broadcast_message(LP_mypubsock,"","",zero,Reserved_msgs[1][num_Reserved_msgs[1]]); Reserved_msgs[1][num_Reserved_msgs[1]] = 0; } else if ( num_Reserved_msgs[0] > 0 ) { num_Reserved_msgs[0]--; + printf("BROADCAST.(%s)\n",Reserved_msgs[0][num_Reserved_msgs[0]]); LP_broadcast_message(LP_mypubsock,"","",zero,Reserved_msgs[0][num_Reserved_msgs[0]]); Reserved_msgs[0][num_Reserved_msgs[0]] = 0; } diff --git a/iguana/exchanges/LP_socket.c b/iguana/exchanges/LP_socket.c index 5be93ba33..0dc2d6596 100644 --- a/iguana/exchanges/LP_socket.c +++ b/iguana/exchanges/LP_socket.c @@ -288,7 +288,7 @@ int32_t electrum_process_array(struct iguana_info *coin,struct electrum_info *ep 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 ) { - //printf("PROCESS %s/%s %s num.%d\n",coin->symbol,ep!=0?ep->symbol:"nanolistunspent",coinaddr,n); + printf("PROCESS %s/%s %s num.%d\n",coin->symbol,ep!=0?ep->symbol:"nanolistunspent",coinaddr,n); for (i=0; i 1 ) + if ( 1 && electrumflag > 1 ) printf("%s.%d u.%u/%d t.%ld %s LISTUNSPENT.(%d)\n",coin->symbol,height,ap->unspenttime,ap->unspentheight,time(NULL),addr,(int32_t)strlen(jprint(retjson,0))); updatedflag = 0; if ( electrum_process_array(coin,ep,addr,retjson,electrumflag) != 0 ) diff --git a/iguana/exchanges/LP_utxo.c b/iguana/exchanges/LP_utxo.c index e76b74a54..855794a45 100644 --- a/iguana/exchanges/LP_utxo.c +++ b/iguana/exchanges/LP_utxo.c @@ -145,6 +145,7 @@ int32_t LP_address_utxo_ptrs(struct iguana_info *coin,int32_t iambob,struct LP_a //printf("LP_address_utxo_ptrs for (%s).(%s)\n",ap->coinaddr,coinaddr); if ( strcmp(ap->coinaddr,coinaddr) != 0 ) printf("UNEXPECTED coinaddr mismatch (%s) != (%s)\n",ap->coinaddr,coinaddr); + LP_listunspent_issue(coin->symbol,coin->smartaddr,2); portable_mutex_lock(&LP_utxomutex); DL_FOREACH_SAFE(ap->utxos,up,tmp) { diff --git a/iguana/exchanges/LP_utxos.c b/iguana/exchanges/LP_utxos.c index e82541a63..c453368f2 100644 --- a/iguana/exchanges/LP_utxos.c +++ b/iguana/exchanges/LP_utxos.c @@ -550,6 +550,7 @@ int32_t LP_privkey_init(int32_t mypubsock,struct iguana_info *coin,bits256 mypri return(0); coin->privkeydepth++; //printf("privkey init.(%s) %s depth.%d\n",coin->symbol,coin->smartaddr,coin->privkeydepth); + LP_listunspent_issue(coin->symbol,coin->smartaddr,2); if ( coin->inactive == 0 ) LP_listunspent_issue(coin->symbol,coin->smartaddr,0); array = LP_listunspent(coin->symbol,coin->smartaddr); From 197fffb8466d125939a41920b82eefaff46a93a2 Mon Sep 17 00:00:00 2001 From: jl777 Date: Sun, 12 Nov 2017 13:16:54 +0200 Subject: [PATCH 0631/1664] Test --- iguana/exchanges/LP_utxo.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/iguana/exchanges/LP_utxo.c b/iguana/exchanges/LP_utxo.c index 855794a45..16ecba91d 100644 --- a/iguana/exchanges/LP_utxo.c +++ b/iguana/exchanges/LP_utxo.c @@ -186,7 +186,7 @@ int32_t LP_address_utxo_ptrs(struct iguana_info *coin,int32_t iambob,struct LP_a continue; } } - if ( LP_allocated(up->U.txid,up->U.vout) == 0 && _LP_utxofind(iambob,up->U.txid,up->U.vout) == 0 && _LP_utxo2find(iambob,up->U.txid,up->U.vout) == 0 ) + if ( LP_allocated(up->U.txid,up->U.vout) == 0 && (iambob == 0 || (_LP_utxofind(iambob,up->U.txid,up->U.vout) == 0 && _LP_utxo2find(iambob,up->U.txid,up->U.vout) == 0)) ) { utxos[n++] = up; if ( n >= max ) From 8fe188021c5610b5776ae06efbe8d8b198954084 Mon Sep 17 00:00:00 2001 From: jl777 Date: Sun, 12 Nov 2017 13:28:28 +0200 Subject: [PATCH 0632/1664] Test --- iguana/exchanges/LP_socket.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/iguana/exchanges/LP_socket.c b/iguana/exchanges/LP_socket.c index 0dc2d6596..5be93ba33 100644 --- a/iguana/exchanges/LP_socket.c +++ b/iguana/exchanges/LP_socket.c @@ -288,7 +288,7 @@ int32_t electrum_process_array(struct iguana_info *coin,struct electrum_info *ep 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 ) { - printf("PROCESS %s/%s %s num.%d\n",coin->symbol,ep!=0?ep->symbol:"nanolistunspent",coinaddr,n); + //printf("PROCESS %s/%s %s num.%d\n",coin->symbol,ep!=0?ep->symbol:"nanolistunspent",coinaddr,n); for (i=0; i 1 ) + if ( 0 && electrumflag > 1 ) printf("%s.%d u.%u/%d t.%ld %s LISTUNSPENT.(%d)\n",coin->symbol,height,ap->unspenttime,ap->unspentheight,time(NULL),addr,(int32_t)strlen(jprint(retjson,0))); updatedflag = 0; if ( electrum_process_array(coin,ep,addr,retjson,electrumflag) != 0 ) From 8571a0e1cb6f00af15b48a0daafa6c2d89dbebf4 Mon Sep 17 00:00:00 2001 From: jl777 Date: Sun, 12 Nov 2017 13:38:53 +0200 Subject: [PATCH 0633/1664] Test --- iguana/exchanges/LP_ordermatch.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/iguana/exchanges/LP_ordermatch.c b/iguana/exchanges/LP_ordermatch.c index ac4034a29..305322e22 100644 --- a/iguana/exchanges/LP_ordermatch.c +++ b/iguana/exchanges/LP_ordermatch.c @@ -676,7 +676,7 @@ int32_t LP_tradecommand(void *ctx,char *myipaddr,int32_t pubsock,cJSON *argjson, LP_quoteparse(&Q,argjson); LP_requestinit(&Q.R,Q.srchash,Q.desthash,Q.srccoin,Q.satoshis-Q.txfee,Q.destcoin,Q.destsatoshis-Q.desttxfee,Q.timestamp,Q.quotetime,DEXselector); LP_tradecommand_log(argjson); - //printf("LP_tradecommand: check received method %s aliceid.%llx\n",method,(long long)Q.aliceid); + printf("LP_tradecommand: check received method %s aliceid.%llx %s/%s %.8f -> %.8f\n",method,(long long)Q.aliceid,Q.srccoin,Q.destcoin,dstr(Q.satoshis),dstr(Q.destsatoshis)); retval = 1; autxo = &A; butxo = &B; @@ -761,7 +761,7 @@ int32_t LP_tradecommand(void *ctx,char *myipaddr,int32_t pubsock,cJSON *argjson, if ( strcmp(method,"request") == 0 ) { char str[65],str2[65]; - //printf("address.(%s/%s) request.(%s)\n",Q.coinaddr,coin->smartaddr,jprint(argjson,0)); + printf("address.(%s/%s) request.(%s)\n",Q.coinaddr,coin->smartaddr,jprint(argjson,0)); recalc = 0; if ( bits256_cmp(Q.srchash,G.LP_mypub25519) != 0 || strcmp(butxo->coinaddr,coin->smartaddr) != 0 ) { @@ -808,7 +808,7 @@ int32_t LP_tradecommand(void *ctx,char *myipaddr,int32_t pubsock,cJSON *argjson, printf("request from blacklisted %s, ignore\n",bits256_str(str,Q.desthash)); return(retval); } - //printf("butxo.%p recalc 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)); + printf("butxo.%p recalc 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,0); if ( (butxo= LP_address_utxopair(1,utxos,max,LP_coinfind(Q.srccoin),Q.coinaddr,Q.txfee,dstr(Q.destsatoshis),price,Q.desttxfee)) != 0 ) { From 9bc00587a7920a8af8e01cf5080c45d72cd23036 Mon Sep 17 00:00:00 2001 From: jl777 Date: Sun, 12 Nov 2017 13:41:32 +0200 Subject: [PATCH 0634/1664] Test --- iguana/exchanges/LP_nativeDEX.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/iguana/exchanges/LP_nativeDEX.c b/iguana/exchanges/LP_nativeDEX.c index a3f9a648f..7fc952235 100644 --- a/iguana/exchanges/LP_nativeDEX.c +++ b/iguana/exchanges/LP_nativeDEX.c @@ -813,14 +813,14 @@ void LP_reserved_msgs(void *ignore) if ( num_Reserved_msgs[1] > 0 ) { num_Reserved_msgs[1]--; - printf("PRIORITY BROADCAST.(%s)\n",Reserved_msgs[1][num_Reserved_msgs[1]]); + //printf("PRIORITY BROADCAST.(%s)\n",Reserved_msgs[1][num_Reserved_msgs[1]]); LP_broadcast_message(LP_mypubsock,"","",zero,Reserved_msgs[1][num_Reserved_msgs[1]]); Reserved_msgs[1][num_Reserved_msgs[1]] = 0; } else if ( num_Reserved_msgs[0] > 0 ) { num_Reserved_msgs[0]--; - printf("BROADCAST.(%s)\n",Reserved_msgs[0][num_Reserved_msgs[0]]); + //printf("BROADCAST.(%s)\n",Reserved_msgs[0][num_Reserved_msgs[0]]); LP_broadcast_message(LP_mypubsock,"","",zero,Reserved_msgs[0][num_Reserved_msgs[0]]); Reserved_msgs[0][num_Reserved_msgs[0]] = 0; } From 05ba34f9b14beb2dd8dbe35b8a90b72fe98a79e2 Mon Sep 17 00:00:00 2001 From: jl777 Date: Sun, 12 Nov 2017 13:53:55 +0200 Subject: [PATCH 0635/1664] Test --- iguana/exchanges/LP_ordermatch.c | 14 ++++---------- 1 file changed, 4 insertions(+), 10 deletions(-) diff --git a/iguana/exchanges/LP_ordermatch.c b/iguana/exchanges/LP_ordermatch.c index 305322e22..9e7305d72 100644 --- a/iguana/exchanges/LP_ordermatch.c +++ b/iguana/exchanges/LP_ordermatch.c @@ -486,14 +486,6 @@ char *LP_connectedalice(cJSON *argjson) // alice return(clonestr("{\"result\",\"update stats\"}")); } printf("CONNECTED.(%s) numpending.%d tradeid.%u\n",jprint(argjson,0),G.LP_pendingswaps,Q.tradeid); - /*if ( LP_alice_eligible() == 0 || LP_quotecmp(&Q,&LP_Alicequery) != 0 ) - { - printf("reject mismatched alice query\n"); - return(clonestr("{\"error\",\"mismatched alice query\"}")); - } - memset(&LP_Alicequery,0,sizeof(LP_Alicequery)); - LP_Alicemaxprice = 0.; - Alice_expiration = 0;*/ if ( (autxo= LP_utxopairfind(0,Q.desttxid,Q.destvout,Q.feetxid,Q.feevout)) == 0 ) { printf("cant find autxo\n"); @@ -761,9 +753,8 @@ int32_t LP_tradecommand(void *ctx,char *myipaddr,int32_t pubsock,cJSON *argjson, if ( strcmp(method,"request") == 0 ) { char str[65],str2[65]; - printf("address.(%s/%s) request.(%s)\n",Q.coinaddr,coin->smartaddr,jprint(argjson,0)); recalc = 0; - if ( bits256_cmp(Q.srchash,G.LP_mypub25519) != 0 || strcmp(butxo->coinaddr,coin->smartaddr) != 0 ) + if ( bits256_cmp(Q.srchash,G.LP_mypub25519) != 0 || strcmp(butxo->coinaddr,coin->smartaddr) != 0 || bits256_nonz(butxo->payment.txid) == 0 || bits256_nonz(butxo->deposit.txid) == 0 ) { strcpy(Q.gui,G.gui); strcpy(Q.coinaddr,coin->smartaddr); @@ -800,6 +791,7 @@ int32_t LP_tradecommand(void *ctx,char *myipaddr,int32_t pubsock,cJSON *argjson, recalc = 1; } } + printf("recalc.%d address.(%s/%s) request.(%s)\n",recalc,Q.coinaddr,coin->smartaddr,jprint(argjson,0)); if ( recalc != 0 ) { LP_RTmetrics_update(Q.srccoin,Q.destcoin); @@ -1083,6 +1075,8 @@ 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\"}")); + int32_t changed; + LP_mypriceset(&changed,autxo->coin,base,1. / maxprice); return(LP_trade(ctx,myipaddr,mypubsock,&Q,maxprice,timeout,duration,tradeid)); LP_RTmetrics_update(base,rel); From 91eb8aadb1efbab4a342bd037a4913cad9439479 Mon Sep 17 00:00:00 2001 From: jl777 Date: Sun, 12 Nov 2017 13:59:27 +0200 Subject: [PATCH 0636/1664] Test --- iguana/exchanges/LP_ordermatch.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/iguana/exchanges/LP_ordermatch.c b/iguana/exchanges/LP_ordermatch.c index 9e7305d72..6a10898a9 100644 --- a/iguana/exchanges/LP_ordermatch.c +++ b/iguana/exchanges/LP_ordermatch.c @@ -494,6 +494,7 @@ char *LP_connectedalice(cJSON *argjson) // alice } if ( autxo->S.swap != 0 ) { + printf("ignore duplicate swap\n"); LP_aliceid(Q.tradeid,Q.aliceid,"error3",0,0); return(clonestr("{\"error\":\"ignore duplicate swap\"}")); } @@ -510,7 +511,7 @@ char *LP_connectedalice(cJSON *argjson) // alice } if ( LP_myprice(&bid,&ask,Q.srccoin,Q.destcoin) <= SMALLVAL || bid <= SMALLVAL ) { - //printf("this node has no price for %s/%s (%.8f %.8f)\n",Q.destcoin,Q.srccoin,bid,ask); + printf("this node has no price for %s/%s (%.8f %.8f)\n",Q.destcoin,Q.srccoin,bid,ask); LP_availableset(autxo); LP_aliceid(Q.tradeid,Q.aliceid,"error5",0,0); return(clonestr("{\"error\":\"no price set\"}")); From 94013d9cd04c54f2ba138b3100a5eebbcef4d1ec Mon Sep 17 00:00:00 2001 From: jl777 Date: Sun, 12 Nov 2017 14:11:31 +0200 Subject: [PATCH 0637/1664] Test --- iguana/exchanges/LP_ordermatch.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/iguana/exchanges/LP_ordermatch.c b/iguana/exchanges/LP_ordermatch.c index 6a10898a9..a0a6ca5f2 100644 --- a/iguana/exchanges/LP_ordermatch.c +++ b/iguana/exchanges/LP_ordermatch.c @@ -801,7 +801,6 @@ int32_t LP_tradecommand(void *ctx,char *myipaddr,int32_t pubsock,cJSON *argjson, printf("request from blacklisted %s, ignore\n",bits256_str(str,Q.desthash)); return(retval); } - printf("butxo.%p recalc 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,0); if ( (butxo= LP_address_utxopair(1,utxos,max,LP_coinfind(Q.srccoin),Q.coinaddr,Q.txfee,dstr(Q.destsatoshis),price,Q.desttxfee)) != 0 ) { @@ -817,7 +816,7 @@ int32_t LP_tradecommand(void *ctx,char *myipaddr,int32_t pubsock,cJSON *argjson, } else { - //printf("cant find utxopair\n"); + printf("cant find utxopair\n"); return(retval); } } From eb3984aecea9d628f5d68743c168cd62779474a6 Mon Sep 17 00:00:00 2001 From: jl777 Date: Sun, 12 Nov 2017 14:17:08 +0200 Subject: [PATCH 0638/1664] Test --- iguana/exchanges/LP_ordermatch.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/iguana/exchanges/LP_ordermatch.c b/iguana/exchanges/LP_ordermatch.c index a0a6ca5f2..a43b776da 100644 --- a/iguana/exchanges/LP_ordermatch.c +++ b/iguana/exchanges/LP_ordermatch.c @@ -261,7 +261,7 @@ int32_t LP_nearest_utxovalue(struct iguana_info *coin,char *coinaddr,struct LP_a 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); @@ -669,7 +669,7 @@ int32_t LP_tradecommand(void *ctx,char *myipaddr,int32_t pubsock,cJSON *argjson, LP_quoteparse(&Q,argjson); LP_requestinit(&Q.R,Q.srchash,Q.desthash,Q.srccoin,Q.satoshis-Q.txfee,Q.destcoin,Q.destsatoshis-Q.desttxfee,Q.timestamp,Q.quotetime,DEXselector); LP_tradecommand_log(argjson); - printf("LP_tradecommand: check received method %s aliceid.%llx %s/%s %.8f -> %.8f\n",method,(long long)Q.aliceid,Q.srccoin,Q.destcoin,dstr(Q.satoshis),dstr(Q.destsatoshis)); + printf("LP_tradecommand: check received method %s aliceid.%llx %s/%s %.8f -> %.8f price %.8f\n",method,(long long)Q.aliceid,Q.srccoin,Q.destcoin,dstr(Q.satoshis),dstr(Q.destsatoshis),(double)Q.destsatoshis/Q.satoshis); retval = 1; autxo = &A; butxo = &B; @@ -771,6 +771,7 @@ int32_t LP_tradecommand(void *ctx,char *myipaddr,int32_t pubsock,cJSON *argjson, else { char tmp[64]; + printf("price %.8f qprice %.8f -> %.8f\n",dstr(price),dstr(qprice),dstr((qprice * 0.5) + (0.5 * price))); price = (qprice * 0.5) + (0.5 * price); if ( bits256_nonz(Q.txid) != 0 ) LP_utxos_remove(Q.txid,Q.vout); From a45ced08e94badf081f7c4c2500c53b0e790ac52 Mon Sep 17 00:00:00 2001 From: jl777 Date: Sun, 12 Nov 2017 14:44:29 +0200 Subject: [PATCH 0639/1664] Test --- iguana/exchanges/LP_ordermatch.c | 53 +++++++++++++++++++++++++------- 1 file changed, 42 insertions(+), 11 deletions(-) diff --git a/iguana/exchanges/LP_ordermatch.c b/iguana/exchanges/LP_ordermatch.c index a43b776da..a46ba3902 100644 --- a/iguana/exchanges/LP_ordermatch.c +++ b/iguana/exchanges/LP_ordermatch.c @@ -18,6 +18,31 @@ // LP_ordermatch.c // marketmaker // +struct LP_quoteinfo LP_Alicequery; +double LP_Alicemaxprice; +uint32_t Alice_expiration; +struct { uint64_t aliceid; double bestprice; } Bob_competition[512]; + +double LP_bob_competition(uint64_t aliceid,double price) +{ + int32_t i,firsti = -1; + for (i=0; i dstr(desttxfee) && price > SMALLVAL ) return(SATOSHIDEN * (relvolume / price) + 2*txfee); else return(0); @@ -413,9 +438,6 @@ int32_t LP_connectstartbob(void *ctx,int32_t pubsock,struct LP_utxoinfo *utxo,cJ return(retval); } -struct LP_quoteinfo LP_Alicequery; -double LP_Alicemaxprice; -uint32_t Alice_expiration; char *LP_trade(void *ctx,char *myipaddr,int32_t mypubsock,struct LP_quoteinfo *qp,double maxprice,int32_t timeout,int32_t duration,uint32_t tradeid) { 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; @@ -662,14 +684,14 @@ int32_t LP_validSPV(char *symbol,char *coinaddr,bits256 txid,int32_t vout) int32_t LP_tradecommand(void *ctx,char *myipaddr,int32_t pubsock,cJSON *argjson,uint8_t *data,int32_t datalen) { - 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,recalc,max=(int32_t)(sizeof(utxos)/sizeof(*utxos)); + char *method,*msg,*retstr,str[65]; int32_t DEXselector = 0; uint64_t aliceid,value,value2; cJSON *retjson; double qprice,bestprice,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,recalc,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) ) { // LP_checksig LP_quoteparse(&Q,argjson); LP_requestinit(&Q.R,Q.srchash,Q.desthash,Q.srccoin,Q.satoshis-Q.txfee,Q.destcoin,Q.destsatoshis-Q.desttxfee,Q.timestamp,Q.quotetime,DEXselector); LP_tradecommand_log(argjson); - printf("LP_tradecommand: check received method %s aliceid.%llx %s/%s %.8f -> %.8f price %.8f\n",method,(long long)Q.aliceid,Q.srccoin,Q.destcoin,dstr(Q.satoshis),dstr(Q.destsatoshis),(double)Q.destsatoshis/Q.satoshis); + printf("LP_tradecommand: check received method %12s aliceid.%16llx %5s/%-5s %12.8f -> %12.8f price %12.8f\n",method,(long long)Q.aliceid,Q.srccoin,Q.destcoin,dstr(Q.satoshis),dstr(Q.destsatoshis),(double)Q.destsatoshis/Q.satoshis); retval = 1; autxo = &A; butxo = &B; @@ -678,6 +700,10 @@ int32_t LP_tradecommand(void *ctx,char *myipaddr,int32_t pubsock,cJSON *argjson, LP_abutxo_set(autxo,butxo,&Q); if ( strcmp(method,"reserved") == 0 ) { + aliceid = j64bits(argjson,"aliceid"); + price = jdouble(argjson,"price"); + bestprice = LP_bob_competition(aliceid,price); + printf("aliceid.%llx price %.8f -> bestprice %.8f\n",(long long)aliceid,price,bestprice); if ( LP_Alicemaxprice == 0. ) return(retval); if ( bits256_cmp(G.LP_mypub25519,Q.desthash) == 0 && bits256_cmp(G.LP_mypub25519,Q.srchash) != 0 && LP_alice_eligible() > 0 ) @@ -768,11 +794,16 @@ int32_t LP_tradecommand(void *ctx,char *myipaddr,int32_t pubsock,cJSON *argjson, } else if ( (qprice= LP_quote_validate(autxo,butxo,&Q,1)) < SMALLVAL ) recalc = 1; - else + else if ( price < qprice ) { - char tmp[64]; - printf("price %.8f qprice %.8f -> %.8f\n",dstr(price),dstr(qprice),dstr((qprice * 0.5) + (0.5 * price))); - price = (qprice * 0.5) + (0.5 * price); + char tmp[64]; double range; int32_t r; + r = (rand() % 100); + range = (qprice - price); + bestprice = LP_bob_competition(j64bits(argjson,"aliceid"),price); + printf(">>>>>>>>>>>>> price %.8f qprice %.8f r.%d range %.8f -> %.8f vs bestprice %.8f\n",dstr(price),dstr(qprice),r,range,price + r*range,bestprice); + price += (r * range); + if ( price < bestprice+SMALLVAL ) + return(retval); if ( bits256_nonz(Q.txid) != 0 ) LP_utxos_remove(Q.txid,Q.vout); else recalc = 1; @@ -792,7 +823,7 @@ int32_t LP_tradecommand(void *ctx,char *myipaddr,int32_t pubsock,cJSON *argjson, if ( bits256_cmp(Q.txid,butxo->payment.txid) != 0 || Q.vout != butxo->payment.vout || bits256_cmp(Q.txid2,butxo->deposit.txid) != 0 || Q.vout2 != butxo->deposit.vout ) recalc = 1; } - } + } else return(retval); printf("recalc.%d address.(%s/%s) request.(%s)\n",recalc,Q.coinaddr,coin->smartaddr,jprint(argjson,0)); if ( recalc != 0 ) { From 2c9e15808345dc40464b55b562a31301a9e6a4ee Mon Sep 17 00:00:00 2001 From: jl777 Date: Sun, 12 Nov 2017 14:53:43 +0200 Subject: [PATCH 0640/1664] Test --- iguana/exchanges/LP_ordermatch.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/iguana/exchanges/LP_ordermatch.c b/iguana/exchanges/LP_ordermatch.c index a46ba3902..bedd8223b 100644 --- a/iguana/exchanges/LP_ordermatch.c +++ b/iguana/exchanges/LP_ordermatch.c @@ -1100,7 +1100,7 @@ char *LP_autobuy(void *ctx,char *myipaddr,int32_t mypubsock,char *base,char *rel printf("destsatoshis %.8f vs utxo %.8f this would have triggered an quote error -13\n",dstr(destsatoshis),dstr(autxo->payment.value)); return(clonestr("{\"error\":\"cant find alice utxo that is small enough\"}")); } - bestsatoshis = LP_basesatoshis(relvolume,maxprice,txfee,desttxfee); + bestsatoshis = LP_basesatoshis(dstr(destsatoshis),maxprice,txfee,desttxfee); memset(&B,0,sizeof(B)); strcpy(B.coin,base); if ( LP_quoteinfoinit(&Q,&B,rel,maxprice,bestsatoshis,destsatoshis) < 0 ) From c01ef0fe05f0f00ea9df78e805ed7a05f0d77bd7 Mon Sep 17 00:00:00 2001 From: jl777 Date: Sun, 12 Nov 2017 14:59:14 +0200 Subject: [PATCH 0641/1664] Test --- iguana/exchanges/LP_ordermatch.c | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/iguana/exchanges/LP_ordermatch.c b/iguana/exchanges/LP_ordermatch.c index bedd8223b..fb7e8103c 100644 --- a/iguana/exchanges/LP_ordermatch.c +++ b/iguana/exchanges/LP_ordermatch.c @@ -30,8 +30,11 @@ double LP_bob_competition(uint64_t aliceid,double price) { if ( Bob_competition[i].aliceid == aliceid ) { - if ( price < Bob_competition[i].bestprice ) + if ( price != 0. && (Bob_competition[i].bestprice == 0. || price < Bob_competition[i].bestprice) ) + { Bob_competition[i].bestprice = price; + printf("Bob competition aliceid.%llx <- bestprice %.8f\n",(long long)aliceid,price); + } return(Bob_competition[i].bestprice); } else if ( Bob_competition[i].aliceid == 0 ) @@ -41,7 +44,8 @@ double LP_bob_competition(uint64_t aliceid,double price) firsti = (rand() % (sizeof(Bob_competition)/sizeof(*Bob_competition))); Bob_competition[firsti].aliceid = aliceid; Bob_competition[firsti].bestprice = price; - return(Bob_competition[i].bestprice); + printf("Bob competition aliceid.%llx %.8f\n",(long long)aliceid,price); + return(price); } uint64_t LP_txfeecalc(struct iguana_info *coin,uint64_t txfee,int32_t txlen) From 1c6eaf859d6a7a3811f2afd1db0443e97ec2adcd Mon Sep 17 00:00:00 2001 From: jl777 Date: Sun, 12 Nov 2017 15:22:46 +0200 Subject: [PATCH 0642/1664] Test --- iguana/exchanges/LP_ordermatch.c | 17 +++++++++-------- 1 file changed, 9 insertions(+), 8 deletions(-) diff --git a/iguana/exchanges/LP_ordermatch.c b/iguana/exchanges/LP_ordermatch.c index fb7e8103c..5f8c7b81f 100644 --- a/iguana/exchanges/LP_ordermatch.c +++ b/iguana/exchanges/LP_ordermatch.c @@ -800,14 +800,7 @@ int32_t LP_tradecommand(void *ctx,char *myipaddr,int32_t pubsock,cJSON *argjson, recalc = 1; else if ( price < qprice ) { - char tmp[64]; double range; int32_t r; - r = (rand() % 100); - range = (qprice - price); - bestprice = LP_bob_competition(j64bits(argjson,"aliceid"),price); - printf(">>>>>>>>>>>>> price %.8f qprice %.8f r.%d range %.8f -> %.8f vs bestprice %.8f\n",dstr(price),dstr(qprice),r,range,price + r*range,bestprice); - price += (r * range); - if ( price < bestprice+SMALLVAL ) - return(retval); + char tmp[64]; if ( bits256_nonz(Q.txid) != 0 ) LP_utxos_remove(Q.txid,Q.vout); else recalc = 1; @@ -828,6 +821,14 @@ int32_t LP_tradecommand(void *ctx,char *myipaddr,int32_t pubsock,cJSON *argjson, recalc = 1; } } else return(retval); + double range; int32_t r; + r = (rand() % 100); + range = (qprice - price); + bestprice = LP_bob_competition(j64bits(argjson,"aliceid"),price); + printf(">>>>>>>>>>>>> price %.8f qprice %.8f r.%d range %.8f -> %.8f vs bestprice %.8f\n",dstr(price),dstr(qprice),r,range,price + r*range,bestprice); + price += (r * range); + if ( price < bestprice+SMALLVAL ) + return(retval); printf("recalc.%d address.(%s/%s) request.(%s)\n",recalc,Q.coinaddr,coin->smartaddr,jprint(argjson,0)); if ( recalc != 0 ) { From 006cf524691402583f2ffbd510a836274107f073 Mon Sep 17 00:00:00 2001 From: jl777 Date: Sun, 12 Nov 2017 15:26:47 +0200 Subject: [PATCH 0643/1664] Test --- iguana/exchanges/LP_ordermatch.c | 1 + 1 file changed, 1 insertion(+) diff --git a/iguana/exchanges/LP_ordermatch.c b/iguana/exchanges/LP_ordermatch.c index 5f8c7b81f..defd94f6b 100644 --- a/iguana/exchanges/LP_ordermatch.c +++ b/iguana/exchanges/LP_ordermatch.c @@ -787,6 +787,7 @@ int32_t LP_tradecommand(void *ctx,char *myipaddr,int32_t pubsock,cJSON *argjson, recalc = 0; if ( bits256_cmp(Q.srchash,G.LP_mypub25519) != 0 || strcmp(butxo->coinaddr,coin->smartaddr) != 0 || bits256_nonz(butxo->payment.txid) == 0 || bits256_nonz(butxo->deposit.txid) == 0 ) { + qprice = (double)Q.destsatoshis / Q.satoshis; strcpy(Q.gui,G.gui); strcpy(Q.coinaddr,coin->smartaddr); strcpy(butxo->coinaddr,coin->smartaddr); From be8e18ac41caf85f2ee8ecf443068f7597c89409 Mon Sep 17 00:00:00 2001 From: jl777 Date: Sun, 12 Nov 2017 15:27:52 +0200 Subject: [PATCH 0644/1664] Test --- iguana/exchanges/LP_ordermatch.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/iguana/exchanges/LP_ordermatch.c b/iguana/exchanges/LP_ordermatch.c index defd94f6b..59ea546c0 100644 --- a/iguana/exchanges/LP_ordermatch.c +++ b/iguana/exchanges/LP_ordermatch.c @@ -760,7 +760,8 @@ int32_t LP_tradecommand(void *ctx,char *myipaddr,int32_t pubsock,cJSON *argjson, } return(retval); } - if ( (coin= LP_coinfind(Q.srccoin)) == 0 || (price= LP_myprice(&bid,&ask,Q.srccoin,Q.destcoin)) <= SMALLVAL || ask <= SMALLVAL ) + price = LP_myprice(&bid,&ask,Q.srccoin,Q.destcoin); + if ( (coin= LP_coinfind(Q.srccoin)) == 0 || ask <= SMALLVAL ) { //printf("this node has no price for %s/%s\n",Q.srccoin,Q.destcoin); return(retval); From 913504797fcf93a972cdc327b19e6b40670eb5ae Mon Sep 17 00:00:00 2001 From: jl777 Date: Sun, 12 Nov 2017 15:38:15 +0200 Subject: [PATCH 0645/1664] Test --- iguana/exchanges/LP_ordermatch.c | 9 +++------ 1 file changed, 3 insertions(+), 6 deletions(-) diff --git a/iguana/exchanges/LP_ordermatch.c b/iguana/exchanges/LP_ordermatch.c index 59ea546c0..354c5c762 100644 --- a/iguana/exchanges/LP_ordermatch.c +++ b/iguana/exchanges/LP_ordermatch.c @@ -761,7 +761,7 @@ int32_t LP_tradecommand(void *ctx,char *myipaddr,int32_t pubsock,cJSON *argjson, return(retval); } price = LP_myprice(&bid,&ask,Q.srccoin,Q.destcoin); - if ( (coin= LP_coinfind(Q.srccoin)) == 0 || ask <= SMALLVAL ) + if ( (coin= LP_coinfind(Q.srccoin)) == 0 || price <= SMALLVAL || ask <= SMALLVAL ) { //printf("this node has no price for %s/%s\n",Q.srccoin,Q.destcoin); return(retval); @@ -816,10 +816,7 @@ int32_t LP_tradecommand(void *ctx,char *myipaddr,int32_t pubsock,cJSON *argjson, //printf("call LP_utxoadd.(%s) %.8f %.8f\n",Q.coinaddr,dstr(value),dstr(value2)); if ( (butxo= LP_utxoadd(1,coin->symbol,Q.txid,Q.vout,value,Q.txid2,Q.vout2,value2,Q.coinaddr,Q.srchash,G.gui,0,Q.satoshis)) == 0 ) recalc = 1; - } - else - { - if ( bits256_cmp(Q.txid,butxo->payment.txid) != 0 || Q.vout != butxo->payment.vout || bits256_cmp(Q.txid2,butxo->deposit.txid) != 0 || Q.vout2 != butxo->deposit.vout ) + else if ( bits256_cmp(Q.txid,butxo->payment.txid) != 0 || Q.vout != butxo->payment.vout || bits256_cmp(Q.txid2,butxo->deposit.txid) != 0 || Q.vout2 != butxo->deposit.vout ) recalc = 1; } } else return(retval); @@ -831,7 +828,7 @@ int32_t LP_tradecommand(void *ctx,char *myipaddr,int32_t pubsock,cJSON *argjson, price += (r * range); if ( price < bestprice+SMALLVAL ) return(retval); - printf("recalc.%d address.(%s/%s) request.(%s)\n",recalc,Q.coinaddr,coin->smartaddr,jprint(argjson,0)); + printf("recalc.%d address.(%s/%s) price %.8f request.(%s)\n",recalc,Q.coinaddr,coin->smartaddr,price,jprint(argjson,0)); if ( recalc != 0 ) { LP_RTmetrics_update(Q.srccoin,Q.destcoin); From b95f610e890a67a4d3e23aae1995cb5a262b48e5 Mon Sep 17 00:00:00 2001 From: jl777 Date: Sun, 12 Nov 2017 15:47:42 +0200 Subject: [PATCH 0646/1664] Test --- iguana/exchanges/LP_ordermatch.c | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/iguana/exchanges/LP_ordermatch.c b/iguana/exchanges/LP_ordermatch.c index 354c5c762..3630e89aa 100644 --- a/iguana/exchanges/LP_ordermatch.c +++ b/iguana/exchanges/LP_ordermatch.c @@ -702,12 +702,12 @@ int32_t LP_tradecommand(void *ctx,char *myipaddr,int32_t pubsock,cJSON *argjson, memset(autxo,0,sizeof(*autxo)); memset(butxo,0,sizeof(*butxo)); LP_abutxo_set(autxo,butxo,&Q); + aliceid = j64bits(argjson,"aliceid"); + qprice = jdouble(argjson,"price"); if ( strcmp(method,"reserved") == 0 ) { - aliceid = j64bits(argjson,"aliceid"); - price = jdouble(argjson,"price"); - bestprice = LP_bob_competition(aliceid,price); - printf("aliceid.%llx price %.8f -> bestprice %.8f\n",(long long)aliceid,price,bestprice); + bestprice = LP_bob_competition(aliceid,qprice); + printf("aliceid.%llx price %.8f -> bestprice %.8f\n",(long long)aliceid,qprice,bestprice); if ( LP_Alicemaxprice == 0. ) return(retval); if ( bits256_cmp(G.LP_mypub25519,Q.desthash) == 0 && bits256_cmp(G.LP_mypub25519,Q.srchash) != 0 && LP_alice_eligible() > 0 ) @@ -823,9 +823,9 @@ int32_t LP_tradecommand(void *ctx,char *myipaddr,int32_t pubsock,cJSON *argjson, double range; int32_t r; r = (rand() % 100); range = (qprice - price); - bestprice = LP_bob_competition(j64bits(argjson,"aliceid"),price); - printf(">>>>>>>>>>>>> price %.8f qprice %.8f r.%d range %.8f -> %.8f vs bestprice %.8f\n",dstr(price),dstr(qprice),r,range,price + r*range,bestprice); + printf(">>>>>>>>>>>>> price %.8f qprice %.8f r.%d range %.8f -> %.8f vs bestprice %.8f\n",dstr(price),dstr(qprice),r,range,price + r*range,LP_bob_competition(aliceid,price)); price += (r * range); + bestprice = LP_bob_competition(aliceid,price); if ( price < bestprice+SMALLVAL ) return(retval); printf("recalc.%d address.(%s/%s) price %.8f request.(%s)\n",recalc,Q.coinaddr,coin->smartaddr,price,jprint(argjson,0)); From 6ff2d4fdfd513d571fc7b9094e4ba1995924c905 Mon Sep 17 00:00:00 2001 From: jl777 Date: Sun, 12 Nov 2017 15:58:20 +0200 Subject: [PATCH 0647/1664] Test --- iguana/exchanges/LP_ordermatch.c | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/iguana/exchanges/LP_ordermatch.c b/iguana/exchanges/LP_ordermatch.c index 3630e89aa..53342ae2d 100644 --- a/iguana/exchanges/LP_ordermatch.c +++ b/iguana/exchanges/LP_ordermatch.c @@ -688,7 +688,7 @@ int32_t LP_validSPV(char *symbol,char *coinaddr,bits256 txid,int32_t vout) int32_t LP_tradecommand(void *ctx,char *myipaddr,int32_t pubsock,cJSON *argjson,uint8_t *data,int32_t datalen) { - char *method,*msg,*retstr,str[65]; int32_t DEXselector = 0; uint64_t aliceid,value,value2; cJSON *retjson; double qprice,bestprice,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,recalc,max=(int32_t)(sizeof(utxos)/sizeof(*utxos)); + char *method,*msg,*retstr,str[65]; int32_t DEXselector = 0; uint64_t aliceid,value,value2; cJSON *retjson; double qprice,range,bestprice,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 r,retval = -1,recalc,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) ) { // LP_checksig @@ -766,6 +766,8 @@ int32_t LP_tradecommand(void *ctx,char *myipaddr,int32_t pubsock,cJSON *argjson, //printf("this node has no price for %s/%s\n",Q.srccoin,Q.destcoin); return(retval); } + price = ask; + printf("MYPRICE %s/%s %.8f\n",Q.srccoin,Q.destcoin,price); if ( LP_validSPV(Q.destcoin,Q.destaddr,Q.desttxid,Q.destvout) < 0 ) { printf("%s dest %s failed SPV check\n",Q.destcoin,bits256_str(str,Q.desttxid)); @@ -776,7 +778,6 @@ int32_t LP_tradecommand(void *ctx,char *myipaddr,int32_t pubsock,cJSON *argjson, printf("%s dexfee %s failed SPV check\n",Q.destcoin,bits256_str(str,Q.feetxid)); return(retval); } - price = ask; if ( LP_aliceonly(Q.srccoin) > 0 ) { printf("{\"error\":\"GAME can only be alice coin\"}\n"); @@ -809,6 +810,7 @@ int32_t LP_tradecommand(void *ctx,char *myipaddr,int32_t pubsock,cJSON *argjson, if ( bits256_nonz(Q.txid2) != 0 ) LP_utxos_remove(Q.txid2,Q.vout2); else recalc = 1; + printf("price %.8f qprice %.8f\n",price,qprice); if ( recalc == 0 ) { value = LP_txvalue(tmp,Q.srccoin,Q.txid,Q.vout); @@ -820,10 +822,9 @@ int32_t LP_tradecommand(void *ctx,char *myipaddr,int32_t pubsock,cJSON *argjson, recalc = 1; } } else return(retval); - double range; int32_t r; r = (rand() % 100); range = (qprice - price); - printf(">>>>>>>>>>>>> price %.8f qprice %.8f r.%d range %.8f -> %.8f vs bestprice %.8f\n",dstr(price),dstr(qprice),r,range,price + r*range,LP_bob_competition(aliceid,price)); + printf(">>>>>>>>>>>>> price %.8f qprice %.8f r.%d range %.8f -> %.8f vs bestprice %.8f\n",price,qprice,r,range,price + r*range,LP_bob_competition(aliceid,price)); price += (r * range); bestprice = LP_bob_competition(aliceid,price); if ( price < bestprice+SMALLVAL ) @@ -847,7 +848,7 @@ int32_t LP_tradecommand(void *ctx,char *myipaddr,int32_t pubsock,cJSON *argjson, Q.vout = butxo->payment.vout; Q.txid2 = butxo->deposit.txid; Q.vout2 = butxo->deposit.vout; - butxo->S.satoshis = Q.satoshis; + Q.satoshis = butxo->S.satoshis; printf("set butxo.%p %s/v%d %s/v%d %.8f %.8f -> bsat %.8f asat %.8f\n",butxo,bits256_str(str,butxo->payment.txid),butxo->payment.vout,bits256_str(str2,butxo->deposit.txid),butxo->deposit.vout,dstr(butxo->payment.value),dstr(butxo->deposit.value),dstr(butxo->S.satoshis),dstr(autxo->S.satoshis)); } else From 0eba6792441aeb61943594d241ade40866a9efed Mon Sep 17 00:00:00 2001 From: jl777 Date: Sun, 12 Nov 2017 16:01:08 +0200 Subject: [PATCH 0648/1664] Test --- iguana/exchanges/LP_ordermatch.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/iguana/exchanges/LP_ordermatch.c b/iguana/exchanges/LP_ordermatch.c index 53342ae2d..6f21fc40d 100644 --- a/iguana/exchanges/LP_ordermatch.c +++ b/iguana/exchanges/LP_ordermatch.c @@ -825,7 +825,7 @@ int32_t LP_tradecommand(void *ctx,char *myipaddr,int32_t pubsock,cJSON *argjson, r = (rand() % 100); range = (qprice - price); printf(">>>>>>>>>>>>> price %.8f qprice %.8f r.%d range %.8f -> %.8f vs bestprice %.8f\n",price,qprice,r,range,price + r*range,LP_bob_competition(aliceid,price)); - price += (r * range); + price += (r * range) / 100.; bestprice = LP_bob_competition(aliceid,price); if ( price < bestprice+SMALLVAL ) return(retval); From 6e799be950afe0be666b7b16ecac86de5329b7ff Mon Sep 17 00:00:00 2001 From: jl777 Date: Sun, 12 Nov 2017 16:05:27 +0200 Subject: [PATCH 0649/1664] Test --- iguana/exchanges/LP_ordermatch.c | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/iguana/exchanges/LP_ordermatch.c b/iguana/exchanges/LP_ordermatch.c index 6f21fc40d..f6a947e69 100644 --- a/iguana/exchanges/LP_ordermatch.c +++ b/iguana/exchanges/LP_ordermatch.c @@ -707,7 +707,7 @@ int32_t LP_tradecommand(void *ctx,char *myipaddr,int32_t pubsock,cJSON *argjson, if ( strcmp(method,"reserved") == 0 ) { bestprice = LP_bob_competition(aliceid,qprice); - printf("aliceid.%llx price %.8f -> bestprice %.8f\n",(long long)aliceid,qprice,bestprice); + //printf("aliceid.%llx price %.8f -> bestprice %.8f\n",(long long)aliceid,qprice,bestprice); if ( LP_Alicemaxprice == 0. ) return(retval); if ( bits256_cmp(G.LP_mypub25519,Q.desthash) == 0 && bits256_cmp(G.LP_mypub25519,Q.srchash) != 0 && LP_alice_eligible() > 0 ) @@ -767,7 +767,7 @@ int32_t LP_tradecommand(void *ctx,char *myipaddr,int32_t pubsock,cJSON *argjson, return(retval); } price = ask; - printf("MYPRICE %s/%s %.8f\n",Q.srccoin,Q.destcoin,price); + //printf("MYPRICE %s/%s %.8f\n",Q.srccoin,Q.destcoin,price); if ( LP_validSPV(Q.destcoin,Q.destaddr,Q.desttxid,Q.destvout) < 0 ) { printf("%s dest %s failed SPV check\n",Q.destcoin,bits256_str(str,Q.desttxid)); @@ -785,7 +785,7 @@ int32_t LP_tradecommand(void *ctx,char *myipaddr,int32_t pubsock,cJSON *argjson, } if ( strcmp(method,"request") == 0 ) { - char str[65],str2[65]; + char str[65];//,str2[65]; recalc = 0; if ( bits256_cmp(Q.srchash,G.LP_mypub25519) != 0 || strcmp(butxo->coinaddr,coin->smartaddr) != 0 || bits256_nonz(butxo->payment.txid) == 0 || bits256_nonz(butxo->deposit.txid) == 0 ) { @@ -829,7 +829,7 @@ int32_t LP_tradecommand(void *ctx,char *myipaddr,int32_t pubsock,cJSON *argjson, bestprice = LP_bob_competition(aliceid,price); if ( price < bestprice+SMALLVAL ) return(retval); - printf("recalc.%d address.(%s/%s) price %.8f request.(%s)\n",recalc,Q.coinaddr,coin->smartaddr,price,jprint(argjson,0)); + //printf("recalc.%d address.(%s/%s) price %.8f request.(%s)\n",recalc,Q.coinaddr,coin->smartaddr,price,jprint(argjson,0)); if ( recalc != 0 ) { LP_RTmetrics_update(Q.srccoin,Q.destcoin); @@ -849,7 +849,7 @@ int32_t LP_tradecommand(void *ctx,char *myipaddr,int32_t pubsock,cJSON *argjson, Q.txid2 = butxo->deposit.txid; Q.vout2 = butxo->deposit.vout; Q.satoshis = butxo->S.satoshis; - printf("set butxo.%p %s/v%d %s/v%d %.8f %.8f -> bsat %.8f asat %.8f\n",butxo,bits256_str(str,butxo->payment.txid),butxo->payment.vout,bits256_str(str2,butxo->deposit.txid),butxo->deposit.vout,dstr(butxo->payment.value),dstr(butxo->deposit.value),dstr(butxo->S.satoshis),dstr(autxo->S.satoshis)); + //printf("set butxo.%p %s/v%d %s/v%d %.8f %.8f -> bsat %.8f asat %.8f\n",butxo,bits256_str(str,butxo->payment.txid),butxo->payment.vout,bits256_str(str2,butxo->deposit.txid),butxo->deposit.vout,dstr(butxo->payment.value),dstr(butxo->deposit.value),dstr(butxo->S.satoshis),dstr(autxo->S.satoshis)); } else { From 525411bc891f77e6312b8948b6eb0f18453fde94 Mon Sep 17 00:00:00 2001 From: jl777 Date: Sun, 12 Nov 2017 16:20:54 +0200 Subject: [PATCH 0650/1664] Test --- iguana/exchanges/LP_commands.c | 1 + iguana/exchanges/LP_utxos.c | 1 - 2 files changed, 1 insertion(+), 1 deletion(-) diff --git a/iguana/exchanges/LP_commands.c b/iguana/exchanges/LP_commands.c index 1b25666c9..9d0f4ff47 100644 --- a/iguana/exchanges/LP_commands.c +++ b/iguana/exchanges/LP_commands.c @@ -395,6 +395,7 @@ bot_resume(botid)\n\ LP_address(ptr,coinaddr); if ( strcmp(coinaddr,ptr->smartaddr) == 0 && bits256_nonz(G.LP_privkey) != 0 ) { + LP_listunspent_issue(coin,coinaddr,2); LP_privkey_init(-1,ptr,G.LP_privkey,G.LP_mypub25519); //LP_smartutxos_push(ptr); if ( ptr->electrum != 0 ) diff --git a/iguana/exchanges/LP_utxos.c b/iguana/exchanges/LP_utxos.c index c453368f2..e82541a63 100644 --- a/iguana/exchanges/LP_utxos.c +++ b/iguana/exchanges/LP_utxos.c @@ -550,7 +550,6 @@ int32_t LP_privkey_init(int32_t mypubsock,struct iguana_info *coin,bits256 mypri return(0); coin->privkeydepth++; //printf("privkey init.(%s) %s depth.%d\n",coin->symbol,coin->smartaddr,coin->privkeydepth); - LP_listunspent_issue(coin->symbol,coin->smartaddr,2); if ( coin->inactive == 0 ) LP_listunspent_issue(coin->symbol,coin->smartaddr,0); array = LP_listunspent(coin->symbol,coin->smartaddr); From 633473fc9c38b3259dd1439027e4874f779d196c Mon Sep 17 00:00:00 2001 From: jl777 Date: Sun, 12 Nov 2017 16:30:54 +0200 Subject: [PATCH 0651/1664] Test --- iguana/exchanges/LP_utxos.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/iguana/exchanges/LP_utxos.c b/iguana/exchanges/LP_utxos.c index e82541a63..36612ddaa 100644 --- a/iguana/exchanges/LP_utxos.c +++ b/iguana/exchanges/LP_utxos.c @@ -549,12 +549,12 @@ int32_t LP_privkey_init(int32_t mypubsock,struct iguana_info *coin,bits256 mypri if ( coin->privkeydepth > 0 ) return(0); coin->privkeydepth++; + LP_address(coin,coin->smartaddr); //printf("privkey init.(%s) %s depth.%d\n",coin->symbol,coin->smartaddr,coin->privkeydepth); if ( coin->inactive == 0 ) LP_listunspent_issue(coin->symbol,coin->smartaddr,0); array = LP_listunspent(coin->symbol,coin->smartaddr); - //printf("unspent array %ld\n",strlen(jprint(array,0))); - LP_address(coin,coin->smartaddr); + printf("unspent array %ld\n",strlen(jprint(array,0))); if ( array != 0 ) { txfee = LP_txfeecalc(coin,0,0); From 5e2655b301b6932595addc3221d54c499862ac71 Mon Sep 17 00:00:00 2001 From: jl777 Date: Sun, 12 Nov 2017 16:47:29 +0200 Subject: [PATCH 0652/1664] Test --- iguana/exchanges/LP_ordermatch.c | 25 ++++++++++++++----------- iguana/exchanges/LP_socket.c | 2 +- 2 files changed, 15 insertions(+), 12 deletions(-) diff --git a/iguana/exchanges/LP_ordermatch.c b/iguana/exchanges/LP_ordermatch.c index f6a947e69..af7f7c5e2 100644 --- a/iguana/exchanges/LP_ordermatch.c +++ b/iguana/exchanges/LP_ordermatch.c @@ -33,7 +33,7 @@ double LP_bob_competition(uint64_t aliceid,double price) if ( price != 0. && (Bob_competition[i].bestprice == 0. || price < Bob_competition[i].bestprice) ) { Bob_competition[i].bestprice = price; - printf("Bob competition aliceid.%llx <- bestprice %.8f\n",(long long)aliceid,price); + //printf("Bob competition aliceid.%llx <- bestprice %.8f\n",(long long)aliceid,price); } return(Bob_competition[i].bestprice); } @@ -44,7 +44,7 @@ double LP_bob_competition(uint64_t aliceid,double price) firsti = (rand() % (sizeof(Bob_competition)/sizeof(*Bob_competition))); Bob_competition[firsti].aliceid = aliceid; Bob_competition[firsti].bestprice = price; - printf("Bob competition aliceid.%llx %.8f\n",(long long)aliceid,price); + //printf("Bob competition aliceid.%llx %.8f\n",(long long)aliceid,price); return(price); } @@ -695,7 +695,7 @@ int32_t LP_tradecommand(void *ctx,char *myipaddr,int32_t pubsock,cJSON *argjson, LP_quoteparse(&Q,argjson); LP_requestinit(&Q.R,Q.srchash,Q.desthash,Q.srccoin,Q.satoshis-Q.txfee,Q.destcoin,Q.destsatoshis-Q.desttxfee,Q.timestamp,Q.quotetime,DEXselector); LP_tradecommand_log(argjson); - printf("LP_tradecommand: check received method %12s aliceid.%16llx %5s/%-5s %12.8f -> %12.8f price %12.8f\n",method,(long long)Q.aliceid,Q.srccoin,Q.destcoin,dstr(Q.satoshis),dstr(Q.destsatoshis),(double)Q.destsatoshis/Q.satoshis); + //printf("LP_tradecommand: check received method %12s aliceid.%16llx %5s/%-5s %12.8f -> %12.8f price %12.8f\n",method,(long long)Q.aliceid,Q.srccoin,Q.destcoin,dstr(Q.satoshis),dstr(Q.destsatoshis),(double)Q.destsatoshis/Q.satoshis); retval = 1; autxo = &A; butxo = &B; @@ -822,13 +822,16 @@ int32_t LP_tradecommand(void *ctx,char *myipaddr,int32_t pubsock,cJSON *argjson, recalc = 1; } } else return(retval); - r = (rand() % 100); - range = (qprice - price); - printf(">>>>>>>>>>>>> price %.8f qprice %.8f r.%d range %.8f -> %.8f vs bestprice %.8f\n",price,qprice,r,range,price + r*range,LP_bob_competition(aliceid,price)); - price += (r * range) / 100.; - bestprice = LP_bob_competition(aliceid,price); - if ( price < bestprice+SMALLVAL ) - return(retval); + if ( qprice > price ) + { + r = (rand() % 100); + range = (qprice - price); + printf(">>>>>>>>>>>>> price %.8f qprice %.8f r.%d range %.8f -> %.8f vs bestprice %.8f\n",price,qprice,r,range,price + r*range,LP_bob_competition(aliceid,price)); + price += (r * range) / 100.; + bestprice = LP_bob_competition(aliceid,price); + if ( price < bestprice+SMALLVAL ) + return(retval); + } else return(retval); //printf("recalc.%d address.(%s/%s) price %.8f request.(%s)\n",recalc,Q.coinaddr,coin->smartaddr,price,jprint(argjson,0)); if ( recalc != 0 ) { @@ -853,7 +856,7 @@ int32_t LP_tradecommand(void *ctx,char *myipaddr,int32_t pubsock,cJSON *argjson, } else { - printf("cant find utxopair\n"); + //printf("cant find utxopair\n"); return(retval); } } diff --git a/iguana/exchanges/LP_socket.c b/iguana/exchanges/LP_socket.c index 5be93ba33..e679ef67f 100644 --- a/iguana/exchanges/LP_socket.c +++ b/iguana/exchanges/LP_socket.c @@ -329,7 +329,7 @@ int32_t electrum_process_array(struct iguana_info *coin,struct electrum_info *ep tx->height = ht; if ( ep != 0 && coin != 0 && tx->SPV == 0 ) { - if ( strcmp(coinaddr,coin->smartaddr) == 0 ) + if ( 0 && strcmp(coinaddr,coin->smartaddr) == 0 ) tx->SPV = LP_merkleproof(coin,coin->smartaddr,ep,txid,tx->height); //printf("%s %s >>>>>>>>>> set %s <- height %d\n",coin->symbol,coinaddr,bits256_str(str,txid),tx->height); } From b420153811bd6bc1c1d71d5fd6fc1d99bd6109c1 Mon Sep 17 00:00:00 2001 From: jl777 Date: Sun, 12 Nov 2017 16:52:02 +0200 Subject: [PATCH 0653/1664] Test --- iguana/exchanges/LP_nativeDEX.c | 1 - iguana/exchanges/LP_utxos.c | 2 +- 2 files changed, 1 insertion(+), 2 deletions(-) diff --git a/iguana/exchanges/LP_nativeDEX.c b/iguana/exchanges/LP_nativeDEX.c index 7fc952235..6383119ff 100644 --- a/iguana/exchanges/LP_nativeDEX.c +++ b/iguana/exchanges/LP_nativeDEX.c @@ -521,7 +521,6 @@ void LP_coinsloop(void *_coins) free_json(retjson); DL_FOREACH_SAFE(ap->utxos,up,tmp) { - break; if ( up->U.height > 0 && up->spendheight < 0 ) { if ( up->SPV == 0 ) diff --git a/iguana/exchanges/LP_utxos.c b/iguana/exchanges/LP_utxos.c index 36612ddaa..2d5a04915 100644 --- a/iguana/exchanges/LP_utxos.c +++ b/iguana/exchanges/LP_utxos.c @@ -554,7 +554,7 @@ int32_t LP_privkey_init(int32_t mypubsock,struct iguana_info *coin,bits256 mypri if ( coin->inactive == 0 ) LP_listunspent_issue(coin->symbol,coin->smartaddr,0); array = LP_listunspent(coin->symbol,coin->smartaddr); - printf("unspent array %ld\n",strlen(jprint(array,0))); + //printf("unspent array %ld\n",strlen(jprint(array,0))); if ( array != 0 ) { txfee = LP_txfeecalc(coin,0,0); From 1d11d9a78f458a20a6e331338c0a0270873cf468 Mon Sep 17 00:00:00 2001 From: jl777 Date: Sun, 12 Nov 2017 16:59:46 +0200 Subject: [PATCH 0654/1664] Test --- iguana/exchanges/LP_tradebots.c | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/iguana/exchanges/LP_tradebots.c b/iguana/exchanges/LP_tradebots.c index 9f7a94b4e..a2e82ac10 100644 --- a/iguana/exchanges/LP_tradebots.c +++ b/iguana/exchanges/LP_tradebots.c @@ -476,13 +476,14 @@ char *LP_tradebot_buy(int32_t dispdir,char *base,char *rel,double maxprice,doubl free(retstr); txfee = LP_txfeecalc(relcoin,0,0); txfees = 10 * txfee; - printf("%s inventory balance %.8f, relvolume %.8f + txfees %.8f\n",rel,dstr(abalance),relvolume,dstr(txfees)); - if ( dstr(abalance) < relvolume + dstr(txfees) ) + if ( relcoin->electrum != 0 ) + balance = LP_unspents_load(relcoin->symbol,relcoin->smartaddr); + else balance = LP_RTsmartbalance(relcoin); + sum = (relvolume+2*dstr(txfees)) + 3 * ((relvolume+2*dstr(txfees))/777); + printf("%s inventory balance %.8f, relvolume %.8f + txfees %.8f, utxobal %.8f sum %.8f\n",rel,dstr(abalance),relvolume,dstr(txfees),dstr(balance),dstr(sum)); + if ( dstr(abalance) < relvolume + dstr(txfees) && balance > sum+txfee ) { retjson = cJSON_CreateObject(); - if ( relcoin->electrum != 0 ) - balance = LP_unspents_load(relcoin->symbol,relcoin->smartaddr); - else balance = LP_RTsmartbalance(relcoin); jaddstr(retjson,"error","not enough funds"); jaddstr(retjson,"coin",rel); jaddnum(retjson,"abalance",dstr(abalance)); @@ -491,7 +492,6 @@ char *LP_tradebot_buy(int32_t dispdir,char *base,char *rel,double maxprice,doubl jaddnum(retjson,"txfees",dstr(txfees)); shortfall = (relvolume + dstr(txfees)) - dstr(balance); jaddnum(retjson,"shortfall",shortfall); - sum = (relvolume+2*dstr(txfees)) + 3 * ((relvolume+2*dstr(txfees))/777); if ( balance >= sum+txfee ) { char *withdrawstr; cJSON *outputjson,*withdrawjson,*outputs,*item; From 7909aed3f146fcd8c3598cf3d6e08062e89a038e Mon Sep 17 00:00:00 2001 From: jl777 Date: Sun, 12 Nov 2017 17:57:24 +0200 Subject: [PATCH 0655/1664] Fix native missed numconfirms --- iguana/exchanges/LP_nativeDEX.c | 4 ++-- iguana/exchanges/LP_ordermatch.c | 2 +- iguana/exchanges/LP_utxo.c | 5 +++++ 3 files changed, 8 insertions(+), 3 deletions(-) diff --git a/iguana/exchanges/LP_nativeDEX.c b/iguana/exchanges/LP_nativeDEX.c index 6383119ff..0bb66c9bf 100644 --- a/iguana/exchanges/LP_nativeDEX.c +++ b/iguana/exchanges/LP_nativeDEX.c @@ -18,9 +18,9 @@ // LP_nativeDEX.c // marketmaker // -// immediate "request", actual auction +// alice waiting for bestprice // previously, it used to show amount, kmd equiv, perc -//there is still a pending one with `-1 wait for bobpayment bYoNxkfvwQ42Yufry8J5y8BYi6mQxokvW9 numconfs.1 MNZ c0ea4aa808a653222a15122d96692fecf734dbbacfb9a54cb4711306ea0c3cef`, but that tx is already spent including 6 confirmation +// there is still a pending one with `-1 wait for bobpayment bYoNxkfvwQ42Yufry8J5y8BYi6mQxokvW9 numconfs.1 MNZ c0ea4aa808a653222a15122d96692fecf734dbbacfb9a54cb4711306ea0c3cef`, but that tx is already spent including 6 confirmation // bot safe to exit? // // BCH signing diff --git a/iguana/exchanges/LP_ordermatch.c b/iguana/exchanges/LP_ordermatch.c index af7f7c5e2..8222443ed 100644 --- a/iguana/exchanges/LP_ordermatch.c +++ b/iguana/exchanges/LP_ordermatch.c @@ -826,7 +826,7 @@ int32_t LP_tradecommand(void *ctx,char *myipaddr,int32_t pubsock,cJSON *argjson, { r = (rand() % 100); range = (qprice - price); - printf(">>>>>>>>>>>>> price %.8f qprice %.8f r.%d range %.8f -> %.8f vs bestprice %.8f\n",price,qprice,r,range,price + r*range,LP_bob_competition(aliceid,price)); + printf(">>>>>>>>>>>>> price %.8f qprice %.8f r.%d range %.8f -> %.8f vs bestprice %.8f\n",price,qprice,r,range,price + (r*range)/100.,LP_bob_competition(aliceid,price)); price += (r * range) / 100.; bestprice = LP_bob_competition(aliceid,price); if ( price < bestprice+SMALLVAL ) diff --git a/iguana/exchanges/LP_utxo.c b/iguana/exchanges/LP_utxo.c index 16ecba91d..54cb5a27d 100644 --- a/iguana/exchanges/LP_utxo.c +++ b/iguana/exchanges/LP_utxo.c @@ -661,6 +661,11 @@ int32_t LP_numconfirms(char *symbol,char *coinaddr,bits256 txid,int32_t vout,int } else if ( mempool != 0 && LP_mempoolscan(symbol,txid) >= 0 ) numconfirms = 0; + else if ( (txobj= LP_gettx(symbol,txid)) != 0 ) + { + numconfirms = jint(txobj,"confirmations"); + free_json(txobj); + } } else { From 4f171163db4444e249e9ca179afef3b4df31b181 Mon Sep 17 00:00:00 2001 From: jl777 Date: Sun, 12 Nov 2017 18:12:43 +0200 Subject: [PATCH 0656/1664] Test --- iguana/exchanges/LP_nativeDEX.c | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-) diff --git a/iguana/exchanges/LP_nativeDEX.c b/iguana/exchanges/LP_nativeDEX.c index 0bb66c9bf..4cad2061d 100644 --- a/iguana/exchanges/LP_nativeDEX.c +++ b/iguana/exchanges/LP_nativeDEX.c @@ -466,7 +466,7 @@ void utxosQ_loop(void *myipaddr) void LP_coinsloop(void *_coins) { - struct LP_address *ap=0; 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 oldht,j,nonz; char *coins = _coins; if ( strcmp("BTC",coins) == 0 ) { strcpy(LP_coinsloopBTC_stats.name,"BTC coin loop"); @@ -514,11 +514,18 @@ void LP_coinsloop(void *_coins) { if ( (backupep= ep->prev) == 0 ) backupep = ep; - //HASH_ITER(hh,coin->addresses,ap,atmp) if ( (ap= LP_addressfind(coin,coin->smartaddr)) != 0 ) { if ( (retjson= electrum_address_listunspent(coin->symbol,ep,&retjson,ap->coinaddr,1)) != 0 ) free_json(retjson); + } + HASH_ITER(hh,coin->addresses,ap,atmp) + { + if ( (retjson= electrum_address_listunspent(coin->symbol,ep,&retjson,ap->coinaddr,1)) != 0 ) + free_json(retjson); + } + HASH_ITER(hh,coin->addresses,ap,atmp) + { DL_FOREACH_SAFE(ap->utxos,up,tmp) { if ( up->U.height > 0 && up->spendheight < 0 ) From 65e276c004560e88fe126928bfcb981fa27fb125 Mon Sep 17 00:00:00 2001 From: jl777 Date: Sun, 12 Nov 2017 18:31:57 +0200 Subject: [PATCH 0657/1664] Test --- iguana/exchanges/LP_nativeDEX.c | 1 + iguana/exchanges/LP_socket.c | 2 +- 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/iguana/exchanges/LP_nativeDEX.c b/iguana/exchanges/LP_nativeDEX.c index 4cad2061d..158d51b48 100644 --- a/iguana/exchanges/LP_nativeDEX.c +++ b/iguana/exchanges/LP_nativeDEX.c @@ -521,6 +521,7 @@ void LP_coinsloop(void *_coins) } HASH_ITER(hh,coin->addresses,ap,atmp) { + printf("call unspent %s\n",ap->coinaddr); if ( (retjson= electrum_address_listunspent(coin->symbol,ep,&retjson,ap->coinaddr,1)) != 0 ) free_json(retjson); } diff --git a/iguana/exchanges/LP_socket.c b/iguana/exchanges/LP_socket.c index e679ef67f..b60f91c34 100644 --- a/iguana/exchanges/LP_socket.c +++ b/iguana/exchanges/LP_socket.c @@ -596,7 +596,7 @@ cJSON *electrum_address_listunspent(char *symbol,struct electrum_info *ep,cJSON { if ( jobj(retjson,"error") == 0 && is_cJSON_Array(retjson) != 0 ) { - if ( 0 && electrumflag > 1 ) + //if ( 0 && electrumflag > 1 ) printf("%s.%d u.%u/%d t.%ld %s LISTUNSPENT.(%d)\n",coin->symbol,height,ap->unspenttime,ap->unspentheight,time(NULL),addr,(int32_t)strlen(jprint(retjson,0))); updatedflag = 0; if ( electrum_process_array(coin,ep,addr,retjson,electrumflag) != 0 ) From 19aec0f9ce34f23d21297504a478b61e5ca95a1b Mon Sep 17 00:00:00 2001 From: jl777 Date: Sun, 12 Nov 2017 18:40:03 +0200 Subject: [PATCH 0658/1664] Test --- iguana/exchanges/LP_utxo.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/iguana/exchanges/LP_utxo.c b/iguana/exchanges/LP_utxo.c index 54cb5a27d..29446521f 100644 --- a/iguana/exchanges/LP_utxo.c +++ b/iguana/exchanges/LP_utxo.c @@ -64,7 +64,10 @@ struct LP_address *_LP_address(struct iguana_info *coin,char *coinaddr) { struct LP_address *ap = 0; if ( (ap= _LP_addressfind(coin,coinaddr)) == 0 ) + { ap = _LP_addressadd(coin,coinaddr); + printf("LP_address %s %s\n",coin->symbol,coinaddr); + } return(ap); } From 026c707045cde6035db7ed4f15cc0b09ebf71d62 Mon Sep 17 00:00:00 2001 From: jl777 Date: Sun, 12 Nov 2017 18:45:41 +0200 Subject: [PATCH 0659/1664] Test --- iguana/exchanges/LP_nativeDEX.c | 1 + 1 file changed, 1 insertion(+) diff --git a/iguana/exchanges/LP_nativeDEX.c b/iguana/exchanges/LP_nativeDEX.c index 158d51b48..972c04374 100644 --- a/iguana/exchanges/LP_nativeDEX.c +++ b/iguana/exchanges/LP_nativeDEX.c @@ -514,6 +514,7 @@ void LP_coinsloop(void *_coins) { if ( (backupep= ep->prev) == 0 ) backupep = ep; + printf("electrum %s\n",coin->symbol); if ( (ap= LP_addressfind(coin,coin->smartaddr)) != 0 ) { if ( (retjson= electrum_address_listunspent(coin->symbol,ep,&retjson,ap->coinaddr,1)) != 0 ) From d085e808602041c28c79afb0718fa275e77568ad Mon Sep 17 00:00:00 2001 From: jl777 Date: Sun, 12 Nov 2017 18:47:31 +0200 Subject: [PATCH 0660/1664] Test --- iguana/exchanges/LP_utxo.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/iguana/exchanges/LP_utxo.c b/iguana/exchanges/LP_utxo.c index 29446521f..33554c05e 100644 --- a/iguana/exchanges/LP_utxo.c +++ b/iguana/exchanges/LP_utxo.c @@ -66,7 +66,7 @@ struct LP_address *_LP_address(struct iguana_info *coin,char *coinaddr) if ( (ap= _LP_addressfind(coin,coinaddr)) == 0 ) { ap = _LP_addressadd(coin,coinaddr); - printf("LP_address %s %s\n",coin->symbol,coinaddr); + //printf("LP_address %s %s\n",coin->symbol,coinaddr); } return(ap); } From 4da0f241b00a141fb48ae0e43f49539eea01080f Mon Sep 17 00:00:00 2001 From: jl777 Date: Sun, 12 Nov 2017 20:35:54 +0200 Subject: [PATCH 0661/1664] Test --- iguana/exchanges/LP_nativeDEX.c | 5 +++-- iguana/exchanges/LP_socket.c | 2 +- 2 files changed, 4 insertions(+), 3 deletions(-) diff --git a/iguana/exchanges/LP_nativeDEX.c b/iguana/exchanges/LP_nativeDEX.c index 972c04374..27ab16469 100644 --- a/iguana/exchanges/LP_nativeDEX.c +++ b/iguana/exchanges/LP_nativeDEX.c @@ -514,7 +514,8 @@ void LP_coinsloop(void *_coins) { if ( (backupep= ep->prev) == 0 ) backupep = ep; - printf("electrum %s\n",coin->symbol); + // skip cLP_address MNZ bXcSsYBiVKtTzYErqxvma4UsojZTEf5L6H + //printf("electrum %s\n",coin->symbol); if ( (ap= LP_addressfind(coin,coin->smartaddr)) != 0 ) { if ( (retjson= electrum_address_listunspent(coin->symbol,ep,&retjson,ap->coinaddr,1)) != 0 ) @@ -522,7 +523,7 @@ void LP_coinsloop(void *_coins) } HASH_ITER(hh,coin->addresses,ap,atmp) { - printf("call unspent %s\n",ap->coinaddr); + //printf("call unspent %s\n",ap->coinaddr); if ( (retjson= electrum_address_listunspent(coin->symbol,ep,&retjson,ap->coinaddr,1)) != 0 ) free_json(retjson); } diff --git a/iguana/exchanges/LP_socket.c b/iguana/exchanges/LP_socket.c index b60f91c34..e679ef67f 100644 --- a/iguana/exchanges/LP_socket.c +++ b/iguana/exchanges/LP_socket.c @@ -596,7 +596,7 @@ cJSON *electrum_address_listunspent(char *symbol,struct electrum_info *ep,cJSON { if ( jobj(retjson,"error") == 0 && is_cJSON_Array(retjson) != 0 ) { - //if ( 0 && electrumflag > 1 ) + if ( 0 && electrumflag > 1 ) printf("%s.%d u.%u/%d t.%ld %s LISTUNSPENT.(%d)\n",coin->symbol,height,ap->unspenttime,ap->unspentheight,time(NULL),addr,(int32_t)strlen(jprint(retjson,0))); updatedflag = 0; if ( electrum_process_array(coin,ep,addr,retjson,electrumflag) != 0 ) From fda20a4b9edafed1e0e5d091851437020e59c12a Mon Sep 17 00:00:00 2001 From: jl777 Date: Sun, 12 Nov 2017 20:37:38 +0200 Subject: [PATCH 0662/1664] Test --- iguana/exchanges/sell | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/iguana/exchanges/sell b/iguana/exchanges/sell index fccc4d61e..a48ffaac1 100755 --- a/iguana/exchanges/sell +++ b/iguana/exchanges/sell @@ -1,3 +1,3 @@ #!/bin/bash source userpass -curl --url "http://127.0.0.1:7783" --data "{\"userpass\":\"$userpass\",\"method\":\"sell\",\"base\":\"KMD\",\"rel\":\"BTC\",\"basevolume\":10.0\",price\":0.0005}" +curl --url "http://127.0.0.1:7783" --data "{\"userpass\":\"$userpass\",\"method\":\"sell\",\"base\":\"KMD\",\"rel\":\"BTC\",\"basevolume\":10.0\",\"price\":0.0005}" From 645351ae44e6c4b5ba80542c6bcf0611e70805d0 Mon Sep 17 00:00:00 2001 From: jl777 Date: Sun, 12 Nov 2017 22:03:01 +0200 Subject: [PATCH 0663/1664] Test --- iguana/exchanges/LP_ordermatch.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/iguana/exchanges/LP_ordermatch.c b/iguana/exchanges/LP_ordermatch.c index 8222443ed..1aa138e33 100644 --- a/iguana/exchanges/LP_ordermatch.c +++ b/iguana/exchanges/LP_ordermatch.c @@ -883,7 +883,7 @@ int32_t LP_tradecommand(void *ctx,char *myipaddr,int32_t pubsock,cJSON *argjson, printf("quote validate error %.0f\n",qprice); return(-3); } - if ( qprice < (price - 0.00000001) * 0.998 ) + if ( qprice < (ask - 0.00000001) * 0.998 ) { printf("(%.8f %.8f) quote price %.8f too low vs %.8f for %s/%s\n",bid,ask,qprice,price,Q.srccoin,Q.destcoin); return(retval); From 59e688208289c6299b43272cadebc698687f7850 Mon Sep 17 00:00:00 2001 From: jl777 Date: Sun, 12 Nov 2017 22:22:19 +0200 Subject: [PATCH 0664/1664] Test --- iguana/exchanges/LP_ordermatch.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/iguana/exchanges/LP_ordermatch.c b/iguana/exchanges/LP_ordermatch.c index 1aa138e33..7bb60dd40 100644 --- a/iguana/exchanges/LP_ordermatch.c +++ b/iguana/exchanges/LP_ordermatch.c @@ -144,7 +144,7 @@ double LP_quote_validate(struct LP_utxoinfo *autxo,struct LP_utxoinfo *butxo,str { if ( LP_iseligible(&destvalue,&destvalue2,0,qp->destcoin,qp->desttxid,qp->destvout,qp->destsatoshis,qp->feetxid,qp->feevout) == 0 ) { - char str[65]; printf("alice not eligible destsatoshis %.8f (%.8f %.8f) %s/v%d\n",dstr(qp->destsatoshis),dstr(destvalue),dstr(destvalue2),bits256_str(str,qp->feetxid),qp->feevout); + char str[65],str2[65]; printf("alice not eligible %.8f -> dest %.8f %.8f (%.8f %.8f) %s/v%d %s/v%d\n",dstr(qp->satoshis),dstr(qp->destsatoshis),(double)qp->destsatoshis/qp->satoshis,dstr(destvalue),dstr(destvalue2),bits256_str(str,qp->desttxid),qp->destvout,bits256_str(str2,qp->feetxid),qp->feevout); return(-3); } if ( (txout= LP_gettxout(qp->destcoin,qp->destaddr,qp->desttxid,qp->destvout)) != 0 ) @@ -885,7 +885,7 @@ int32_t LP_tradecommand(void *ctx,char *myipaddr,int32_t pubsock,cJSON *argjson, } if ( qprice < (ask - 0.00000001) * 0.998 ) { - printf("(%.8f %.8f) quote price %.8f too low vs %.8f for %s/%s\n",bid,ask,qprice,price,Q.srccoin,Q.destcoin); + printf("(%.8f %.8f) quote price %.8f too low vs %.8f for %s/%s %.8f < %.8f\n",bid,ask,qprice,price,Q.srccoin,Q.destcoin,qprice,(ask - 0.00000001) * 0.998); return(retval); } char str[65],str2[65]; printf("butxo.%p (%s %s) TRADECOMMAND.(%s)\n",butxo,butxo!=0?bits256_str(str,butxo->payment.txid):"",butxo!=0?bits256_str(str2,butxo->deposit.txid):"",jprint(argjson,0)); @@ -906,7 +906,7 @@ int32_t LP_tradecommand(void *ctx,char *myipaddr,int32_t pubsock,cJSON *argjson, jaddstr(retjson,"method","reserved"); msg = jprint(retjson,0); butxo->T.lasttime = (uint32_t)time(NULL); - printf("return after queued RESERVED: set swappending.%u accept qprice %.8f, min %.8f\n(%s)\n",butxo->T.swappending,qprice,price,msg); + printf("return after queued RESERVED: set swappending.%u accept qprice %.8f, min %.8f\n(%s)\n",butxo->T.swappending,qprice,ask,msg); // LP_addsig //msg2 = clonestr(msg); LP_reserved_msg(1,Q.srccoin,Q.destcoin,butxo->S.otherpubkey,clonestr(msg)); From d8fad6895fb658b9854e3df122ee4ade6102e70b Mon Sep 17 00:00:00 2001 From: jl777 Date: Sun, 12 Nov 2017 22:23:35 +0200 Subject: [PATCH 0665/1664] Test --- iguana/exchanges/LP_transaction.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/iguana/exchanges/LP_transaction.c b/iguana/exchanges/LP_transaction.c index d9939432d..bc582236c 100644 --- a/iguana/exchanges/LP_transaction.c +++ b/iguana/exchanges/LP_transaction.c @@ -652,7 +652,7 @@ char *basilisk_swap_bobtxspend(bits256 *signedtxidp,uint64_t txfee,char *name,ch satoshis = value - 3*txfee/4; printf("reduce satoshis %.8f by txfee %.8f to value %.8f\n",dstr(satoshis),dstr(txfee),dstr(value)); } - else if ( value == satoshis && (double)txfee/value < 0.1 ) + else if ( value == satoshis && (double)txfee/value < 0.25 ) { satoshis = value - txfee; printf("txfee allocation from value %.8f identical to satoshis: %.8f txfee %.8f\n",dstr(value),dstr(satoshis),dstr(txfee)); From 4dfa34bf9069399e703ec154a47b2476fb5039d0 Mon Sep 17 00:00:00 2001 From: jl777 Date: Sun, 12 Nov 2017 22:53:01 +0200 Subject: [PATCH 0666/1664] Test --- iguana/exchanges/LP_nativeDEX.c | 3 ++- iguana/exchanges/LP_utxo.c | 2 +- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/iguana/exchanges/LP_nativeDEX.c b/iguana/exchanges/LP_nativeDEX.c index 27ab16469..c24f24cd4 100644 --- a/iguana/exchanges/LP_nativeDEX.c +++ b/iguana/exchanges/LP_nativeDEX.c @@ -856,7 +856,8 @@ int32_t LP_reserved_msg(int32_t priority,char *base,char *rel,bits256 pubkey,cha if ( num_Reserved_msgs[priority] > max_Reserved_msgs[priority] ) { max_Reserved_msgs[priority] = num_Reserved_msgs[priority]; - printf("New priority.%d max_Reserved_msgs.%d\n",priority,max_Reserved_msgs[priority]); + if ( (max_Reserved_msgs[priority] % 100) == 0 )) + printf("New priority.%d max_Reserved_msgs.%d\n",priority,max_Reserved_msgs[priority]); } portable_mutex_unlock(&LP_reservedmutex); return(n); diff --git a/iguana/exchanges/LP_utxo.c b/iguana/exchanges/LP_utxo.c index 33554c05e..bfd1103f3 100644 --- a/iguana/exchanges/LP_utxo.c +++ b/iguana/exchanges/LP_utxo.c @@ -856,7 +856,7 @@ int32_t LP_iseligible(uint64_t *valp,uint64_t *val2p,int32_t iambob,char *symbol } return(1); } - } // else printf("no val2\n"); + } else printf("no val2 %.8f < threshold %.8f\n",dstr(val),dstr(threshold)); } /*char str2[65]; if ( val != 0 && val2 != 0 ) From 8140631cdc21af687e87ffe7b1825e4d9703bc5c Mon Sep 17 00:00:00 2001 From: jl777 Date: Sun, 12 Nov 2017 22:55:32 +0200 Subject: [PATCH 0667/1664] Test --- iguana/exchanges/LP_nativeDEX.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/iguana/exchanges/LP_nativeDEX.c b/iguana/exchanges/LP_nativeDEX.c index c24f24cd4..0e427191c 100644 --- a/iguana/exchanges/LP_nativeDEX.c +++ b/iguana/exchanges/LP_nativeDEX.c @@ -856,7 +856,7 @@ int32_t LP_reserved_msg(int32_t priority,char *base,char *rel,bits256 pubkey,cha if ( num_Reserved_msgs[priority] > max_Reserved_msgs[priority] ) { max_Reserved_msgs[priority] = num_Reserved_msgs[priority]; - if ( (max_Reserved_msgs[priority] % 100) == 0 )) + if ( (max_Reserved_msgs[priority] % 100) == 0 ) printf("New priority.%d max_Reserved_msgs.%d\n",priority,max_Reserved_msgs[priority]); } portable_mutex_unlock(&LP_reservedmutex); From f7e2cfb985e70cb36118873af9bdb6ab09073a91 Mon Sep 17 00:00:00 2001 From: jl777 Date: Sun, 12 Nov 2017 23:49:04 +0200 Subject: [PATCH 0668/1664] Test --- iguana/exchanges/LP_nativeDEX.c | 1 + 1 file changed, 1 insertion(+) diff --git a/iguana/exchanges/LP_nativeDEX.c b/iguana/exchanges/LP_nativeDEX.c index 0e427191c..ce4574d09 100644 --- a/iguana/exchanges/LP_nativeDEX.c +++ b/iguana/exchanges/LP_nativeDEX.c @@ -19,6 +19,7 @@ // marketmaker // // alice waiting for bestprice +// regen inventory // previously, it used to show amount, kmd equiv, perc // there is still a pending one with `-1 wait for bobpayment bYoNxkfvwQ42Yufry8J5y8BYi6mQxokvW9 numconfs.1 MNZ c0ea4aa808a653222a15122d96692fecf734dbbacfb9a54cb4711306ea0c3cef`, but that tx is already spent including 6 confirmation // bot safe to exit? From 047df333a036d79c9adb911e4963a045b6cfb2ba Mon Sep 17 00:00:00 2001 From: jl777 Date: Sun, 12 Nov 2017 23:49:39 +0200 Subject: [PATCH 0669/1664] No MUSTFIX --- iguana/exchanges/LP_include.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/iguana/exchanges/LP_include.h b/iguana/exchanges/LP_include.h index 4e3a1e5f2..a46edacae 100644 --- a/iguana/exchanges/LP_include.h +++ b/iguana/exchanges/LP_include.h @@ -23,7 +23,7 @@ #define LP_MAJOR_VERSION "0" #define LP_MINOR_VERSION "1" -#define LP_BUILD_NUMBER "14288" +#define LP_BUILD_NUMBER "14336" #ifdef FROM_JS #include From b1d772b8aa619bd997b8356edaeb30c7b41fb75a Mon Sep 17 00:00:00 2001 From: jl777 Date: Mon, 13 Nov 2017 14:16:09 +0200 Subject: [PATCH 0670/1664] Test --- iguana/exchanges/LP_nativeDEX.c | 1 - iguana/exchanges/LP_swap.c | 6 +++--- 2 files changed, 3 insertions(+), 4 deletions(-) diff --git a/iguana/exchanges/LP_nativeDEX.c b/iguana/exchanges/LP_nativeDEX.c index ce4574d09..6486bfa83 100644 --- a/iguana/exchanges/LP_nativeDEX.c +++ b/iguana/exchanges/LP_nativeDEX.c @@ -21,7 +21,6 @@ // alice waiting for bestprice // regen inventory // previously, it used to show amount, kmd equiv, perc -// there is still a pending one with `-1 wait for bobpayment bYoNxkfvwQ42Yufry8J5y8BYi6mQxokvW9 numconfs.1 MNZ c0ea4aa808a653222a15122d96692fecf734dbbacfb9a54cb4711306ea0c3cef`, but that tx is already spent including 6 confirmation // bot safe to exit? // // BCH signing diff --git a/iguana/exchanges/LP_swap.c b/iguana/exchanges/LP_swap.c index f923ad161..11dba75e7 100644 --- a/iguana/exchanges/LP_swap.c +++ b/iguana/exchanges/LP_swap.c @@ -1121,20 +1121,20 @@ struct basilisk_swap *bitcoin_swapinit(bits256 privkey,uint8_t *pubkey33,bits256 } swap->myfee.I.locktime = swap->I.started + 1; swap->otherfee.I.locktime = swap->I.started + 1; - basilisk_rawtx_setparms("bobdeposit",swap->I.req.quoteid,&swap->bobdeposit,&swap->bobcoin,swap->I.bobconfirms,0,LP_DEPOSITSATOSHIS(swap->I.bobsatoshis) + 0*swap->bobcoin.txfee,4,0,jumblrflag); + basilisk_rawtx_setparms("bobdeposit",swap->I.req.quoteid,&swap->bobdeposit,&swap->bobcoin,swap->I.bobconfirms,0,LP_DEPOSITSATOSHIS(swap->I.bobsatoshis) + swap->bobcoin.txfee,4,0,jumblrflag); basilisk_rawtx_setparms("bobrefund",swap->I.req.quoteid,&swap->bobrefund,&swap->bobcoin,1,4,LP_DEPOSITSATOSHIS(swap->I.bobsatoshis),1,bobpub33,jumblrflag); swap->bobrefund.I.suppress_pubkeys = 1; basilisk_rawtx_setparms("aliceclaim",swap->I.req.quoteid,&swap->aliceclaim,&swap->bobcoin,1,4,LP_DEPOSITSATOSHIS(swap->I.bobsatoshis),1,alicepub33,jumblrflag); swap->aliceclaim.I.suppress_pubkeys = 1; swap->aliceclaim.I.locktime = swap->I.started + swap->I.putduration+swap->I.callduration + 1; - basilisk_rawtx_setparms("bobpayment",swap->I.req.quoteid,&swap->bobpayment,&swap->bobcoin,swap->I.bobconfirms,0,swap->I.bobsatoshis + 0*swap->bobcoin.txfee,3,0,jumblrflag); + basilisk_rawtx_setparms("bobpayment",swap->I.req.quoteid,&swap->bobpayment,&swap->bobcoin,swap->I.bobconfirms,0,swap->I.bobsatoshis + swap->bobcoin.txfee,3,0,jumblrflag); basilisk_rawtx_setparms("alicespend",swap->I.req.quoteid,&swap->alicespend,&swap->bobcoin,swap->I.bobconfirms,3,swap->I.bobsatoshis,1,alicepub33,jumblrflag); swap->alicespend.I.suppress_pubkeys = 1; basilisk_rawtx_setparms("bobreclaim",swap->I.req.quoteid,&swap->bobreclaim,&swap->bobcoin,swap->I.bobconfirms,3,swap->I.bobsatoshis,1,bobpub33,jumblrflag); swap->bobreclaim.I.suppress_pubkeys = 1; swap->bobreclaim.I.locktime = swap->I.started + swap->I.putduration + 1; - basilisk_rawtx_setparms("alicepayment",swap->I.req.quoteid,&swap->alicepayment,&swap->alicecoin,swap->I.aliceconfirms,0,swap->I.alicesatoshis + 0*swap->alicecoin.txfee,2,0,jumblrflag); + basilisk_rawtx_setparms("alicepayment",swap->I.req.quoteid,&swap->alicepayment,&swap->alicecoin,swap->I.aliceconfirms,0,swap->I.alicesatoshis + swap->alicecoin.txfee,2,0,jumblrflag); basilisk_rawtx_setparms("bobspend",swap->I.req.quoteid,&swap->bobspend,&swap->alicecoin,swap->I.aliceconfirms,2,swap->I.alicesatoshis,1,bobpub33,jumblrflag); swap->bobspend.I.suppress_pubkeys = 1; basilisk_rawtx_setparms("alicereclaim",swap->I.req.quoteid,&swap->alicereclaim,&swap->alicecoin,swap->I.aliceconfirms,2,swap->I.alicesatoshis,1,alicepub33,jumblrflag); From 4cd023ccfc1bea17364a8fe3fe80279019de954e Mon Sep 17 00:00:00 2001 From: jl777 Date: Mon, 13 Nov 2017 14:26:08 +0200 Subject: [PATCH 0671/1664] Test --- iguana/exchanges/LP_ordermatch.c | 1 + 1 file changed, 1 insertion(+) diff --git a/iguana/exchanges/LP_ordermatch.c b/iguana/exchanges/LP_ordermatch.c index 7bb60dd40..b04094aa1 100644 --- a/iguana/exchanges/LP_ordermatch.c +++ b/iguana/exchanges/LP_ordermatch.c @@ -852,6 +852,7 @@ int32_t LP_tradecommand(void *ctx,char *myipaddr,int32_t pubsock,cJSON *argjson, Q.txid2 = butxo->deposit.txid; Q.vout2 = butxo->deposit.vout; Q.satoshis = butxo->S.satoshis; + printf("found %.8f -> %.8f newprice %.8f vs ask %.8f += %.8f qprice %.8f\n",dstr(Q.satoshis),dstr(Q.destsatoshis),(double)Q.destsatoshis/Q.satoshis,ask,price,qprice); //printf("set butxo.%p %s/v%d %s/v%d %.8f %.8f -> bsat %.8f asat %.8f\n",butxo,bits256_str(str,butxo->payment.txid),butxo->payment.vout,bits256_str(str2,butxo->deposit.txid),butxo->deposit.vout,dstr(butxo->payment.value),dstr(butxo->deposit.value),dstr(butxo->S.satoshis),dstr(autxo->S.satoshis)); } else From c0672f2658ea17ccad8c0c78336e70143699cca6 Mon Sep 17 00:00:00 2001 From: jl777 Date: Mon, 13 Nov 2017 14:34:15 +0200 Subject: [PATCH 0672/1664] test --- iguana/exchanges/LP_ordermatch.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/iguana/exchanges/LP_ordermatch.c b/iguana/exchanges/LP_ordermatch.c index b04094aa1..bd480c224 100644 --- a/iguana/exchanges/LP_ordermatch.c +++ b/iguana/exchanges/LP_ordermatch.c @@ -842,7 +842,7 @@ int32_t LP_tradecommand(void *ctx,char *myipaddr,int32_t pubsock,cJSON *argjson, return(retval); } 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 ) + if ( (butxo= LP_address_utxopair(1,utxos,max,LP_coinfind(Q.srccoin),Q.coinaddr,2*Q.txfee,dstr(Q.destsatoshis),price,Q.desttxfee)) != 0 ) { strcpy(Q.gui,G.gui); strcpy(Q.coinaddr,coin->smartaddr); From 37349c8e4db7af3b3ce90fad1d3b671b5b9f9665 Mon Sep 17 00:00:00 2001 From: jl777 Date: Mon, 13 Nov 2017 14:38:12 +0200 Subject: [PATCH 0673/1664] Test --- iguana/exchanges/LP_ordermatch.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/iguana/exchanges/LP_ordermatch.c b/iguana/exchanges/LP_ordermatch.c index bd480c224..b04094aa1 100644 --- a/iguana/exchanges/LP_ordermatch.c +++ b/iguana/exchanges/LP_ordermatch.c @@ -842,7 +842,7 @@ int32_t LP_tradecommand(void *ctx,char *myipaddr,int32_t pubsock,cJSON *argjson, return(retval); } LP_listunspent_both(Q.srccoin,Q.coinaddr,0); - if ( (butxo= LP_address_utxopair(1,utxos,max,LP_coinfind(Q.srccoin),Q.coinaddr,2*Q.txfee,dstr(Q.destsatoshis),price,Q.desttxfee)) != 0 ) + if ( (butxo= LP_address_utxopair(1,utxos,max,LP_coinfind(Q.srccoin),Q.coinaddr,Q.txfee,dstr(Q.destsatoshis),price,Q.desttxfee)) != 0 ) { strcpy(Q.gui,G.gui); strcpy(Q.coinaddr,coin->smartaddr); From 2bc60b60ddcb372a5e10890fec91eb575b865ad4 Mon Sep 17 00:00:00 2001 From: jl777 Date: Mon, 13 Nov 2017 14:52:32 +0200 Subject: [PATCH 0674/1664] Test --- iguana/exchanges/LP_include.h | 2 +- iguana/exchanges/LP_ordermatch.c | 10 ++++++++-- 2 files changed, 9 insertions(+), 3 deletions(-) diff --git a/iguana/exchanges/LP_include.h b/iguana/exchanges/LP_include.h index a46edacae..b23ba015f 100644 --- a/iguana/exchanges/LP_include.h +++ b/iguana/exchanges/LP_include.h @@ -43,7 +43,7 @@ void emscripten_usleep(int32_t x); // returns immediate, no sense for sleeping #define LP_MAXVINS 64 #define LP_HTTP_TIMEOUT 3 // 1 is too small due to edge cases of time(NULL) -#define LP_AUTOTRADE_TIMEOUT 40 +#define LP_AUTOTRADE_TIMEOUT 30 #define ELECTRUM_TIMEOUT 7 #define LP_ELECTRUM_KEEPALIVE 60 #define LP_ELECTRUM_MAXERRORS 777 diff --git a/iguana/exchanges/LP_ordermatch.c b/iguana/exchanges/LP_ordermatch.c index b04094aa1..c210ba075 100644 --- a/iguana/exchanges/LP_ordermatch.c +++ b/iguana/exchanges/LP_ordermatch.c @@ -21,15 +21,20 @@ struct LP_quoteinfo LP_Alicequery; double LP_Alicemaxprice; uint32_t Alice_expiration; -struct { uint64_t aliceid; double bestprice; } Bob_competition[512]; +struct { uint64_t aliceid; double bestprice; uint32_t starttime; } Bob_competition[512]; double LP_bob_competition(uint64_t aliceid,double price) { - int32_t i,firsti = -1; + int32_t i,firsti = -1; uint32_t now = (uint32_t)time(NULL); for (i=0; i Bob_competition[i].starttime+LP_AUTOTRADE_TIMEOUT ) + { + printf("aliceid.%llx expired\n",(long long)aliceid); + Bob_competition[i].bestprice = 0.; + } if ( price != 0. && (Bob_competition[i].bestprice == 0. || price < Bob_competition[i].bestprice) ) { Bob_competition[i].bestprice = price; @@ -42,6 +47,7 @@ double LP_bob_competition(uint64_t aliceid,double price) } if ( firsti < 0 ) firsti = (rand() % (sizeof(Bob_competition)/sizeof(*Bob_competition))); + Bob_competition[firsti].starttime = (uint32_t)time(NULL); Bob_competition[firsti].aliceid = aliceid; Bob_competition[firsti].bestprice = price; //printf("Bob competition aliceid.%llx %.8f\n",(long long)aliceid,price); From d2e53f072467989e37bb25dcaa3b72d683de0a55 Mon Sep 17 00:00:00 2001 From: jl777 Date: Mon, 13 Nov 2017 14:59:12 +0200 Subject: [PATCH 0675/1664] Test --- iguana/exchanges/LP_ordermatch.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/iguana/exchanges/LP_ordermatch.c b/iguana/exchanges/LP_ordermatch.c index c210ba075..22f503cd1 100644 --- a/iguana/exchanges/LP_ordermatch.c +++ b/iguana/exchanges/LP_ordermatch.c @@ -832,7 +832,7 @@ int32_t LP_tradecommand(void *ctx,char *myipaddr,int32_t pubsock,cJSON *argjson, { r = (rand() % 100); range = (qprice - price); - printf(">>>>>>>>>>>>> price %.8f qprice %.8f r.%d range %.8f -> %.8f vs bestprice %.8f\n",price,qprice,r,range,price + (r*range)/100.,LP_bob_competition(aliceid,price)); + printf(">>>>>>>>>>>>> price %.8f qprice %.8f r.%d range %.8f -> %.8f\n",price,qprice,r,range,price + (r*range)/100.); price += (r * range) / 100.; bestprice = LP_bob_competition(aliceid,price); if ( price < bestprice+SMALLVAL ) From 5e6710410fc116aa2198d68d20a1b5bc6140e1a6 Mon Sep 17 00:00:00 2001 From: jl777 Date: Mon, 13 Nov 2017 15:02:35 +0200 Subject: [PATCH 0676/1664] Test --- iguana/exchanges/LP_ordermatch.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/iguana/exchanges/LP_ordermatch.c b/iguana/exchanges/LP_ordermatch.c index 22f503cd1..d6b929b84 100644 --- a/iguana/exchanges/LP_ordermatch.c +++ b/iguana/exchanges/LP_ordermatch.c @@ -32,8 +32,9 @@ double LP_bob_competition(uint64_t aliceid,double price) { if ( now > Bob_competition[i].starttime+LP_AUTOTRADE_TIMEOUT ) { - printf("aliceid.%llx expired\n",(long long)aliceid); + //printf("aliceid.%llx expired\n",(long long)aliceid); Bob_competition[i].bestprice = 0.; + Bob_competition[i].starttime = now; } if ( price != 0. && (Bob_competition[i].bestprice == 0. || price < Bob_competition[i].bestprice) ) { From ea468bab7f89b7df42c4e00a6df576495d8abf89 Mon Sep 17 00:00:00 2001 From: jl777 Date: Mon, 13 Nov 2017 15:19:35 +0200 Subject: [PATCH 0677/1664] Test --- iguana/exchanges/LP_include.h | 2 +- iguana/exchanges/LP_ordermatch.c | 21 ++++++++++++++------- iguana/exchanges/LP_socket.c | 2 ++ 3 files changed, 17 insertions(+), 8 deletions(-) diff --git a/iguana/exchanges/LP_include.h b/iguana/exchanges/LP_include.h index b23ba015f..c7eeca62e 100644 --- a/iguana/exchanges/LP_include.h +++ b/iguana/exchanges/LP_include.h @@ -96,7 +96,7 @@ void emscripten_usleep(int32_t x); // returns immediate, no sense for sleeping #define JUMBLR_RMD160 "5177f8b427e5f47342a4b8ab5dac770815d4389e" #define TIERNOLAN_RMD160 "daedddd8dbe7a2439841ced40ba9c3d375f98146" #define INSTANTDEX_BTC "1KRhTPvoxyJmVALwHFXZdeeWFbcJSbkFPu" -#define INSTANTDEX_BTCD "RThtXup6Zo7LZAi8kRWgjAyi1s4u6U9Cpf" +#define INSTANTDEX_KMD "RThtXup6Zo7LZAi8kRWgjAyi1s4u6U9Cpf" //#define BASILISK_DISABLEWAITTX //#define BASILISK_DISABLESENDTX diff --git a/iguana/exchanges/LP_ordermatch.c b/iguana/exchanges/LP_ordermatch.c index d6b929b84..57e8d451b 100644 --- a/iguana/exchanges/LP_ordermatch.c +++ b/iguana/exchanges/LP_ordermatch.c @@ -21,11 +21,12 @@ struct LP_quoteinfo LP_Alicequery; double LP_Alicemaxprice; uint32_t Alice_expiration; -struct { uint64_t aliceid; double bestprice; uint32_t starttime; } Bob_competition[512]; +struct { uint64_t aliceid; double bestprice; uint32_t starttime,counter; } Bob_competition[512]; -double LP_bob_competition(uint64_t aliceid,double price) +double LP_bob_competition(int32_t *counterp,uint64_t aliceid,double price,int32_t counter) { int32_t i,firsti = -1; uint32_t now = (uint32_t)time(NULL); + *counterp = 0; for (i=0; i bestprice %.8f\n",(long long)aliceid,qprice,bestprice); if ( LP_Alicemaxprice == 0. ) return(retval); @@ -744,6 +750,7 @@ int32_t LP_tradecommand(void *ctx,char *myipaddr,int32_t pubsock,cJSON *argjson, } else if ( strcmp(method,"connected") == 0 ) { + bestprice = LP_bob_competition(&counter,aliceid,qprice,1000); if ( bits256_cmp(G.LP_mypub25519,Q.desthash) == 0 && bits256_cmp(G.LP_mypub25519,Q.srchash) != 0 ) { if ( (qprice= LP_quote_validate(autxo,butxo,&Q,0)) <= SMALLVAL ) @@ -833,10 +840,10 @@ int32_t LP_tradecommand(void *ctx,char *myipaddr,int32_t pubsock,cJSON *argjson, { r = (rand() % 100); range = (qprice - price); - printf(">>>>>>>>>>>>> price %.8f qprice %.8f r.%d range %.8f -> %.8f\n",price,qprice,r,range,price + (r*range)/100.); price += (r * range) / 100.; - bestprice = LP_bob_competition(aliceid,price); - if ( price < bestprice+SMALLVAL ) + bestprice = LP_bob_competition(&counter,aliceid,price,0); + printf(">>>>>>>>>>>>> price %.8f qprice %.8f r.%d range %.8f -> %.8f, bestprice %.8f counter.%d\n",ask,qprice,r,range,price,bestprice,counter); + if ( counter > 2 || price > bestprice*1.1 ) return(retval); } else return(retval); //printf("recalc.%d address.(%s/%s) price %.8f request.(%s)\n",recalc,Q.coinaddr,coin->smartaddr,price,jprint(argjson,0)); diff --git a/iguana/exchanges/LP_socket.c b/iguana/exchanges/LP_socket.c index e679ef67f..8d8cbb908 100644 --- a/iguana/exchanges/LP_socket.c +++ b/iguana/exchanges/LP_socket.c @@ -578,6 +578,8 @@ cJSON *electrum_address_listunspent(char *symbol,struct electrum_info *ep,cJSON cJSON *retjson=0; char *retstr; struct LP_address *ap; struct iguana_info *coin; int32_t updatedflag,height,usecache=1; if ( (coin= LP_coinfind(symbol)) == 0 ) return(0); + if ( strcmp(addr,INSTANTDEX_KMD) == 0 ) + return(cJSON_Parse("[]")); if ( ep == 0 || ep->heightp == 0 ) height = coin->longestchain; else height = *(ep->heightp); From 99e6f263dcdf1e130047b1a23e77508f178c7231 Mon Sep 17 00:00:00 2001 From: jl777 Date: Mon, 13 Nov 2017 15:28:01 +0200 Subject: [PATCH 0678/1664] test --- iguana/exchanges/LP_socket.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/iguana/exchanges/LP_socket.c b/iguana/exchanges/LP_socket.c index 8d8cbb908..951e14923 100644 --- a/iguana/exchanges/LP_socket.c +++ b/iguana/exchanges/LP_socket.c @@ -703,7 +703,7 @@ cJSON *_electrum_transaction(char *symbol,struct electrum_info *ep,cJSON **retjs } hexjson = electrum_hasharg(symbol,ep,&hexjson,"blockchain.transaction.get",txid,ELECTRUM_TIMEOUT); hexstr = jprint(hexjson,0); - if ( strlen(hexstr) > 60000 ) + if ( strlen(hexstr) > 100000 ) { static uint32_t counter; if ( counter++ < 3 ) From 5284db6b197faba46e3c3a815492350c94f1ed12 Mon Sep 17 00:00:00 2001 From: jl777 Date: Mon, 13 Nov 2017 17:25:44 +0200 Subject: [PATCH 0679/1664] Test --- iguana/exchanges/LP_coins.c | 2 +- iguana/exchanges/LP_nativeDEX.c | 4 ++++ iguana/exchanges/LP_stats.c | 11 +++++++++-- iguana/exchanges/LP_swap.c | 6 +++--- iguana/exchanges/LP_tradebots.c | 6 +++--- 5 files changed, 20 insertions(+), 9 deletions(-) diff --git a/iguana/exchanges/LP_coins.c b/iguana/exchanges/LP_coins.c index 38c62ac64..7f43a005a 100644 --- a/iguana/exchanges/LP_coins.c +++ b/iguana/exchanges/LP_coins.c @@ -229,7 +229,7 @@ cJSON *LP_coinjson(struct iguana_info *coin,int32_t showwif) jaddnum(item,"pubtype",coin->pubtype); jaddnum(item,"p2shtype",coin->p2shtype); jaddnum(item,"wiftype",coin->wiftype); - jaddnum(item,"txfee",coin->txfee); + jaddnum(item,"txfee",strcmp(coin->symbol,"BTC") != 0 ? coin->txfee : LP_txfeecalc(coin,0,0)); return(item); } diff --git a/iguana/exchanges/LP_nativeDEX.c b/iguana/exchanges/LP_nativeDEX.c index 6486bfa83..c41f82f88 100644 --- a/iguana/exchanges/LP_nativeDEX.c +++ b/iguana/exchanges/LP_nativeDEX.c @@ -666,6 +666,8 @@ void LP_initcoins(void *ctx,int32_t pubsock,cJSON *coins) if ( LP_getheight(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 ) + coin->txfee = LP_MIN_TXFEE; } } if ( (n= cJSON_GetArraySize(coins)) > 0 ) @@ -683,6 +685,8 @@ void LP_initcoins(void *ctx,int32_t pubsock,cJSON *coins) if ( LP_getheight(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 ) + coin->txfee = LP_MIN_TXFEE; } } } diff --git a/iguana/exchanges/LP_stats.c b/iguana/exchanges/LP_stats.c index 1fcea0355..853ce8bd0 100644 --- a/iguana/exchanges/LP_stats.c +++ b/iguana/exchanges/LP_stats.c @@ -34,6 +34,13 @@ int32_t LP_statslog_parsequote(char *method,cJSON *lineobj); char *LP_stats_methods[] = { "unknown", "request", "reserved", "connect", "connected", "tradestatus" }; +uint32_t LP_atomic_locktime(char *base,char *rel) +{ + if ( strcmp(base,"BTC") != 0 && strcmp(rel,"BTC") != 0 ) + return(INSTANTDEX_LOCKTIME); + else return(INSTANTDEX_LOCKTIME * 10); +} + static uint32_t LP_requests,LP_reserveds,LP_connects,LP_connecteds,LP_tradestatuses,LP_parse_errors,LP_unknowns,LP_duplicates,LP_aliceids; void LP_tradecommand_log(cJSON *argjson) @@ -195,7 +202,7 @@ int32_t LP_swapstats_update(struct LP_swapstats *sp,struct LP_quoteinfo *qp,cJSO if ( (sp->finished= juint(lineobj,"timestamp")) == 0 ) sp->finished = (uint32_t)time(NULL); } - if ( sp->finished == 0 && time(NULL) > sp->Q.timestamp+INSTANTDEX_LOCKTIME*2 ) + if ( sp->finished == 0 && time(NULL) > sp->Q.timestamp+LP_atomic_locktime(base,rel)*2 ) sp->expired = (uint32_t)time(NULL); return(0); } @@ -337,7 +344,7 @@ char *LP_statslog_disp(int32_t n,uint32_t starttime,uint32_t endtime,char *refgu array = cJSON_CreateArray(); HASH_ITER(hh,LP_swapstats,sp,tmp) { - if ( sp->finished == 0 && time(NULL) > sp->Q.timestamp+INSTANTDEX_LOCKTIME*2 ) + if ( sp->finished == 0 && time(NULL) > sp->Q.timestamp+LP_atomic_locktime(sp->Q.srccoin,sp->Q.destcoin)*2 ) sp->expired = (uint32_t)time(NULL); dispflag = 0; if ( starttime == 0 && endtime == 0 ) diff --git a/iguana/exchanges/LP_swap.c b/iguana/exchanges/LP_swap.c index 11dba75e7..fb6adf940 100644 --- a/iguana/exchanges/LP_swap.c +++ b/iguana/exchanges/LP_swap.c @@ -801,7 +801,7 @@ void LP_bobloop(void *_swap) basilisk_bobpayment_reclaim(swap,swap->I.callduration); if ( swap->N.pair >= 0 ) nn_close(swap->N.pair), swap->N.pair = -1; - LP_swapwait(swap->I.req.requestid,swap->I.req.quoteid,INSTANTDEX_LOCKTIME*2,30); + LP_swapwait(swap->I.req.requestid,swap->I.req.quoteid,LP_atomic_locktime(swap->bobcoin.symbol,swap->alicecoin.symbol)*2,30); } } } @@ -867,7 +867,7 @@ void LP_aliceloop(void *_swap) }*/ if ( swap->N.pair >= 0 ) nn_close(swap->N.pair), swap->N.pair = -1; - LP_swapwait(swap->I.req.requestid,swap->I.req.quoteid,INSTANTDEX_LOCKTIME*2,30); + LP_swapwait(swap->I.req.requestid,swap->I.req.quoteid,LP_atomic_locktime(swap->bobcoin.symbol,swap->alicecoin.symbol)*2,30); } } } @@ -1009,7 +1009,7 @@ struct basilisk_swap *bitcoin_swapinit(bits256 privkey,uint8_t *pubkey33,bits256 printf("bitcoin_swapinit %s Btxfee %.8f rejected\n",swap->I.req.src,dstr(swap->I.Btxfee)); return(0); } - swap->I.putduration = swap->I.callduration = INSTANTDEX_LOCKTIME; + swap->I.putduration = swap->I.callduration = LP_atomic_locktime(swap->bobcoin.symbol,swap->alicecoin.symbol); if ( optionduration < 0 ) swap->I.putduration -= optionduration; else if ( optionduration > 0 ) diff --git a/iguana/exchanges/LP_tradebots.c b/iguana/exchanges/LP_tradebots.c index a2e82ac10..a0b4406cb 100644 --- a/iguana/exchanges/LP_tradebots.c +++ b/iguana/exchanges/LP_tradebots.c @@ -27,13 +27,13 @@ struct LP_tradebot_trade uint64_t aliceid; int32_t dispdir; uint32_t started,finished,requestid,quoteid,tradeid,expired; - char base[32],rel[32],event[32]; + char base[65],rel[65],event[32]; }; struct LP_tradebot { struct LP_tradebot *next,*prev; - char name[128],base[32],rel[32]; + char name[128],base[65],rel[65]; int32_t numtrades,numpending,completed,dispdir; double maxprice,totalrelvolume,totalbasevolume,basesum,relsum,pendbasesum,pendrelsum; uint32_t lasttime,dead,pause,userpause,started,id; @@ -74,7 +74,7 @@ void LP_tradebot_calcstats(struct LP_tradebot *bot) { if ( (tp= bot->trades[i]) == 0 ) continue; - if ( tp->finished == 0 && time(NULL) > tp->started+INSTANTDEX_LOCKTIME*2 ) + if ( tp->finished == 0 && time(NULL) > tp->started+LP_atomic_locktime(bot->base,bot->rel)*2 ) { tp->expired = tp->finished = (uint32_t)time(NULL); printf("tradeid.%u expired\n",tp->tradeid); From d59aca98d1791190854436185140d23649e2cf22 Mon Sep 17 00:00:00 2001 From: jl777 Date: Mon, 13 Nov 2017 18:51:52 +0200 Subject: [PATCH 0680/1664] Test --- iguana/exchanges/DEXstats.h | 4 ++-- iguana/exchanges/LP_RTmetrics.c | 2 +- iguana/exchanges/LP_include.h | 12 ++++++------ iguana/exchanges/LP_nativeDEX.c | 3 +++ iguana/exchanges/LP_portfolio.c | 8 ++++---- iguana/exchanges/LP_prices.c | 2 +- iguana/exchanges/LP_remember.c | 10 ++++++++++ iguana/exchanges/LP_rpc.c | 2 +- iguana/exchanges/LP_scan.c | 2 +- iguana/exchanges/LP_socket.c | 6 +++--- iguana/exchanges/mm.c | 4 ++-- iguana/exchanges/stats.c | 4 ++-- 12 files changed, 36 insertions(+), 23 deletions(-) diff --git a/iguana/exchanges/DEXstats.h b/iguana/exchanges/DEXstats.h index edf2157cb..dc1f89864 100644 --- a/iguana/exchanges/DEXstats.h +++ b/iguana/exchanges/DEXstats.h @@ -51,7 +51,7 @@ struct DEXstats_pricepoint struct DEXstats_pairinfo { - char dest[16]; + char dest[128]; int32_t numprices; struct DEXstats_pricepoint *prices; }; @@ -64,7 +64,7 @@ struct DEXstats_datenuminfo struct DEXstats_priceinfo { - char symbol[16]; + char symbol[128]; int32_t firstdatenum,numdates; struct DEXstats_datenuminfo *dates; } Prices[1024]; diff --git a/iguana/exchanges/LP_RTmetrics.c b/iguana/exchanges/LP_RTmetrics.c index 54d9300bd..ac01d3025 100644 --- a/iguana/exchanges/LP_RTmetrics.c +++ b/iguana/exchanges/LP_RTmetrics.c @@ -29,7 +29,7 @@ struct LP_metricinfo struct LP_RTmetrics_pendings { - char refbase[16],refrel[16]; + char refbase[65],refrel[65]; int32_t numswaps,numavoidtxids,numwhitelist,numblacklist,numpendings,pending_swaps[1024]; bits256 avoidtxids[8192],whitelist[1024],blacklist[1024],pending_pubkeys[1024]; } LP_RTmetrics; diff --git a/iguana/exchanges/LP_include.h b/iguana/exchanges/LP_include.h index c7eeca62e..a8d31fc40 100644 --- a/iguana/exchanges/LP_include.h +++ b/iguana/exchanges/LP_include.h @@ -166,7 +166,7 @@ struct basilisk_swap; struct basilisk_rawtxinfo { - char destaddr[64],coinstr[16]; + char destaddr[64],coinstr[128]; bits256 txid,signedtxid,actualtxid; int64_t amount,change,inputsum; int32_t redeemlen,datalen,completed,vintype,vouttype,numconfirms,spendlen,secretstart,suppress_pubkeys; @@ -200,7 +200,7 @@ struct basilisk_rawtx struct basilisk_swapinfo { struct basilisk_request req; - char bobstr[64],alicestr[64]; + char bobstr[128],alicestr[128]; bits256 myhash,otherhash,orderhash; uint32_t statebits,otherstatebits,started,expiration,finished,dead,reftime,putduration,callduration; int32_t bobconfirms,aliceconfirms,iambob,reclaimed,bobspent,alicespent,pad,aliceistrusted,bobistrusted,otheristrusted,otherstrust,alicemaxconfirms,bobmaxconfirms; @@ -270,7 +270,7 @@ struct iguana_info 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; uint8_t pubtype,p2shtype,isPoS,wiftype,wiftaddr,taddr,noimportprivkey_flag,userconfirms,isassetchain,maxconfirms; - char symbol[16],smartaddr[64],userpass[1024],serverport[128]; + char symbol[128],smartaddr[64],userpass[1024],serverport[128]; // portfolio double price_kmd,force,perc,goal,goalperc,relvolume,rate; void *electrum; void *ctx; @@ -301,7 +301,7 @@ struct LP_utxoinfo int32_t iambob,iamlp; uint8_t key[sizeof(bits256) + sizeof(int32_t)]; uint8_t key2[sizeof(bits256) + sizeof(int32_t)]; - char coin[16],coinaddr[64],gui[16];//spendscript[256]; + char coin[65],coinaddr[64],gui[16];//spendscript[256]; }; struct LP_address_utxo @@ -340,7 +340,7 @@ struct LP_quoteinfo uint64_t satoshis,txfee,destsatoshis,desttxfee,aliceid; uint32_t timestamp,quotetime,tradeid; int32_t vout,vout2,destvout,feevout,pair; - char srccoin[16],coinaddr[64],destcoin[16],destaddr[64],gui[64]; + char srccoin[65],coinaddr[64],destcoin[65],destaddr[64],gui[64]; }; struct LP_endpoint { int32_t pair; char ipaddr[64]; uint16_t port; }; @@ -384,7 +384,7 @@ struct electrum_info int32_t bufsize,sock,*heightp,numerrors; struct iguana_info *coin; uint32_t stratumid,lasttime,keepalive,pending,*heighttimep; - char ipaddr[64],symbol[16]; + char ipaddr[64],symbol[66]; uint16_t port; uint8_t buf[]; }; diff --git a/iguana/exchanges/LP_nativeDEX.c b/iguana/exchanges/LP_nativeDEX.c index c41f82f88..782fa35ce 100644 --- a/iguana/exchanges/LP_nativeDEX.c +++ b/iguana/exchanges/LP_nativeDEX.c @@ -26,6 +26,9 @@ // BCH signing // dPoW security -> 4: KMD notarized, 5: BTC notarized, after next notary elections // bigendian architectures need to use little endian for sighash calcs +//BTC LP_transaction_fromdata mismatched txid f78c80e831c02c89c0888e7d4438287030238e09e33f88da6df4dc84b949959b vs 1390f386f5997607e646be9c93f30018aa68ea971790b92b7b06e892656f0769 +//failed blockchain.transaction.get BTC f78c80e831c02c89c0888e7d4438287030238e09e33f88da6df4dc84b949959b +//02000000000101242344292f9117c8318adb84f7991239361da2ff0a15ad2106d402945072cc110a0000001716001470eb5212b558cfc10b31f0849ef88ecf17097ac1ffffffff0c4a8321000000000017a914baed1c79cc6325333d5013b44dc17e8256bf5b718704bf3c000000000017a914255cf2809a1f42569c5c47c71e6234aac35a800f873099f400000000001976a914049877b81a8d6d8592919b75b9bcb4182f7c52cd88acb907e200000000001976a9140614fc114940e867210b09cc900db14d8bc58d2b88ac40771b00000000001976a9148cadbb1d7002d22d60e38ca238678d00f04ed22988ac002d3101000000001976a9140d05714431cf478846cea1435f9eabae9ad5c65388acc0f280010000000017a914c17a70c74154fc53263652aaca26c8d71683f1ba87aa2a4e00000000001976a914feea6b867954b1072962083233796d47e4c1665e88ace0e1de02000000001976a91445b71fbb02df53be5563257b77780b9afcc55bdc88acf6fe6700000000001976a91492332f8ff3b26e3ce2666afa5fee2e45308225af88ace74c1500000000001976a914fc7580f1ce24b2c85c80b2c8e641592b9bbf974588ac081ad000000000001976a9145e61c81c9b3ac55bf90ab00240023e8ddaf43e1788ac02483045022100a74be4e00585637c6792eeff9279508f09163db525f8b16c03e57283d12b0a6a022042cc061d70e78e9260ff30635db4f4e0b317831a8cb1f30473a25b93b4d1b4fb01210238288b60e8c50785809a69517ae3ca2fe3e407cac8b5868c5fb3803c233dfbcc00000000 data2json n.219 vs len.586 #include struct LP_millistats diff --git a/iguana/exchanges/LP_portfolio.c b/iguana/exchanges/LP_portfolio.c index 43fd77c89..4004a8c41 100644 --- a/iguana/exchanges/LP_portfolio.c +++ b/iguana/exchanges/LP_portfolio.c @@ -18,7 +18,7 @@ // marketmaker // -char LP_portfolio_base[16],LP_portfolio_rel[16]; +char LP_portfolio_base[128],LP_portfolio_rel[128]; double LP_portfolio_relvolume; cJSON *LP_portfolio_entry(struct iguana_info *coin) @@ -203,7 +203,7 @@ int32_t LP_autoprices,num_LP_autorefs; struct LP_autoprice_ref { - char refbase[16],refrel[16],base[16],rel[16]; + char refbase[65],refrel[65],base[65],rel[65]; } LP_autorefs[100]; /*int32_t LP_autofill(char *base,char *rel,double maxprice,double totalrelvolume) @@ -325,7 +325,7 @@ double LP_pricesparse(void *ctx,int32_t trexflag,char *retstr,struct LP_priceinf { //{"success":true,"message":"","result":[{"MarketName":"BTC-KMD","High":0.00040840,"Low":0.00034900,"Volume":328042.46061669,"Last":0.00037236,"BaseVolume":123.36439511,"TimeStamp":"2017-07-15T13:50:21.87","Bid":0.00035721,"Ask":0.00037069,"OpenBuyOrders":343,"OpenSellOrders":1690,"PrevDay":0.00040875,"Created":"2017-02-11T23:04:01.853"}, //{"TradePairId":4762,"Label":"WAVES/BTC","AskPrice":0.00099989,"BidPrice":0.00097350,"Low":0.00095000,"High":0.00108838,"Volume":6501.24403100,"LastPrice":0.00098028,"BuyVolume":1058994.86554882,"SellVolume":2067.87377158,"Change":-7.46,"Open":0.00105926,"Close":0.00098028,"BaseVolume":6.52057452,"BuyBaseVolume":2.33098660,"SellBaseVolume":1167.77655709}, - int32_t i,j,n,iter; double price,kmdbtc,bid,ask,nxtkmd=0.; struct LP_priceinfo *coinpp,*refpp; char symbol[16],*name,*refcoin; cJSON *retjson,*array,*item; + int32_t i,j,n,iter; double price,kmdbtc,bid,ask,nxtkmd=0.; struct LP_priceinfo *coinpp,*refpp; char symbol[65],*name,*refcoin; cJSON *retjson,*array,*item; if ( (retjson= cJSON_Parse(retstr)) != 0 ) { //printf("got.(%s)\n",retstr); @@ -553,7 +553,7 @@ int32_t LP_portfolio_trade(void *ctx,uint32_t *requestidp,uint32_t *quoteidp,str else return(-1); } -struct LP_portfoliotrade { double metric; char buycoin[16],sellcoin[16]; }; +struct LP_portfoliotrade { double metric; char buycoin[65],sellcoin[65]; }; int32_t LP_portfolio_order(struct LP_portfoliotrade *trades,int32_t max,cJSON *array) { diff --git a/iguana/exchanges/LP_prices.c b/iguana/exchanges/LP_prices.c index 66bb2fdc3..7313c733b 100644 --- a/iguana/exchanges/LP_prices.c +++ b/iguana/exchanges/LP_prices.c @@ -22,7 +22,7 @@ struct LP_orderbookentry { bits256 pubkey; double price; uint64_t minsatoshis,ma struct LP_priceinfo { - char symbol[16]; + char symbol[68]; uint64_t coinbits; int32_t ind,pad; double diagval,high[2],low[2],last[2],bid[2],ask[2]; //volume,btcvolume,prevday; // mostly bittrex info diff --git a/iguana/exchanges/LP_remember.c b/iguana/exchanges/LP_remember.c index 44d93a71a..2180a498c 100644 --- a/iguana/exchanges/LP_remember.c +++ b/iguana/exchanges/LP_remember.c @@ -94,6 +94,10 @@ void basilisk_dontforget(struct basilisk_swap *swap,struct basilisk_rawtx *rawtx if ( (fp= fopen(fname,"wb")) != 0 ) { fprintf(fp,"{\"tradeid\":%u,\"aliceid\":\"%llu\",\"src\":\"%s\",\"srcamount\":%.8f,\"dest\":\"%s\",\"destamount\":%.8f,\"requestid\":%u,\"quoteid\":%u,\"iambob\":%d,\"state\":%u,\"otherstate\":%u,\"expiration\":%u,\"dlocktime\":%u,\"plocktime\":%u,\"Atxfee\":%llu,\"Btxfee\":%llu",swap->tradeid,(long long)swap->aliceid,swap->I.req.src,dstr(swap->I.req.srcamount),swap->I.req.dest,dstr(swap->I.req.destamount),swap->I.req.requestid,swap->I.req.quoteid,swap->I.iambob,swap->I.statebits,swap->I.otherstatebits,swap->I.expiration,swap->bobdeposit.I.locktime,swap->bobpayment.I.locktime,(long long)swap->I.Atxfee,(long long)swap->I.Btxfee); + if ( swap->I.iambob == 0 ) + fprintf(fp,",\"Agui\":\"%s\"",G.gui); + else fprintf(fp,",\"Bgui\":\"%s\"",G.gui); + fprintf(fp,",\"gui\":\"%s\"",G.gui); if ( memcmp(zeroes,swap->I.secretAm,20) != 0 ) { init_hexbytes_noT(secretAmstr,swap->I.secretAm,20); @@ -455,6 +459,9 @@ cJSON *LP_swap_json(struct LP_swap_remember *rswap) jaddnum(item,"requestid",rswap->requestid); jaddnum(item,"quoteid",rswap->quoteid); jaddnum(item,"iambob",rswap->iambob); + jaddstr(item,"Bgui",rswap->Bgui); + jaddstr(item,"Agui",rswap->Agui); + jaddstr(item,"gui",rswap->gui); jaddstr(item,"bob",rswap->src); jaddnum(item,"srcamount",dstr(rswap->srcamount)); jaddnum(item,"bobtxfee",dstr(rswap->Btxfee)); @@ -503,6 +510,9 @@ int32_t LP_rswap_init(struct LP_swap_remember *rswap,uint32_t requestid,uint32_t if ( (item= cJSON_Parse(fstr)) != 0 ) { rswap->iambob = jint(item,"iambob"); + safecopy(rswap->Bgui,jstr(item,"Bgui"),sizeof(rswap->Bgui)); + safecopy(rswap->Agui,jstr(item,"Agui"),sizeof(rswap->Agui)); + safecopy(rswap->gui,jstr(item,"gui"),sizeof(rswap->gui)); rswap->tradeid = juint(item,"tradeid"); rswap->aliceid = j64bits(item,"aliceid"); if ( (secretstr= jstr(item,"secretAm")) != 0 && strlen(secretstr) == 40 ) diff --git a/iguana/exchanges/LP_rpc.c b/iguana/exchanges/LP_rpc.c index 1d952ff6d..30789efe7 100644 --- a/iguana/exchanges/LP_rpc.c +++ b/iguana/exchanges/LP_rpc.c @@ -208,7 +208,7 @@ cJSON *LP_NXT_decrypt(uint64_t txnum,char *account,char *data,char *nonce,char * cJSON *LP_NXT_redeems() { - char url[1024],*retstr,*recv,*method,*msgstr,assetname[16]; uint64_t totals[20],mult,txnum,assetid,qty; int32_t i,ind,numtx,past_marker=0; cJSON *item,*attach,*decjson,*array,*msgjson,*encjson,*retjson=0; + char url[1024],*retstr,*recv,*method,*msgstr,assetname[128]; uint64_t totals[20],mult,txnum,assetid,qty; int32_t i,ind,numtx,past_marker=0; cJSON *item,*attach,*decjson,*array,*msgjson,*encjson,*retjson=0; uint64_t txnum_marker = calc_nxt64bits("0"); uint64_t txnum_marker2 = calc_nxt64bits("7256847492742571143"); char *passphrase = ""; diff --git a/iguana/exchanges/LP_scan.c b/iguana/exchanges/LP_scan.c index a8c33fc28..5a5a12051 100644 --- a/iguana/exchanges/LP_scan.c +++ b/iguana/exchanges/LP_scan.c @@ -127,7 +127,7 @@ int sort_balance(void *a,void *b) cJSON *LP_snapshot(struct iguana_info *coin,int32_t height) { - static bits256 bannedarray[64]; static int32_t numbanned,indallvouts,maxsnapht; static char lastcoin[16]; + static bits256 bannedarray[64]; static int32_t numbanned,indallvouts,maxsnapht; static char lastcoin[65]; struct LP_transaction *tx,*tmp; struct LP_address *ap,*atmp; int32_t isKMD,i,j,n,skipflag=0,startht,endht,ht; uint64_t banned_balance=0,balance=0,noaddr_balance=0; cJSON *retjson,*array,*item; if ( bannedarray[0].txid == 0 ) numbanned = komodo_bannedset(&indallvouts,bannedarray,(int32_t)(sizeof(bannedarray)/sizeof(*bannedarray))); diff --git a/iguana/exchanges/LP_socket.c b/iguana/exchanges/LP_socket.c index 951e14923..96855e6d7 100644 --- a/iguana/exchanges/LP_socket.c +++ b/iguana/exchanges/LP_socket.c @@ -98,7 +98,7 @@ int32_t LP_socket(int32_t bindflag,char *hostname,uint16_t port) #endif expand_ipbits(checkipaddr,saddr.sin_addr.s_addr); if ( strcmp(ipaddr,checkipaddr) != 0 ) - printf("bindflag.%d iguana_socket mismatch (%s) -> (%s)?\n",bindflag,checkipaddr,ipaddr); + printf("bindflag.%d iguana_socket mismatch (%s) -> (%s)\n",bindflag,checkipaddr,ipaddr); //#endif if ( (sock= socket(AF_INET,SOCK_STREAM,0)) < 0 ) { @@ -578,8 +578,8 @@ cJSON *electrum_address_listunspent(char *symbol,struct electrum_info *ep,cJSON cJSON *retjson=0; char *retstr; struct LP_address *ap; struct iguana_info *coin; int32_t updatedflag,height,usecache=1; if ( (coin= LP_coinfind(symbol)) == 0 ) return(0); - if ( strcmp(addr,INSTANTDEX_KMD) == 0 ) - return(cJSON_Parse("[]")); + //if ( strcmp(addr,INSTANTDEX_KMD) == 0 ) + // return(cJSON_Parse("[]")); if ( ep == 0 || ep->heightp == 0 ) height = coin->longestchain; else height = *(ep->heightp); diff --git a/iguana/exchanges/mm.c b/iguana/exchanges/mm.c index 12c8f1496..1d2a1bd5e 100644 --- a/iguana/exchanges/mm.c +++ b/iguana/exchanges/mm.c @@ -74,7 +74,7 @@ struct mmpending_order int32_t dir; uint32_t pending,completed,canceled,cancelstarted,reported; cJSON *errorjson; - char exchange[16],base[16],rel[16],orderid[64]; + char exchange[16],base[65],rel[65],orderid[64]; } *Pending_orders; int32_t Num_Pending; @@ -415,7 +415,7 @@ void marketmaker_pendingupdate(char *exchange,char *base,char *rel) void marketmaker_pendinginit(char *exchange,char *base,char *rel) { - char *retstr,*orderid,*pairstr,relbase[64]; cJSON *retjson,*array,*item; int32_t i,j,n,dir; struct mmpending_order *ptr; + char *retstr,*orderid,*pairstr,relbase[65]; cJSON *retjson,*array,*item; int32_t i,j,n,dir; struct mmpending_order *ptr; sprintf(relbase,"%s-%s",rel,base); if ( (retstr= DEX_openorders(exchange)) != 0 ) { diff --git a/iguana/exchanges/stats.c b/iguana/exchanges/stats.c index 6453b85d5..d283b1301 100644 --- a/iguana/exchanges/stats.c +++ b/iguana/exchanges/stats.c @@ -62,7 +62,7 @@ char CURRENCIES[][8] = { "USD", "EUR", "JPY", "GBP", "AUD", "CAD", "CHF", "NZD", "CNY", "RUB", "MXN", "BRL", "INR", "HKD", "TRY", "ZAR", "PLN", "NOK", "SEK", "DKK", "CZK", "HUF", "ILS", "KRW", "MYR", "PHP", "RON", "SGD", "THB", "BGN", "IDR", "HRK", // end of currencies }; -char ASSETCHAINS_SYMBOL[16] = { "KV" }; +char ASSETCHAINS_SYMBOL[65] = { "KV" }; struct komodo_state { @@ -1090,7 +1090,7 @@ int32_t komodo_parsestatefile(FILE *logfp,struct komodo_state *sp,FILE *fp,char int32_t stats_stateupdate(FILE *logfp,char *destdir,char *statefname,int32_t maxseconds,char *komodofile) { static long lastpos[2]; - char symbol[64],base[64]; int32_t iter,n; FILE *fp; uint32_t starttime; struct komodo_state *sp; + char symbol[65],base[65]; int32_t iter,n; FILE *fp; uint32_t starttime; struct komodo_state *sp; starttime = (uint32_t)time(NULL); strcpy(base,"KV"); strcpy(symbol,"KV"); From 987e52e408abefeebe6d8834e7380f60e82b80f4 Mon Sep 17 00:00:00 2001 From: jl777 Date: Mon, 13 Nov 2017 19:07:25 +0200 Subject: [PATCH 0681/1664] Test --- iguana/exchanges/LP_cache.c | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/iguana/exchanges/LP_cache.c b/iguana/exchanges/LP_cache.c index 95fbe6f99..65140dc2c 100644 --- a/iguana/exchanges/LP_cache.c +++ b/iguana/exchanges/LP_cache.c @@ -247,7 +247,7 @@ int32_t LP_merkleproof(struct iguana_info *coin,char *coinaddr,struct electrum_i if ( (merkobj= electrum_getmerkle(coin->symbol,ep,&merkobj,txid,height)) != 0 ) { char str[65],str2[65],str3[65]; - SPV = -1; + SPV = 0; memset(roothash.bytes,0,sizeof(roothash)); if ( (merkles= jarray(&m,merkobj,"merkle")) != 0 ) { @@ -271,7 +271,11 @@ int32_t LP_merkleproof(struct iguana_info *coin,char *coinaddr,struct electrum_i } //printf("validated MERK %s ht.%d -> %s root.(%s)\n",bits256_str(str,txid),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)); + else + { + SPV = -1; + 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)); + } } else SPV = 0; } if ( SPV < 0 ) From 7b451b5cb16284bb5672dc6f03bf354cabf01e7b Mon Sep 17 00:00:00 2001 From: jl777 Date: Mon, 13 Nov 2017 19:11:01 +0200 Subject: [PATCH 0682/1664] Test --- iguana/exchanges/LP_include.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/iguana/exchanges/LP_include.h b/iguana/exchanges/LP_include.h index a8d31fc40..cda3f0348 100644 --- a/iguana/exchanges/LP_include.h +++ b/iguana/exchanges/LP_include.h @@ -180,7 +180,7 @@ struct basilisk_request int64_t srcamount,unused; // 16 to 31 bits256 srchash; // 32 to 63 bits256 desthash; - char src[8],dest[8]; + char src[65],dest[65]; uint64_t destamount; int32_t optionhours,DEXselector; }; @@ -241,7 +241,7 @@ struct LP_swap_remember uint32_t finishtime,tradeid,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],Sdestaddr[64],alicepaymentaddr[64],bobpaymentaddr[64],bobdepositaddr[64],alicecoin[64],bobcoin[64],*txbytes[sizeof(txnames)/sizeof(*txnames)]; + char Agui[65],Bgui[65],gui[65],src[65],dest[65],destaddr[64],Adestaddr[64],Sdestaddr[64],alicepaymentaddr[64],bobpaymentaddr[64],bobdepositaddr[64],alicecoin[65],bobcoin[65],*txbytes[sizeof(txnames)/sizeof(*txnames)]; }; struct LP_outpoint From 34bd4fab06ebe8747e0f929fdc42b41042099180 Mon Sep 17 00:00:00 2001 From: jl777 Date: Mon, 13 Nov 2017 19:47:27 +0200 Subject: [PATCH 0683/1664] Test --- iguana/exchanges/LP_bitcoin.c | 9 +++++++++ iguana/exchanges/LP_nativeDEX.c | 10 ++++++++++ iguana/exchanges/LP_tradebots.c | 2 +- 3 files changed, 20 insertions(+), 1 deletion(-) diff --git a/iguana/exchanges/LP_bitcoin.c b/iguana/exchanges/LP_bitcoin.c index 0eef539d1..cd70c13d4 100644 --- a/iguana/exchanges/LP_bitcoin.c +++ b/iguana/exchanges/LP_bitcoin.c @@ -3328,6 +3328,15 @@ int32_t iguana_rwjoinsplit(int32_t rwflag,uint8_t *serialized,struct iguana_msgj return(len); } +/* + normal: nVersion|txins|txouts|nLockTime. + segwit + nVersion|marker|flag|txins|txouts|witness|nLockTime +Format of nVersion, txins, txouts, and nLockTime are same as the original format +The marker MUST be 0x00 +The flag MUST be 0x01 +*/ + int32_t iguana_rwmsgtx(uint8_t taddr,uint8_t pubtype,uint8_t p2shtype,uint8_t isPoS,int32_t height,int32_t rwflag,cJSON *json,uint8_t *serialized,int32_t maxsize,struct iguana_msgtx *msg,bits256 *txidp,char *vpnstr,uint8_t *extraspace,int32_t extralen,cJSON *vins,int32_t suppress_pubkeys,int32_t zcash) { int32_t i,n,len = 0,extraused=0; uint8_t spendscript[IGUANA_MAXSCRIPTSIZE],*txstart = serialized,*sigser=0; char txidstr[65]; cJSON *vinarray=0,*voutarray=0; bits256 sigtxid; diff --git a/iguana/exchanges/LP_nativeDEX.c b/iguana/exchanges/LP_nativeDEX.c index 782fa35ce..05ce41c36 100644 --- a/iguana/exchanges/LP_nativeDEX.c +++ b/iguana/exchanges/LP_nativeDEX.c @@ -30,6 +30,16 @@ //failed blockchain.transaction.get BTC f78c80e831c02c89c0888e7d4438287030238e09e33f88da6df4dc84b949959b //02000000000101242344292f9117c8318adb84f7991239361da2ff0a15ad2106d402945072cc110a0000001716001470eb5212b558cfc10b31f0849ef88ecf17097ac1ffffffff0c4a8321000000000017a914baed1c79cc6325333d5013b44dc17e8256bf5b718704bf3c000000000017a914255cf2809a1f42569c5c47c71e6234aac35a800f873099f400000000001976a914049877b81a8d6d8592919b75b9bcb4182f7c52cd88acb907e200000000001976a9140614fc114940e867210b09cc900db14d8bc58d2b88ac40771b00000000001976a9148cadbb1d7002d22d60e38ca238678d00f04ed22988ac002d3101000000001976a9140d05714431cf478846cea1435f9eabae9ad5c65388acc0f280010000000017a914c17a70c74154fc53263652aaca26c8d71683f1ba87aa2a4e00000000001976a914feea6b867954b1072962083233796d47e4c1665e88ace0e1de02000000001976a91445b71fbb02df53be5563257b77780b9afcc55bdc88acf6fe6700000000001976a91492332f8ff3b26e3ce2666afa5fee2e45308225af88ace74c1500000000001976a914fc7580f1ce24b2c85c80b2c8e641592b9bbf974588ac081ad000000000001976a9145e61c81c9b3ac55bf90ab00240023e8ddaf43e1788ac02483045022100a74be4e00585637c6792eeff9279508f09163db525f8b16c03e57283d12b0a6a022042cc061d70e78e9260ff30635db4f4e0b317831a8cb1f30473a25b93b4d1b4fb01210238288b60e8c50785809a69517ae3ca2fe3e407cac8b5868c5fb3803c233dfbcc00000000 data2json n.219 vs len.586 + +//BTC LP_transaction_fromdata mismatched txid ae7af65215554964b7af01babb58fce10fc51d9812ced07ee4a62a1ffe10c0bb vs 051ef4f75898b511dd3aebd687d5a5bdb004226d811aaf13e64be741dbe81ff2 +//failed blockchain.transaction.get BTC ae7af65215554964b7af01babb58fce10fc51d9812ced07ee4a62a1ffe10c0bb +//errortxobj.({"version":1}) +//010000000001010c590740b0c558f75b64cc0d00b0533ff951e403d993b866a87c7c52981388a60300000017160014cd2b7646f9931c85bb9d4d353b652c76b40aff84ffffffff0240420f000000000017a914239ae54cd403a91b084d3244e7e423f05c25ec268728fe28010000000017a914b96e21dd6e11bb67479f9072df55881e7fb17f788702473044022076e4c1cfba0dab889598efdfdcbc7a1046cc0eecfb8fec379994d559143d271c02206b16d9a0e3c425434d1b793d61e1e491f269abc7e7d3af52d95f6a26c1c2aa0d0121037f88a6ccdd608645024b05f408324550cf6fa1c74e3d7c1f94a1e9b57369d10600000000 data2json n.-1 vs len.247 + + +//ScriptSig: PUSHDATA(34)[002072d8f7debd607b94c95ced6cff38265ed99c7c1ee58b67d0a3f3ed43b6d9a977] +//Witness: 040047304402206f23bb2dd06bc70d78312e27d53954420d0defbda7ad638718b9dc2c1efb93100220270f79bfb3230194d2e625875073799f6f07d96d5bce43b19cfe6be9957d95540148304502210081842f5987009e65f1d7de6140433da541b9da52ed211e87e1ae6fc25260d7680220798de97c682541d7b26b0795b19994f045f3ef4f433c55da0b5f1506ddeec413014752210305345798069ac85285628732485a3ce7e96b85696ed7da72287f6eae3b275363210268aace9c841b8d61fe3532981c8b25e235690003916c5a90c23a708e5d8f929752ae + #include struct LP_millistats { diff --git a/iguana/exchanges/LP_tradebots.c b/iguana/exchanges/LP_tradebots.c index a0b4406cb..1f6fa7c48 100644 --- a/iguana/exchanges/LP_tradebots.c +++ b/iguana/exchanges/LP_tradebots.c @@ -481,7 +481,7 @@ char *LP_tradebot_buy(int32_t dispdir,char *base,char *rel,double maxprice,doubl else balance = LP_RTsmartbalance(relcoin); sum = (relvolume+2*dstr(txfees)) + 3 * ((relvolume+2*dstr(txfees))/777); printf("%s inventory balance %.8f, relvolume %.8f + txfees %.8f, utxobal %.8f sum %.8f\n",rel,dstr(abalance),relvolume,dstr(txfees),dstr(balance),dstr(sum)); - if ( dstr(abalance) < relvolume + dstr(txfees) && balance > sum+txfee ) + if ( dstr(abalance) < relvolume && balance > sum+txfee ) { retjson = cJSON_CreateObject(); jaddstr(retjson,"error","not enough funds"); From 989bffe20a0b7d7e10520db1cedfce86edb42d4c Mon Sep 17 00:00:00 2001 From: jl777 Date: Mon, 13 Nov 2017 20:38:14 +0200 Subject: [PATCH 0684/1664] Test --- iguana/exchanges/LP_bitcoin.c | 28 ++++++++++++++++++---------- iguana/exchanges/LP_ordermatch.c | 24 +++++++++++++++++------- 2 files changed, 35 insertions(+), 17 deletions(-) diff --git a/iguana/exchanges/LP_bitcoin.c b/iguana/exchanges/LP_bitcoin.c index cd70c13d4..4106f0399 100644 --- a/iguana/exchanges/LP_bitcoin.c +++ b/iguana/exchanges/LP_bitcoin.c @@ -3328,18 +3328,9 @@ int32_t iguana_rwjoinsplit(int32_t rwflag,uint8_t *serialized,struct iguana_msgj return(len); } -/* - normal: nVersion|txins|txouts|nLockTime. - segwit - nVersion|marker|flag|txins|txouts|witness|nLockTime -Format of nVersion, txins, txouts, and nLockTime are same as the original format -The marker MUST be 0x00 -The flag MUST be 0x01 -*/ - int32_t iguana_rwmsgtx(uint8_t taddr,uint8_t pubtype,uint8_t p2shtype,uint8_t isPoS,int32_t height,int32_t rwflag,cJSON *json,uint8_t *serialized,int32_t maxsize,struct iguana_msgtx *msg,bits256 *txidp,char *vpnstr,uint8_t *extraspace,int32_t extralen,cJSON *vins,int32_t suppress_pubkeys,int32_t zcash) { - int32_t i,n,len = 0,extraused=0; uint8_t spendscript[IGUANA_MAXSCRIPTSIZE],*txstart = serialized,*sigser=0; char txidstr[65]; cJSON *vinarray=0,*voutarray=0; bits256 sigtxid; + int32_t i,n,len = 0,extraused=0; uint8_t segwitflag=0,spendscript[IGUANA_MAXSCRIPTSIZE],*txstart = serialized,*sigser=0; char txidstr[65]; cJSON *vinarray=0,*voutarray=0; bits256 sigtxid; len += iguana_rwnum(rwflag,&serialized[len],sizeof(msg->version),&msg->version); if ( json != 0 ) @@ -3359,6 +3350,19 @@ int32_t iguana_rwmsgtx(uint8_t taddr,uint8_t pubtype,uint8_t p2shtype,uint8_t is if ( json != 0 ) jaddnum(json,"timestamp",msg->timestamp); } + if ( rwflag == 0 ) + { + /* + normal: nVersion|txins|txouts|nLockTime. + segwit + nVersion|marker|flag|txins|txouts|witness|nLockTime + Format of nVersion, txins, txouts, and nLockTime are same as the original format + The marker MUST be 0x00 + The flag MUST be 0x01 + */ + if ( serialized[len] == 0x00 && (segwitflag= serialized[len+1]) == 0x01 ) + len += 2; + } len += iguana_rwvarint32(rwflag,&serialized[len],&msg->tx_in); if ( rwflag == 0 ) { @@ -3425,6 +3429,10 @@ int32_t iguana_rwmsgtx(uint8_t taddr,uint8_t pubtype,uint8_t p2shtype,uint8_t is } if ( voutarray != 0 ) jaddi(voutarray,iguana_voutjson(taddr,pubtype,p2shtype,&msg->vouts[i],i,*txidp)); + } + if ( segwitflag != 0 ) + { + } len += iguana_rwnum(rwflag,&serialized[len],sizeof(msg->lock_time),&msg->lock_time); //printf("lock_time.%08x len.%d\n",msg->lock_time,len); diff --git a/iguana/exchanges/LP_ordermatch.c b/iguana/exchanges/LP_ordermatch.c index 57e8d451b..5a9b2031b 100644 --- a/iguana/exchanges/LP_ordermatch.c +++ b/iguana/exchanges/LP_ordermatch.c @@ -20,6 +20,7 @@ // struct LP_quoteinfo LP_Alicequery; double LP_Alicemaxprice; +bits256 LP_Alicedestpubkey; uint32_t Alice_expiration; struct { uint64_t aliceid; double bestprice; uint32_t starttime,counter; } Bob_competition[512]; @@ -455,7 +456,7 @@ int32_t LP_connectstartbob(void *ctx,int32_t pubsock,struct LP_utxoinfo *utxo,cJ return(retval); } -char *LP_trade(void *ctx,char *myipaddr,int32_t mypubsock,struct LP_quoteinfo *qp,double maxprice,int32_t timeout,int32_t duration,uint32_t tradeid) +char *LP_trade(void *ctx,char *myipaddr,int32_t mypubsock,struct LP_quoteinfo *qp,double maxprice,int32_t timeout,int32_t duration,uint32_t tradeid,bits256 destpubkey) { 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 ) @@ -469,14 +470,16 @@ char *LP_trade(void *ctx,char *myipaddr,int32_t mypubsock,struct LP_quoteinfo *q qp->aliceid = LP_aliceid_calc(qp->desttxid,qp->destvout,qp->feetxid,qp->feevout); qp->tradeid = tradeid; LP_query(ctx,myipaddr,mypubsock,"request",qp); - LP_Alicequery = *qp, LP_Alicemaxprice = maxprice, Alice_expiration = qp->timestamp + timeout; - printf("LP_trade %s/%s %.8f vol %.8f\n",qp->srccoin,qp->destcoin,dstr(qp->satoshis),dstr(qp->destsatoshis)); + LP_Alicequery = *qp, LP_Alicemaxprice = maxprice, Alice_expiration = qp->timestamp + timeout, LP_Alicedestpubkey = destpubkey; + char str[65]; printf("LP_trade %s/%s %.8f vol %.8f dest.(%s)\n",qp->srccoin,qp->destcoin,dstr(qp->satoshis),dstr(qp->destsatoshis),bits256_str(str,LP_Alicedestpubkey)); return(LP_recent_swaps(0)); } int32_t LP_quotecmp(struct LP_quoteinfo *qp,struct LP_quoteinfo *qp2) { - if ( 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 ) //bits256_cmp(qp->srchash,qp2->srchash) == 0 && + if ( bits256_nonz(LP_Alicedestpubkey) != 0 && bits256_cmp(LP_Alicedestpubkey,qp->srchash) != 0 ) + return(-1); + else if ( 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 ) //bits256_cmp(qp->srchash,qp2->srchash) == 0 && return(0); else return(-1); } @@ -487,6 +490,7 @@ int32_t LP_alice_eligible() { printf("time expired for Alice_request\n"); memset(&LP_Alicequery,0,sizeof(LP_Alicequery)); + memset(&LP_Alicedestpubkey,0,sizeof(LP_Alicedestpubkey)); LP_Alicemaxprice = 0.; Alice_expiration = 0; } @@ -503,6 +507,7 @@ void LP_reserved(void *ctx,char *myipaddr,int32_t mypubsock,struct LP_quoteinfo { qp->tradeid = LP_Alicequery.tradeid; memset(&LP_Alicequery,0,sizeof(LP_Alicequery)); + memset(&LP_Alicedestpubkey,0,sizeof(LP_Alicedestpubkey)); LP_Alicemaxprice = 0.; Alice_expiration = 0; printf("send CONNECT\n"); @@ -723,6 +728,11 @@ int32_t LP_tradecommand(void *ctx,char *myipaddr,int32_t pubsock,cJSON *argjson, //printf("aliceid.%llx price %.8f -> bestprice %.8f\n",(long long)aliceid,qprice,bestprice); if ( LP_Alicemaxprice == 0. ) return(retval); + if ( bits256_nonz(LP_Alicedestpubkey) != 0 && bits256_cmp(LP_Alicedestpubkey,Q.srchash) != 0 ) + { + printf("got reserved response from different node\n"); + return(retval); + } if ( bits256_cmp(G.LP_mypub25519,Q.desthash) == 0 && bits256_cmp(G.LP_mypub25519,Q.srchash) != 0 && LP_alice_eligible() > 0 ) { if ( (qprice= LP_quote_validate(autxo,butxo,&Q,0)) <= SMALLVAL ) @@ -801,7 +811,7 @@ int32_t LP_tradecommand(void *ctx,char *myipaddr,int32_t pubsock,cJSON *argjson, { char str[65];//,str2[65]; recalc = 0; - if ( bits256_cmp(Q.srchash,G.LP_mypub25519) != 0 || strcmp(butxo->coinaddr,coin->smartaddr) != 0 || bits256_nonz(butxo->payment.txid) == 0 || bits256_nonz(butxo->deposit.txid) == 0 ) + if ( bits256_nonz(Q.srchash) == 0 || bits256_cmp(Q.srchash,G.LP_mypub25519) != 0 || strcmp(butxo->coinaddr,coin->smartaddr) != 0 || bits256_nonz(butxo->payment.txid) == 0 || bits256_nonz(butxo->deposit.txid) == 0 ) { qprice = (double)Q.destsatoshis / Q.satoshis; strcpy(Q.gui,G.gui); @@ -1132,7 +1142,7 @@ char *LP_autobuy(void *ctx,char *myipaddr,int32_t mypubsock,char *base,char *rel return(clonestr("{\"error\":\"cant set ordermatch quote info\"}")); int32_t changed; LP_mypriceset(&changed,autxo->coin,base,1. / maxprice); - return(LP_trade(ctx,myipaddr,mypubsock,&Q,maxprice,timeout,duration,tradeid)); + return(LP_trade(ctx,myipaddr,mypubsock,&Q,maxprice,timeout,duration,tradeid,destpubkey)); LP_RTmetrics_update(base,rel); while ( 1 ) @@ -1172,7 +1182,7 @@ char *LP_autobuy(void *ctx,char *myipaddr,int32_t mypubsock,char *base,char *rel else return(clonestr("{\"error\":\"cant ordermatch to destpubkey\"}")); } printf("i.%d maxiters.%d qprice %.8f vs maxprice %.8f\n",i,maxiters,dstr(qprice),dstr(maxprice)); - return(LP_trade(ctx,myipaddr,mypubsock,&Q,maxprice,timeout,duration,tradeid)); + return(LP_trade(ctx,myipaddr,mypubsock,&Q,maxprice,timeout,duration,tradeid,destpubkey)); } return(clonestr("{\"error\":\"cant get here\"}")); } From 147d0b124998af842aa49d554abd8c020f2005c7 Mon Sep 17 00:00:00 2001 From: jl777 Date: Mon, 13 Nov 2017 20:47:50 +0200 Subject: [PATCH 0685/1664] Test --- iguana/exchanges/LP_bitcoin.c | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-) diff --git a/iguana/exchanges/LP_bitcoin.c b/iguana/exchanges/LP_bitcoin.c index 4106f0399..f2ebd671d 100644 --- a/iguana/exchanges/LP_bitcoin.c +++ b/iguana/exchanges/LP_bitcoin.c @@ -3330,7 +3330,7 @@ int32_t iguana_rwjoinsplit(int32_t rwflag,uint8_t *serialized,struct iguana_msgj int32_t iguana_rwmsgtx(uint8_t taddr,uint8_t pubtype,uint8_t p2shtype,uint8_t isPoS,int32_t height,int32_t rwflag,cJSON *json,uint8_t *serialized,int32_t maxsize,struct iguana_msgtx *msg,bits256 *txidp,char *vpnstr,uint8_t *extraspace,int32_t extralen,cJSON *vins,int32_t suppress_pubkeys,int32_t zcash) { - int32_t i,n,len = 0,extraused=0; uint8_t segwitflag=0,spendscript[IGUANA_MAXSCRIPTSIZE],*txstart = serialized,*sigser=0; char txidstr[65]; cJSON *vinarray=0,*voutarray=0; bits256 sigtxid; + int32_t i,n,len = 0,extraused=0; uint32_t seglen; uint8_t segwitflag=0,spendscript[IGUANA_MAXSCRIPTSIZE],*txstart = serialized,*sigser=0; char txidstr[65]; cJSON *vinarray=0,*voutarray=0; bits256 sigtxid; len += iguana_rwnum(rwflag,&serialized[len],sizeof(msg->version),&msg->version); if ( json != 0 ) @@ -3432,7 +3432,14 @@ int32_t iguana_rwmsgtx(uint8_t taddr,uint8_t pubtype,uint8_t p2shtype,uint8_t is } if ( segwitflag != 0 ) { - + if ( rwflag != 0 ) + printf("unsupported rwflag.%d when segwitflag\n",rwflag); + else + { + len += iguana_rwvarint32(rwflag,&serialized[len],&seglen); + if ( seglen+len < maxsize ) + len += maxsize; + } } len += iguana_rwnum(rwflag,&serialized[len],sizeof(msg->lock_time),&msg->lock_time); //printf("lock_time.%08x len.%d\n",msg->lock_time,len); From a3c72ca74d911627e13d94d19aa0f56d64c7fc6a Mon Sep 17 00:00:00 2001 From: jl777 Date: Mon, 13 Nov 2017 20:55:00 +0200 Subject: [PATCH 0686/1664] Test --- iguana/exchanges/LP_bitcoin.c | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/iguana/exchanges/LP_bitcoin.c b/iguana/exchanges/LP_bitcoin.c index f2ebd671d..d408de24d 100644 --- a/iguana/exchanges/LP_bitcoin.c +++ b/iguana/exchanges/LP_bitcoin.c @@ -3361,7 +3361,10 @@ int32_t iguana_rwmsgtx(uint8_t taddr,uint8_t pubtype,uint8_t p2shtype,uint8_t is The flag MUST be 0x01 */ if ( serialized[len] == 0x00 && (segwitflag= serialized[len+1]) == 0x01 ) + { len += 2; + printf("SEGWIT transaction\n"); + } } len += iguana_rwvarint32(rwflag,&serialized[len],&msg->tx_in); if ( rwflag == 0 ) @@ -3437,6 +3440,7 @@ int32_t iguana_rwmsgtx(uint8_t taddr,uint8_t pubtype,uint8_t p2shtype,uint8_t is else { len += iguana_rwvarint32(rwflag,&serialized[len],&seglen); + printf("witness len.%d sum %d vs max.%d\n",seglen,seglen+len,maxsize); if ( seglen+len < maxsize ) len += maxsize; } From 61368ea65751d22aa465fafa525682c025f84d85 Mon Sep 17 00:00:00 2001 From: jl777 Date: Mon, 13 Nov 2017 21:00:04 +0200 Subject: [PATCH 0687/1664] Test --- iguana/exchanges/LP_bitcoin.c | 1 + 1 file changed, 1 insertion(+) diff --git a/iguana/exchanges/LP_bitcoin.c b/iguana/exchanges/LP_bitcoin.c index d408de24d..5e4e78a33 100644 --- a/iguana/exchanges/LP_bitcoin.c +++ b/iguana/exchanges/LP_bitcoin.c @@ -3366,6 +3366,7 @@ int32_t iguana_rwmsgtx(uint8_t taddr,uint8_t pubtype,uint8_t p2shtype,uint8_t is printf("SEGWIT transaction\n"); } } + printf("segwit.%d \n",segwitflag); len += iguana_rwvarint32(rwflag,&serialized[len],&msg->tx_in); if ( rwflag == 0 ) { From feb53d0648a797fa49d99b2c7b9286b3108ed076 Mon Sep 17 00:00:00 2001 From: jl777 Date: Mon, 13 Nov 2017 21:02:50 +0200 Subject: [PATCH 0688/1664] Test --- iguana/exchanges/LP_bitcoin.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/iguana/exchanges/LP_bitcoin.c b/iguana/exchanges/LP_bitcoin.c index 5e4e78a33..ab3bd968a 100644 --- a/iguana/exchanges/LP_bitcoin.c +++ b/iguana/exchanges/LP_bitcoin.c @@ -3628,7 +3628,7 @@ cJSON *bitcoin_data2json(uint8_t taddr,uint8_t pubtype,uint8_t p2shtype,uint8_t txobj = cJSON_CreateObject(); jaddstr(txobj,"error","couldnt decode transaction"); } - //printf("msgtx.(%s)\n",jprint(txobj,0)); + printf("msgtx.(%s)\n",jprint(txobj,0)); if ( n != len ) { int32_t i; From 5bc027c57b8d50206b5d86090d8987e3591168c5 Mon Sep 17 00:00:00 2001 From: jl777 Date: Mon, 13 Nov 2017 21:05:18 +0200 Subject: [PATCH 0689/1664] Test --- iguana/exchanges/LP_bitcoin.c | 4 ++-- iguana/exchanges/LP_socket.c | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/iguana/exchanges/LP_bitcoin.c b/iguana/exchanges/LP_bitcoin.c index ab3bd968a..c934ea48e 100644 --- a/iguana/exchanges/LP_bitcoin.c +++ b/iguana/exchanges/LP_bitcoin.c @@ -3628,11 +3628,11 @@ cJSON *bitcoin_data2json(uint8_t taddr,uint8_t pubtype,uint8_t p2shtype,uint8_t txobj = cJSON_CreateObject(); jaddstr(txobj,"error","couldnt decode transaction"); } - printf("msgtx.(%s)\n",jprint(txobj,0)); + //printf("msgtx.(%s)\n",jprint(txobj,0)); if ( n != len ) { int32_t i; - for (i=0; iserialized != 0 ) { - //char str[65]; printf("%s cache hit -> TRANSACTION.(%s)\n",symbol,bits256_str(str,txid)); + char str[65]; printf("%s cache hit -> TRANSACTION.(%s)\n",symbol,bits256_str(str,txid)); if ( (txobj= LP_transaction_fromdata(coin,txid,tx->serialized,tx->len)) != 0 ) { *retjsonp = txobj; From 3df69fab0a75c942661faec84ca87b98a623777b Mon Sep 17 00:00:00 2001 From: jl777 Date: Mon, 13 Nov 2017 21:08:36 +0200 Subject: [PATCH 0690/1664] Test --- iguana/exchanges/LP_ordermatch.c | 21 +++++++++++++++------ 1 file changed, 15 insertions(+), 6 deletions(-) diff --git a/iguana/exchanges/LP_ordermatch.c b/iguana/exchanges/LP_ordermatch.c index 5a9b2031b..cb9a88bf9 100644 --- a/iguana/exchanges/LP_ordermatch.c +++ b/iguana/exchanges/LP_ordermatch.c @@ -477,9 +477,15 @@ char *LP_trade(void *ctx,char *myipaddr,int32_t mypubsock,struct LP_quoteinfo *q int32_t LP_quotecmp(struct LP_quoteinfo *qp,struct LP_quoteinfo *qp2) { - if ( bits256_nonz(LP_Alicedestpubkey) != 0 && bits256_cmp(LP_Alicedestpubkey,qp->srchash) != 0 ) - return(-1); - else if ( 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 ) //bits256_cmp(qp->srchash,qp2->srchash) == 0 && + if ( bits256_nonz(LP_Alicedestpubkey) != 0 ) + { + if (bits256_cmp(LP_Alicedestpubkey,qp->srchash) != 0 ) + { + printf("reject quote from non-matching pubkey\n"); + return(-1); + } else printf("dont reject quote from destpubkey\n"); + } + if ( 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 ) //bits256_cmp(qp->srchash,qp2->srchash) == 0 && return(0); else return(-1); } @@ -728,10 +734,13 @@ int32_t LP_tradecommand(void *ctx,char *myipaddr,int32_t pubsock,cJSON *argjson, //printf("aliceid.%llx price %.8f -> bestprice %.8f\n",(long long)aliceid,qprice,bestprice); if ( LP_Alicemaxprice == 0. ) return(retval); - if ( bits256_nonz(LP_Alicedestpubkey) != 0 && bits256_cmp(LP_Alicedestpubkey,Q.srchash) != 0 ) + if ( bits256_nonz(LP_Alicedestpubkey) != 0 ) { - printf("got reserved response from different node\n"); - return(retval); + if (bits256_cmp(LP_Alicedestpubkey,Q.srchash) != 0 ) + { + printf("got reserved response from different node %s\n",bits256_str(str,Q.srchash)); + return(retval); + } else printf("got reserved response from destpubkey %s\n",bits256_str(str,Q.srchash)); } if ( bits256_cmp(G.LP_mypub25519,Q.desthash) == 0 && bits256_cmp(G.LP_mypub25519,Q.srchash) != 0 && LP_alice_eligible() > 0 ) { From 6f5bb98d6b3d2a978447bb70e812efe43f351622 Mon Sep 17 00:00:00 2001 From: jl777 Date: Mon, 13 Nov 2017 21:13:26 +0200 Subject: [PATCH 0691/1664] Test --- iguana/exchanges/LP_bitcoin.c | 3 +-- iguana/exchanges/LP_socket.c | 4 ++-- 2 files changed, 3 insertions(+), 4 deletions(-) diff --git a/iguana/exchanges/LP_bitcoin.c b/iguana/exchanges/LP_bitcoin.c index c934ea48e..19c34cf6b 100644 --- a/iguana/exchanges/LP_bitcoin.c +++ b/iguana/exchanges/LP_bitcoin.c @@ -3350,7 +3350,7 @@ int32_t iguana_rwmsgtx(uint8_t taddr,uint8_t pubtype,uint8_t p2shtype,uint8_t is if ( json != 0 ) jaddnum(json,"timestamp",msg->timestamp); } - if ( rwflag == 0 ) + if ( rwflag == 0 && zcash == 0 ) { /* normal: nVersion|txins|txouts|nLockTime. @@ -3366,7 +3366,6 @@ int32_t iguana_rwmsgtx(uint8_t taddr,uint8_t pubtype,uint8_t p2shtype,uint8_t is printf("SEGWIT transaction\n"); } } - printf("segwit.%d \n",segwitflag); len += iguana_rwvarint32(rwflag,&serialized[len],&msg->tx_in); if ( rwflag == 0 ) { diff --git a/iguana/exchanges/LP_socket.c b/iguana/exchanges/LP_socket.c index 673412be8..96855e6d7 100644 --- a/iguana/exchanges/LP_socket.c +++ b/iguana/exchanges/LP_socket.c @@ -681,12 +681,12 @@ cJSON *LP_cache_transaction(struct iguana_info *coin,bits256 txid,uint8_t *seria cJSON *_electrum_transaction(char *symbol,struct electrum_info *ep,cJSON **retjsonp,bits256 txid) { char *hexstr,str[65]; int32_t len; cJSON *hexjson,*txobj=0; struct iguana_info *coin; uint8_t *serialized; struct LP_transaction *tx; - printf("electrum_transaction %s %s\n",symbol,bits256_str(str,txid)); + //printf("electrum_transaction %s %s\n",symbol,bits256_str(str,txid)); if ( bits256_nonz(txid) != 0 && (coin= LP_coinfind(symbol)) != 0 ) { if ( (tx= LP_transactionfind(coin,txid)) != 0 && tx->serialized != 0 ) { - char str[65]; printf("%s cache hit -> TRANSACTION.(%s)\n",symbol,bits256_str(str,txid)); + //char str[65]; printf("%s cache hit -> TRANSACTION.(%s)\n",symbol,bits256_str(str,txid)); if ( (txobj= LP_transaction_fromdata(coin,txid,tx->serialized,tx->len)) != 0 ) { *retjsonp = txobj; From e84cf291f30d757137bf896c16e65a93b83842a5 Mon Sep 17 00:00:00 2001 From: jl777 Date: Mon, 13 Nov 2017 21:19:00 +0200 Subject: [PATCH 0692/1664] Test --- iguana/exchanges/LP_bitcoin.c | 1 + 1 file changed, 1 insertion(+) diff --git a/iguana/exchanges/LP_bitcoin.c b/iguana/exchanges/LP_bitcoin.c index 19c34cf6b..373af373b 100644 --- a/iguana/exchanges/LP_bitcoin.c +++ b/iguana/exchanges/LP_bitcoin.c @@ -3435,6 +3435,7 @@ int32_t iguana_rwmsgtx(uint8_t taddr,uint8_t pubtype,uint8_t p2shtype,uint8_t is } if ( segwitflag != 0 ) { + printf("tx_out %d, tx_in %d %02x %02x %02x\n",msg->tx_out,msg->tx_in,serialized[len],serialized[len+1],serialized[len+2]); if ( rwflag != 0 ) printf("unsupported rwflag.%d when segwitflag\n",rwflag); else From d9cca82171819ef9885908f6f5c71af6f6278dec Mon Sep 17 00:00:00 2001 From: jl777 Date: Mon, 13 Nov 2017 21:41:39 +0200 Subject: [PATCH 0693/1664] Test --- iguana/exchanges/LP_socket.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/iguana/exchanges/LP_socket.c b/iguana/exchanges/LP_socket.c index 96855e6d7..24aa88653 100644 --- a/iguana/exchanges/LP_socket.c +++ b/iguana/exchanges/LP_socket.c @@ -598,7 +598,7 @@ cJSON *electrum_address_listunspent(char *symbol,struct electrum_info *ep,cJSON { if ( jobj(retjson,"error") == 0 && is_cJSON_Array(retjson) != 0 ) { - if ( 0 && electrumflag > 1 ) + if ( electrumflag > 1 ) printf("%s.%d u.%u/%d t.%ld %s LISTUNSPENT.(%d)\n",coin->symbol,height,ap->unspenttime,ap->unspentheight,time(NULL),addr,(int32_t)strlen(jprint(retjson,0))); updatedflag = 0; if ( electrum_process_array(coin,ep,addr,retjson,electrumflag) != 0 ) From 1c1c1467b273c6a4df4cfeccb77da72e30440653 Mon Sep 17 00:00:00 2001 From: jl777 Date: Mon, 13 Nov 2017 21:49:48 +0200 Subject: [PATCH 0694/1664] Test --- iguana/exchanges/LP_nativeDEX.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/iguana/exchanges/LP_nativeDEX.c b/iguana/exchanges/LP_nativeDEX.c index 05ce41c36..0901d9c0b 100644 --- a/iguana/exchanges/LP_nativeDEX.c +++ b/iguana/exchanges/LP_nativeDEX.c @@ -540,7 +540,7 @@ void LP_coinsloop(void *_coins) if ( (retjson= electrum_address_listunspent(coin->symbol,ep,&retjson,ap->coinaddr,1)) != 0 ) free_json(retjson); } - HASH_ITER(hh,coin->addresses,ap,atmp) + if ( (ap= LP_addressfind(coin,coin->smartaddr)) != 0 ) { DL_FOREACH_SAFE(ap->utxos,up,tmp) { From 6ce04c99c883f44c9be0cb2b77d85defd662487e Mon Sep 17 00:00:00 2001 From: jl777 Date: Mon, 13 Nov 2017 22:02:01 +0200 Subject: [PATCH 0695/1664] Test --- iguana/exchanges/LP_socket.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/iguana/exchanges/LP_socket.c b/iguana/exchanges/LP_socket.c index 24aa88653..e200c5891 100644 --- a/iguana/exchanges/LP_socket.c +++ b/iguana/exchanges/LP_socket.c @@ -598,7 +598,7 @@ cJSON *electrum_address_listunspent(char *symbol,struct electrum_info *ep,cJSON { if ( jobj(retjson,"error") == 0 && is_cJSON_Array(retjson) != 0 ) { - if ( electrumflag > 1 ) + if ( 0 && electrumflag > 1 ) printf("%s.%d u.%u/%d t.%ld %s LISTUNSPENT.(%d)\n",coin->symbol,height,ap->unspenttime,ap->unspentheight,time(NULL),addr,(int32_t)strlen(jprint(retjson,0))); updatedflag = 0; if ( electrum_process_array(coin,ep,addr,retjson,electrumflag) != 0 ) @@ -707,7 +707,7 @@ cJSON *_electrum_transaction(char *symbol,struct electrum_info *ep,cJSON **retjs { static uint32_t counter; if ( counter++ < 3 ) - printf("rawtransaction too big %d\n",(int32_t)strlen(hexstr)); + printf("rawtransaction %s %s too big %d\n",coin->symbol,bits256_str(str,txid),(int32_t)strlen(hexstr)); free(hexstr); free_json(hexjson); *retjsonp = cJSON_Parse("{\"error\":\"transaction too big\"}"); From f2a39dcc835bb3bf1d3b38cb1d74958585ec2815 Mon Sep 17 00:00:00 2001 From: jl777 Date: Mon, 13 Nov 2017 22:13:25 +0200 Subject: [PATCH 0696/1664] Test --- iguana/exchanges/LP_transaction.c | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/iguana/exchanges/LP_transaction.c b/iguana/exchanges/LP_transaction.c index bc582236c..6990da6e6 100644 --- a/iguana/exchanges/LP_transaction.c +++ b/iguana/exchanges/LP_transaction.c @@ -978,7 +978,7 @@ int32_t LP_vins_select(void *ctx,struct iguana_info *coin,int64_t *totalp,int64_ char str[65]; printf("%s/%d %.8f interest %.8f -> sum %.8f\n",bits256_str(str,up->U.txid),up->U.vout,dstr(up->U.value),dstr(interest),dstr(interestsum)); } } - printf("numunspents.%d vini.%d value %.8f, total %.8f remains %.8f interest %.8f sum %.8f\n",numunspents,n,dstr(up->U.value),dstr(total),dstr(remains),dstr(interest),dstr(interestsum)); + printf("numunspents.%d vini.%d value %.8f, total %.8f remains %.8f interest %.8f sum %.8f %s/v%d\n",numunspents,n,dstr(up->U.value),dstr(total),dstr(remains),dstr(interest),dstr(interestsum),bits256_str(str,up->U.txid),up->U.vout); vp = &V[n++]; vp->N = vp->M = 1; vp->signers[0].privkey = privkey; @@ -1059,6 +1059,10 @@ char *LP_createrawtransaction(cJSON **txobjp,int32_t *numvinsp,struct iguana_inf printf("LP_createrawtransaction: address_utxo_ptrs %d, error\n",numutxos); //return(0); } + char str[65]; + for (i=0; iU.txid),utxos[i]->U.vout,dstr(utxos[i]->U.value)); + ignore_cltverr = 0; suppress_pubkeys = 1; scriptlen = bitcoin_standardspend(script,0,G.LP_myrmd160); From 0a84293c5d2c2f3acef0f22299d6314c29ffea3c Mon Sep 17 00:00:00 2001 From: jl777 Date: Mon, 13 Nov 2017 22:29:15 +0200 Subject: [PATCH 0697/1664] Test --- iguana/exchanges/LP_transaction.c | 22 ++++++++++++++++++++-- 1 file changed, 20 insertions(+), 2 deletions(-) diff --git a/iguana/exchanges/LP_transaction.c b/iguana/exchanges/LP_transaction.c index 6990da6e6..8ee70ca89 100644 --- a/iguana/exchanges/LP_transaction.c +++ b/iguana/exchanges/LP_transaction.c @@ -1002,7 +1002,7 @@ int32_t LP_vins_select(void *ctx,struct iguana_info *coin,int64_t *totalp,int64_ 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,bits256 utxotxid,int32_t utxovout,uint32_t locktime) { static void *ctx; - cJSON *txobj,*item; uint8_t addrtype,rmd160[20],script[64],spendscript[256]; char *coinaddr,*rawtxbytes; bits256 txid; uint32_t timestamp; int64_t change=0,adjust=0,total,value,amount = 0; int32_t i,dustcombine,scriptlen,spendlen,suppress_pubkeys,ignore_cltverr,numvouts=0,numvins=0,numutxos=0; struct LP_address_utxo *utxos[LP_MAXVINS]; struct LP_address *ap; + cJSON *txobj,*item,*array; uint8_t addrtype,rmd160[20],script[64],spendscript[256]; char *coinaddr,*rawtxbytes; bits256 txid; uint32_t timestamp; int64_t change=0,adjust=0,total,value,amount = 0; int32_t i,n,dustcombine,scriptlen,spendlen,suppress_pubkeys,ignore_cltverr,numvouts=0,numvins=0,numutxos=0; struct LP_address_utxo *utxos[LP_MAXVINS]; struct LP_address *ap; if ( ctx == 0 ) ctx = bitcoin_ctx(); *numvinsp = 0; @@ -1047,13 +1047,31 @@ char *LP_createrawtransaction(cJSON **txobjp,int32_t *numvinsp,struct iguana_inf return(0); } } - LP_listunspent_issue(coin->symbol,coin->smartaddr,1); + LP_listunspent_issue(coin->symbol,coin->smartaddr,2); if ( (ap= LP_addressfind(coin,coin->smartaddr)) == 0 ) { printf("LP_createrawtransaction: cant find address data\n"); return(0); } memset(utxos,0,sizeof(utxos)); + if ( (array= LP_listunspent(coin->symbol,coin->smartaddr)) != 0 ) + { + int32_t vout,height; + ap->utxos = 0; + if ( (n= cJSON_GetArraySize(array)) > 0 ) + { + for (i=0; ismartaddr,txid,vout,value,height,-1); + } + } + } if ( (numutxos= LP_address_utxo_ptrs(coin,0,utxos,max,ap,coin->smartaddr)) <= 0 ) { printf("LP_createrawtransaction: address_utxo_ptrs %d, error\n",numutxos); From 7923b76d4311dd722f79c092fa4296f8bccae0ed Mon Sep 17 00:00:00 2001 From: jl777 Date: Mon, 13 Nov 2017 22:39:19 +0200 Subject: [PATCH 0698/1664] Test --- iguana/exchanges/LP_commands.c | 10 +++--- iguana/exchanges/LP_nativeDEX.c | 2 +- iguana/exchanges/LP_transaction.c | 56 ++++++++++++++++++------------- iguana/exchanges/LP_utxos.c | 1 + 4 files changed, 40 insertions(+), 29 deletions(-) diff --git a/iguana/exchanges/LP_commands.c b/iguana/exchanges/LP_commands.c index 9d0f4ff47..a084c0e0d 100644 --- a/iguana/exchanges/LP_commands.c +++ b/iguana/exchanges/LP_commands.c @@ -103,7 +103,7 @@ notarizations(coin)\n\ parselog()\n\ statsdisp(starttime=0, endtime=0, gui="", pubkey="")\n\ getrawtransaction(coin, txid)\n\ -inventory(coin)\n\ +inventory(coin, reset=0)\n\ bestfit(rel, relvolume)\n\ lastnonce()\n\ buy(base, rel, price, relvolume, timeout=10, duration=3600, nonce, destpubkey="")\n\ @@ -484,10 +484,12 @@ bot_resume(botid)\n\ struct iguana_info *ptr; if ( (ptr= LP_coinfind(coin)) != 0 ) { - //privkey = LP_privkeycalc(ctx,pubkey33,&pubkey,ptr,"",USERPASS_WIFSTR); - //LP_utxopurge(0); LP_address(ptr,ptr->smartaddr); - LP_listunspent_issue(coin,ptr->smartaddr,2); + if ( jint(argjson,"reset") != 0 ) + { + LP_address_utxo_reset(ptr); + LP_passphrase_init(G.PASSPHRASE,G.gui); + } if ( bits256_nonz(G.LP_privkey) != 0 ) LP_privkey_init(-1,ptr,G.LP_privkey,G.LP_mypub25519); else printf("no LP_privkey\n"); diff --git a/iguana/exchanges/LP_nativeDEX.c b/iguana/exchanges/LP_nativeDEX.c index 0901d9c0b..047c485c9 100644 --- a/iguana/exchanges/LP_nativeDEX.c +++ b/iguana/exchanges/LP_nativeDEX.c @@ -122,7 +122,7 @@ struct LP_globals uint8_t LP_myrmd160[20],LP_pubsecp[33]; uint32_t LP_sessionid,counter; int32_t LP_IAMLP,LP_pendingswaps,USERPASS_COUNTER,LP_numprivkeys,initializing,waiting,LP_numskips; - char USERPASS[65],USERPASS_WIFSTR[64],LP_myrmd160str[41],gui[16]; + char USERPASS[65],USERPASS_WIFSTR[64],PASSPHRASE[1024],LP_myrmd160str[41],gui[16]; struct LP_privkey LP_privkeys[100]; } G; diff --git a/iguana/exchanges/LP_transaction.c b/iguana/exchanges/LP_transaction.c index 8ee70ca89..574fcbbb2 100644 --- a/iguana/exchanges/LP_transaction.c +++ b/iguana/exchanges/LP_transaction.c @@ -999,10 +999,40 @@ int32_t LP_vins_select(void *ctx,struct iguana_info *coin,int64_t *totalp,int64_ return(n); } +struct LP_address *LP_address_utxo_reset(struct iguana_info *coin) +{ + struct LP_address *ap; int32_t i,n; cJSON *array,*item; int64_t value; bits256 txid; int32_t vout,height; + LP_listunspent_issue(coin->symbol,coin->smartaddr,2); + if ( (ap= LP_addressfind(coin,coin->smartaddr)) == 0 ) + { + printf("LP_createrawtransaction: cant find address data\n"); + return(0); + } + if ( (array= LP_listunspent(coin->symbol,coin->smartaddr)) != 0 ) + { + ap->utxos = 0; + if ( (n= cJSON_GetArraySize(array)) > 0 ) + { + for (i=0; ismartaddr,txid,vout,value,height,-1); + } + } + free_json(array); + } + return(ap); +} + 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,bits256 utxotxid,int32_t utxovout,uint32_t locktime) { static void *ctx; - cJSON *txobj,*item,*array; uint8_t addrtype,rmd160[20],script[64],spendscript[256]; char *coinaddr,*rawtxbytes; bits256 txid; uint32_t timestamp; int64_t change=0,adjust=0,total,value,amount = 0; int32_t i,n,dustcombine,scriptlen,spendlen,suppress_pubkeys,ignore_cltverr,numvouts=0,numvins=0,numutxos=0; struct LP_address_utxo *utxos[LP_MAXVINS]; struct LP_address *ap; + cJSON *txobj,*item; uint8_t addrtype,rmd160[20],script[64],spendscript[256]; char *coinaddr,*rawtxbytes; bits256 txid; uint32_t timestamp; int64_t change=0,adjust=0,total,value,amount = 0; int32_t i,dustcombine,scriptlen,spendlen,suppress_pubkeys,ignore_cltverr,numvouts=0,numvins=0,numutxos=0; struct LP_address_utxo *utxos[LP_MAXVINS]; struct LP_address *ap; if ( ctx == 0 ) ctx = bitcoin_ctx(); *numvinsp = 0; @@ -1047,31 +1077,9 @@ char *LP_createrawtransaction(cJSON **txobjp,int32_t *numvinsp,struct iguana_inf return(0); } } - LP_listunspent_issue(coin->symbol,coin->smartaddr,2); - if ( (ap= LP_addressfind(coin,coin->smartaddr)) == 0 ) - { - printf("LP_createrawtransaction: cant find address data\n"); + if ( (ap= LP_address_utxo_reset(coin)) == 0 ) return(0); - } memset(utxos,0,sizeof(utxos)); - if ( (array= LP_listunspent(coin->symbol,coin->smartaddr)) != 0 ) - { - int32_t vout,height; - ap->utxos = 0; - if ( (n= cJSON_GetArraySize(array)) > 0 ) - { - for (i=0; ismartaddr,txid,vout,value,height,-1); - } - } - } if ( (numutxos= LP_address_utxo_ptrs(coin,0,utxos,max,ap,coin->smartaddr)) <= 0 ) { printf("LP_createrawtransaction: address_utxo_ptrs %d, error\n",numutxos); diff --git a/iguana/exchanges/LP_utxos.c b/iguana/exchanges/LP_utxos.c index 2d5a04915..3fbf10371 100644 --- a/iguana/exchanges/LP_utxos.c +++ b/iguana/exchanges/LP_utxos.c @@ -870,6 +870,7 @@ int32_t LP_passphrase_init(char *passphrase,char *gui) } } memset(&G,0,sizeof(G)); + strcpy(G.PASSPHRASE,passphrase); LP_privkey_updates(ctx,LP_mypubsock,passphrase); init_hexbytes_noT(G.LP_myrmd160str,G.LP_myrmd160,20); G.LP_sessionid = (uint32_t)time(NULL); From f955f2a28f3587bd89ae4fab1738a1aa7cd1790d Mon Sep 17 00:00:00 2001 From: jl777 Date: Mon, 13 Nov 2017 22:42:30 +0200 Subject: [PATCH 0699/1664] Test --- iguana/exchanges/LP_utxos.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/iguana/exchanges/LP_utxos.c b/iguana/exchanges/LP_utxos.c index 3fbf10371..0c7fa39a5 100644 --- a/iguana/exchanges/LP_utxos.c +++ b/iguana/exchanges/LP_utxos.c @@ -870,12 +870,13 @@ int32_t LP_passphrase_init(char *passphrase,char *gui) } } memset(&G,0,sizeof(G)); - strcpy(G.PASSPHRASE,passphrase); LP_privkey_updates(ctx,LP_mypubsock,passphrase); init_hexbytes_noT(G.LP_myrmd160str,G.LP_myrmd160,20); G.LP_sessionid = (uint32_t)time(NULL); safecopy(G.gui,gui,sizeof(G.gui)); G.USERPASS_COUNTER = counter; + strcpy(G.PASSPHRASE,passphrase); + printf("set PASSPHRASE.(%s)\n",G.PASSPHRASE); G.initializing = 0; return(0); } From b9cc5ba6bb6d002628e6be7b09a7afe1b11ce8ff Mon Sep 17 00:00:00 2001 From: jl777 Date: Mon, 13 Nov 2017 22:46:20 +0200 Subject: [PATCH 0700/1664] Test --- iguana/exchanges/LP_commands.c | 4 ++-- iguana/exchanges/LP_nativeDEX.c | 2 +- iguana/exchanges/LP_utxos.c | 2 -- 3 files changed, 3 insertions(+), 5 deletions(-) diff --git a/iguana/exchanges/LP_commands.c b/iguana/exchanges/LP_commands.c index a084c0e0d..9e68ead18 100644 --- a/iguana/exchanges/LP_commands.c +++ b/iguana/exchanges/LP_commands.c @@ -103,7 +103,7 @@ notarizations(coin)\n\ parselog()\n\ statsdisp(starttime=0, endtime=0, gui="", pubkey="")\n\ getrawtransaction(coin, txid)\n\ -inventory(coin, reset=0)\n\ +inventory(coin, reset=0, [passphrase=])\n\ bestfit(rel, relvolume)\n\ lastnonce()\n\ buy(base, rel, price, relvolume, timeout=10, duration=3600, nonce, destpubkey="")\n\ @@ -488,7 +488,7 @@ bot_resume(botid)\n\ if ( jint(argjson,"reset") != 0 ) { LP_address_utxo_reset(ptr); - LP_passphrase_init(G.PASSPHRASE,G.gui); + LP_passphrase_init(jstr(argjson,"passphrase"),G.gui); } if ( bits256_nonz(G.LP_privkey) != 0 ) LP_privkey_init(-1,ptr,G.LP_privkey,G.LP_mypub25519); diff --git a/iguana/exchanges/LP_nativeDEX.c b/iguana/exchanges/LP_nativeDEX.c index 047c485c9..0901d9c0b 100644 --- a/iguana/exchanges/LP_nativeDEX.c +++ b/iguana/exchanges/LP_nativeDEX.c @@ -122,7 +122,7 @@ struct LP_globals uint8_t LP_myrmd160[20],LP_pubsecp[33]; uint32_t LP_sessionid,counter; int32_t LP_IAMLP,LP_pendingswaps,USERPASS_COUNTER,LP_numprivkeys,initializing,waiting,LP_numskips; - char USERPASS[65],USERPASS_WIFSTR[64],PASSPHRASE[1024],LP_myrmd160str[41],gui[16]; + char USERPASS[65],USERPASS_WIFSTR[64],LP_myrmd160str[41],gui[16]; struct LP_privkey LP_privkeys[100]; } G; diff --git a/iguana/exchanges/LP_utxos.c b/iguana/exchanges/LP_utxos.c index 0c7fa39a5..2d5a04915 100644 --- a/iguana/exchanges/LP_utxos.c +++ b/iguana/exchanges/LP_utxos.c @@ -875,8 +875,6 @@ int32_t LP_passphrase_init(char *passphrase,char *gui) G.LP_sessionid = (uint32_t)time(NULL); safecopy(G.gui,gui,sizeof(G.gui)); G.USERPASS_COUNTER = counter; - strcpy(G.PASSPHRASE,passphrase); - printf("set PASSPHRASE.(%s)\n",G.PASSPHRASE); G.initializing = 0; return(0); } From 1d7ac2dc9da2ef963acc7dce01e03e696ff1bfb3 Mon Sep 17 00:00:00 2001 From: jl777 Date: Mon, 13 Nov 2017 22:55:29 +0200 Subject: [PATCH 0701/1664] Test --- iguana/exchanges/LP_commands.c | 1 + 1 file changed, 1 insertion(+) diff --git a/iguana/exchanges/LP_commands.c b/iguana/exchanges/LP_commands.c index 9e68ead18..eda89f9f7 100644 --- a/iguana/exchanges/LP_commands.c +++ b/iguana/exchanges/LP_commands.c @@ -488,6 +488,7 @@ bot_resume(botid)\n\ if ( jint(argjson,"reset") != 0 ) { LP_address_utxo_reset(ptr); + ptr->privkeydepth = 0; LP_passphrase_init(jstr(argjson,"passphrase"),G.gui); } if ( bits256_nonz(G.LP_privkey) != 0 ) From 06c4d96c866f6689c26c79985497af3fe43a3842 Mon Sep 17 00:00:00 2001 From: jl777 Date: Mon, 13 Nov 2017 22:56:01 +0200 Subject: [PATCH 0702/1664] Test --- iguana/exchanges/LP_commands.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/iguana/exchanges/LP_commands.c b/iguana/exchanges/LP_commands.c index eda89f9f7..3aca6ee1c 100644 --- a/iguana/exchanges/LP_commands.c +++ b/iguana/exchanges/LP_commands.c @@ -484,11 +484,11 @@ bot_resume(botid)\n\ struct iguana_info *ptr; if ( (ptr= LP_coinfind(coin)) != 0 ) { + ptr->privkeydepth = 0; LP_address(ptr,ptr->smartaddr); if ( jint(argjson,"reset") != 0 ) { LP_address_utxo_reset(ptr); - ptr->privkeydepth = 0; LP_passphrase_init(jstr(argjson,"passphrase"),G.gui); } if ( bits256_nonz(G.LP_privkey) != 0 ) From d716a534da7412222b4a2542e2d1da1c4d4b9f2d Mon Sep 17 00:00:00 2001 From: jl777 Date: Mon, 13 Nov 2017 23:01:06 +0200 Subject: [PATCH 0703/1664] Test --- iguana/exchanges/LP_socket.c | 2 +- iguana/exchanges/install | 2 +- iguana/exchanges/invreset | 3 +++ 3 files changed, 5 insertions(+), 2 deletions(-) create mode 100755 iguana/exchanges/invreset diff --git a/iguana/exchanges/LP_socket.c b/iguana/exchanges/LP_socket.c index e200c5891..282124a6f 100644 --- a/iguana/exchanges/LP_socket.c +++ b/iguana/exchanges/LP_socket.c @@ -598,7 +598,7 @@ cJSON *electrum_address_listunspent(char *symbol,struct electrum_info *ep,cJSON { if ( jobj(retjson,"error") == 0 && is_cJSON_Array(retjson) != 0 ) { - if ( 0 && electrumflag > 1 ) + if ( 1 && electrumflag > 1 ) printf("%s.%d u.%u/%d t.%ld %s LISTUNSPENT.(%d)\n",coin->symbol,height,ap->unspenttime,ap->unspentheight,time(NULL),addr,(int32_t)strlen(jprint(retjson,0))); updatedflag = 0; if ( electrum_process_array(coin,ep,addr,retjson,electrumflag) != 0 ) diff --git a/iguana/exchanges/install b/iguana/exchanges/install index 86709f0ab..efb2c7a2e 100755 --- a/iguana/exchanges/install +++ b/iguana/exchanges/install @@ -1,5 +1,5 @@ #!/bin/bash -cp sendrawtransaction processfiles stop millis mnzservers bot_buy bot_list bot_statuslist bot_pause bot_resume bot_sell bot_settings bot_status bot_stop guistats pubkeystats pendings coinswaps baserelswaps setpassphrase notarizations getrawtransaction parselog statsdisp m_js 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 invreset sendrawtransaction processfiles stop millis mnzservers bot_buy bot_list bot_statuslist bot_pause bot_resume bot_sell bot_settings bot_status bot_stop guistats pubkeystats pendings coinswaps baserelswaps setpassphrase notarizations getrawtransaction parselog statsdisp m_js 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 . diff --git a/iguana/exchanges/invreset b/iguana/exchanges/invreset new file mode 100755 index 000000000..f0b1c79e3 --- /dev/null +++ b/iguana/exchanges/invreset @@ -0,0 +1,3 @@ +source userpass +source passphrase +curl --url "http://127.0.0.1:7783" --data "{\"userpass\":\"$userpass\",\"method\":\"inventory\",\"coin\":\"KMD\",\"reset\":1,\"passphrase\":\"$passphrase\"}" From c874bfbe676682440489d61fec213dad6074f229 Mon Sep 17 00:00:00 2001 From: jl777 Date: Mon, 13 Nov 2017 23:07:33 +0200 Subject: [PATCH 0704/1664] Test --- iguana/exchanges/LP_commands.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/iguana/exchanges/LP_commands.c b/iguana/exchanges/LP_commands.c index 3aca6ee1c..5773bf88a 100644 --- a/iguana/exchanges/LP_commands.c +++ b/iguana/exchanges/LP_commands.c @@ -388,13 +388,16 @@ bot_resume(botid)\n\ if ( (ptr= LP_coinsearch(coin)) != 0 ) { char *coinaddr; + printf("listunspent\n"); if ( (coinaddr= jstr(argjson,"address")) != 0 ) { if ( coinaddr[0] != 0 ) { LP_address(ptr,coinaddr); + printf("check addr\n"); if ( strcmp(coinaddr,ptr->smartaddr) == 0 && bits256_nonz(G.LP_privkey) != 0 ) { + printf("my addr\n"); LP_listunspent_issue(coin,coinaddr,2); LP_privkey_init(-1,ptr,G.LP_privkey,G.LP_mypub25519); //LP_smartutxos_push(ptr); From 0c30756bd149e613b76405a14f58142931191381 Mon Sep 17 00:00:00 2001 From: jl777 Date: Mon, 13 Nov 2017 23:15:35 +0200 Subject: [PATCH 0705/1664] Test --- iguana/exchanges/LP_transaction.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/iguana/exchanges/LP_transaction.c b/iguana/exchanges/LP_transaction.c index 574fcbbb2..661319305 100644 --- a/iguana/exchanges/LP_transaction.c +++ b/iguana/exchanges/LP_transaction.c @@ -989,7 +989,7 @@ int32_t LP_vins_select(void *ctx,struct iguana_info *coin,int64_t *totalp,int64_ jaddi(vins,LP_inputjson(up->U.txid,up->U.vout,spendscriptstr)); if ( remains <= 0 && i >= numpre-1 ) break; - if ( numunspents == 0 ) + if ( numunspents < 0 ) { printf("total %.8f not enough for amount %.8f\n",dstr(total),dstr(amount)); return(0); From 3db4ea83ef1de3c2247ffbc9701a43aba62dbcbb Mon Sep 17 00:00:00 2001 From: jl777 Date: Mon, 13 Nov 2017 23:23:13 +0200 Subject: [PATCH 0706/1664] Test --- iguana/exchanges/LP_utxos.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/iguana/exchanges/LP_utxos.c b/iguana/exchanges/LP_utxos.c index 2d5a04915..93d6ff688 100644 --- a/iguana/exchanges/LP_utxos.c +++ b/iguana/exchanges/LP_utxos.c @@ -550,7 +550,7 @@ int32_t LP_privkey_init(int32_t mypubsock,struct iguana_info *coin,bits256 mypri return(0); coin->privkeydepth++; LP_address(coin,coin->smartaddr); - //printf("privkey init.(%s) %s depth.%d\n",coin->symbol,coin->smartaddr,coin->privkeydepth); + printf("privkey init.(%s) %s depth.%d\n",coin->symbol,coin->smartaddr,coin->privkeydepth); if ( coin->inactive == 0 ) LP_listunspent_issue(coin->symbol,coin->smartaddr,0); array = LP_listunspent(coin->symbol,coin->smartaddr); From 8dd3b6520637eb5e2867ffefedfd3d4f890337b7 Mon Sep 17 00:00:00 2001 From: jl777 Date: Mon, 13 Nov 2017 23:26:02 +0200 Subject: [PATCH 0707/1664] Test --- iguana/exchanges/LP_commands.c | 3 --- iguana/exchanges/LP_socket.c | 2 +- iguana/exchanges/LP_utxos.c | 6 +++--- 3 files changed, 4 insertions(+), 7 deletions(-) diff --git a/iguana/exchanges/LP_commands.c b/iguana/exchanges/LP_commands.c index 5773bf88a..3aca6ee1c 100644 --- a/iguana/exchanges/LP_commands.c +++ b/iguana/exchanges/LP_commands.c @@ -388,16 +388,13 @@ bot_resume(botid)\n\ if ( (ptr= LP_coinsearch(coin)) != 0 ) { char *coinaddr; - printf("listunspent\n"); if ( (coinaddr= jstr(argjson,"address")) != 0 ) { if ( coinaddr[0] != 0 ) { LP_address(ptr,coinaddr); - printf("check addr\n"); if ( strcmp(coinaddr,ptr->smartaddr) == 0 && bits256_nonz(G.LP_privkey) != 0 ) { - printf("my addr\n"); LP_listunspent_issue(coin,coinaddr,2); LP_privkey_init(-1,ptr,G.LP_privkey,G.LP_mypub25519); //LP_smartutxos_push(ptr); diff --git a/iguana/exchanges/LP_socket.c b/iguana/exchanges/LP_socket.c index 282124a6f..e200c5891 100644 --- a/iguana/exchanges/LP_socket.c +++ b/iguana/exchanges/LP_socket.c @@ -598,7 +598,7 @@ cJSON *electrum_address_listunspent(char *symbol,struct electrum_info *ep,cJSON { if ( jobj(retjson,"error") == 0 && is_cJSON_Array(retjson) != 0 ) { - if ( 1 && electrumflag > 1 ) + if ( 0 && electrumflag > 1 ) printf("%s.%d u.%u/%d t.%ld %s LISTUNSPENT.(%d)\n",coin->symbol,height,ap->unspenttime,ap->unspentheight,time(NULL),addr,(int32_t)strlen(jprint(retjson,0))); updatedflag = 0; if ( electrum_process_array(coin,ep,addr,retjson,electrumflag) != 0 ) diff --git a/iguana/exchanges/LP_utxos.c b/iguana/exchanges/LP_utxos.c index 93d6ff688..770b84b89 100644 --- a/iguana/exchanges/LP_utxos.c +++ b/iguana/exchanges/LP_utxos.c @@ -542,15 +542,15 @@ int32_t LP_privkey_init(int32_t mypubsock,struct iguana_info *coin,bits256 mypri //printf("coin not active\n"); return(0); } - if ( bits256_cmp(myprivkey,coin->lastprivkey) == 0 && time(NULL) < coin->lastprivkeytime+60 ) - return(0); + /*if ( bits256_cmp(myprivkey,coin->lastprivkey) == 0 && time(NULL) < coin->lastprivkeytime+60 ) + return(0);*/ coin->lastprivkey = myprivkey; coin->lastprivkeytime = (uint32_t)time(NULL); if ( coin->privkeydepth > 0 ) return(0); coin->privkeydepth++; LP_address(coin,coin->smartaddr); - printf("privkey init.(%s) %s depth.%d\n",coin->symbol,coin->smartaddr,coin->privkeydepth); + //printf("privkey init.(%s) %s depth.%d\n",coin->symbol,coin->smartaddr,coin->privkeydepth); if ( coin->inactive == 0 ) LP_listunspent_issue(coin->symbol,coin->smartaddr,0); array = LP_listunspent(coin->symbol,coin->smartaddr); From 0660c741744b47f62c0b78a3511d33bb068455d5 Mon Sep 17 00:00:00 2001 From: jl777 Date: Mon, 13 Nov 2017 23:47:27 +0200 Subject: [PATCH 0708/1664] Test --- iguana/exchanges/LP_utxos.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/iguana/exchanges/LP_utxos.c b/iguana/exchanges/LP_utxos.c index 770b84b89..8991e141c 100644 --- a/iguana/exchanges/LP_utxos.c +++ b/iguana/exchanges/LP_utxos.c @@ -238,11 +238,11 @@ struct LP_utxoinfo *LP_utxo_bestfit(char *symbol,uint64_t destsatoshis) // jl777 remove mempool HASH_ITER(hh,G.LP_utxoinfos[iambob],utxo,tmp) { - //char str[65]; printf("s%u %d [%.8f vs %.8f] check %s.%s avail.%d ismine.%d >= %d\n",utxo->T.spentflag,LP_iseligible(&srcvalue,&srcvalue2,utxo->iambob,symbol,utxo->payment.txid,utxo->payment.vout,utxo->S.satoshis,utxo->fee.txid,utxo->fee.vout),dstr(destsatoshis),dstr(utxo->S.satoshis),utxo->coin,bits256_str(str,utxo->payment.txid),LP_isavailable(utxo) > 0,LP_ismine(utxo) > 0,utxo->S.satoshis >= destsatoshis); if ( strcmp(symbol,utxo->coin) != 0 ) continue; if ( LP_isavailable(utxo) > 0 && LP_ismine(utxo) > 0 ) { + char str[65]; printf("s%u %d [%.8f vs %.8f] check %s.%s avail.%d ismine.%d >= %d\n",utxo->T.spentflag,LP_iseligible(&srcvalue,&srcvalue2,utxo->iambob,symbol,utxo->payment.txid,utxo->payment.vout,utxo->S.satoshis,utxo->fee.txid,utxo->fee.vout),dstr(destsatoshis),dstr(utxo->S.satoshis),utxo->coin,bits256_str(str,utxo->payment.txid),LP_isavailable(utxo) > 0,LP_ismine(utxo) > 0,utxo->S.satoshis >= destsatoshis); bestsize = 0; if ( bestutxo == 0 ) { @@ -273,7 +273,7 @@ struct LP_utxoinfo *LP_utxo_bestfit(char *symbol,uint64_t destsatoshis) continue; } bestutxo = utxo; - } // else printf("skip alice utxo %.8f vs dest %.8f\n",dstr(utxo->S.satoshis),dstr(destsatoshis)); + } else printf("skip alice utxo %.8f vs dest %.8f, bestsize.%d\n",dstr(utxo->S.satoshis),dstr(destsatoshis),bestsize); } } return(bestutxo); From ca4c233201dade6d1931de95ba23cae4fa7e7607 Mon Sep 17 00:00:00 2001 From: jl777 Date: Mon, 13 Nov 2017 23:55:49 +0200 Subject: [PATCH 0709/1664] Test --- iguana/exchanges/LP_ordermatch.c | 1 + iguana/exchanges/LP_utxos.c | 3 ++- 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/iguana/exchanges/LP_ordermatch.c b/iguana/exchanges/LP_ordermatch.c index cb9a88bf9..47fc78296 100644 --- a/iguana/exchanges/LP_ordermatch.c +++ b/iguana/exchanges/LP_ordermatch.c @@ -1125,6 +1125,7 @@ char *LP_autobuy(void *ctx,char *myipaddr,int32_t mypubsock,char *base,char *rel destsatoshis = SATOSHIDEN * relvolume; if ( (autxo= LP_utxo_bestfit(rel,destsatoshis + 2*desttxfee)) == 0 ) return(clonestr("{\"error\":\"cant find alice utxo that is big enough\"}")); + printf("bestfit selected alice (%.8f %.8f) for %.8f sats %.8f\n",dstr(autxo->payment.value),dstr(autxo->fee.value),dstr(destsatoshis),dstr(autxo->S.satoshis)); if ( destsatoshis - desttxfee < autxo->S.satoshis ) { destsatoshis -= desttxfee; diff --git a/iguana/exchanges/LP_utxos.c b/iguana/exchanges/LP_utxos.c index 8991e141c..0a5546d5e 100644 --- a/iguana/exchanges/LP_utxos.c +++ b/iguana/exchanges/LP_utxos.c @@ -266,6 +266,7 @@ struct LP_utxoinfo *LP_utxo_bestfit(char *symbol,uint64_t destsatoshis) } if ( bestsize > 0 ) { + printf("bestsize.%d %.8f %.8f\n",dstr(utxo->payment.value),dstr(utxo->fee.value),dstr(utxo->S.satoshis)); if ( LP_iseligible(&srcvalue,&srcvalue2,utxo->iambob,symbol,utxo->payment.txid,utxo->payment.vout,utxo->S.satoshis,utxo->fee.txid,utxo->fee.vout) == 0 ) { //if ( utxo->T.spentflag == 0 ) @@ -273,7 +274,7 @@ struct LP_utxoinfo *LP_utxo_bestfit(char *symbol,uint64_t destsatoshis) continue; } bestutxo = utxo; - } else printf("skip alice utxo %.8f vs dest %.8f, bestsize.%d\n",dstr(utxo->S.satoshis),dstr(destsatoshis),bestsize); + } else printf("skip alice utxo %.8f vs dest %.8f, bestsize.%d %p\n",dstr(utxo->S.satoshis),dstr(destsatoshis),bestsize,bestutxo); } } return(bestutxo); From f4d9d95f7a6dd9a7eb02836125d2fa3c8a5b7d89 Mon Sep 17 00:00:00 2001 From: jl777 Date: Mon, 13 Nov 2017 23:59:18 +0200 Subject: [PATCH 0710/1664] Test --- iguana/exchanges/LP_utxos.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/iguana/exchanges/LP_utxos.c b/iguana/exchanges/LP_utxos.c index 0a5546d5e..96a20984e 100644 --- a/iguana/exchanges/LP_utxos.c +++ b/iguana/exchanges/LP_utxos.c @@ -242,7 +242,8 @@ struct LP_utxoinfo *LP_utxo_bestfit(char *symbol,uint64_t destsatoshis) continue; if ( LP_isavailable(utxo) > 0 && LP_ismine(utxo) > 0 ) { - char str[65]; printf("s%u %d [%.8f vs %.8f] check %s.%s avail.%d ismine.%d >= %d\n",utxo->T.spentflag,LP_iseligible(&srcvalue,&srcvalue2,utxo->iambob,symbol,utxo->payment.txid,utxo->payment.vout,utxo->S.satoshis,utxo->fee.txid,utxo->fee.vout),dstr(destsatoshis),dstr(utxo->S.satoshis),utxo->coin,bits256_str(str,utxo->payment.txid),LP_isavailable(utxo) > 0,LP_ismine(utxo) > 0,utxo->S.satoshis >= destsatoshis); + printf("(%.8f %.8f %.8f)\n",dstr(utxo->payment.value),dstr(utxo->fee.value),dstr(utxo->S.satoshis)); + //char str[65]; printf("s%u %d [%.8f vs %.8f] check %s.%s avail.%d ismine.%d >= %d\n",utxo->T.spentflag,LP_iseligible(&srcvalue,&srcvalue2,utxo->iambob,symbol,utxo->payment.txid,utxo->payment.vout,utxo->S.satoshis,utxo->fee.txid,utxo->fee.vout),dstr(destsatoshis),dstr(utxo->S.satoshis),utxo->coin,bits256_str(str,utxo->payment.txid),LP_isavailable(utxo) > 0,LP_ismine(utxo) > 0,utxo->S.satoshis >= destsatoshis); bestsize = 0; if ( bestutxo == 0 ) { @@ -266,7 +267,7 @@ struct LP_utxoinfo *LP_utxo_bestfit(char *symbol,uint64_t destsatoshis) } if ( bestsize > 0 ) { - printf("bestsize.%d %.8f %.8f\n",dstr(utxo->payment.value),dstr(utxo->fee.value),dstr(utxo->S.satoshis)); + printf("bestsize.%d %.8f %.8f -> %.8f\n",bestsize,dstr(utxo->payment.value),dstr(utxo->fee.value),dstr(utxo->S.satoshis)); if ( LP_iseligible(&srcvalue,&srcvalue2,utxo->iambob,symbol,utxo->payment.txid,utxo->payment.vout,utxo->S.satoshis,utxo->fee.txid,utxo->fee.vout) == 0 ) { //if ( utxo->T.spentflag == 0 ) From 194a356815d786b2b7787bfc446a047347919433 Mon Sep 17 00:00:00 2001 From: jl777 Date: Tue, 14 Nov 2017 00:04:38 +0200 Subject: [PATCH 0711/1664] Test --- iguana/exchanges/LP_utxos.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/iguana/exchanges/LP_utxos.c b/iguana/exchanges/LP_utxos.c index 96a20984e..20aadc7a9 100644 --- a/iguana/exchanges/LP_utxos.c +++ b/iguana/exchanges/LP_utxos.c @@ -414,7 +414,7 @@ struct LP_utxoinfo *LP_utxoadd(int32_t iambob,char *symbol,bits256 txid,int32_t printf("utxoadd selector.%d spent in mempool %s vini.%d",selector,bits256_str(str,spendtxid),spendvini); utxo->T.spentflag = (uint32_t)time(NULL); } - //printf(" %s %.8f %.8f %p addutxo.%d (%s %s) session.%u iambob.%d <<<<<<<<<<<<<<<\n",symbol,dstr(value),dstr(value2),utxo,LP_ismine(utxo) > 0,bits256_str(str,utxo->payment.txid),bits256_str(str2,iambob != 0 ? utxo->deposit.txid : utxo->fee.txid),utxo->T.sessionid,iambob); + printf(" %s %.8f %.8f %p addutxo.%d (%s %s) session.%u iambob.%d <<<<<<<<<<<<<<<\n",symbol,dstr(value),dstr(value2),utxo,LP_ismine(utxo) > 0,bits256_str(str,utxo->payment.txid),bits256_str(str2,iambob != 0 ? utxo->deposit.txid : utxo->fee.txid),utxo->T.sessionid,iambob); portable_mutex_lock(&LP_utxomutex); HASH_ADD_KEYPTR(hh,G.LP_utxoinfos[iambob],utxo->key,sizeof(utxo->key),utxo); if ( _LP_utxo2find(iambob,txid2,vout2) == 0 ) From e7f594d9968a26cc64054e1a6997a68c5ee6f190 Mon Sep 17 00:00:00 2001 From: jl777 Date: Tue, 14 Nov 2017 00:11:46 +0200 Subject: [PATCH 0712/1664] Test --- iguana/exchanges/LP_utxos.c | 20 ++++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) diff --git a/iguana/exchanges/LP_utxos.c b/iguana/exchanges/LP_utxos.c index 20aadc7a9..5aa0d7554 100644 --- a/iguana/exchanges/LP_utxos.c +++ b/iguana/exchanges/LP_utxos.c @@ -414,7 +414,7 @@ struct LP_utxoinfo *LP_utxoadd(int32_t iambob,char *symbol,bits256 txid,int32_t printf("utxoadd selector.%d spent in mempool %s vini.%d",selector,bits256_str(str,spendtxid),spendvini); utxo->T.spentflag = (uint32_t)time(NULL); } - printf(" %s %.8f %.8f %p addutxo.%d (%s %s) session.%u iambob.%d <<<<<<<<<<<<<<<\n",symbol,dstr(value),dstr(value2),utxo,LP_ismine(utxo) > 0,bits256_str(str,utxo->payment.txid),bits256_str(str2,iambob != 0 ? utxo->deposit.txid : utxo->fee.txid),utxo->T.sessionid,iambob); + printf(" %s %.8f %.8f %p addutxo.%d (%s %s) session.%u iambob.%d <<<<<<<<<<<<<<< %.8f\n",symbol,dstr(value),dstr(value2),utxo,LP_ismine(utxo) > 0,bits256_str(str,utxo->payment.txid),bits256_str(str2,iambob != 0 ? utxo->deposit.txid : utxo->fee.txid),utxo->T.sessionid,iambob,dstr(satoshis)); portable_mutex_lock(&LP_utxomutex); HASH_ADD_KEYPTR(hh,G.LP_utxoinfos[iambob],utxo->key,sizeof(utxo->key),utxo); if ( _LP_utxo2find(iambob,txid2,vout2) == 0 ) @@ -538,7 +538,7 @@ int32_t LP_nearestvalue(int32_t iambob,uint64_t *values,int32_t n,uint64_t targe int32_t LP_privkey_init(int32_t mypubsock,struct iguana_info *coin,bits256 myprivkey,bits256 mypub) { int32_t enable_utxos = 0; - char *script,destaddr[64]; struct LP_utxoinfo *utxo; cJSON *array,*item; bits256 txid,deposittxid; int32_t used,i,flag=0,height,n,cmpflag,iambob,vout,depositvout; uint64_t *values=0,satoshis,txfee,depositval,value,total = 0; int64_t targetval; + char *script,destaddr[64]; struct LP_utxoinfo *utxo; cJSON *array,*item; bits256 txid,deposittxid; int32_t used,i,flag=0,height,n,cmpflag,iambob,vout,depositvout; uint64_t *values=0,satoshis,txfee,biggerval,value,total = 0; int64_t targetval; if ( coin == 0 || (IAMLP == 0 && coin->inactive != 0) ) { //printf("coin not active\n"); @@ -617,15 +617,15 @@ int32_t LP_privkey_init(int32_t mypubsock,struct iguana_info *coin,bits256 mypri depositvout = juint(item,"tx_pos"); script = coin->smartaddr; } - depositval = values[i]; + biggerval = values[i]; values[i] = 0, used++; if ( iambob == 0 ) - targetval = (depositval / 776) + txfee; - else targetval = (depositval / 9) * 8 + 2*txfee; + targetval = (biggerval / 776) + txfee; + else targetval = (biggerval / 9) * 8 + 2*txfee; if ( targetval < txfee*2 ) targetval = txfee*2; - //printf("iambob.%d i.%d deposit %.8f min %.8f target %.8f\n",iambob,i,dstr(depositval),dstr((1+LP_MINSIZE_TXFEEMULT)*txfee),dstr(targetval)); - if ( depositval < (1+LP_MINSIZE_TXFEEMULT)*txfee ) + //printf("iambob.%d i.%d deposit %.8f min %.8f target %.8f\n",iambob,i,dstr(biggerval),dstr((1+LP_MINSIZE_TXFEEMULT)*txfee),dstr(targetval)); + if ( biggerval < (1+LP_MINSIZE_TXFEEMULT)*txfee ) continue; i = -1; if ( iambob != 0 ) @@ -637,7 +637,7 @@ int32_t LP_privkey_init(int32_t mypubsock,struct iguana_info *coin,bits256 mypri } if ( i >= 0 || (i= LP_nearestvalue(iambob,values,n,targetval)) >= 0 ) { - //printf("iambob.%d i.%d %.8f target %.8f\n",iambob,i,dstr(depositval),dstr(targetval)); + //printf("iambob.%d i.%d %.8f target %.8f\n",iambob,i,dstr(biggerval),dstr(targetval)); item = jitem(array,i); cmpflag = 0; if ( coin->electrum == 0 ) @@ -660,14 +660,14 @@ int32_t LP_privkey_init(int32_t mypubsock,struct iguana_info *coin,bits256 mypri portable_mutex_lock(&LP_UTXOmutex); if ( iambob != 0 ) { - if ( (utxo= LP_utxoadd(1,coin->symbol,txid,vout,value,deposittxid,depositvout,depositval,coin->smartaddr,mypub,LP_gui,G.LP_sessionid,value)) != 0 ) + if ( (utxo= LP_utxoadd(1,coin->symbol,txid,vout,value,deposittxid,depositvout,biggerval,coin->smartaddr,mypub,LP_gui,G.LP_sessionid,value)) != 0 ) { } } else { //printf("call utxoadd\n"); - if ( (utxo= LP_utxoadd(0,coin->symbol,deposittxid,depositvout,depositval,txid,vout,value,coin->smartaddr,mypub,LP_gui,G.LP_sessionid,value)) != 0 ) + if ( (utxo= LP_utxoadd(0,coin->symbol,deposittxid,depositvout,biggerval,txid,vout,value,coin->smartaddr,mypub,LP_gui,G.LP_sessionid,biggerval)) != 0 ) { } } From 287310ae293e46098148bf1ad6fd8c0e09be564c Mon Sep 17 00:00:00 2001 From: jl777 Date: Tue, 14 Nov 2017 00:17:30 +0200 Subject: [PATCH 0713/1664] Test --- iguana/exchanges/LP_ordermatch.c | 2 +- iguana/exchanges/LP_tradebots.c | 4 ++-- iguana/exchanges/LP_utxos.c | 8 ++++---- 3 files changed, 7 insertions(+), 7 deletions(-) diff --git a/iguana/exchanges/LP_ordermatch.c b/iguana/exchanges/LP_ordermatch.c index 47fc78296..12e8dccb0 100644 --- a/iguana/exchanges/LP_ordermatch.c +++ b/iguana/exchanges/LP_ordermatch.c @@ -1125,7 +1125,7 @@ char *LP_autobuy(void *ctx,char *myipaddr,int32_t mypubsock,char *base,char *rel destsatoshis = SATOSHIDEN * relvolume; if ( (autxo= LP_utxo_bestfit(rel,destsatoshis + 2*desttxfee)) == 0 ) return(clonestr("{\"error\":\"cant find alice utxo that is big enough\"}")); - printf("bestfit selected alice (%.8f %.8f) for %.8f sats %.8f\n",dstr(autxo->payment.value),dstr(autxo->fee.value),dstr(destsatoshis),dstr(autxo->S.satoshis)); + //printf("bestfit selected alice (%.8f %.8f) for %.8f sats %.8f\n",dstr(autxo->payment.value),dstr(autxo->fee.value),dstr(destsatoshis),dstr(autxo->S.satoshis)); if ( destsatoshis - desttxfee < autxo->S.satoshis ) { destsatoshis -= desttxfee; diff --git a/iguana/exchanges/LP_tradebots.c b/iguana/exchanges/LP_tradebots.c index 1f6fa7c48..022b7d3d9 100644 --- a/iguana/exchanges/LP_tradebots.c +++ b/iguana/exchanges/LP_tradebots.c @@ -481,7 +481,7 @@ char *LP_tradebot_buy(int32_t dispdir,char *base,char *rel,double maxprice,doubl else balance = LP_RTsmartbalance(relcoin); sum = (relvolume+2*dstr(txfees)) + 3 * ((relvolume+2*dstr(txfees))/777); printf("%s inventory balance %.8f, relvolume %.8f + txfees %.8f, utxobal %.8f sum %.8f\n",rel,dstr(abalance),relvolume,dstr(txfees),dstr(balance),dstr(sum)); - if ( dstr(abalance) < relvolume && balance > sum+txfee ) + if ( dstr(abalance) < relvolume && balance > sum+2*txfee ) { retjson = cJSON_CreateObject(); jaddstr(retjson,"error","not enough funds"); @@ -492,7 +492,7 @@ char *LP_tradebot_buy(int32_t dispdir,char *base,char *rel,double maxprice,doubl jaddnum(retjson,"txfees",dstr(txfees)); shortfall = (relvolume + dstr(txfees)) - dstr(balance); jaddnum(retjson,"shortfall",shortfall); - if ( balance >= sum+txfee ) + if ( balance > sum+2*txfee ) { char *withdrawstr; cJSON *outputjson,*withdrawjson,*outputs,*item; outputjson = cJSON_CreateObject(); diff --git a/iguana/exchanges/LP_utxos.c b/iguana/exchanges/LP_utxos.c index 5aa0d7554..b24c47ff3 100644 --- a/iguana/exchanges/LP_utxos.c +++ b/iguana/exchanges/LP_utxos.c @@ -242,7 +242,7 @@ struct LP_utxoinfo *LP_utxo_bestfit(char *symbol,uint64_t destsatoshis) continue; if ( LP_isavailable(utxo) > 0 && LP_ismine(utxo) > 0 ) { - printf("(%.8f %.8f %.8f)\n",dstr(utxo->payment.value),dstr(utxo->fee.value),dstr(utxo->S.satoshis)); + //printf("(%.8f %.8f %.8f)\n",dstr(utxo->payment.value),dstr(utxo->fee.value),dstr(utxo->S.satoshis)); //char str[65]; printf("s%u %d [%.8f vs %.8f] check %s.%s avail.%d ismine.%d >= %d\n",utxo->T.spentflag,LP_iseligible(&srcvalue,&srcvalue2,utxo->iambob,symbol,utxo->payment.txid,utxo->payment.vout,utxo->S.satoshis,utxo->fee.txid,utxo->fee.vout),dstr(destsatoshis),dstr(utxo->S.satoshis),utxo->coin,bits256_str(str,utxo->payment.txid),LP_isavailable(utxo) > 0,LP_ismine(utxo) > 0,utxo->S.satoshis >= destsatoshis); bestsize = 0; if ( bestutxo == 0 ) @@ -267,7 +267,7 @@ struct LP_utxoinfo *LP_utxo_bestfit(char *symbol,uint64_t destsatoshis) } if ( bestsize > 0 ) { - printf("bestsize.%d %.8f %.8f -> %.8f\n",bestsize,dstr(utxo->payment.value),dstr(utxo->fee.value),dstr(utxo->S.satoshis)); + //printf("bestsize.%d %.8f %.8f -> %.8f\n",bestsize,dstr(utxo->payment.value),dstr(utxo->fee.value),dstr(utxo->S.satoshis)); if ( LP_iseligible(&srcvalue,&srcvalue2,utxo->iambob,symbol,utxo->payment.txid,utxo->payment.vout,utxo->S.satoshis,utxo->fee.txid,utxo->fee.vout) == 0 ) { //if ( utxo->T.spentflag == 0 ) @@ -275,7 +275,7 @@ struct LP_utxoinfo *LP_utxo_bestfit(char *symbol,uint64_t destsatoshis) continue; } bestutxo = utxo; - } else printf("skip alice utxo %.8f vs dest %.8f, bestsize.%d %p\n",dstr(utxo->S.satoshis),dstr(destsatoshis),bestsize,bestutxo); + } //else printf("skip alice utxo %.8f vs dest %.8f, bestsize.%d %p\n",dstr(utxo->S.satoshis),dstr(destsatoshis),bestsize,bestutxo); } } return(bestutxo); @@ -414,7 +414,7 @@ struct LP_utxoinfo *LP_utxoadd(int32_t iambob,char *symbol,bits256 txid,int32_t printf("utxoadd selector.%d spent in mempool %s vini.%d",selector,bits256_str(str,spendtxid),spendvini); utxo->T.spentflag = (uint32_t)time(NULL); } - printf(" %s %.8f %.8f %p addutxo.%d (%s %s) session.%u iambob.%d <<<<<<<<<<<<<<< %.8f\n",symbol,dstr(value),dstr(value2),utxo,LP_ismine(utxo) > 0,bits256_str(str,utxo->payment.txid),bits256_str(str2,iambob != 0 ? utxo->deposit.txid : utxo->fee.txid),utxo->T.sessionid,iambob,dstr(satoshis)); + //printf(" %s %.8f %.8f %p addutxo.%d (%s %s) session.%u iambob.%d <<<<<<<<<<<<<<< %.8f\n",symbol,dstr(value),dstr(value2),utxo,LP_ismine(utxo) > 0,bits256_str(str,utxo->payment.txid),bits256_str(str2,iambob != 0 ? utxo->deposit.txid : utxo->fee.txid),utxo->T.sessionid,iambob,dstr(satoshis)); portable_mutex_lock(&LP_utxomutex); HASH_ADD_KEYPTR(hh,G.LP_utxoinfos[iambob],utxo->key,sizeof(utxo->key),utxo); if ( _LP_utxo2find(iambob,txid2,vout2) == 0 ) From f892e94d3bd43470ec2d012a611b280d6b1a2ae6 Mon Sep 17 00:00:00 2001 From: jl777 Date: Tue, 14 Nov 2017 00:21:43 +0200 Subject: [PATCH 0714/1664] Test --- crypto777/iguana_utils.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/crypto777/iguana_utils.c b/crypto777/iguana_utils.c index 153cd4529..8d461fa13 100755 --- a/crypto777/iguana_utils.c +++ b/crypto777/iguana_utils.c @@ -446,6 +446,7 @@ char *clonestr(char *str) return(clone); } +int32_t zeroval() { return(0); } int32_t safecopy(char *dest,char *src,long len) { @@ -459,6 +460,7 @@ int32_t safecopy(char *dest,char *src,long len) if ( i == len ) { printf("safecopy: %s too long %ld\n",src,len); + printf("divide by zero! %d\n",1/zeroval()); #ifdef __APPLE__ //getchar(); #endif From b457e62a9b158266128ea37c2c95bd5957898985 Mon Sep 17 00:00:00 2001 From: jl777 Date: Tue, 14 Nov 2017 00:30:28 +0200 Subject: [PATCH 0715/1664] Test --- iguana/exchanges/LP_include.h | 2 +- iguana/exchanges/LP_tradebots.c | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/iguana/exchanges/LP_include.h b/iguana/exchanges/LP_include.h index cda3f0348..ce65acb43 100644 --- a/iguana/exchanges/LP_include.h +++ b/iguana/exchanges/LP_include.h @@ -43,7 +43,7 @@ void emscripten_usleep(int32_t x); // returns immediate, no sense for sleeping #define LP_MAXVINS 64 #define LP_HTTP_TIMEOUT 3 // 1 is too small due to edge cases of time(NULL) -#define LP_AUTOTRADE_TIMEOUT 30 +#define LP_AUTOTRADE_TIMEOUT 60 #define ELECTRUM_TIMEOUT 7 #define LP_ELECTRUM_KEEPALIVE 60 #define LP_ELECTRUM_MAXERRORS 777 diff --git a/iguana/exchanges/LP_tradebots.c b/iguana/exchanges/LP_tradebots.c index 022b7d3d9..ce3a6a65a 100644 --- a/iguana/exchanges/LP_tradebots.c +++ b/iguana/exchanges/LP_tradebots.c @@ -479,7 +479,7 @@ char *LP_tradebot_buy(int32_t dispdir,char *base,char *rel,double maxprice,doubl if ( relcoin->electrum != 0 ) balance = LP_unspents_load(relcoin->symbol,relcoin->smartaddr); else balance = LP_RTsmartbalance(relcoin); - sum = (relvolume+2*dstr(txfees)) + 3 * ((relvolume+2*dstr(txfees))/777); + sum = (SATOSHIDEN*relvolume+2*dstr(txfees)) + 3 * ((SATOSHIDEN*relvolume+2*dstr(txfees))/777); printf("%s inventory balance %.8f, relvolume %.8f + txfees %.8f, utxobal %.8f sum %.8f\n",rel,dstr(abalance),relvolume,dstr(txfees),dstr(balance),dstr(sum)); if ( dstr(abalance) < relvolume && balance > sum+2*txfee ) { From a93ea0a7f7a8bb094532b37cd02580b53e59e5cd Mon Sep 17 00:00:00 2001 From: jl777 Date: Tue, 14 Nov 2017 00:31:33 +0200 Subject: [PATCH 0716/1664] Test --- iguana/exchanges/LP_nativeDEX.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/iguana/exchanges/LP_nativeDEX.c b/iguana/exchanges/LP_nativeDEX.c index 0901d9c0b..430b104dd 100644 --- a/iguana/exchanges/LP_nativeDEX.c +++ b/iguana/exchanges/LP_nativeDEX.c @@ -856,8 +856,8 @@ void LP_reserved_msgs(void *ignore) if ( ignore == 0 ) break; if ( nonz != 0 ) - usleep(3000); - else usleep(25000); + usleep(1000); + else usleep(5000); } } From d7795cc3723cbead3c799c8fe43d742fa58f539a Mon Sep 17 00:00:00 2001 From: jl777 Date: Tue, 14 Nov 2017 00:39:48 +0200 Subject: [PATCH 0717/1664] Test --- iguana/exchanges/LP_signatures.c | 1 + 1 file changed, 1 insertion(+) diff --git a/iguana/exchanges/LP_signatures.c b/iguana/exchanges/LP_signatures.c index 1ac171c03..6b5643bb6 100644 --- a/iguana/exchanges/LP_signatures.c +++ b/iguana/exchanges/LP_signatures.c @@ -104,6 +104,7 @@ cJSON *LP_quotejson(struct LP_quoteinfo *qp) int32_t LP_quoteparse(struct LP_quoteinfo *qp,cJSON *argjson) { uint32_t rid,qid; + memset(qp,0,sizeof(*qp)); safecopy(qp->gui,LP_gui,sizeof(qp->gui)); safecopy(qp->srccoin,jstr(argjson,"base"),sizeof(qp->srccoin)); safecopy(qp->coinaddr,jstr(argjson,"address"),sizeof(qp->coinaddr)); From d738c7b99abdb37aeeaa03c888a56bd9536e0aa2 Mon Sep 17 00:00:00 2001 From: jl777 Date: Tue, 14 Nov 2017 00:40:07 +0200 Subject: [PATCH 0718/1664] Test --- crypto777/iguana_utils.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/crypto777/iguana_utils.c b/crypto777/iguana_utils.c index 8d461fa13..e75257149 100755 --- a/crypto777/iguana_utils.c +++ b/crypto777/iguana_utils.c @@ -460,7 +460,7 @@ int32_t safecopy(char *dest,char *src,long len) if ( i == len ) { printf("safecopy: %s too long %ld\n",src,len); - printf("divide by zero! %d\n",1/zeroval()); + //printf("divide by zero! %d\n",1/zeroval()); #ifdef __APPLE__ //getchar(); #endif From b9a5c02bdfa6c90e4f18bebc88cb63e59ede1463 Mon Sep 17 00:00:00 2001 From: jl777 Date: Tue, 14 Nov 2017 00:53:29 +0200 Subject: [PATCH 0719/1664] Test --- iguana/exchanges/LP_socket.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/iguana/exchanges/LP_socket.c b/iguana/exchanges/LP_socket.c index e200c5891..f345e9ab6 100644 --- a/iguana/exchanges/LP_socket.c +++ b/iguana/exchanges/LP_socket.c @@ -922,9 +922,11 @@ int32_t LP_recvfunc(struct electrum_info *ep,char *str,int32_t len) if ( item->type == idnum ) { DL_DELETE(ep->pendingQ.list,item); - *((cJSON **)stritem->retptrp) = (resultjson != 0 ? jduplicate(resultjson) : jduplicate(strjson)); + if ( resultjson != 0 ) + *((cJSON **)stritem->retptrp) = jduplicate(resultjson); + else *((cJSON **)stritem->retptrp) = strjson, strjson = 0; //printf("matched idnum.%d result.(%s)\n",idnum,jprint(*((cJSON **)stritem->retptrp),0)); - resultjson = strjson = 0; + //resultjson = strjson = 0; free(item); break; } From bcf793e545f9304ad315cc74930d277a53992490 Mon Sep 17 00:00:00 2001 From: jl777 Date: Tue, 14 Nov 2017 01:10:50 +0200 Subject: [PATCH 0720/1664] Test --- iguana/exchanges/LP_include.h | 2 +- iguana/exchanges/LP_remember.c | 12 ++-- iguana/exchanges/LP_swap.c | 94 +++++++++++++++---------------- iguana/exchanges/LP_transaction.c | 78 ++++++++++++------------- 4 files changed, 93 insertions(+), 93 deletions(-) diff --git a/iguana/exchanges/LP_include.h b/iguana/exchanges/LP_include.h index ce65acb43..ec9a2eca5 100644 --- a/iguana/exchanges/LP_include.h +++ b/iguana/exchanges/LP_include.h @@ -347,7 +347,7 @@ struct LP_endpoint { int32_t pair; char ipaddr[64]; uint16_t port; }; struct basilisk_swap { - void *ctx; struct iguana_info bobcoin,alicecoin; struct LP_utxoinfo *utxo; + void *ctx; struct iguana_info *bobcoin,*alicecoin; struct LP_utxoinfo *utxo; struct LP_endpoint N; void (*balancingtrade)(struct basilisk_swap *swap,int32_t iambob); int32_t subsock,pushsock,connected,aliceunconf,depositunconf,paymentunconf; diff --git a/iguana/exchanges/LP_remember.c b/iguana/exchanges/LP_remember.c index 2180a498c..0820bf82b 100644 --- a/iguana/exchanges/LP_remember.c +++ b/iguana/exchanges/LP_remember.c @@ -47,10 +47,10 @@ void basilisk_dontforget(struct basilisk_swap *swap,struct basilisk_rawtx *rawtx fprintf(fp,"\",\"txid\":\"%s\"",bits256_str(str,bits256_doublesha256(0,rawtx->txbytes,rawtx->I.datalen))); if ( rawtx == &swap->bobdeposit || rawtx == &swap->bobpayment ) { - LP_swap_coinaddr(&swap->bobcoin,coinaddr,0,rawtx->txbytes,rawtx->I.datalen,0); + LP_swap_coinaddr(swap->bobcoin,coinaddr,0,rawtx->txbytes,rawtx->I.datalen,0); if ( coinaddr[0] != 0 ) { - LP_importaddress(swap->bobcoin.symbol,coinaddr); + LP_importaddress(swap->bobcoin->symbol,coinaddr); if ( rawtx == &swap->bobdeposit ) safecopy(swap->Bdeposit,coinaddr,sizeof(swap->Bdeposit)); else safecopy(swap->Bpayment,coinaddr,sizeof(swap->Bpayment)); @@ -63,16 +63,16 @@ void basilisk_dontforget(struct basilisk_swap *swap,struct basilisk_rawtx *rawtx fprintf(fp,",\"%s\":\"%s\"","Bpayment",swap->Bpayment); fprintf(fp,",\"expiration\":%u",swap->I.expiration); fprintf(fp,",\"iambob\":%d",swap->I.iambob); - fprintf(fp,",\"bobcoin\":\"%s\"",swap->bobcoin.symbol); - fprintf(fp,",\"alicecoin\":\"%s\"",swap->alicecoin.symbol); + fprintf(fp,",\"bobcoin\":\"%s\"",swap->bobcoin->symbol); + fprintf(fp,",\"alicecoin\":\"%s\"",swap->alicecoin->symbol); fprintf(fp,",\"lock\":%u",locktime); fprintf(fp,",\"amount\":%.8f",dstr(rawtx->I.amount)); if ( bits256_nonz(triggertxid) != 0 ) fprintf(fp,",\"trigger\":\"%s\"",bits256_str(str,triggertxid)); if ( bits256_nonz(swap->I.pubAm) != 0 && bits256_nonz(swap->I.pubBn) != 0 ) { - basilisk_alicescript(redeemscript,&len,script,0,coinaddr,swap->alicecoin.taddr,swap->alicecoin.p2shtype,swap->I.pubAm,swap->I.pubBn); - LP_importaddress(swap->alicecoin.symbol,coinaddr); + basilisk_alicescript(redeemscript,&len,script,0,coinaddr,swap->alicecoin->taddr,swap->alicecoin->p2shtype,swap->I.pubAm,swap->I.pubBn); + LP_importaddress(swap->alicecoin->symbol,coinaddr); fprintf(fp,",\"Apayment\":\"%s\"",coinaddr); } if ( rawtx->I.redeemlen > 0 ) diff --git a/iguana/exchanges/LP_swap.c b/iguana/exchanges/LP_swap.c index fb6adf940..e803f48fd 100644 --- a/iguana/exchanges/LP_swap.c +++ b/iguana/exchanges/LP_swap.c @@ -620,9 +620,9 @@ int32_t LP_rawtx_spendscript(struct basilisk_swap *swap,int32_t height,struct ba txfee = LP_MIN_TXFEE; else { - if ( strcmp(rawtx->coin->symbol,swap->bobcoin.symbol) == 0 ) + if ( strcmp(rawtx->coin->symbol,swap->bobcoin->symbol) == 0 ) txfee = swap->I.Btxfee; - else if ( strcmp(rawtx->coin->symbol,swap->alicecoin.symbol) == 0 ) + else if ( strcmp(rawtx->coin->symbol,swap->alicecoin->symbol) == 0 ) txfee = swap->I.Atxfee; else txfee = LP_MIN_TXFEE; } @@ -783,12 +783,12 @@ void LP_bobloop(void *_swap) printf("error bobscripts payment\n"); else { - if ( strcmp(swap->alicecoin.symbol,"BTC") == 0 ) + if ( strcmp(swap->alicecoin->symbol,"BTC") == 0 ) m = 0; 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 + 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 wait for alicepayment %s numconfs.%d %s %s\n",n,swap->alicepayment.I.destaddr,m,swap->alicecoin.symbol,bits256_str(str,swap->alicepayment.I.signedtxid)); + char str[65];printf("%d wait for alicepayment %s numconfs.%d %s %s\n",n,swap->alicepayment.I.destaddr,m,swap->alicecoin->symbol,bits256_str(str,swap->alicepayment.I.signedtxid)); sleep(10); } if ( LP_swapdata_rawtxsend(swap->N.pair,swap,0x8000,data,maxlen,&swap->bobpayment,0x4000,0) == 0 ) @@ -801,7 +801,7 @@ void LP_bobloop(void *_swap) basilisk_bobpayment_reclaim(swap,swap->I.callduration); if ( swap->N.pair >= 0 ) nn_close(swap->N.pair), swap->N.pair = -1; - LP_swapwait(swap->I.req.requestid,swap->I.req.quoteid,LP_atomic_locktime(swap->bobcoin.symbol,swap->alicecoin.symbol)*2,30); + LP_swapwait(swap->I.req.requestid,swap->I.req.quoteid,LP_atomic_locktime(swap->bobcoin->symbol,swap->alicecoin->symbol)*2,30); } } } @@ -840,12 +840,12 @@ void LP_aliceloop(void *_swap) printf("error sending alicepayment\n"); else { - if ( strcmp(swap->alicecoin.symbol,"BTC") == 0 ) + if ( strcmp(swap->alicecoin->symbol,"BTC") == 0 ) m = 0; else m = swap->I.aliceconfirms; - while ( (n= LP_numconfirms(swap->alicecoin.symbol,swap->alicepayment.I.destaddr,swap->alicepayment.I.signedtxid,0,1)) < m ) + while ( (n= LP_numconfirms(swap->alicecoin->symbol,swap->alicepayment.I.destaddr,swap->alicepayment.I.signedtxid,0,1)) < m ) { - char str[65];printf("%d wait for alicepayment %s numconfs.%d %s %s\n",n,swap->alicepayment.I.destaddr,m,swap->alicecoin.symbol,bits256_str(str,swap->alicepayment.I.signedtxid)); + char str[65];printf("%d wait for alicepayment %s numconfs.%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; @@ -853,21 +853,21 @@ void LP_aliceloop(void *_swap) printf("error waiting for bobpayment\n"); else { - while ( (n= LP_numconfirms(swap->bobcoin.symbol,swap->bobpayment.I.destaddr,swap->bobpayment.I.signedtxid,0,1)) < swap->I.bobconfirms ) + while ( (n= LP_numconfirms(swap->bobcoin->symbol,swap->bobpayment.I.destaddr,swap->bobpayment.I.signedtxid,0,1)) < swap->I.bobconfirms ) { - char str[65];printf("%d wait for bobpayment %s numconfs.%d %s %s\n",n,swap->bobpayment.I.destaddr,swap->I.bobconfirms,swap->bobcoin.symbol,bits256_str(str,swap->bobpayment.I.signedtxid)); + char str[65];printf("%d wait for bobpayment %s numconfs.%d %s %s\n",n,swap->bobpayment.I.destaddr,swap->I.bobconfirms,swap->bobcoin->symbol,bits256_str(str,swap->bobpayment.I.signedtxid)); sleep(10); } /*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 ) + 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 wait for alicespend %s numconfs.%d %s %s\n",n,swap->alicespend.I.destaddr,swap->I.aliceconfirms,swap->bobcoin.symbol,bits256_str(str,swap->alicespend.I.signedtxid)); + char str[65];printf("%d wait for alicespend %s numconfs.%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,LP_atomic_locktime(swap->bobcoin.symbol,swap->alicecoin.symbol)*2,30); + LP_swapwait(swap->I.req.requestid,swap->I.req.quoteid,LP_atomic_locktime(swap->bobcoin->symbol,swap->alicecoin->symbol)*2,30); } } } @@ -1009,7 +1009,7 @@ struct basilisk_swap *bitcoin_swapinit(bits256 privkey,uint8_t *pubkey33,bits256 printf("bitcoin_swapinit %s Btxfee %.8f rejected\n",swap->I.req.src,dstr(swap->I.Btxfee)); return(0); } - swap->I.putduration = swap->I.callduration = LP_atomic_locktime(swap->bobcoin.symbol,swap->alicecoin.symbol); + swap->I.putduration = swap->I.callduration = LP_atomic_locktime(swap->bobcoin->symbol,swap->alicecoin->symbol); if ( optionduration < 0 ) swap->I.putduration -= optionduration; else if ( optionduration > 0 ) @@ -1058,27 +1058,27 @@ struct basilisk_swap *bitcoin_swapinit(bits256 privkey,uint8_t *pubkey33,bits256 return(0); } if ( (coin= LP_coinfind(swap->I.alicestr)) != 0 ) - swap->alicecoin = *coin; + swap->alicecoin = coin; else { - printf("missing bobcoin.%p or missing alicecoin.%p src.%p dest.%p\n",&swap->bobcoin,&swap->alicecoin,LP_coinfind(swap->I.req.src),LP_coinfind(swap->I.req.dest)); + printf("missing bobcoin->%p or missing alicecoin->%p src.%p dest.%p\n",swap->bobcoin,swap->alicecoin,LP_coinfind(swap->I.req.src),LP_coinfind(swap->I.req.dest)); free(swap); return(0); } if ( (coin= LP_coinfind(swap->I.bobstr)) != 0 ) - swap->bobcoin = *coin; + swap->bobcoin = coin; else { - printf("missing bobcoin.%p or missing alicecoin.%p src.%p dest.%p\n",&swap->bobcoin,&swap->alicecoin,LP_coinfind(swap->I.req.src),LP_coinfind(swap->I.req.dest)); + printf("missing bobcoin->%p or missing alicecoin->%p src.%p dest.%p\n",swap->bobcoin,swap->alicecoin,LP_coinfind(swap->I.req.src),LP_coinfind(swap->I.req.dest)); free(swap); return(0); } - if ( strcmp("BTC",swap->bobcoin.symbol) == 0 ) + if ( strcmp("BTC",swap->bobcoin->symbol) == 0 ) { swap->I.bobconfirms = (1 + sqrt(dstr(swap->I.bobsatoshis) * .1)); swap->I.aliceconfirms = BASILISK_DEFAULT_NUMCONFIRMS; } - else if ( strcmp("BTC",swap->alicecoin.symbol) == 0 ) + else if ( strcmp("BTC",swap->alicecoin->symbol) == 0 ) { swap->I.aliceconfirms = (1 + sqrt(dstr(swap->I.alicesatoshis) * .1)); swap->I.bobconfirms = BASILISK_DEFAULT_NUMCONFIRMS; @@ -1088,17 +1088,17 @@ struct basilisk_swap *bitcoin_swapinit(bits256 privkey,uint8_t *pubkey33,bits256 swap->I.bobconfirms = BASILISK_DEFAULT_NUMCONFIRMS; swap->I.aliceconfirms = BASILISK_DEFAULT_NUMCONFIRMS; } - if ( swap->bobcoin.isassetchain != 0 ) + if ( swap->bobcoin->isassetchain != 0 ) swap->I.bobconfirms = 1; - if ( swap->alicecoin.isassetchain != 0 ) + 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 ) + 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 ) + 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; @@ -1106,51 +1106,51 @@ struct basilisk_swap *bitcoin_swapinit(bits256 privkey,uint8_t *pubkey33,bits256 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); + 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 ) { - basilisk_rawtx_setparms("myfee",swap->I.req.quoteid,&swap->myfee,&swap->bobcoin,0,0,LP_DEXFEE(swap->I.bobsatoshis) + 0*swap->bobcoin.txfee,0,0,jumblrflag); - basilisk_rawtx_setparms("otherfee",swap->I.req.quoteid,&swap->otherfee,&swap->alicecoin,0,0,LP_DEXFEE(swap->I.alicesatoshis) + 0*swap->alicecoin.txfee,0,0,jumblrflag); + basilisk_rawtx_setparms("myfee",swap->I.req.quoteid,&swap->myfee,swap->bobcoin,0,0,LP_DEXFEE(swap->I.bobsatoshis) + 0*swap->bobcoin->txfee,0,0,jumblrflag); + basilisk_rawtx_setparms("otherfee",swap->I.req.quoteid,&swap->otherfee,swap->alicecoin,0,0,LP_DEXFEE(swap->I.alicesatoshis) + 0*swap->alicecoin->txfee,0,0,jumblrflag); bobpub33 = pubkey33; } else { - basilisk_rawtx_setparms("otherfee",swap->I.req.quoteid,&swap->otherfee,&swap->bobcoin,0,0,LP_DEXFEE(swap->I.bobsatoshis) + 0*swap->bobcoin.txfee,0,0,jumblrflag); - basilisk_rawtx_setparms("myfee",swap->I.req.quoteid,&swap->myfee,&swap->alicecoin,0,0,LP_DEXFEE(swap->I.alicesatoshis) + 0*swap->alicecoin.txfee,0,0,jumblrflag); + basilisk_rawtx_setparms("otherfee",swap->I.req.quoteid,&swap->otherfee,swap->bobcoin,0,0,LP_DEXFEE(swap->I.bobsatoshis) + 0*swap->bobcoin->txfee,0,0,jumblrflag); + basilisk_rawtx_setparms("myfee",swap->I.req.quoteid,&swap->myfee,swap->alicecoin,0,0,LP_DEXFEE(swap->I.alicesatoshis) + 0*swap->alicecoin->txfee,0,0,jumblrflag); alicepub33 = pubkey33; } swap->myfee.I.locktime = swap->I.started + 1; swap->otherfee.I.locktime = swap->I.started + 1; - basilisk_rawtx_setparms("bobdeposit",swap->I.req.quoteid,&swap->bobdeposit,&swap->bobcoin,swap->I.bobconfirms,0,LP_DEPOSITSATOSHIS(swap->I.bobsatoshis) + swap->bobcoin.txfee,4,0,jumblrflag); - basilisk_rawtx_setparms("bobrefund",swap->I.req.quoteid,&swap->bobrefund,&swap->bobcoin,1,4,LP_DEPOSITSATOSHIS(swap->I.bobsatoshis),1,bobpub33,jumblrflag); + basilisk_rawtx_setparms("bobdeposit",swap->I.req.quoteid,&swap->bobdeposit,swap->bobcoin,swap->I.bobconfirms,0,LP_DEPOSITSATOSHIS(swap->I.bobsatoshis) + swap->bobcoin->txfee,4,0,jumblrflag); + basilisk_rawtx_setparms("bobrefund",swap->I.req.quoteid,&swap->bobrefund,swap->bobcoin,1,4,LP_DEPOSITSATOSHIS(swap->I.bobsatoshis),1,bobpub33,jumblrflag); swap->bobrefund.I.suppress_pubkeys = 1; - basilisk_rawtx_setparms("aliceclaim",swap->I.req.quoteid,&swap->aliceclaim,&swap->bobcoin,1,4,LP_DEPOSITSATOSHIS(swap->I.bobsatoshis),1,alicepub33,jumblrflag); + basilisk_rawtx_setparms("aliceclaim",swap->I.req.quoteid,&swap->aliceclaim,swap->bobcoin,1,4,LP_DEPOSITSATOSHIS(swap->I.bobsatoshis),1,alicepub33,jumblrflag); swap->aliceclaim.I.suppress_pubkeys = 1; swap->aliceclaim.I.locktime = swap->I.started + swap->I.putduration+swap->I.callduration + 1; - basilisk_rawtx_setparms("bobpayment",swap->I.req.quoteid,&swap->bobpayment,&swap->bobcoin,swap->I.bobconfirms,0,swap->I.bobsatoshis + swap->bobcoin.txfee,3,0,jumblrflag); - basilisk_rawtx_setparms("alicespend",swap->I.req.quoteid,&swap->alicespend,&swap->bobcoin,swap->I.bobconfirms,3,swap->I.bobsatoshis,1,alicepub33,jumblrflag); + basilisk_rawtx_setparms("bobpayment",swap->I.req.quoteid,&swap->bobpayment,swap->bobcoin,swap->I.bobconfirms,0,swap->I.bobsatoshis + swap->bobcoin->txfee,3,0,jumblrflag); + basilisk_rawtx_setparms("alicespend",swap->I.req.quoteid,&swap->alicespend,swap->bobcoin,swap->I.bobconfirms,3,swap->I.bobsatoshis,1,alicepub33,jumblrflag); swap->alicespend.I.suppress_pubkeys = 1; - basilisk_rawtx_setparms("bobreclaim",swap->I.req.quoteid,&swap->bobreclaim,&swap->bobcoin,swap->I.bobconfirms,3,swap->I.bobsatoshis,1,bobpub33,jumblrflag); + basilisk_rawtx_setparms("bobreclaim",swap->I.req.quoteid,&swap->bobreclaim,swap->bobcoin,swap->I.bobconfirms,3,swap->I.bobsatoshis,1,bobpub33,jumblrflag); swap->bobreclaim.I.suppress_pubkeys = 1; swap->bobreclaim.I.locktime = swap->I.started + swap->I.putduration + 1; - basilisk_rawtx_setparms("alicepayment",swap->I.req.quoteid,&swap->alicepayment,&swap->alicecoin,swap->I.aliceconfirms,0,swap->I.alicesatoshis + swap->alicecoin.txfee,2,0,jumblrflag); - basilisk_rawtx_setparms("bobspend",swap->I.req.quoteid,&swap->bobspend,&swap->alicecoin,swap->I.aliceconfirms,2,swap->I.alicesatoshis,1,bobpub33,jumblrflag); + basilisk_rawtx_setparms("alicepayment",swap->I.req.quoteid,&swap->alicepayment,swap->alicecoin,swap->I.aliceconfirms,0,swap->I.alicesatoshis + swap->alicecoin->txfee,2,0,jumblrflag); + basilisk_rawtx_setparms("bobspend",swap->I.req.quoteid,&swap->bobspend,swap->alicecoin,swap->I.aliceconfirms,2,swap->I.alicesatoshis,1,bobpub33,jumblrflag); swap->bobspend.I.suppress_pubkeys = 1; - basilisk_rawtx_setparms("alicereclaim",swap->I.req.quoteid,&swap->alicereclaim,&swap->alicecoin,swap->I.aliceconfirms,2,swap->I.alicesatoshis,1,alicepub33,jumblrflag); + basilisk_rawtx_setparms("alicereclaim",swap->I.req.quoteid,&swap->alicereclaim,swap->alicecoin,swap->I.aliceconfirms,2,swap->I.alicesatoshis,1,alicepub33,jumblrflag); swap->alicereclaim.I.suppress_pubkeys = 1; swap->bobpayment.utxotxid = qp->txid, swap->bobpayment.utxovout = qp->vout; swap->bobdeposit.utxotxid = qp->txid2, swap->bobdeposit.utxovout = qp->vout2; swap->alicepayment.utxotxid = qp->desttxid, swap->alicepayment.utxovout = qp->destvout; - LP_mark_spent(swap->bobcoin.symbol,qp->txid,qp->vout); - LP_mark_spent(swap->bobcoin.symbol,qp->txid2,qp->vout2); - LP_mark_spent(swap->alicecoin.symbol,qp->desttxid,qp->destvout); + LP_mark_spent(swap->bobcoin->symbol,qp->txid,qp->vout); + LP_mark_spent(swap->bobcoin->symbol,qp->txid2,qp->vout2); + LP_mark_spent(swap->alicecoin->symbol,qp->desttxid,qp->destvout); if ( swap->I.iambob != 0 ) swap->otherfee.utxotxid = qp->feetxid, swap->otherfee.utxovout = qp->feevout; else { swap->myfee.utxotxid = qp->feetxid, swap->myfee.utxovout = qp->feevout; - LP_mark_spent(swap->alicecoin.symbol,qp->feetxid,qp->feevout); + LP_mark_spent(swap->alicecoin->symbol,qp->feetxid,qp->feevout); } char str[65],str2[65],str3[65]; printf("IAMBOB.%d %s %s %s\n",swap->I.iambob,bits256_str(str,qp->txid),bits256_str(str2,qp->txid2),bits256_str(str3,qp->feetxid)); return(swap); diff --git a/iguana/exchanges/LP_transaction.c b/iguana/exchanges/LP_transaction.c index 661319305..54c3045c0 100644 --- a/iguana/exchanges/LP_transaction.c +++ b/iguana/exchanges/LP_transaction.c @@ -1230,7 +1230,7 @@ int32_t basilisk_rawtx_gen(void *ctx,char *str,uint32_t swapstarted,uint8_t *pub return(-1); if ( strcmp(coin->smartaddr,vinaddr) != 0 ) { - printf("basilisk_rawtx_gen mismatched vinaddr.%s != %s\n",vinaddr,coin->smartaddr); + printf("basilisk_rawtx_gen mismatched %s vinaddr.%s != (%s)\n",coin->symbol,vinaddr,coin->smartaddr); return(-1); } argjson = cJSON_CreateObject(); @@ -1613,7 +1613,7 @@ int32_t basilisk_bobpayment_reclaim(struct basilisk_swap *swap,int32_t delay) 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,swap->bobcoin.zcash)) == 0 ) + 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,swap->bobcoin->zcash)) == 0 ) { for (i=0; ibobreclaim.I.datalen; i++) printf("%02x",swap->bobreclaim.txbytes[i]); @@ -1630,7 +1630,7 @@ int32_t basilisk_bobdeposit_refund(struct basilisk_swap *swap,int32_t delay) len = basilisk_swapuserdata(userdata,swap->I.privBn,0,swap->I.myprivs[0],swap->bobdeposit.redeemscript,swap->bobdeposit.I.redeemlen); memcpy(swap->I.userdata_bobrefund,userdata,len); swap->I.userdata_bobrefundlen = 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->bobrefund,&swap->bobdeposit,swap->I.myprivs[0],0,userdata,len,0,swap->changermd160,swap->bobdeposit.I.destaddr,swap->bobcoin.zcash)) == 0 ) + 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->bobrefund,&swap->bobdeposit,swap->I.myprivs[0],0,userdata,len,0,swap->changermd160,swap->bobdeposit.I.destaddr,swap->bobcoin->zcash)) == 0 ) { for (i=0; ibobrefund.I.datalen; i++) printf("%02x",swap->bobrefund.txbytes[i]); @@ -1674,15 +1674,15 @@ void LP_swap_coinaddr(struct iguana_info *coin,char *coinaddr,uint64_t *valuep,u int32_t basilisk_bobscripts_set(struct basilisk_swap *swap,int32_t depositflag,int32_t genflag) { int32_t j; char coinaddr[64],checkaddr[64]; - bitcoin_address(coinaddr,swap->bobcoin.taddr,swap->bobcoin.pubtype,swap->changermd160,20); + bitcoin_address(coinaddr,swap->bobcoin->taddr,swap->bobcoin->pubtype,swap->changermd160,20); if ( genflag != 0 && swap->I.iambob == 0 ) printf("basilisk_bobscripts_set WARNING: alice generating BOB tx\n"); if ( depositflag == 0 ) { swap->bobpayment.I.spendlen = basilisk_bobscript(swap->bobpayment.I.rmd160,swap->bobpayment.redeemscript,&swap->bobpayment.I.redeemlen,swap->bobpayment.spendscript,0,&swap->bobpayment.I.locktime,&swap->bobpayment.I.secretstart,&swap->I,0); - bitcoin_address(swap->bobpayment.p2shaddr,swap->bobcoin.taddr,swap->bobcoin.p2shtype,swap->bobpayment.redeemscript,swap->bobpayment.I.redeemlen); + bitcoin_address(swap->bobpayment.p2shaddr,swap->bobcoin->taddr,swap->bobcoin->p2shtype,swap->bobpayment.redeemscript,swap->bobpayment.I.redeemlen); strcpy(swap->bobpayment.I.destaddr,swap->bobpayment.p2shaddr); - //LP_importaddress(swap->bobcoin.symbol,swap->bobpayment.I.destaddr); + //LP_importaddress(swap->bobcoin->symbol,swap->bobpayment.I.destaddr); //int32_t i; for (i=0; ibobpayment.I.redeemlen; i++) // printf("%02x",swap->bobpayment.redeemscript[i]); //printf(" <- bobpayment redeem %d %s\n",i,swap->bobpayment.I.destaddr); @@ -1703,13 +1703,13 @@ int32_t basilisk_bobscripts_set(struct basilisk_swap *swap,int32_t depositflag,i printf("%02x",swap->bobpayment.redeemscript[j]); printf(" <- redeem.%d\n",swap->bobpayment.I.redeemlen); printf(" <- GENERATED BOB PAYMENT.%d destaddr.(%s)\n",swap->bobpayment.I.datalen,swap->bobpayment.I.destaddr); - LP_swap_coinaddr(&swap->bobcoin,checkaddr,0,swap->bobpayment.txbytes,swap->bobpayment.I.datalen,0); + LP_swap_coinaddr(swap->bobcoin,checkaddr,0,swap->bobpayment.txbytes,swap->bobpayment.I.datalen,0); if ( strcmp(swap->bobpayment.I.destaddr,checkaddr) != 0 ) { printf("BOBPAYMENT REDEEMADDR MISMATCH??? %s != %s\n",swap->bobpayment.I.destaddr,checkaddr); return(-1); } - LP_unspents_mark(swap->bobcoin.symbol,swap->bobpayment.vins); + LP_unspents_mark(swap->bobcoin->symbol,swap->bobpayment.vins); //printf("bobscripts set completed\n"); return(0); } @@ -1718,7 +1718,7 @@ int32_t basilisk_bobscripts_set(struct basilisk_swap *swap,int32_t depositflag,i else { swap->bobdeposit.I.spendlen = basilisk_bobscript(swap->bobdeposit.I.rmd160,swap->bobdeposit.redeemscript,&swap->bobdeposit.I.redeemlen,swap->bobdeposit.spendscript,0,&swap->bobdeposit.I.locktime,&swap->bobdeposit.I.secretstart,&swap->I,1); - bitcoin_address(swap->bobdeposit.p2shaddr,swap->bobcoin.taddr,swap->bobcoin.p2shtype,swap->bobdeposit.redeemscript,swap->bobdeposit.I.redeemlen); + bitcoin_address(swap->bobdeposit.p2shaddr,swap->bobcoin->taddr,swap->bobcoin->p2shtype,swap->bobdeposit.redeemscript,swap->bobdeposit.I.redeemlen); strcpy(swap->bobdeposit.I.destaddr,swap->bobdeposit.p2shaddr); //int32_t i; for (i=0; ibobdeposit.I.redeemlen; i++) // printf("%02x",swap->bobdeposit.redeemscript[i]); @@ -1736,13 +1736,13 @@ int32_t basilisk_bobscripts_set(struct basilisk_swap *swap,int32_t depositflag,i for (j=0; jbobdeposit.I.datalen; j++) printf("%02x",swap->bobdeposit.txbytes[j]); printf(" <- GENERATED BOB DEPOSIT.%d (%s)\n",swap->bobdeposit.I.datalen,swap->bobdeposit.I.destaddr); - LP_swap_coinaddr(&swap->bobcoin,checkaddr,0,swap->bobdeposit.txbytes,swap->bobdeposit.I.datalen,0); + LP_swap_coinaddr(swap->bobcoin,checkaddr,0,swap->bobdeposit.txbytes,swap->bobdeposit.I.datalen,0); if ( strcmp(swap->bobdeposit.I.destaddr,checkaddr) != 0 ) { printf("BOBDEPOSIT REDEEMADDR MISMATCH??? %s != %s\n",swap->bobdeposit.I.destaddr,checkaddr); return(-1); } - LP_unspents_mark(swap->bobcoin.symbol,swap->bobdeposit.vins); + LP_unspents_mark(swap->bobcoin->symbol,swap->bobdeposit.vins); printf("bobscripts set completed\n"); return(0); } @@ -1758,7 +1758,7 @@ int32_t basilisk_alicepayment_spend(struct basilisk_swap *swap,struct basilisk_r { int32_t i,retval; printf("alicepayment_spend\n"); - swap->alicepayment.I.spendlen = basilisk_alicescript(swap->alicepayment.redeemscript,&swap->alicepayment.I.redeemlen,swap->alicepayment.spendscript,0,swap->alicepayment.I.destaddr,swap->alicecoin.p2shtype,swap->I.pubAm,swap->I.pubBn); + swap->alicepayment.I.spendlen = basilisk_alicescript(swap->alicepayment.redeemscript,&swap->alicepayment.I.redeemlen,swap->alicepayment.spendscript,0,swap->alicepayment.I.destaddr,swap->alicecoin->p2shtype,swap->I.pubAm,swap->I.pubBn); printf("alicepayment_spend len.%d\n",swap->alicepayment.I.spendlen); if ( swap->I.iambob == 0 ) { @@ -1770,7 +1770,7 @@ int32_t basilisk_alicepayment_spend(struct basilisk_swap *swap,struct basilisk_r memcpy(swap->I.userdata_bobspend,swap->alicepayment.redeemscript,swap->alicepayment.I.spendlen); swap->I.userdata_bobspendlen = swap->alicepayment.I.spendlen; } - if ( (retval= basilisk_rawtx_sign(swap->alicecoin.symbol,swap->alicecoin.pubtype,swap->alicecoin.p2shtype,swap->alicecoin.isPoS,swap->alicecoin.wiftype,swap,dest,&swap->alicepayment,swap->I.privAm,&swap->I.privBn,0,0,1,swap->changermd160)) == 0 ) + if ( (retval= basilisk_rawtx_sign(swap->alicecoin->symbol,swap->alicecoin->pubtype,swap->alicecoin->p2shtype,swap->alicecoin->isPoS,swap->alicecoin->wiftype,swap,dest,&swap->alicepayment,swap->I.privAm,&swap->I.privBn,0,0,1,swap->changermd160)) == 0 ) { for (i=0; iI.datalen; i++) printf("%02x",dest->txbytes[i]); @@ -1802,26 +1802,26 @@ int32_t basilisk_alicetxs(int32_t pairsock,struct basilisk_swap *swap,uint8_t *d printf("error alice generating payment.%d\n",swap->alicepayment.I.spendlen); else { - bitcoin_address(swap->alicepayment.I.destaddr,swap->alicecoin.taddr,swap->alicecoin.p2shtype,swap->alicepayment.redeemscript,swap->alicepayment.I.redeemlen); - //LP_importaddress(swap->alicecoin.symbol,swap->alicepayment.I.destaddr); + bitcoin_address(swap->alicepayment.I.destaddr,swap->alicecoin->taddr,swap->alicecoin->p2shtype,swap->alicepayment.redeemscript,swap->alicepayment.I.redeemlen); + //LP_importaddress(swap->alicecoin->symbol,swap->alicepayment.I.destaddr); strcpy(swap->alicepayment.p2shaddr,swap->alicepayment.I.destaddr); retval = 0; for (i=0; ialicepayment.I.datalen; i++) printf("%02x",swap->alicepayment.txbytes[i]); printf(" ALICE PAYMENT created.(%s)\n",swap->alicepayment.I.destaddr); - LP_unspents_mark(swap->alicecoin.symbol,swap->alicepayment.vins); - //LP_importaddress(swap->alicecoin.symbol,swap->alicepayment.I.destaddr); + LP_unspents_mark(swap->alicecoin->symbol,swap->alicepayment.vins); + //LP_importaddress(swap->alicecoin->symbol,swap->alicepayment.I.destaddr); //basilisk_txlog(swap,&swap->alicepayment,-1); } if ( swap->myfee.I.datalen == 0 ) { - printf("generate fee %.8f\n",dstr(strcmp(swap->myfee.coin->symbol,"BTC") == 0 ? LP_MIN_TXFEE : swap->myfee.coin->txfee)); - bitcoin_address(coinaddr,swap->alicecoin.taddr,swap->alicecoin.pubtype,swap->changermd160,20); + printf("%s generate fee %.8f from.%s\n",swap->alicecoin->symbol,dstr(strcmp(swap->myfee.coin->symbol,"BTC") == 0 ? LP_MIN_TXFEE : swap->myfee.coin->txfee),swap->alicecoin->smartaddr); + bitcoin_address(coinaddr,swap->alicecoin->taddr,swap->alicecoin->pubtype,swap->changermd160,20); if ( basilisk_rawtx_gen(swap->ctx,"myfee",swap->I.started,swap->persistent_pubkey33,swap->I.iambob,1,&swap->myfee,swap->myfee.I.locktime,swap->myfee.spendscript,swap->myfee.I.spendlen,strcmp(swap->myfee.coin->symbol,"BTC") == 0 ? LP_MIN_TXFEE : swap->myfee.coin->txfee,1,0,swap->persistent_privkey,swap->changermd160,coinaddr) == 0 ) { printf("rawtxsend %s %.8f\n",swap->myfee.coin->symbol,dstr(strcmp(swap->myfee.coin->symbol,"BTC") == 0 ? LP_MIN_TXFEE : swap->myfee.coin->txfee)); swap->I.statebits |= LP_swapdata_rawtxsend(pairsock,swap,0x80,data,maxlen,&swap->myfee,0x40,0); - LP_unspents_mark(swap->I.iambob!=0?swap->bobcoin.symbol:swap->alicecoin.symbol,swap->myfee.vins); + LP_unspents_mark(swap->I.iambob!=0?swap->bobcoin->symbol:swap->alicecoin->symbol,swap->myfee.vins); //basilisk_txlog(swap,&swap->myfee,-1); for (i=0; imyfee.I.datalen; i++) printf("%02x",swap->myfee.txbytes[i]); @@ -1845,7 +1845,7 @@ int32_t basilisk_alicetxs(int32_t pairsock,struct basilisk_swap *swap,uint8_t *d int32_t LP_verify_otherfee(struct basilisk_swap *swap,uint8_t *data,int32_t datalen) { int32_t diff; - if ( LP_rawtx_spendscript(swap,swap->bobcoin.longestchain,&swap->otherfee,0,data,datalen,0) == 0 ) + if ( LP_rawtx_spendscript(swap,swap->bobcoin->longestchain,&swap->otherfee,0,data,datalen,0) == 0 ) { printf("otherfee amount %.8f -> %s vs %s locktime %u vs %u\n",dstr(swap->otherfee.I.amount),swap->otherfee.p2shaddr,swap->otherfee.I.destaddr,swap->otherfee.I.locktime,swap->I.started+1); if ( strcmp(swap->otherfee.I.destaddr,swap->otherfee.p2shaddr) == 0 ) @@ -1864,7 +1864,7 @@ int32_t LP_verify_otherfee(struct basilisk_swap *swap,uint8_t *data,int32_t data 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 ) + 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 ) @@ -1886,10 +1886,10 @@ int32_t LP_verify_alicespend(struct basilisk_swap *swap,uint8_t *data,int32_t da int32_t LP_verify_bobdeposit(struct basilisk_swap *swap,uint8_t *data,int32_t datalen) { uint8_t userdata[512]; int32_t retval=-1,len = 0; static bits256 zero; - if ( LP_rawtx_spendscript(swap,swap->bobcoin.longestchain,&swap->bobdeposit,0,data,datalen,0) == 0 ) + if ( LP_rawtx_spendscript(swap,swap->bobcoin->longestchain,&swap->bobdeposit,0,data,datalen,0) == 0 ) { swap->aliceclaim.utxovout = 0; - swap->bobdeposit.I.signedtxid = LP_broadcast_tx(swap->bobdeposit.name,swap->bobcoin.symbol,swap->bobdeposit.txbytes,swap->bobdeposit.I.datalen); + swap->bobdeposit.I.signedtxid = LP_broadcast_tx(swap->bobdeposit.name,swap->bobcoin->symbol,swap->bobdeposit.txbytes,swap->bobdeposit.I.datalen); if ( bits256_nonz(swap->bobdeposit.I.signedtxid) != 0 ) swap->depositunconf = 1; else swap->bobdeposit.I.signedtxid = swap->bobdeposit.I.actualtxid; @@ -1897,7 +1897,7 @@ int32_t LP_verify_bobdeposit(struct basilisk_swap *swap,uint8_t *data,int32_t da swap->aliceclaim.utxotxid = swap->bobdeposit.I.signedtxid; memcpy(swap->I.userdata_aliceclaim,userdata,len); swap->I.userdata_aliceclaimlen = len; - bitcoin_address(swap->bobdeposit.p2shaddr,swap->bobcoin.taddr,swap->bobcoin.p2shtype,swap->bobdeposit.redeemscript,swap->bobdeposit.I.redeemlen); + bitcoin_address(swap->bobdeposit.p2shaddr,swap->bobcoin->taddr,swap->bobcoin->p2shtype,swap->bobdeposit.redeemscript,swap->bobdeposit.I.redeemlen); strcpy(swap->bobdeposit.I.destaddr,swap->bobdeposit.p2shaddr); basilisk_dontforget_update(swap,&swap->bobdeposit); //int32_t i; char str[65]; for (i=0; ibobdeposit.I.datalen; i++) @@ -1909,9 +1909,9 @@ int32_t LP_verify_bobdeposit(struct basilisk_swap *swap,uint8_t *data,int32_t da memcpy(swap->aliceclaim.redeemscript,swap->bobdeposit.redeemscript,swap->bobdeposit.I.redeemlen); swap->aliceclaim.I.redeemlen = swap->bobdeposit.I.redeemlen; memcpy(swap->aliceclaim.I.pubkey33,swap->persistent_pubkey33,33); - bitcoin_address(swap->aliceclaim.I.destaddr,swap->alicecoin.taddr,swap->alicecoin.pubtype,swap->persistent_pubkey33,33); + bitcoin_address(swap->aliceclaim.I.destaddr,swap->alicecoin->taddr,swap->alicecoin->pubtype,swap->persistent_pubkey33,33); retval = 0; - 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->aliceclaim,&swap->bobdeposit,swap->I.myprivs[0],0,userdata,len,1,swap->changermd160,swap->bobdeposit.I.destaddr,swap->bobcoin.zcash)) == 0 ) + 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->aliceclaim,&swap->bobdeposit,swap->I.myprivs[0],0,userdata,len,1,swap->changermd160,swap->bobdeposit.I.destaddr,swap->bobcoin->zcash)) == 0 ) { int32_t i; for (i=0; ibobdeposit.I.datalen; i++) printf("%02x",swap->bobdeposit.txbytes[i]); @@ -1920,7 +1920,7 @@ int32_t LP_verify_bobdeposit(struct basilisk_swap *swap,uint8_t *data,int32_t da printf("%02x",swap->aliceclaim.txbytes[i]); printf(" <- aliceclaim\n"); //basilisk_txlog(swap,&swap->aliceclaim,swap->I.putduration+swap->I.callduration); - return(LP_waitmempool(swap->bobcoin.symbol,swap->bobdeposit.I.destaddr,swap->bobdeposit.I.signedtxid,0,60)); + return(LP_waitmempool(swap->bobcoin->symbol,swap->bobdeposit.I.destaddr,swap->bobdeposit.I.signedtxid,0,60)); } else printf("error signing aliceclaim suppress.%d vin.(%s)\n",swap->aliceclaim.I.suppress_pubkeys,swap->bobdeposit.I.destaddr); } printf("error with bobdeposit\n"); @@ -1929,18 +1929,18 @@ int32_t LP_verify_bobdeposit(struct basilisk_swap *swap,uint8_t *data,int32_t da int32_t LP_verify_alicepayment(struct basilisk_swap *swap,uint8_t *data,int32_t datalen) { - if ( LP_rawtx_spendscript(swap,swap->alicecoin.longestchain,&swap->alicepayment,0,data,datalen,0) == 0 ) + if ( LP_rawtx_spendscript(swap,swap->alicecoin->longestchain,&swap->alicepayment,0,data,datalen,0) == 0 ) { swap->bobspend.utxovout = 0; - swap->bobspend.utxotxid = swap->alicepayment.I.signedtxid = LP_broadcast_tx(swap->alicepayment.name,swap->alicecoin.symbol,swap->alicepayment.txbytes,swap->alicepayment.I.datalen); - bitcoin_address(swap->alicepayment.p2shaddr,swap->alicecoin.taddr,swap->alicecoin.p2shtype,swap->alicepayment.redeemscript,swap->alicepayment.I.redeemlen); + swap->bobspend.utxotxid = swap->alicepayment.I.signedtxid = LP_broadcast_tx(swap->alicepayment.name,swap->alicecoin->symbol,swap->alicepayment.txbytes,swap->alicepayment.I.datalen); + bitcoin_address(swap->alicepayment.p2shaddr,swap->alicecoin->taddr,swap->alicecoin->p2shtype,swap->alicepayment.redeemscript,swap->alicepayment.I.redeemlen); strcpy(swap->alicepayment.I.destaddr,swap->alicepayment.p2shaddr); if ( bits256_nonz(swap->alicepayment.I.signedtxid) != 0 ) swap->aliceunconf = 1; basilisk_dontforget_update(swap,&swap->alicepayment); - return(LP_waitmempool(swap->alicecoin.symbol,swap->alicepayment.I.destaddr,swap->alicepayment.I.signedtxid,0,60)); + return(LP_waitmempool(swap->alicecoin->symbol,swap->alicepayment.I.destaddr,swap->alicepayment.I.signedtxid,0,60)); //printf("import alicepayment address.(%s)\n",swap->alicepayment.p2shaddr); - //LP_importaddress(swap->alicecoin.symbol,swap->alicepayment.p2shaddr); + //LP_importaddress(swap->alicecoin->symbol,swap->alicepayment.p2shaddr); return(0); } printf("error validating alicepayment\n"); @@ -1951,7 +1951,7 @@ int32_t LP_verify_bobpayment(struct basilisk_swap *swap,uint8_t *data,int32_t da { uint8_t userdata[512]; int32_t i,retval=-1,len = 0; bits256 revAm; memset(revAm.bytes,0,sizeof(revAm)); - if ( LP_rawtx_spendscript(swap,swap->bobcoin.longestchain,&swap->bobpayment,0,data,datalen,0) == 0 ) + if ( LP_rawtx_spendscript(swap,swap->bobcoin->longestchain,&swap->bobpayment,0,data,datalen,0) == 0 ) { swap->alicespend.utxovout = 0; swap->alicespend.utxotxid = swap->bobpayment.I.signedtxid = LP_broadcast_tx(swap->bobpayment.name,swap->bobpayment.coin->symbol,swap->bobpayment.txbytes,swap->bobpayment.I.datalen); @@ -1960,10 +1960,10 @@ int32_t LP_verify_bobpayment(struct basilisk_swap *swap,uint8_t *data,int32_t da for (i=0; i<32; i++) revAm.bytes[i] = swap->I.privAm.bytes[31-i]; len = basilisk_swapuserdata(userdata,revAm,0,swap->I.myprivs[0],swap->bobpayment.redeemscript,swap->bobpayment.I.redeemlen); - bitcoin_address(swap->bobpayment.p2shaddr,swap->bobcoin.taddr,swap->bobcoin.p2shtype,swap->bobpayment.redeemscript,swap->bobpayment.I.redeemlen); + bitcoin_address(swap->bobpayment.p2shaddr,swap->bobcoin->taddr,swap->bobcoin->p2shtype,swap->bobpayment.redeemscript,swap->bobpayment.I.redeemlen); strcpy(swap->bobpayment.I.destaddr,swap->bobpayment.p2shaddr); basilisk_dontforget_update(swap,&swap->bobpayment); - //LP_importaddress(swap->bobcoin.symbol,swap->bobpayment.I.destaddr); + //LP_importaddress(swap->bobcoin->symbol,swap->bobpayment.I.destaddr); /*for (i=0; ibobpayment.I.datalen; i++) printf("%02x",swap->bobpayment.txbytes[i]); printf(" <- bobpayment.%d\n",swap->bobpayment.I.datalen); @@ -1974,9 +1974,9 @@ int32_t LP_verify_bobpayment(struct basilisk_swap *swap,uint8_t *data,int32_t da swap->I.userdata_alicespendlen = len; retval = 0; memcpy(swap->alicespend.I.pubkey33,swap->persistent_pubkey33,33); - bitcoin_address(swap->alicespend.I.destaddr,swap->bobcoin.taddr,swap->bobcoin.pubtype,swap->persistent_pubkey33,33); + bitcoin_address(swap->alicespend.I.destaddr,swap->bobcoin->taddr,swap->bobcoin->pubtype,swap->persistent_pubkey33,33); //char str[65],str2[65]; printf("bobpaid privAm.(%s) myprivs[0].(%s)\n",bits256_str(str,swap->I.privAm),bits256_str(str2,swap->I.myprivs[0])); - 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->alicespend,&swap->bobpayment,swap->I.myprivs[0],0,userdata,len,1,swap->changermd160,swap->alicepayment.I.destaddr,swap->bobcoin.zcash)) == 0 ) + 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->alicespend,&swap->bobpayment,swap->I.myprivs[0],0,userdata,len,1,swap->changermd160,swap->alicepayment.I.destaddr,swap->bobcoin->zcash)) == 0 ) { /*for (i=0; ibobpayment.I.datalen; i++) printf("%02x",swap->bobpayment.txbytes[i]); @@ -1985,7 +1985,7 @@ int32_t LP_verify_bobpayment(struct basilisk_swap *swap,uint8_t *data,int32_t da printf("%02x",swap->alicespend.txbytes[i]); printf(" <- alicespend\n\n");*/ swap->I.alicespent = 1; - return(LP_waitmempool(swap->bobcoin.symbol,swap->bobpayment.I.destaddr,swap->bobpayment.I.signedtxid,0,60)); + return(LP_waitmempool(swap->bobcoin->symbol,swap->bobpayment.I.destaddr,swap->bobpayment.I.signedtxid,0,60)); } else printf("error signing aliceclaim suppress.%d vin.(%s)\n",swap->alicespend.I.suppress_pubkeys,swap->bobpayment.I.destaddr); } printf("error validating bobpayment\n"); From 90d9f06d4448ac5a7e94323c3a5f719693fecb51 Mon Sep 17 00:00:00 2001 From: jl777 Date: Tue, 14 Nov 2017 01:16:40 +0200 Subject: [PATCH 0721/1664] Test --- iguana/exchanges/LP_ordermatch.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/iguana/exchanges/LP_ordermatch.c b/iguana/exchanges/LP_ordermatch.c index 12e8dccb0..f65f88370 100644 --- a/iguana/exchanges/LP_ordermatch.c +++ b/iguana/exchanges/LP_ordermatch.c @@ -719,7 +719,7 @@ int32_t LP_tradecommand(void *ctx,char *myipaddr,int32_t pubsock,cJSON *argjson, LP_quoteparse(&Q,argjson); LP_requestinit(&Q.R,Q.srchash,Q.desthash,Q.srccoin,Q.satoshis-Q.txfee,Q.destcoin,Q.destsatoshis-Q.desttxfee,Q.timestamp,Q.quotetime,DEXselector); LP_tradecommand_log(argjson); - //printf("LP_tradecommand: check received method %12s aliceid.%16llx %5s/%-5s %12.8f -> %12.8f price %12.8f\n",method,(long long)Q.aliceid,Q.srccoin,Q.destcoin,dstr(Q.satoshis),dstr(Q.destsatoshis),(double)Q.destsatoshis/Q.satoshis); + printf("LP_tradecommand: check received method %12s aliceid.%16llx %5s/%-5s %12.8f -> %12.8f price %12.8f\n",method,(long long)Q.aliceid,Q.srccoin,Q.destcoin,dstr(Q.satoshis),dstr(Q.destsatoshis),(double)Q.destsatoshis/Q.satoshis); retval = 1; autxo = &A; butxo = &B; From 262a9b132c23792aead7da4e1cc3ea42965f0fdd Mon Sep 17 00:00:00 2001 From: jl777 Date: Tue, 14 Nov 2017 01:22:17 +0200 Subject: [PATCH 0722/1664] Test --- iguana/exchanges/LP_swap.c | 42 +++++++++++++++++++------------------- 1 file changed, 21 insertions(+), 21 deletions(-) diff --git a/iguana/exchanges/LP_swap.c b/iguana/exchanges/LP_swap.c index e803f48fd..008bdf45f 100644 --- a/iguana/exchanges/LP_swap.c +++ b/iguana/exchanges/LP_swap.c @@ -801,7 +801,7 @@ void LP_bobloop(void *_swap) basilisk_bobpayment_reclaim(swap,swap->I.callduration); if ( swap->N.pair >= 0 ) nn_close(swap->N.pair), swap->N.pair = -1; - LP_swapwait(swap->I.req.requestid,swap->I.req.quoteid,LP_atomic_locktime(swap->bobcoin->symbol,swap->alicecoin->symbol)*2,30); + LP_swapwait(swap->I.req.requestid,swap->I.req.quoteid,LP_atomic_locktime(swap->I.bobstr,swap->I.alicestr)*2,30); } } } @@ -867,7 +867,7 @@ void LP_aliceloop(void *_swap) }*/ if ( swap->N.pair >= 0 ) nn_close(swap->N.pair), swap->N.pair = -1; - LP_swapwait(swap->I.req.requestid,swap->I.req.quoteid,LP_atomic_locktime(swap->bobcoin->symbol,swap->alicecoin->symbol)*2,30); + LP_swapwait(swap->I.req.requestid,swap->I.req.quoteid,LP_atomic_locktime(swap->I.bobstr,swap->I.alicestr)*2,30); } } } @@ -999,6 +999,24 @@ struct basilisk_swap *bitcoin_swapinit(bits256 privkey,uint8_t *pubkey33,bits256 { //FILE *fp; char fname[512]; uint8_t *alicepub33=0,*bobpub33=0; int32_t jumblrflag=-2,x = -1; struct iguana_info *coin; + strcpy(swap->I.bobstr,swap->I.req.src); + strcpy(swap->I.alicestr,swap->I.req.dest); + if ( (coin= LP_coinfind(swap->I.alicestr)) != 0 ) + swap->alicecoin = coin; + else + { + printf("missing bobcoin->%p or missing alicecoin->%p src.%p dest.%p\n",swap->bobcoin,swap->alicecoin,LP_coinfind(swap->I.req.src),LP_coinfind(swap->I.req.dest)); + free(swap); + return(0); + } + if ( (coin= LP_coinfind(swap->I.bobstr)) != 0 ) + swap->bobcoin = coin; + else + { + printf("missing bobcoin->%p or missing alicecoin->%p src.%p dest.%p\n",swap->bobcoin,swap->alicecoin,LP_coinfind(swap->I.req.src),LP_coinfind(swap->I.req.dest)); + free(swap); + return(0); + } if ( (swap->I.Atxfee= qp->desttxfee) < 0 ) { printf("bitcoin_swapinit %s Atxfee %.8f rejected\n",swap->I.req.dest,dstr(swap->I.Atxfee)); @@ -1009,7 +1027,7 @@ struct basilisk_swap *bitcoin_swapinit(bits256 privkey,uint8_t *pubkey33,bits256 printf("bitcoin_swapinit %s Btxfee %.8f rejected\n",swap->I.req.src,dstr(swap->I.Btxfee)); return(0); } - swap->I.putduration = swap->I.callduration = LP_atomic_locktime(swap->bobcoin->symbol,swap->alicecoin->symbol); + swap->I.putduration = swap->I.callduration = LP_atomic_locktime(swap->I.bobstr,swap->I.alicestr); if ( optionduration < 0 ) swap->I.putduration -= optionduration; else if ( optionduration > 0 ) @@ -1028,8 +1046,6 @@ struct basilisk_swap *bitcoin_swapinit(bits256 privkey,uint8_t *pubkey33,bits256 swap->I.bobinsurance = LP_MIN_TXFEE; if ( (swap->I.aliceinsurance= (swap->I.alicesatoshis / INSTANTDEX_INSURANCEDIV)) < LP_MIN_TXFEE ) swap->I.aliceinsurance = LP_MIN_TXFEE; - strcpy(swap->I.bobstr,swap->I.req.src); - strcpy(swap->I.alicestr,swap->I.req.dest); swap->I.started = (uint32_t)time(NULL); swap->I.expiration = swap->I.req.timestamp + swap->I.putduration + swap->I.callduration; OS_randombytes((uint8_t *)&swap->I.choosei,sizeof(swap->I.choosei)); @@ -1057,22 +1073,6 @@ struct basilisk_swap *bitcoin_swapinit(bits256 privkey,uint8_t *pubkey33,bits256 char str[65]; printf("couldnt generate privkeys %d %s\n",x,bits256_str(str,privkey)); return(0); } - if ( (coin= LP_coinfind(swap->I.alicestr)) != 0 ) - swap->alicecoin = coin; - else - { - printf("missing bobcoin->%p or missing alicecoin->%p src.%p dest.%p\n",swap->bobcoin,swap->alicecoin,LP_coinfind(swap->I.req.src),LP_coinfind(swap->I.req.dest)); - free(swap); - return(0); - } - if ( (coin= LP_coinfind(swap->I.bobstr)) != 0 ) - swap->bobcoin = coin; - else - { - printf("missing bobcoin->%p or missing alicecoin->%p src.%p dest.%p\n",swap->bobcoin,swap->alicecoin,LP_coinfind(swap->I.req.src),LP_coinfind(swap->I.req.dest)); - free(swap); - return(0); - } if ( strcmp("BTC",swap->bobcoin->symbol) == 0 ) { swap->I.bobconfirms = (1 + sqrt(dstr(swap->I.bobsatoshis) * .1)); From fa9f638ebec8105b53dd3a94928b1a1e46750273 Mon Sep 17 00:00:00 2001 From: jl777 Date: Tue, 14 Nov 2017 01:46:28 +0200 Subject: [PATCH 0723/1664] Use decker's condition --- iguana/exchanges/LP_tradebots.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/iguana/exchanges/LP_tradebots.c b/iguana/exchanges/LP_tradebots.c index ce3a6a65a..12d93436c 100644 --- a/iguana/exchanges/LP_tradebots.c +++ b/iguana/exchanges/LP_tradebots.c @@ -481,7 +481,8 @@ char *LP_tradebot_buy(int32_t dispdir,char *base,char *rel,double maxprice,doubl else balance = LP_RTsmartbalance(relcoin); sum = (SATOSHIDEN*relvolume+2*dstr(txfees)) + 3 * ((SATOSHIDEN*relvolume+2*dstr(txfees))/777); printf("%s inventory balance %.8f, relvolume %.8f + txfees %.8f, utxobal %.8f sum %.8f\n",rel,dstr(abalance),relvolume,dstr(txfees),dstr(balance),dstr(sum)); - if ( dstr(abalance) < relvolume && balance > sum+2*txfee ) + if ( (dstr(abalance + txfees) < relvolume) || (dstr(balance - abalance) < dstr(balance - abalance + txfees)) ) + //if ( dstr(abalance) < relvolume && balance > sum+2*txfee ) { retjson = cJSON_CreateObject(); jaddstr(retjson,"error","not enough funds"); From 7e70c96a1a7fc7ee1b63e6439f3d1b224d404115 Mon Sep 17 00:00:00 2001 From: jl777 Date: Tue, 14 Nov 2017 01:51:05 +0200 Subject: [PATCH 0724/1664] Test --- iguana/exchanges/LP_swap.c | 3 ++- iguana/exchanges/LP_transaction.c | 4 ++-- 2 files changed, 4 insertions(+), 3 deletions(-) diff --git a/iguana/exchanges/LP_swap.c b/iguana/exchanges/LP_swap.c index 008bdf45f..c98cc0dd9 100644 --- a/iguana/exchanges/LP_swap.c +++ b/iguana/exchanges/LP_swap.c @@ -969,6 +969,7 @@ void basilisk_rawtx_setparms(char *name,uint32_t quoteid,struct basilisk_rawtx * #endif strcpy(rawtx->name,name); rawtx->coin = coin; + printf("set coin.%s %s -> %s\n",coin->symbol,coin->smartaddr,name); strcpy(rawtx->I.coinstr,coin->symbol); rawtx->I.numconfirms = numconfirms; if ( (rawtx->I.amount= satoshis) < LP_MIN_TXFEE ) @@ -1152,7 +1153,7 @@ struct basilisk_swap *bitcoin_swapinit(bits256 privkey,uint8_t *pubkey33,bits256 swap->myfee.utxotxid = qp->feetxid, swap->myfee.utxovout = qp->feevout; LP_mark_spent(swap->alicecoin->symbol,qp->feetxid,qp->feevout); } - char str[65],str2[65],str3[65]; printf("IAMBOB.%d %s %s %s\n",swap->I.iambob,bits256_str(str,qp->txid),bits256_str(str2,qp->txid2),bits256_str(str3,qp->feetxid)); + char str[65],str2[65],str3[65]; printf("IAMBOB.%d %s %s %s [%s %s]\n",swap->I.iambob,bits256_str(str,qp->txid),bits256_str(str2,qp->txid2),bits256_str(str3,qp->feetxid),swap->bobcoin->symbol,swap->alicecoin->symbol); return(swap); } diff --git a/iguana/exchanges/LP_transaction.c b/iguana/exchanges/LP_transaction.c index 54c3045c0..453cd0fd4 100644 --- a/iguana/exchanges/LP_transaction.c +++ b/iguana/exchanges/LP_transaction.c @@ -1230,8 +1230,8 @@ int32_t basilisk_rawtx_gen(void *ctx,char *str,uint32_t swapstarted,uint8_t *pub return(-1); if ( strcmp(coin->smartaddr,vinaddr) != 0 ) { - printf("basilisk_rawtx_gen mismatched %s vinaddr.%s != (%s)\n",coin->symbol,vinaddr,coin->smartaddr); - return(-1); + printf("???????????????????????? basilisk_rawtx_gen mismatched %s vinaddr.%s != (%s)\n",coin->symbol,vinaddr,coin->smartaddr); + //return(-1); } argjson = cJSON_CreateObject(); jaddbits256(argjson,"utxotxid",rawtx->utxotxid); From e1b227ef25cec4998d7d8bf7f85810cdcd3a7f00 Mon Sep 17 00:00:00 2001 From: jl777 Date: Tue, 14 Nov 2017 02:32:32 +0200 Subject: [PATCH 0725/1664] Test --- iguana/exchanges/LP_include.h | 7 +- iguana/exchanges/LP_remember.c | 20 +- iguana/exchanges/LP_statemachine.c | 18 - iguana/exchanges/LP_swap.c | 130 ++++---- iguana/exchanges/LP_tradebots.c | 2 +- iguana/exchanges/LP_transaction.c | 516 +++++++++++++++-------------- 6 files changed, 354 insertions(+), 339 deletions(-) diff --git a/iguana/exchanges/LP_include.h b/iguana/exchanges/LP_include.h index ec9a2eca5..839333523 100644 --- a/iguana/exchanges/LP_include.h +++ b/iguana/exchanges/LP_include.h @@ -166,7 +166,7 @@ struct basilisk_swap; struct basilisk_rawtxinfo { - char destaddr[64],coinstr[128]; + char destaddr[64]; bits256 txid,signedtxid,actualtxid; int64_t amount,change,inputsum; int32_t redeemlen,datalen,completed,vintype,vouttype,numconfirms,spendlen,secretstart,suppress_pubkeys; @@ -187,10 +187,9 @@ struct basilisk_request struct basilisk_rawtx { - char name[32]; + char name[32],symbol[65]; struct iguana_msgtx msgtx; struct basilisk_rawtxinfo I; - struct iguana_info *coin; char vinstr[8192],p2shaddr[64]; cJSON *vins; bits256 utxotxid; int32_t utxovout; @@ -347,7 +346,7 @@ struct LP_endpoint { int32_t pair; char ipaddr[64]; uint16_t port; }; struct basilisk_swap { - void *ctx; struct iguana_info *bobcoin,*alicecoin; struct LP_utxoinfo *utxo; + void *ctx; struct LP_utxoinfo *utxo; struct LP_endpoint N; void (*balancingtrade)(struct basilisk_swap *swap,int32_t iambob); int32_t subsock,pushsock,connected,aliceunconf,depositunconf,paymentunconf; diff --git a/iguana/exchanges/LP_remember.c b/iguana/exchanges/LP_remember.c index 0820bf82b..d8b264e7c 100644 --- a/iguana/exchanges/LP_remember.c +++ b/iguana/exchanges/LP_remember.c @@ -32,13 +32,15 @@ void basilisk_dontforget_userdata(char *userdataname,FILE *fp,uint8_t *script,in void basilisk_dontforget(struct basilisk_swap *swap,struct basilisk_rawtx *rawtx,int32_t locktime,bits256 triggertxid) { - char zeroes[32],fname[512],str[65],coinaddr[64],secretAmstr[41],secretAm256str[65],secretBnstr[41],secretBn256str[65]; FILE *fp; int32_t i,len; uint8_t redeemscript[256],script[256]; + char zeroes[32],fname[512],str[65],coinaddr[64],secretAmstr[41],secretAm256str[65],secretBnstr[41],secretBn256str[65]; FILE *fp; int32_t i,len; uint8_t redeemscript[256],script[256]; struct iguana_info *bobcoin,*alicecoin; sprintf(fname,"%s/SWAPS/%u-%u.%s",GLOBAL_DBDIR,swap->I.req.requestid,swap->I.req.quoteid,rawtx->name), OS_compatible_path(fname); + bobcoin = LP_coinfind(swap->I.bobstr); + alicecoin = LP_coinfind(swap->I.alicestr); coinaddr[0] = secretAmstr[0] = secretAm256str[0] = secretBnstr[0] = secretBn256str[0] = 0; memset(zeroes,0,sizeof(zeroes)); - if ( rawtx != 0 && (fp= fopen(fname,"wb")) != 0 ) + if ( alicecoin != 0 && bobcoin != 0 && rawtx != 0 && (fp= fopen(fname,"wb")) != 0 ) { - fprintf(fp,"{\"name\":\"%s\",\"coin\":\"%s\"",rawtx->name,rawtx->coin->symbol); + fprintf(fp,"{\"name\":\"%s\",\"coin\":\"%s\"",rawtx->name,rawtx->symbol); if ( rawtx->I.datalen > 0 ) { fprintf(fp,",\"tx\":\""); @@ -47,10 +49,10 @@ void basilisk_dontforget(struct basilisk_swap *swap,struct basilisk_rawtx *rawtx fprintf(fp,"\",\"txid\":\"%s\"",bits256_str(str,bits256_doublesha256(0,rawtx->txbytes,rawtx->I.datalen))); if ( rawtx == &swap->bobdeposit || rawtx == &swap->bobpayment ) { - LP_swap_coinaddr(swap->bobcoin,coinaddr,0,rawtx->txbytes,rawtx->I.datalen,0); + LP_swap_coinaddr(bobcoin,coinaddr,0,rawtx->txbytes,rawtx->I.datalen,0); if ( coinaddr[0] != 0 ) { - LP_importaddress(swap->bobcoin->symbol,coinaddr); + LP_importaddress(swap->I.bobstr,coinaddr); if ( rawtx == &swap->bobdeposit ) safecopy(swap->Bdeposit,coinaddr,sizeof(swap->Bdeposit)); else safecopy(swap->Bpayment,coinaddr,sizeof(swap->Bpayment)); @@ -63,16 +65,16 @@ void basilisk_dontforget(struct basilisk_swap *swap,struct basilisk_rawtx *rawtx fprintf(fp,",\"%s\":\"%s\"","Bpayment",swap->Bpayment); fprintf(fp,",\"expiration\":%u",swap->I.expiration); fprintf(fp,",\"iambob\":%d",swap->I.iambob); - fprintf(fp,",\"bobcoin\":\"%s\"",swap->bobcoin->symbol); - fprintf(fp,",\"alicecoin\":\"%s\"",swap->alicecoin->symbol); + fprintf(fp,",\"bobcoin\":\"%s\"",swap->I.bobstr); + fprintf(fp,",\"alicecoin\":\"%s\"",swap->I.alicestr); fprintf(fp,",\"lock\":%u",locktime); fprintf(fp,",\"amount\":%.8f",dstr(rawtx->I.amount)); if ( bits256_nonz(triggertxid) != 0 ) fprintf(fp,",\"trigger\":\"%s\"",bits256_str(str,triggertxid)); if ( bits256_nonz(swap->I.pubAm) != 0 && bits256_nonz(swap->I.pubBn) != 0 ) { - basilisk_alicescript(redeemscript,&len,script,0,coinaddr,swap->alicecoin->taddr,swap->alicecoin->p2shtype,swap->I.pubAm,swap->I.pubBn); - LP_importaddress(swap->alicecoin->symbol,coinaddr); + basilisk_alicescript(redeemscript,&len,script,0,coinaddr,alicecoin->taddr,alicecoin->p2shtype,swap->I.pubAm,swap->I.pubBn); + LP_importaddress(swap->I.alicestr,coinaddr); fprintf(fp,",\"Apayment\":\"%s\"",coinaddr); } if ( rawtx->I.redeemlen > 0 ) diff --git a/iguana/exchanges/LP_statemachine.c b/iguana/exchanges/LP_statemachine.c index 6bb33ffcc..b267364df 100644 --- a/iguana/exchanges/LP_statemachine.c +++ b/iguana/exchanges/LP_statemachine.c @@ -595,24 +595,6 @@ void basilisk_swap_saveupdate(struct basilisk_swap *swap) } } -/*int32_t basilisk_swap_loadtx(struct basilisk_rawtx *rawtx,FILE *fp,char *bobcoinstr,char *alicecoinstr) - { - if ( fread(rawtx,1,sizeof(*rawtx),fp) == sizeof(*rawtx) ) - { - rawtx->coin = 0; - rawtx->vins = 0; - if ( strcmp(rawtx->I.coinstr,bobcoinstr) == 0 || strcmp(rawtx->I.coinstr,alicecoinstr) == 0 ) - { - rawtx->coin = LP_coinfind(rawtx->I.coinstr); - if ( rawtx->vinstr[0] != 0 ) - rawtx->vins = cJSON_Parse(rawtx->vinstr); - printf("loaded.%s len.%d\n",rawtx->name,rawtx->I.datalen); - return(0); - } - } - return(-1); - }*/ - void basilisk_swap_sendabort(struct basilisk_swap *swap) { uint32_t msgbits = 0; uint8_t buf[sizeof(msgbits) + sizeof(swap->I.req.quoteid) + sizeof(bits256)*2]; int32_t sentbytes,offset=0; diff --git a/iguana/exchanges/LP_swap.c b/iguana/exchanges/LP_swap.c index c98cc0dd9..ce1b725da 100644 --- a/iguana/exchanges/LP_swap.c +++ b/iguana/exchanges/LP_swap.c @@ -556,7 +556,12 @@ struct basilisk_rawtx *LP_swapdata_rawtx(struct basilisk_swap *swap,uint8_t *dat int32_t LP_rawtx_spendscript(struct basilisk_swap *swap,int32_t height,struct basilisk_rawtx *rawtx,int32_t v,uint8_t *recvbuf,int32_t recvlen,int32_t suppress_pubkeys) { - bits256 otherhash,myhash,txid; int64_t txfee,val; int32_t i,offset=0,datalen=0,retval=-1,hexlen,n; uint8_t *data; cJSON *txobj,*skey,*vouts,*vout; char *hexstr,redeemaddr[64],checkaddr[64]; uint32_t quoteid,msgbits; + bits256 otherhash,myhash,txid; int64_t txfee,val; int32_t i,offset=0,datalen=0,retval=-1,hexlen,n; uint8_t *data; cJSON *txobj,*skey,*vouts,*vout; char *hexstr,redeemaddr[64],checkaddr[64]; uint32_t quoteid,msgbits; struct iguana_info *coin; + if ( (coin= LP_coinfind(rawtx->symbol)) == 0 ) + { + printf("LP_rawtx_spendscript couldnt find coin.(%s)\n",rawtx->symbol); + return(-1); + } for (i=0; i<32; i++) otherhash.bytes[i] = recvbuf[offset++]; for (i=0; i<32; i++) @@ -577,9 +582,9 @@ int32_t LP_rawtx_spendscript(struct basilisk_swap *swap,int32_t height,struct ba memcpy(rawtx->redeemscript,&data[datalen],rawtx->I.redeemlen); //for (i=0; iI.redeemlen; i++) // printf("%02x",rawtx->redeemscript[i]); - bitcoin_address(redeemaddr,rawtx->coin->taddr,rawtx->coin->p2shtype,rawtx->redeemscript,rawtx->I.redeemlen); - //printf(" received redeemscript.(%s) %s taddr.%d\n",redeemaddr,rawtx->coin->symbol,rawtx->coin->taddr); - LP_swap_coinaddr(rawtx->coin,checkaddr,0,data,datalen,0); + bitcoin_address(redeemaddr,coin->taddr,coin->p2shtype,rawtx->redeemscript,rawtx->I.redeemlen); + //printf(" received redeemscript.(%s) %s taddr.%d\n",redeemaddr,coin->symbol,coin->taddr); + LP_swap_coinaddr(coin,checkaddr,0,data,datalen,0); if ( strcmp(redeemaddr,checkaddr) != 0 ) { printf("REDEEMADDR MISMATCH??? %s != %s\n",redeemaddr,checkaddr); @@ -609,20 +614,20 @@ int32_t LP_rawtx_spendscript(struct basilisk_swap *swap,int32_t height,struct ba char str[65]; printf("rawtx.%s txid %s\n",rawtx->name,bits256_str(str,txid)); if ( bits256_cmp(txid,rawtx->I.actualtxid) != 0 && bits256_nonz(rawtx->I.actualtxid) == 0 ) rawtx->I.actualtxid = txid; - if ( (txobj= bitcoin_data2json(rawtx->coin->taddr,rawtx->coin->pubtype,rawtx->coin->p2shtype,rawtx->coin->isPoS,height,&rawtx->I.signedtxid,&rawtx->msgtx,rawtx->extraspace,sizeof(rawtx->extraspace),data,datalen,0,suppress_pubkeys,rawtx->coin->zcash)) != 0 ) + if ( (txobj= bitcoin_data2json(coin->taddr,coin->pubtype,coin->p2shtype,coin->isPoS,height,&rawtx->I.signedtxid,&rawtx->msgtx,rawtx->extraspace,sizeof(rawtx->extraspace),data,datalen,0,suppress_pubkeys,coin->zcash)) != 0 ) { rawtx->I.actualtxid = rawtx->I.signedtxid; rawtx->I.locktime = rawtx->msgtx.lock_time; if ( (vouts= jarray(&n,txobj,"vout")) != 0 && v < n ) { vout = jitem(vouts,v); - if ( strcmp("BTC",rawtx->coin->symbol) == 0 && rawtx == &swap->otherfee ) + if ( strcmp("BTC",coin->symbol) == 0 && rawtx == &swap->otherfee ) txfee = LP_MIN_TXFEE; else { - if ( strcmp(rawtx->coin->symbol,swap->bobcoin->symbol) == 0 ) + if ( strcmp(coin->symbol,swap->I.bobstr) == 0 ) txfee = swap->I.Btxfee; - else if ( strcmp(rawtx->coin->symbol,swap->alicecoin->symbol) == 0 ) + else if ( strcmp(coin->symbol,swap->I.alicestr) == 0 ) txfee = swap->I.Atxfee; else txfee = LP_MIN_TXFEE; } @@ -641,9 +646,9 @@ int32_t LP_rawtx_spendscript(struct basilisk_swap *swap,int32_t height,struct ba if ( rawtx == &swap->otherfee ) { char str[65]; - LP_swap_coinaddr(rawtx->coin,rawtx->p2shaddr,0,data,datalen,0); + LP_swap_coinaddr(coin,rawtx->p2shaddr,0,data,datalen,0); printf("got %s txid.%s (%s) -> %s\n",rawtx->name,bits256_str(str,rawtx->I.signedtxid),jprint(txobj,0),rawtx->p2shaddr); - } else bitcoin_address(rawtx->p2shaddr,rawtx->coin->taddr,rawtx->coin->p2shtype,rawtx->spendscript,hexlen); + } else bitcoin_address(rawtx->p2shaddr,coin->taddr,coin->p2shtype,rawtx->spendscript,hexlen); } } else printf("%s satoshis %.8f ERROR.(%s) txfees.[%.8f %.8f: %.8f] amount.%.8f -> %.8f\n",rawtx->name,dstr(j64bits(vout,"satoshis")),jprint(txobj,0),dstr(swap->I.Atxfee),dstr(swap->I.Btxfee),dstr(txfee),dstr(rawtx->I.amount),dstr(rawtx->I.amount)-dstr(txfee)); } @@ -659,7 +664,7 @@ uint32_t LP_swapdata_rawtxsend(int32_t pairsock,struct basilisk_swap *swap,uint3 { if ( bits256_nonz(rawtx->I.signedtxid) != 0 && bits256_nonz(rawtx->I.actualtxid) == 0 ) { - rawtx->I.actualtxid = LP_broadcast_tx(rawtx->name,rawtx->coin->symbol,rawtx->txbytes,rawtx->I.datalen); + rawtx->I.actualtxid = LP_broadcast_tx(rawtx->name,rawtx->symbol,rawtx->txbytes,rawtx->I.datalen); if ( bits256_cmp(rawtx->I.actualtxid,rawtx->I.signedtxid) != 0 ) { char str[65],str2[65]; @@ -687,7 +692,7 @@ uint32_t LP_swapdata_rawtxsend(int32_t pairsock,struct basilisk_swap *swap,uint3 if ( suppress_swapsend == 0 ) { retval = LP_swapsend(pairsock,swap,msgbits,sendbuf,sendlen,nextbits,rawtx->I.crcs); - if ( LP_waitmempool(rawtx->coin->symbol,rawtx->I.destaddr,rawtx->I.signedtxid,0,LP_SWAPSTEP_TIMEOUT*10) < 0 ) + if ( LP_waitmempool(rawtx->symbol,rawtx->I.destaddr,rawtx->I.signedtxid,0,LP_SWAPSTEP_TIMEOUT*10) < 0 ) { char str[65]; printf("failed to find %s %s %s in the mempool?\n",rawtx->name,rawtx->I.destaddr,bits256_str(str,rawtx->I.actualtxid)); retval = -1; @@ -783,12 +788,12 @@ void LP_bobloop(void *_swap) printf("error bobscripts payment\n"); else { - if ( strcmp(swap->alicecoin->symbol,"BTC") == 0 ) + if ( strcmp(swap->I.alicestr,"BTC") == 0 ) m = 0; 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 + while ( (n= LP_numconfirms(swap->I.alicestr,swap->alicepayment.I.destaddr,swap->alicepayment.I.signedtxid,0,1)) < m ) // sync with alice { - char str[65];printf("%d wait for alicepayment %s numconfs.%d %s %s\n",n,swap->alicepayment.I.destaddr,m,swap->alicecoin->symbol,bits256_str(str,swap->alicepayment.I.signedtxid)); + char str[65];printf("%d wait for alicepayment %s numconfs.%d %s %s\n",n,swap->alicepayment.I.destaddr,m,swap->I.alicestr,bits256_str(str,swap->alicepayment.I.signedtxid)); sleep(10); } if ( LP_swapdata_rawtxsend(swap->N.pair,swap,0x8000,data,maxlen,&swap->bobpayment,0x4000,0) == 0 ) @@ -840,12 +845,12 @@ void LP_aliceloop(void *_swap) printf("error sending alicepayment\n"); else { - if ( strcmp(swap->alicecoin->symbol,"BTC") == 0 ) + if ( strcmp(swap->I.alicestr,"BTC") == 0 ) m = 0; else m = swap->I.aliceconfirms; - while ( (n= LP_numconfirms(swap->alicecoin->symbol,swap->alicepayment.I.destaddr,swap->alicepayment.I.signedtxid,0,1)) < m ) + while ( (n= LP_numconfirms(swap->I.alicestr,swap->alicepayment.I.destaddr,swap->alicepayment.I.signedtxid,0,1)) < m ) { - char str[65];printf("%d wait for alicepayment %s numconfs.%d %s %s\n",n,swap->alicepayment.I.destaddr,m,swap->alicecoin->symbol,bits256_str(str,swap->alicepayment.I.signedtxid)); + char str[65];printf("%d wait for alicepayment %s numconfs.%d %s %s\n",n,swap->alicepayment.I.destaddr,m,swap->I.alicestr,bits256_str(str,swap->alicepayment.I.signedtxid)); sleep(10); } swap->sentflag = 1; @@ -853,16 +858,16 @@ void LP_aliceloop(void *_swap) printf("error waiting for bobpayment\n"); else { - while ( (n= LP_numconfirms(swap->bobcoin->symbol,swap->bobpayment.I.destaddr,swap->bobpayment.I.signedtxid,0,1)) < swap->I.bobconfirms ) + while ( (n= LP_numconfirms(swap->I.bobstr,swap->bobpayment.I.destaddr,swap->bobpayment.I.signedtxid,0,1)) < swap->I.bobconfirms ) { - char str[65];printf("%d wait for bobpayment %s numconfs.%d %s %s\n",n,swap->bobpayment.I.destaddr,swap->I.bobconfirms,swap->bobcoin->symbol,bits256_str(str,swap->bobpayment.I.signedtxid)); + char str[65];printf("%d wait for bobpayment %s numconfs.%d %s %s\n",n,swap->bobpayment.I.destaddr,swap->I.bobconfirms,swap->I.bobstr,bits256_str(str,swap->bobpayment.I.signedtxid)); sleep(10); } /*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 ) + while ( (n= LP_numconfirms(swap->I.alicestr,swap->alicespend.I.destaddr,swap->alicespend.I.signedtxid,0,1)) < swap->I.aliceconfirms ) { - char str[65];printf("%d wait for alicespend %s numconfs.%d %s %s\n",n,swap->alicespend.I.destaddr,swap->I.aliceconfirms,swap->bobcoin->symbol,bits256_str(str,swap->alicespend.I.signedtxid)); + char str[65];printf("%d wait for alicespend %s numconfs.%d %s %s\n",n,swap->alicespend.I.destaddr,swap->I.aliceconfirms,swap->I.bobstr,bits256_str(str,swap->alicespend.I.signedtxid)); sleep(LP_SWAPSTEP_TIMEOUT); }*/ if ( swap->N.pair >= 0 ) @@ -968,9 +973,8 @@ void basilisk_rawtx_setparms(char *name,uint32_t quoteid,struct basilisk_rawtx * numconfirms = 0; #endif strcpy(rawtx->name,name); - rawtx->coin = coin; printf("set coin.%s %s -> %s\n",coin->symbol,coin->smartaddr,name); - strcpy(rawtx->I.coinstr,coin->symbol); + strcpy(rawtx->symbol,coin->symbol); rawtx->I.numconfirms = numconfirms; if ( (rawtx->I.amount= satoshis) < LP_MIN_TXFEE ) rawtx->I.amount = LP_MIN_TXFEE; @@ -981,13 +985,13 @@ void basilisk_rawtx_setparms(char *name,uint32_t quoteid,struct basilisk_rawtx * if ( strcmp(coin->symbol,"BTC") == 0 && (quoteid % 10) == 0 ) decode_hex(rawtx->I.rmd160,20,TIERNOLAN_RMD160); else decode_hex(rawtx->I.rmd160,20,INSTANTDEX_RMD160); - bitcoin_address(rawtx->I.destaddr,rawtx->coin->taddr,rawtx->coin->pubtype,rawtx->I.rmd160,20); + bitcoin_address(rawtx->I.destaddr,coin->taddr,coin->pubtype,rawtx->I.rmd160,20); } if ( pubkey33 != 0 ) { memcpy(rawtx->I.pubkey33,pubkey33,33); - bitcoin_address(rawtx->I.destaddr,rawtx->coin->taddr,rawtx->coin->pubtype,rawtx->I.pubkey33,33); - bitcoin_addr2rmd160(rawtx->coin->taddr,&rawtx->I.addrtype,rawtx->I.rmd160,rawtx->I.destaddr); + bitcoin_address(rawtx->I.destaddr,coin->taddr,coin->pubtype,rawtx->I.pubkey33,33); + bitcoin_addr2rmd160(coin->taddr,&rawtx->I.addrtype,rawtx->I.rmd160,rawtx->I.destaddr); } if ( rawtx->I.vouttype <= 1 && rawtx->I.destaddr[0] != 0 ) { @@ -999,22 +1003,18 @@ 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 jumblrflag=-2,x = -1; struct iguana_info *coin; + uint8_t *alicepub33=0,*bobpub33=0; int32_t jumblrflag=-2,x = -1; struct iguana_info *bobcoin,*alicecoin; strcpy(swap->I.bobstr,swap->I.req.src); strcpy(swap->I.alicestr,swap->I.req.dest); - if ( (coin= LP_coinfind(swap->I.alicestr)) != 0 ) - swap->alicecoin = coin; - else + if ( (alicecoin= LP_coinfind(swap->I.alicestr)) == 0 ) { - printf("missing bobcoin->%p or missing alicecoin->%p src.%p dest.%p\n",swap->bobcoin,swap->alicecoin,LP_coinfind(swap->I.req.src),LP_coinfind(swap->I.req.dest)); + printf("missing alicecoin src.%p dest.%p\n",LP_coinfind(swap->I.req.src),LP_coinfind(swap->I.req.dest)); free(swap); return(0); } - if ( (coin= LP_coinfind(swap->I.bobstr)) != 0 ) - swap->bobcoin = coin; - else + if ( (bobcoin= LP_coinfind(swap->I.bobstr)) == 0 ) { - printf("missing bobcoin->%p or missing alicecoin->%p src.%p dest.%p\n",swap->bobcoin,swap->alicecoin,LP_coinfind(swap->I.req.src),LP_coinfind(swap->I.req.dest)); + printf("missing bobcoin src.%p dest.%p\n",LP_coinfind(swap->I.req.src),LP_coinfind(swap->I.req.dest)); free(swap); return(0); } @@ -1074,12 +1074,12 @@ struct basilisk_swap *bitcoin_swapinit(bits256 privkey,uint8_t *pubkey33,bits256 char str[65]; printf("couldnt generate privkeys %d %s\n",x,bits256_str(str,privkey)); return(0); } - if ( strcmp("BTC",swap->bobcoin->symbol) == 0 ) + if ( strcmp("BTC",swap->I.bobstr) == 0 ) { swap->I.bobconfirms = (1 + sqrt(dstr(swap->I.bobsatoshis) * .1)); swap->I.aliceconfirms = BASILISK_DEFAULT_NUMCONFIRMS; } - else if ( strcmp("BTC",swap->alicecoin->symbol) == 0 ) + else if ( strcmp("BTC",swap->I.alicestr) == 0 ) { swap->I.aliceconfirms = (1 + sqrt(dstr(swap->I.alicesatoshis) * .1)); swap->I.bobconfirms = BASILISK_DEFAULT_NUMCONFIRMS; @@ -1089,17 +1089,17 @@ struct basilisk_swap *bitcoin_swapinit(bits256 privkey,uint8_t *pubkey33,bits256 swap->I.bobconfirms = BASILISK_DEFAULT_NUMCONFIRMS; swap->I.aliceconfirms = BASILISK_DEFAULT_NUMCONFIRMS; } - if ( swap->bobcoin->isassetchain != 0 ) + if ( bobcoin->isassetchain != 0 ) swap->I.bobconfirms = 1; - if ( swap->alicecoin->isassetchain != 0 ) + if ( 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 ) + if ( bobcoin->userconfirms > 0 ) + swap->I.bobconfirms = bobcoin->userconfirms; + if ( alicecoin->userconfirms > 0 ) + swap->I.aliceconfirms = alicecoin->userconfirms; + if ( (swap->I.bobmaxconfirms= bobcoin->maxconfirms) == 0 ) swap->I.bobmaxconfirms = BASILISK_DEFAULT_MAXCONFIRMS; - if ( (swap->I.alicemaxconfirms= swap->alicecoin->maxconfirms) == 0 ) + if ( (swap->I.alicemaxconfirms= alicecoin->maxconfirms) == 0 ) swap->I.alicemaxconfirms = BASILISK_DEFAULT_MAXCONFIRMS; if ( swap->I.bobconfirms > swap->I.bobmaxconfirms ) swap->I.bobconfirms = swap->I.bobmaxconfirms; @@ -1107,53 +1107,53 @@ struct basilisk_swap *bitcoin_swapinit(bits256 privkey,uint8_t *pubkey33,bits256 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); + 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,bobcoin->taddr,alicecoin->taddr); if ( swap->I.iambob != 0 ) { - basilisk_rawtx_setparms("myfee",swap->I.req.quoteid,&swap->myfee,swap->bobcoin,0,0,LP_DEXFEE(swap->I.bobsatoshis) + 0*swap->bobcoin->txfee,0,0,jumblrflag); - basilisk_rawtx_setparms("otherfee",swap->I.req.quoteid,&swap->otherfee,swap->alicecoin,0,0,LP_DEXFEE(swap->I.alicesatoshis) + 0*swap->alicecoin->txfee,0,0,jumblrflag); + basilisk_rawtx_setparms("myfee",swap->I.req.quoteid,&swap->myfee,bobcoin,0,0,LP_DEXFEE(swap->I.bobsatoshis) + 0*bobcoin->txfee,0,0,jumblrflag); + basilisk_rawtx_setparms("otherfee",swap->I.req.quoteid,&swap->otherfee,alicecoin,0,0,LP_DEXFEE(swap->I.alicesatoshis) + 0*alicecoin->txfee,0,0,jumblrflag); bobpub33 = pubkey33; } else { - basilisk_rawtx_setparms("otherfee",swap->I.req.quoteid,&swap->otherfee,swap->bobcoin,0,0,LP_DEXFEE(swap->I.bobsatoshis) + 0*swap->bobcoin->txfee,0,0,jumblrflag); - basilisk_rawtx_setparms("myfee",swap->I.req.quoteid,&swap->myfee,swap->alicecoin,0,0,LP_DEXFEE(swap->I.alicesatoshis) + 0*swap->alicecoin->txfee,0,0,jumblrflag); + basilisk_rawtx_setparms("otherfee",swap->I.req.quoteid,&swap->otherfee,bobcoin,0,0,LP_DEXFEE(swap->I.bobsatoshis) + 0*bobcoin->txfee,0,0,jumblrflag); + basilisk_rawtx_setparms("myfee",swap->I.req.quoteid,&swap->myfee,alicecoin,0,0,LP_DEXFEE(swap->I.alicesatoshis) + 0*alicecoin->txfee,0,0,jumblrflag); alicepub33 = pubkey33; } swap->myfee.I.locktime = swap->I.started + 1; swap->otherfee.I.locktime = swap->I.started + 1; - basilisk_rawtx_setparms("bobdeposit",swap->I.req.quoteid,&swap->bobdeposit,swap->bobcoin,swap->I.bobconfirms,0,LP_DEPOSITSATOSHIS(swap->I.bobsatoshis) + swap->bobcoin->txfee,4,0,jumblrflag); - basilisk_rawtx_setparms("bobrefund",swap->I.req.quoteid,&swap->bobrefund,swap->bobcoin,1,4,LP_DEPOSITSATOSHIS(swap->I.bobsatoshis),1,bobpub33,jumblrflag); + basilisk_rawtx_setparms("bobdeposit",swap->I.req.quoteid,&swap->bobdeposit,bobcoin,swap->I.bobconfirms,0,LP_DEPOSITSATOSHIS(swap->I.bobsatoshis) + bobcoin->txfee,4,0,jumblrflag); + basilisk_rawtx_setparms("bobrefund",swap->I.req.quoteid,&swap->bobrefund,bobcoin,1,4,LP_DEPOSITSATOSHIS(swap->I.bobsatoshis),1,bobpub33,jumblrflag); swap->bobrefund.I.suppress_pubkeys = 1; - basilisk_rawtx_setparms("aliceclaim",swap->I.req.quoteid,&swap->aliceclaim,swap->bobcoin,1,4,LP_DEPOSITSATOSHIS(swap->I.bobsatoshis),1,alicepub33,jumblrflag); + basilisk_rawtx_setparms("aliceclaim",swap->I.req.quoteid,&swap->aliceclaim,bobcoin,1,4,LP_DEPOSITSATOSHIS(swap->I.bobsatoshis),1,alicepub33,jumblrflag); swap->aliceclaim.I.suppress_pubkeys = 1; swap->aliceclaim.I.locktime = swap->I.started + swap->I.putduration+swap->I.callduration + 1; - basilisk_rawtx_setparms("bobpayment",swap->I.req.quoteid,&swap->bobpayment,swap->bobcoin,swap->I.bobconfirms,0,swap->I.bobsatoshis + swap->bobcoin->txfee,3,0,jumblrflag); - basilisk_rawtx_setparms("alicespend",swap->I.req.quoteid,&swap->alicespend,swap->bobcoin,swap->I.bobconfirms,3,swap->I.bobsatoshis,1,alicepub33,jumblrflag); + basilisk_rawtx_setparms("bobpayment",swap->I.req.quoteid,&swap->bobpayment,bobcoin,swap->I.bobconfirms,0,swap->I.bobsatoshis + bobcoin->txfee,3,0,jumblrflag); + basilisk_rawtx_setparms("alicespend",swap->I.req.quoteid,&swap->alicespend,bobcoin,swap->I.bobconfirms,3,swap->I.bobsatoshis,1,alicepub33,jumblrflag); swap->alicespend.I.suppress_pubkeys = 1; - basilisk_rawtx_setparms("bobreclaim",swap->I.req.quoteid,&swap->bobreclaim,swap->bobcoin,swap->I.bobconfirms,3,swap->I.bobsatoshis,1,bobpub33,jumblrflag); + basilisk_rawtx_setparms("bobreclaim",swap->I.req.quoteid,&swap->bobreclaim,bobcoin,swap->I.bobconfirms,3,swap->I.bobsatoshis,1,bobpub33,jumblrflag); swap->bobreclaim.I.suppress_pubkeys = 1; swap->bobreclaim.I.locktime = swap->I.started + swap->I.putduration + 1; - basilisk_rawtx_setparms("alicepayment",swap->I.req.quoteid,&swap->alicepayment,swap->alicecoin,swap->I.aliceconfirms,0,swap->I.alicesatoshis + swap->alicecoin->txfee,2,0,jumblrflag); - basilisk_rawtx_setparms("bobspend",swap->I.req.quoteid,&swap->bobspend,swap->alicecoin,swap->I.aliceconfirms,2,swap->I.alicesatoshis,1,bobpub33,jumblrflag); + basilisk_rawtx_setparms("alicepayment",swap->I.req.quoteid,&swap->alicepayment,alicecoin,swap->I.aliceconfirms,0,swap->I.alicesatoshis + alicecoin->txfee,2,0,jumblrflag); + basilisk_rawtx_setparms("bobspend",swap->I.req.quoteid,&swap->bobspend,alicecoin,swap->I.aliceconfirms,2,swap->I.alicesatoshis,1,bobpub33,jumblrflag); swap->bobspend.I.suppress_pubkeys = 1; - basilisk_rawtx_setparms("alicereclaim",swap->I.req.quoteid,&swap->alicereclaim,swap->alicecoin,swap->I.aliceconfirms,2,swap->I.alicesatoshis,1,alicepub33,jumblrflag); + basilisk_rawtx_setparms("alicereclaim",swap->I.req.quoteid,&swap->alicereclaim,alicecoin,swap->I.aliceconfirms,2,swap->I.alicesatoshis,1,alicepub33,jumblrflag); swap->alicereclaim.I.suppress_pubkeys = 1; swap->bobpayment.utxotxid = qp->txid, swap->bobpayment.utxovout = qp->vout; swap->bobdeposit.utxotxid = qp->txid2, swap->bobdeposit.utxovout = qp->vout2; swap->alicepayment.utxotxid = qp->desttxid, swap->alicepayment.utxovout = qp->destvout; - LP_mark_spent(swap->bobcoin->symbol,qp->txid,qp->vout); - LP_mark_spent(swap->bobcoin->symbol,qp->txid2,qp->vout2); - LP_mark_spent(swap->alicecoin->symbol,qp->desttxid,qp->destvout); + LP_mark_spent(swap->I.bobstr,qp->txid,qp->vout); + LP_mark_spent(swap->I.bobstr,qp->txid2,qp->vout2); + LP_mark_spent(swap->I.alicestr,qp->desttxid,qp->destvout); if ( swap->I.iambob != 0 ) swap->otherfee.utxotxid = qp->feetxid, swap->otherfee.utxovout = qp->feevout; else { swap->myfee.utxotxid = qp->feetxid, swap->myfee.utxovout = qp->feevout; - LP_mark_spent(swap->alicecoin->symbol,qp->feetxid,qp->feevout); + LP_mark_spent(swap->I.alicestr,qp->feetxid,qp->feevout); } - char str[65],str2[65],str3[65]; printf("IAMBOB.%d %s %s %s [%s %s]\n",swap->I.iambob,bits256_str(str,qp->txid),bits256_str(str2,qp->txid2),bits256_str(str3,qp->feetxid),swap->bobcoin->symbol,swap->alicecoin->symbol); + char str[65],str2[65],str3[65]; printf("IAMBOB.%d %s %s %s [%s %s]\n",swap->I.iambob,bits256_str(str,qp->txid),bits256_str(str2,qp->txid2),bits256_str(str3,qp->feetxid),swap->I.bobstr,swap->I.alicestr); return(swap); } diff --git a/iguana/exchanges/LP_tradebots.c b/iguana/exchanges/LP_tradebots.c index 12d93436c..762a5c6bf 100644 --- a/iguana/exchanges/LP_tradebots.c +++ b/iguana/exchanges/LP_tradebots.c @@ -481,7 +481,7 @@ char *LP_tradebot_buy(int32_t dispdir,char *base,char *rel,double maxprice,doubl else balance = LP_RTsmartbalance(relcoin); sum = (SATOSHIDEN*relvolume+2*dstr(txfees)) + 3 * ((SATOSHIDEN*relvolume+2*dstr(txfees))/777); printf("%s inventory balance %.8f, relvolume %.8f + txfees %.8f, utxobal %.8f sum %.8f\n",rel,dstr(abalance),relvolume,dstr(txfees),dstr(balance),dstr(sum)); - if ( (dstr(abalance + txfees) < relvolume) || (dstr(balance - abalance) < dstr(balance - abalance + txfees)) ) + if ( (abalance < SATOSHIDEN*relvolume + txfees) || ((balance-abalance) < (uint64_t)(SATOSHIDEN*relvolume)/777 + txfees) ) //if ( dstr(abalance) < relvolume && balance > sum+2*txfee ) { retjson = cJSON_CreateObject(); diff --git a/iguana/exchanges/LP_transaction.c b/iguana/exchanges/LP_transaction.c index 453cd0fd4..c2a07a804 100644 --- a/iguana/exchanges/LP_transaction.c +++ b/iguana/exchanges/LP_transaction.c @@ -1226,7 +1226,7 @@ char *LP_withdraw(struct iguana_info *coin,cJSON *argjson) 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) { struct iguana_info *coin; int32_t len,retval=-1; char *retstr,*hexstr; cJSON *argjson,*outputs,*item,*retjson,*obj; - if ( (coin= rawtx->coin) == 0 ) + if ( (coin= LP_coinfind(rawtx->symbol)) == 0 ) return(-1); if ( strcmp(coin->smartaddr,vinaddr) != 0 ) { @@ -1608,36 +1608,44 @@ 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,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,swap->bobcoin->zcash)) == 0 ) - { - for (i=0; ibobreclaim.I.datalen; i++) - printf("%02x",swap->bobreclaim.txbytes[i]); - printf(" <- bobreclaim\n"); - //basilisk_txlog(swap,&swap->bobreclaim,delay); - return(retval); - } + static bits256 zero; + uint8_t userdata[512]; int32_t retval,i,len = 0; struct iguana_info *coin; + if ( (coin= LP_coinfind(swap->I.bobstr)) != 0 ) + { + //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(coin->symbol,coin->wiftaddr,coin->taddr,coin->pubtype,coin->p2shtype,coin->isPoS,coin->wiftype,swap,&swap->bobreclaim,&swap->bobpayment,swap->I.myprivs[1],0,userdata,len,1,swap->changermd160,swap->bobpayment.I.destaddr,coin->zcash)) == 0 ) + { + for (i=0; ibobreclaim.I.datalen; i++) + printf("%02x",swap->bobreclaim.txbytes[i]); + printf(" <- bobreclaim\n"); + //basilisk_txlog(swap,&swap->bobreclaim,delay); + return(retval); + } + } else printf("basilisk_bobpayment_reclaim cant find (%s)\n",swap->I.bobstr); return(-1); } int32_t basilisk_bobdeposit_refund(struct basilisk_swap *swap,int32_t delay) { - uint8_t userdata[512]; int32_t i,retval,len = 0; char str[65]; - len = basilisk_swapuserdata(userdata,swap->I.privBn,0,swap->I.myprivs[0],swap->bobdeposit.redeemscript,swap->bobdeposit.I.redeemlen); - memcpy(swap->I.userdata_bobrefund,userdata,len); - swap->I.userdata_bobrefundlen = 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->bobrefund,&swap->bobdeposit,swap->I.myprivs[0],0,userdata,len,0,swap->changermd160,swap->bobdeposit.I.destaddr,swap->bobcoin->zcash)) == 0 ) - { - for (i=0; ibobrefund.I.datalen; i++) - printf("%02x",swap->bobrefund.txbytes[i]); - printf(" <- bobrefund.(%s)\n",bits256_str(str,swap->bobrefund.I.txid)); - //basilisk_txlog(swap,&swap->bobrefund,delay); - return(retval); - } + uint8_t userdata[512]; int32_t i,retval,len = 0; char str[65]; struct iguana_info *coin; + if ( (coin= LP_coinfind(swap->I.bobstr)) != 0 ) + { + len = basilisk_swapuserdata(userdata,swap->I.privBn,0,swap->I.myprivs[0],swap->bobdeposit.redeemscript,swap->bobdeposit.I.redeemlen); + memcpy(swap->I.userdata_bobrefund,userdata,len); + swap->I.userdata_bobrefundlen = len; + if ( (retval= basilisk_rawtx_sign(coin->symbol,coin->wiftaddr,coin->taddr,coin->pubtype,coin->p2shtype,coin->isPoS,coin->wiftype,swap,&swap->bobrefund,&swap->bobdeposit,swap->I.myprivs[0],0,userdata,len,0,swap->changermd160,swap->bobdeposit.I.destaddr,coin->zcash)) == 0 ) + { + for (i=0; ibobrefund.I.datalen; i++) + printf("%02x",swap->bobrefund.txbytes[i]); + printf(" <- bobrefund.(%s)\n",bits256_str(str,swap->bobrefund.I.txid)); + //basilisk_txlog(swap,&swap->bobrefund,delay); + return(retval); + } + } else printf("basilisk_bobdeposit_refund cant find (%s)\n",swap->I.bobstr); + return(-1); } @@ -1673,81 +1681,84 @@ void LP_swap_coinaddr(struct iguana_info *coin,char *coinaddr,uint64_t *valuep,u int32_t basilisk_bobscripts_set(struct basilisk_swap *swap,int32_t depositflag,int32_t genflag) { - int32_t j; char coinaddr[64],checkaddr[64]; - bitcoin_address(coinaddr,swap->bobcoin->taddr,swap->bobcoin->pubtype,swap->changermd160,20); - if ( genflag != 0 && swap->I.iambob == 0 ) - printf("basilisk_bobscripts_set WARNING: alice generating BOB tx\n"); - if ( depositflag == 0 ) - { - swap->bobpayment.I.spendlen = basilisk_bobscript(swap->bobpayment.I.rmd160,swap->bobpayment.redeemscript,&swap->bobpayment.I.redeemlen,swap->bobpayment.spendscript,0,&swap->bobpayment.I.locktime,&swap->bobpayment.I.secretstart,&swap->I,0); - bitcoin_address(swap->bobpayment.p2shaddr,swap->bobcoin->taddr,swap->bobcoin->p2shtype,swap->bobpayment.redeemscript,swap->bobpayment.I.redeemlen); - strcpy(swap->bobpayment.I.destaddr,swap->bobpayment.p2shaddr); - //LP_importaddress(swap->bobcoin->symbol,swap->bobpayment.I.destaddr); - //int32_t i; for (i=0; ibobpayment.I.redeemlen; i++) - // printf("%02x",swap->bobpayment.redeemscript[i]); - //printf(" <- bobpayment redeem %d %s\n",i,swap->bobpayment.I.destaddr); - if ( genflag != 0 && bits256_nonz(*(bits256 *)swap->I.secretBn256) != 0 && swap->bobpayment.I.datalen == 0 ) - { - basilisk_rawtx_gen(swap->ctx,"payment",swap->I.started,swap->persistent_pubkey33,1,1,&swap->bobpayment,swap->bobpayment.I.locktime,swap->bobpayment.spendscript,swap->bobpayment.I.spendlen,swap->bobpayment.coin->txfee,1,0,swap->persistent_privkey,swap->changermd160,coinaddr); - if ( swap->bobpayment.I.spendlen == 0 || swap->bobpayment.I.datalen == 0 ) - { - printf("error bob generating %p payment.%d\n",swap->bobpayment.txbytes,swap->bobpayment.I.spendlen); - sleep(DEX_SLEEP); - } - else + int32_t j; char coinaddr[64],checkaddr[64]; struct iguana_info *coin; + if ( (coin= LP_coinfind(swap->I.bobstr)) != 0 ) + { + bitcoin_address(coinaddr,coin->taddr,coin->pubtype,swap->changermd160,20); + if ( genflag != 0 && swap->I.iambob == 0 ) + printf("basilisk_bobscripts_set WARNING: alice generating BOB tx\n"); + if ( depositflag == 0 ) + { + swap->bobpayment.I.spendlen = basilisk_bobscript(swap->bobpayment.I.rmd160,swap->bobpayment.redeemscript,&swap->bobpayment.I.redeemlen,swap->bobpayment.spendscript,0,&swap->bobpayment.I.locktime,&swap->bobpayment.I.secretstart,&swap->I,0); + bitcoin_address(swap->bobpayment.p2shaddr,coin->taddr,coin->p2shtype,swap->bobpayment.redeemscript,swap->bobpayment.I.redeemlen); + strcpy(swap->bobpayment.I.destaddr,swap->bobpayment.p2shaddr); + //LP_importaddress(coin->symbol,swap->bobpayment.I.destaddr); + //int32_t i; for (i=0; ibobpayment.I.redeemlen; i++) + // printf("%02x",swap->bobpayment.redeemscript[i]); + //printf(" <- bobpayment redeem %d %s\n",i,swap->bobpayment.I.destaddr); + if ( genflag != 0 && bits256_nonz(*(bits256 *)swap->I.secretBn256) != 0 && swap->bobpayment.I.datalen == 0 ) { - for (j=0; jbobpayment.I.datalen; j++) - printf("%02x",swap->bobpayment.txbytes[j]); - printf(" <- bobpayment.%d\n",swap->bobpayment.I.datalen); - for (j=0; jbobpayment.I.redeemlen; j++) - printf("%02x",swap->bobpayment.redeemscript[j]); - printf(" <- redeem.%d\n",swap->bobpayment.I.redeemlen); - printf(" <- GENERATED BOB PAYMENT.%d destaddr.(%s)\n",swap->bobpayment.I.datalen,swap->bobpayment.I.destaddr); - LP_swap_coinaddr(swap->bobcoin,checkaddr,0,swap->bobpayment.txbytes,swap->bobpayment.I.datalen,0); - if ( strcmp(swap->bobpayment.I.destaddr,checkaddr) != 0 ) + basilisk_rawtx_gen(swap->ctx,"payment",swap->I.started,swap->persistent_pubkey33,1,1,&swap->bobpayment,swap->bobpayment.I.locktime,swap->bobpayment.spendscript,swap->bobpayment.I.spendlen,coin->txfee,1,0,swap->persistent_privkey,swap->changermd160,coinaddr); + if ( swap->bobpayment.I.spendlen == 0 || swap->bobpayment.I.datalen == 0 ) { - printf("BOBPAYMENT REDEEMADDR MISMATCH??? %s != %s\n",swap->bobpayment.I.destaddr,checkaddr); - return(-1); + printf("error bob generating %p payment.%d\n",swap->bobpayment.txbytes,swap->bobpayment.I.spendlen); + sleep(DEX_SLEEP); + } + else + { + for (j=0; jbobpayment.I.datalen; j++) + printf("%02x",swap->bobpayment.txbytes[j]); + printf(" <- bobpayment.%d\n",swap->bobpayment.I.datalen); + for (j=0; jbobpayment.I.redeemlen; j++) + printf("%02x",swap->bobpayment.redeemscript[j]); + printf(" <- redeem.%d\n",swap->bobpayment.I.redeemlen); + printf(" <- GENERATED BOB PAYMENT.%d destaddr.(%s)\n",swap->bobpayment.I.datalen,swap->bobpayment.I.destaddr); + LP_swap_coinaddr(coin,checkaddr,0,swap->bobpayment.txbytes,swap->bobpayment.I.datalen,0); + if ( strcmp(swap->bobpayment.I.destaddr,checkaddr) != 0 ) + { + printf("BOBPAYMENT REDEEMADDR MISMATCH??? %s != %s\n",swap->bobpayment.I.destaddr,checkaddr); + return(-1); + } + LP_unspents_mark(coin->symbol,swap->bobpayment.vins); + //printf("bobscripts set completed\n"); + return(0); } - LP_unspents_mark(swap->bobcoin->symbol,swap->bobpayment.vins); - //printf("bobscripts set completed\n"); - return(0); } } - } - else - { - swap->bobdeposit.I.spendlen = basilisk_bobscript(swap->bobdeposit.I.rmd160,swap->bobdeposit.redeemscript,&swap->bobdeposit.I.redeemlen,swap->bobdeposit.spendscript,0,&swap->bobdeposit.I.locktime,&swap->bobdeposit.I.secretstart,&swap->I,1); - bitcoin_address(swap->bobdeposit.p2shaddr,swap->bobcoin->taddr,swap->bobcoin->p2shtype,swap->bobdeposit.redeemscript,swap->bobdeposit.I.redeemlen); - strcpy(swap->bobdeposit.I.destaddr,swap->bobdeposit.p2shaddr); - //int32_t i; for (i=0; ibobdeposit.I.redeemlen; i++) - // printf("%02x",swap->bobdeposit.redeemscript[i]); - //printf(" <- bobdeposit redeem %d %s\n",i,swap->bobdeposit.I.destaddr); - if ( genflag != 0 && (swap->bobdeposit.I.datalen == 0 || swap->bobrefund.I.datalen == 0) ) + else { - basilisk_rawtx_gen(swap->ctx,"deposit",swap->I.started,swap->persistent_pubkey33,1,1,&swap->bobdeposit,swap->bobdeposit.I.locktime,swap->bobdeposit.spendscript,swap->bobdeposit.I.spendlen,swap->bobdeposit.coin->txfee,1,0,swap->persistent_privkey,swap->changermd160,coinaddr); - if ( swap->bobdeposit.I.datalen == 0 || swap->bobdeposit.I.spendlen == 0 ) + swap->bobdeposit.I.spendlen = basilisk_bobscript(swap->bobdeposit.I.rmd160,swap->bobdeposit.redeemscript,&swap->bobdeposit.I.redeemlen,swap->bobdeposit.spendscript,0,&swap->bobdeposit.I.locktime,&swap->bobdeposit.I.secretstart,&swap->I,1); + bitcoin_address(swap->bobdeposit.p2shaddr,coin->taddr,coin->p2shtype,swap->bobdeposit.redeemscript,swap->bobdeposit.I.redeemlen); + strcpy(swap->bobdeposit.I.destaddr,swap->bobdeposit.p2shaddr); + //int32_t i; for (i=0; ibobdeposit.I.redeemlen; i++) + // printf("%02x",swap->bobdeposit.redeemscript[i]); + //printf(" <- bobdeposit redeem %d %s\n",i,swap->bobdeposit.I.destaddr); + if ( genflag != 0 && (swap->bobdeposit.I.datalen == 0 || swap->bobrefund.I.datalen == 0) ) { - printf("error bob generating %p deposit.%d\n",swap->bobdeposit.txbytes,swap->bobdeposit.I.spendlen); - sleep(DEX_SLEEP); - } - else - { - for (j=0; jbobdeposit.I.datalen; j++) - printf("%02x",swap->bobdeposit.txbytes[j]); - printf(" <- GENERATED BOB DEPOSIT.%d (%s)\n",swap->bobdeposit.I.datalen,swap->bobdeposit.I.destaddr); - LP_swap_coinaddr(swap->bobcoin,checkaddr,0,swap->bobdeposit.txbytes,swap->bobdeposit.I.datalen,0); - if ( strcmp(swap->bobdeposit.I.destaddr,checkaddr) != 0 ) + basilisk_rawtx_gen(swap->ctx,"deposit",swap->I.started,swap->persistent_pubkey33,1,1,&swap->bobdeposit,swap->bobdeposit.I.locktime,swap->bobdeposit.spendscript,swap->bobdeposit.I.spendlen,coin->txfee,1,0,swap->persistent_privkey,swap->changermd160,coinaddr); + if ( swap->bobdeposit.I.datalen == 0 || swap->bobdeposit.I.spendlen == 0 ) { - printf("BOBDEPOSIT REDEEMADDR MISMATCH??? %s != %s\n",swap->bobdeposit.I.destaddr,checkaddr); - return(-1); + printf("error bob generating %p deposit.%d\n",swap->bobdeposit.txbytes,swap->bobdeposit.I.spendlen); + sleep(DEX_SLEEP); + } + else + { + for (j=0; jbobdeposit.I.datalen; j++) + printf("%02x",swap->bobdeposit.txbytes[j]); + printf(" <- GENERATED BOB DEPOSIT.%d (%s)\n",swap->bobdeposit.I.datalen,swap->bobdeposit.I.destaddr); + LP_swap_coinaddr(coin,checkaddr,0,swap->bobdeposit.txbytes,swap->bobdeposit.I.datalen,0); + if ( strcmp(swap->bobdeposit.I.destaddr,checkaddr) != 0 ) + { + printf("BOBDEPOSIT REDEEMADDR MISMATCH??? %s != %s\n",swap->bobdeposit.I.destaddr,checkaddr); + return(-1); + } + LP_unspents_mark(coin->symbol,swap->bobdeposit.vins); + printf("bobscripts set completed\n"); + return(0); } - LP_unspents_mark(swap->bobcoin->symbol,swap->bobdeposit.vins); - printf("bobscripts set completed\n"); - return(0); } } - } + } else printf("bobscripts set cant find (%s)\n",swap->I.bobstr); return(0); } @@ -1758,7 +1769,7 @@ int32_t basilisk_alicepayment_spend(struct basilisk_swap *swap,struct basilisk_r { int32_t i,retval; printf("alicepayment_spend\n"); - swap->alicepayment.I.spendlen = basilisk_alicescript(swap->alicepayment.redeemscript,&swap->alicepayment.I.redeemlen,swap->alicepayment.spendscript,0,swap->alicepayment.I.destaddr,swap->alicecoin->p2shtype,swap->I.pubAm,swap->I.pubBn); + swap->alicepayment.I.spendlen = basilisk_alicescript(swap->alicepayment.redeemscript,&swap->alicepayment.I.redeemlen,swap->alicepayment.spendscript,0,swap->alicepayment.I.destaddr,coin->p2shtype,swap->I.pubAm,swap->I.pubBn); printf("alicepayment_spend len.%d\n",swap->alicepayment.I.spendlen); if ( swap->I.iambob == 0 ) { @@ -1770,7 +1781,7 @@ int32_t basilisk_alicepayment_spend(struct basilisk_swap *swap,struct basilisk_r memcpy(swap->I.userdata_bobspend,swap->alicepayment.redeemscript,swap->alicepayment.I.spendlen); swap->I.userdata_bobspendlen = swap->alicepayment.I.spendlen; } - if ( (retval= basilisk_rawtx_sign(swap->alicecoin->symbol,swap->alicecoin->pubtype,swap->alicecoin->p2shtype,swap->alicecoin->isPoS,swap->alicecoin->wiftype,swap,dest,&swap->alicepayment,swap->I.privAm,&swap->I.privBn,0,0,1,swap->changermd160)) == 0 ) + if ( (retval= basilisk_rawtx_sign(coin->symbol,coin->pubtype,coin->p2shtype,coin->isPoS,coin->wiftype,swap,dest,&swap->alicepayment,swap->I.privAm,&swap->I.privBn,0,0,1,swap->changermd160)) == 0 ) { for (i=0; iI.datalen; i++) printf("%02x",dest->txbytes[i]); @@ -1795,84 +1806,94 @@ void basilisk_alicepayment(struct basilisk_swap *swap,struct iguana_info *coin,s int32_t basilisk_alicetxs(int32_t pairsock,struct basilisk_swap *swap,uint8_t *data,int32_t maxlen) { - char coinaddr[64]; int32_t i,retval = -1; - if ( swap->alicepayment.I.datalen == 0 ) - basilisk_alicepayment(swap,swap->alicepayment.coin,&swap->alicepayment,swap->I.pubAm,swap->I.pubBn); - if ( swap->alicepayment.I.datalen == 0 || swap->alicepayment.I.spendlen == 0 ) - printf("error alice generating payment.%d\n",swap->alicepayment.I.spendlen); - else + char coinaddr[64]; int32_t i,retval = -1; struct iguana_info *coin; + if ( (coin= LP_coinfind(swap->I.alicestr)) != 0 ) { - bitcoin_address(swap->alicepayment.I.destaddr,swap->alicecoin->taddr,swap->alicecoin->p2shtype,swap->alicepayment.redeemscript,swap->alicepayment.I.redeemlen); - //LP_importaddress(swap->alicecoin->symbol,swap->alicepayment.I.destaddr); - strcpy(swap->alicepayment.p2shaddr,swap->alicepayment.I.destaddr); - retval = 0; - for (i=0; ialicepayment.I.datalen; i++) - printf("%02x",swap->alicepayment.txbytes[i]); - printf(" ALICE PAYMENT created.(%s)\n",swap->alicepayment.I.destaddr); - LP_unspents_mark(swap->alicecoin->symbol,swap->alicepayment.vins); - //LP_importaddress(swap->alicecoin->symbol,swap->alicepayment.I.destaddr); - //basilisk_txlog(swap,&swap->alicepayment,-1); - } - if ( swap->myfee.I.datalen == 0 ) - { - printf("%s generate fee %.8f from.%s\n",swap->alicecoin->symbol,dstr(strcmp(swap->myfee.coin->symbol,"BTC") == 0 ? LP_MIN_TXFEE : swap->myfee.coin->txfee),swap->alicecoin->smartaddr); - bitcoin_address(coinaddr,swap->alicecoin->taddr,swap->alicecoin->pubtype,swap->changermd160,20); - if ( basilisk_rawtx_gen(swap->ctx,"myfee",swap->I.started,swap->persistent_pubkey33,swap->I.iambob,1,&swap->myfee,swap->myfee.I.locktime,swap->myfee.spendscript,swap->myfee.I.spendlen,strcmp(swap->myfee.coin->symbol,"BTC") == 0 ? LP_MIN_TXFEE : swap->myfee.coin->txfee,1,0,swap->persistent_privkey,swap->changermd160,coinaddr) == 0 ) - { - printf("rawtxsend %s %.8f\n",swap->myfee.coin->symbol,dstr(strcmp(swap->myfee.coin->symbol,"BTC") == 0 ? LP_MIN_TXFEE : swap->myfee.coin->txfee)); - swap->I.statebits |= LP_swapdata_rawtxsend(pairsock,swap,0x80,data,maxlen,&swap->myfee,0x40,0); - LP_unspents_mark(swap->I.iambob!=0?swap->bobcoin->symbol:swap->alicecoin->symbol,swap->myfee.vins); - //basilisk_txlog(swap,&swap->myfee,-1); - for (i=0; imyfee.I.datalen; i++) - printf("%02x",swap->myfee.txbytes[i]); - printf(" <- fee state.%x\n",swap->I.statebits); - swap->I.statebits |= 0x40; - } + if ( swap->alicepayment.I.datalen == 0 ) + basilisk_alicepayment(swap,coin,&swap->alicepayment,swap->I.pubAm,swap->I.pubBn); + if ( swap->alicepayment.I.datalen == 0 || swap->alicepayment.I.spendlen == 0 ) + printf("error alice generating payment.%d\n",swap->alicepayment.I.spendlen); else { - printf("error creating myfee\n"); - return(-2); + bitcoin_address(swap->alicepayment.I.destaddr,coin->taddr,coin->p2shtype,swap->alicepayment.redeemscript,swap->alicepayment.I.redeemlen); + //LP_importaddress(coin->symbol,swap->alicepayment.I.destaddr); + strcpy(swap->alicepayment.p2shaddr,swap->alicepayment.I.destaddr); + retval = 0; + for (i=0; ialicepayment.I.datalen; i++) + printf("%02x",swap->alicepayment.txbytes[i]); + printf(" ALICE PAYMENT created.(%s)\n",swap->alicepayment.I.destaddr); + LP_unspents_mark(coin->symbol,swap->alicepayment.vins); + //LP_importaddress(coin->symbol,swap->alicepayment.I.destaddr); + //basilisk_txlog(swap,&swap->alicepayment,-1); } - } - if ( swap->alicepayment.I.datalen != 0 && swap->alicepayment.I.spendlen > 0 && swap->myfee.I.datalen != 0 && swap->myfee.I.spendlen > 0 ) - { - printf("fee sent\n"); - return(0); - } + if ( swap->myfee.I.datalen == 0 ) + { + printf("%s generate fee %.8f from.%s\n",coin->symbol,dstr(strcmp(coin->symbol,"BTC") == 0 ? LP_MIN_TXFEE : coin->txfee),coin->smartaddr); + bitcoin_address(coinaddr,coin->taddr,coin->pubtype,swap->changermd160,20); + if ( basilisk_rawtx_gen(swap->ctx,"myfee",swap->I.started,swap->persistent_pubkey33,swap->I.iambob,1,&swap->myfee,swap->myfee.I.locktime,swap->myfee.spendscript,swap->myfee.I.spendlen,strcmp(coin->symbol,"BTC") == 0 ? LP_MIN_TXFEE : coin->txfee,1,0,swap->persistent_privkey,swap->changermd160,coinaddr) == 0 ) + { + printf("rawtxsend %s %.8f\n",coin->symbol,dstr(strcmp(coin->symbol,"BTC") == 0 ? LP_MIN_TXFEE : coin->txfee)); + swap->I.statebits |= LP_swapdata_rawtxsend(pairsock,swap,0x80,data,maxlen,&swap->myfee,0x40,0); + LP_unspents_mark(swap->I.iambob!=0?coin->symbol:coin->symbol,swap->myfee.vins); + //basilisk_txlog(swap,&swap->myfee,-1); + for (i=0; imyfee.I.datalen; i++) + printf("%02x",swap->myfee.txbytes[i]); + printf(" <- fee state.%x\n",swap->I.statebits); + swap->I.statebits |= 0x40; + } + else + { + printf("error creating myfee\n"); + return(-2); + } + } + if ( swap->alicepayment.I.datalen != 0 && swap->alicepayment.I.spendlen > 0 && swap->myfee.I.datalen != 0 && swap->myfee.I.spendlen > 0 ) + { + printf("fee sent\n"); + return(0); + } + } else printf("basilisk alicetx cant find (%s)\n",swap->I.alicestr); return(-1); } int32_t LP_verify_otherfee(struct basilisk_swap *swap,uint8_t *data,int32_t datalen) { - int32_t diff; - if ( LP_rawtx_spendscript(swap,swap->bobcoin->longestchain,&swap->otherfee,0,data,datalen,0) == 0 ) - { - printf("otherfee amount %.8f -> %s vs %s locktime %u vs %u\n",dstr(swap->otherfee.I.amount),swap->otherfee.p2shaddr,swap->otherfee.I.destaddr,swap->otherfee.I.locktime,swap->I.started+1); - if ( strcmp(swap->otherfee.I.destaddr,swap->otherfee.p2shaddr) == 0 ) - { - diff = swap->otherfee.I.locktime - (swap->I.started+1); - if ( diff < 0 ) - diff = -diff; - if ( diff < 10 ) - printf("dexfee verified\n"); - else printf("locktime mismatch in otherfee, reject %u vs %u\n",swap->otherfee.I.locktime,swap->I.started+1); - return(0); - } else printf("destaddress mismatch in other fee, reject (%s) vs (%s)\n",swap->otherfee.I.destaddr,swap->otherfee.p2shaddr); - } + int32_t diff; struct iguana_info *coin; + if ( (coin= LP_coinfind(swap->I.iambob != 0 ? swap->I.alicestr : swap->I.bobstr)) != 0 ) + { + if ( LP_rawtx_spendscript(swap,coin->longestchain,&swap->otherfee,0,data,datalen,0) == 0 ) + { + printf("otherfee amount %.8f -> %s vs %s locktime %u vs %u\n",dstr(swap->otherfee.I.amount),swap->otherfee.p2shaddr,swap->otherfee.I.destaddr,swap->otherfee.I.locktime,swap->I.started+1); + if ( strcmp(swap->otherfee.I.destaddr,swap->otherfee.p2shaddr) == 0 ) + { + diff = swap->otherfee.I.locktime - (swap->I.started+1); + if ( diff < 0 ) + diff = -diff; + if ( diff < 10 ) + printf("dexfee verified\n"); + else printf("locktime mismatch in otherfee, reject %u vs %u\n",swap->otherfee.I.locktime,swap->I.started+1); + return(0); + } else printf("destaddress mismatch in other fee, reject (%s) vs (%s)\n",swap->otherfee.I.destaddr,swap->otherfee.p2shaddr); + } + } else printf("cant find other coin iambob.%d\n",swap->I.iambob); 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 ) + struct iguana_info *coin; + if ( (coin= LP_coinfind(swap->I.alicestr)) != 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 ) + if ( LP_rawtx_spendscript(swap,coin->longestchain,&swap->alicespend,0,data,datalen,0) == 0 ) { - printf("alicespend verified\n"); - return(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); + } } - } + } else printf("verify alicespend cant find (%s)\n",swap->I.alicestr); return(-1); } @@ -1885,109 +1906,120 @@ int32_t LP_verify_alicespend(struct basilisk_swap *swap,uint8_t *data,int32_t da int32_t LP_verify_bobdeposit(struct basilisk_swap *swap,uint8_t *data,int32_t datalen) { - uint8_t userdata[512]; int32_t retval=-1,len = 0; static bits256 zero; - if ( LP_rawtx_spendscript(swap,swap->bobcoin->longestchain,&swap->bobdeposit,0,data,datalen,0) == 0 ) - { - swap->aliceclaim.utxovout = 0; - swap->bobdeposit.I.signedtxid = LP_broadcast_tx(swap->bobdeposit.name,swap->bobcoin->symbol,swap->bobdeposit.txbytes,swap->bobdeposit.I.datalen); - if ( bits256_nonz(swap->bobdeposit.I.signedtxid) != 0 ) - swap->depositunconf = 1; - else swap->bobdeposit.I.signedtxid = swap->bobdeposit.I.actualtxid; - len = basilisk_swapuserdata(userdata,zero,1,swap->I.myprivs[0],swap->bobdeposit.redeemscript,swap->bobdeposit.I.redeemlen); - swap->aliceclaim.utxotxid = swap->bobdeposit.I.signedtxid; - memcpy(swap->I.userdata_aliceclaim,userdata,len); - swap->I.userdata_aliceclaimlen = len; - bitcoin_address(swap->bobdeposit.p2shaddr,swap->bobcoin->taddr,swap->bobcoin->p2shtype,swap->bobdeposit.redeemscript,swap->bobdeposit.I.redeemlen); - strcpy(swap->bobdeposit.I.destaddr,swap->bobdeposit.p2shaddr); - basilisk_dontforget_update(swap,&swap->bobdeposit); - //int32_t i; char str[65]; for (i=0; ibobdeposit.I.datalen; i++) - // printf("%02x",swap->bobdeposit.txbytes[i]); - //printf(" <- bobdeposit.%d %s\n",swap->bobdeposit.I.datalen,bits256_str(str,swap->bobdeposit.I.signedtxid)); - //for (i=0; ibobdeposit.I.redeemlen; i++) - // printf("%02x",swap->bobdeposit.redeemscript[i]); - //printf(" <- bobdeposit redeem %d %s suppress.%d\n",i,swap->bobdeposit.I.destaddr,swap->aliceclaim.I.suppress_pubkeys); - memcpy(swap->aliceclaim.redeemscript,swap->bobdeposit.redeemscript,swap->bobdeposit.I.redeemlen); - swap->aliceclaim.I.redeemlen = swap->bobdeposit.I.redeemlen; - memcpy(swap->aliceclaim.I.pubkey33,swap->persistent_pubkey33,33); - bitcoin_address(swap->aliceclaim.I.destaddr,swap->alicecoin->taddr,swap->alicecoin->pubtype,swap->persistent_pubkey33,33); - retval = 0; - 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->aliceclaim,&swap->bobdeposit,swap->I.myprivs[0],0,userdata,len,1,swap->changermd160,swap->bobdeposit.I.destaddr,swap->bobcoin->zcash)) == 0 ) - { - int32_t i; for (i=0; ibobdeposit.I.datalen; i++) - printf("%02x",swap->bobdeposit.txbytes[i]); - printf(" <- bobdeposit\n"); - for (i=0; ialiceclaim.I.datalen; i++) - printf("%02x",swap->aliceclaim.txbytes[i]); - printf(" <- aliceclaim\n"); - //basilisk_txlog(swap,&swap->aliceclaim,swap->I.putduration+swap->I.callduration); - return(LP_waitmempool(swap->bobcoin->symbol,swap->bobdeposit.I.destaddr,swap->bobdeposit.I.signedtxid,0,60)); - } else printf("error signing aliceclaim suppress.%d vin.(%s)\n",swap->aliceclaim.I.suppress_pubkeys,swap->bobdeposit.I.destaddr); - } + static bits256 zero; + uint8_t userdata[512]; int32_t retval=-1,len = 0; struct iguana_info *coin; + if ( (coin= LP_coinfind(swap->I.bobstr)) != 0 ) + { + if ( LP_rawtx_spendscript(swap,coin->longestchain,&swap->bobdeposit,0,data,datalen,0) == 0 ) + { + swap->aliceclaim.utxovout = 0; + swap->bobdeposit.I.signedtxid = LP_broadcast_tx(swap->bobdeposit.name,coin->symbol,swap->bobdeposit.txbytes,swap->bobdeposit.I.datalen); + if ( bits256_nonz(swap->bobdeposit.I.signedtxid) != 0 ) + swap->depositunconf = 1; + else swap->bobdeposit.I.signedtxid = swap->bobdeposit.I.actualtxid; + len = basilisk_swapuserdata(userdata,zero,1,swap->I.myprivs[0],swap->bobdeposit.redeemscript,swap->bobdeposit.I.redeemlen); + swap->aliceclaim.utxotxid = swap->bobdeposit.I.signedtxid; + memcpy(swap->I.userdata_aliceclaim,userdata,len); + swap->I.userdata_aliceclaimlen = len; + bitcoin_address(swap->bobdeposit.p2shaddr,coin->taddr,coin->p2shtype,swap->bobdeposit.redeemscript,swap->bobdeposit.I.redeemlen); + strcpy(swap->bobdeposit.I.destaddr,swap->bobdeposit.p2shaddr); + basilisk_dontforget_update(swap,&swap->bobdeposit); + //int32_t i; char str[65]; for (i=0; ibobdeposit.I.datalen; i++) + // printf("%02x",swap->bobdeposit.txbytes[i]); + //printf(" <- bobdeposit.%d %s\n",swap->bobdeposit.I.datalen,bits256_str(str,swap->bobdeposit.I.signedtxid)); + //for (i=0; ibobdeposit.I.redeemlen; i++) + // printf("%02x",swap->bobdeposit.redeemscript[i]); + //printf(" <- bobdeposit redeem %d %s suppress.%d\n",i,swap->bobdeposit.I.destaddr,swap->aliceclaim.I.suppress_pubkeys); + memcpy(swap->aliceclaim.redeemscript,swap->bobdeposit.redeemscript,swap->bobdeposit.I.redeemlen); + swap->aliceclaim.I.redeemlen = swap->bobdeposit.I.redeemlen; + memcpy(swap->aliceclaim.I.pubkey33,swap->persistent_pubkey33,33); + bitcoin_address(swap->aliceclaim.I.destaddr,coin->taddr,coin->pubtype,swap->persistent_pubkey33,33); + retval = 0; + if ( (retval= basilisk_rawtx_sign(coin->symbol,coin->wiftaddr,coin->taddr,coin->pubtype,coin->p2shtype,coin->isPoS,coin->wiftype,swap,&swap->aliceclaim,&swap->bobdeposit,swap->I.myprivs[0],0,userdata,len,1,swap->changermd160,swap->bobdeposit.I.destaddr,coin->zcash)) == 0 ) + { + int32_t i; for (i=0; ibobdeposit.I.datalen; i++) + printf("%02x",swap->bobdeposit.txbytes[i]); + printf(" <- bobdeposit\n"); + for (i=0; ialiceclaim.I.datalen; i++) + printf("%02x",swap->aliceclaim.txbytes[i]); + printf(" <- aliceclaim\n"); + //basilisk_txlog(swap,&swap->aliceclaim,swap->I.putduration+swap->I.callduration); + return(LP_waitmempool(coin->symbol,swap->bobdeposit.I.destaddr,swap->bobdeposit.I.signedtxid,0,60)); + } else printf("error signing aliceclaim suppress.%d vin.(%s)\n",swap->aliceclaim.I.suppress_pubkeys,swap->bobdeposit.I.destaddr); + } + } else printf("verify bob depositcant find bob coin (%s)\n",swap->I.bobstr); printf("error with bobdeposit\n"); return(retval); } int32_t LP_verify_alicepayment(struct basilisk_swap *swap,uint8_t *data,int32_t datalen) { - if ( LP_rawtx_spendscript(swap,swap->alicecoin->longestchain,&swap->alicepayment,0,data,datalen,0) == 0 ) - { - swap->bobspend.utxovout = 0; - swap->bobspend.utxotxid = swap->alicepayment.I.signedtxid = LP_broadcast_tx(swap->alicepayment.name,swap->alicecoin->symbol,swap->alicepayment.txbytes,swap->alicepayment.I.datalen); - bitcoin_address(swap->alicepayment.p2shaddr,swap->alicecoin->taddr,swap->alicecoin->p2shtype,swap->alicepayment.redeemscript,swap->alicepayment.I.redeemlen); - strcpy(swap->alicepayment.I.destaddr,swap->alicepayment.p2shaddr); - if ( bits256_nonz(swap->alicepayment.I.signedtxid) != 0 ) - swap->aliceunconf = 1; - basilisk_dontforget_update(swap,&swap->alicepayment); - return(LP_waitmempool(swap->alicecoin->symbol,swap->alicepayment.I.destaddr,swap->alicepayment.I.signedtxid,0,60)); - //printf("import alicepayment address.(%s)\n",swap->alicepayment.p2shaddr); - //LP_importaddress(swap->alicecoin->symbol,swap->alicepayment.p2shaddr); - return(0); - } + struct iguana_info *coin; + if ( (coin= LP_coinfind(swap->I.alicestr)) != 0 ) + { + if ( LP_rawtx_spendscript(swap,coin->longestchain,&swap->alicepayment,0,data,datalen,0) == 0 ) + { + swap->bobspend.utxovout = 0; + swap->bobspend.utxotxid = swap->alicepayment.I.signedtxid = LP_broadcast_tx(swap->alicepayment.name,coin->symbol,swap->alicepayment.txbytes,swap->alicepayment.I.datalen); + bitcoin_address(swap->alicepayment.p2shaddr,coin->taddr,coin->p2shtype,swap->alicepayment.redeemscript,swap->alicepayment.I.redeemlen); + strcpy(swap->alicepayment.I.destaddr,swap->alicepayment.p2shaddr); + if ( bits256_nonz(swap->alicepayment.I.signedtxid) != 0 ) + swap->aliceunconf = 1; + basilisk_dontforget_update(swap,&swap->alicepayment); + return(LP_waitmempool(coin->symbol,swap->alicepayment.I.destaddr,swap->alicepayment.I.signedtxid,0,60)); + //printf("import alicepayment address.(%s)\n",swap->alicepayment.p2shaddr); + //LP_importaddress(coin->symbol,swap->alicepayment.p2shaddr); + return(0); + } + } else printf("verify alicepayment couldnt find coin.(%s)\n",swap->I.alicestr); printf("error validating alicepayment\n"); return(-1); } int32_t LP_verify_bobpayment(struct basilisk_swap *swap,uint8_t *data,int32_t datalen) { - uint8_t userdata[512]; int32_t i,retval=-1,len = 0; bits256 revAm; - memset(revAm.bytes,0,sizeof(revAm)); - if ( LP_rawtx_spendscript(swap,swap->bobcoin->longestchain,&swap->bobpayment,0,data,datalen,0) == 0 ) - { - swap->alicespend.utxovout = 0; - swap->alicespend.utxotxid = swap->bobpayment.I.signedtxid = LP_broadcast_tx(swap->bobpayment.name,swap->bobpayment.coin->symbol,swap->bobpayment.txbytes,swap->bobpayment.I.datalen); - if ( bits256_nonz(swap->bobpayment.I.signedtxid) != 0 ) - swap->paymentunconf = 1; - for (i=0; i<32; i++) - revAm.bytes[i] = swap->I.privAm.bytes[31-i]; - len = basilisk_swapuserdata(userdata,revAm,0,swap->I.myprivs[0],swap->bobpayment.redeemscript,swap->bobpayment.I.redeemlen); - bitcoin_address(swap->bobpayment.p2shaddr,swap->bobcoin->taddr,swap->bobcoin->p2shtype,swap->bobpayment.redeemscript,swap->bobpayment.I.redeemlen); - strcpy(swap->bobpayment.I.destaddr,swap->bobpayment.p2shaddr); - basilisk_dontforget_update(swap,&swap->bobpayment); - //LP_importaddress(swap->bobcoin->symbol,swap->bobpayment.I.destaddr); - /*for (i=0; ibobpayment.I.datalen; i++) - printf("%02x",swap->bobpayment.txbytes[i]); - printf(" <- bobpayment.%d\n",swap->bobpayment.I.datalen); - for (i=0; ibobpayment.I.redeemlen; i++) - printf("%02x",swap->bobpayment.redeemscript[i]); - printf(" <- bobpayment redeem %d %s %s\n",i,swap->bobpayment.I.destaddr,bits256_str(str,swap->bobpayment.I.signedtxid));*/ - memcpy(swap->I.userdata_alicespend,userdata,len); - swap->I.userdata_alicespendlen = len; - retval = 0; - memcpy(swap->alicespend.I.pubkey33,swap->persistent_pubkey33,33); - bitcoin_address(swap->alicespend.I.destaddr,swap->bobcoin->taddr,swap->bobcoin->pubtype,swap->persistent_pubkey33,33); - //char str[65],str2[65]; printf("bobpaid privAm.(%s) myprivs[0].(%s)\n",bits256_str(str,swap->I.privAm),bits256_str(str2,swap->I.myprivs[0])); - 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->alicespend,&swap->bobpayment,swap->I.myprivs[0],0,userdata,len,1,swap->changermd160,swap->alicepayment.I.destaddr,swap->bobcoin->zcash)) == 0 ) + uint8_t userdata[512]; int32_t i,retval=-1,len = 0; bits256 revAm; struct iguana_info *coin; + if ( (coin= LP_coinfind(swap->I.bobstr)) != 0 ) + { + memset(revAm.bytes,0,sizeof(revAm)); + if ( LP_rawtx_spendscript(swap,coin->longestchain,&swap->bobpayment,0,data,datalen,0) == 0 ) { + swap->alicespend.utxovout = 0; + swap->alicespend.utxotxid = swap->bobpayment.I.signedtxid = LP_broadcast_tx(swap->bobpayment.name,coin->symbol,swap->bobpayment.txbytes,swap->bobpayment.I.datalen); + if ( bits256_nonz(swap->bobpayment.I.signedtxid) != 0 ) + swap->paymentunconf = 1; + for (i=0; i<32; i++) + revAm.bytes[i] = swap->I.privAm.bytes[31-i]; + len = basilisk_swapuserdata(userdata,revAm,0,swap->I.myprivs[0],swap->bobpayment.redeemscript,swap->bobpayment.I.redeemlen); + bitcoin_address(swap->bobpayment.p2shaddr,coin->taddr,coin->p2shtype,swap->bobpayment.redeemscript,swap->bobpayment.I.redeemlen); + strcpy(swap->bobpayment.I.destaddr,swap->bobpayment.p2shaddr); + basilisk_dontforget_update(swap,&swap->bobpayment); + //LP_importaddress(coin->symbol,swap->bobpayment.I.destaddr); /*for (i=0; ibobpayment.I.datalen; i++) - printf("%02x",swap->bobpayment.txbytes[i]); - printf(" <- bobpayment\n"); - for (i=0; ialicespend.I.datalen; i++) - printf("%02x",swap->alicespend.txbytes[i]); - printf(" <- alicespend\n\n");*/ - swap->I.alicespent = 1; - return(LP_waitmempool(swap->bobcoin->symbol,swap->bobpayment.I.destaddr,swap->bobpayment.I.signedtxid,0,60)); - } else printf("error signing aliceclaim suppress.%d vin.(%s)\n",swap->alicespend.I.suppress_pubkeys,swap->bobpayment.I.destaddr); - } + printf("%02x",swap->bobpayment.txbytes[i]); + printf(" <- bobpayment.%d\n",swap->bobpayment.I.datalen); + for (i=0; ibobpayment.I.redeemlen; i++) + printf("%02x",swap->bobpayment.redeemscript[i]); + printf(" <- bobpayment redeem %d %s %s\n",i,swap->bobpayment.I.destaddr,bits256_str(str,swap->bobpayment.I.signedtxid));*/ + memcpy(swap->I.userdata_alicespend,userdata,len); + swap->I.userdata_alicespendlen = len; + retval = 0; + memcpy(swap->alicespend.I.pubkey33,swap->persistent_pubkey33,33); + bitcoin_address(swap->alicespend.I.destaddr,coin->taddr,coin->pubtype,swap->persistent_pubkey33,33); + //char str[65],str2[65]; printf("bobpaid privAm.(%s) myprivs[0].(%s)\n",bits256_str(str,swap->I.privAm),bits256_str(str2,swap->I.myprivs[0])); + if ( (retval= basilisk_rawtx_sign(coin->symbol,coin->wiftaddr,coin->taddr,coin->pubtype,coin->p2shtype,coin->isPoS,coin->wiftype,swap,&swap->alicespend,&swap->bobpayment,swap->I.myprivs[0],0,userdata,len,1,swap->changermd160,swap->alicepayment.I.destaddr,coin->zcash)) == 0 ) + { + /*for (i=0; ibobpayment.I.datalen; i++) + printf("%02x",swap->bobpayment.txbytes[i]); + printf(" <- bobpayment\n"); + for (i=0; ialicespend.I.datalen; i++) + printf("%02x",swap->alicespend.txbytes[i]); + printf(" <- alicespend\n\n");*/ + swap->I.alicespent = 1; + return(LP_waitmempool(coin->symbol,swap->bobpayment.I.destaddr,swap->bobpayment.I.signedtxid,0,60)); + } else printf("error signing aliceclaim suppress.%d vin.(%s)\n",swap->alicespend.I.suppress_pubkeys,swap->bobpayment.I.destaddr); + } + } else printf("verify bobpayment cant find (%s)\n",swap->I.bobstr); printf("error validating bobpayment\n"); return(-1); } From 574014c366ce041e09487bab4416a7913d0d379c Mon Sep 17 00:00:00 2001 From: jl777 Date: Tue, 14 Nov 2017 02:43:17 +0200 Subject: [PATCH 0726/1664] Test --- iguana/exchanges/LP_nativeDEX.c | 2 +- iguana/exchanges/LP_ordermatch.c | 1 + 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/iguana/exchanges/LP_nativeDEX.c b/iguana/exchanges/LP_nativeDEX.c index 430b104dd..497aebe75 100644 --- a/iguana/exchanges/LP_nativeDEX.c +++ b/iguana/exchanges/LP_nativeDEX.c @@ -133,7 +133,7 @@ char GLOBAL_DBDIR[] = { "DB" }; char LP_myipaddr[64],LP_publicaddr[64],USERHOME[512] = { "/root" }; char LP_gui[16] = { "cli" }; -char *default_LPnodes[] = { "5.9.253.195", "5.9.253.196", //"5.9.253.197", "5.9.253.198", "5.9.253.199", "5.9.253.200", "5.9.253.201", "5.9.253.202", "5.9.253.203", +char *default_LPnodes[] = { "5.9.253.195", "5.9.253.196", "5.9.253.197", "5.9.253.198", "5.9.253.199", "5.9.253.200", "5.9.253.201", "5.9.253.202", "5.9.253.203", //"24.54.206.138", "173.212.225.176", "136.243.45.140", "107.72.162.127", "72.50.16.86", "51.15.202.191", "173.228.198.88", "51.15.203.171", "51.15.86.136", "51.15.94.249", "51.15.80.18", "51.15.91.40", "51.15.54.2", "51.15.86.31", "51.15.82.29", "51.15.89.155", };//"5.9.253.204" }; // diff --git a/iguana/exchanges/LP_ordermatch.c b/iguana/exchanges/LP_ordermatch.c index f65f88370..4f99f2298 100644 --- a/iguana/exchanges/LP_ordermatch.c +++ b/iguana/exchanges/LP_ordermatch.c @@ -158,6 +158,7 @@ double LP_quote_validate(struct LP_utxoinfo *autxo,struct LP_utxoinfo *butxo,str { if ( LP_iseligible(&destvalue,&destvalue2,0,qp->destcoin,qp->desttxid,qp->destvout,qp->destsatoshis,qp->feetxid,qp->feevout) == 0 ) { + //alice not eligible 0.36893923 -> dest 0.55020000 1.49130251 (0.61732249 0.00104324) 14b8b74808d2d34a70e5eddd1cad47d855858f8b23cac802576d4d37b5f8af8f/v1 abec6e76169bcb738235ca67fab02cc55390f39e422aa71f1badf8747c290cc4/v1 char str[65],str2[65]; printf("alice not eligible %.8f -> dest %.8f %.8f (%.8f %.8f) %s/v%d %s/v%d\n",dstr(qp->satoshis),dstr(qp->destsatoshis),(double)qp->destsatoshis/qp->satoshis,dstr(destvalue),dstr(destvalue2),bits256_str(str,qp->desttxid),qp->destvout,bits256_str(str2,qp->feetxid),qp->feevout); return(-3); } From 6e73032283844d668b7e0f78d08fee596c85f3d3 Mon Sep 17 00:00:00 2001 From: jl777 Date: Tue, 14 Nov 2017 02:45:42 +0200 Subject: [PATCH 0727/1664] Test --- iguana/exchanges/LP_transaction.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/iguana/exchanges/LP_transaction.c b/iguana/exchanges/LP_transaction.c index c2a07a804..82120368d 100644 --- a/iguana/exchanges/LP_transaction.c +++ b/iguana/exchanges/LP_transaction.c @@ -1230,8 +1230,8 @@ int32_t basilisk_rawtx_gen(void *ctx,char *str,uint32_t swapstarted,uint8_t *pub return(-1); if ( strcmp(coin->smartaddr,vinaddr) != 0 ) { - printf("???????????????????????? basilisk_rawtx_gen mismatched %s vinaddr.%s != (%s)\n",coin->symbol,vinaddr,coin->smartaddr); - //return(-1); + printf("???????????????????????? basilisk_rawtx_gen mismatched %s %s vinaddr.%s != (%s)\n",rawtx->symbol,coin->symbol,vinaddr,coin->smartaddr); + return(-1); } argjson = cJSON_CreateObject(); jaddbits256(argjson,"utxotxid",rawtx->utxotxid); From 08d4dc192b55a7d38949fdf22874704efae85409 Mon Sep 17 00:00:00 2001 From: jl777 Date: Tue, 14 Nov 2017 02:49:43 +0200 Subject: [PATCH 0728/1664] Test --- iguana/exchanges/LP_commands.c | 2 +- iguana/exchanges/LP_nativeDEX.c | 2 ++ 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/iguana/exchanges/LP_commands.c b/iguana/exchanges/LP_commands.c index 3aca6ee1c..41df9bd17 100644 --- a/iguana/exchanges/LP_commands.c +++ b/iguana/exchanges/LP_commands.c @@ -486,7 +486,7 @@ bot_resume(botid)\n\ { ptr->privkeydepth = 0; LP_address(ptr,ptr->smartaddr); - if ( jint(argjson,"reset") != 0 ) + if ( 0 && jint(argjson,"reset") != 0 ) { LP_address_utxo_reset(ptr); LP_passphrase_init(jstr(argjson,"passphrase"),G.gui); diff --git a/iguana/exchanges/LP_nativeDEX.c b/iguana/exchanges/LP_nativeDEX.c index 497aebe75..bd0bb193a 100644 --- a/iguana/exchanges/LP_nativeDEX.c +++ b/iguana/exchanges/LP_nativeDEX.c @@ -518,6 +518,8 @@ void LP_coinsloop(void *_coins) continue; } } + if ( coin->smartaddr[0] == 0 ) + printf("%s has no smartaddress??\n",coin->symbol); memset(&zero,0,sizeof(zero)); if ( coin->inactive != 0 ) continue; From d7a48f542cecb8b99702779660a57ff5cafb13ec Mon Sep 17 00:00:00 2001 From: jl777 Date: Tue, 14 Nov 2017 03:00:37 +0200 Subject: [PATCH 0729/1664] Test --- iguana/exchanges/LP_bitcoin.c | 1 + 1 file changed, 1 insertion(+) diff --git a/iguana/exchanges/LP_bitcoin.c b/iguana/exchanges/LP_bitcoin.c index 373af373b..8eaeafd86 100644 --- a/iguana/exchanges/LP_bitcoin.c +++ b/iguana/exchanges/LP_bitcoin.c @@ -3198,6 +3198,7 @@ cJSON *iguana_voutjson(uint8_t taddr,uint8_t pubtype,uint8_t p2shtype,struct igu jadd(json,"scriptPubKey",skey); } } + free(vp); return(json); } From 7432c82dc5c4521ff80c7ac11113c435ef4461ae Mon Sep 17 00:00:00 2001 From: jl777 Date: Tue, 14 Nov 2017 03:05:38 +0200 Subject: [PATCH 0730/1664] Test --- iguana/exchanges/LP_transaction.c | 2 +- iguana/exchanges/LP_utxo.c | 7 +++---- 2 files changed, 4 insertions(+), 5 deletions(-) diff --git a/iguana/exchanges/LP_transaction.c b/iguana/exchanges/LP_transaction.c index 82120368d..6f54db403 100644 --- a/iguana/exchanges/LP_transaction.c +++ b/iguana/exchanges/LP_transaction.c @@ -910,7 +910,7 @@ int32_t LP_vins_select(void *ctx,struct iguana_info *coin,int64_t *totalp,int64_ printf("have utxotxid but wasnt found up.%p\n",up); if ( up == 0 ) { - value = LP_txvalue(coin->smartaddr,coin->symbol,utxotxid,utxovout); + value = LP_txvalue(0,coin->symbol,utxotxid,utxovout); LP_address_utxoadd("withdraw",coin,coin->smartaddr,utxotxid,utxovout,value,1,-1); printf("added after not finding\n"); } diff --git a/iguana/exchanges/LP_utxo.c b/iguana/exchanges/LP_utxo.c index bfd1103f3..5d4b5b482 100644 --- a/iguana/exchanges/LP_utxo.c +++ b/iguana/exchanges/LP_utxo.c @@ -765,13 +765,12 @@ uint64_t LP_txvalue(char *coinaddr,char *symbol,bits256 txid,int32_t vout) } else if ( coin->electrum == 0 ) { - uint64_t value; char _coinaddr[64]; + uint64_t value; if ( (txobj= LP_gettxout(coin->symbol,coinaddr,txid,vout)) != 0 ) { value = LP_value_extract(txobj,0);//SATOSHIDEN * (jdouble(txobj,"value") + jdouble(txobj,"interest")); - if ( coinaddr == 0 ) - coinaddr = _coinaddr; - LP_destaddr(coinaddr,txobj); + if ( coinaddr != 0 ) + LP_destaddr(coinaddr,txobj); //printf("pruned node? LP_txvalue couldnt find %s tx %s, but gettxout %.8f\n",coin->symbol,bits256_str(str,txid),dstr(value)); if ( value != 0 ) { From cea1ddfe59664030786be3851404dddd0dbbcadf Mon Sep 17 00:00:00 2001 From: jl777 Date: Tue, 14 Nov 2017 03:24:54 +0200 Subject: [PATCH 0731/1664] Test --- iguana/exchanges/LP_bitcoin.c | 18 +++++++++++++----- 1 file changed, 13 insertions(+), 5 deletions(-) diff --git a/iguana/exchanges/LP_bitcoin.c b/iguana/exchanges/LP_bitcoin.c index 8eaeafd86..a86473d61 100644 --- a/iguana/exchanges/LP_bitcoin.c +++ b/iguana/exchanges/LP_bitcoin.c @@ -3331,7 +3331,7 @@ int32_t iguana_rwjoinsplit(int32_t rwflag,uint8_t *serialized,struct iguana_msgj int32_t iguana_rwmsgtx(uint8_t taddr,uint8_t pubtype,uint8_t p2shtype,uint8_t isPoS,int32_t height,int32_t rwflag,cJSON *json,uint8_t *serialized,int32_t maxsize,struct iguana_msgtx *msg,bits256 *txidp,char *vpnstr,uint8_t *extraspace,int32_t extralen,cJSON *vins,int32_t suppress_pubkeys,int32_t zcash) { - int32_t i,n,len = 0,extraused=0; uint32_t seglen; uint8_t segwitflag=0,spendscript[IGUANA_MAXSCRIPTSIZE],*txstart = serialized,*sigser=0; char txidstr[65]; cJSON *vinarray=0,*voutarray=0; bits256 sigtxid; + int32_t i,n,len = 0,extraused=0; uint32_t seglen,tmp,segitems; uint8_t segwitflag=0,spendscript[IGUANA_MAXSCRIPTSIZE],*txstart = serialized,*sigser=0; char txidstr[65]; cJSON *vinarray=0,*voutarray=0; bits256 sigtxid; len += iguana_rwnum(rwflag,&serialized[len],sizeof(msg->version),&msg->version); if ( json != 0 ) @@ -3441,10 +3441,18 @@ int32_t iguana_rwmsgtx(uint8_t taddr,uint8_t pubtype,uint8_t p2shtype,uint8_t is printf("unsupported rwflag.%d when segwitflag\n",rwflag); else { - len += iguana_rwvarint32(rwflag,&serialized[len],&seglen); - printf("witness len.%d sum %d vs max.%d\n",seglen,seglen+len,maxsize); - if ( seglen+len < maxsize ) - len += maxsize; + len += iguana_rwvarint32(rwflag,&serialized[len],&segitems); + printf("witness segitems.%d sum %d vs max.%d\n",segitems,len,maxsize); + for (i=0; i= maxsize ) + { + printf("i.%d of segitems.%d overflowed %d+%d >= max.%d\n",i,segitems,len,tmp,maxsize); + break; + } else len += tmp; + } } } len += iguana_rwnum(rwflag,&serialized[len],sizeof(msg->lock_time),&msg->lock_time); From cfacf467cabe9a1fc5360d15ec87e99cb589a776 Mon Sep 17 00:00:00 2001 From: jl777 Date: Tue, 14 Nov 2017 03:38:11 +0200 Subject: [PATCH 0732/1664] Test --- iguana/exchanges/LP_bitcoin.c | 25 +++++++++++++++---------- 1 file changed, 15 insertions(+), 10 deletions(-) diff --git a/iguana/exchanges/LP_bitcoin.c b/iguana/exchanges/LP_bitcoin.c index a86473d61..7d945ebb2 100644 --- a/iguana/exchanges/LP_bitcoin.c +++ b/iguana/exchanges/LP_bitcoin.c @@ -3331,7 +3331,7 @@ int32_t iguana_rwjoinsplit(int32_t rwflag,uint8_t *serialized,struct iguana_msgj int32_t iguana_rwmsgtx(uint8_t taddr,uint8_t pubtype,uint8_t p2shtype,uint8_t isPoS,int32_t height,int32_t rwflag,cJSON *json,uint8_t *serialized,int32_t maxsize,struct iguana_msgtx *msg,bits256 *txidp,char *vpnstr,uint8_t *extraspace,int32_t extralen,cJSON *vins,int32_t suppress_pubkeys,int32_t zcash) { - int32_t i,n,len = 0,extraused=0; uint32_t seglen,tmp,segitems; uint8_t segwitflag=0,spendscript[IGUANA_MAXSCRIPTSIZE],*txstart = serialized,*sigser=0; char txidstr[65]; cJSON *vinarray=0,*voutarray=0; bits256 sigtxid; + int32_t i,j,n,len = 0,extraused=0; uint32_t tmp,segitems; uint8_t segwitflag=0,spendscript[IGUANA_MAXSCRIPTSIZE],*txstart = serialized,*sigser=0; char txidstr[65]; cJSON *vinarray=0,*voutarray=0; bits256 sigtxid; len += iguana_rwnum(rwflag,&serialized[len],sizeof(msg->version),&msg->version); if ( json != 0 ) @@ -3441,18 +3441,23 @@ int32_t iguana_rwmsgtx(uint8_t taddr,uint8_t pubtype,uint8_t p2shtype,uint8_t is printf("unsupported rwflag.%d when segwitflag\n",rwflag); else { - len += iguana_rwvarint32(rwflag,&serialized[len],&segitems); - printf("witness segitems.%d sum %d vs max.%d\n",segitems,len,maxsize); - for (i=0; itx_in; i++) { - len += iguana_rwvarint32(rwflag,&serialized[len],&tmp); - printf("%d ",tmp); - if ( len+tmp >= maxsize ) + len += iguana_rwvarint32(rwflag,&serialized[len],&segitems); + printf("vini.%d (%d:",i,segitems); + for (j=0; j= max.%d\n",i,segitems,len,tmp,maxsize); - break; - } else len += tmp; + len += iguana_rwvarint32(rwflag,&serialized[len],&tmp); + printf(" %d",tmp); + if ( len+tmp >= maxsize ) + { + printf("vini.%d of %d, j.%d of segitems.%d overflowed %d+%d >= max.%d\n",i,msg->tx_in,j,segitems,len,tmp,maxsize); + break; + } else len += tmp; + } + printf("), "); } + printf("witness sum %d vs max.%d\n",len,maxsize); } } len += iguana_rwnum(rwflag,&serialized[len],sizeof(msg->lock_time),&msg->lock_time); From 142b72804e238182766746e05345a0fed738ffa0 Mon Sep 17 00:00:00 2001 From: jl777 Date: Tue, 14 Nov 2017 03:46:41 +0200 Subject: [PATCH 0733/1664] Test --- iguana/exchanges/LP_bitcoin.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/iguana/exchanges/LP_bitcoin.c b/iguana/exchanges/LP_bitcoin.c index 7d945ebb2..772e4aa34 100644 --- a/iguana/exchanges/LP_bitcoin.c +++ b/iguana/exchanges/LP_bitcoin.c @@ -3457,7 +3457,8 @@ int32_t iguana_rwmsgtx(uint8_t taddr,uint8_t pubtype,uint8_t p2shtype,uint8_t is } printf("), "); } - printf("witness sum %d vs max.%d\n",len,maxsize); + bits256 txid = bits256_doublesha256(0,serialized,len+sizeof(msg->lock_time)); + char str[65]; printf("witness sum %d vs max.%d txid %s\n",len,maxsize,bits256_str(str,txid)); } } len += iguana_rwnum(rwflag,&serialized[len],sizeof(msg->lock_time),&msg->lock_time); From b1de4ec3032e19fcf3219c8db3bc899d2fe0234c Mon Sep 17 00:00:00 2001 From: jl777 Date: Tue, 14 Nov 2017 03:54:00 +0200 Subject: [PATCH 0734/1664] Test --- iguana/exchanges/LP_bitcoin.c | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/iguana/exchanges/LP_bitcoin.c b/iguana/exchanges/LP_bitcoin.c index 772e4aa34..657672b64 100644 --- a/iguana/exchanges/LP_bitcoin.c +++ b/iguana/exchanges/LP_bitcoin.c @@ -3331,7 +3331,7 @@ int32_t iguana_rwjoinsplit(int32_t rwflag,uint8_t *serialized,struct iguana_msgj int32_t iguana_rwmsgtx(uint8_t taddr,uint8_t pubtype,uint8_t p2shtype,uint8_t isPoS,int32_t height,int32_t rwflag,cJSON *json,uint8_t *serialized,int32_t maxsize,struct iguana_msgtx *msg,bits256 *txidp,char *vpnstr,uint8_t *extraspace,int32_t extralen,cJSON *vins,int32_t suppress_pubkeys,int32_t zcash) { - int32_t i,j,n,len = 0,extraused=0; uint32_t tmp,segitems; uint8_t segwitflag=0,spendscript[IGUANA_MAXSCRIPTSIZE],*txstart = serialized,*sigser=0; char txidstr[65]; cJSON *vinarray=0,*voutarray=0; bits256 sigtxid; + int32_t i,j,n,segtxlen,len = 0,extraused=0; uint32_t tmp,segitems; uint8_t *segtx,segwitflag=0,spendscript[IGUANA_MAXSCRIPTSIZE],*txstart = serialized,*sigser=0; char txidstr[65]; cJSON *vinarray=0,*voutarray=0; bits256 sigtxid; len += iguana_rwnum(rwflag,&serialized[len],sizeof(msg->version),&msg->version); if ( json != 0 ) @@ -3436,6 +3436,11 @@ int32_t iguana_rwmsgtx(uint8_t taddr,uint8_t pubtype,uint8_t p2shtype,uint8_t is } if ( segwitflag != 0 ) { + segtxlen = len - 2 + sizeof(msg->lock_time); + segtx = malloc(segtxlen); + memcpy(segtx,serialized,sizeof(int32_t)); + memcpy(&segtx[sizeof(int32_t)],&serialized[sizeof(int32_t)+2],len-2-sizeof(int32_t)); + printf("tx_out %d, tx_in %d %02x %02x %02x\n",msg->tx_out,msg->tx_in,serialized[len],serialized[len+1],serialized[len+2]); if ( rwflag != 0 ) printf("unsupported rwflag.%d when segwitflag\n",rwflag); @@ -3457,7 +3462,8 @@ int32_t iguana_rwmsgtx(uint8_t taddr,uint8_t pubtype,uint8_t p2shtype,uint8_t is } printf("), "); } - bits256 txid = bits256_doublesha256(0,serialized,len+sizeof(msg->lock_time)); + memcpy(&segtx[segtxlen-sizeof(int32_t)],&serialized[len],sizeof(int32_t)); + bits256 txid = bits256_doublesha256(0,segtx,segtxlen); char str[65]; printf("witness sum %d vs max.%d txid %s\n",len,maxsize,bits256_str(str,txid)); } } From 825115c4a28e06d2c3a435845b032e6c01b2af6d Mon Sep 17 00:00:00 2001 From: jl777 Date: Tue, 14 Nov 2017 03:56:32 +0200 Subject: [PATCH 0735/1664] Test --- iguana/exchanges/LP_bitcoin.c | 13 +++++++------ 1 file changed, 7 insertions(+), 6 deletions(-) diff --git a/iguana/exchanges/LP_bitcoin.c b/iguana/exchanges/LP_bitcoin.c index 657672b64..97ca24817 100644 --- a/iguana/exchanges/LP_bitcoin.c +++ b/iguana/exchanges/LP_bitcoin.c @@ -3449,22 +3449,22 @@ int32_t iguana_rwmsgtx(uint8_t taddr,uint8_t pubtype,uint8_t p2shtype,uint8_t is for (i=0; itx_in; i++) { len += iguana_rwvarint32(rwflag,&serialized[len],&segitems); - printf("vini.%d (%d:",i,segitems); + //printf("vini.%d (%d:",i,segitems); for (j=0; j= maxsize ) { printf("vini.%d of %d, j.%d of segitems.%d overflowed %d+%d >= max.%d\n",i,msg->tx_in,j,segitems,len,tmp,maxsize); break; } else len += tmp; } - printf("), "); + //printf("), "); } memcpy(&segtx[segtxlen-sizeof(int32_t)],&serialized[len],sizeof(int32_t)); - bits256 txid = bits256_doublesha256(0,segtx,segtxlen); - char str[65]; printf("witness sum %d vs max.%d txid %s\n",len,maxsize,bits256_str(str,txid)); + *txidp = bits256_doublesha256(0,segtx,segtxlen); + //char str[65]; printf("witness sum %d vs max.%d txid %s\n",len,maxsize,bits256_str(str,txid)); } } len += iguana_rwnum(rwflag,&serialized[len],sizeof(msg->lock_time),&msg->lock_time); @@ -3519,7 +3519,8 @@ int32_t iguana_rwmsgtx(uint8_t taddr,uint8_t pubtype,uint8_t p2shtype,uint8_t is jadd(json,"vout",voutarray); jaddnum(json,"numvouts",msg->tx_out); } - *txidp = bits256_doublesha256(txidstr,txstart,len); + if ( segwitflag == 0 ) + *txidp = bits256_doublesha256(txidstr,txstart,len); if ( json != 0 ) { jaddnum(json,"locktime",msg->lock_time); From a2d3150dd5d64a43faeea07845878613326616d3 Mon Sep 17 00:00:00 2001 From: jl777 Date: Tue, 14 Nov 2017 03:58:27 +0200 Subject: [PATCH 0736/1664] Test --- iguana/exchanges/LP_bitcoin.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/iguana/exchanges/LP_bitcoin.c b/iguana/exchanges/LP_bitcoin.c index 97ca24817..0c8e9abc6 100644 --- a/iguana/exchanges/LP_bitcoin.c +++ b/iguana/exchanges/LP_bitcoin.c @@ -3364,7 +3364,7 @@ int32_t iguana_rwmsgtx(uint8_t taddr,uint8_t pubtype,uint8_t p2shtype,uint8_t is if ( serialized[len] == 0x00 && (segwitflag= serialized[len+1]) == 0x01 ) { len += 2; - printf("SEGWIT transaction\n"); + //printf("SEGWIT transaction\n"); } } len += iguana_rwvarint32(rwflag,&serialized[len],&msg->tx_in); @@ -3441,7 +3441,7 @@ int32_t iguana_rwmsgtx(uint8_t taddr,uint8_t pubtype,uint8_t p2shtype,uint8_t is memcpy(segtx,serialized,sizeof(int32_t)); memcpy(&segtx[sizeof(int32_t)],&serialized[sizeof(int32_t)+2],len-2-sizeof(int32_t)); - printf("tx_out %d, tx_in %d %02x %02x %02x\n",msg->tx_out,msg->tx_in,serialized[len],serialized[len+1],serialized[len+2]); + //printf("tx_out %d, tx_in %d %02x %02x %02x\n",msg->tx_out,msg->tx_in,serialized[len],serialized[len+1],serialized[len+2]); if ( rwflag != 0 ) printf("unsupported rwflag.%d when segwitflag\n",rwflag); else From e480e2d7e38b2ac99dd8d8f493f078580fe36aed Mon Sep 17 00:00:00 2001 From: jl777 Date: Tue, 14 Nov 2017 04:04:44 +0200 Subject: [PATCH 0737/1664] Test --- iguana/exchanges/LP_commands.c | 2 +- iguana/exchanges/LP_nativeDEX.c | 16 +--------------- iguana/exchanges/LP_transaction.c | 7 +++++-- 3 files changed, 7 insertions(+), 18 deletions(-) diff --git a/iguana/exchanges/LP_commands.c b/iguana/exchanges/LP_commands.c index 41df9bd17..3aca6ee1c 100644 --- a/iguana/exchanges/LP_commands.c +++ b/iguana/exchanges/LP_commands.c @@ -486,7 +486,7 @@ bot_resume(botid)\n\ { ptr->privkeydepth = 0; LP_address(ptr,ptr->smartaddr); - if ( 0 && jint(argjson,"reset") != 0 ) + if ( jint(argjson,"reset") != 0 ) { LP_address_utxo_reset(ptr); LP_passphrase_init(jstr(argjson,"passphrase"),G.gui); diff --git a/iguana/exchanges/LP_nativeDEX.c b/iguana/exchanges/LP_nativeDEX.c index bd0bb193a..123c461be 100644 --- a/iguana/exchanges/LP_nativeDEX.c +++ b/iguana/exchanges/LP_nativeDEX.c @@ -19,26 +19,12 @@ // marketmaker // // alice waiting for bestprice -// regen inventory -// previously, it used to show amount, kmd equiv, perc // bot safe to exit? // // BCH signing +// previously, it used to show amount, kmd equiv, perc // dPoW security -> 4: KMD notarized, 5: BTC notarized, after next notary elections // bigendian architectures need to use little endian for sighash calcs -//BTC LP_transaction_fromdata mismatched txid f78c80e831c02c89c0888e7d4438287030238e09e33f88da6df4dc84b949959b vs 1390f386f5997607e646be9c93f30018aa68ea971790b92b7b06e892656f0769 -//failed blockchain.transaction.get BTC f78c80e831c02c89c0888e7d4438287030238e09e33f88da6df4dc84b949959b -//02000000000101242344292f9117c8318adb84f7991239361da2ff0a15ad2106d402945072cc110a0000001716001470eb5212b558cfc10b31f0849ef88ecf17097ac1ffffffff0c4a8321000000000017a914baed1c79cc6325333d5013b44dc17e8256bf5b718704bf3c000000000017a914255cf2809a1f42569c5c47c71e6234aac35a800f873099f400000000001976a914049877b81a8d6d8592919b75b9bcb4182f7c52cd88acb907e200000000001976a9140614fc114940e867210b09cc900db14d8bc58d2b88ac40771b00000000001976a9148cadbb1d7002d22d60e38ca238678d00f04ed22988ac002d3101000000001976a9140d05714431cf478846cea1435f9eabae9ad5c65388acc0f280010000000017a914c17a70c74154fc53263652aaca26c8d71683f1ba87aa2a4e00000000001976a914feea6b867954b1072962083233796d47e4c1665e88ace0e1de02000000001976a91445b71fbb02df53be5563257b77780b9afcc55bdc88acf6fe6700000000001976a91492332f8ff3b26e3ce2666afa5fee2e45308225af88ace74c1500000000001976a914fc7580f1ce24b2c85c80b2c8e641592b9bbf974588ac081ad000000000001976a9145e61c81c9b3ac55bf90ab00240023e8ddaf43e1788ac02483045022100a74be4e00585637c6792eeff9279508f09163db525f8b16c03e57283d12b0a6a022042cc061d70e78e9260ff30635db4f4e0b317831a8cb1f30473a25b93b4d1b4fb01210238288b60e8c50785809a69517ae3ca2fe3e407cac8b5868c5fb3803c233dfbcc00000000 data2json n.219 vs len.586 - - -//BTC LP_transaction_fromdata mismatched txid ae7af65215554964b7af01babb58fce10fc51d9812ced07ee4a62a1ffe10c0bb vs 051ef4f75898b511dd3aebd687d5a5bdb004226d811aaf13e64be741dbe81ff2 -//failed blockchain.transaction.get BTC ae7af65215554964b7af01babb58fce10fc51d9812ced07ee4a62a1ffe10c0bb -//errortxobj.({"version":1}) -//010000000001010c590740b0c558f75b64cc0d00b0533ff951e403d993b866a87c7c52981388a60300000017160014cd2b7646f9931c85bb9d4d353b652c76b40aff84ffffffff0240420f000000000017a914239ae54cd403a91b084d3244e7e423f05c25ec268728fe28010000000017a914b96e21dd6e11bb67479f9072df55881e7fb17f788702473044022076e4c1cfba0dab889598efdfdcbc7a1046cc0eecfb8fec379994d559143d271c02206b16d9a0e3c425434d1b793d61e1e491f269abc7e7d3af52d95f6a26c1c2aa0d0121037f88a6ccdd608645024b05f408324550cf6fa1c74e3d7c1f94a1e9b57369d10600000000 data2json n.-1 vs len.247 - - -//ScriptSig: PUSHDATA(34)[002072d8f7debd607b94c95ced6cff38265ed99c7c1ee58b67d0a3f3ed43b6d9a977] -//Witness: 040047304402206f23bb2dd06bc70d78312e27d53954420d0defbda7ad638718b9dc2c1efb93100220270f79bfb3230194d2e625875073799f6f07d96d5bce43b19cfe6be9957d95540148304502210081842f5987009e65f1d7de6140433da541b9da52ed211e87e1ae6fc25260d7680220798de97c682541d7b26b0795b19994f045f3ef4f433c55da0b5f1506ddeec413014752210305345798069ac85285628732485a3ce7e96b85696ed7da72287f6eae3b275363210268aace9c841b8d61fe3532981c8b25e235690003916c5a90c23a708e5d8f929752ae #include struct LP_millistats diff --git a/iguana/exchanges/LP_transaction.c b/iguana/exchanges/LP_transaction.c index 6f54db403..8431e90fb 100644 --- a/iguana/exchanges/LP_transaction.c +++ b/iguana/exchanges/LP_transaction.c @@ -1082,8 +1082,11 @@ char *LP_createrawtransaction(cJSON **txobjp,int32_t *numvinsp,struct iguana_inf memset(utxos,0,sizeof(utxos)); if ( (numutxos= LP_address_utxo_ptrs(coin,0,utxos,max,ap,coin->smartaddr)) <= 0 ) { - printf("LP_createrawtransaction: address_utxo_ptrs %d, error\n",numutxos); - //return(0); + if ( bits256_nonz(utxotxid) == 0 ) + { + printf("LP_createrawtransaction: address_utxo_ptrs %d, error\n",numutxos); + return(0); + } } char str[65]; for (i=0; i Date: Tue, 14 Nov 2017 04:07:33 +0200 Subject: [PATCH 0738/1664] Test --- iguana/exchanges/LP_ordermatch.c | 7 ++++--- iguana/exchanges/LP_transaction.c | 12 ++++++------ 2 files changed, 10 insertions(+), 9 deletions(-) diff --git a/iguana/exchanges/LP_ordermatch.c b/iguana/exchanges/LP_ordermatch.c index 4f99f2298..d2b7b9e79 100644 --- a/iguana/exchanges/LP_ordermatch.c +++ b/iguana/exchanges/LP_ordermatch.c @@ -844,7 +844,7 @@ int32_t LP_tradecommand(void *ctx,char *myipaddr,int32_t pubsock,cJSON *argjson, if ( bits256_nonz(Q.txid2) != 0 ) LP_utxos_remove(Q.txid2,Q.vout2); else recalc = 1; - printf("price %.8f qprice %.8f\n",price,qprice); + //printf("price %.8f qprice %.8f\n",price,qprice); if ( recalc == 0 ) { value = LP_txvalue(tmp,Q.srccoin,Q.txid,Q.vout); @@ -941,14 +941,15 @@ int32_t LP_tradecommand(void *ctx,char *myipaddr,int32_t pubsock,cJSON *argjson, jaddstr(retjson,"method","reserved"); msg = jprint(retjson,0); butxo->T.lasttime = (uint32_t)time(NULL); - printf("return after queued RESERVED: set swappending.%u accept qprice %.8f, min %.8f\n(%s)\n",butxo->T.swappending,qprice,ask,msg); + //printf("return after queued RESERVED: set swappending.%u accept qprice %.8f, min %.8f\n(%s)\n",butxo->T.swappending,qprice,ask,msg); // LP_addsig //msg2 = clonestr(msg); LP_reserved_msg(1,Q.srccoin,Q.destcoin,butxo->S.otherpubkey,clonestr(msg)); sleep(1); bits256 zero; memset(zero.bytes,0,sizeof(zero)); - LP_reserved_msg(1,Q.srccoin,Q.destcoin,zero,msg); + //LP_reserved_msg(1,Q.srccoin,Q.destcoin,zero,msg); + LP_reserved_msg(0,Q.srccoin,Q.destcoin,zero,msg); //LP_broadcast_message(LP_mypubsock,Q.srccoin,Q.destcoin,Q.desthash,jprint(retjson,0)); free_json(retjson); return(retval); diff --git a/iguana/exchanges/LP_transaction.c b/iguana/exchanges/LP_transaction.c index 8431e90fb..6e4642f3e 100644 --- a/iguana/exchanges/LP_transaction.c +++ b/iguana/exchanges/LP_transaction.c @@ -907,12 +907,12 @@ int32_t LP_vins_select(void *ctx,struct iguana_info *coin,int64_t *totalp,int64_ if ( bits256_nonz(utxotxid) != 0 && numpre == 0 ) { up = LP_address_utxofind(coin,coin->smartaddr,utxotxid,utxovout); - printf("have utxotxid but wasnt found up.%p\n",up); + //printf("have utxotxid but wasnt found up.%p\n",up); if ( up == 0 ) { value = LP_txvalue(0,coin->symbol,utxotxid,utxovout); LP_address_utxoadd("withdraw",coin,coin->smartaddr,utxotxid,utxovout,value,1,-1); - printf("added after not finding\n"); + //printf("added after not finding\n"); } if ( (up= LP_address_utxofind(coin,coin->smartaddr,utxotxid,utxovout)) != 0 ) preselected[numpre++] = up; @@ -978,7 +978,7 @@ int32_t LP_vins_select(void *ctx,struct iguana_info *coin,int64_t *totalp,int64_ char str[65]; printf("%s/%d %.8f interest %.8f -> sum %.8f\n",bits256_str(str,up->U.txid),up->U.vout,dstr(up->U.value),dstr(interest),dstr(interestsum)); } } - printf("numunspents.%d vini.%d value %.8f, total %.8f remains %.8f interest %.8f sum %.8f %s/v%d\n",numunspents,n,dstr(up->U.value),dstr(total),dstr(remains),dstr(interest),dstr(interestsum),bits256_str(str,up->U.txid),up->U.vout); + //printf("numunspents.%d vini.%d value %.8f, total %.8f remains %.8f interest %.8f sum %.8f %s/v%d\n",numunspents,n,dstr(up->U.value),dstr(total),dstr(remains),dstr(interest),dstr(interestsum),bits256_str(str,up->U.txid),up->U.vout); vp = &V[n++]; vp->N = vp->M = 1; vp->signers[0].privkey = privkey; @@ -1088,9 +1088,9 @@ char *LP_createrawtransaction(cJSON **txobjp,int32_t *numvinsp,struct iguana_inf return(0); } } - char str[65]; - for (i=0; iU.txid),utxos[i]->U.vout,dstr(utxos[i]->U.value)); + //char str[65]; + //for (i=0; iU.txid),utxos[i]->U.vout,dstr(utxos[i]->U.value)); ignore_cltverr = 0; suppress_pubkeys = 1; From 3c1fc577da6cc1cdb256ffcb17a4b00478958536 Mon Sep 17 00:00:00 2001 From: jl777 Date: Tue, 14 Nov 2017 04:17:12 +0200 Subject: [PATCH 0739/1664] Test --- iguana/exchanges/LP_ordermatch.c | 10 +++++----- iguana/exchanges/LP_stats.c | 2 +- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/iguana/exchanges/LP_ordermatch.c b/iguana/exchanges/LP_ordermatch.c index d2b7b9e79..86ca8afc4 100644 --- a/iguana/exchanges/LP_ordermatch.c +++ b/iguana/exchanges/LP_ordermatch.c @@ -34,7 +34,7 @@ double LP_bob_competition(int32_t *counterp,uint64_t aliceid,double price,int32_ { if ( now > Bob_competition[i].starttime+LP_AUTOTRADE_TIMEOUT ) { - //printf("aliceid.%llx expired\n",(long long)aliceid); + //printf("aliceid.%llu expired\n",(long long)aliceid); Bob_competition[i].bestprice = 0.; Bob_competition[i].starttime = now; Bob_competition[i].counter = 0; @@ -42,7 +42,7 @@ double LP_bob_competition(int32_t *counterp,uint64_t aliceid,double price,int32_ if ( price != 0. && (Bob_competition[i].bestprice == 0. || price < Bob_competition[i].bestprice) ) { Bob_competition[i].bestprice = price; - //printf("Bob competition aliceid.%llx <- bestprice %.8f\n",(long long)aliceid,price); + //printf("Bob competition aliceid.%llu <- bestprice %.8f\n",(long long)aliceid,price); } Bob_competition[i].counter += counter; *counterp = Bob_competition[i].counter; @@ -58,7 +58,7 @@ double LP_bob_competition(int32_t *counterp,uint64_t aliceid,double price,int32_ Bob_competition[firsti].aliceid = aliceid; Bob_competition[firsti].bestprice = price; *counterp = counter; - //printf("Bob competition aliceid.%llx %.8f\n",(long long)aliceid,price); + //printf("Bob competition aliceid.%llu %.8f\n",(long long)aliceid,price); return(price); } @@ -720,7 +720,7 @@ int32_t LP_tradecommand(void *ctx,char *myipaddr,int32_t pubsock,cJSON *argjson, LP_quoteparse(&Q,argjson); LP_requestinit(&Q.R,Q.srchash,Q.desthash,Q.srccoin,Q.satoshis-Q.txfee,Q.destcoin,Q.destsatoshis-Q.desttxfee,Q.timestamp,Q.quotetime,DEXselector); LP_tradecommand_log(argjson); - printf("LP_tradecommand: check received method %12s aliceid.%16llx %5s/%-5s %12.8f -> %12.8f price %12.8f\n",method,(long long)Q.aliceid,Q.srccoin,Q.destcoin,dstr(Q.satoshis),dstr(Q.destsatoshis),(double)Q.destsatoshis/Q.satoshis); + printf("LP_tradecommand: received %12s aliceid.%22llu %5s/%-5s %12.8f -> %12.8f price %12.8f\n",method,(long long)Q.aliceid,Q.srccoin,Q.destcoin,dstr(Q.satoshis),dstr(Q.destsatoshis),(double)Q.destsatoshis/Q.satoshis); retval = 1; autxo = &A; butxo = &B; @@ -732,7 +732,7 @@ int32_t LP_tradecommand(void *ctx,char *myipaddr,int32_t pubsock,cJSON *argjson, if ( strcmp(method,"reserved") == 0 ) { bestprice = LP_bob_competition(&counter,aliceid,qprice,1); - //printf("aliceid.%llx price %.8f -> bestprice %.8f\n",(long long)aliceid,qprice,bestprice); + //printf("aliceid.%llu price %.8f -> bestprice %.8f\n",(long long)aliceid,qprice,bestprice); if ( LP_Alicemaxprice == 0. ) return(retval); if ( bits256_nonz(LP_Alicedestpubkey) != 0 ) diff --git a/iguana/exchanges/LP_stats.c b/iguana/exchanges/LP_stats.c index 853ce8bd0..40569f027 100644 --- a/iguana/exchanges/LP_stats.c +++ b/iguana/exchanges/LP_stats.c @@ -209,7 +209,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 ) - printf("mismatched tradestatus aliceid.%016llx 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)); + 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); } From 7e6479b0a23a418100cb5446ffa81921e31473c0 Mon Sep 17 00:00:00 2001 From: jl777 Date: Tue, 14 Nov 2017 04:27:04 +0200 Subject: [PATCH 0740/1664] Test --- iguana/exchanges/LP_ordermatch.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/iguana/exchanges/LP_ordermatch.c b/iguana/exchanges/LP_ordermatch.c index 86ca8afc4..da83aeb26 100644 --- a/iguana/exchanges/LP_ordermatch.c +++ b/iguana/exchanges/LP_ordermatch.c @@ -863,7 +863,7 @@ int32_t LP_tradecommand(void *ctx,char *myipaddr,int32_t pubsock,cJSON *argjson, price += (r * range) / 100.; bestprice = LP_bob_competition(&counter,aliceid,price,0); printf(">>>>>>>>>>>>> price %.8f qprice %.8f r.%d range %.8f -> %.8f, bestprice %.8f counter.%d\n",ask,qprice,r,range,price,bestprice,counter); - if ( counter > 2 || price > bestprice*1.1 ) + if ( counter > 10 )//2 || price > bestprice*1.1 ) return(retval); } else return(retval); //printf("recalc.%d address.(%s/%s) price %.8f request.(%s)\n",recalc,Q.coinaddr,coin->smartaddr,price,jprint(argjson,0)); @@ -948,8 +948,8 @@ int32_t LP_tradecommand(void *ctx,char *myipaddr,int32_t pubsock,cJSON *argjson, sleep(1); bits256 zero; memset(zero.bytes,0,sizeof(zero)); - //LP_reserved_msg(1,Q.srccoin,Q.destcoin,zero,msg); - LP_reserved_msg(0,Q.srccoin,Q.destcoin,zero,msg); + LP_reserved_msg(1,Q.srccoin,Q.destcoin,zero,msg); + //LP_reserved_msg(0,Q.srccoin,Q.destcoin,zero,msg); //LP_broadcast_message(LP_mypubsock,Q.srccoin,Q.destcoin,Q.desthash,jprint(retjson,0)); free_json(retjson); return(retval); From 0902ea2c030085a407a734591d4ad33f158cdf47 Mon Sep 17 00:00:00 2001 From: jl777 Date: Tue, 14 Nov 2017 04:36:27 +0200 Subject: [PATCH 0741/1664] Test --- iguana/exchanges/LP_ordermatch.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/iguana/exchanges/LP_ordermatch.c b/iguana/exchanges/LP_ordermatch.c index da83aeb26..95278302d 100644 --- a/iguana/exchanges/LP_ordermatch.c +++ b/iguana/exchanges/LP_ordermatch.c @@ -801,7 +801,7 @@ int32_t LP_tradecommand(void *ctx,char *myipaddr,int32_t pubsock,cJSON *argjson, return(retval); } price = ask; - //printf("MYPRICE %s/%s %.8f\n",Q.srccoin,Q.destcoin,price); + printf("MYPRICE %s/%s %.8f vs qprice %.8f\n",Q.srccoin,Q.destcoin,price,qprice); if ( LP_validSPV(Q.destcoin,Q.destaddr,Q.desttxid,Q.destvout) < 0 ) { printf("%s dest %s failed SPV check\n",Q.destcoin,bits256_str(str,Q.desttxid)); @@ -891,7 +891,7 @@ int32_t LP_tradecommand(void *ctx,char *myipaddr,int32_t pubsock,cJSON *argjson, } else { - //printf("cant find utxopair\n"); + printf("cant find utxopair\n"); return(retval); } } @@ -941,7 +941,7 @@ int32_t LP_tradecommand(void *ctx,char *myipaddr,int32_t pubsock,cJSON *argjson, jaddstr(retjson,"method","reserved"); msg = jprint(retjson,0); butxo->T.lasttime = (uint32_t)time(NULL); - //printf("return after queued RESERVED: set swappending.%u accept qprice %.8f, min %.8f\n(%s)\n",butxo->T.swappending,qprice,ask,msg); + printf("return after queued RESERVED: set swappending.%u accept qprice %.8f, min %.8f\n(%s)\n",butxo->T.swappending,qprice,ask,msg); // LP_addsig //msg2 = clonestr(msg); LP_reserved_msg(1,Q.srccoin,Q.destcoin,butxo->S.otherpubkey,clonestr(msg)); From 7d9fdd77eb5d6b70162800aea98222410ddc0df7 Mon Sep 17 00:00:00 2001 From: jl777 Date: Tue, 14 Nov 2017 04:42:07 +0200 Subject: [PATCH 0742/1664] Test --- iguana/exchanges/LP_ordermatch.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/iguana/exchanges/LP_ordermatch.c b/iguana/exchanges/LP_ordermatch.c index 95278302d..88171d831 100644 --- a/iguana/exchanges/LP_ordermatch.c +++ b/iguana/exchanges/LP_ordermatch.c @@ -863,7 +863,7 @@ int32_t LP_tradecommand(void *ctx,char *myipaddr,int32_t pubsock,cJSON *argjson, price += (r * range) / 100.; bestprice = LP_bob_competition(&counter,aliceid,price,0); printf(">>>>>>>>>>>>> price %.8f qprice %.8f r.%d range %.8f -> %.8f, bestprice %.8f counter.%d\n",ask,qprice,r,range,price,bestprice,counter); - if ( counter > 10 )//2 || price > bestprice*1.1 ) + if ( counter > 5 || price > bestprice*1.1 ) return(retval); } else return(retval); //printf("recalc.%d address.(%s/%s) price %.8f request.(%s)\n",recalc,Q.coinaddr,coin->smartaddr,price,jprint(argjson,0)); From b695221cb19237c232e851d0a672af8d62e6d84e Mon Sep 17 00:00:00 2001 From: jl777 Date: Tue, 14 Nov 2017 04:49:26 +0200 Subject: [PATCH 0743/1664] Test --- iguana/exchanges/LP_utxo.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/iguana/exchanges/LP_utxo.c b/iguana/exchanges/LP_utxo.c index 5d4b5b482..3257f6096 100644 --- a/iguana/exchanges/LP_utxo.c +++ b/iguana/exchanges/LP_utxo.c @@ -189,7 +189,7 @@ int32_t LP_address_utxo_ptrs(struct iguana_info *coin,int32_t iambob,struct LP_a continue; } } - if ( LP_allocated(up->U.txid,up->U.vout) == 0 && (iambob == 0 || (_LP_utxofind(iambob,up->U.txid,up->U.vout) == 0 && _LP_utxo2find(iambob,up->U.txid,up->U.vout) == 0)) ) + if ( LP_allocated(up->U.txid,up->U.vout) == 0 )//&& (iambob == 0 || (_LP_utxofind(iambob,up->U.txid,up->U.vout) == 0 && _LP_utxo2find(iambob,up->U.txid,up->U.vout) == 0)) ) { utxos[n++] = up; if ( n >= max ) From e8e6fd263330dac03fae301b582f9bf7760ce210 Mon Sep 17 00:00:00 2001 From: jl777 Date: Tue, 14 Nov 2017 04:50:58 +0200 Subject: [PATCH 0744/1664] Test --- iguana/exchanges/LP_commands.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/iguana/exchanges/LP_commands.c b/iguana/exchanges/LP_commands.c index 3aca6ee1c..56ed047e4 100644 --- a/iguana/exchanges/LP_commands.c +++ b/iguana/exchanges/LP_commands.c @@ -484,10 +484,10 @@ bot_resume(botid)\n\ struct iguana_info *ptr; if ( (ptr= LP_coinfind(coin)) != 0 ) { - ptr->privkeydepth = 0; LP_address(ptr,ptr->smartaddr); if ( jint(argjson,"reset") != 0 ) { + ptr->privkeydepth = 0; LP_address_utxo_reset(ptr); LP_passphrase_init(jstr(argjson,"passphrase"),G.gui); } From 818fceb3e260082a097a1faa3b2e24cdc508cb5b Mon Sep 17 00:00:00 2001 From: jl777 Date: Tue, 14 Nov 2017 13:20:24 +0200 Subject: [PATCH 0745/1664] Test --- iguana/exchanges/LP_bitcoin.c | 3 ++- iguana/exchanges/LP_nativeDEX.c | 2 +- iguana/exchanges/LP_ordermatch.c | 2 +- 3 files changed, 4 insertions(+), 3 deletions(-) diff --git a/iguana/exchanges/LP_bitcoin.c b/iguana/exchanges/LP_bitcoin.c index 0c8e9abc6..a9aa5751b 100644 --- a/iguana/exchanges/LP_bitcoin.c +++ b/iguana/exchanges/LP_bitcoin.c @@ -3331,7 +3331,7 @@ int32_t iguana_rwjoinsplit(int32_t rwflag,uint8_t *serialized,struct iguana_msgj int32_t iguana_rwmsgtx(uint8_t taddr,uint8_t pubtype,uint8_t p2shtype,uint8_t isPoS,int32_t height,int32_t rwflag,cJSON *json,uint8_t *serialized,int32_t maxsize,struct iguana_msgtx *msg,bits256 *txidp,char *vpnstr,uint8_t *extraspace,int32_t extralen,cJSON *vins,int32_t suppress_pubkeys,int32_t zcash) { - int32_t i,j,n,segtxlen,len = 0,extraused=0; uint32_t tmp,segitems; uint8_t *segtx,segwitflag=0,spendscript[IGUANA_MAXSCRIPTSIZE],*txstart = serialized,*sigser=0; char txidstr[65]; cJSON *vinarray=0,*voutarray=0; bits256 sigtxid; + int32_t i,j,n,segtxlen,len = 0,extraused=0; uint32_t tmp,segitems; uint8_t *segtx=0,segwitflag=0,spendscript[IGUANA_MAXSCRIPTSIZE],*txstart = serialized,*sigser=0; char txidstr[65]; cJSON *vinarray=0,*voutarray=0; bits256 sigtxid; len += iguana_rwnum(rwflag,&serialized[len],sizeof(msg->version),&msg->version); if ( json != 0 ) @@ -3464,6 +3464,7 @@ int32_t iguana_rwmsgtx(uint8_t taddr,uint8_t pubtype,uint8_t p2shtype,uint8_t is } memcpy(&segtx[segtxlen-sizeof(int32_t)],&serialized[len],sizeof(int32_t)); *txidp = bits256_doublesha256(0,segtx,segtxlen); + free(segtx); //char str[65]; printf("witness sum %d vs max.%d txid %s\n",len,maxsize,bits256_str(str,txid)); } } diff --git a/iguana/exchanges/LP_nativeDEX.c b/iguana/exchanges/LP_nativeDEX.c index 123c461be..455845d77 100644 --- a/iguana/exchanges/LP_nativeDEX.c +++ b/iguana/exchanges/LP_nativeDEX.c @@ -13,11 +13,11 @@ * Removal or modification of this copyright notice is prohibited. * * * ******************************************************************************/ - // // LP_nativeDEX.c // marketmaker // +// single utxo allocations, reject result, latency // alice waiting for bestprice // bot safe to exit? // diff --git a/iguana/exchanges/LP_ordermatch.c b/iguana/exchanges/LP_ordermatch.c index 88171d831..7f7e946c1 100644 --- a/iguana/exchanges/LP_ordermatch.c +++ b/iguana/exchanges/LP_ordermatch.c @@ -891,7 +891,7 @@ int32_t LP_tradecommand(void *ctx,char *myipaddr,int32_t pubsock,cJSON *argjson, } else { - printf("cant find utxopair\n"); + printf("cant find utxopair %s/%s\n",Q.srccoin,Q.destcoin); return(retval); } } From c7d175dac94a82a86be3a85248827c806bafdfb7 Mon Sep 17 00:00:00 2001 From: jl777 Date: Tue, 14 Nov 2017 18:39:22 +0200 Subject: [PATCH 0746/1664] Dynamic inventory --- iguana/exchanges/LP_cache.c | 4 +- iguana/exchanges/LP_include.h | 15 +- iguana/exchanges/LP_nativeDEX.c | 3 +- iguana/exchanges/LP_ordermatch.c | 320 +++++++++++++++--------------- iguana/exchanges/LP_signatures.c | 11 +- iguana/exchanges/LP_socket.c | 6 +- iguana/exchanges/LP_swap.c | 12 +- iguana/exchanges/LP_transaction.c | 39 +--- iguana/exchanges/LP_utxo.c | 206 +++++++++++++++---- iguana/exchanges/LP_utxos.c | 52 +++-- 10 files changed, 405 insertions(+), 263 deletions(-) diff --git a/iguana/exchanges/LP_cache.c b/iguana/exchanges/LP_cache.c index 65140dc2c..a08828966 100644 --- a/iguana/exchanges/LP_cache.c +++ b/iguana/exchanges/LP_cache.c @@ -58,7 +58,7 @@ struct LP_transaction *LP_create_transaction(struct iguana_info *coin,bits256 tx tx->outpoints[i].interest = SATOSHIDEN * jdouble(vout,"interest"); LP_destaddr(tx->outpoints[i].coinaddr,vout); //printf("from transaction init %s %s %s/v%d <- %.8f\n",coin->symbol,tx->outpoints[i].coinaddr,bits256_str(str,txid),i,dstr(tx->outpoints[i].value)); - LP_address_utxoadd("LP_create_transaction",coin,tx->outpoints[i].coinaddr,txid,i,tx->outpoints[i].value,height,-1); + LP_address_utxoadd((uint32_t)time(NULL),"LP_create_transaction",coin,tx->outpoints[i].coinaddr,txid,i,tx->outpoints[i].value,height,-1); } for (i=0; ioutpoints[spentvout].spendtxid = txid; tx->outpoints[spentvout].spendvini = i; tx->outpoints[spentvout].spendheight = height > 0 ? height : 1; - LP_address_utxoadd("LP_transactioninit iter1",coin,tx->outpoints[spentvout].coinaddr,spenttxid,spentvout,tx->outpoints[spentvout].value,-1,height>0?height:1); + LP_address_utxoadd((uint32_t)time(NULL),"LP_transactioninit iter1",coin,tx->outpoints[spentvout].coinaddr,spenttxid,spentvout,tx->outpoints[spentvout].value,-1,height>0?height:1); if ( 0 && strcmp(coin->symbol,"REVS") == 0 ) printf("spend %s %s/v%d at ht.%d\n",coin->symbol,bits256_str(str,tx->txid),spentvout,height); } diff --git a/iguana/exchanges/LP_include.h b/iguana/exchanges/LP_include.h index 839333523..c24ad9bf4 100644 --- a/iguana/exchanges/LP_include.h +++ b/iguana/exchanges/LP_include.h @@ -23,7 +23,7 @@ #define LP_MAJOR_VERSION "0" #define LP_MINOR_VERSION "1" -#define LP_BUILD_NUMBER "14336" +#define LP_BUILD_NUMBER "14414" #ifdef FROM_JS #include @@ -43,7 +43,8 @@ void emscripten_usleep(int32_t x); // returns immediate, no sense for sleeping #define LP_MAXVINS 64 #define LP_HTTP_TIMEOUT 3 // 1 is too small due to edge cases of time(NULL) -#define LP_AUTOTRADE_TIMEOUT 60 +#define LP_AUTOTRADE_TIMEOUT 30 +#define LP_RESERVETIME (LP_AUTOTRADE_TIMEOUT * 2) #define ELECTRUM_TIMEOUT 7 #define LP_ELECTRUM_KEEPALIVE 60 #define LP_ELECTRUM_MAXERRORS 777 @@ -103,7 +104,6 @@ void emscripten_usleep(int32_t x); // returns immediate, no sense for sleeping #define LP_RPCPORT 7783 #define LP_PROPAGATION_SLACK 100 // txid ordering is not enforced, so getting extra recent txid -#define LP_RESERVETIME 60 #define LP_AVETXSIZE 256 #define LP_CACHEDURATION 60 #define BASILISK_DEFAULT_NUMCONFIRMS 1 @@ -288,7 +288,7 @@ struct LP_utxobob { struct _LP_utxoinfo utxo,deposit; }; struct LP_utxoalice { struct _LP_utxoinfo utxo,fee; }; -struct LP_utxoswap { bits256 otherpubkey; void *swap; uint64_t satoshis; }; +struct LP_utxoswap { bits256 otherpubkey; uint64_t satoshis; }; struct LP_utxoinfo { @@ -308,6 +308,7 @@ struct LP_address_utxo struct LP_address_utxo *next,*prev; struct _LP_utxoinfo U; int32_t SPV,spendheight; + uint32_t timestamp; }; struct LP_address @@ -346,7 +347,7 @@ struct LP_endpoint { int32_t pair; char ipaddr[64]; uint16_t port; }; struct basilisk_swap { - void *ctx; struct LP_utxoinfo *utxo; + void *ctx; //struct LP_utxoinfo *utxo; struct LP_endpoint N; void (*balancingtrade)(struct basilisk_swap *swap,int32_t iambob); int32_t subsock,pushsock,connected,aliceunconf,depositunconf,paymentunconf; @@ -410,7 +411,7 @@ 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); int64_t LP_komodo_interest(bits256 txid,int64_t value); -void LP_availableset(struct LP_utxoinfo *utxo); +void LP_availableset(bits256 txid,int32_t vout); 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); int32_t LP_pullsock_check(void *ctx,char **retstrp,char *myipaddr,int32_t pubsock,int32_t pullsock); void LP_unspents_cache(char *symbol,char *addr,char *arraystr,int32_t updatedflag); @@ -452,7 +453,7 @@ int32_t LP_txheight(struct iguana_info *coin,bits256 txid); int32_t LP_numpeers(); char *basilisk_swapentry(uint32_t requestid,uint32_t quoteid); uint64_t LP_KMDvalue(struct iguana_info *coin,uint64_t balance); -int32_t LP_address_utxoadd(char *debug,struct iguana_info *coin,char *coinaddr,bits256 txid,int32_t vout,uint64_t value,int32_t height,int32_t spendheight); +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); void LP_cacheptrs_init(struct iguana_info *coin); cJSON *LP_address_utxos(struct iguana_info *coin,char *coinaddr,int32_t electrumret); diff --git a/iguana/exchanges/LP_nativeDEX.c b/iguana/exchanges/LP_nativeDEX.c index 455845d77..713e8e7de 100644 --- a/iguana/exchanges/LP_nativeDEX.c +++ b/iguana/exchanges/LP_nativeDEX.c @@ -78,7 +78,7 @@ void LP_millistats_update(struct LP_millistats *mp) } #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,LP_reservedmutex,LP_nanorecvsmutex,LP_tradebotsmutex,LP_gcmutex; +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,LP_tradebotsmutex,LP_gcmutex,LP_inusemutex; int32_t LP_canbind; char *Broadcaststr,*Reserved_msgs[2][1000]; int32_t num_Reserved_msgs[2],max_Reserved_msgs[2]; @@ -923,6 +923,7 @@ void LPinit(uint16_t myport,uint16_t mypullport,uint16_t mypubport,uint16_t mybu portable_mutex_init(&LP_networkmutex); portable_mutex_init(&LP_gcmutex); portable_mutex_init(&LP_forwardmutex); + portable_mutex_init(&LP_inusemutex); portable_mutex_init(&LP_psockmutex); portable_mutex_init(&LP_coinmutex); portable_mutex_init(&LP_pubkeymutex); diff --git a/iguana/exchanges/LP_ordermatch.c b/iguana/exchanges/LP_ordermatch.c index 7f7e946c1..0ef73ab65 100644 --- a/iguana/exchanges/LP_ordermatch.c +++ b/iguana/exchanges/LP_ordermatch.c @@ -290,7 +290,7 @@ int32_t LP_nearest_utxovalue(struct iguana_info *coin,char *coinaddr,struct LP_a //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 ( dist >= 0 && dist < mindist ) //(coin->electrum == 0 || up->SPV > 0) && + if ( dist >= 0 && dist < mindist ) { //printf("(%.8f %.8f %.8f).%d ",dstr(up->U.value),dstr(dist),dstr(mindist),mini); mini = i; @@ -303,6 +303,55 @@ int32_t LP_nearest_utxovalue(struct iguana_info *coin,char *coinaddr,struct LP_a return(mini); } +void LP_butxo_set(struct LP_utxoinfo *butxo,struct iguana_info *coin,struct LP_address_utxo *up,struct LP_address_utxo *up2,int64_t satoshis) +{ + butxo->pubkey = G.LP_mypub25519; + safecopy(butxo->coin,coin->symbol,sizeof(butxo->coin)); + safecopy(butxo->coinaddr,coin->smartaddr,sizeof(butxo->coinaddr)); + butxo->payment.txid = up->U.txid; + butxo->payment.vout = up->U.vout; + butxo->payment.value = up->U.value; + butxo->iambob = 1; + butxo->deposit.txid = up2->U.txid; + butxo->deposit.vout = up2->U.vout; + butxo->deposit.value = up2->U.value; + butxo->S.satoshis = satoshis; +} + +void LP_abutxo_set(struct LP_utxoinfo *autxo,struct LP_utxoinfo *butxo,struct LP_quoteinfo *qp) +{ + if ( butxo != 0 ) + { + memset(butxo,0,sizeof(*butxo)); + butxo->pubkey = qp->srchash; + safecopy(butxo->coin,qp->srccoin,sizeof(butxo->coin)); + safecopy(butxo->coinaddr,qp->coinaddr,sizeof(butxo->coinaddr)); + butxo->payment.txid = qp->txid; + butxo->payment.vout = qp->vout; + //butxo->payment.value = qp->value; + butxo->iambob = 1; + butxo->deposit.txid = qp->txid2; + butxo->deposit.vout = qp->vout2; + //butxo->deposit.value = up2->U.value; + butxo->S.satoshis = qp->satoshis; + } + if ( autxo != 0 ) + { + memset(autxo,0,sizeof(*autxo)); + autxo->pubkey = qp->desthash; + safecopy(autxo->coin,qp->destcoin,sizeof(autxo->coin)); + safecopy(autxo->coinaddr,qp->destaddr,sizeof(autxo->coinaddr)); + autxo->payment.txid = qp->desttxid; + autxo->payment.vout = qp->destvout; + //autxo->payment.value = qp->value; + autxo->iambob = 0; + autxo->fee.txid = qp->feetxid; + autxo->fee.vout = qp->feevout; + //autxo->deposit.value = up2->U.value; + autxo->S.satoshis = qp->destsatoshis; + } +} + 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); @@ -311,9 +360,10 @@ uint64_t LP_basesatoshis(double relvolume,double price,uint64_t txfee,uint64_t d else return(0); } -struct LP_utxoinfo *LP_address_utxopair(int32_t iambob,struct LP_address_utxo **utxos,int32_t max,struct iguana_info *coin,char *coinaddr,uint64_t txfee,double relvolume,double price,uint64_t desttxfee) +struct LP_utxoinfo *LP_address_myutxopair(struct LP_utxoinfo *butxo,int32_t iambob,struct LP_address_utxo **utxos,int32_t max,struct iguana_info *coin,char *coinaddr,uint64_t txfee,double relvolume,double price,uint64_t desttxfee) { - struct LP_address *ap; uint64_t targetval,targetval2; int32_t m,mini; struct LP_address_utxo *up,*up2; struct LP_utxoinfo *utxo = 0;//,*utmp; + struct LP_address *ap; uint64_t targetval,targetval2; int32_t m,mini; struct LP_address_utxo *up,*up2; + memset(butxo,0,sizeof(*butxo)); targetval = LP_basesatoshis(relvolume,price,txfee,desttxfee); targetval2 = (targetval / 8) * 9 + 2*txfee; if ( coin != 0 && (ap= LP_addressfind(coin,coinaddr)) != 0 ) @@ -340,12 +390,13 @@ struct LP_utxoinfo *LP_address_utxopair(int32_t iambob,struct LP_address_utxo ** { if ( up != 0 && (up2= utxos[mini]) != 0 ) { - if ( (utxo= LP_utxoadd(1,coin->symbol,up->U.txid,up->U.vout,up->U.value,up2->U.txid,up2->U.vout,up2->U.value,coinaddr,ap->pubkey,G.gui,0,targetval)) != 0 ) + /*if ( (utxo= LP_utxoadd(1,coin->symbol,up->U.txid,up->U.vout,up->U.value,up2->U.txid,up2->U.vout,up2->U.value,coinaddr,ap->pubkey,G.gui,0,targetval)) != 0 ) { utxo->S.satoshis = targetval; char str[65],str2[65]; printf("butxo.%p targetval %.8f, found val %.8f %s | targetval2 %.8f val2 %.8f %s\n",utxo,dstr(targetval),dstr(up->U.value),bits256_str(str,utxo->payment.txid),dstr(targetval2),dstr(up2->U.value),bits256_str(str2,utxo->deposit.txid)); - return(utxo); - } + return(butxo); + }*/ + LP_butxo_set(butxo,coin,up,up2,targetval); } } //else printf("cant find targetval2 %.8f\n",dstr(targetval2)); } //else printf("failed ratio test %.8f\n",(double)up->U.value/targetval); @@ -353,64 +404,21 @@ struct LP_utxoinfo *LP_address_utxopair(int32_t iambob,struct LP_address_utxo ** printf("targetval %.8f mini.%d\n",dstr(targetval),mini); } //else printf("no %s utxos pass LP_address_utxo_ptrs filter\n",coinaddr); } else printf("couldnt find %s %s\n",coin->symbol,coinaddr); - /*HASH_ITER(hh,G.LP_utxoinfos[iambob],utxo,utmp) - { - if ( LP_isavailable(utxo) != 0 && utxo->payment.value >= targetval && targetval >= utxo->payment.value/2 && utxo->deposit.value >= targetval2 ) - { - utxo->S.satoshis = targetval; - printf("backup method found utxo!\n"); - return(utxo); - } - }*/ return(0); } -void LP_abutxo_set(struct LP_utxoinfo *autxo,struct LP_utxoinfo *butxo,struct LP_quoteinfo *qp) -{ - if ( butxo != 0 ) - { - memset(butxo,0,sizeof(*butxo)); - butxo->pubkey = qp->srchash; - safecopy(butxo->coin,qp->srccoin,sizeof(butxo->coin)); - safecopy(butxo->coinaddr,qp->coinaddr,sizeof(butxo->coinaddr)); - butxo->payment.txid = qp->txid; - butxo->payment.vout = qp->vout; - //butxo->payment.value = qp->value; - butxo->iambob = 1; - butxo->deposit.txid = qp->txid2; - butxo->deposit.vout = qp->vout2; - //butxo->deposit.value = up2->U.value; - butxo->S.satoshis = qp->satoshis; - } - if ( autxo != 0 ) - { - memset(autxo,0,sizeof(*autxo)); - autxo->pubkey = qp->desthash; - safecopy(autxo->coin,qp->destcoin,sizeof(autxo->coin)); - safecopy(autxo->coinaddr,qp->destaddr,sizeof(autxo->coinaddr)); - autxo->payment.txid = qp->desttxid; - autxo->payment.vout = qp->destvout; - //autxo->payment.value = qp->value; - autxo->iambob = 0; - autxo->fee.txid = qp->feetxid; - autxo->fee.vout = qp->feevout; - //autxo->deposit.value = up2->U.value; - autxo->S.satoshis = qp->destsatoshis; - } -} - -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) +int32_t LP_connectstartbob(void *ctx,int32_t pubsock,cJSON *argjson,char *base,char *rel,double price,struct LP_quoteinfo *qp) { 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 ) + if ( (coin= LP_coinfind(qp->srccoin)) == 0 ) { - printf("cant find coin.%s\n",utxo->coin); + printf("cant find coin.%s\n",qp->srccoin); return(-1); } - privkey = LP_privkey(utxo->coinaddr,coin->taddr); - if ( bits256_nonz(privkey) != 0 && bits256_cmp(G.LP_mypub25519,qp->srchash) == 0 ) //qp->quotetime >= qp->timestamp-3 && qp->quotetime <= utxo->T.swappending && + privkey = LP_privkey(coin->smartaddr,coin->taddr); + if ( bits256_nonz(privkey) != 0 && bits256_cmp(G.LP_mypub25519,qp->srchash) == 0 ) { LP_requestinit(&qp->R,qp->srchash,qp->desthash,base,qp->satoshis-qp->txfee,rel,qp->destsatoshis-qp->desttxfee,qp->timestamp,qp->quotetime,DEXselector); if ( (swap= LP_swapinit(1,0,privkey,&qp->R,qp)) == 0 ) @@ -421,45 +429,37 @@ int32_t LP_connectstartbob(void *ctx,int32_t pubsock,struct LP_utxoinfo *utxo,cJ if ( (pair= LP_nanobind(ctx,pairstr)) >= 0 ) { swap->N.pair = pair; - utxo->S.swap = swap; - swap->utxo = utxo; + //utxo->S.swap = swap; + //swap->utxo = utxo; if ( OS_thread_create(malloc(sizeof(pthread_t)),NULL,(void *)LP_bobloop,(void *)swap) == 0 ) { retjson = LP_quotejson(qp); jaddstr(retjson,"method","connected"); jaddstr(retjson,"pair",pairstr); - //jaddnum(retjson,"requestid",qp->R.requestid); - //jaddnum(retjson,"quoteid",qp->R.quoteid); - // LP_addsig - char str[65]; printf("BOB pubsock.%d binds to %d (%s)\n",pubsock,pair,bits256_str(str,utxo->S.otherpubkey)); - LP_reserved_msg(1,base,rel,utxo->S.otherpubkey,jprint(retjson,0)); + char str[65]; printf("BOB pubsock.%d binds to %d (%s)\n",pubsock,pair,bits256_str(str,qp->desthash)); + LP_reserved_msg(1,base,rel,qp->desthash,jprint(retjson,0)); sleep(1); bits256 zero; memset(zero.bytes,0,sizeof(zero)); LP_reserved_msg(1,base,rel,zero,jprint(retjson,0)); - //LP_broadcast_message(LP_mypubsock,qp->srccoin,qp->destcoin,qp->desthash,jprint(retjson,0)); free_json(retjson); retval = 0; } else printf("error launching swaploop\n"); } else printf("couldnt bind to any port %s\n",pairstr); } - else - { - printf("dest %.8f vs required %.8f (%d %d %d %d %d)\n",dstr(qp->destsatoshis),dstr(price*(utxo->S.satoshis-qp->txfee)),bits256_nonz(privkey) != 0 ,qp->timestamp == utxo->T.swappending-LP_RESERVETIME,qp->quotetime >= qp->timestamp-3,qp->quotetime < utxo->T.swappending,bits256_cmp(G.LP_mypub25519,qp->srchash) == 0); - } if ( retval < 0 ) { if ( pair >= 0 ) nn_close(pair); - LP_availableset(utxo); - } else LP_unavailableset(utxo,utxo->S.otherpubkey); - //LP_butxo_swapfields(utxo); + LP_availableset(qp->txid,qp->vout); + LP_availableset(qp->txid2,qp->vout2); + } return(retval); } char *LP_trade(void *ctx,char *myipaddr,int32_t mypubsock,struct LP_quoteinfo *qp,double maxprice,int32_t timeout,int32_t duration,uint32_t tradeid,bits256 destpubkey) { - 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; + struct LP_utxoinfo *aliceutxo; double price; 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); @@ -491,15 +491,20 @@ int32_t LP_quotecmp(struct LP_quoteinfo *qp,struct LP_quoteinfo *qp2) else return(-1); } +void LP_alicequery_clear() +{ + memset(&LP_Alicequery,0,sizeof(LP_Alicequery)); + memset(&LP_Alicedestpubkey,0,sizeof(LP_Alicedestpubkey)); + LP_Alicemaxprice = 0.; + Alice_expiration = 0; +} + int32_t LP_alice_eligible() { if ( Alice_expiration != 0 && time(NULL) > Alice_expiration ) { printf("time expired for Alice_request\n"); - memset(&LP_Alicequery,0,sizeof(LP_Alicequery)); - memset(&LP_Alicedestpubkey,0,sizeof(LP_Alicedestpubkey)); - LP_Alicemaxprice = 0.; - Alice_expiration = 0; + LP_alicequery_clear(); } return(Alice_expiration == 0 || time(NULL) < Alice_expiration); } @@ -513,10 +518,7 @@ void LP_reserved(void *ctx,char *myipaddr,int32_t mypubsock,struct LP_quoteinfo if ( LP_pricevalid(price) > 0 && maxprice > SMALLVAL && price <= maxprice*1.005 ) { qp->tradeid = LP_Alicequery.tradeid; - memset(&LP_Alicequery,0,sizeof(LP_Alicequery)); - memset(&LP_Alicedestpubkey,0,sizeof(LP_Alicedestpubkey)); - LP_Alicemaxprice = 0.; - Alice_expiration = 0; + LP_alicequery_clear(); printf("send CONNECT\n"); LP_query(ctx,myipaddr,mypubsock,"connect",qp); } else printf("LP_reserved price %.8f vs maxprice %.8f\n",price,maxprice*1.005); @@ -543,19 +545,20 @@ char *LP_connectedalice(cJSON *argjson) // alice LP_aliceid(Q.tradeid,Q.aliceid,"error2",0,0); return(clonestr("{\"error\":\"cant find autxo\"}")); } - if ( autxo->S.swap != 0 ) + /*if ( autxo->S.swap != 0 ) { printf("ignore duplicate swap\n"); LP_aliceid(Q.tradeid,Q.aliceid,"error3",0,0); return(clonestr("{\"error\":\"ignore duplicate swap\"}")); - } + }*/ LP_aliceid(Q.tradeid,Q.aliceid,"connected",Q.R.requestid,Q.R.quoteid); butxo = &B; memset(butxo,0,sizeof(*butxo)); LP_abutxo_set(0,butxo,&Q); if ( (qprice= LP_quote_validate(autxo,butxo,&Q,0)) <= SMALLVAL ) { - LP_availableset(autxo); + LP_availableset(Q.desttxid,Q.vout); + LP_availableset(Q.feetxid,Q.feevout); LP_aliceid(Q.tradeid,Q.aliceid,"error4",0,0); printf("quote validate error %.0f\n",qprice); return(clonestr("{\"error\":\"quote validation error\"}")); @@ -563,7 +566,8 @@ char *LP_connectedalice(cJSON *argjson) // alice if ( LP_myprice(&bid,&ask,Q.srccoin,Q.destcoin) <= SMALLVAL || bid <= SMALLVAL ) { printf("this node has no price for %s/%s (%.8f %.8f)\n",Q.destcoin,Q.srccoin,bid,ask); - LP_availableset(autxo); + LP_availableset(Q.desttxid,Q.vout); + LP_availableset(Q.feetxid,Q.feevout); LP_aliceid(Q.tradeid,Q.aliceid,"error5",0,0); return(clonestr("{\"error\":\"no price set\"}")); } @@ -582,7 +586,8 @@ char *LP_connectedalice(cJSON *argjson) // alice if ( (swap= LP_swapinit(0,0,Q.privkey,&Q.R,&Q)) == 0 ) { jaddstr(retjson,"error","couldnt swapinit"); - LP_availableset(autxo); + LP_availableset(Q.desttxid,Q.vout); + LP_availableset(Q.feetxid,Q.feevout); LP_aliceid(Q.tradeid,Q.aliceid,"error7",Q.R.requestid,Q.R.quoteid); return(jprint(retjson,1)); } @@ -598,8 +603,8 @@ char *LP_connectedalice(cJSON *argjson) // alice //nn_setsockopt(pairsock,NN_SOL_SOCKET,NN_RCVTIMEO,&timeout,sizeof(timeout)); swap->tradeid = Q.tradeid; swap->N.pair = pairsock; - autxo->S.swap = swap; - swap->utxo = autxo; + //autxo->S.swap = swap; + //swap->utxo = autxo; LP_aliceid(Q.tradeid,Q.aliceid,"started",Q.R.requestid,Q.R.quoteid); printf("alice pairstr.(%s) pairsock.%d\n",pairstr,pairsock); if ( OS_thread_create(malloc(sizeof(pthread_t)),NULL,(void *)LP_aliceloop,(void *)swap) == 0 ) @@ -622,12 +627,16 @@ char *LP_connectedalice(cJSON *argjson) // alice } printf("connected result.(%s)\n",jprint(retjson,0)); if ( jobj(retjson,"error") != 0 ) - LP_availableset(autxo); + { + LP_availableset(Q.desttxid,Q.vout); + LP_availableset(Q.feetxid,Q.feevout); + } return(jprint(retjson,1)); } else { - LP_availableset(autxo); + LP_availableset(Q.desttxid,Q.vout); + LP_availableset(Q.feetxid,Q.feevout); LP_aliceid(Q.tradeid,Q.aliceid,"error11",0,0); printf("no privkey found coin.%s %s taddr.%u\n",Q.destcoin,Q.destaddr,coin->taddr); return(clonestr("{\"error\",\"no privkey\"}")); @@ -636,7 +645,7 @@ char *LP_connectedalice(cJSON *argjson) // alice int32_t LP_listunspent_both(char *symbol,char *coinaddr,int32_t fullflag) { - int32_t i,v,numconfs,height,n=0; uint64_t value; bits256 txid; char buf[512]; cJSON *array,*item; struct iguana_info *coin = LP_coinfind(symbol); + int32_t i,v,numconfs,height,n=0; uint64_t value; bits256 txid; char buf[512]; cJSON *array,*item; uint32_t now; struct iguana_info *coin = LP_coinfind(symbol); if ( coin != 0 )//&& (IAMLP != 0 || coin->inactive == 0) ) { if ( coin->electrum != 0 || LP_address_ismine(symbol,coinaddr) <= 0 ) @@ -657,6 +666,7 @@ int32_t LP_listunspent_both(char *symbol,char *coinaddr,int32_t fullflag) { if ( (n= cJSON_GetArraySize(array)) > 0 ) { + now = (uint32_t)time(NULL); for (i=0; icoinaddr,coin->smartaddr) != 0 || bits256_nonz(butxo->payment.txid) == 0 || bits256_nonz(butxo->deposit.txid) == 0 ) + char str[65]; + if ( bits256_nonz(Q.srchash) == 0 || bits256_cmp(Q.srchash,G.LP_mypub25519) == 0 ) + { + qprice = (double)Q.destsatoshis / Q.satoshis; + strcpy(Q.gui,G.gui); + strcpy(Q.coinaddr,coin->smartaddr); + strcpy(butxo->coinaddr,coin->smartaddr); + Q.srchash = G.LP_mypub25519; + memset(&Q.txid,0,sizeof(Q.txid)); + memset(&Q.txid2,0,sizeof(Q.txid2)); + Q.vout = Q.vout2 = -1; + } else return(retval); + /*if ( bits256_nonz(Q.srchash) == 0 || bits256_cmp(Q.srchash,G.LP_mypub25519) == 0 || strcmp(butxo->coinaddr,coin->smartaddr) != 0 || bits256_nonz(butxo->payment.txid) == 0 || bits256_nonz(butxo->deposit.txid) == 0 ) { qprice = (double)Q.destsatoshis / Q.satoshis; strcpy(Q.gui,G.gui); @@ -855,7 +875,7 @@ int32_t LP_tradecommand(void *ctx,char *myipaddr,int32_t pubsock,cJSON *argjson, else if ( bits256_cmp(Q.txid,butxo->payment.txid) != 0 || Q.vout != butxo->payment.vout || bits256_cmp(Q.txid2,butxo->deposit.txid) != 0 || Q.vout2 != butxo->deposit.vout ) recalc = 1; } - } else return(retval); + } else return(retval);*/ if ( qprice > price ) { r = (rand() % 100); @@ -863,45 +883,33 @@ int32_t LP_tradecommand(void *ctx,char *myipaddr,int32_t pubsock,cJSON *argjson, price += (r * range) / 100.; bestprice = LP_bob_competition(&counter,aliceid,price,0); printf(">>>>>>>>>>>>> price %.8f qprice %.8f r.%d range %.8f -> %.8f, bestprice %.8f counter.%d\n",ask,qprice,r,range,price,bestprice,counter); - if ( counter > 5 || price > bestprice*1.1 ) + if ( counter > 5 || price > bestprice*1.1 ) // skip if late or bad price return(retval); } else return(retval); - //printf("recalc.%d address.(%s/%s) price %.8f request.(%s)\n",recalc,Q.coinaddr,coin->smartaddr,price,jprint(argjson,0)); - if ( recalc != 0 ) + LP_RTmetrics_update(Q.srccoin,Q.destcoin); + if ( LP_RTmetrics_blacklisted(Q.desthash) >= 0 ) { - LP_RTmetrics_update(Q.srccoin,Q.destcoin); - if ( LP_RTmetrics_blacklisted(Q.desthash) >= 0 ) - { - printf("request from blacklisted %s, ignore\n",bits256_str(str,Q.desthash)); - return(retval); - } - 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 ) - { - strcpy(Q.gui,G.gui); - strcpy(Q.coinaddr,coin->smartaddr); - Q.srchash = G.LP_mypub25519; - Q.txid = butxo->payment.txid; - Q.vout = butxo->payment.vout; - Q.txid2 = butxo->deposit.txid; - Q.vout2 = butxo->deposit.vout; - Q.satoshis = butxo->S.satoshis; - printf("found %.8f -> %.8f newprice %.8f vs ask %.8f += %.8f qprice %.8f\n",dstr(Q.satoshis),dstr(Q.destsatoshis),(double)Q.destsatoshis/Q.satoshis,ask,price,qprice); - //printf("set butxo.%p %s/v%d %s/v%d %.8f %.8f -> bsat %.8f asat %.8f\n",butxo,bits256_str(str,butxo->payment.txid),butxo->payment.vout,bits256_str(str2,butxo->deposit.txid),butxo->deposit.vout,dstr(butxo->payment.value),dstr(butxo->deposit.value),dstr(butxo->S.satoshis),dstr(autxo->S.satoshis)); - } - else - { - printf("cant find utxopair %s/%s\n",Q.srccoin,Q.destcoin); - return(retval); - } + printf("request from blacklisted %s, ignore\n",bits256_str(str,Q.desthash)); + return(retval); } - } - else // "connect" - { - if ( bits256_cmp(G.LP_mypub25519,Q.srchash) == 0 && bits256_cmp(G.LP_mypub25519,Q.desthash) != 0 ) + LP_address_utxo_reset(coin); + if ( (butxo= LP_address_myutxopair(butxo,1,utxos,max,LP_coinfind(Q.srccoin),Q.coinaddr,Q.txfee,dstr(Q.destsatoshis),price,Q.desttxfee)) != 0 ) { - butxo = LP_utxopairfind(1,Q.txid,Q.vout,Q.txid2,Q.vout2); // better work! - } else return(retval); + strcpy(Q.gui,G.gui); + strcpy(Q.coinaddr,coin->smartaddr); + Q.srchash = G.LP_mypub25519; + Q.txid = butxo->payment.txid; + Q.vout = butxo->payment.vout; + Q.txid2 = butxo->deposit.txid; + Q.vout2 = butxo->deposit.vout; + Q.satoshis = butxo->S.satoshis; + printf("found %.8f -> %.8f newprice %.8f vs ask %.8f += %.8f qprice %.8f\n",dstr(Q.satoshis),dstr(Q.destsatoshis),(double)Q.destsatoshis/Q.satoshis,ask,price,qprice); + } + else + { + printf("cant find utxopair aliceid.%llu %s/%s\n",(long long)aliceid,Q.srccoin,Q.destcoin); + return(retval); + } } if ( strcmp(Q.coinaddr,coin->smartaddr) != 0 ) { @@ -923,55 +931,46 @@ int32_t LP_tradecommand(void *ctx,char *myipaddr,int32_t pubsock,cJSON *argjson, printf("(%.8f %.8f) quote price %.8f too low vs %.8f for %s/%s %.8f < %.8f\n",bid,ask,qprice,price,Q.srccoin,Q.destcoin,qprice,(ask - 0.00000001) * 0.998); return(retval); } - char str[65],str2[65]; printf("butxo.%p (%s %s) TRADECOMMAND.(%s)\n",butxo,butxo!=0?bits256_str(str,butxo->payment.txid):"",butxo!=0?bits256_str(str2,butxo->deposit.txid):"",jprint(argjson,0)); - if ( butxo->S.swap == 0 && time(NULL) > butxo->T.swappending ) - butxo->T.swappending = 0; + char str[65],str2[65]; printf("(%s/v%d %s/v%d) TRADECOMMAND.(%s)\n",bits256_str(str,Q.txid),Q.vout,bits256_str(str2,Q.txid2),Q.vout2,jprint(argjson,0)); if ( strcmp(method,"request") == 0 ) // bob needs apayment + fee tx's { - if ( LP_isavailable(butxo) > 0 ) + if ( LP_allocated(Q.txid,Q.vout) == 0 && LP_allocated(Q.txid2,Q.vout2) == 0 ) { - 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); - jaddnum(retjson,"quotetime",juint(argjson,"quotetime")); - jaddnum(retjson,"pending",butxo->T.swappending); - jaddbits256(retjson,"desthash",butxo->S.otherpubkey); - jaddbits256(retjson,"pubkey",butxo->S.otherpubkey); + LP_unavailableset(Q.txid,Q.vout,Q.timestamp + LP_RESERVETIME,Q.desthash); + LP_unavailableset(Q.txid2,Q.vout2,Q.timestamp + LP_RESERVETIME,Q.desthash); + jaddnum(retjson,"quotetime",Q.quotetime); + jaddnum(retjson,"pending",Q.timestamp + LP_RESERVETIME); + jaddbits256(retjson,"desthash",Q.desthash); jaddstr(retjson,"method","reserved"); msg = jprint(retjson,0); - butxo->T.lasttime = (uint32_t)time(NULL); - printf("return after queued RESERVED: set swappending.%u accept qprice %.8f, min %.8f\n(%s)\n",butxo->T.swappending,qprice,ask,msg); - // LP_addsig - //msg2 = clonestr(msg); - LP_reserved_msg(1,Q.srccoin,Q.destcoin,butxo->S.otherpubkey,clonestr(msg)); + printf("return after queued RESERVED: set swappending.%u accept qprice %.8f, min %.8f\n(%s)\n",Q.timestamp + LP_RESERVETIME,qprice,ask,msg); + LP_reserved_msg(1,Q.srccoin,Q.destcoin,Q.desthash,clonestr(msg)); sleep(1); bits256 zero; memset(zero.bytes,0,sizeof(zero)); LP_reserved_msg(1,Q.srccoin,Q.destcoin,zero,msg); - //LP_reserved_msg(0,Q.srccoin,Q.destcoin,zero,msg); - //LP_broadcast_message(LP_mypubsock,Q.srccoin,Q.destcoin,Q.desthash,jprint(retjson,0)); free_json(retjson); + butxo->T.lasttime = (uint32_t)time(NULL); return(retval); - } else printf("warning swappending.%u swap.%p\n",butxo->T.swappending,butxo->S.swap); + } else printf("request processing selected ineligible utxos?\n"); } else if ( strcmp(method,"connect") == 0 ) // bob { retval = 4; - if ( butxo->S.swap == 0 && butxo->T.swappending != 0 ) + if ( bits256_cmp(G.LP_mypub25519,Q.srchash) != 0 || bits256_cmp(G.LP_mypub25519,Q.desthash) == 0 ) + return(retval); + else if ( LP_reservation_check(Q.txid,Q.vout,Q.desthash) == 0 && LP_reservation_check(Q.txid2,Q.vout2,Q.desthash) == 0 ) { - // validate SPV alice - LP_connectstartbob(ctx,pubsock,butxo,argjson,Q.srccoin,Q.destcoin,qprice,&Q); - //LP_butxo_swapfields_set(butxo); + LP_connectstartbob(ctx,pubsock,argjson,Q.srccoin,Q.destcoin,qprice,&Q); return(retval); - } - else printf("pend.%u swap %p when connect came in (%s)\n",butxo->T.swappending,butxo->S.swap,jprint(argjson,0)); + } else printf("connect message from non-reserved (%s)\n",jprint(argjson,0)); } - //LP_butxo_swapfields_set(butxo); } return(retval); } +#ifdef oldway 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; @@ -1076,10 +1075,11 @@ struct LP_utxoinfo *LP_buyutxo(double *ordermatchpricep,int64_t *bestsatoshisp,i LP_mypriceset(&changed,autxo->coin,base,1. / *ordermatchpricep); return(bestutxo); } +#endif 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,bits256 destpubkey,uint32_t tradeid) { - uint64_t desttxfee,txfee; uint32_t lastnonce; int32_t i,maxiters,numpubs = 0; int64_t bestsatoshis=0,destsatoshis,bestdestsatoshis=0; struct iguana_info *basecoin,*relcoin; struct LP_utxoinfo *autxo,B,*bestutxo = 0; double qprice,ordermatchprice=0.; struct LP_quoteinfo Q; bits256 pubkeys[100]; + uint64_t desttxfee,txfee; uint32_t lastnonce; int64_t bestsatoshis=0,destsatoshis; struct iguana_info *basecoin,*relcoin; struct LP_utxoinfo *autxo,B; struct LP_quoteinfo Q; bits256 pubkeys[100]; basecoin = LP_coinfind(base); relcoin = LP_coinfind(rel); if ( gui == 0 ) @@ -1111,12 +1111,7 @@ char *LP_autobuy(void *ctx,char *myipaddr,int32_t mypubsock,char *base,char *rel } if ( time(NULL) < Alice_expiration ) return(clonestr("{\"error\":\"only one pending request at a time\"}")); - else - { - Alice_expiration = 0; - memset(&LP_Alicequery,0,sizeof(LP_Alicequery)); - LP_Alicemaxprice = 0.; - } + else LP_alicequery_clear(); if ( maxprice <= 0. || relvolume <= 0. || LP_priceinfofind(base) == 0 || LP_priceinfofind(rel) == 0 ) return(clonestr("{\"error\":\"invalid parameter\"}")); if ( strcmp("BTC",rel) == 0 ) @@ -1155,7 +1150,7 @@ char *LP_autobuy(void *ctx,char *myipaddr,int32_t mypubsock,char *base,char *rel int32_t changed; LP_mypriceset(&changed,autxo->coin,base,1. / maxprice); return(LP_trade(ctx,myipaddr,mypubsock,&Q,maxprice,timeout,duration,tradeid,destpubkey)); - +#ifdef oldway LP_RTmetrics_update(base,rel); while ( 1 ) { @@ -1197,6 +1192,7 @@ char *LP_autobuy(void *ctx,char *myipaddr,int32_t mypubsock,char *base,char *rel return(LP_trade(ctx,myipaddr,mypubsock,&Q,maxprice,timeout,duration,tradeid,destpubkey)); } return(clonestr("{\"error\":\"cant get here\"}")); +#endif } diff --git a/iguana/exchanges/LP_signatures.c b/iguana/exchanges/LP_signatures.c index 6b5643bb6..fee4a1189 100644 --- a/iguana/exchanges/LP_signatures.c +++ b/iguana/exchanges/LP_signatures.c @@ -658,7 +658,7 @@ char *LP_uitem_recv(cJSON *argjson) { //char str[65]; printf("uitem %s %s %s/v%d %.8f ht.%d\n",symbol,coinaddr,bits256_str(str,txid),vout,dstr(value),height); if ( strcmp(coin->smartaddr,coinaddr) != 0 ) - LP_address_utxoadd("LP_uitem_recv",coin,coinaddr,txid,vout,value,height,-1); + LP_address_utxoadd((uint32_t)time(NULL),"LP_uitem_recv",coin,coinaddr,txid,vout,value,height,-1); //else printf("ignore external uitem %s %s\n",symbol,coin->smartaddr); } return(clonestr("{\"result\":\"success\"}")); @@ -676,11 +676,14 @@ void LP_listunspent_query(char *symbol,char *coinaddr) void LP_query(void *ctx,char *myipaddr,int32_t mypubsock,char *method,struct LP_quoteinfo *qp) { - cJSON *reqjson; bits256 zero; char *msg,*msg2; int32_t flag = 0; struct LP_utxoinfo *utxo; + cJSON *reqjson; bits256 zero; char *msg,*msg2; int32_t flag = 0; if ( strcmp(method,"request") == 0 ) { - if ( (utxo= LP_utxofind(0,qp->desttxid,qp->destvout)) != 0 && LP_ismine(utxo) > 0 && LP_isavailable(utxo) > 0 ) - LP_unavailableset(utxo,qp->srchash); + if ( LP_allocated(qp->desttxid,qp->destvout) == 0 && LP_allocated(qp->feetxid,qp->feevout) == 0 ) + { + LP_unavailableset(qp->desttxid,qp->destvout,qp->timestamp+LP_AUTOTRADE_TIMEOUT,qp->srchash); + LP_unavailableset(qp->feetxid,qp->feevout,qp->timestamp+LP_AUTOTRADE_TIMEOUT,qp->srchash); + } else { printf("couldnt find my txid to make request\n"); diff --git a/iguana/exchanges/LP_socket.c b/iguana/exchanges/LP_socket.c index f345e9ab6..870543904 100644 --- a/iguana/exchanges/LP_socket.c +++ b/iguana/exchanges/LP_socket.c @@ -303,7 +303,7 @@ int32_t electrum_process_array(struct iguana_info *coin,struct electrum_info *ep else { //printf("external unspent has no gettxout\n"); - flag += LP_address_utxoadd("electrum process",coin,coinaddr,txid,v,value,0,1); + flag += LP_address_utxoadd((uint32_t)time(NULL),"electrum process",coin,coinaddr,txid,v,value,0,1); } } else @@ -345,7 +345,7 @@ int32_t electrum_process_array(struct iguana_info *coin,struct electrum_info *ep if ( tx->height > 0 ) { //printf("from electrum_process_array\n"); - flag += LP_address_utxoadd("electrum process2",coin,coinaddr,txid,v,value,tx->height,-1); + flag += LP_address_utxoadd((uint32_t)time(NULL),"electrum process2",coin,coinaddr,txid,v,value,tx->height,-1); } //printf("v.%d numvouts.%d %.8f (%s)\n",v,tx->numvouts,dstr(tx->outpoints[jint(item,"tx_pos")].value),jprint(item,0)); } //else printf("cant find tx\n"); @@ -544,7 +544,7 @@ cJSON *electrum_address_gethistory(char *symbol,struct electrum_info *ep,cJSON * if ( tx->height > 0 && tx->height != height ) printf("update %s height.%d <- %d\n",bits256_str(str,txid),tx->height,height); tx->height = height; - LP_address_utxoadd("electrum history",coin,addr,txid,0,0,height,-1); + LP_address_utxoadd((uint32_t)time(NULL),"electrum history",coin,addr,txid,0,0,height,-1); } } } diff --git a/iguana/exchanges/LP_swap.c b/iguana/exchanges/LP_swap.c index ce1b725da..03d08d69e 100644 --- a/iguana/exchanges/LP_swap.c +++ b/iguana/exchanges/LP_swap.c @@ -120,11 +120,21 @@ void basilisk_rawtx_purge(struct basilisk_rawtx *rawtx) void basilisk_swap_finished(struct basilisk_swap *swap) { int32_t i; - if ( swap->utxo != 0 && swap->sentflag == 0 ) + /*if ( swap->utxo != 0 && swap->sentflag == 0 ) { LP_availableset(swap->utxo); swap->utxo = 0; //LP_butxo_swapfields_set(swap->utxo); + }*/ + if ( swap->I.iambob != 0 ) + { + LP_availableset(swap->bobdeposit.utxotxid,swap->bobdeposit.utxovout); + LP_availableset(swap->bobpayment.utxotxid,swap->bobpayment.utxovout); + } + else + { + LP_availableset(swap->alicepayment.utxotxid,swap->alicepayment.utxovout); + LP_availableset(swap->myfee.utxotxid,swap->myfee.utxovout); } swap->I.finished = (uint32_t)time(NULL); // save to permanent storage diff --git a/iguana/exchanges/LP_transaction.c b/iguana/exchanges/LP_transaction.c index 6e4642f3e..4d9ee5fe1 100644 --- a/iguana/exchanges/LP_transaction.c +++ b/iguana/exchanges/LP_transaction.c @@ -911,7 +911,7 @@ int32_t LP_vins_select(void *ctx,struct iguana_info *coin,int64_t *totalp,int64_ if ( up == 0 ) { value = LP_txvalue(0,coin->symbol,utxotxid,utxovout); - LP_address_utxoadd("withdraw",coin,coin->smartaddr,utxotxid,utxovout,value,1,-1); + LP_address_utxoadd((uint32_t)time(NULL),"withdraw",coin,coin->smartaddr,utxotxid,utxovout,value,1,-1); //printf("added after not finding\n"); } if ( (up= LP_address_utxofind(coin,coin->smartaddr,utxotxid,utxovout)) != 0 ) @@ -999,36 +999,6 @@ int32_t LP_vins_select(void *ctx,struct iguana_info *coin,int64_t *totalp,int64_ return(n); } -struct LP_address *LP_address_utxo_reset(struct iguana_info *coin) -{ - struct LP_address *ap; int32_t i,n; cJSON *array,*item; int64_t value; bits256 txid; int32_t vout,height; - LP_listunspent_issue(coin->symbol,coin->smartaddr,2); - if ( (ap= LP_addressfind(coin,coin->smartaddr)) == 0 ) - { - printf("LP_createrawtransaction: cant find address data\n"); - return(0); - } - if ( (array= LP_listunspent(coin->symbol,coin->smartaddr)) != 0 ) - { - ap->utxos = 0; - if ( (n= cJSON_GetArraySize(array)) > 0 ) - { - for (i=0; ismartaddr,txid,vout,value,height,-1); - } - } - free_json(array); - } - return(ap); -} - 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,bits256 utxotxid,int32_t utxovout,uint32_t locktime) { static void *ctx; @@ -1077,7 +1047,12 @@ char *LP_createrawtransaction(cJSON **txobjp,int32_t *numvinsp,struct iguana_inf return(0); } } - if ( (ap= LP_address_utxo_reset(coin)) == 0 ) + if ( bits256_nonz(utxotxid) == 0 ) + { + if ( (ap= LP_address_utxo_reset(coin)) == 0 ) + return(0); + } + else if ( (ap= LP_address(coin,coin->smartaddr)) == 0 ) return(0); memset(utxos,0,sizeof(utxos)); if ( (numutxos= LP_address_utxo_ptrs(coin,0,utxos,max,ap,coin->smartaddr)) <= 0 ) diff --git a/iguana/exchanges/LP_utxo.c b/iguana/exchanges/LP_utxo.c index 3257f6096..f8fab79a7 100644 --- a/iguana/exchanges/LP_utxo.c +++ b/iguana/exchanges/LP_utxo.c @@ -18,6 +18,124 @@ // marketmaker // + +struct LP_inuse_info +{ + bits256 txid,otherpub; + uint32_t expiration; + int32_t vout,ind; +} LP_inuse[1024]; +int32_t LP_numinuse; + +struct LP_inuse_info *_LP_inuse_find(bits256 txid,int32_t vout) +{ + int32_t i; + if ( bits256_nonz(txid) != 0 ) + { + for (i=0; iind; + *lp = LP_inuse[--LP_numinuse]; + lp->ind = ind; + memset(&LP_inuse[LP_numinuse],0,sizeof(struct LP_inuse_info)); + for (ind=0; indtxid = txid; + lp->vout = vout; + lp->expiration = expiration; + lp->otherpub = otherpub; + lp->ind = LP_numinuse++; + } + else + { + if ( bits256_nonz(otherpub) != 0 ) + lp->otherpub = otherpub; + if ( expiration > lp->expiration || expiration == 0 ) + lp->expiration = expiration; + } + return(lp); + } else printf("_LP_inuse_add [%d] overflow\n",LP_numinuse); + return(0); +} + +int32_t LP_reservation_check(bits256 txid,int32_t vout,bits256 pubkey) +{ + struct LP_inuse_info *lp; int32_t retval = -1; + if ( bits256_nonz(pubkey) != 0 ) + { + portable_mutex_lock(&LP_inusemutex); + if ( (lp= _LP_inuse_find(txid,vout)) != 0 ) + { + if ( bits256_cmp(lp->otherpub,pubkey) == 0 ) + retval = 0; + } + portable_mutex_unlock(&LP_inusemutex); + } + return(retval); +} + +uint32_t LP_allocated(bits256 txid,int32_t vout) +{ + struct LP_inuse_info *lp; uint32_t now,duration = 0; + now = (uint32_t)time(NULL); + portable_mutex_lock(&LP_inusemutex); + if ( (lp= _LP_inuse_find(txid,vout)) != 0 ) + { + if ( lp->expiration != 0 && now < lp->expiration ) + duration = (lp->expiration - now); + } + portable_mutex_unlock(&LP_inusemutex); + return(duration); +} + +void LP_unavailableset(bits256 txid,int32_t vout,uint32_t expiration,bits256 otherpub) +{ + portable_mutex_lock(&LP_inusemutex); + _LP_inuse_add(expiration,otherpub,txid,vout); + portable_mutex_unlock(&LP_inusemutex); +} + +void LP_availableset(bits256 txid,int32_t vout) +{ + portable_mutex_lock(&LP_inusemutex); + _LP_inuse_delete(txid,vout); + portable_mutex_unlock(&LP_inusemutex); +} + +int32_t LP_isavailable(struct LP_utxoinfo *utxo) +{ + struct _LP_utxoinfo u; + u = (utxo->iambob != 0) ? utxo->deposit : utxo->fee; + if ( LP_allocated(utxo->payment.txid,utxo->payment.vout) == 0 && LP_allocated(u.txid,u.vout) == 0 ) + return(1); + else return(0); +} + uint64_t LP_value_extract(cJSON *obj,int32_t addinterest) { double val = 0.; uint64_t value = 0; int32_t electrumflag; @@ -116,36 +234,9 @@ int32_t LP_address_minmax(uint64_t *balancep,uint64_t *minp,uint64_t *maxp,struc return(n); } -struct LP_utxoinfo *LP_allocated(bits256 txid,int32_t vout) -{ - struct LP_utxoinfo *utxo; - if ( (utxo= _LP_utxofind(0,txid,vout)) != 0 && LP_isavailable(utxo) == 0 ) - { - //char str[65]; printf("%s/v%d not available\n",bits256_str(str,txid),vout); - return(utxo); - } - if ( (utxo= _LP_utxo2find(0,txid,vout)) != 0 && LP_isavailable(utxo) == 0 ) - { - //char str[65]; printf("%s/v%d not available2\n",bits256_str(str,txid),vout); - return(utxo); - } - if ( (utxo= _LP_utxofind(1,txid,vout)) != 0 && LP_isavailable(utxo) == 0 ) - { - //char str[65]; printf("%s/v%d not available\n",bits256_str(str,txid),vout); - return(utxo); - } - if ( (utxo= _LP_utxo2find(1,txid,vout)) != 0 && LP_isavailable(utxo) == 0 ) - { - //char str[65]; printf("%s/v%d not available2\n",bits256_str(str,txid),vout); - return(utxo); - } - return(0); -} - int32_t LP_address_utxo_ptrs(struct iguana_info *coin,int32_t iambob,struct LP_address_utxo **utxos,int32_t max,struct LP_address *ap,char *coinaddr) { struct LP_address_utxo *up,*tmp; struct LP_transaction *tx; cJSON *txout; int32_t n = 0; - //printf("LP_address_utxo_ptrs for (%s).(%s)\n",ap->coinaddr,coinaddr); if ( strcmp(ap->coinaddr,coinaddr) != 0 ) printf("UNEXPECTED coinaddr mismatch (%s) != (%s)\n",ap->coinaddr,coinaddr); LP_listunspent_issue(coin->symbol,coin->smartaddr,2); @@ -189,7 +280,7 @@ int32_t LP_address_utxo_ptrs(struct iguana_info *coin,int32_t iambob,struct LP_a continue; } } - if ( LP_allocated(up->U.txid,up->U.vout) == 0 )//&& (iambob == 0 || (_LP_utxofind(iambob,up->U.txid,up->U.vout) == 0 && _LP_utxo2find(iambob,up->U.txid,up->U.vout) == 0)) ) + if ( LP_allocated(up->U.txid,up->U.vout) == 0 ) { utxos[n++] = up; if ( n >= max ) @@ -239,7 +330,7 @@ void LP_mark_spent(char *symbol,bits256 txid,int32_t vout) } } -int32_t LP_address_utxoadd(char *debug,struct iguana_info *coin,char *coinaddr,bits256 txid,int32_t vout,uint64_t value,int32_t height,int32_t spendheight) +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) { struct LP_address *ap; cJSON *txobj; struct LP_transaction *tx; struct LP_address_utxo *up,*tmp; int32_t flag,retval = 0; //char str[65]; if ( coin == 0 ) @@ -262,6 +353,7 @@ int32_t LP_address_utxoadd(char *debug,struct iguana_info *coin,char *coinaddr,b up->spendheight = spendheight, flag |= 4; if ( value != 0 && up->U.value == 0 && up->U.value != value ) up->U.value = value, flag |= 8; + up->timestamp = timestamp; //printf("found >>>>>>>>>> %s %s %s/v%d ht.%d %.8f\n",coin->symbol,coinaddr,bits256_str(str,txid),vout,height,dstr(value)); break; } @@ -282,21 +374,61 @@ int32_t LP_address_utxoadd(char *debug,struct iguana_info *coin,char *coinaddr,b up->U.height = height; up->U.value = value; up->spendheight = spendheight; - portable_mutex_lock(&coin->addrmutex); - DL_APPEND(ap->utxos,up); - portable_mutex_unlock(&coin->addrmutex); + up->timestamp = timestamp; retval = 1; if ( (tx= LP_transactionfind(coin,txid)) != 0 && tx->SPV > 0 ) { up->SPV = tx->SPV; //printf("%s ADD UTXO >> %s %s %s/v%d ht.%d %.8f\n",debug,coin->symbol,coinaddr,bits256_str(str,txid),vout,height,dstr(value)); } + portable_mutex_lock(&coin->addrmutex); + DL_APPEND(ap->utxos,up); + portable_mutex_unlock(&coin->addrmutex); } } // else printf("cant get ap %s %s\n",coin->symbol,coinaddr); //printf("done %s add addr.%s ht.%d\n",coin->symbol,coinaddr,height); return(retval); } +struct LP_address *LP_address_utxo_reset(struct iguana_info *coin) +{ + struct LP_address *ap; struct LP_address_utxo *up,*tmp; int32_t i,n,vout,height; cJSON *array,*item; int64_t value; bits256 txid; uint32_t now; + LP_listunspent_issue(coin->symbol,coin->smartaddr,2); + if ( (ap= LP_addressfind(coin,coin->smartaddr)) == 0 ) + { + printf("LP_createrawtransaction: cant find address data\n"); + return(0); + } + if ( (array= LP_listunspent(coin->symbol,coin->smartaddr)) != 0 ) + { + //ap->utxos = 0; + now = (uint32_t)time(NULL); + if ( (n= cJSON_GetArraySize(array)) > 0 ) + { + for (i=0; ismartaddr,txid,vout,value,height,-1); + } + } + free_json(array); + DL_FOREACH_SAFE(ap->utxos,up,tmp) + { + if ( up->timestamp < now ) + { + char str[65]; printf("purge %s/v%d as it wasnt in listunspent\n",bits256_str(str,up->U.txid),up->U.vout); + up->spendheight = 1; + } + } + } + return(ap); +} + cJSON *LP_address_item(struct iguana_info *coin,struct LP_address_utxo *up,int32_t electrumret) { cJSON *item = cJSON_CreateObject(); @@ -422,7 +554,7 @@ cJSON *LP_address_balance(struct iguana_info *coin,char *coinaddr,int32_t electr int32_t LP_unspents_array(struct iguana_info *coin,char *coinaddr,cJSON *array) { - int32_t i,n,v,ht,errs,height,count=0; uint64_t value,val; cJSON *item,*txobj; bits256 txid; + int32_t i,n,v,errs,height,count=0; uint64_t value,val; cJSON *item,*txobj; bits256 txid; if ( (n= cJSON_GetArraySize(array)) <= 0 ) return(0); //printf("%s %s LP_unspents.(%s)\n",coin->symbol,coinaddr,jprint(array,0)); @@ -442,7 +574,7 @@ int32_t LP_unspents_array(struct iguana_info *coin,char *coinaddr,cJSON *array) char str[65]; printf("REJECT %s %s/v%d value.%llu vs %llu (%s)\n",coin->symbol,bits256_str(str,txid),v,(long long)value,(long long)val,jprint(txobj,0)); errs++; } - ht = LP_txheight(coin,txid); + //ht = LP_txheight(coin,txid); //if ( coin->height != 0 ) // ht = LP_getheight(coin) - jint(txobj,"confirmations") + 1; //else ht = 0; @@ -456,7 +588,7 @@ int32_t LP_unspents_array(struct iguana_info *coin,char *coinaddr,cJSON *array) if ( errs == 0 ) { //printf("from LP_unspents_array\n"); - LP_address_utxoadd("LP_unspents_array",coin,coinaddr,txid,v,val,height,-1); + LP_address_utxoadd((uint32_t)time(NULL),"LP_unspents_array",coin,coinaddr,txid,v,val,height,-1); count++; } } @@ -580,7 +712,7 @@ cJSON *LP_transactioninit(struct iguana_info *coin,bits256 txid,int32_t iter,cJS tx->outpoints[i].interest = SATOSHIDEN * jdouble(vout,"interest"); LP_destaddr(tx->outpoints[i].coinaddr,vout); //printf("from transaction init %s %s %s/v%d <- %.8f\n",coin->symbol,tx->outpoints[i].coinaddr,bits256_str(str,txid),i,dstr(tx->outpoints[i].value)); - LP_address_utxoadd("LP_transactioninit iter0",coin,tx->outpoints[i].coinaddr,txid,i,tx->outpoints[i].value,height,-1); + LP_address_utxoadd((uint32_t)time(NULL),"LP_transactioninit iter0",coin,tx->outpoints[i].coinaddr,txid,i,tx->outpoints[i].value,height,-1); } //printf("numvouts.%d\n",numvouts); } @@ -602,7 +734,7 @@ cJSON *LP_transactioninit(struct iguana_info *coin,bits256 txid,int32_t iter,cJS tx->outpoints[spentvout].spendtxid = txid; tx->outpoints[spentvout].spendvini = i; tx->outpoints[spentvout].spendheight = height > 0 ? height : 1; - LP_address_utxoadd("LP_transactioninit iter1",coin,tx->outpoints[spentvout].coinaddr,spenttxid,spentvout,tx->outpoints[spentvout].value,-1,height>0?height:1); + LP_address_utxoadd((uint32_t)time(NULL),"LP_transactioninit iter1",coin,tx->outpoints[spentvout].coinaddr,spenttxid,spentvout,tx->outpoints[spentvout].value,-1,height>0?height:1); if ( 0 && strcmp(coin->symbol,"REVS") == 0 ) printf("spend %s %s/v%d at ht.%d\n",coin->symbol,bits256_str(str,tx->txid),spentvout,height); } diff --git a/iguana/exchanges/LP_utxos.c b/iguana/exchanges/LP_utxos.c index b24c47ff3..c09e7e6c4 100644 --- a/iguana/exchanges/LP_utxos.c +++ b/iguana/exchanges/LP_utxos.c @@ -19,8 +19,6 @@ // - - int32_t LP_ismine(struct LP_utxoinfo *utxo) { if ( utxo != 0 && bits256_cmp(utxo->pubkey,G.LP_mypub25519) == 0 ) @@ -28,15 +26,6 @@ int32_t LP_ismine(struct LP_utxoinfo *utxo) else return(0); } -int32_t LP_isavailable(struct LP_utxoinfo *utxo) -{ - if ( time(NULL) > utxo->T.swappending ) - utxo->T.swappending = 0; - if ( utxo != 0 && utxo->T.swappending == 0 && utxo->S.swap == 0 ) - return(1); - else return(0); -} - int32_t LP_isunspent(struct LP_utxoinfo *utxo) { struct LP_address_utxo *up; struct _LP_utxoinfo u; struct iguana_info *coin; @@ -88,6 +77,41 @@ int32_t LP_utxoaddptrs(struct LP_utxoinfo *ptrs[],int32_t n,struct LP_utxoinfo * return(n); } +/*uint32_t LP_allocated(bits256 txid,int32_t vout) +{ + struct LP_utxoinfo *utxo; + if ( (utxo= _LP_utxofind(0,txid,vout)) != 0 && LP_isavailable(utxo) == 0 ) + { + //char str[65]; printf("%s/v%d not available\n",bits256_str(str,txid),vout); + return(utxo); + } + if ( (utxo= _LP_utxo2find(0,txid,vout)) != 0 && LP_isavailable(utxo) == 0 ) + { + //char str[65]; printf("%s/v%d not available2\n",bits256_str(str,txid),vout); + return(utxo); + } + if ( (utxo= _LP_utxofind(1,txid,vout)) != 0 && LP_isavailable(utxo) == 0 ) + { + //char str[65]; printf("%s/v%d not available\n",bits256_str(str,txid),vout); + return(utxo); + } + if ( (utxo= _LP_utxo2find(1,txid,vout)) != 0 && LP_isavailable(utxo) == 0 ) + { + //char str[65]; printf("%s/v%d not available2\n",bits256_str(str,txid),vout); + return(utxo); + } + return(0); +} + +int32_t LP_isavailable(struct LP_utxoinfo *utxo) +{ + if ( time(NULL) > utxo->T.swappending ) + utxo->T.swappending = 0; + if ( utxo != 0 && utxo->T.swappending == 0 && utxo->S.swap == 0 ) + return(1); + else return(0); +} + int32_t LP_utxocollisions(struct LP_utxoinfo *ptrs[],struct LP_utxoinfo *refutxo) { int32_t iambob,n = 0; struct LP_utxoinfo *utxo; struct _LP_utxoinfo u; @@ -170,6 +194,7 @@ void LP_availableset(struct LP_utxoinfo *utxo) } } } +*/ cJSON *LP_inventoryjson(cJSON *item,struct LP_utxoinfo *utxo) { @@ -208,8 +233,8 @@ cJSON *LP_inventoryjson(cJSON *item,struct LP_utxoinfo *utxo) if ( bits256_nonz(utxo->S.otherpubkey) != 0 ) jaddbits256(item,"srchash",utxo->S.otherpubkey); } - if ( utxo->S.swap != 0 ) - jaddstr(item,"swap","in progress"); + //if ( utxo->S.swap != 0 ) + // jaddstr(item,"swap","in progress"); if ( utxo->T.spentflag != 0 ) jaddnum(item,"spent",utxo->T.spentflag); jaddnum(item,"session",utxo->T.sessionid); @@ -235,7 +260,6 @@ struct LP_utxoinfo *LP_utxo_bestfit(char *symbol,uint64_t destsatoshis) printf("LP_utxo_bestfit error symbol.%p %.8f\n",symbol,dstr(destsatoshis)); return(0); } - // jl777 remove mempool HASH_ITER(hh,G.LP_utxoinfos[iambob],utxo,tmp) { if ( strcmp(symbol,utxo->coin) != 0 ) From bf6c9969aea363188daaf2d58b421a7bbfbf0158 Mon Sep 17 00:00:00 2001 From: jl777 Date: Tue, 14 Nov 2017 18:45:41 +0200 Subject: [PATCH 0747/1664] Test --- iguana/exchanges/LP_utxo.c | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/iguana/exchanges/LP_utxo.c b/iguana/exchanges/LP_utxo.c index f8fab79a7..481250689 100644 --- a/iguana/exchanges/LP_utxo.c +++ b/iguana/exchanges/LP_utxo.c @@ -419,11 +419,12 @@ struct LP_address *LP_address_utxo_reset(struct iguana_info *coin) free_json(array); DL_FOREACH_SAFE(ap->utxos,up,tmp) { - if ( up->timestamp < now ) + char str[65]; + if ( up->timestamp < now && up->spendheight <= 0 ) { - char str[65]; printf("purge %s/v%d as it wasnt in listunspent\n",bits256_str(str,up->U.txid),up->U.vout); + printf("purge %s/v%d as it wasnt in listunspent\n",bits256_str(str,up->U.txid),up->U.vout); up->spendheight = 1; - } + } else printf("%s/v%d %.8f avail\n",bits256_str(str,up->U.txid),up->U.vout,dstr(up->U.value)); } } return(ap); From 2173fc7abb41073e3f48b73b5384641802228111 Mon Sep 17 00:00:00 2001 From: jl777 Date: Tue, 14 Nov 2017 18:47:15 +0200 Subject: [PATCH 0748/1664] Test --- iguana/exchanges/LP_ordermatch.c | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/iguana/exchanges/LP_ordermatch.c b/iguana/exchanges/LP_ordermatch.c index 0ef73ab65..0dcf2bdeb 100644 --- a/iguana/exchanges/LP_ordermatch.c +++ b/iguana/exchanges/LP_ordermatch.c @@ -911,6 +911,11 @@ int32_t LP_tradecommand(void *ctx,char *myipaddr,int32_t pubsock,cJSON *argjson, return(retval); } } + else if ( strcmp(method,"connect") == 0 ) + { + if ( bits256_cmp(G.LP_mypub25519,Q.srchash) != 0 || bits256_cmp(G.LP_mypub25519,Q.desthash) == 0 ) + return(retval); + } if ( strcmp(Q.coinaddr,coin->smartaddr) != 0 ) { printf("bob is patching Q.coinaddr %s mismatch != %s\n",Q.coinaddr,coin->smartaddr); @@ -958,9 +963,7 @@ int32_t LP_tradecommand(void *ctx,char *myipaddr,int32_t pubsock,cJSON *argjson, else if ( strcmp(method,"connect") == 0 ) // bob { retval = 4; - if ( bits256_cmp(G.LP_mypub25519,Q.srchash) != 0 || bits256_cmp(G.LP_mypub25519,Q.desthash) == 0 ) - return(retval); - else if ( LP_reservation_check(Q.txid,Q.vout,Q.desthash) == 0 && LP_reservation_check(Q.txid2,Q.vout2,Q.desthash) == 0 ) + if ( LP_reservation_check(Q.txid,Q.vout,Q.desthash) == 0 && LP_reservation_check(Q.txid2,Q.vout2,Q.desthash) == 0 ) { LP_connectstartbob(ctx,pubsock,argjson,Q.srccoin,Q.destcoin,qprice,&Q); return(retval); From 5b3d32166247efac6dd283c09552428c248fbc45 Mon Sep 17 00:00:00 2001 From: jl777 Date: Tue, 14 Nov 2017 18:52:54 +0200 Subject: [PATCH 0749/1664] Test --- iguana/exchanges/LP_utxo.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/iguana/exchanges/LP_utxo.c b/iguana/exchanges/LP_utxo.c index 481250689..c43d2e02c 100644 --- a/iguana/exchanges/LP_utxo.c +++ b/iguana/exchanges/LP_utxo.c @@ -393,10 +393,11 @@ int32_t LP_address_utxoadd(uint32_t timestamp,char *debug,struct iguana_info *co struct LP_address *LP_address_utxo_reset(struct iguana_info *coin) { struct LP_address *ap; struct LP_address_utxo *up,*tmp; int32_t i,n,vout,height; cJSON *array,*item; int64_t value; bits256 txid; uint32_t now; + LP_address(coin,coin->smartaddr); LP_listunspent_issue(coin->symbol,coin->smartaddr,2); if ( (ap= LP_addressfind(coin,coin->smartaddr)) == 0 ) { - printf("LP_createrawtransaction: cant find address data\n"); + printf("LP_address_utxo_reset: cant find address data\n"); return(0); } if ( (array= LP_listunspent(coin->symbol,coin->smartaddr)) != 0 ) From 9b896d4d4a4c8ee4616d351c60095403f9ded856 Mon Sep 17 00:00:00 2001 From: jl777 Date: Tue, 14 Nov 2017 18:56:03 +0200 Subject: [PATCH 0750/1664] Test --- iguana/exchanges/LP_utxo.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/iguana/exchanges/LP_utxo.c b/iguana/exchanges/LP_utxo.c index c43d2e02c..715c103a8 100644 --- a/iguana/exchanges/LP_utxo.c +++ b/iguana/exchanges/LP_utxo.c @@ -354,7 +354,7 @@ int32_t LP_address_utxoadd(uint32_t timestamp,char *debug,struct iguana_info *co if ( value != 0 && up->U.value == 0 && up->U.value != value ) up->U.value = value, flag |= 8; up->timestamp = timestamp; -//printf("found >>>>>>>>>> %s %s %s/v%d ht.%d %.8f\n",coin->symbol,coinaddr,bits256_str(str,txid),vout,height,dstr(value)); + char str[65]; printf("found >>>>>>>>>> %s %s %s/v%d ht.%d %.8f\n",coin->symbol,coinaddr,bits256_str(str,txid),vout,height,dstr(value)); break; } } @@ -379,8 +379,8 @@ int32_t LP_address_utxoadd(uint32_t timestamp,char *debug,struct iguana_info *co if ( (tx= LP_transactionfind(coin,txid)) != 0 && tx->SPV > 0 ) { up->SPV = tx->SPV; - //printf("%s ADD UTXO >> %s %s %s/v%d ht.%d %.8f\n",debug,coin->symbol,coinaddr,bits256_str(str,txid),vout,height,dstr(value)); } + char str[65]; printf("%s ADD UTXO >> %s %s %s/v%d ht.%d %.8f\n",debug,coin->symbol,coinaddr,bits256_str(str,txid),vout,height,dstr(value)); portable_mutex_lock(&coin->addrmutex); DL_APPEND(ap->utxos,up); portable_mutex_unlock(&coin->addrmutex); From d2314e8a25c1f63f788f2c9c7060cbf90f17fe97 Mon Sep 17 00:00:00 2001 From: jl777 Date: Tue, 14 Nov 2017 19:02:03 +0200 Subject: [PATCH 0751/1664] Test --- iguana/exchanges/LP_utxo.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/iguana/exchanges/LP_utxo.c b/iguana/exchanges/LP_utxo.c index 715c103a8..8d35d9ea5 100644 --- a/iguana/exchanges/LP_utxo.c +++ b/iguana/exchanges/LP_utxo.c @@ -354,7 +354,7 @@ int32_t LP_address_utxoadd(uint32_t timestamp,char *debug,struct iguana_info *co if ( value != 0 && up->U.value == 0 && up->U.value != value ) up->U.value = value, flag |= 8; up->timestamp = timestamp; - char str[65]; printf("found >>>>>>>>>> %s %s %s/v%d ht.%d %.8f\n",coin->symbol,coinaddr,bits256_str(str,txid),vout,height,dstr(value)); + //char str[65]; printf("found >>>>>>>>>> %s %s %s/v%d ht.%d %.8f\n",coin->symbol,coinaddr,bits256_str(str,txid),vout,height,dstr(value)); break; } } @@ -379,8 +379,8 @@ int32_t LP_address_utxoadd(uint32_t timestamp,char *debug,struct iguana_info *co if ( (tx= LP_transactionfind(coin,txid)) != 0 && tx->SPV > 0 ) { up->SPV = tx->SPV; + //char str[65]; printf("%s ADD UTXO >> %s %s %s/v%d ht.%d %.8f\n",debug,coin->symbol,coinaddr,bits256_str(str,txid),vout,height,dstr(value)); } - char str[65]; printf("%s ADD UTXO >> %s %s %s/v%d ht.%d %.8f\n",debug,coin->symbol,coinaddr,bits256_str(str,txid),vout,height,dstr(value)); portable_mutex_lock(&coin->addrmutex); DL_APPEND(ap->utxos,up); portable_mutex_unlock(&coin->addrmutex); From 12408f15db8c2367fd96273ab05b72b607593d45 Mon Sep 17 00:00:00 2001 From: jl777 Date: Tue, 14 Nov 2017 19:07:32 +0200 Subject: [PATCH 0752/1664] Test --- iguana/exchanges/LP_ordermatch.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/iguana/exchanges/LP_ordermatch.c b/iguana/exchanges/LP_ordermatch.c index 0dcf2bdeb..1b8103090 100644 --- a/iguana/exchanges/LP_ordermatch.c +++ b/iguana/exchanges/LP_ordermatch.c @@ -370,7 +370,7 @@ struct LP_utxoinfo *LP_address_myutxopair(struct LP_utxoinfo *butxo,int32_t iamb { if ( (m= LP_address_utxo_ptrs(coin,iambob,utxos,max,ap,coinaddr)) > 1 ) { - if ( 0 ) + if ( 1 ) { int32_t i; for (i=0; i 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 ) { @@ -397,6 +397,7 @@ struct LP_utxoinfo *LP_address_myutxopair(struct LP_utxoinfo *butxo,int32_t iamb return(butxo); }*/ LP_butxo_set(butxo,coin,up,up2,targetval); + return(butxo); } } //else printf("cant find targetval2 %.8f\n",dstr(targetval2)); } //else printf("failed ratio test %.8f\n",(double)up->U.value/targetval); From accfa2bc627d35f1eda979f7886300be1cf4e33a Mon Sep 17 00:00:00 2001 From: jl777 Date: Tue, 14 Nov 2017 19:15:34 +0200 Subject: [PATCH 0753/1664] Test --- iguana/exchanges/LP_utxo.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/iguana/exchanges/LP_utxo.c b/iguana/exchanges/LP_utxo.c index 8d35d9ea5..268a6362c 100644 --- a/iguana/exchanges/LP_utxo.c +++ b/iguana/exchanges/LP_utxo.c @@ -349,7 +349,7 @@ int32_t LP_address_utxoadd(uint32_t timestamp,char *debug,struct iguana_info *co flag = 1; if ( height > 0 && up->U.height != height ) up->U.height = height, flag |= 2; - if ( spendheight > 0 && up->spendheight != spendheight ) + if ( up->spendheight != spendheight ) up->spendheight = spendheight, flag |= 4; if ( value != 0 && up->U.value == 0 && up->U.value != value ) up->U.value = value, flag |= 8; From a286a2339316c4a92d6858b65c7a7213fdc081ca Mon Sep 17 00:00:00 2001 From: jl777 Date: Tue, 14 Nov 2017 19:22:48 +0200 Subject: [PATCH 0754/1664] Test --- iguana/exchanges/LP_include.h | 2 +- iguana/exchanges/LP_utxo.c | 25 +++++++++++-------------- 2 files changed, 12 insertions(+), 15 deletions(-) diff --git a/iguana/exchanges/LP_include.h b/iguana/exchanges/LP_include.h index c24ad9bf4..1b0394f95 100644 --- a/iguana/exchanges/LP_include.h +++ b/iguana/exchanges/LP_include.h @@ -308,7 +308,7 @@ struct LP_address_utxo struct LP_address_utxo *next,*prev; struct _LP_utxoinfo U; int32_t SPV,spendheight; - uint32_t timestamp; + //uint32_t timestamp; }; struct LP_address diff --git a/iguana/exchanges/LP_utxo.c b/iguana/exchanges/LP_utxo.c index 268a6362c..007178e94 100644 --- a/iguana/exchanges/LP_utxo.c +++ b/iguana/exchanges/LP_utxo.c @@ -243,7 +243,7 @@ int32_t LP_address_utxo_ptrs(struct iguana_info *coin,int32_t iambob,struct LP_a portable_mutex_lock(&LP_utxomutex); DL_FOREACH_SAFE(ap->utxos,up,tmp) { - //char str[65]; printf("LP_address_utxo_ptrs %s n.%d %.8f %s v%d spendheight.%d allocated.%p\n",ap->coinaddr,n,dstr(up->U.value),bits256_str(str,up->U.txid),up->U.vout,up->spendheight,LP_allocated(up->U.txid,up->U.vout)); + char str[65]; printf("LP_address_utxo_ptrs %s n.%d %.8f %s v%d spendheight.%d allocated.%d\n",ap->coinaddr,n,dstr(up->U.value),bits256_str(str,up->U.txid),up->U.vout,up->spendheight,LP_allocated(up->U.txid,up->U.vout)); if ( up->spendheight <= 0 && LP_RTmetrics_avoidtxid(up->U.txid) < 0 ) { if ( coin->electrum == 0 ) @@ -349,11 +349,11 @@ int32_t LP_address_utxoadd(uint32_t timestamp,char *debug,struct iguana_info *co flag = 1; if ( height > 0 && up->U.height != height ) up->U.height = height, flag |= 2; - if ( up->spendheight != spendheight ) + if ( spendheight > 0 && up->spendheight != spendheight ) up->spendheight = spendheight, flag |= 4; if ( value != 0 && up->U.value == 0 && up->U.value != value ) up->U.value = value, flag |= 8; - up->timestamp = timestamp; + //up->timestamp = timestamp; //char str[65]; printf("found >>>>>>>>>> %s %s %s/v%d ht.%d %.8f\n",coin->symbol,coinaddr,bits256_str(str,txid),vout,height,dstr(value)); break; } @@ -374,7 +374,7 @@ int32_t LP_address_utxoadd(uint32_t timestamp,char *debug,struct iguana_info *co up->U.height = height; up->U.value = value; up->spendheight = spendheight; - up->timestamp = timestamp; + //up->timestamp = timestamp; retval = 1; if ( (tx= LP_transactionfind(coin,txid)) != 0 && tx->SPV > 0 ) { @@ -402,7 +402,13 @@ struct LP_address *LP_address_utxo_reset(struct iguana_info *coin) } if ( (array= LP_listunspent(coin->symbol,coin->smartaddr)) != 0 ) { - //ap->utxos = 0; + DL_FOREACH_SAFE(ap->utxos,up,tmp) + { + portable_mutex_lock(&coin->addrmutex); + DL_DELETE(ap->utxos,up); + portable_mutex_unlock(&coin->addrmutex); + free(up); + } now = (uint32_t)time(NULL); if ( (n= cJSON_GetArraySize(array)) > 0 ) { @@ -418,15 +424,6 @@ struct LP_address *LP_address_utxo_reset(struct iguana_info *coin) } } free_json(array); - DL_FOREACH_SAFE(ap->utxos,up,tmp) - { - char str[65]; - if ( up->timestamp < now && up->spendheight <= 0 ) - { - printf("purge %s/v%d as it wasnt in listunspent\n",bits256_str(str,up->U.txid),up->U.vout); - up->spendheight = 1; - } else printf("%s/v%d %.8f avail\n",bits256_str(str,up->U.txid),up->U.vout,dstr(up->U.value)); - } } return(ap); } From 1be8574932fdfc0df0de45e7dbf4aca5f04d0a20 Mon Sep 17 00:00:00 2001 From: jl777 Date: Tue, 14 Nov 2017 19:28:32 +0200 Subject: [PATCH 0755/1664] Test --- iguana/exchanges/LP_utxo.c | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/iguana/exchanges/LP_utxo.c b/iguana/exchanges/LP_utxo.c index 007178e94..7d36a9eab 100644 --- a/iguana/exchanges/LP_utxo.c +++ b/iguana/exchanges/LP_utxo.c @@ -252,7 +252,7 @@ int32_t LP_address_utxo_ptrs(struct iguana_info *coin,int32_t iambob,struct LP_a { if ( LP_value_extract(txout,0) == 0 ) { - //printf("LP_address_utxo_ptrs skip zero value %s/v%d\n",bits256_str(str,up->U.txid),up->U.vout); + printf("LP_address_utxo_ptrs skip zero value %s/v%d\n",bits256_str(str,up->U.txid),up->U.vout); free_json(txout); up->spendheight = 1; if ( (tx= LP_transactionfind(coin,up->U.txid)) != 0 && up->U.vout < tx->numvouts ) @@ -263,7 +263,7 @@ int32_t LP_address_utxo_ptrs(struct iguana_info *coin,int32_t iambob,struct LP_a } else { - //printf("LP_address_utxo_ptrs skips %s %s payment %s/v%d is spent\n",coin->symbol,coinaddr,bits256_str(str,up->U.txid),up->U.vout); + printf("LP_address_utxo_ptrs skips %s %s payment %s/v%d is spent\n",coin->symbol,coinaddr,bits256_str(str,up->U.txid),up->U.vout); up->spendheight = 1; if ( (tx= LP_transactionfind(coin,up->U.txid)) != 0 && up->U.vout < tx->numvouts ) tx->outpoints[up->U.vout].spendheight = 1; @@ -274,7 +274,7 @@ int32_t LP_address_utxo_ptrs(struct iguana_info *coin,int32_t iambob,struct LP_a { if ( up->SPV < 0 || up->U.height == 0 ) { -//printf("LP_address_utxo_ptrs skips %s/v%u due to SPV.%d ht.%d\n",bits256_str(str,up->U.txid),up->U.vout,up->SPV,up->U.height); +printf("LP_address_utxo_ptrs skips %s/v%u due to SPV.%d ht.%d\n",bits256_str(str,up->U.txid),up->U.vout,up->SPV,up->U.height); if ( (tx= LP_transactionfind(coin,up->U.txid)) != 0 && up->U.vout < tx->numvouts ) tx->outpoints[up->U.vout].spendheight = 1; continue; @@ -285,7 +285,7 @@ int32_t LP_address_utxo_ptrs(struct iguana_info *coin,int32_t iambob,struct LP_a utxos[n++] = up; if ( n >= max ) break; - } + } else printf("LP_allocated skip\n"); } else { @@ -422,6 +422,7 @@ struct LP_address *LP_address_utxo_reset(struct iguana_info *coin) height = jint(item,"height"); LP_address_utxoadd(now,"withdraw",coin,coin->smartaddr,txid,vout,value,height,-1); } + printf("added %d from listunspents\n",n); } free_json(array); } From 58896cc3b8be5fcbaf53e0b23a77dade8671a1b7 Mon Sep 17 00:00:00 2001 From: jl777 Date: Tue, 14 Nov 2017 19:32:45 +0200 Subject: [PATCH 0756/1664] Test --- iguana/exchanges/LP_ordermatch.c | 4 ++-- iguana/exchanges/LP_utxo.c | 8 ++++---- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/iguana/exchanges/LP_ordermatch.c b/iguana/exchanges/LP_ordermatch.c index 1b8103090..1c8524d06 100644 --- a/iguana/exchanges/LP_ordermatch.c +++ b/iguana/exchanges/LP_ordermatch.c @@ -366,7 +366,7 @@ struct LP_utxoinfo *LP_address_myutxopair(struct LP_utxoinfo *butxo,int32_t iamb memset(butxo,0,sizeof(*butxo)); targetval = LP_basesatoshis(relvolume,price,txfee,desttxfee); targetval2 = (targetval / 8) * 9 + 2*txfee; - if ( coin != 0 && (ap= LP_addressfind(coin,coinaddr)) != 0 ) + if ( coin != 0 && (ap= LP_address(coin,coinaddr)) != 0 ) { if ( (m= LP_address_utxo_ptrs(coin,iambob,utxos,max,ap,coinaddr)) > 1 ) { @@ -403,7 +403,7 @@ printf("found mini.%d %.8f for targetval %.8f -> targetval2 %.8f, ratio %.2f\n", } //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); - } //else printf("no %s utxos pass LP_address_utxo_ptrs filter\n",coinaddr); + } else printf("no %s utxos pass LP_address_utxo_ptrs filter\n",coinaddr); } else printf("couldnt find %s %s\n",coin->symbol,coinaddr); return(0); } diff --git a/iguana/exchanges/LP_utxo.c b/iguana/exchanges/LP_utxo.c index 7d36a9eab..b63ee8673 100644 --- a/iguana/exchanges/LP_utxo.c +++ b/iguana/exchanges/LP_utxo.c @@ -239,8 +239,8 @@ int32_t LP_address_utxo_ptrs(struct iguana_info *coin,int32_t iambob,struct LP_a struct LP_address_utxo *up,*tmp; struct LP_transaction *tx; cJSON *txout; int32_t n = 0; if ( strcmp(ap->coinaddr,coinaddr) != 0 ) printf("UNEXPECTED coinaddr mismatch (%s) != (%s)\n",ap->coinaddr,coinaddr); - LP_listunspent_issue(coin->symbol,coin->smartaddr,2); - portable_mutex_lock(&LP_utxomutex); + //LP_listunspent_issue(coin->symbol,coin->smartaddr,2); + //portable_mutex_lock(&LP_utxomutex); DL_FOREACH_SAFE(ap->utxos,up,tmp) { char str[65]; printf("LP_address_utxo_ptrs %s n.%d %.8f %s v%d spendheight.%d allocated.%d\n",ap->coinaddr,n,dstr(up->U.value),bits256_str(str,up->U.txid),up->U.vout,up->spendheight,LP_allocated(up->U.txid,up->U.vout)); @@ -293,8 +293,8 @@ printf("LP_address_utxo_ptrs skips %s/v%u due to SPV.%d ht.%d\n",bits256_str(str tx->outpoints[up->U.vout].spendheight = 1; } } - portable_mutex_unlock(&LP_utxomutex); - //printf("return n.%d\n",n); + //portable_mutex_unlock(&LP_utxomutex); + printf("return n.%d for %s %s\n",n,coin->symbol,coinaddr); return(n); } From e15152011322a7c1006e288c6064c939232388cd Mon Sep 17 00:00:00 2001 From: jl777 Date: Tue, 14 Nov 2017 19:36:21 +0200 Subject: [PATCH 0757/1664] Test --- iguana/exchanges/LP_utxo.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/iguana/exchanges/LP_utxo.c b/iguana/exchanges/LP_utxo.c index b63ee8673..250e5c1c2 100644 --- a/iguana/exchanges/LP_utxo.c +++ b/iguana/exchanges/LP_utxo.c @@ -364,7 +364,7 @@ int32_t LP_address_utxoadd(uint32_t timestamp,char *debug,struct iguana_info *co { if ( (txobj= LP_gettxout(coin->symbol,coinaddr,txid,vout)) == 0 ) { - //printf("prevent utxoadd since gettxout %s %s %s/v%d missing\n",coin->symbol,coinaddr,bits256_str(str,txid),vout); + char str[65]; printf("prevent utxoadd since gettxout %s %s %s/v%d missing\n",coin->symbol,coinaddr,bits256_str(str,txid),vout); return(0); } else free_json(txobj); } @@ -379,8 +379,10 @@ int32_t LP_address_utxoadd(uint32_t timestamp,char *debug,struct iguana_info *co if ( (tx= LP_transactionfind(coin,txid)) != 0 && tx->SPV > 0 ) { up->SPV = tx->SPV; - //char str[65]; printf("%s ADD UTXO >> %s %s %s/v%d ht.%d %.8f\n",debug,coin->symbol,coinaddr,bits256_str(str,txid),vout,height,dstr(value)); } + char str[65]; + if ( strcmp(coin->smartaddr,coinaddr) == 0 && strcmp("KMD",coin->symbol) == 0 ) + printf("%s ADD UTXO >> %s %s %s/v%d ht.%d %.8f\n",debug,coin->symbol,coinaddr,bits256_str(str,txid),vout,height,dstr(value)); portable_mutex_lock(&coin->addrmutex); DL_APPEND(ap->utxos,up); portable_mutex_unlock(&coin->addrmutex); From 4057fd6f59ecf4a68d014a0ba1337fac3b20753f Mon Sep 17 00:00:00 2001 From: jl777 Date: Tue, 14 Nov 2017 19:41:20 +0200 Subject: [PATCH 0758/1664] Test --- iguana/exchanges/LP_utxo.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/iguana/exchanges/LP_utxo.c b/iguana/exchanges/LP_utxo.c index 250e5c1c2..1d0770e44 100644 --- a/iguana/exchanges/LP_utxo.c +++ b/iguana/exchanges/LP_utxo.c @@ -414,6 +414,7 @@ struct LP_address *LP_address_utxo_reset(struct iguana_info *coin) now = (uint32_t)time(NULL); if ( (n= cJSON_GetArraySize(array)) > 0 ) { + char str[65]; for (i=0; ismartaddr,txid,vout,value,height,-1); + if ( (up= LP_address_utxofind(coin,coin->smartaddr,txid,vout)) == 0 ) + printf("couldnt find just added %s/%d ht.%d %.8f\n",bits256_str(str,txid),vout,height,dstr(value)); } printf("added %d from listunspents\n",n); } From f0063628c38e000cc7ef0aba9826768644206e6b Mon Sep 17 00:00:00 2001 From: jl777 Date: Tue, 14 Nov 2017 19:44:44 +0200 Subject: [PATCH 0759/1664] Test --- iguana/exchanges/LP_utxo.c | 18 ++++++++++++++---- 1 file changed, 14 insertions(+), 4 deletions(-) diff --git a/iguana/exchanges/LP_utxo.c b/iguana/exchanges/LP_utxo.c index 1d0770e44..c695ffae6 100644 --- a/iguana/exchanges/LP_utxo.c +++ b/iguana/exchanges/LP_utxo.c @@ -419,10 +419,20 @@ struct LP_address *LP_address_utxo_reset(struct iguana_info *coin) { //{"tx_hash":"38d1b7c73015e1b1d6cb7fc314cae402a635b7d7ea294970ab857df8777a66f4","tx_pos":0,"height":577975,"value":238700} item = jitem(array,i); - txid = jbits256(item,"tx_hash"); - vout = juint(item,"tx_pos"); - value = j64bits(item,"value"); - height = jint(item,"height"); + if ( coin->electrum != 0 ) + { + txid = jbits256(item,"tx_hash"); + vout = juint(item,"tx_pos"); + value = j64bits(item,"value"); + height = jint(item,"height"); + } + else + { + txid = jbits256(item,"txid"); + vout = juint(item,"vout"); + value = LP_value_extract(item,0); + height = LP_txheight(coin,txid); + } LP_address_utxoadd(now,"withdraw",coin,coin->smartaddr,txid,vout,value,height,-1); if ( (up= LP_address_utxofind(coin,coin->smartaddr,txid,vout)) == 0 ) printf("couldnt find just added %s/%d ht.%d %.8f\n",bits256_str(str,txid),vout,height,dstr(value)); From c569b02a464982e328742698712e9892d4148d9c Mon Sep 17 00:00:00 2001 From: jl777 Date: Tue, 14 Nov 2017 19:50:34 +0200 Subject: [PATCH 0760/1664] Test --- iguana/exchanges/LP_utxo.c | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/iguana/exchanges/LP_utxo.c b/iguana/exchanges/LP_utxo.c index c695ffae6..85d7df5ed 100644 --- a/iguana/exchanges/LP_utxo.c +++ b/iguana/exchanges/LP_utxo.c @@ -364,7 +364,7 @@ int32_t LP_address_utxoadd(uint32_t timestamp,char *debug,struct iguana_info *co { if ( (txobj= LP_gettxout(coin->symbol,coinaddr,txid,vout)) == 0 ) { - char str[65]; printf("prevent utxoadd since gettxout %s %s %s/v%d missing\n",coin->symbol,coinaddr,bits256_str(str,txid),vout); + //char str[65]; printf("prevent utxoadd since gettxout %s %s %s/v%d missing\n",coin->symbol,coinaddr,bits256_str(str,txid),vout); return(0); } else free_json(txobj); } @@ -381,7 +381,7 @@ int32_t LP_address_utxoadd(uint32_t timestamp,char *debug,struct iguana_info *co up->SPV = tx->SPV; } char str[65]; - if ( strcmp(coin->smartaddr,coinaddr) == 0 && strcmp("KMD",coin->symbol) == 0 ) + if ( 0 && strcmp(coin->smartaddr,coinaddr) == 0 && strcmp("KMD",coin->symbol) == 0 ) printf("%s ADD UTXO >> %s %s %s/v%d ht.%d %.8f\n",debug,coin->symbol,coinaddr,bits256_str(str,txid),vout,height,dstr(value)); portable_mutex_lock(&coin->addrmutex); DL_APPEND(ap->utxos,up); @@ -492,7 +492,10 @@ cJSON *LP_address_utxos(struct iguana_info *coin,char *coinaddr,int32_t electrum } if ( up->spendheight <= 0 && up->U.value != 0 ) { - if ( coin->electrum == 0 || up->SPV > 0 ) + char str[65]; + if ( LP_allocated(up->U.txid,up->U.vout) != 0 ) + printf("%s %s/v%d allocated\n",coin->symbol,bits256_str(str,up->U.txid),up->U.vout); + else if ( coin->electrum == 0 || up->SPV > 0 ) { jaddi(array,LP_address_item(coin,up,electrumret)); n++; From 383adfe215b06060b56fcb30d0117dc6cfd0bf1c Mon Sep 17 00:00:00 2001 From: jl777 Date: Tue, 14 Nov 2017 20:06:45 +0200 Subject: [PATCH 0761/1664] Test --- iguana/exchanges/LP_utxo.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/iguana/exchanges/LP_utxo.c b/iguana/exchanges/LP_utxo.c index 85d7df5ed..0fe71aa4e 100644 --- a/iguana/exchanges/LP_utxo.c +++ b/iguana/exchanges/LP_utxo.c @@ -243,7 +243,7 @@ int32_t LP_address_utxo_ptrs(struct iguana_info *coin,int32_t iambob,struct LP_a //portable_mutex_lock(&LP_utxomutex); DL_FOREACH_SAFE(ap->utxos,up,tmp) { - char str[65]; printf("LP_address_utxo_ptrs %s n.%d %.8f %s v%d spendheight.%d allocated.%d\n",ap->coinaddr,n,dstr(up->U.value),bits256_str(str,up->U.txid),up->U.vout,up->spendheight,LP_allocated(up->U.txid,up->U.vout)); + //char str[65]; printf("LP_address_utxo_ptrs %s n.%d %.8f %s v%d spendheight.%d allocated.%d\n",ap->coinaddr,n,dstr(up->U.value),bits256_str(str,up->U.txid),up->U.vout,up->spendheight,LP_allocated(up->U.txid,up->U.vout)); if ( up->spendheight <= 0 && LP_RTmetrics_avoidtxid(up->U.txid) < 0 ) { if ( coin->electrum == 0 ) @@ -252,7 +252,7 @@ int32_t LP_address_utxo_ptrs(struct iguana_info *coin,int32_t iambob,struct LP_a { if ( LP_value_extract(txout,0) == 0 ) { - printf("LP_address_utxo_ptrs skip zero value %s/v%d\n",bits256_str(str,up->U.txid),up->U.vout); + //printf("LP_address_utxo_ptrs skip zero value %s/v%d\n",bits256_str(str,up->U.txid),up->U.vout); free_json(txout); up->spendheight = 1; if ( (tx= LP_transactionfind(coin,up->U.txid)) != 0 && up->U.vout < tx->numvouts ) @@ -263,7 +263,7 @@ int32_t LP_address_utxo_ptrs(struct iguana_info *coin,int32_t iambob,struct LP_a } else { - printf("LP_address_utxo_ptrs skips %s %s payment %s/v%d is spent\n",coin->symbol,coinaddr,bits256_str(str,up->U.txid),up->U.vout); + //printf("LP_address_utxo_ptrs skips %s %s payment %s/v%d is spent\n",coin->symbol,coinaddr,bits256_str(str,up->U.txid),up->U.vout); up->spendheight = 1; if ( (tx= LP_transactionfind(coin,up->U.txid)) != 0 && up->U.vout < tx->numvouts ) tx->outpoints[up->U.vout].spendheight = 1; @@ -274,7 +274,7 @@ int32_t LP_address_utxo_ptrs(struct iguana_info *coin,int32_t iambob,struct LP_a { if ( up->SPV < 0 || up->U.height == 0 ) { -printf("LP_address_utxo_ptrs skips %s/v%u due to SPV.%d ht.%d\n",bits256_str(str,up->U.txid),up->U.vout,up->SPV,up->U.height); +//printf("LP_address_utxo_ptrs skips %s/v%u due to SPV.%d ht.%d\n",bits256_str(str,up->U.txid),up->U.vout,up->SPV,up->U.height); if ( (tx= LP_transactionfind(coin,up->U.txid)) != 0 && up->U.vout < tx->numvouts ) tx->outpoints[up->U.vout].spendheight = 1; continue; From 434c96cd41b1e6d5d2f1531af202be2faeb17ed9 Mon Sep 17 00:00:00 2001 From: jl777 Date: Tue, 14 Nov 2017 21:02:34 +0200 Subject: [PATCH 0762/1664] Test --- iguana/exchanges/LP_ordermatch.c | 4 ++-- iguana/exchanges/LP_socket.c | 4 ++-- iguana/exchanges/LP_utxos.c | 2 +- 3 files changed, 5 insertions(+), 5 deletions(-) diff --git a/iguana/exchanges/LP_ordermatch.c b/iguana/exchanges/LP_ordermatch.c index 1c8524d06..a27dc1078 100644 --- a/iguana/exchanges/LP_ordermatch.c +++ b/iguana/exchanges/LP_ordermatch.c @@ -404,7 +404,7 @@ printf("found mini.%d %.8f for targetval %.8f -> targetval2 %.8f, ratio %.2f\n", } else if ( targetval != 0 && mini >= 0 ) printf("targetval %.8f mini.%d\n",dstr(targetval),mini); } else printf("no %s utxos pass LP_address_utxo_ptrs filter\n",coinaddr); - } else printf("couldnt find %s %s\n",coin->symbol,coinaddr); + } else printf("address_myutxopair couldnt find %s %s\n",coin->symbol,coinaddr); return(0); } @@ -812,7 +812,7 @@ int32_t LP_tradecommand(void *ctx,char *myipaddr,int32_t pubsock,cJSON *argjson, return(retval); } price = ask; - printf("MYPRICE %s/%s %.8f vs qprice %.8f\n",Q.srccoin,Q.destcoin,price,qprice); + //printf("MYPRICE %s/%s %.8f vs qprice %.8f\n",Q.srccoin,Q.destcoin,price,qprice); if ( LP_validSPV(Q.destcoin,Q.destaddr,Q.desttxid,Q.destvout) < 0 ) { printf("%s dest %s failed SPV check\n",Q.destcoin,bits256_str(str,Q.desttxid)); diff --git a/iguana/exchanges/LP_socket.c b/iguana/exchanges/LP_socket.c index 870543904..e50e648d4 100644 --- a/iguana/exchanges/LP_socket.c +++ b/iguana/exchanges/LP_socket.c @@ -578,8 +578,8 @@ cJSON *electrum_address_listunspent(char *symbol,struct electrum_info *ep,cJSON cJSON *retjson=0; char *retstr; struct LP_address *ap; struct iguana_info *coin; int32_t updatedflag,height,usecache=1; if ( (coin= LP_coinfind(symbol)) == 0 ) return(0); - //if ( strcmp(addr,INSTANTDEX_KMD) == 0 ) - // return(cJSON_Parse("[]")); + if ( strcmp(addr,INSTANTDEX_KMD) == 0 ) + return(cJSON_Parse("[]")); if ( ep == 0 || ep->heightp == 0 ) height = coin->longestchain; else height = *(ep->heightp); diff --git a/iguana/exchanges/LP_utxos.c b/iguana/exchanges/LP_utxos.c index c09e7e6c4..2816dd303 100644 --- a/iguana/exchanges/LP_utxos.c +++ b/iguana/exchanges/LP_utxos.c @@ -516,7 +516,7 @@ cJSON *LP_inventory(char *symbol) { //if ( utxo->T.spentflag == 0 ) // utxo->T.spentflag = (uint32_t)time(NULL); - printf("%s %s ineligible %.8f %.8f\n",utxo->coin,bits256_str(str,u.txid),dstr(val),dstr(val2)); + //printf("%s %s ineligible %.8f %.8f\n",utxo->coin,bits256_str(str,u.txid),dstr(val),dstr(val2)); continue; } //if ( iambob != 0 ) From 437501f854783fe1a5995a4ed8c9a8593f646a53 Mon Sep 17 00:00:00 2001 From: jl777 Date: Tue, 14 Nov 2017 21:55:30 +0200 Subject: [PATCH 0763/1664] Test --- iguana/exchanges/LP_nativeDEX.c | 1 + iguana/exchanges/LP_network.c | 15 ++++++- iguana/exchanges/LP_ordermatch.c | 64 ++++++++++++------------------ iguana/exchanges/LP_statemachine.c | 35 ++++++++++++++++ iguana/exchanges/LP_utxo.c | 7 +++- 5 files changed, 81 insertions(+), 41 deletions(-) diff --git a/iguana/exchanges/LP_nativeDEX.c b/iguana/exchanges/LP_nativeDEX.c index 713e8e7de..64687dedc 100644 --- a/iguana/exchanges/LP_nativeDEX.c +++ b/iguana/exchanges/LP_nativeDEX.c @@ -87,6 +87,7 @@ struct LP_forwardinfo *LP_forwardinfos; struct iguana_info *LP_coins; struct LP_pubkeyinfo *LP_pubkeyinfos; struct rpcrequest_info *LP_garbage_collector; +struct LP_address_utxo *LP_garbage_collector2; //uint32_t LP_deadman_switch; diff --git a/iguana/exchanges/LP_network.c b/iguana/exchanges/LP_network.c index 101313348..49cefa778 100644 --- a/iguana/exchanges/LP_network.c +++ b/iguana/exchanges/LP_network.c @@ -267,7 +267,7 @@ int32_t LP_peerindsock(int32_t *peerindp) void gc_loop(void *arg) { - struct rpcrequest_info *req,*rtmp; int32_t flag = 0; + uint32_t now; struct LP_address_utxo *up,*utmp; struct rpcrequest_info *req,*rtmp; int32_t flag = 0; strcpy(LP_gcloop_stats.name,"gc_loop"); LP_gcloop_stats.threshold = 1100.; while ( 1 ) @@ -282,6 +282,19 @@ void gc_loop(void *arg) free(req); flag++; } + now = (uint32_t)time(NULL); + DL_FOREACH_SAFE(LP_garbage_collector2,up,utmp) + { + if ( (uint32_t)up->spendheight > now-120 ) + printf("recent gc2 %u lag.%d\n",up->spendheight,now-up->spendheight); + else + { + DL_DELETE(LP_garbage_collector2,up); + char str[65]; printf("garbage collect %s/v%d\n",bits256_str(str,up->U.txid),up->U.vout); + free(up); + } + flag++; + } portable_mutex_unlock(&LP_gcmutex); if ( 0 && flag != 0 ) printf("gc_loop.%d\n",flag); diff --git a/iguana/exchanges/LP_ordermatch.c b/iguana/exchanges/LP_ordermatch.c index a27dc1078..c897f55f5 100644 --- a/iguana/exchanges/LP_ordermatch.c +++ b/iguana/exchanges/LP_ordermatch.c @@ -275,7 +275,7 @@ int32_t LP_nanobind(void *ctx,char *pairstr) int32_t LP_nearest_utxovalue(struct iguana_info *coin,char *coinaddr,struct LP_address_utxo **utxos,int32_t n,uint64_t targetval) { - int32_t i,mini = -1; struct LP_address_utxo *up; struct electrum_info *backupep=0,*ep; int64_t dist; uint64_t mindist = (1LL << 60); + int32_t i,replacei,bestheight,mini = -1; struct LP_address_utxo *up,*bestup; struct electrum_info *backupep=0,*ep; int64_t dist,bestdist; uint64_t mindist = (1LL << 60); if ( (ep= coin->electrum) != 0 ) { if ( (backupep= ep->prev) == 0 ) @@ -299,6 +299,29 @@ int32_t LP_nearest_utxovalue(struct iguana_info *coin,char *coinaddr,struct LP_a } } } + if ( mini >= 0 && (bestup= utxos[mini]) != 0 ) + { + bestdist = (bestup->U.value - targetval); + replacei = -1; + bestheight = bestup->U.height; + for (i=0; iU.value - targetval); + if ( dist > 0 && (double)dist/bestdist < 1.1 && up->U.height < bestheight ) + { + replacei = i; + bestheight = up->U.height; + } + } + } + if ( replacei >= 0 ) + { + printf("REPLACE bestdist %.8f height %d with dist %.8f height %d\n",dstr(bestdist),bestup->U.height,dstr(utxos[replacei]->U.value - targetval),utxos[replacei]->U.height); + return(replacei); + } + } //printf("return mini.%d\n",mini); return(mini); } @@ -370,7 +393,7 @@ struct LP_utxoinfo *LP_address_myutxopair(struct LP_utxoinfo *butxo,int32_t iamb { if ( (m= LP_address_utxo_ptrs(coin,iambob,utxos,max,ap,coinaddr)) > 1 ) { - if ( 1 ) + if ( 0 ) { int32_t i; for (i=0; i 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 ) { @@ -842,41 +865,6 @@ int32_t LP_tradecommand(void *ctx,char *myipaddr,int32_t pubsock,cJSON *argjson, memset(&Q.txid2,0,sizeof(Q.txid2)); Q.vout = Q.vout2 = -1; } else return(retval); - /*if ( bits256_nonz(Q.srchash) == 0 || bits256_cmp(Q.srchash,G.LP_mypub25519) == 0 || strcmp(butxo->coinaddr,coin->smartaddr) != 0 || bits256_nonz(butxo->payment.txid) == 0 || bits256_nonz(butxo->deposit.txid) == 0 ) - { - qprice = (double)Q.destsatoshis / Q.satoshis; - strcpy(Q.gui,G.gui); - strcpy(Q.coinaddr,coin->smartaddr); - strcpy(butxo->coinaddr,coin->smartaddr); - Q.srchash = G.LP_mypub25519; - memset(&Q.txid,0,sizeof(Q.txid)); - memset(&Q.txid2,0,sizeof(Q.txid2)); - Q.vout = Q.vout2 = -1; - recalc = 1; - } - else if ( (qprice= LP_quote_validate(autxo,butxo,&Q,1)) < SMALLVAL ) - recalc = 1; - else if ( price < qprice ) - { - char tmp[64]; - if ( bits256_nonz(Q.txid) != 0 ) - LP_utxos_remove(Q.txid,Q.vout); - else recalc = 1; - if ( bits256_nonz(Q.txid2) != 0 ) - LP_utxos_remove(Q.txid2,Q.vout2); - else recalc = 1; - //printf("price %.8f qprice %.8f\n",price,qprice); - if ( recalc == 0 ) - { - value = LP_txvalue(tmp,Q.srccoin,Q.txid,Q.vout); - value2 = LP_txvalue(tmp,Q.srccoin,Q.txid2,Q.vout2); - //printf("call LP_utxoadd.(%s) %.8f %.8f\n",Q.coinaddr,dstr(value),dstr(value2)); - if ( (butxo= LP_utxoadd(1,coin->symbol,Q.txid,Q.vout,value,Q.txid2,Q.vout2,value2,Q.coinaddr,Q.srchash,G.gui,0,Q.satoshis)) == 0 ) - recalc = 1; - else if ( bits256_cmp(Q.txid,butxo->payment.txid) != 0 || Q.vout != butxo->payment.vout || bits256_cmp(Q.txid2,butxo->deposit.txid) != 0 || Q.vout2 != butxo->deposit.vout ) - recalc = 1; - } - } else return(retval);*/ if ( qprice > price ) { r = (rand() % 100); diff --git a/iguana/exchanges/LP_statemachine.c b/iguana/exchanges/LP_statemachine.c index b267364df..3c32b8cad 100644 --- a/iguana/exchanges/LP_statemachine.c +++ b/iguana/exchanges/LP_statemachine.c @@ -1704,6 +1704,41 @@ int32_t bitcoin_coinptrs(bits256 pubkey,struct iguana_info **bobcoinp,struct igu } portable_mutex_unlock(&myinfo->DEX_swapmutex); }*/ +/*if ( bits256_nonz(Q.srchash) == 0 || bits256_cmp(Q.srchash,G.LP_mypub25519) == 0 || strcmp(butxo->coinaddr,coin->smartaddr) != 0 || bits256_nonz(butxo->payment.txid) == 0 || bits256_nonz(butxo->deposit.txid) == 0 ) + { + qprice = (double)Q.destsatoshis / Q.satoshis; + strcpy(Q.gui,G.gui); + strcpy(Q.coinaddr,coin->smartaddr); + strcpy(butxo->coinaddr,coin->smartaddr); + Q.srchash = G.LP_mypub25519; + memset(&Q.txid,0,sizeof(Q.txid)); + memset(&Q.txid2,0,sizeof(Q.txid2)); + Q.vout = Q.vout2 = -1; + recalc = 1; + } + else if ( (qprice= LP_quote_validate(autxo,butxo,&Q,1)) < SMALLVAL ) + recalc = 1; + else if ( price < qprice ) + { + char tmp[64]; + if ( bits256_nonz(Q.txid) != 0 ) + LP_utxos_remove(Q.txid,Q.vout); + else recalc = 1; + if ( bits256_nonz(Q.txid2) != 0 ) + LP_utxos_remove(Q.txid2,Q.vout2); + else recalc = 1; + //printf("price %.8f qprice %.8f\n",price,qprice); + if ( recalc == 0 ) + { + value = LP_txvalue(tmp,Q.srccoin,Q.txid,Q.vout); + value2 = LP_txvalue(tmp,Q.srccoin,Q.txid2,Q.vout2); + //printf("call LP_utxoadd.(%s) %.8f %.8f\n",Q.coinaddr,dstr(value),dstr(value2)); + if ( (butxo= LP_utxoadd(1,coin->symbol,Q.txid,Q.vout,value,Q.txid2,Q.vout2,value2,Q.coinaddr,Q.srchash,G.gui,0,Q.satoshis)) == 0 ) + recalc = 1; + else if ( bits256_cmp(Q.txid,butxo->payment.txid) != 0 || Q.vout != butxo->payment.vout || bits256_cmp(Q.txid2,butxo->deposit.txid) != 0 || Q.vout2 != butxo->deposit.vout ) + recalc = 1; + } + } else return(retval);*/ /*int32_t LP_priceping(int32_t pubsock,struct LP_utxoinfo *utxo,char *rel,double origprice) { diff --git a/iguana/exchanges/LP_utxo.c b/iguana/exchanges/LP_utxo.c index 0fe71aa4e..a89fc0cfe 100644 --- a/iguana/exchanges/LP_utxo.c +++ b/iguana/exchanges/LP_utxo.c @@ -409,8 +409,11 @@ struct LP_address *LP_address_utxo_reset(struct iguana_info *coin) portable_mutex_lock(&coin->addrmutex); DL_DELETE(ap->utxos,up); portable_mutex_unlock(&coin->addrmutex); - free(up); - } + portable_mutex_lock(&LP_gcmutex); + up->spendheight = (int32_t)time(NULL); + DL_APPEND(LP_garbage_collector2,up); + portable_mutex_unlock(&LP_gcmutex); + } now = (uint32_t)time(NULL); if ( (n= cJSON_GetArraySize(array)) > 0 ) { From b93cf95bd9133837decadadf80146706ff96a021 Mon Sep 17 00:00:00 2001 From: jl777 Date: Tue, 14 Nov 2017 21:59:35 +0200 Subject: [PATCH 0764/1664] Test --- iguana/exchanges/LP_network.c | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/iguana/exchanges/LP_network.c b/iguana/exchanges/LP_network.c index 49cefa778..63bfcdb44 100644 --- a/iguana/exchanges/LP_network.c +++ b/iguana/exchanges/LP_network.c @@ -285,9 +285,7 @@ void gc_loop(void *arg) now = (uint32_t)time(NULL); DL_FOREACH_SAFE(LP_garbage_collector2,up,utmp) { - if ( (uint32_t)up->spendheight > now-120 ) - printf("recent gc2 %u lag.%d\n",up->spendheight,now-up->spendheight); - else + if ( now > (uint32_t)up->spendheight+120 ) { DL_DELETE(LP_garbage_collector2,up); char str[65]; printf("garbage collect %s/v%d\n",bits256_str(str,up->U.txid),up->U.vout); @@ -298,7 +296,7 @@ void gc_loop(void *arg) portable_mutex_unlock(&LP_gcmutex); if ( 0 && flag != 0 ) printf("gc_loop.%d\n",flag); - sleep(1); + sleep(10); } } From 1e994506be3119545197a684997e618df75f4f5e Mon Sep 17 00:00:00 2001 From: jl777 Date: Tue, 14 Nov 2017 22:00:09 +0200 Subject: [PATCH 0765/1664] Test --- iguana/exchanges/LP_network.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/iguana/exchanges/LP_network.c b/iguana/exchanges/LP_network.c index 63bfcdb44..dd6713e6d 100644 --- a/iguana/exchanges/LP_network.c +++ b/iguana/exchanges/LP_network.c @@ -288,7 +288,7 @@ void gc_loop(void *arg) if ( now > (uint32_t)up->spendheight+120 ) { DL_DELETE(LP_garbage_collector2,up); - char str[65]; printf("garbage collect %s/v%d\n",bits256_str(str,up->U.txid),up->U.vout); + char str[65]; printf("garbage collect %s/v%d lag.%d\n",bits256_str(str,up->U.txid),up->U.vout,now-up->spendheight); free(up); } flag++; From 2dd9f64d536430e1c508c5991dca4ed9717ca2ce Mon Sep 17 00:00:00 2001 From: jl777 Date: Tue, 14 Nov 2017 22:05:11 +0200 Subject: [PATCH 0766/1664] Test --- iguana/exchanges/LP_include.h | 2 +- iguana/exchanges/LP_network.c | 2 +- iguana/exchanges/LP_ordermatch.c | 8 ++++---- iguana/exchanges/LP_utxo.c | 4 ++-- 4 files changed, 8 insertions(+), 8 deletions(-) diff --git a/iguana/exchanges/LP_include.h b/iguana/exchanges/LP_include.h index 1b0394f95..b7dd79e03 100644 --- a/iguana/exchanges/LP_include.h +++ b/iguana/exchanges/LP_include.h @@ -82,7 +82,7 @@ void emscripten_usleep(int32_t x); // returns immediate, no sense for sleeping #define LP_SWAPSTEP_TIMEOUT 30 #define LP_MIN_TXFEE 10000 #define LP_MINVOL 20 -#define LP_MINCLIENTVOL 1000 +#define LP_MINCLIENTVOL 100 #define LP_MINSIZE_TXFEEMULT 10 #define LP_REQUIRED_TXFEE 0.8 diff --git a/iguana/exchanges/LP_network.c b/iguana/exchanges/LP_network.c index dd6713e6d..8fedbc1ab 100644 --- a/iguana/exchanges/LP_network.c +++ b/iguana/exchanges/LP_network.c @@ -269,7 +269,7 @@ void gc_loop(void *arg) { uint32_t now; struct LP_address_utxo *up,*utmp; struct rpcrequest_info *req,*rtmp; int32_t flag = 0; strcpy(LP_gcloop_stats.name,"gc_loop"); - LP_gcloop_stats.threshold = 1100.; + LP_gcloop_stats.threshold = 11000.; while ( 1 ) { flag = 0; diff --git a/iguana/exchanges/LP_ordermatch.c b/iguana/exchanges/LP_ordermatch.c index c897f55f5..3dd21d90c 100644 --- a/iguana/exchanges/LP_ordermatch.c +++ b/iguana/exchanges/LP_ordermatch.c @@ -393,7 +393,7 @@ struct LP_utxoinfo *LP_address_myutxopair(struct LP_utxoinfo *butxo,int32_t iamb { if ( (m= LP_address_utxo_ptrs(coin,iambob,utxos,max,ap,coinaddr)) > 1 ) { - if ( 0 ) + if ( 1 ) { int32_t i; for (i=0; iU.value/targetval); + } 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); } else printf("no %s utxos pass LP_address_utxo_ptrs filter\n",coinaddr); @@ -896,7 +896,7 @@ int32_t LP_tradecommand(void *ctx,char *myipaddr,int32_t pubsock,cJSON *argjson, } else { - printf("cant find utxopair aliceid.%llu %s/%s\n",(long long)aliceid,Q.srccoin,Q.destcoin); + printf("cant find utxopair aliceid.%llu %s/%s %.8f -> relvol %.8f\n",(long long)aliceid,Q.srccoin,Q.destcoin,dstr(Q.satoshis),dstr(Q.destsatoshis)); return(retval); } } diff --git a/iguana/exchanges/LP_utxo.c b/iguana/exchanges/LP_utxo.c index a89fc0cfe..2bd6ebdcd 100644 --- a/iguana/exchanges/LP_utxo.c +++ b/iguana/exchanges/LP_utxo.c @@ -294,7 +294,7 @@ int32_t LP_address_utxo_ptrs(struct iguana_info *coin,int32_t iambob,struct LP_a } } //portable_mutex_unlock(&LP_utxomutex); - printf("return n.%d for %s %s\n",n,coin->symbol,coinaddr); + //printf("return n.%d for %s %s\n",n,coin->symbol,coinaddr); return(n); } @@ -440,7 +440,7 @@ struct LP_address *LP_address_utxo_reset(struct iguana_info *coin) if ( (up= LP_address_utxofind(coin,coin->smartaddr,txid,vout)) == 0 ) printf("couldnt find just added %s/%d ht.%d %.8f\n",bits256_str(str,txid),vout,height,dstr(value)); } - printf("added %d from listunspents\n",n); + //printf("added %d from listunspents\n",n); } free_json(array); } From 63b0fe14e423b677f772bfdddf5dd0cc7c499dc2 Mon Sep 17 00:00:00 2001 From: jl777 Date: Tue, 14 Nov 2017 22:05:41 +0200 Subject: [PATCH 0767/1664] test --- iguana/exchanges/LP_network.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/iguana/exchanges/LP_network.c b/iguana/exchanges/LP_network.c index 8fedbc1ab..4b33a4717 100644 --- a/iguana/exchanges/LP_network.c +++ b/iguana/exchanges/LP_network.c @@ -288,7 +288,7 @@ void gc_loop(void *arg) if ( now > (uint32_t)up->spendheight+120 ) { DL_DELETE(LP_garbage_collector2,up); - char str[65]; printf("garbage collect %s/v%d lag.%d\n",bits256_str(str,up->U.txid),up->U.vout,now-up->spendheight); + //char str[65]; printf("garbage collect %s/v%d lag.%d\n",bits256_str(str,up->U.txid),up->U.vout,now-up->spendheight); free(up); } flag++; From a619fe39bd5c42ef299bb982acfcc8ddb8908fdb Mon Sep 17 00:00:00 2001 From: jl777 Date: Tue, 14 Nov 2017 22:19:56 +0200 Subject: [PATCH 0768/1664] Test --- iguana/exchanges/LP_ordermatch.c | 16 ++++++++++------ iguana/exchanges/LP_utxo.c | 4 ++-- 2 files changed, 12 insertions(+), 8 deletions(-) diff --git a/iguana/exchanges/LP_ordermatch.c b/iguana/exchanges/LP_ordermatch.c index 3dd21d90c..1066284da 100644 --- a/iguana/exchanges/LP_ordermatch.c +++ b/iguana/exchanges/LP_ordermatch.c @@ -309,10 +309,13 @@ int32_t LP_nearest_utxovalue(struct iguana_info *coin,char *coinaddr,struct LP_a if ( i != mini && (up= utxos[i]) != 0 ) { dist = (up->U.value - targetval); - if ( dist > 0 && (double)dist/bestdist < 1.1 && up->U.height < bestheight ) + if ( dist > 0 && up->U.height < bestheight ) { - replacei = i; - bestheight = up->U.height; + if ( (double)dist/bestdist < 1.1 ) + { + replacei = i; + bestheight = up->U.height; + } else printf("almost ratio %.3f dist %.8f vs best %.8f, ht %d vs best ht %d\n",(double)dist/bestdist,dstr(dist),dstr(bestdist),up->U.height,bestheight); } } } @@ -397,8 +400,9 @@ struct LP_utxoinfo *LP_address_myutxopair(struct LP_utxoinfo *butxo,int32_t iamb { int32_t i; for (i=0; iU.value)); - printf("targetval %.8f vol %.8f price %.8f txfee %.8f %s\n",dstr(targetval),relvolume,price,dstr(txfee),coinaddr); + if ( utxos[i]->U.value >= targetval ) + printf("%.8f ",dstr(utxos[i]->U.value)); + printf("targetval %.8f vol %.8f price %.8f txfee %.8f %s %s\n",dstr(targetval),relvolume,price,dstr(txfee),coin->symbol,coinaddr); } mini = -1; if ( targetval != 0 && (mini= LP_nearest_utxovalue(coin,coinaddr,utxos,m,targetval)) >= 0 ) @@ -896,7 +900,7 @@ int32_t LP_tradecommand(void *ctx,char *myipaddr,int32_t pubsock,cJSON *argjson, } else { - printf("cant find utxopair aliceid.%llu %s/%s %.8f -> relvol %.8f\n",(long long)aliceid,Q.srccoin,Q.destcoin,dstr(Q.satoshis),dstr(Q.destsatoshis)); + printf("cant find utxopair aliceid.%llu %s/%s %.8f -> relvol %.8f\n",(long long)aliceid,Q.srccoin,Q.destcoin,dstr(LP_basesatoshis(dstr(Q.destsatoshis),price,Q.txfee,Q.desttxfee)),dstr(Q.destsatoshis)); return(retval); } } diff --git a/iguana/exchanges/LP_utxo.c b/iguana/exchanges/LP_utxo.c index 2bd6ebdcd..0f2aee2c3 100644 --- a/iguana/exchanges/LP_utxo.c +++ b/iguana/exchanges/LP_utxo.c @@ -52,7 +52,7 @@ int32_t _LP_inuse_delete(bits256 txid,int32_t vout) if ( LP_inuse[ind].ind != ind ) printf("ind.%d of %d: mismatched ind.%d\n",ind,LP_numinuse,LP_inuse[ind].ind); } - char str[65]; printf("_LP_inuse_delete cant find %s/v%d\n",bits256_str(str,txid),vout); + //char str[65]; printf("_LP_inuse_delete cant find %s/v%d\n",bits256_str(str,txid),vout); return(-1); } @@ -285,7 +285,7 @@ int32_t LP_address_utxo_ptrs(struct iguana_info *coin,int32_t iambob,struct LP_a utxos[n++] = up; if ( n >= max ) break; - } else printf("LP_allocated skip\n"); + } //else printf("LP_allocated skip\n"); } else { From 47490054aa33f130594d6cb5a136a928e641fb7a Mon Sep 17 00:00:00 2001 From: jl777 Date: Tue, 14 Nov 2017 22:25:33 +0200 Subject: [PATCH 0769/1664] Test --- iguana/exchanges/LP_ordermatch.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/iguana/exchanges/LP_ordermatch.c b/iguana/exchanges/LP_ordermatch.c index 1066284da..b9bb28e29 100644 --- a/iguana/exchanges/LP_ordermatch.c +++ b/iguana/exchanges/LP_ordermatch.c @@ -311,11 +311,11 @@ int32_t LP_nearest_utxovalue(struct iguana_info *coin,char *coinaddr,struct LP_a dist = (up->U.value - targetval); if ( dist > 0 && up->U.height < bestheight ) { - if ( (double)dist/bestdist < 1.1 ) + if ( (double)dist/bestdist < sqrt(bestheight - up->U.height) ) { replacei = i; bestheight = up->U.height; - } else printf("almost ratio %.3f dist %.8f vs best %.8f, ht %d vs best ht %d\n",(double)dist/bestdist,dstr(dist),dstr(bestdist),up->U.height,bestheight); + } //else printf("almost ratio %.3f dist %.8f vs best %.8f, ht %d vs best ht %d\n",(double)dist/bestdist,dstr(dist),dstr(bestdist),up->U.height,bestheight); } } } From 1a0e13355c5e6a53a01029c355a22094f6be207f Mon Sep 17 00:00:00 2001 From: jl777 Date: Tue, 14 Nov 2017 22:57:52 +0200 Subject: [PATCH 0770/1664] Test --- iguana/exchanges/LP_ordermatch.c | 2 +- iguana/exchanges/LP_rpc.c | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/iguana/exchanges/LP_ordermatch.c b/iguana/exchanges/LP_ordermatch.c index b9bb28e29..a8c061359 100644 --- a/iguana/exchanges/LP_ordermatch.c +++ b/iguana/exchanges/LP_ordermatch.c @@ -543,7 +543,7 @@ void LP_reserved(void *ctx,char *myipaddr,int32_t mypubsock,struct LP_quoteinfo if ( LP_alice_eligible() > 0 && 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*1.005 ) + if ( LP_pricevalid(price) > 0 && maxprice > SMALLVAL && price <= maxprice ) { qp->tradeid = LP_Alicequery.tradeid; LP_alicequery_clear(); diff --git a/iguana/exchanges/LP_rpc.c b/iguana/exchanges/LP_rpc.c index 30789efe7..2a66c9b94 100644 --- a/iguana/exchanges/LP_rpc.c +++ b/iguana/exchanges/LP_rpc.c @@ -544,7 +544,7 @@ cJSON *LP_gettxout(char *symbol,char *coinaddr,bits256 txid,int32_t vout) return(retjson); } } - printf("couldnt find %s (%s) %s/v%d\n",symbol,coinaddr,bits256_str(str,txid),vout); + //printf("couldnt find %s (%s) %s/v%d\n",symbol,coinaddr,bits256_str(str,txid),vout); return(cJSON_Parse("{\"error\":\"couldnt get tx\"}")); } } From 3cb25a8c237b5dac0f8372f25a347f55c9f8267b Mon Sep 17 00:00:00 2001 From: jl777 Date: Tue, 14 Nov 2017 23:18:21 +0200 Subject: [PATCH 0771/1664] Test --- iguana/exchanges/LP_nativeDEX.c | 18 ++++++++++-------- 1 file changed, 10 insertions(+), 8 deletions(-) diff --git a/iguana/exchanges/LP_nativeDEX.c b/iguana/exchanges/LP_nativeDEX.c index 64687dedc..4b33908b8 100644 --- a/iguana/exchanges/LP_nativeDEX.c +++ b/iguana/exchanges/LP_nativeDEX.c @@ -17,8 +17,10 @@ // LP_nativeDEX.c // marketmaker // -// single utxo allocations, reject result, latency +// single utxo allocations alice, reject result, latency // alice waiting for bestprice +//if ( G.LP_pendingswaps != 0 ) +//return(-1); // bot safe to exit? // // BCH signing @@ -1054,37 +1056,37 @@ void LPinit(uint16_t myport,uint16_t mypullport,uint16_t mypubport,uint16_t mybu printf("error launching gc_loop for port.%u\n",myport); exit(-1); } - if ( OS_thread_create(malloc(sizeof(pthread_t)),NULL,(void *)prices_loop,ctx) != 0 ) + if ( 0 && OS_thread_create(malloc(sizeof(pthread_t)),NULL,(void *)prices_loop,ctx) != 0 ) { printf("error launching prices_loop for port.%u\n",myport); exit(-1); } - if ( OS_thread_create(malloc(sizeof(pthread_t)),NULL,(void *)LP_coinsloop,(void *)"") != 0 ) + if ( 0 && OS_thread_create(malloc(sizeof(pthread_t)),NULL,(void *)LP_coinsloop,(void *)"") != 0 ) { printf("error launching LP_coinsloop for port.%u\n",myport); exit(-1); } - if ( OS_thread_create(malloc(sizeof(pthread_t)),NULL,(void *)LP_coinsloop,(void *)"BTC") != 0 ) + if ( 0 && OS_thread_create(malloc(sizeof(pthread_t)),NULL,(void *)LP_coinsloop,(void *)"BTC") != 0 ) { printf("error launching BTC LP_coinsloop for port.%u\n",myport); exit(-1); } - if ( OS_thread_create(malloc(sizeof(pthread_t)),NULL,(void *)LP_coinsloop,(void *)"KMD") != 0 ) + if ( 0 && OS_thread_create(malloc(sizeof(pthread_t)),NULL,(void *)LP_coinsloop,(void *)"KMD") != 0 ) { printf("error launching KMD LP_coinsloop for port.%u\n",myport); exit(-1); } - if ( OS_thread_create(malloc(sizeof(pthread_t)),NULL,(void *)LP_pubkeysloop,(void *)myipaddr) != 0 ) + if ( 0 && OS_thread_create(malloc(sizeof(pthread_t)),NULL,(void *)LP_pubkeysloop,(void *)myipaddr) != 0 ) { printf("error launching LP_pubkeysloop for ctx.%p\n",ctx); exit(-1); } - if ( OS_thread_create(malloc(sizeof(pthread_t)),NULL,(void *)LP_privkeysloop,(void *)myipaddr) != 0 ) + if ( 0 && OS_thread_create(malloc(sizeof(pthread_t)),NULL,(void *)LP_privkeysloop,(void *)myipaddr) != 0 ) { printf("error launching LP_privkeysloop for ctx.%p\n",ctx); exit(-1); } - if ( OS_thread_create(malloc(sizeof(pthread_t)),NULL,(void *)LP_swapsloop,(void *)myipaddr) != 0 ) + if ( 0 && OS_thread_create(malloc(sizeof(pthread_t)),NULL,(void *)LP_swapsloop,(void *)myipaddr) != 0 ) { printf("error launching LP_swapsloop for port.%u\n",myport); exit(-1); From 8c07a90770936fa667c3250611138b7f5d37ed03 Mon Sep 17 00:00:00 2001 From: jl777 Date: Tue, 14 Nov 2017 23:21:55 +0200 Subject: [PATCH 0772/1664] Test --- iguana/exchanges/LP_nativeDEX.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/iguana/exchanges/LP_nativeDEX.c b/iguana/exchanges/LP_nativeDEX.c index 4b33908b8..7510f368c 100644 --- a/iguana/exchanges/LP_nativeDEX.c +++ b/iguana/exchanges/LP_nativeDEX.c @@ -1020,7 +1020,7 @@ void LPinit(uint16_t myport,uint16_t mypullport,uint16_t mypubport,uint16_t mybu printf("error launching LP_psockloop for (%s)\n",myipaddr); exit(-1); } - if ( OS_thread_create(malloc(sizeof(pthread_t)),NULL,(void *)LP_reserved_msgs,(void *)myipaddr) != 0 ) + if ( 0 && OS_thread_create(malloc(sizeof(pthread_t)),NULL,(void *)LP_reserved_msgs,(void *)myipaddr) != 0 ) { printf("error launching LP_reserved_msgs for (%s)\n",myipaddr); exit(-1); @@ -1030,13 +1030,13 @@ void LPinit(uint16_t myport,uint16_t mypullport,uint16_t mypubport,uint16_t mybu printf("error launching utxosQ_loop for (%s)\n",myipaddr); exit(-1); } - if ( OS_thread_create(malloc(sizeof(pthread_t)),NULL,(void *)stats_rpcloop,(void *)&myport) != 0 ) + if ( 0 && OS_thread_create(malloc(sizeof(pthread_t)),NULL,(void *)stats_rpcloop,(void *)&myport) != 0 ) { printf("error launching stats rpcloop for port.%u\n",myport); exit(-1); } uint16_t myport2 = myport-1; - if ( OS_thread_create(malloc(sizeof(pthread_t)),NULL,(void *)stats_rpcloop,(void *)&myport2) != 0 ) + if ( 0 && OS_thread_create(malloc(sizeof(pthread_t)),NULL,(void *)stats_rpcloop,(void *)&myport2) != 0 ) { printf("error launching stats rpcloop for port.%u\n",myport); exit(-1); From 823e972eda4df41c9a4a467877ad76feedda2898 Mon Sep 17 00:00:00 2001 From: jl777 Date: Tue, 14 Nov 2017 23:24:13 +0200 Subject: [PATCH 0773/1664] Test --- iguana/exchanges/LP_nativeDEX.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/iguana/exchanges/LP_nativeDEX.c b/iguana/exchanges/LP_nativeDEX.c index 7510f368c..259053f1a 100644 --- a/iguana/exchanges/LP_nativeDEX.c +++ b/iguana/exchanges/LP_nativeDEX.c @@ -1025,7 +1025,7 @@ void LPinit(uint16_t myport,uint16_t mypullport,uint16_t mypubport,uint16_t mybu printf("error launching LP_reserved_msgs for (%s)\n",myipaddr); exit(-1); } - if ( OS_thread_create(malloc(sizeof(pthread_t)),NULL,(void *)utxosQ_loop,(void *)myipaddr) != 0 ) + if ( 0 && OS_thread_create(malloc(sizeof(pthread_t)),NULL,(void *)utxosQ_loop,(void *)myipaddr) != 0 ) { printf("error launching utxosQ_loop for (%s)\n",myipaddr); exit(-1); @@ -1046,12 +1046,12 @@ void LPinit(uint16_t myport,uint16_t mypullport,uint16_t mypubport,uint16_t mybu printf("error launching command_rpcloop for port.%u\n",myport); exit(-1); } - if ( OS_thread_create(malloc(sizeof(pthread_t)),NULL,(void *)queue_loop,(void *)myipaddr) != 0 ) + if ( 0 && OS_thread_create(malloc(sizeof(pthread_t)),NULL,(void *)queue_loop,(void *)myipaddr) != 0 ) { printf("error launching queue_loop for port.%u\n",myport); exit(-1); } - if ( OS_thread_create(malloc(sizeof(pthread_t)),NULL,(void *)gc_loop,(void *)myipaddr) != 0 ) + if ( 0 && OS_thread_create(malloc(sizeof(pthread_t)),NULL,(void *)gc_loop,(void *)myipaddr) != 0 ) { printf("error launching gc_loop for port.%u\n",myport); exit(-1); From bbd790bf5582e4965de7968aa4164e1371937dff Mon Sep 17 00:00:00 2001 From: jl777 Date: Tue, 14 Nov 2017 23:25:51 +0200 Subject: [PATCH 0774/1664] Test --- iguana/exchanges/LP_nativeDEX.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/iguana/exchanges/LP_nativeDEX.c b/iguana/exchanges/LP_nativeDEX.c index 259053f1a..6108a2f87 100644 --- a/iguana/exchanges/LP_nativeDEX.c +++ b/iguana/exchanges/LP_nativeDEX.c @@ -1101,7 +1101,7 @@ void LPinit(uint16_t myport,uint16_t mypullport,uint16_t mypubport,uint16_t mybu //fprintf(stderr,"."); sleep(3); } - if ( LP_mainloop_iter(ctx,myipaddr,mypeer,pubsock,pushaddr,myport) != 0 ) + if ( 0 && LP_mainloop_iter(ctx,myipaddr,mypeer,pubsock,pushaddr,myport) != 0 ) nonz++; if ( nonz == 0 ) usleep(1000); From 17ff863160d9684ab167a69fded6f3444a53084f Mon Sep 17 00:00:00 2001 From: jl777 Date: Tue, 14 Nov 2017 23:27:11 +0200 Subject: [PATCH 0775/1664] Test --- iguana/exchanges/LP_nativeDEX.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/iguana/exchanges/LP_nativeDEX.c b/iguana/exchanges/LP_nativeDEX.c index 6108a2f87..431500f4b 100644 --- a/iguana/exchanges/LP_nativeDEX.c +++ b/iguana/exchanges/LP_nativeDEX.c @@ -1041,7 +1041,7 @@ void LPinit(uint16_t myport,uint16_t mypullport,uint16_t mypubport,uint16_t mybu printf("error launching stats rpcloop for port.%u\n",myport); exit(-1); } - if ( OS_thread_create(malloc(sizeof(pthread_t)),NULL,(void *)command_rpcloop,(void *)myipaddr) != 0 ) + if ( 0 && OS_thread_create(malloc(sizeof(pthread_t)),NULL,(void *)command_rpcloop,(void *)myipaddr) != 0 ) { printf("error launching command_rpcloop for port.%u\n",myport); exit(-1); From 7df0dbc54070b20302f099b52ba639a9ded2f901 Mon Sep 17 00:00:00 2001 From: jl777 Date: Tue, 14 Nov 2017 23:29:50 +0200 Subject: [PATCH 0776/1664] Test --- iguana/exchanges/LP_nativeDEX.c | 28 ++++++++++++++-------------- 1 file changed, 14 insertions(+), 14 deletions(-) diff --git a/iguana/exchanges/LP_nativeDEX.c b/iguana/exchanges/LP_nativeDEX.c index 431500f4b..3703437f6 100644 --- a/iguana/exchanges/LP_nativeDEX.c +++ b/iguana/exchanges/LP_nativeDEX.c @@ -1020,23 +1020,23 @@ void LPinit(uint16_t myport,uint16_t mypullport,uint16_t mypubport,uint16_t mybu printf("error launching LP_psockloop for (%s)\n",myipaddr); exit(-1); } - if ( 0 && OS_thread_create(malloc(sizeof(pthread_t)),NULL,(void *)LP_reserved_msgs,(void *)myipaddr) != 0 ) + if ( OS_thread_create(malloc(sizeof(pthread_t)),NULL,(void *)LP_reserved_msgs,(void *)myipaddr) != 0 ) { printf("error launching LP_reserved_msgs for (%s)\n",myipaddr); exit(-1); } - if ( 0 && OS_thread_create(malloc(sizeof(pthread_t)),NULL,(void *)utxosQ_loop,(void *)myipaddr) != 0 ) + if ( OS_thread_create(malloc(sizeof(pthread_t)),NULL,(void *)utxosQ_loop,(void *)myipaddr) != 0 ) { printf("error launching utxosQ_loop for (%s)\n",myipaddr); exit(-1); } - if ( 0 && OS_thread_create(malloc(sizeof(pthread_t)),NULL,(void *)stats_rpcloop,(void *)&myport) != 0 ) + if ( OS_thread_create(malloc(sizeof(pthread_t)),NULL,(void *)stats_rpcloop,(void *)&myport) != 0 ) { printf("error launching stats rpcloop for port.%u\n",myport); exit(-1); } uint16_t myport2 = myport-1; - if ( 0 && OS_thread_create(malloc(sizeof(pthread_t)),NULL,(void *)stats_rpcloop,(void *)&myport2) != 0 ) + if ( OS_thread_create(malloc(sizeof(pthread_t)),NULL,(void *)stats_rpcloop,(void *)&myport2) != 0 ) { printf("error launching stats rpcloop for port.%u\n",myport); exit(-1); @@ -1046,47 +1046,47 @@ void LPinit(uint16_t myport,uint16_t mypullport,uint16_t mypubport,uint16_t mybu printf("error launching command_rpcloop for port.%u\n",myport); exit(-1); } - if ( 0 && OS_thread_create(malloc(sizeof(pthread_t)),NULL,(void *)queue_loop,(void *)myipaddr) != 0 ) + if ( OS_thread_create(malloc(sizeof(pthread_t)),NULL,(void *)queue_loop,(void *)myipaddr) != 0 ) { printf("error launching queue_loop for port.%u\n",myport); exit(-1); } - if ( 0 && OS_thread_create(malloc(sizeof(pthread_t)),NULL,(void *)gc_loop,(void *)myipaddr) != 0 ) + if ( OS_thread_create(malloc(sizeof(pthread_t)),NULL,(void *)gc_loop,(void *)myipaddr) != 0 ) { printf("error launching gc_loop for port.%u\n",myport); exit(-1); } - if ( 0 && OS_thread_create(malloc(sizeof(pthread_t)),NULL,(void *)prices_loop,ctx) != 0 ) + if ( OS_thread_create(malloc(sizeof(pthread_t)),NULL,(void *)prices_loop,ctx) != 0 ) { printf("error launching prices_loop for port.%u\n",myport); exit(-1); } - if ( 0 && OS_thread_create(malloc(sizeof(pthread_t)),NULL,(void *)LP_coinsloop,(void *)"") != 0 ) + if ( OS_thread_create(malloc(sizeof(pthread_t)),NULL,(void *)LP_coinsloop,(void *)"") != 0 ) { printf("error launching LP_coinsloop for port.%u\n",myport); exit(-1); } - if ( 0 && OS_thread_create(malloc(sizeof(pthread_t)),NULL,(void *)LP_coinsloop,(void *)"BTC") != 0 ) + if ( OS_thread_create(malloc(sizeof(pthread_t)),NULL,(void *)LP_coinsloop,(void *)"BTC") != 0 ) { printf("error launching BTC LP_coinsloop for port.%u\n",myport); exit(-1); } - if ( 0 && OS_thread_create(malloc(sizeof(pthread_t)),NULL,(void *)LP_coinsloop,(void *)"KMD") != 0 ) + if ( OS_thread_create(malloc(sizeof(pthread_t)),NULL,(void *)LP_coinsloop,(void *)"KMD") != 0 ) { printf("error launching KMD LP_coinsloop for port.%u\n",myport); exit(-1); } - if ( 0 && OS_thread_create(malloc(sizeof(pthread_t)),NULL,(void *)LP_pubkeysloop,(void *)myipaddr) != 0 ) + if ( OS_thread_create(malloc(sizeof(pthread_t)),NULL,(void *)LP_pubkeysloop,(void *)myipaddr) != 0 ) { printf("error launching LP_pubkeysloop for ctx.%p\n",ctx); exit(-1); } - if ( 0 && OS_thread_create(malloc(sizeof(pthread_t)),NULL,(void *)LP_privkeysloop,(void *)myipaddr) != 0 ) + if ( OS_thread_create(malloc(sizeof(pthread_t)),NULL,(void *)LP_privkeysloop,(void *)myipaddr) != 0 ) { printf("error launching LP_privkeysloop for ctx.%p\n",ctx); exit(-1); } - if ( 0 && OS_thread_create(malloc(sizeof(pthread_t)),NULL,(void *)LP_swapsloop,(void *)myipaddr) != 0 ) + if ( OS_thread_create(malloc(sizeof(pthread_t)),NULL,(void *)LP_swapsloop,(void *)myipaddr) != 0 ) { printf("error launching LP_swapsloop for port.%u\n",myport); exit(-1); @@ -1101,7 +1101,7 @@ void LPinit(uint16_t myport,uint16_t mypullport,uint16_t mypubport,uint16_t mybu //fprintf(stderr,"."); sleep(3); } - if ( 0 && LP_mainloop_iter(ctx,myipaddr,mypeer,pubsock,pushaddr,myport) != 0 ) + if ( LP_mainloop_iter(ctx,myipaddr,mypeer,pubsock,pushaddr,myport) != 0 ) nonz++; if ( nonz == 0 ) usleep(1000); From 2e867f10f4a15a98d50786902ee68b0cb49e03a0 Mon Sep 17 00:00:00 2001 From: jl777 Date: Tue, 14 Nov 2017 23:34:27 +0200 Subject: [PATCH 0777/1664] Test --- iguana/exchanges/LP_nativeDEX.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/iguana/exchanges/LP_nativeDEX.c b/iguana/exchanges/LP_nativeDEX.c index 3703437f6..7e876b432 100644 --- a/iguana/exchanges/LP_nativeDEX.c +++ b/iguana/exchanges/LP_nativeDEX.c @@ -364,7 +364,7 @@ int32_t LP_sock_check(char *typestr,void *ctx,char *myipaddr,int32_t pubsock,int } else validreq = 1; recvlen -= sizeof(bits256); } - if ( validreq != 0 ) + if ( 0 && validreq != 0 ) { if ( (retstr= LP_process_message(ctx,typestr,myipaddr,pubsock,ptr,recvlen,sock)) != 0 ) free(retstr); @@ -1041,7 +1041,7 @@ void LPinit(uint16_t myport,uint16_t mypullport,uint16_t mypubport,uint16_t mybu printf("error launching stats rpcloop for port.%u\n",myport); exit(-1); } - if ( 0 && OS_thread_create(malloc(sizeof(pthread_t)),NULL,(void *)command_rpcloop,(void *)myipaddr) != 0 ) + if ( OS_thread_create(malloc(sizeof(pthread_t)),NULL,(void *)command_rpcloop,(void *)myipaddr) != 0 ) { printf("error launching command_rpcloop for port.%u\n",myport); exit(-1); From c71b1ad57081979b0f5b62d72d3b995f2c84be6f Mon Sep 17 00:00:00 2001 From: jl777 Date: Tue, 14 Nov 2017 23:37:12 +0200 Subject: [PATCH 0778/1664] Test --- iguana/exchanges/LP_nativeDEX.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/iguana/exchanges/LP_nativeDEX.c b/iguana/exchanges/LP_nativeDEX.c index 7e876b432..ae1894ea9 100644 --- a/iguana/exchanges/LP_nativeDEX.c +++ b/iguana/exchanges/LP_nativeDEX.c @@ -356,7 +356,7 @@ int32_t LP_sock_check(char *typestr,void *ctx,char *myipaddr,int32_t pubsock,int } } int32_t validreq = 0; - if ( strlen((char *)ptr)+sizeof(bits256) <= recvlen ) + if ( 0 && strlen((char *)ptr)+sizeof(bits256) <= recvlen ) { if ( LP_magic_check(ptr,recvlen,remoteaddr) <= 0 ) { From 40c3173ec20ad82c1e1181362d17a74da469932a Mon Sep 17 00:00:00 2001 From: jl777 Date: Tue, 14 Nov 2017 23:40:05 +0200 Subject: [PATCH 0779/1664] Test --- iguana/exchanges/LP_nativeDEX.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/iguana/exchanges/LP_nativeDEX.c b/iguana/exchanges/LP_nativeDEX.c index ae1894ea9..4f82d0c4a 100644 --- a/iguana/exchanges/LP_nativeDEX.c +++ b/iguana/exchanges/LP_nativeDEX.c @@ -338,6 +338,7 @@ int32_t LP_sock_check(char *typestr,void *ctx,char *myipaddr,int32_t pubsock,int pfd.events = NN_POLLIN; if ( nn_poll(&pfd,1,1) != 1 ) break; + ptr = 0; if ( (recvlen= nn_recv(sock,&ptr,NN_MSG,0)) > 0 ) { methodstr[0] = 0; @@ -387,9 +388,9 @@ int32_t LP_sock_check(char *typestr,void *ctx,char *myipaddr,int32_t pubsock,int free(str); } } - if ( ptr != 0 ) - nn_freemsg(ptr), ptr = 0; } + if ( ptr != 0 ) + nn_freemsg(ptr), ptr = 0; } } return(nonz); From 9006c80202870a7eadbfd1bc6a62f45956db5f84 Mon Sep 17 00:00:00 2001 From: jl777 Date: Tue, 14 Nov 2017 23:44:00 +0200 Subject: [PATCH 0780/1664] Test --- iguana/exchanges/LP_network.c | 19 +++++++++++++------ 1 file changed, 13 insertions(+), 6 deletions(-) diff --git a/iguana/exchanges/LP_network.c b/iguana/exchanges/LP_network.c index 4b33a4717..f45f5142d 100644 --- a/iguana/exchanges/LP_network.c +++ b/iguana/exchanges/LP_network.c @@ -574,12 +574,19 @@ void LP_psockloop(void *_ptr) // printouts seem to be needed for forwarding to w else if ( (pfds[n].revents & POLLIN) != 0 ) { printf("publicsock.%d %s has pollin\n",ptr->publicsock,ptr->publicaddr); + buf = 0; if ( (size= nn_recv(ptr->publicsock,&buf,NN_MSG,0)) > 0 ) { ptr->lasttime = now; sendsock = ptr->sendsock; break; } + else if ( buf != 0 ) + { + nn_freemsg(buf); + buf = 0; + size = 0; + } } } n++; @@ -606,12 +613,12 @@ void LP_psockloop(void *_ptr) // printouts seem to be needed for forwarding to w sendsock = ptr->publicsock; break; } - else - { - nn_freemsg(buf); - buf = 0; - size = 0; - } + } + if ( buf != 0 ) + { + nn_freemsg(buf); + buf = 0; + size = 0; } } } From 67a4e5191f995a8e690340b2e2c58f7d7694d080 Mon Sep 17 00:00:00 2001 From: jl777 Date: Tue, 14 Nov 2017 23:45:58 +0200 Subject: [PATCH 0781/1664] Test --- iguana/exchanges/LP_nativeDEX.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/iguana/exchanges/LP_nativeDEX.c b/iguana/exchanges/LP_nativeDEX.c index 4f82d0c4a..75e236dac 100644 --- a/iguana/exchanges/LP_nativeDEX.c +++ b/iguana/exchanges/LP_nativeDEX.c @@ -357,7 +357,7 @@ int32_t LP_sock_check(char *typestr,void *ctx,char *myipaddr,int32_t pubsock,int } } int32_t validreq = 0; - if ( 0 && strlen((char *)ptr)+sizeof(bits256) <= recvlen ) + if ( strlen((char *)ptr)+sizeof(bits256) <= recvlen ) { if ( LP_magic_check(ptr,recvlen,remoteaddr) <= 0 ) { @@ -365,7 +365,7 @@ int32_t LP_sock_check(char *typestr,void *ctx,char *myipaddr,int32_t pubsock,int } else validreq = 1; recvlen -= sizeof(bits256); } - if ( 0 && validreq != 0 ) + if ( validreq != 0 ) { if ( (retstr= LP_process_message(ctx,typestr,myipaddr,pubsock,ptr,recvlen,sock)) != 0 ) free(retstr); From 3bb38b13bc1e8c259c78d488baef5ee529af625d Mon Sep 17 00:00:00 2001 From: jl777 Date: Tue, 14 Nov 2017 23:48:07 +0200 Subject: [PATCH 0782/1664] Test --- iguana/exchanges/LP_nativeDEX.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/iguana/exchanges/LP_nativeDEX.c b/iguana/exchanges/LP_nativeDEX.c index 75e236dac..98f4cc927 100644 --- a/iguana/exchanges/LP_nativeDEX.c +++ b/iguana/exchanges/LP_nativeDEX.c @@ -365,7 +365,7 @@ int32_t LP_sock_check(char *typestr,void *ctx,char *myipaddr,int32_t pubsock,int } else validreq = 1; recvlen -= sizeof(bits256); } - if ( validreq != 0 ) + if ( 0 && validreq != 0 ) { if ( (retstr= LP_process_message(ctx,typestr,myipaddr,pubsock,ptr,recvlen,sock)) != 0 ) free(retstr); From 83a6006d7e5bd687f63e9b3e1521244839dac090 Mon Sep 17 00:00:00 2001 From: jl777 Date: Tue, 14 Nov 2017 23:58:00 +0200 Subject: [PATCH 0783/1664] Test --- iguana/exchanges/LP_nativeDEX.c | 5 +++-- iguana/exchanges/LP_ordermatch.c | 6 ++++-- 2 files changed, 7 insertions(+), 4 deletions(-) diff --git a/iguana/exchanges/LP_nativeDEX.c b/iguana/exchanges/LP_nativeDEX.c index 98f4cc927..c5c34b353 100644 --- a/iguana/exchanges/LP_nativeDEX.c +++ b/iguana/exchanges/LP_nativeDEX.c @@ -315,8 +315,9 @@ char *LP_process_message(void *ctx,char *typestr,char *myipaddr,int32_t pubsock, } //printf("%.3f %s LP_command_process\n",OS_milliseconds()-millis,jstr(argjson,"method")); } - free_json(argjson); } + if ( argjson != 0 ) + free_json(argjson); } } //else printf("DUPLICATE.(%s)\n",(char *)ptr); portable_mutex_unlock(&LP_commandmutex); @@ -365,7 +366,7 @@ int32_t LP_sock_check(char *typestr,void *ctx,char *myipaddr,int32_t pubsock,int } else validreq = 1; recvlen -= sizeof(bits256); } - if ( 0 && validreq != 0 ) + if ( validreq != 0 ) { if ( (retstr= LP_process_message(ctx,typestr,myipaddr,pubsock,ptr,recvlen,sock)) != 0 ) free(retstr); diff --git a/iguana/exchanges/LP_ordermatch.c b/iguana/exchanges/LP_ordermatch.c index a8c061359..0ab6faca0 100644 --- a/iguana/exchanges/LP_ordermatch.c +++ b/iguana/exchanges/LP_ordermatch.c @@ -799,7 +799,7 @@ int32_t LP_tradecommand(void *ctx,char *myipaddr,int32_t pubsock,cJSON *argjson, return(retval); } LP_aliceid(Q.tradeid,Q.aliceid,"reserved",0,0); - printf("alice %s received RESERVED.(%s)\n",bits256_str(str,G.LP_mypub25519),jprint(argjson,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); @@ -929,7 +929,9 @@ int32_t LP_tradecommand(void *ctx,char *myipaddr,int32_t pubsock,cJSON *argjson, printf("(%.8f %.8f) quote price %.8f too low vs %.8f for %s/%s %.8f < %.8f\n",bid,ask,qprice,price,Q.srccoin,Q.destcoin,qprice,(ask - 0.00000001) * 0.998); return(retval); } - char str[65],str2[65]; printf("(%s/v%d %s/v%d) TRADECOMMAND.(%s)\n",bits256_str(str,Q.txid),Q.vout,bits256_str(str2,Q.txid2),Q.vout2,jprint(argjson,0)); + char *astr = jprint(argjson,0); + char str[65],str2[65]; printf("(%s/v%d %s/v%d) TRADECOMMAND.(%s)\n",bits256_str(str,Q.txid),Q.vout,bits256_str(str2,Q.txid2),Q.vout2,astr); + free(astr); if ( strcmp(method,"request") == 0 ) // bob needs apayment + fee tx's { if ( LP_allocated(Q.txid,Q.vout) == 0 && LP_allocated(Q.txid2,Q.vout2) == 0 ) From 0eb9fd4328fb9aa2ee4453484f09846ca5f40c3c Mon Sep 17 00:00:00 2001 From: jl777 Date: Wed, 15 Nov 2017 00:02:11 +0200 Subject: [PATCH 0784/1664] Test --- iguana/exchanges/LP_transaction.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/iguana/exchanges/LP_transaction.c b/iguana/exchanges/LP_transaction.c index 4d9ee5fe1..4df4b3895 100644 --- a/iguana/exchanges/LP_transaction.c +++ b/iguana/exchanges/LP_transaction.c @@ -1047,13 +1047,13 @@ char *LP_createrawtransaction(cJSON **txobjp,int32_t *numvinsp,struct iguana_inf return(0); } } - if ( bits256_nonz(utxotxid) == 0 ) + //if ( bits256_nonz(utxotxid) == 0 ) { if ( (ap= LP_address_utxo_reset(coin)) == 0 ) return(0); } - else if ( (ap= LP_address(coin,coin->smartaddr)) == 0 ) - return(0); + //else if ( (ap= LP_address(coin,coin->smartaddr)) == 0 ) + // return(0); memset(utxos,0,sizeof(utxos)); if ( (numutxos= LP_address_utxo_ptrs(coin,0,utxos,max,ap,coin->smartaddr)) <= 0 ) { From 1775a5dbea16212762b4991659b86b716649717e Mon Sep 17 00:00:00 2001 From: jl777 Date: Wed, 15 Nov 2017 00:15:18 +0200 Subject: [PATCH 0785/1664] Test --- iguana/exchanges/LP_nativeDEX.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/iguana/exchanges/LP_nativeDEX.c b/iguana/exchanges/LP_nativeDEX.c index c5c34b353..d17299573 100644 --- a/iguana/exchanges/LP_nativeDEX.c +++ b/iguana/exchanges/LP_nativeDEX.c @@ -310,7 +310,7 @@ char *LP_process_message(void *ctx,char *typestr,char *myipaddr,int32_t pubsock, } else { - if ( (retstr= LP_command_process(ctx,myipaddr,pubsock,argjson,&((uint8_t *)ptr)[len],recvlen - len)) != 0 ) + if ( 0 && (retstr= LP_command_process(ctx,myipaddr,pubsock,argjson,&((uint8_t *)ptr)[len],recvlen - len)) != 0 ) { } //printf("%.3f %s LP_command_process\n",OS_milliseconds()-millis,jstr(argjson,"method")); From c871feeb8b57c7d7c6802c840b69da6967767a22 Mon Sep 17 00:00:00 2001 From: jl777 Date: Wed, 15 Nov 2017 00:19:55 +0200 Subject: [PATCH 0786/1664] Test --- iguana/exchanges/LP_nativeDEX.c | 7 ++----- 1 file changed, 2 insertions(+), 5 deletions(-) diff --git a/iguana/exchanges/LP_nativeDEX.c b/iguana/exchanges/LP_nativeDEX.c index d17299573..87360c470 100644 --- a/iguana/exchanges/LP_nativeDEX.c +++ b/iguana/exchanges/LP_nativeDEX.c @@ -179,18 +179,15 @@ char *LP_command_process(void *ctx,char *myipaddr,int32_t pubsock,cJSON *argjson char *retstr=0; if ( jobj(argjson,"result") != 0 || jobj(argjson,"error") != 0 ) return(0); - //double millis = OS_milliseconds(); if ( LP_tradecommand(ctx,myipaddr,pubsock,argjson,data,datalen) <= 0 ) { - if ( (retstr= stats_JSON(ctx,myipaddr,pubsock,argjson,"127.0.0.1",0)) != 0 ) + if ( 0 && (retstr= stats_JSON(ctx,myipaddr,pubsock,argjson,"127.0.0.1",0)) != 0 ) { //printf("%s PULL.[%d]-> (%s)\n",myipaddr != 0 ? myipaddr : "127.0.0.1",datalen,retstr); //if ( pubsock >= 0 ) //strncmp("{\"error\":",retstr,strlen("{\"error\":")) != 0 && //LP_send(pubsock,retstr,(int32_t)strlen(retstr)+1,0); } } //else printf("finished tradecommand (%s)\n",jprint(argjson,0)); - //if ( OS_milliseconds()-millis > 100 ) - // printf("%.3f %s\n",OS_milliseconds()-millis,jprint(argjson,0)); return(retstr); } @@ -310,7 +307,7 @@ char *LP_process_message(void *ctx,char *typestr,char *myipaddr,int32_t pubsock, } else { - if ( 0 && (retstr= LP_command_process(ctx,myipaddr,pubsock,argjson,&((uint8_t *)ptr)[len],recvlen - len)) != 0 ) + if ( (retstr= LP_command_process(ctx,myipaddr,pubsock,argjson,&((uint8_t *)ptr)[len],recvlen - len)) != 0 ) { } //printf("%.3f %s LP_command_process\n",OS_milliseconds()-millis,jstr(argjson,"method")); From 1fca97e9e6437a0e6207f8399471cb42e1a0a7f6 Mon Sep 17 00:00:00 2001 From: jl777 Date: Wed, 15 Nov 2017 00:21:16 +0200 Subject: [PATCH 0787/1664] Test --- iguana/exchanges/LP_nativeDEX.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/iguana/exchanges/LP_nativeDEX.c b/iguana/exchanges/LP_nativeDEX.c index 87360c470..5969f11a1 100644 --- a/iguana/exchanges/LP_nativeDEX.c +++ b/iguana/exchanges/LP_nativeDEX.c @@ -181,7 +181,7 @@ char *LP_command_process(void *ctx,char *myipaddr,int32_t pubsock,cJSON *argjson return(0); if ( LP_tradecommand(ctx,myipaddr,pubsock,argjson,data,datalen) <= 0 ) { - if ( 0 && (retstr= stats_JSON(ctx,myipaddr,pubsock,argjson,"127.0.0.1",0)) != 0 ) + if ( (retstr= stats_JSON(ctx,myipaddr,pubsock,argjson,"127.0.0.1",0)) != 0 ) { //printf("%s PULL.[%d]-> (%s)\n",myipaddr != 0 ? myipaddr : "127.0.0.1",datalen,retstr); //if ( pubsock >= 0 ) //strncmp("{\"error\":",retstr,strlen("{\"error\":")) != 0 && From dc5149ed0deceafd3855086ad56a6c057578852b Mon Sep 17 00:00:00 2001 From: DeckerSU Date: Wed, 15 Nov 2017 04:56:35 +0400 Subject: [PATCH 0788/1664] added q/a in script use faq --- iguana/dexscripts.win32/how_to_use.md | 12 +++++++++--- iguana/dexscripts.win32/images/conemu_jq.png | Bin 0 -> 31836 bytes 2 files changed, 9 insertions(+), 3 deletions(-) create mode 100644 iguana/dexscripts.win32/images/conemu_jq.png diff --git a/iguana/dexscripts.win32/how_to_use.md b/iguana/dexscripts.win32/how_to_use.md index 29fdcc537..5d1488885 100644 --- a/iguana/dexscripts.win32/how_to_use.md +++ b/iguana/dexscripts.win32/how_to_use.md @@ -1,15 +1,15 @@ ## DexScripts for Windows. How to use? ## -**1. ** Before start you should put scripts and following binaries into one folder: +**1.** Before start you should put scripts and following binaries into one folder: - curl.exe (required for all scripts) - marketmaker.exe - libcurl.dll (required to run marketmaker) - nanomsg.dll (required to run marketmaker) -**2. ** Don't forget to put `coins.json` file into a same folder. This file is available it this repo. +**2.** Don't forget to put `coins.json` file into a same folder. This file is available it this repo. -**3. ** Type your passphrase into passphrase file in this folder (you should create file with name `passphrase` and without extension) and run `1-client.cmd`. This will run marketmaker. Next step is to obtain userpass needed for other scripts, you can simply copy and paste it from marketmaker output on startup into userpass file. +**3.** Type your passphrase into passphrase file in this folder (you should create file with name `passphrase` and without extension) and run `1-client.cmd`. This will run marketmaker. Next step is to obtain userpass needed for other scripts, you can simply copy and paste it from marketmaker output on startup into userpass file. ![](./images/userpass.png) @@ -42,3 +42,9 @@ And nothing works. **A.** Before run `1-client.cmd` make sure in Task Manager that you haven't already running `marketmaker.exe`. If have - kill this process via Task Manager or via command line command `taskkill /f /im taskkill.exe` . +**Q.** How can i pretty print JSON answers of marketmaker? +**A.** You can get best results with 2 tools - [conemu](https://conemu.github.io/) and [jq](https://stedolan.github.io/jq/), conemu supports ANSI X3.64 and Xterm 256 colors and jq allow you to pretty-print json output with colors, like this: + +![](./images/conemu_jq.png) + +Also i'm always recommend to install [Far Manager](https://www.farmanager.com/index.php?l=en) - this is powerful console file manager for Windows, like Midnight Commander in *nix. \ No newline at end of file diff --git a/iguana/dexscripts.win32/images/conemu_jq.png b/iguana/dexscripts.win32/images/conemu_jq.png new file mode 100644 index 0000000000000000000000000000000000000000..e8eeaf523849b859d5b9a396090f3a3b59e4137b GIT binary patch literal 31836 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 IqWAj$0BxH_7ytkO literal 0 HcmV?d00001 From af80a8ed2ff70c3994a7ef29db82ab43902fb4a7 Mon Sep 17 00:00:00 2001 From: jl777 Date: Wed, 15 Nov 2017 11:40:24 +0200 Subject: [PATCH 0789/1664] mark as spent LP_withdraw --- iguana/exchanges/LP_nativeDEX.c | 5 ++++- iguana/exchanges/LP_transaction.c | 1 + iguana/exchanges/LP_utxo.c | 6 +++++- 3 files changed, 10 insertions(+), 2 deletions(-) diff --git a/iguana/exchanges/LP_nativeDEX.c b/iguana/exchanges/LP_nativeDEX.c index 5969f11a1..6232d159b 100644 --- a/iguana/exchanges/LP_nativeDEX.c +++ b/iguana/exchanges/LP_nativeDEX.c @@ -17,7 +17,10 @@ // LP_nativeDEX.c // marketmaker // -// single utxo allocations alice, reject result, latency +// single utxo allocations alice +// gc cJSON +// more retries for swap sendrawtransaction +// pbca26 unfinished swaps // alice waiting for bestprice //if ( G.LP_pendingswaps != 0 ) //return(-1); diff --git a/iguana/exchanges/LP_transaction.c b/iguana/exchanges/LP_transaction.c index 4df4b3895..098d2cb84 100644 --- a/iguana/exchanges/LP_transaction.c +++ b/iguana/exchanges/LP_transaction.c @@ -987,6 +987,7 @@ int32_t LP_vins_select(void *ctx,struct iguana_info *coin,int64_t *totalp,int64_ vp->suppress_pubkeys = suppress_pubkeys; vp->ignore_cltverr = ignore_cltverr; jaddi(vins,LP_inputjson(up->U.txid,up->U.vout,spendscriptstr)); + LP_unavailableset(up->U.txid,up->U.vout,(uint32_t)time(NULL)+600,G.LP_mypub25519); if ( remains <= 0 && i >= numpre-1 ) break; if ( numunspents < 0 ) diff --git a/iguana/exchanges/LP_utxo.c b/iguana/exchanges/LP_utxo.c index 0f2aee2c3..f8b4d7fac 100644 --- a/iguana/exchanges/LP_utxo.c +++ b/iguana/exchanges/LP_utxo.c @@ -59,7 +59,11 @@ int32_t _LP_inuse_delete(bits256 txid,int32_t vout) struct LP_inuse_info *_LP_inuse_add(uint32_t expiration,bits256 otherpub,bits256 txid,int32_t vout) { struct LP_inuse_info *lp; - if ( bits256_nonz(txid) != 0 && LP_numinuse < sizeof(LP_inuse)/sizeof(*LP_inuse) ) + if ( LP_numinuse >= sizeof(LP_inuse)/sizeof(*LP_inuse) ) + { + + } + if ( bits256_nonz(txid) != 0 && ) { if ( (lp= _LP_inuse_find(txid,vout)) == 0 ) { From 57fd772dfc465dca44cf40e50afe2cb278d25a70 Mon Sep 17 00:00:00 2001 From: jl777 Date: Wed, 15 Nov 2017 11:45:41 +0200 Subject: [PATCH 0790/1664] Test --- iguana/exchanges/LP_utxo.c | 26 +++++++++++++++++++++++--- 1 file changed, 23 insertions(+), 3 deletions(-) diff --git a/iguana/exchanges/LP_utxo.c b/iguana/exchanges/LP_utxo.c index f8b4d7fac..6e49013b0 100644 --- a/iguana/exchanges/LP_utxo.c +++ b/iguana/exchanges/LP_utxo.c @@ -58,12 +58,32 @@ int32_t _LP_inuse_delete(bits256 txid,int32_t vout) struct LP_inuse_info *_LP_inuse_add(uint32_t expiration,bits256 otherpub,bits256 txid,int32_t vout) { - struct LP_inuse_info *lp; + struct LP_inuse_info *lp; int32_t i,n,oldesti; uint32_t now,oldest; if ( LP_numinuse >= sizeof(LP_inuse)/sizeof(*LP_inuse) ) { - + now = (uint32_t)time(NULL); + n = 0; + oldesti = -1; + oldest = 0; + for (i=0; i lp->expiration ) + _LP_inuse_delete(lp->txid,lp->vout), n++; + else if ( oldest == 0 || lp->expiration < oldest ) + { + oldest = lp->expiration; + oldesti = i; + } + } + if ( n == 0 ) + { + printf("_LP_inuse_add out of slots error, pick oldesti %d\n",oldesti); + lp = &LP_inuse[oldesti]; + _LP_inuse_delete(lp->txid,lp->vout); + } else printf("expired %d inuse slots\n",n); } - if ( bits256_nonz(txid) != 0 && ) + if ( bits256_nonz(txid) != 0 ) { if ( (lp= _LP_inuse_find(txid,vout)) == 0 ) { From cb09859e0e8975f2b736628cfa0140cf242fd77c Mon Sep 17 00:00:00 2001 From: jl777 Date: Wed, 15 Nov 2017 11:59:39 +0200 Subject: [PATCH 0791/1664] Test --- iguana/exchanges/LP_transaction.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/iguana/exchanges/LP_transaction.c b/iguana/exchanges/LP_transaction.c index 098d2cb84..3f6ff3e43 100644 --- a/iguana/exchanges/LP_transaction.c +++ b/iguana/exchanges/LP_transaction.c @@ -1020,7 +1020,7 @@ char *LP_createrawtransaction(cJSON **txobjp,int32_t *numvinsp,struct iguana_inf } if ( coin->numutxos < LP_MINDESIRED_UTXOS ) dustcombine = 0; - else if ( coin->numutxos >= LP_MINDESIRED_UTXOS ) + else if ( coin->numutxos >= LP_MAXDESIRED_UTXOS ) dustcombine = 2; else dustcombine = 1; amount = txfee; From be324b6c5fabb94c86a462d9e3fdec26e1b877c5 Mon Sep 17 00:00:00 2001 From: jl777 Date: Wed, 15 Nov 2017 12:17:10 +0200 Subject: [PATCH 0792/1664] Test --- iguana/exchanges/LP_include.h | 4 ++-- iguana/exchanges/LP_nativeDEX.c | 9 ++++----- 2 files changed, 6 insertions(+), 7 deletions(-) diff --git a/iguana/exchanges/LP_include.h b/iguana/exchanges/LP_include.h index b7dd79e03..5e530f9c1 100644 --- a/iguana/exchanges/LP_include.h +++ b/iguana/exchanges/LP_include.h @@ -53,8 +53,8 @@ void emscripten_usleep(int32_t x); // returns immediate, no sense for sleeping #define LP_MIN_PEERS 8 #define LP_MAX_PEERS 32 -#define LP_MAXDESIRED_UTXOS 128 -#define LP_MINDESIRED_UTXOS 32 +#define LP_MAXDESIRED_UTXOS (IAMLP != 0 ? 128 : 64) +#define LP_MINDESIRED_UTXOS (IAMLP != 0 ? 32 : 16) #define LP_DUSTCOMBINE_THRESHOLD 1000000 // RTmetrics diff --git a/iguana/exchanges/LP_nativeDEX.c b/iguana/exchanges/LP_nativeDEX.c index 6232d159b..ae5fa57a7 100644 --- a/iguana/exchanges/LP_nativeDEX.c +++ b/iguana/exchanges/LP_nativeDEX.c @@ -17,16 +17,15 @@ // LP_nativeDEX.c // marketmaker // -// single utxo allocations alice // gc cJSON -// more retries for swap sendrawtransaction +// more retries for swap sendrawtransaction? // pbca26 unfinished swaps -// alice waiting for bestprice -//if ( G.LP_pendingswaps != 0 ) -//return(-1); +// if ( G.LP_pendingswaps != 0 ) return(-1); // bot safe to exit? // // BCH signing +// single utxo allocations alice +// alice waiting for bestprice // previously, it used to show amount, kmd equiv, perc // dPoW security -> 4: KMD notarized, 5: BTC notarized, after next notary elections // bigendian architectures need to use little endian for sighash calcs From 48ffd56a48f7843f33eb5c043a41d04da7b608b4 Mon Sep 17 00:00:00 2001 From: jl777 Date: Wed, 15 Nov 2017 13:04:17 +0200 Subject: [PATCH 0793/1664] Test --- crypto777/cJSON.c | 33 ++++++++++++++++++++++++++++++--- iguana/exchanges/mm.c | 1 + 2 files changed, 31 insertions(+), 3 deletions(-) diff --git a/crypto777/cJSON.c b/crypto777/cJSON.c index 8bce48b19..9674910b8 100755 --- a/crypto777/cJSON.c +++ b/crypto777/cJSON.c @@ -578,8 +578,6 @@ cJSON *cJSON_CreateFalse(void) {cJSON *item=cJSON_New_Item();if(item)item->t cJSON *cJSON_CreateBool(int32_t b) {cJSON *item=cJSON_New_Item();if(item)item->type=b?cJSON_True:cJSON_False;return item;} cJSON *cJSON_CreateNumber(double num) {cJSON *item=cJSON_New_Item();if(item){item->type=cJSON_Number;item->valuedouble=num;item->valueint=(int64_t)num;}return item;} cJSON *cJSON_CreateString(const char *string) {cJSON *item=cJSON_New_Item();if(item){item->type=cJSON_String;item->valuestring=cJSON_strdup(string);}return item;} -cJSON *cJSON_CreateArray(void) {cJSON *item=cJSON_New_Item();if(item)item->type=cJSON_Array;return item;} -cJSON *cJSON_CreateObject(void) {cJSON *item=cJSON_New_Item();if(item)item->type=cJSON_Object;return item;} /* Create Arrays: */ cJSON *cJSON_CreateIntArray(int64_t *numbers,int32_t count) {int32_t i;cJSON *n=0,*p=0,*a=cJSON_CreateArray();for(i=0;a && ichild=n;else suffix_object(p,n);p=n;}return a;} @@ -1129,4 +1127,33 @@ cJSON *addrs_jsonarray(uint64_t *addrs,int32_t num) return(array); } -void free_json(cJSON *json) { if ( json != 0 ) cJSON_Delete(json); } +cJSON *cJSON_CreateArray(void) +{ + cJSON *item = cJSON_New_Item(); + if ( item ) + item->type = cJSON_Array; +#ifdef CJSON_GARBAGECOLLECTION + cJSON_register(item); +#endif + return(item); +} + +cJSON *cJSON_CreateObject(void) +{ + cJSON *item = cJSON_New_Item(); + if ( item ) + item->type = cJSON_Object; +#ifdef CJSON_GARBAGECOLLECTION + cJSON_register(item); +#endif + return item; +} + +void free_json(cJSON *json) +{ +#ifdef CJSON_GARBAGECOLLECTION + cJSON_unregister(item); +#endif + if ( json != 0 ) + cJSON_Delete(json); +} diff --git a/iguana/exchanges/mm.c b/iguana/exchanges/mm.c index 1d2a1bd5e..8ce073d1f 100644 --- a/iguana/exchanges/mm.c +++ b/iguana/exchanges/mm.c @@ -24,6 +24,7 @@ void PNACL_message(char *arg,...) } #define FROM_MARKETMAKER +#define CJSON_GARBAGECOLLECTION #include #include #ifndef NATIVE_WINDOWS From 7e999953c64612ea58110f01b0aa123621781814 Mon Sep 17 00:00:00 2001 From: jl777 Date: Wed, 15 Nov 2017 13:16:29 +0200 Subject: [PATCH 0794/1664] Test --- crypto777/cJSON.c | 2 +- iguana/m_mm | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/crypto777/cJSON.c b/crypto777/cJSON.c index 9674910b8..404931fcf 100755 --- a/crypto777/cJSON.c +++ b/crypto777/cJSON.c @@ -1144,7 +1144,7 @@ cJSON *cJSON_CreateObject(void) if ( item ) item->type = cJSON_Object; #ifdef CJSON_GARBAGECOLLECTION - cJSON_register(item); + cJSON_register(item); fff #endif return item; } diff --git a/iguana/m_mm b/iguana/m_mm index b5ba405ca..3905b5d84 100755 --- a/iguana/m_mm +++ b/iguana/m_mm @@ -1,3 +1,3 @@ cd secp256k1; ./m_unix; cd .. cd ../crypto777; ./m_LP; cd ../iguana -gcc -g -o marketmaker -I../crypto777 exchanges/mm.c mini-gmp.c secp256k1.o ../agents/libcrypto777.a -lnanomsg -lcurl -lpthread -lm +gcc -DFROM_MARKETMAKER -g -o marketmaker -I../crypto777 exchanges/mm.c ../crypto777/cJSON.c mini-gmp.c secp256k1.o ../agents/libcrypto777.a -lnanomsg -lcurl -lpthread -lm From 32191a3f60704664049426d0242e0bf5753a36c2 Mon Sep 17 00:00:00 2001 From: jl777 Date: Wed, 15 Nov 2017 13:26:24 +0200 Subject: [PATCH 0795/1664] Test --- crypto777/cJSON.c | 2 ++ iguana/exchanges/mm.c | 3 +++ 2 files changed, 5 insertions(+) diff --git a/crypto777/cJSON.c b/crypto777/cJSON.c index 404931fcf..a9bb74dd7 100755 --- a/crypto777/cJSON.c +++ b/crypto777/cJSON.c @@ -25,6 +25,8 @@ /* JSON parser in C. */ #include +#define CJSON_GARBAGECOLLECTION + #include "../includes/cJSON.h" #ifndef DBL_EPSILON diff --git a/iguana/exchanges/mm.c b/iguana/exchanges/mm.c index 8ce073d1f..56498394a 100644 --- a/iguana/exchanges/mm.c +++ b/iguana/exchanges/mm.c @@ -23,7 +23,10 @@ void PNACL_message(char *arg,...) { } +#ifndef FROM_MARKETMAKER #define FROM_MARKETMAKER +#endif + #define CJSON_GARBAGECOLLECTION #include #include From 3df1acbc3b4bd1470d291f8c36c21d3a29477032 Mon Sep 17 00:00:00 2001 From: jl777 Date: Wed, 15 Nov 2017 13:28:05 +0200 Subject: [PATCH 0796/1664] Test --- crypto777/cJSON.c | 2 -- iguana/exchanges/mm.c | 5 +++-- iguana/m_mm | 2 +- 3 files changed, 4 insertions(+), 5 deletions(-) diff --git a/crypto777/cJSON.c b/crypto777/cJSON.c index a9bb74dd7..404931fcf 100755 --- a/crypto777/cJSON.c +++ b/crypto777/cJSON.c @@ -25,8 +25,6 @@ /* JSON parser in C. */ #include -#define CJSON_GARBAGECOLLECTION - #include "../includes/cJSON.h" #ifndef DBL_EPSILON diff --git a/iguana/exchanges/mm.c b/iguana/exchanges/mm.c index 56498394a..e20b1dcb6 100644 --- a/iguana/exchanges/mm.c +++ b/iguana/exchanges/mm.c @@ -23,11 +23,12 @@ void PNACL_message(char *arg,...) { } -#ifndef FROM_MARKETMAKER #define FROM_MARKETMAKER -#endif +#ifndef CJSON_GARBAGECOLLECTION #define CJSON_GARBAGECOLLECTION +#endif + #include #include #ifndef NATIVE_WINDOWS diff --git a/iguana/m_mm b/iguana/m_mm index 3905b5d84..0609d842c 100755 --- a/iguana/m_mm +++ b/iguana/m_mm @@ -1,3 +1,3 @@ cd secp256k1; ./m_unix; cd .. cd ../crypto777; ./m_LP; cd ../iguana -gcc -DFROM_MARKETMAKER -g -o marketmaker -I../crypto777 exchanges/mm.c ../crypto777/cJSON.c mini-gmp.c secp256k1.o ../agents/libcrypto777.a -lnanomsg -lcurl -lpthread -lm +gcc -DCJSON_GARBAGECOLLECTION -g -o marketmaker -I../crypto777 exchanges/mm.c ../crypto777/cJSON.c mini-gmp.c secp256k1.o ../agents/libcrypto777.a -lnanomsg -lcurl -lpthread -lm From 62ff96b246815feebf2e2d55e39f75d96cec226b Mon Sep 17 00:00:00 2001 From: jl777 Date: Wed, 15 Nov 2017 13:29:15 +0200 Subject: [PATCH 0797/1664] Test --- crypto777/cJSON.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/crypto777/cJSON.c b/crypto777/cJSON.c index 404931fcf..9674910b8 100755 --- a/crypto777/cJSON.c +++ b/crypto777/cJSON.c @@ -1144,7 +1144,7 @@ cJSON *cJSON_CreateObject(void) if ( item ) item->type = cJSON_Object; #ifdef CJSON_GARBAGECOLLECTION - cJSON_register(item); fff + cJSON_register(item); #endif return item; } From 21b83eaf5fc3d5e978d247524c46dd2745834c15 Mon Sep 17 00:00:00 2001 From: jl777 Date: Wed, 15 Nov 2017 13:31:20 +0200 Subject: [PATCH 0798/1664] Test --- includes/cJSON.h | 2 ++ 1 file changed, 2 insertions(+) diff --git a/includes/cJSON.h b/includes/cJSON.h index 77e0752e6..cd8e6d00f 100755 --- a/includes/cJSON.h +++ b/includes/cJSON.h @@ -218,6 +218,8 @@ extern "C" char *nxt64str2(uint64_t nxt64bits); cJSON *addrs_jsonarray(uint64_t *addrs,int32_t num); int32_t myatoi(char *str,int32_t range); + void cJSON_register(cJSON *item); + void cJSON_unregister(cJSON *item); char *stringifyM(char *str); #define replace_backslashquotes unstringify From fc1c161db6650d8cd989ae00d742596606d1116d Mon Sep 17 00:00:00 2001 From: jl777 Date: Wed, 15 Nov 2017 13:47:36 +0200 Subject: [PATCH 0799/1664] Test --- iguana/exchanges/LP_nativeDEX.c | 3 ++- iguana/exchanges/LP_utxo.c | 36 +++++++++++++++++++++++++++++++++ 2 files changed, 38 insertions(+), 1 deletion(-) diff --git a/iguana/exchanges/LP_nativeDEX.c b/iguana/exchanges/LP_nativeDEX.c index ae5fa57a7..c7ba59d0b 100644 --- a/iguana/exchanges/LP_nativeDEX.c +++ b/iguana/exchanges/LP_nativeDEX.c @@ -82,7 +82,7 @@ void LP_millistats_update(struct LP_millistats *mp) } #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,LP_reservedmutex,LP_nanorecvsmutex,LP_tradebotsmutex,LP_gcmutex,LP_inusemutex; +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,LP_tradebotsmutex,LP_gcmutex,LP_inusemutex,LP_cJSONmutex; int32_t LP_canbind; char *Broadcaststr,*Reserved_msgs[2][1000]; int32_t num_Reserved_msgs[2],max_Reserved_msgs[2]; @@ -938,6 +938,7 @@ void LPinit(uint16_t myport,uint16_t mypullport,uint16_t mypubport,uint16_t mybu portable_mutex_init(&LP_reservedmutex); portable_mutex_init(&LP_nanorecvsmutex); portable_mutex_init(&LP_tradebotsmutex); + portable_mutex_init(&LP_cJSONmutex); myipaddr = clonestr("127.0.0.1"); #ifndef _WIN32 #ifndef FROM_JS diff --git a/iguana/exchanges/LP_utxo.c b/iguana/exchanges/LP_utxo.c index 6e49013b0..cdfff09a1 100644 --- a/iguana/exchanges/LP_utxo.c +++ b/iguana/exchanges/LP_utxo.c @@ -27,6 +27,42 @@ struct LP_inuse_info } LP_inuse[1024]; int32_t LP_numinuse; +struct cJSON_list +{ + struct cJSON_list *next,*prev; + cJSON *item; + uint32_t timestamp; +} *LP_cJSONlist; + +void cJSON_register(cJSON *item) +{ + struct cJSON_list *ptr; + ptr = calloc(1,sizeof(*ptr)); + ptr->timestamp = (uint32_t)time(NULL); + ptr->item = item; + portable_mutex_lock(&LP_cJSONmutex); + DL_APPEND(LP_cJSONlist,ptr); + portable_mutex_unlock(&LP_cJSONmutex); +} + +void cJSON_unregister(cJSON *item) +{ + struct cJSON_list *ptr,*tmp; + DL_FOREACH_SAFE(LP_cJSONlist,ptr,tmp) + { + if ( ptr->item == item ) + break; + ptr = 0; + } + if ( ptr != 0 ) + { + portable_mutex_lock(&LP_cJSONmutex); + DL_DELETE(LP_cJSONlist,ptr); + free(ptr); + portable_mutex_unlock(&LP_cJSONmutex); + } +} + struct LP_inuse_info *_LP_inuse_find(bits256 txid,int32_t vout) { int32_t i; From 5770810c609ab69de70d92bebe61a202bf8fcb5f Mon Sep 17 00:00:00 2001 From: jl777 Date: Wed, 15 Nov 2017 13:48:38 +0200 Subject: [PATCH 0800/1664] Test --- crypto777/cJSON.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/crypto777/cJSON.c b/crypto777/cJSON.c index 9674910b8..28f02bafc 100755 --- a/crypto777/cJSON.c +++ b/crypto777/cJSON.c @@ -1149,11 +1149,11 @@ cJSON *cJSON_CreateObject(void) return item; } -void free_json(cJSON *json) +void free_json(cJSON *item) { #ifdef CJSON_GARBAGECOLLECTION cJSON_unregister(item); #endif if ( json != 0 ) - cJSON_Delete(json); + cJSON_Delete(item); } From b86d13d6b503774c2c54b4c83c02560396b71f1c Mon Sep 17 00:00:00 2001 From: jl777 Date: Wed, 15 Nov 2017 13:49:30 +0200 Subject: [PATCH 0801/1664] Test --- crypto777/cJSON.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/crypto777/cJSON.c b/crypto777/cJSON.c index 28f02bafc..555fdf29c 100755 --- a/crypto777/cJSON.c +++ b/crypto777/cJSON.c @@ -1154,6 +1154,6 @@ void free_json(cJSON *item) #ifdef CJSON_GARBAGECOLLECTION cJSON_unregister(item); #endif - if ( json != 0 ) + if ( item != 0 ) cJSON_Delete(item); } From 2d23ba8dd6bf0d45f5bd5c8cb32d4498b354aa26 Mon Sep 17 00:00:00 2001 From: jl777 Date: Wed, 15 Nov 2017 14:15:08 +0200 Subject: [PATCH 0802/1664] Test --- iguana/exchanges/LP_utxo.c | 20 ++++++++++++++++++-- 1 file changed, 18 insertions(+), 2 deletions(-) diff --git a/iguana/exchanges/LP_utxo.c b/iguana/exchanges/LP_utxo.c index cdfff09a1..6d22d3faf 100644 --- a/iguana/exchanges/LP_utxo.c +++ b/iguana/exchanges/LP_utxo.c @@ -45,9 +45,25 @@ void cJSON_register(cJSON *item) portable_mutex_unlock(&LP_cJSONmutex); } +char *mbstr(char *str,double n); void cJSON_unregister(cJSON *item) { - struct cJSON_list *ptr,*tmp; + static uint32_t lasttime; + char *tmpstr,str[65]; int32_t n; uint64_t total; struct cJSON_list *ptr,*tmp; + if ( time(NULL) > lasttime+600 ) + { + n = 0; + total = 0; + DL_FOREACH_SAFE(LP_cJSONlist,ptr,tmp) + { + tmpstr = jprint(ptr->item,0); + total += strlen(tmpstr); + free(tmpstr); + n++; + } + printf("total %d cJSON pending %s\n",n,mbstr(str,total)); + lasttime = (uint32_t)time(NULL); + } DL_FOREACH_SAFE(LP_cJSONlist,ptr,tmp) { if ( ptr->item == item ) @@ -60,7 +76,7 @@ void cJSON_unregister(cJSON *item) DL_DELETE(LP_cJSONlist,ptr); free(ptr); portable_mutex_unlock(&LP_cJSONmutex); - } + } else printf("cJSON_unregister of unknown %p\n",item); } struct LP_inuse_info *_LP_inuse_find(bits256 txid,int32_t vout) From 19634a3c9afa042ef0b92574c8f608ed3a55770a Mon Sep 17 00:00:00 2001 From: jl777 Date: Wed, 15 Nov 2017 14:18:04 +0200 Subject: [PATCH 0803/1664] Test --- iguana/exchanges/LP_utxo.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/iguana/exchanges/LP_utxo.c b/iguana/exchanges/LP_utxo.c index 6d22d3faf..e36afaff5 100644 --- a/iguana/exchanges/LP_utxo.c +++ b/iguana/exchanges/LP_utxo.c @@ -72,11 +72,12 @@ void cJSON_unregister(cJSON *item) } if ( ptr != 0 ) { + printf("found %p\n",item); portable_mutex_lock(&LP_cJSONmutex); DL_DELETE(LP_cJSONlist,ptr); free(ptr); portable_mutex_unlock(&LP_cJSONmutex); - } else printf("cJSON_unregister of unknown %p\n",item); + } //else printf("cJSON_unregister of unknown %p\n",item); } struct LP_inuse_info *_LP_inuse_find(bits256 txid,int32_t vout) From ce6caefbed81964237feb6d8715a6ca8dfc41b78 Mon Sep 17 00:00:00 2001 From: jl777 Date: Wed, 15 Nov 2017 14:24:45 +0200 Subject: [PATCH 0804/1664] Test --- iguana/exchanges/LP_utxo.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/iguana/exchanges/LP_utxo.c b/iguana/exchanges/LP_utxo.c index e36afaff5..a807f2fcc 100644 --- a/iguana/exchanges/LP_utxo.c +++ b/iguana/exchanges/LP_utxo.c @@ -37,6 +37,7 @@ struct cJSON_list void cJSON_register(cJSON *item) { struct cJSON_list *ptr; + printf(" register %p\n",item); ptr = calloc(1,sizeof(*ptr)); ptr->timestamp = (uint32_t)time(NULL); ptr->item = item; @@ -50,6 +51,7 @@ void cJSON_unregister(cJSON *item) { static uint32_t lasttime; char *tmpstr,str[65]; int32_t n; uint64_t total; struct cJSON_list *ptr,*tmp; + printf("unregister %p\n",item); if ( time(NULL) > lasttime+600 ) { n = 0; From 240d250f68c28d0cfe50022e381918f472870639 Mon Sep 17 00:00:00 2001 From: jl777 Date: Wed, 15 Nov 2017 14:34:25 +0200 Subject: [PATCH 0805/1664] Test --- iguana/exchanges/LP_utxo.c | 2 +- iguana/exchanges/invreset | 1 + 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/iguana/exchanges/LP_utxo.c b/iguana/exchanges/LP_utxo.c index a807f2fcc..ce9c0f4ca 100644 --- a/iguana/exchanges/LP_utxo.c +++ b/iguana/exchanges/LP_utxo.c @@ -52,7 +52,7 @@ void cJSON_unregister(cJSON *item) static uint32_t lasttime; char *tmpstr,str[65]; int32_t n; uint64_t total; struct cJSON_list *ptr,*tmp; printf("unregister %p\n",item); - if ( time(NULL) > lasttime+600 ) + if ( time(NULL) > lasttime+6 ) { n = 0; total = 0; diff --git a/iguana/exchanges/invreset b/iguana/exchanges/invreset index f0b1c79e3..0304c7503 100755 --- a/iguana/exchanges/invreset +++ b/iguana/exchanges/invreset @@ -1,3 +1,4 @@ +#!/bin/bash source userpass source passphrase curl --url "http://127.0.0.1:7783" --data "{\"userpass\":\"$userpass\",\"method\":\"inventory\",\"coin\":\"KMD\",\"reset\":1,\"passphrase\":\"$passphrase\"}" From d70d5c835db1c4661513f8b3c9b2280154c09b23 Mon Sep 17 00:00:00 2001 From: jl777 Date: Wed, 15 Nov 2017 14:41:16 +0200 Subject: [PATCH 0806/1664] Test --- iguana/exchanges/LP_utxo.c | 13 ++++++------- includes/cJSON.h | 1 + 2 files changed, 7 insertions(+), 7 deletions(-) diff --git a/iguana/exchanges/LP_utxo.c b/iguana/exchanges/LP_utxo.c index ce9c0f4ca..a329aaef5 100644 --- a/iguana/exchanges/LP_utxo.c +++ b/iguana/exchanges/LP_utxo.c @@ -31,16 +31,17 @@ struct cJSON_list { struct cJSON_list *next,*prev; cJSON *item; - uint32_t timestamp; + uint32_t timestamp,cjsonid; } *LP_cJSONlist; void cJSON_register(cJSON *item) { struct cJSON_list *ptr; - printf(" register %p\n",item); ptr = calloc(1,sizeof(*ptr)); ptr->timestamp = (uint32_t)time(NULL); ptr->item = item; + item->cjsonid = rand(); + ptr->cjsonid = item->cjsonid; portable_mutex_lock(&LP_cJSONmutex); DL_APPEND(LP_cJSONlist,ptr); portable_mutex_unlock(&LP_cJSONmutex); @@ -51,8 +52,7 @@ void cJSON_unregister(cJSON *item) { static uint32_t lasttime; char *tmpstr,str[65]; int32_t n; uint64_t total; struct cJSON_list *ptr,*tmp; - printf("unregister %p\n",item); - if ( time(NULL) > lasttime+6 ) + //if ( time(NULL) > lasttime+6 ) { n = 0; total = 0; @@ -68,18 +68,17 @@ void cJSON_unregister(cJSON *item) } DL_FOREACH_SAFE(LP_cJSONlist,ptr,tmp) { - if ( ptr->item == item ) + if ( ptr->cjsonid == item->cjsonid )//ptr->item == item ) break; ptr = 0; } if ( ptr != 0 ) { - printf("found %p\n",item); portable_mutex_lock(&LP_cJSONmutex); DL_DELETE(LP_cJSONlist,ptr); free(ptr); portable_mutex_unlock(&LP_cJSONmutex); - } //else printf("cJSON_unregister of unknown %p\n",item); + } else printf("cJSON_unregister of unknown %p\n",item); } struct LP_inuse_info *_LP_inuse_find(bits256 txid,int32_t vout) diff --git a/includes/cJSON.h b/includes/cJSON.h index cd8e6d00f..3ecdadc69 100755 --- a/includes/cJSON.h +++ b/includes/cJSON.h @@ -73,6 +73,7 @@ extern "C" double valuedouble; /* The item's number, if type==cJSON_Number */ char *string; /* The item's name string, if this item is the child of, or is in the list of subitems of an object. */ + uint32_t cjsonid; } cJSON; typedef struct cJSON_Hooks { From 006fcdaea0a39052d5ff699b02cb3ea0fcff5639 Mon Sep 17 00:00:00 2001 From: jl777 Date: Wed, 15 Nov 2017 14:42:32 +0200 Subject: [PATCH 0807/1664] Test --- iguana/exchanges/LP_utxo.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/iguana/exchanges/LP_utxo.c b/iguana/exchanges/LP_utxo.c index a329aaef5..8a54d97ae 100644 --- a/iguana/exchanges/LP_utxo.c +++ b/iguana/exchanges/LP_utxo.c @@ -78,7 +78,7 @@ void cJSON_unregister(cJSON *item) DL_DELETE(LP_cJSONlist,ptr); free(ptr); portable_mutex_unlock(&LP_cJSONmutex); - } else printf("cJSON_unregister of unknown %p\n",item); + } else printf("cJSON_unregister of unknown %p %u\n",item,item->cjsonid); } struct LP_inuse_info *_LP_inuse_find(bits256 txid,int32_t vout) From 5e851f41eadad9b2f13beca5ef25db937970b535 Mon Sep 17 00:00:00 2001 From: jl777 Date: Wed, 15 Nov 2017 14:46:40 +0200 Subject: [PATCH 0808/1664] Test --- iguana/exchanges/LP_utxo.c | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/iguana/exchanges/LP_utxo.c b/iguana/exchanges/LP_utxo.c index 8a54d97ae..d785ca933 100644 --- a/iguana/exchanges/LP_utxo.c +++ b/iguana/exchanges/LP_utxo.c @@ -58,9 +58,11 @@ void cJSON_unregister(cJSON *item) total = 0; DL_FOREACH_SAFE(LP_cJSONlist,ptr,tmp) { - tmpstr = jprint(ptr->item,0); - total += strlen(tmpstr); - free(tmpstr); + if ( (tmpstr= jprint(ptr->item,0)) != 0 ) + { + total += strlen(tmpstr); + free(tmpstr); + } n++; } printf("total %d cJSON pending %s\n",n,mbstr(str,total)); From 86e4295c24ea27dfd2528426d565f0f158bca475 Mon Sep 17 00:00:00 2001 From: jl777 Date: Wed, 15 Nov 2017 14:50:28 +0200 Subject: [PATCH 0809/1664] Test --- crypto777/bitcoind_RPC.c | 2 +- iguana/exchanges/LP_utxo.c | 9 ++++++--- 2 files changed, 7 insertions(+), 4 deletions(-) diff --git a/crypto777/bitcoind_RPC.c b/crypto777/bitcoind_RPC.c index 4f0a9cdd4..98c7e7eb0 100755 --- a/crypto777/bitcoind_RPC.c +++ b/crypto777/bitcoind_RPC.c @@ -56,7 +56,7 @@ char *post_process_bitcoind_RPC(char *debugstr,char *command,char *rpcstr,char * char *retstr = 0; cJSON *json,*result,*error; #ifdef FROM_MARKETMAKER - usleep(5000); + usleep(3000); #endif //printf("<<<<<<<<<<< bitcoind_RPC: %s post_process_bitcoind_RPC.%s.[%s]\n",debugstr,command,rpcstr); if ( command == 0 || rpcstr == 0 || rpcstr[0] == 0 ) diff --git a/iguana/exchanges/LP_utxo.c b/iguana/exchanges/LP_utxo.c index d785ca933..c78b475e7 100644 --- a/iguana/exchanges/LP_utxo.c +++ b/iguana/exchanges/LP_utxo.c @@ -58,10 +58,13 @@ void cJSON_unregister(cJSON *item) total = 0; DL_FOREACH_SAFE(LP_cJSONlist,ptr,tmp) { - if ( (tmpstr= jprint(ptr->item,0)) != 0 ) + if ( ptr->item != 0 && ptr->item->child != 0 ) { - total += strlen(tmpstr); - free(tmpstr); + if ( (tmpstr= jprint(ptr->item,0)) != 0 ) + { + total += strlen(tmpstr); + free(tmpstr); + } } n++; } From 54a26a1ebad8d4f05dc943e21de0d681cac5b94a Mon Sep 17 00:00:00 2001 From: jl777 Date: Wed, 15 Nov 2017 14:54:30 +0200 Subject: [PATCH 0810/1664] Test --- iguana/exchanges/LP_utxo.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/iguana/exchanges/LP_utxo.c b/iguana/exchanges/LP_utxo.c index c78b475e7..fa1210cfa 100644 --- a/iguana/exchanges/LP_utxo.c +++ b/iguana/exchanges/LP_utxo.c @@ -58,14 +58,14 @@ void cJSON_unregister(cJSON *item) total = 0; DL_FOREACH_SAFE(LP_cJSONlist,ptr,tmp) { - if ( ptr->item != 0 && ptr->item->child != 0 ) + /*if ( ptr->item != 0 && ptr->item->child != 0 ) { if ( (tmpstr= jprint(ptr->item,0)) != 0 ) { total += strlen(tmpstr); free(tmpstr); } - } + }*/ n++; } printf("total %d cJSON pending %s\n",n,mbstr(str,total)); From 66c434d82d697843a93ff2bca53449cc9e7a1353 Mon Sep 17 00:00:00 2001 From: jl777 Date: Wed, 15 Nov 2017 14:55:57 +0200 Subject: [PATCH 0811/1664] Test --- iguana/exchanges/LP_utxo.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/iguana/exchanges/LP_utxo.c b/iguana/exchanges/LP_utxo.c index fa1210cfa..de6660b86 100644 --- a/iguana/exchanges/LP_utxo.c +++ b/iguana/exchanges/LP_utxo.c @@ -58,14 +58,14 @@ void cJSON_unregister(cJSON *item) total = 0; DL_FOREACH_SAFE(LP_cJSONlist,ptr,tmp) { - /*if ( ptr->item != 0 && ptr->item->child != 0 ) + if ( ptr->item != 0 && ptr->item->child != 0 && ptr->cjsonid != 0 ) { if ( (tmpstr= jprint(ptr->item,0)) != 0 ) { total += strlen(tmpstr); free(tmpstr); } - }*/ + } n++; } printf("total %d cJSON pending %s\n",n,mbstr(str,total)); From a25ab17cbbe7c727b44469f96794a3e0b56f3832 Mon Sep 17 00:00:00 2001 From: jl777 Date: Wed, 15 Nov 2017 15:00:04 +0200 Subject: [PATCH 0812/1664] Test --- iguana/exchanges/LP_utxo.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/iguana/exchanges/LP_utxo.c b/iguana/exchanges/LP_utxo.c index de6660b86..933af800a 100644 --- a/iguana/exchanges/LP_utxo.c +++ b/iguana/exchanges/LP_utxo.c @@ -58,14 +58,14 @@ void cJSON_unregister(cJSON *item) total = 0; DL_FOREACH_SAFE(LP_cJSONlist,ptr,tmp) { - if ( ptr->item != 0 && ptr->item->child != 0 && ptr->cjsonid != 0 ) + /*if ( ptr->item != 0 && ptr->item->child != 0 && ptr->cjsonid != 0 ) { if ( (tmpstr= jprint(ptr->item,0)) != 0 ) { total += strlen(tmpstr); free(tmpstr); } - } + }*/ n++; } printf("total %d cJSON pending %s\n",n,mbstr(str,total)); From 7c29efc217e67da5540e904df1fd2e96d933c7ed Mon Sep 17 00:00:00 2001 From: jl777 Date: Wed, 15 Nov 2017 15:08:29 +0200 Subject: [PATCH 0813/1664] Test --- iguana/exchanges/LP_utxo.c | 17 ++++++++++++----- 1 file changed, 12 insertions(+), 5 deletions(-) diff --git a/iguana/exchanges/LP_utxo.c b/iguana/exchanges/LP_utxo.c index 933af800a..8512572e6 100644 --- a/iguana/exchanges/LP_utxo.c +++ b/iguana/exchanges/LP_utxo.c @@ -51,11 +51,10 @@ char *mbstr(char *str,double n); void cJSON_unregister(cJSON *item) { static uint32_t lasttime; - char *tmpstr,str[65]; int32_t n; uint64_t total; struct cJSON_list *ptr,*tmp; - //if ( time(NULL) > lasttime+6 ) + int32_t n; struct cJSON_list *ptr,*tmp; uint32_t now; + if ( (now= time(NULL)) > lasttime+6 ) { n = 0; - total = 0; DL_FOREACH_SAFE(LP_cJSONlist,ptr,tmp) { /*if ( ptr->item != 0 && ptr->item->child != 0 && ptr->cjsonid != 0 ) @@ -68,13 +67,21 @@ void cJSON_unregister(cJSON *item) }*/ n++; } - printf("total %d cJSON pending %s\n",n,mbstr(str,total)); + printf("total %d cJSON pending\n",n); lasttime = (uint32_t)time(NULL); } DL_FOREACH_SAFE(LP_cJSONlist,ptr,tmp) { - if ( ptr->cjsonid == item->cjsonid )//ptr->item == item ) + if ( ptr->item == item ) break; + else if ( now > ptr->timestamp+60 ) + { + portable_mutex_lock(&LP_cJSONmutex); + DL_DELETE(LP_cJSONlist,ptr); + portable_mutex_unlock(&LP_cJSONmutex); + cJSON_Delete(ptr->item); + free(ptr); + } ptr = 0; } if ( ptr != 0 ) From 02df7289d30f72ab6d33331aeba4808a012da5ec Mon Sep 17 00:00:00 2001 From: jl777 Date: Wed, 15 Nov 2017 15:10:11 +0200 Subject: [PATCH 0814/1664] Test --- iguana/exchanges/LP_utxo.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/iguana/exchanges/LP_utxo.c b/iguana/exchanges/LP_utxo.c index 8512572e6..4b0828a3b 100644 --- a/iguana/exchanges/LP_utxo.c +++ b/iguana/exchanges/LP_utxo.c @@ -79,6 +79,7 @@ void cJSON_unregister(cJSON *item) portable_mutex_lock(&LP_cJSONmutex); DL_DELETE(LP_cJSONlist,ptr); portable_mutex_unlock(&LP_cJSONmutex); + printf("free expired\n"); cJSON_Delete(ptr->item); free(ptr); } @@ -90,7 +91,7 @@ void cJSON_unregister(cJSON *item) DL_DELETE(LP_cJSONlist,ptr); free(ptr); portable_mutex_unlock(&LP_cJSONmutex); - } else printf("cJSON_unregister of unknown %p %u\n",item,item->cjsonid); + } //else printf("cJSON_unregister of unknown %p %u\n",item,item->cjsonid); } struct LP_inuse_info *_LP_inuse_find(bits256 txid,int32_t vout) From 49c0feed90b0686b8210d85d8d808e09f2240e19 Mon Sep 17 00:00:00 2001 From: jl777 Date: Wed, 15 Nov 2017 15:12:56 +0200 Subject: [PATCH 0815/1664] Test --- iguana/exchanges/LP_utxo.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/iguana/exchanges/LP_utxo.c b/iguana/exchanges/LP_utxo.c index 4b0828a3b..1befc1dcf 100644 --- a/iguana/exchanges/LP_utxo.c +++ b/iguana/exchanges/LP_utxo.c @@ -72,9 +72,9 @@ void cJSON_unregister(cJSON *item) } DL_FOREACH_SAFE(LP_cJSONlist,ptr,tmp) { - if ( ptr->item == item ) + if ( ptr->cjsonid == item->cjsonid ) break; - else if ( now > ptr->timestamp+60 ) + else if ( now > ptr->timestamp+60 && item->cjsonid != 0 ) { portable_mutex_lock(&LP_cJSONmutex); DL_DELETE(LP_cJSONlist,ptr); From bea2f74a87beb53592f02099935c6b01a883853b Mon Sep 17 00:00:00 2001 From: jl777 Date: Wed, 15 Nov 2017 15:16:16 +0200 Subject: [PATCH 0816/1664] Test --- crypto777/cJSON.c | 18 +++++++++--------- iguana/m_mm | 2 +- 2 files changed, 10 insertions(+), 10 deletions(-) diff --git a/crypto777/cJSON.c b/crypto777/cJSON.c index 555fdf29c..93438fe79 100755 --- a/crypto777/cJSON.c +++ b/crypto777/cJSON.c @@ -1132,9 +1132,9 @@ cJSON *cJSON_CreateArray(void) cJSON *item = cJSON_New_Item(); if ( item ) item->type = cJSON_Array; -#ifdef CJSON_GARBAGECOLLECTION - cJSON_register(item); -#endif +//#ifdef CJSON_GARBAGECOLLECTION +// cJSON_register(item); +//#endif return(item); } @@ -1143,17 +1143,17 @@ cJSON *cJSON_CreateObject(void) cJSON *item = cJSON_New_Item(); if ( item ) item->type = cJSON_Object; -#ifdef CJSON_GARBAGECOLLECTION - cJSON_register(item); -#endif +//#ifdef CJSON_GARBAGECOLLECTION +// cJSON_register(item); +//#endif return item; } void free_json(cJSON *item) { -#ifdef CJSON_GARBAGECOLLECTION - cJSON_unregister(item); -#endif +//#ifdef CJSON_GARBAGECOLLECTION +// cJSON_unregister(item); +//#endif if ( item != 0 ) cJSON_Delete(item); } diff --git a/iguana/m_mm b/iguana/m_mm index 0609d842c..36a0acad1 100755 --- a/iguana/m_mm +++ b/iguana/m_mm @@ -1,3 +1,3 @@ cd secp256k1; ./m_unix; cd .. cd ../crypto777; ./m_LP; cd ../iguana -gcc -DCJSON_GARBAGECOLLECTION -g -o marketmaker -I../crypto777 exchanges/mm.c ../crypto777/cJSON.c mini-gmp.c secp256k1.o ../agents/libcrypto777.a -lnanomsg -lcurl -lpthread -lm +gcc -g -o marketmaker -I../crypto777 exchanges/mm.c ../crypto777/cJSON.c mini-gmp.c secp256k1.o ../agents/libcrypto777.a -lnanomsg -lcurl -lpthread -lm From b435fe804c7af8da3ce399b9320346f851a2cf5c Mon Sep 17 00:00:00 2001 From: jl777 Date: Wed, 15 Nov 2017 15:18:53 +0200 Subject: [PATCH 0817/1664] Test --- iguana/exchanges/LP_commands.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/iguana/exchanges/LP_commands.c b/iguana/exchanges/LP_commands.c index 56ed047e4..a241aa4ab 100644 --- a/iguana/exchanges/LP_commands.c +++ b/iguana/exchanges/LP_commands.c @@ -35,7 +35,9 @@ char *LP_numutxos() char *stats_JSON(void *ctx,char *myipaddr,int32_t pubsock,cJSON *argjson,char *remoteaddr,uint16_t port) // from rpc port { char *method,*userpass,*base,*rel,*coin,*retstr = 0; int32_t changed,flag = 0; cJSON *retjson,*reqjson = 0; struct iguana_info *ptr; - //printf("stats_JSON(%s)\n",jprint(argjson,0)); + retstr = jprint(argjson,0); + printf("stats_JSON(%s)\n",retstr); + free(retstr), retstr = 0; method = jstr(argjson,"method"); /*if ( (ipaddr= jstr(argjson,"ipaddr")) != 0 && (argport= juint(argjson,"port")) != 0 && (method == 0 || strcmp(method,"electrum") != 0) ) { From cd61cdb07f517ed47b0294890917cc67ae8bb53d Mon Sep 17 00:00:00 2001 From: jl777 Date: Wed, 15 Nov 2017 15:25:35 +0200 Subject: [PATCH 0818/1664] Test --- iguana/exchanges/LP_commands.c | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/iguana/exchanges/LP_commands.c b/iguana/exchanges/LP_commands.c index a241aa4ab..b06fab289 100644 --- a/iguana/exchanges/LP_commands.c +++ b/iguana/exchanges/LP_commands.c @@ -35,10 +35,12 @@ char *LP_numutxos() char *stats_JSON(void *ctx,char *myipaddr,int32_t pubsock,cJSON *argjson,char *remoteaddr,uint16_t port) // from rpc port { char *method,*userpass,*base,*rel,*coin,*retstr = 0; int32_t changed,flag = 0; cJSON *retjson,*reqjson = 0; struct iguana_info *ptr; - retstr = jprint(argjson,0); - printf("stats_JSON(%s)\n",retstr); - free(retstr), retstr = 0; - method = jstr(argjson,"method"); +retstr = jprint(argjson,0); +printf("stats_JSON(%s)\n",retstr); +free(retstr), retstr = 0; +method = jstr(argjson,"method"); +if ( strcmp(method,"uitem") == 0 || strcmp(method,"postutxos") == 0 ) + return(clonestr("{}")); /*if ( (ipaddr= jstr(argjson,"ipaddr")) != 0 && (argport= juint(argjson,"port")) != 0 && (method == 0 || strcmp(method,"electrum") != 0) ) { if ( strcmp(ipaddr,"127.0.0.1") != 0 && argport >= 1000 ) From db088b68ae6cafedf1e013d802ddc030ec2ecaea Mon Sep 17 00:00:00 2001 From: jl777 Date: Wed, 15 Nov 2017 15:28:56 +0200 Subject: [PATCH 0819/1664] Test --- iguana/exchanges/LP_commands.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/iguana/exchanges/LP_commands.c b/iguana/exchanges/LP_commands.c index b06fab289..c583c5346 100644 --- a/iguana/exchanges/LP_commands.c +++ b/iguana/exchanges/LP_commands.c @@ -35,12 +35,12 @@ char *LP_numutxos() char *stats_JSON(void *ctx,char *myipaddr,int32_t pubsock,cJSON *argjson,char *remoteaddr,uint16_t port) // from rpc port { char *method,*userpass,*base,*rel,*coin,*retstr = 0; int32_t changed,flag = 0; cJSON *retjson,*reqjson = 0; struct iguana_info *ptr; -retstr = jprint(argjson,0); -printf("stats_JSON(%s)\n",retstr); -free(retstr), retstr = 0; method = jstr(argjson,"method"); if ( strcmp(method,"uitem") == 0 || strcmp(method,"postutxos") == 0 ) return(clonestr("{}")); +retstr = jprint(argjson,0); +printf("stats_JSON(%s)\n",retstr); +free(retstr), retstr = 0; /*if ( (ipaddr= jstr(argjson,"ipaddr")) != 0 && (argport= juint(argjson,"port")) != 0 && (method == 0 || strcmp(method,"electrum") != 0) ) { if ( strcmp(ipaddr,"127.0.0.1") != 0 && argport >= 1000 ) From ecce4d9c0855bc60f49b675836b7ea4ba5272383 Mon Sep 17 00:00:00 2001 From: jl777 Date: Wed, 15 Nov 2017 15:49:57 +0200 Subject: [PATCH 0820/1664] Test --- iguana/exchanges/LP_commands.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/iguana/exchanges/LP_commands.c b/iguana/exchanges/LP_commands.c index c583c5346..d4487782d 100644 --- a/iguana/exchanges/LP_commands.c +++ b/iguana/exchanges/LP_commands.c @@ -36,7 +36,9 @@ char *stats_JSON(void *ctx,char *myipaddr,int32_t pubsock,cJSON *argjson,char *r { char *method,*userpass,*base,*rel,*coin,*retstr = 0; int32_t changed,flag = 0; cJSON *retjson,*reqjson = 0; struct iguana_info *ptr; method = jstr(argjson,"method"); -if ( strcmp(method,"uitem") == 0 || strcmp(method,"postutxos") == 0 ) +if ( strcmp(method,"uitem") == 0 || strcmp(method,"postutxos") == 0 + || strcmp(method,"notify") == 0 || strcmp(method,"postprice") == 0 + ) return(clonestr("{}")); retstr = jprint(argjson,0); printf("stats_JSON(%s)\n",retstr); From 3843e3d1e843b7cc034f8b2fad849016c976f60f Mon Sep 17 00:00:00 2001 From: jl777 Date: Wed, 15 Nov 2017 16:02:17 +0200 Subject: [PATCH 0821/1664] Test --- iguana/exchanges/LP_commands.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/iguana/exchanges/LP_commands.c b/iguana/exchanges/LP_commands.c index d4487782d..fdc2bc6ff 100644 --- a/iguana/exchanges/LP_commands.c +++ b/iguana/exchanges/LP_commands.c @@ -37,7 +37,8 @@ char *stats_JSON(void *ctx,char *myipaddr,int32_t pubsock,cJSON *argjson,char *r char *method,*userpass,*base,*rel,*coin,*retstr = 0; int32_t changed,flag = 0; cJSON *retjson,*reqjson = 0; struct iguana_info *ptr; method = jstr(argjson,"method"); if ( strcmp(method,"uitem") == 0 || strcmp(method,"postutxos") == 0 - || strcmp(method,"notify") == 0 || strcmp(method,"postprice") == 0 + || strcmp(method,"notify") == 0 + //|| strcmp(method,"postprice") == 0 ) return(clonestr("{}")); retstr = jprint(argjson,0); From 48623418bbeafdae3cc01059f872e52811e3a416 Mon Sep 17 00:00:00 2001 From: jl777 Date: Wed, 15 Nov 2017 16:04:05 +0200 Subject: [PATCH 0822/1664] Test --- iguana/exchanges/LP_commands.c | 7 ++----- 1 file changed, 2 insertions(+), 5 deletions(-) diff --git a/iguana/exchanges/LP_commands.c b/iguana/exchanges/LP_commands.c index fdc2bc6ff..3fc34e752 100644 --- a/iguana/exchanges/LP_commands.c +++ b/iguana/exchanges/LP_commands.c @@ -36,14 +36,11 @@ char *stats_JSON(void *ctx,char *myipaddr,int32_t pubsock,cJSON *argjson,char *r { char *method,*userpass,*base,*rel,*coin,*retstr = 0; int32_t changed,flag = 0; cJSON *retjson,*reqjson = 0; struct iguana_info *ptr; method = jstr(argjson,"method"); -if ( strcmp(method,"uitem") == 0 || strcmp(method,"postutxos") == 0 - || strcmp(method,"notify") == 0 +if ( //strcmp(method,"uitem") == 0 || strcmp(method,"postutxos") == 0 || + strcmp(method,"notify") == 0 //|| strcmp(method,"postprice") == 0 ) return(clonestr("{}")); -retstr = jprint(argjson,0); -printf("stats_JSON(%s)\n",retstr); -free(retstr), retstr = 0; /*if ( (ipaddr= jstr(argjson,"ipaddr")) != 0 && (argport= juint(argjson,"port")) != 0 && (method == 0 || strcmp(method,"electrum") != 0) ) { if ( strcmp(ipaddr,"127.0.0.1") != 0 && argport >= 1000 ) From 12a6db1ac053c50ca87cde167292b5df8f11dcfc Mon Sep 17 00:00:00 2001 From: jl777 Date: Wed, 15 Nov 2017 16:06:28 +0200 Subject: [PATCH 0823/1664] Test --- iguana/exchanges/LP_commands.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/iguana/exchanges/LP_commands.c b/iguana/exchanges/LP_commands.c index 3fc34e752..40f7151c3 100644 --- a/iguana/exchanges/LP_commands.c +++ b/iguana/exchanges/LP_commands.c @@ -38,7 +38,7 @@ char *stats_JSON(void *ctx,char *myipaddr,int32_t pubsock,cJSON *argjson,char *r method = jstr(argjson,"method"); if ( //strcmp(method,"uitem") == 0 || strcmp(method,"postutxos") == 0 || strcmp(method,"notify") == 0 - //|| strcmp(method,"postprice") == 0 + || strcmp(method,"postprice") == 0 ) return(clonestr("{}")); /*if ( (ipaddr= jstr(argjson,"ipaddr")) != 0 && (argport= juint(argjson,"port")) != 0 && (method == 0 || strcmp(method,"electrum") != 0) ) From 8743a5701fb5265647f5f03f36e1dccfd9074061 Mon Sep 17 00:00:00 2001 From: jl777 Date: Wed, 15 Nov 2017 16:37:34 +0200 Subject: [PATCH 0824/1664] Test --- iguana/exchanges/LP_cache.c | 6 +++--- iguana/exchanges/LP_commands.c | 6 +++--- iguana/exchanges/LP_swap.c | 2 +- 3 files changed, 7 insertions(+), 7 deletions(-) diff --git a/iguana/exchanges/LP_cache.c b/iguana/exchanges/LP_cache.c index a08828966..fdc734fe9 100644 --- a/iguana/exchanges/LP_cache.c +++ b/iguana/exchanges/LP_cache.c @@ -45,10 +45,10 @@ struct LP_transaction *LP_create_transaction(struct iguana_info *coin,bits256 tx vins = jarray(&numvins,txobj,"vin"); vouts = jarray(&numvouts,txobj,"vout"); tx = LP_transactionadd(coin,txid,height,numvouts,numvins); - tx->serialized = serialized; - //free(serialized); + tx->serialized = 0;//serialized; + free(serialized); tx->fpos = fpos; - tx->len = tx->len; + tx->len = 0;//tx->len; tx->SPV = tx->height = height; //printf("tx.%s numvins.%d numvouts.%d\n",bits256_str(str,txid),numvins,numvouts); for (i=0; i= 1000 ) diff --git a/iguana/exchanges/LP_swap.c b/iguana/exchanges/LP_swap.c index 03d08d69e..7e31d21e8 100644 --- a/iguana/exchanges/LP_swap.c +++ b/iguana/exchanges/LP_swap.c @@ -895,7 +895,7 @@ void LP_aliceloop(void *_swap) } basilisk_swap_finished(swap); printf("finish swap.%p\n",swap); - //free(swap); + free(swap); G.LP_pendingswaps--; } From 6b98102ea39de321667e0dac15bc985fc70bf047 Mon Sep 17 00:00:00 2001 From: jl777 Date: Wed, 15 Nov 2017 16:39:27 +0200 Subject: [PATCH 0825/1664] Test --- iguana/exchanges/LP_utxo.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/iguana/exchanges/LP_utxo.c b/iguana/exchanges/LP_utxo.c index 1befc1dcf..da6f97cc1 100644 --- a/iguana/exchanges/LP_utxo.c +++ b/iguana/exchanges/LP_utxo.c @@ -51,20 +51,20 @@ char *mbstr(char *str,double n); void cJSON_unregister(cJSON *item) { static uint32_t lasttime; - int32_t n; struct cJSON_list *ptr,*tmp; uint32_t now; - if ( (now= time(NULL)) > lasttime+6 ) + int32_t n; char *tmpstr; uint64_t total = 0; struct cJSON_list *ptr,*tmp; uint32_t now; + if ( (now= (uint32_t)time(NULL)) > lasttime+6 ) { n = 0; DL_FOREACH_SAFE(LP_cJSONlist,ptr,tmp) { - /*if ( ptr->item != 0 && ptr->item->child != 0 && ptr->cjsonid != 0 ) + if ( ptr->item != 0 && ptr->item->child != 0 && ptr->cjsonid != 0 ) { if ( (tmpstr= jprint(ptr->item,0)) != 0 ) { total += strlen(tmpstr); free(tmpstr); } - }*/ + } n++; } printf("total %d cJSON pending\n",n); From 3ef3f0603e5519e6f4c9e393270f272cf81f72c7 Mon Sep 17 00:00:00 2001 From: DeckerSU Date: Wed, 15 Nov 2017 18:45:53 +0400 Subject: [PATCH 0826/1664] added batch script to automate Windows builds (both 32/64-bit) script can be used to automate Windows builds of marketmaker using MSVC 2015 without jenkins. just follow to repo directory and launch marketmaker_build_32_64.cmd . It will generate 32-bit and 64-bit executables in Release and x64/Release directories. Also it has example how to add executables into archive. You can add any custom automate actions, for example, put archive with release on FTP, or syncing it somewhere with rsync, or any other. --- marketmaker_build_32_64.cmd | 47 +++++++++++++++++++++++++++++++++++++ 1 file changed, 47 insertions(+) create mode 100644 marketmaker_build_32_64.cmd diff --git a/marketmaker_build_32_64.cmd b/marketmaker_build_32_64.cmd new file mode 100644 index 000000000..bac8df5e0 --- /dev/null +++ b/marketmaker_build_32_64.cmd @@ -0,0 +1,47 @@ +@echo off + +@REM Check for Visual Studio +call set "VSPATH=" +if defined VS140COMNTOOLS ( if not defined VSPATH ( + call set "VSPATH=%%VS140COMNTOOLS%%" +) ) + +@REM check if we already have the tools in the environment +if exist "%VCINSTALLDIR%" ( + goto compile +) + +if not defined VSPATH ( + echo You need Microsoft Visual Studio 15 installed + pause + exit +) + +@REM set up the environment +if exist "%VSPATH%..\..\vc\vcvarsall.bat" ( + call "%%VSPATH%%..\..\vc\vcvarsall.bat" amd64 + goto compile +) + +echo Unable to set up the environment +pause +exit + +:compile +rem MSBuild /help +MSBuild marketmaker.sln /t:Rebuild /p:Configuration=Release /p:Platform=x64 +MSBuild marketmaker.sln /t:Rebuild /p:Configuration=Release /p:Platform=x86 + +rem Using to add in marketmaker_release.7z +set host=%COMPUTERNAME% +IF "%host%"=="VM-81" ( + mkdir package_content\win32 + mkdir package_content\win64 + copy /y Release\marketmaker.exe package_content\win32 + copy /y x64\Release\marketmaker.exe package_content\win64 + cd package_content + "C:\Program Files\7-Zip\7z.exe" a C:\komodo\marketmaker_release\marketmaker_release.7z win32\marketmaker.exe + "C:\Program Files\7-Zip\7z.exe" a C:\komodo\marketmaker_release\marketmaker_release.7z win64\marketmaker.exe + cd .. + rd package_content /s /q + ) From 86e95d081609a713cd77fd95f73e3c051e879522 Mon Sep 17 00:00:00 2001 From: DeckerSU Date: Wed, 15 Nov 2017 19:33:33 +0400 Subject: [PATCH 0827/1664] added new examples of dexscripts for windows and updated it's description --- iguana/dexscripts.win32/bot_buy.cmd | 7 ++++ iguana/dexscripts.win32/bot_list.cmd | 7 ++++ iguana/dexscripts.win32/bot_statuslist.cmd | 7 ++++ iguana/dexscripts.win32/bot_stop.cmd | 7 ++++ iguana/dexscripts.win32/electrum.cmd | 9 +++++ iguana/dexscripts.win32/help.cmd | 2 ++ iguana/dexscripts.win32/how_to_use.md | 33 +++++++++++++++++++ .../dexscripts.win32/sendrawtransaction.cmd | 5 +++ iguana/dexscripts.win32/withdraw.cmd | 8 +++++ iguana/dexscripts.win32/withdraw_10_send.cmd | 14 ++++++++ iguana/dexscripts.win32/withdraw_send.cmd | 14 ++++++++ 11 files changed, 113 insertions(+) create mode 100644 iguana/dexscripts.win32/bot_buy.cmd create mode 100644 iguana/dexscripts.win32/bot_list.cmd create mode 100644 iguana/dexscripts.win32/bot_statuslist.cmd create mode 100644 iguana/dexscripts.win32/bot_stop.cmd create mode 100644 iguana/dexscripts.win32/electrum.cmd create mode 100644 iguana/dexscripts.win32/help.cmd create mode 100644 iguana/dexscripts.win32/sendrawtransaction.cmd create mode 100644 iguana/dexscripts.win32/withdraw.cmd create mode 100644 iguana/dexscripts.win32/withdraw_10_send.cmd create mode 100644 iguana/dexscripts.win32/withdraw_send.cmd diff --git a/iguana/dexscripts.win32/bot_buy.cmd b/iguana/dexscripts.win32/bot_buy.cmd new file mode 100644 index 000000000..641ef1d7b --- /dev/null +++ b/iguana/dexscripts.win32/bot_buy.cmd @@ -0,0 +1,7 @@ +@echo off +set /p TMPUSERPASS= UTXO PAIRS to understand the basics. This script is just for example how you can split your coins in (X, X/777) to start trading them. + ## F.A.Q. ## **Q.** Is any simple way how i can display JSON results returned by all scripts, like orderbook and others, in human readable form? + **A.** Yes, you can use this service [JSON Editor Online](http://jsoneditoronline.org/), just copy and paste output of script in left column and see structured output in right. **Q.** I see an output like this when i'm start `1-client.cmd` : @@ -43,6 +75,7 @@ And nothing works. **A.** Before run `1-client.cmd` make sure in Task Manager that you haven't already running `marketmaker.exe`. If have - kill this process via Task Manager or via command line command `taskkill /f /im taskkill.exe` . **Q.** How can i pretty print JSON answers of marketmaker? + **A.** You can get best results with 2 tools - [conemu](https://conemu.github.io/) and [jq](https://stedolan.github.io/jq/), conemu supports ANSI X3.64 and Xterm 256 colors and jq allow you to pretty-print json output with colors, like this: ![](./images/conemu_jq.png) diff --git a/iguana/dexscripts.win32/sendrawtransaction.cmd b/iguana/dexscripts.win32/sendrawtransaction.cmd new file mode 100644 index 000000000..a19d77355 --- /dev/null +++ b/iguana/dexscripts.win32/sendrawtransaction.cmd @@ -0,0 +1,5 @@ +@echo off +set /p TMPUSERPASS= withdraw.txt +type withdraw.txt diff --git a/iguana/dexscripts.win32/withdraw_10_send.cmd b/iguana/dexscripts.win32/withdraw_10_send.cmd new file mode 100644 index 000000000..44a947787 --- /dev/null +++ b/iguana/dexscripts.win32/withdraw_10_send.cmd @@ -0,0 +1,14 @@ +@echo off +set /p TMPUSERPASS= withdraw.txt +type withdraw.txt +timeout /t 5 /nobreak +for /f "tokens=4 delims=:," %%a in (' find "hex" "withdraw.txt" ') do ( +rem echo [%%~a] +curl -s --url "http://127.0.0.1:7783" --data "{\"userpass\":\"%USERPASS%\",\"method\":\"sendrawtransaction\",\"coin\":\"%COIN%\",\"signedtx\":\"%%~a\"}" +) diff --git a/iguana/dexscripts.win32/withdraw_send.cmd b/iguana/dexscripts.win32/withdraw_send.cmd new file mode 100644 index 000000000..a26b9bf56 --- /dev/null +++ b/iguana/dexscripts.win32/withdraw_send.cmd @@ -0,0 +1,14 @@ +@echo off +set /p TMPUSERPASS= withdraw.txt +type withdraw.txt +timeout /t 5 /nobreak +for /f "tokens=4 delims=:," %%a in (' find "hex" "withdraw.txt" ') do ( +rem echo [%%~a] +curl -s --url "http://127.0.0.1:7783" --data "{\"userpass\":\"%USERPASS%\",\"method\":\"sendrawtransaction\",\"coin\":\"%COIN%\",\"signedtx\":\"%%~a\"}" +) + From 39d2c7a879c5cdfd281322b45ecf14b82730b60c Mon Sep 17 00:00:00 2001 From: DeckerSU Date: Wed, 15 Nov 2017 19:56:36 +0400 Subject: [PATCH 0828/1664] append faq (q/a: required dlls) --- iguana/dexscripts.win32/how_to_use.md | 19 ++++++++++++++++++- 1 file changed, 18 insertions(+), 1 deletion(-) diff --git a/iguana/dexscripts.win32/how_to_use.md b/iguana/dexscripts.win32/how_to_use.md index e04c14ac1..27b8af5be 100644 --- a/iguana/dexscripts.win32/how_to_use.md +++ b/iguana/dexscripts.win32/how_to_use.md @@ -80,4 +80,21 @@ And nothing works. ![](./images/conemu_jq.png) -Also i'm always recommend to install [Far Manager](https://www.farmanager.com/index.php?l=en) - this is powerful console file manager for Windows, like Midnight Commander in *nix. \ No newline at end of file +Also i'm always recommend to install [Far Manager](https://www.farmanager.com/index.php?l=en) - this is powerful console file manager for Windows, like Midnight Commander in *nix. + +**Q.** What additional dependencies required by marketmaker? + +**A.** Currently marketmaker (Windows) used the following DLLs: + +*32 bit:* +- libcrypto-1_1.dll +- libcurl.dll +- libssl-1_1.dll +- nanomsg.dll +- pthreadvc2.dll + +*64-bit:* +- libcurl.dll +- nanomsg.dll + +It already included in repo and in archive with release. \ No newline at end of file From 496a89c6aa32867a7f232aa49df69d26e932927a Mon Sep 17 00:00:00 2001 From: jl777 Date: Wed, 15 Nov 2017 18:30:29 +0200 Subject: [PATCH 0829/1664] Test --- iguana/exchanges/LP_nativeDEX.c | 13 +++++++++---- 1 file changed, 9 insertions(+), 4 deletions(-) diff --git a/iguana/exchanges/LP_nativeDEX.c b/iguana/exchanges/LP_nativeDEX.c index c7ba59d0b..6f90ed93c 100644 --- a/iguana/exchanges/LP_nativeDEX.c +++ b/iguana/exchanges/LP_nativeDEX.c @@ -17,7 +17,6 @@ // LP_nativeDEX.c // marketmaker // -// gc cJSON // more retries for swap sendrawtransaction? // pbca26 unfinished swaps // if ( G.LP_pendingswaps != 0 ) return(-1); @@ -327,7 +326,7 @@ char *LP_process_message(void *ctx,char *typestr,char *myipaddr,int32_t pubsock, int32_t LP_sock_check(char *typestr,void *ctx,char *myipaddr,int32_t pubsock,int32_t sock,char *remoteaddr,int32_t maxdepth) { - int32_t recvlen=1,nonz = 0; cJSON *argjson; void *ptr; char methodstr[64],*retstr,*str; struct nn_pollfd pfd; + int32_t recvlen=1,nonz = 0; cJSON *argjson; void *ptr,*buf; char methodstr[64],*retstr,*str; struct nn_pollfd pfd; if ( sock >= 0 ) { while ( nonz < maxdepth && recvlen > 0 ) @@ -339,8 +338,11 @@ int32_t LP_sock_check(char *typestr,void *ctx,char *myipaddr,int32_t pubsock,int if ( nn_poll(&pfd,1,1) != 1 ) break; ptr = 0; - if ( (recvlen= nn_recv(sock,&ptr,NN_MSG,0)) > 0 ) + buf = malloc(1000000); + if ( (recvlen= nn_recv(sock,buf,1000000,0)) > 0 ) + //if ( (recvlen= nn_recv(sock,&ptr,NN_MSG,0)) > 0 ) { + ptr = buf; methodstr[0] = 0; //printf("%s.(%s)\n",typestr,(char *)ptr); if ( 0 ) @@ -390,7 +392,10 @@ int32_t LP_sock_check(char *typestr,void *ctx,char *myipaddr,int32_t pubsock,int } } if ( ptr != 0 ) - nn_freemsg(ptr), ptr = 0; + { + //nn_freemsg(ptr), ptr = 0; + free(buf); + } } } return(nonz); From 401f4d8a35f67ceeb4ca8a2b134ac1f158f75b84 Mon Sep 17 00:00:00 2001 From: jl777 Date: Wed, 15 Nov 2017 18:58:29 +0200 Subject: [PATCH 0830/1664] Require requestid/quoteid match --- iguana/exchanges/LP_swap.c | 15 ++++++++++++--- iguana/exchanges/mm.c | 5 +++++ 2 files changed, 17 insertions(+), 3 deletions(-) diff --git a/iguana/exchanges/LP_swap.c b/iguana/exchanges/LP_swap.c index 7e31d21e8..f551b862b 100644 --- a/iguana/exchanges/LP_swap.c +++ b/iguana/exchanges/LP_swap.c @@ -187,6 +187,8 @@ 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; + datalen += iguana_rwnum(1,&data[datalen],sizeof(swap->I.req.requestid),&swap->I.req.requestid); + datalen += iguana_rwnum(1,&data[datalen],sizeof(swap->I.req.quoteid),&swap->I.req.quoteid); data[datalen++] = swap->I.aliceconfirms; data[datalen++] = swap->I.bobconfirms; data[datalen++] = swap->I.alicemaxconfirms; @@ -201,9 +203,16 @@ 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,alicemaxconfirms,bobmaxconfirms,aliceconfirms,bobconfirms,len = 0; uint8_t other33[33]; - if ( datalen == sizeof(swap->otherdeck)+38 ) + uint32_t requestid,quoteid; int32_t i,nonz=0,alicemaxconfirms,bobmaxconfirms,aliceconfirms,bobconfirms,len = 0; uint8_t other33[33]; + if ( datalen == sizeof(swap->otherdeck)+38+sizeof(uint32_t)*2 ) { + datalen += iguana_rwnum(0,&data[len],sizeof(requestid),&requestid); + datalen += iguana_rwnum(0,&data[len],sizeof(quoteid),"eid); + if ( requestid != swap->I.req.requestid || quoteid != swap->I.req.quoteid ) + { + printf("SWAP requestid.%u quoteid.%u mismatch received r.%u q.%u\n",swap->I.req.requestid,swap->I.req.quoteid,requestid,quoteid); + return(-1); + } aliceconfirms = data[len++]; bobconfirms = data[len++]; alicemaxconfirms = data[len++]; @@ -243,7 +252,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)+36); + printf("pubkeys verify size mismatch %d != %d\n",datalen,(int32_t)sizeof(swap->otherdeck)+38+sizeof(uint32_t)*2); return(-1); } diff --git a/iguana/exchanges/mm.c b/iguana/exchanges/mm.c index e20b1dcb6..f906390b8 100644 --- a/iguana/exchanges/mm.c +++ b/iguana/exchanges/mm.c @@ -19,6 +19,11 @@ // Copyright © 2017 SuperNET. All rights reserved. // +/* +#define malloc(n) LP_alloc(n) +#define calloc(a,b) LP_alloc((uint64_t)(a) * (b)) +#define free(ptr) LP_free(ptr)*/ + void PNACL_message(char *arg,...) { From cb8cdd25980f5f3117d0c97494cf064711df1c5d Mon Sep 17 00:00:00 2001 From: jl777 Date: Wed, 15 Nov 2017 19:11:05 +0200 Subject: [PATCH 0831/1664] Test --- iguana/exchanges/LP_swap.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/iguana/exchanges/LP_swap.c b/iguana/exchanges/LP_swap.c index f551b862b..1b6a17ab3 100644 --- a/iguana/exchanges/LP_swap.c +++ b/iguana/exchanges/LP_swap.c @@ -206,8 +206,8 @@ int32_t LP_pubkeys_verify(struct basilisk_swap *swap,uint8_t *data,int32_t datal uint32_t requestid,quoteid; int32_t i,nonz=0,alicemaxconfirms,bobmaxconfirms,aliceconfirms,bobconfirms,len = 0; uint8_t other33[33]; if ( datalen == sizeof(swap->otherdeck)+38+sizeof(uint32_t)*2 ) { - datalen += iguana_rwnum(0,&data[len],sizeof(requestid),&requestid); - datalen += iguana_rwnum(0,&data[len],sizeof(quoteid),"eid); + len += iguana_rwnum(0,&data[len],sizeof(requestid),&requestid); + len += iguana_rwnum(0,&data[len],sizeof(quoteid),"eid); if ( requestid != swap->I.req.requestid || quoteid != swap->I.req.quoteid ) { printf("SWAP requestid.%u quoteid.%u mismatch received r.%u q.%u\n",swap->I.req.requestid,swap->I.req.quoteid,requestid,quoteid); @@ -252,7 +252,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)+38+sizeof(uint32_t)*2); + printf("pubkeys verify size mismatch %d != %d\n",datalen,(int32_t)(sizeof(swap->otherdeck)+38+sizeof(uint32_t)*2)); return(-1); } From a3d3b00649f363abf262567b47eed4f00cee86f5 Mon Sep 17 00:00:00 2001 From: jl777 Date: Wed, 15 Nov 2017 19:15:09 +0200 Subject: [PATCH 0832/1664] Test --- iguana/exchanges/LP_swap.c | 1 + 1 file changed, 1 insertion(+) diff --git a/iguana/exchanges/LP_swap.c b/iguana/exchanges/LP_swap.c index 1b6a17ab3..616ee46f7 100644 --- a/iguana/exchanges/LP_swap.c +++ b/iguana/exchanges/LP_swap.c @@ -189,6 +189,7 @@ int32_t LP_pubkeys_data(struct basilisk_swap *swap,uint8_t *data,int32_t maxlen) int32_t i,datalen = 0; datalen += iguana_rwnum(1,&data[datalen],sizeof(swap->I.req.requestid),&swap->I.req.requestid); datalen += iguana_rwnum(1,&data[datalen],sizeof(swap->I.req.quoteid),&swap->I.req.quoteid); + printf("send >>>>>>>>> r.%u q.%u\n",swap->I.req.requestid,swap->I.req.quoteid); data[datalen++] = swap->I.aliceconfirms; data[datalen++] = swap->I.bobconfirms; data[datalen++] = swap->I.alicemaxconfirms; From 46bd310f62dd4b7ae47ac79ae0079f5602415c3b Mon Sep 17 00:00:00 2001 From: jl777 Date: Wed, 15 Nov 2017 19:19:53 +0200 Subject: [PATCH 0833/1664] Test --- iguana/exchanges/LP_swap.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/iguana/exchanges/LP_swap.c b/iguana/exchanges/LP_swap.c index 616ee46f7..1002517b0 100644 --- a/iguana/exchanges/LP_swap.c +++ b/iguana/exchanges/LP_swap.c @@ -189,7 +189,6 @@ int32_t LP_pubkeys_data(struct basilisk_swap *swap,uint8_t *data,int32_t maxlen) int32_t i,datalen = 0; datalen += iguana_rwnum(1,&data[datalen],sizeof(swap->I.req.requestid),&swap->I.req.requestid); datalen += iguana_rwnum(1,&data[datalen],sizeof(swap->I.req.quoteid),&swap->I.req.quoteid); - printf("send >>>>>>>>> r.%u q.%u\n",swap->I.req.requestid,swap->I.req.quoteid); data[datalen++] = swap->I.aliceconfirms; data[datalen++] = swap->I.bobconfirms; data[datalen++] = swap->I.alicemaxconfirms; @@ -199,6 +198,7 @@ int32_t LP_pubkeys_data(struct basilisk_swap *swap,uint8_t *data,int32_t maxlen) data[datalen++] = swap->persistent_pubkey33[i]; for (i=0; ideck)/sizeof(swap->deck[0][0]); i++) datalen += iguana_rwnum(1,&data[datalen],sizeof(swap->deck[i>>1][i&1]),&swap->deck[i>>1][i&1]); + printf("send >>>>>>>>> r.%u q.%u datalen.%d\n",swap->I.req.requestid,swap->I.req.quoteid,datalen); return(datalen); } From 3a84ed7eb6ee140ebbab59cb3e0deec871fa1c43 Mon Sep 17 00:00:00 2001 From: jl777 Date: Wed, 15 Nov 2017 19:39:16 +0200 Subject: [PATCH 0834/1664] Test --- iguana/exchanges/LP_include.h | 2 +- iguana/exchanges/LP_ordermatch.c | 11 ++++++++++ iguana/exchanges/LP_remember.c | 37 ++++++++++++++++++++++++++++++++ 3 files changed, 49 insertions(+), 1 deletion(-) diff --git a/iguana/exchanges/LP_include.h b/iguana/exchanges/LP_include.h index 5e530f9c1..b1a78c694 100644 --- a/iguana/exchanges/LP_include.h +++ b/iguana/exchanges/LP_include.h @@ -23,7 +23,7 @@ #define LP_MAJOR_VERSION "0" #define LP_MINOR_VERSION "1" -#define LP_BUILD_NUMBER "14414" +#define LP_BUILD_NUMBER "14498" #ifdef FROM_JS #include diff --git a/iguana/exchanges/LP_ordermatch.c b/iguana/exchanges/LP_ordermatch.c index 0ab6faca0..7d60f336d 100644 --- a/iguana/exchanges/LP_ordermatch.c +++ b/iguana/exchanges/LP_ordermatch.c @@ -449,6 +449,11 @@ int32_t LP_connectstartbob(void *ctx,int32_t pubsock,cJSON *argjson,char *base,c if ( bits256_nonz(privkey) != 0 && bits256_cmp(G.LP_mypub25519,qp->srchash) == 0 ) { LP_requestinit(&qp->R,qp->srchash,qp->desthash,base,qp->satoshis-qp->txfee,rel,qp->destsatoshis-qp->desttxfee,qp->timestamp,qp->quotetime,DEXselector); + if ( LP_pendingswap(qp->R.requestid,qp->R.quoteid) > 0 ) + { + printf("requestid.%u quoteid.%u is already in progres\n",qp->R.requestid,qp->R.quoteid); + return(-1); + } if ( (swap= LP_swapinit(1,0,privkey,&qp->R,qp)) == 0 ) { printf("cant initialize swap\n"); @@ -611,6 +616,12 @@ char *LP_connectedalice(cJSON *argjson) // alice { retjson = cJSON_CreateObject(); LP_requestinit(&Q.R,Q.srchash,Q.desthash,Q.srccoin,Q.satoshis-Q.txfee,Q.destcoin,Q.destsatoshis-Q.desttxfee,Q.timestamp,Q.quotetime,DEXselector); + if ( LP_pendingswap(Q.R.requestid,Q.R.quoteid) > 0 ) + { + printf("requestid.%u quoteid.%u is already in progres\n",Q.R.requestid,Q.R.quoteid); + jaddstr(retjson,"error","swap already in progress"); + return(jprint(retjson,1)); + } if ( (swap= LP_swapinit(0,0,Q.privkey,&Q.R,&Q)) == 0 ) { jaddstr(retjson,"error","couldnt swapinit"); diff --git a/iguana/exchanges/LP_remember.c b/iguana/exchanges/LP_remember.c index d8b264e7c..c0ef0efd7 100644 --- a/iguana/exchanges/LP_remember.c +++ b/iguana/exchanges/LP_remember.c @@ -1441,3 +1441,40 @@ char *basilisk_swapentries(char *refbase,char *refrel,int32_t limit) return(jprint(retarray,1)); } +int32_t LP_pendingswap(uint32_t requestid,uint32_t quoteid) +{ + cJSON *retjson,*array,*pending,*item; uint32_t r,q; char *retstr; int32_t i,n,retval = 0; + if ( (retstr= LP_recent_swaps(1000)) != 0 ) + { + if ( (retjson= cJSON_Parse(retstr)) != 0 ) + { + if ( (array= jarray(&n,retjson,"swaps")) != 0 ) + { + for (i=0; i Date: Wed, 15 Nov 2017 19:43:04 +0200 Subject: [PATCH 0835/1664] Test --- iguana/exchanges/LP_include.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/iguana/exchanges/LP_include.h b/iguana/exchanges/LP_include.h index b1a78c694..b6c24be52 100644 --- a/iguana/exchanges/LP_include.h +++ b/iguana/exchanges/LP_include.h @@ -23,7 +23,7 @@ #define LP_MAJOR_VERSION "0" #define LP_MINOR_VERSION "1" -#define LP_BUILD_NUMBER "14498" +#define LP_BUILD_NUMBER "15000" #ifdef FROM_JS #include From 55837efe446da7e9c77907e03a125f887e52bc49 Mon Sep 17 00:00:00 2001 From: jl777 Date: Wed, 15 Nov 2017 19:50:11 +0200 Subject: [PATCH 0836/1664] Test --- iguana/exchanges/LP_ordermatch.c | 15 ++++++++------- 1 file changed, 8 insertions(+), 7 deletions(-) diff --git a/iguana/exchanges/LP_ordermatch.c b/iguana/exchanges/LP_ordermatch.c index 7d60f336d..04faf3715 100644 --- a/iguana/exchanges/LP_ordermatch.c +++ b/iguana/exchanges/LP_ordermatch.c @@ -571,7 +571,14 @@ char *LP_connectedalice(cJSON *argjson) // alice LP_aliceid(Q.tradeid,Q.aliceid,"error1",0,0); return(clonestr("{\"result\",\"update stats\"}")); } - printf("CONNECTED.(%s) numpending.%d tradeid.%u\n",jprint(argjson,0),G.LP_pendingswaps,Q.tradeid); + printf("CONNECTED.(%s) numpending.%d tradeid.%u requestid.%u quoteid.%u\n",jprint(argjson,0),G.LP_pendingswaps,Q.tradeid,Q.R.requestid,Q.R.quoteid); + if ( LP_pendingswap(Q.R.requestid,Q.R.quoteid) > 0 ) + { + printf("requestid.%u quoteid.%u is already in progres\n",Q.R.requestid,Q.R.quoteid); + retjson = cJSON_CreateObject(); + jaddstr(retjson,"error","swap already in progress"); + return(jprint(retjson,1)); + } if ( (autxo= LP_utxopairfind(0,Q.desttxid,Q.destvout,Q.feetxid,Q.feevout)) == 0 ) { printf("cant find autxo\n"); @@ -616,12 +623,6 @@ char *LP_connectedalice(cJSON *argjson) // alice { retjson = cJSON_CreateObject(); LP_requestinit(&Q.R,Q.srchash,Q.desthash,Q.srccoin,Q.satoshis-Q.txfee,Q.destcoin,Q.destsatoshis-Q.desttxfee,Q.timestamp,Q.quotetime,DEXselector); - if ( LP_pendingswap(Q.R.requestid,Q.R.quoteid) > 0 ) - { - printf("requestid.%u quoteid.%u is already in progres\n",Q.R.requestid,Q.R.quoteid); - jaddstr(retjson,"error","swap already in progress"); - return(jprint(retjson,1)); - } if ( (swap= LP_swapinit(0,0,Q.privkey,&Q.R,&Q)) == 0 ) { jaddstr(retjson,"error","couldnt swapinit"); From 30e638296800bfeae1f9be87d355af83ae95a15f Mon Sep 17 00:00:00 2001 From: jl777 Date: Wed, 15 Nov 2017 20:38:55 +0200 Subject: [PATCH 0837/1664] Test --- iguana/exchanges/LP_socket.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/iguana/exchanges/LP_socket.c b/iguana/exchanges/LP_socket.c index e50e648d4..979a0ad0c 100644 --- a/iguana/exchanges/LP_socket.c +++ b/iguana/exchanges/LP_socket.c @@ -1034,7 +1034,7 @@ cJSON *LP_electrumserver(struct iguana_info *coin,char *ipaddr,uint16_t port) retjson = cJSON_CreateObject(); jaddstr(retjson,"ipaddr",ipaddr); jaddnum(retjson,"port",port); - if ( (ep= LP_electrum_info(&already,coin->symbol,ipaddr,port,IGUANA_MAXPACKETSIZE * 10)) == 0 ) + if ( (ep= LP_electrum_info(&already,coin->symbol,ipaddr,port,IGUANA_MAXPACKETSIZE)) == 0 ) { jaddstr(retjson,"error","couldnt connect to electrum server"); return(retjson); From 61ebc0b09176a9c9480588af5b7bce402324f587 Mon Sep 17 00:00:00 2001 From: jl777 Date: Wed, 15 Nov 2017 20:45:40 +0200 Subject: [PATCH 0838/1664] Test --- iguana/exchanges/LP_transaction.c | 12 +++++++++++- 1 file changed, 11 insertions(+), 1 deletion(-) diff --git a/iguana/exchanges/LP_transaction.c b/iguana/exchanges/LP_transaction.c index 3f6ff3e43..d414b2847 100644 --- a/iguana/exchanges/LP_transaction.c +++ b/iguana/exchanges/LP_transaction.c @@ -78,7 +78,8 @@ int32_t LP_gettx_presence(char *symbol,bits256 expectedtxid) bits256 LP_broadcast(char *txname,char *symbol,char *txbytes,bits256 expectedtxid) { - char *retstr; bits256 txid; uint8_t *ptr; cJSON *retjson,*errorobj; int32_t i,len,sentflag = 0; + char *retstr,*errstr; bits256 txid; uint8_t *ptr; cJSON *retjson,*errorobj; struct iguana_info *coin; int32_t i,totalretries=0,len,sentflag = 0; + coin = LP_coinfind(symbol); memset(&txid,0,sizeof(txid)); if ( txbytes == 0 || txbytes[0] == 0 ) return(txid); @@ -115,6 +116,15 @@ bits256 LP_broadcast(char *txname,char *symbol,char *txbytes,bits256 expectedtxi txid = expectedtxid; sentflag = 1; } + else if ( (errstr= jstr(retjson,"error")) != 0 && strcmp(errstr,"timeout") == 0 && coin != 0 && coin->electrum != 0 ) + { + if ( totalretries < 10 ) + { + printf("time error with electrum, retry\n"); + totalretries++; + i--; + } + } else printf("broadcast error.(%s)\n",retstr); } free_json(retjson); From e61d0a0fc4d85dfdd577d929a4cb0b6f64cb0271 Mon Sep 17 00:00:00 2001 From: DeckerSU Date: Wed, 15 Nov 2017 23:28:31 +0400 Subject: [PATCH 0839/1664] added obtaining version number of mm and commit hash in build script --- marketmaker_build_32_64.cmd | 35 +++++++++++++++++++++++++++++++++++ 1 file changed, 35 insertions(+) diff --git a/marketmaker_build_32_64.cmd b/marketmaker_build_32_64.cmd index bac8df5e0..730081702 100644 --- a/marketmaker_build_32_64.cmd +++ b/marketmaker_build_32_64.cmd @@ -32,6 +32,39 @@ rem MSBuild /help MSBuild marketmaker.sln /t:Rebuild /p:Configuration=Release /p:Platform=x64 MSBuild marketmaker.sln /t:Rebuild /p:Configuration=Release /p:Platform=x86 +rem Obtain version number and latest git commit number + +FOR /F "tokens=* USEBACKQ" %%F IN (`find /i "LP_MAJOR_VERSION" "iguana\exchanges\LP_include.h"`) DO ( +SET LP_MAJOR_VERSION_STR=%%F +) +FOR /F "tokens=* USEBACKQ" %%F IN (`find /i "LP_MINOR_VERSION" "iguana\exchanges\LP_include.h"`) DO ( +SET LP_MINOR_VERSION_STR=%%F +) +FOR /F "tokens=* USEBACKQ" %%F IN (`find /i "LP_BUILD_NUMBER" "iguana\exchanges\LP_include.h"`) DO ( +SET LP_BUILD_NUMBER_STR=%%F +) + +for /f delims^=^"^ tokens^=2 %%a in ('echo %LP_MAJOR_VERSION_STR%') do ( +set LP_MAJOR_VERSION=%%a +) +for /f delims^=^"^ tokens^=2 %%a in ('echo %LP_MINOR_VERSION_STR%') do ( +set LP_MINOR_VERSION=%%a +) +for /f delims^=^"^ tokens^=2 %%a in ('echo %LP_BUILD_NUMBER_STR%') do ( +set LP_BUILD_NUMBER=%%a +) + +rem Check if git command exist and if does - receive latest GIT_COMMIT +git --version >nul 2>&1 && ( + for /f "tokens=1" %%a in ('git rev-parse --short HEAD') do ( + set GIT_COMMIT=_%%a + ) +) || ( + set GIT_COMMIT= +) + +rem echo Marketmaker_%LP_MAJOR_VERSION%.%LP_MINOR_VERSION%_%LP_BUILD_NUMBER%%GIT_COMMIT% + rem Using to add in marketmaker_release.7z set host=%COMPUTERNAME% IF "%host%"=="VM-81" ( @@ -39,9 +72,11 @@ IF "%host%"=="VM-81" ( mkdir package_content\win64 copy /y Release\marketmaker.exe package_content\win32 copy /y x64\Release\marketmaker.exe package_content\win64 + echo Marketmaker_%LP_MAJOR_VERSION%.%LP_MINOR_VERSION%_%LP_BUILD_NUMBER%%GIT_COMMIT% > package_content\version.txt cd package_content "C:\Program Files\7-Zip\7z.exe" a C:\komodo\marketmaker_release\marketmaker_release.7z win32\marketmaker.exe "C:\Program Files\7-Zip\7z.exe" a C:\komodo\marketmaker_release\marketmaker_release.7z win64\marketmaker.exe + "C:\Program Files\7-Zip\7z.exe" a C:\komodo\marketmaker_release\marketmaker_release.7z version.txt cd .. rd package_content /s /q ) From 6738004bf87a671c5b28c3f89bc03ec8e6d4248b Mon Sep 17 00:00:00 2001 From: jl777 Date: Wed, 15 Nov 2017 21:55:30 +0200 Subject: [PATCH 0840/1664] Meatiest --- iguana/exchanges/LP_nativeDEX.c | 14 ++++++++++++-- iguana/exchanges/LP_transaction.c | 2 +- iguana/exchanges/mm.c | 11 +++++++---- 3 files changed, 20 insertions(+), 7 deletions(-) diff --git a/iguana/exchanges/LP_nativeDEX.c b/iguana/exchanges/LP_nativeDEX.c index 6f90ed93c..b195a292d 100644 --- a/iguana/exchanges/LP_nativeDEX.c +++ b/iguana/exchanges/LP_nativeDEX.c @@ -17,8 +17,6 @@ // LP_nativeDEX.c // marketmaker // -// more retries for swap sendrawtransaction? -// pbca26 unfinished swaps // if ( G.LP_pendingswaps != 0 ) return(-1); // bot safe to exit? // @@ -1190,4 +1188,16 @@ void LP_fromjs_iter() #endif +#undef calloc +#undef free + +void *LP_alloc(uint64_t len) +{ + return(calloc(1,len)); +} + +void LP_free(void *ptr) +{ + free(ptr); +} diff --git a/iguana/exchanges/LP_transaction.c b/iguana/exchanges/LP_transaction.c index d414b2847..cfd1a6060 100644 --- a/iguana/exchanges/LP_transaction.c +++ b/iguana/exchanges/LP_transaction.c @@ -120,7 +120,7 @@ bits256 LP_broadcast(char *txname,char *symbol,char *txbytes,bits256 expectedtxi { if ( totalretries < 10 ) { - printf("time error with electrum, retry\n"); + printf("time error with electrum, retry.%d\n",totalretries); totalretries++; i--; } diff --git a/iguana/exchanges/mm.c b/iguana/exchanges/mm.c index f906390b8..e199b6bfd 100644 --- a/iguana/exchanges/mm.c +++ b/iguana/exchanges/mm.c @@ -19,10 +19,7 @@ // Copyright © 2017 SuperNET. All rights reserved. // -/* -#define malloc(n) LP_alloc(n) -#define calloc(a,b) LP_alloc((uint64_t)(a) * (b)) -#define free(ptr) LP_free(ptr)*/ + void PNACL_message(char *arg,...) { @@ -42,6 +39,12 @@ void PNACL_message(char *arg,...) #include "../../crypto777/OS_portable.h" #endif // !_WIN_32 +#define malloc(n) LP_alloc(n) +#define calloc(a,b) LP_alloc((uint64_t)(a) * (b)) +#define free(ptr) LP_free(ptr) + +void *LP_alloc(uint64_t len); +void LP_free(void *ptr); #define MAX(a,b) ((a) > (b) ? (a) : (b)) char *stats_JSON(void *ctx,char *myipaddr,int32_t pubsock,cJSON *argjson,char *remoteaddr,uint16_t port); From c02faaadfd525da058d0e75d0fb19e7a2792272a Mon Sep 17 00:00:00 2001 From: jl777 Date: Wed, 15 Nov 2017 22:19:28 +0200 Subject: [PATCH 0841/1664] Test --- iguana/exchanges/LP_nativeDEX.c | 40 +++++++++++++++++++++++++++++++-- 1 file changed, 38 insertions(+), 2 deletions(-) diff --git a/iguana/exchanges/LP_nativeDEX.c b/iguana/exchanges/LP_nativeDEX.c index b195a292d..1bb412af5 100644 --- a/iguana/exchanges/LP_nativeDEX.c +++ b/iguana/exchanges/LP_nativeDEX.c @@ -1191,13 +1191,49 @@ void LP_fromjs_iter() #undef calloc #undef free +struct LP_memory_list +{ + struct LP_memory_list *next,*prev; + void *ptr; + uint32_t timestamp,len; +} *LP_memory_list; + void *LP_alloc(uint64_t len) { - return(calloc(1,len)); + struct LP_memory_list *mp; + mp = calloc(1,sizeof(*mp) + len); + mp->timestamp = (uint32_t)time(NULL); + mp->ptr = calloc(1,len); + mp->len = (uint32_t)len; + portable_mutex_lock(&LP_cJSONmutex); + DL_APPEND(LP_memory_list,mp); + portable_mutex_unlock(&LP_cJSONmutex); + return(&mp[1]); } void LP_free(void *ptr) { - free(ptr); + static uint32_t lasttime; + uint32_t now; int32_t n; uint64_t total = 0; char str[65]; struct LP_memory_list *mp,*tmp,*freemp = ptr; + --freemp; + if ( (now= (uint32_t)time(NULL)) > lasttime+6 ) + { + n = 0; + DL_FOREACH_SAFE(LP_memory_list,mp,tmp) + { + total += mp->len; + n++; + } + printf("total %d allocated total size %s\n",n,mbstr(str,total)); + lasttime = (uint32_t)time(NULL); + } + if ( freemp != 0 ) + { + portable_mutex_lock(&LP_cJSONmutex); + DL_DELETE(LP_memory_list,freemp); + free(freemp); + portable_mutex_unlock(&LP_cJSONmutex); + } //else printf("cJSON_unregister of unknown %p %u\n",item,item->cjsonid); } + From 146b98afffaa6929f2f1c59c25af3ee73f384da9 Mon Sep 17 00:00:00 2001 From: jl777 Date: Wed, 15 Nov 2017 22:24:03 +0200 Subject: [PATCH 0842/1664] Test --- iguana/exchanges/LP_nativeDEX.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/iguana/exchanges/LP_nativeDEX.c b/iguana/exchanges/LP_nativeDEX.c index 1bb412af5..ef97d7d4d 100644 --- a/iguana/exchanges/LP_nativeDEX.c +++ b/iguana/exchanges/LP_nativeDEX.c @@ -1194,7 +1194,6 @@ void LP_fromjs_iter() struct LP_memory_list { struct LP_memory_list *next,*prev; - void *ptr; uint32_t timestamp,len; } *LP_memory_list; @@ -1202,8 +1201,8 @@ void *LP_alloc(uint64_t len) { struct LP_memory_list *mp; mp = calloc(1,sizeof(*mp) + len); + printf("mp.%p ptr.%p\n",mp,&mp[1]); mp->timestamp = (uint32_t)time(NULL); - mp->ptr = calloc(1,len); mp->len = (uint32_t)len; portable_mutex_lock(&LP_cJSONmutex); DL_APPEND(LP_memory_list,mp); @@ -1216,6 +1215,7 @@ void LP_free(void *ptr) static uint32_t lasttime; uint32_t now; int32_t n; uint64_t total = 0; char str[65]; struct LP_memory_list *mp,*tmp,*freemp = ptr; --freemp; + printf("freemp.%p\n",freemp); if ( (now= (uint32_t)time(NULL)) > lasttime+6 ) { n = 0; From 2fe9584e526296c37a59308dd41d1180aa02b5e4 Mon Sep 17 00:00:00 2001 From: jl777 Date: Wed, 15 Nov 2017 22:35:45 +0200 Subject: [PATCH 0843/1664] Test --- iguana/exchanges/LP_nativeDEX.c | 10 +++++----- iguana/exchanges/LP_utxo.c | 4 ++-- 2 files changed, 7 insertions(+), 7 deletions(-) diff --git a/iguana/exchanges/LP_nativeDEX.c b/iguana/exchanges/LP_nativeDEX.c index ef97d7d4d..0828a393a 100644 --- a/iguana/exchanges/LP_nativeDEX.c +++ b/iguana/exchanges/LP_nativeDEX.c @@ -1201,7 +1201,7 @@ void *LP_alloc(uint64_t len) { struct LP_memory_list *mp; mp = calloc(1,sizeof(*mp) + len); - printf("mp.%p ptr.%p\n",mp,&mp[1]); + printf("\n>>>>>>>>>>> LP_alloc mp.%p ptr.%p len.%llu\n",mp,&mp[1],(long long)len); mp->timestamp = (uint32_t)time(NULL); mp->len = (uint32_t)len; portable_mutex_lock(&LP_cJSONmutex); @@ -1213,9 +1213,9 @@ void *LP_alloc(uint64_t len) void LP_free(void *ptr) { static uint32_t lasttime; - uint32_t now; int32_t n; uint64_t total = 0; char str[65]; struct LP_memory_list *mp,*tmp,*freemp = ptr; + uint32_t now; int32_t n; uint64_t total = 0; struct LP_memory_list *mp,*tmp,*freemp = ptr; --freemp; - printf("freemp.%p\n",freemp); + printf("\n>>>>>>>>>>> LP_free freemp.%p\n",freemp); if ( (now= (uint32_t)time(NULL)) > lasttime+6 ) { n = 0; @@ -1224,15 +1224,15 @@ void LP_free(void *ptr) total += mp->len; n++; } - printf("total %d allocated total size %s\n",n,mbstr(str,total)); + printf("total %d allocated total %llu\n",n,(long long)total); lasttime = (uint32_t)time(NULL); } if ( freemp != 0 ) { portable_mutex_lock(&LP_cJSONmutex); DL_DELETE(LP_memory_list,freemp); - free(freemp); portable_mutex_unlock(&LP_cJSONmutex); + free(freemp); } //else printf("cJSON_unregister of unknown %p %u\n",item,item->cjsonid); } diff --git a/iguana/exchanges/LP_utxo.c b/iguana/exchanges/LP_utxo.c index da6f97cc1..fcd05feb3 100644 --- a/iguana/exchanges/LP_utxo.c +++ b/iguana/exchanges/LP_utxo.c @@ -27,7 +27,7 @@ struct LP_inuse_info } LP_inuse[1024]; int32_t LP_numinuse; -struct cJSON_list +/*struct cJSON_list { struct cJSON_list *next,*prev; cJSON *item; @@ -92,7 +92,7 @@ void cJSON_unregister(cJSON *item) free(ptr); portable_mutex_unlock(&LP_cJSONmutex); } //else printf("cJSON_unregister of unknown %p %u\n",item,item->cjsonid); -} +}*/ struct LP_inuse_info *_LP_inuse_find(bits256 txid,int32_t vout) { From 21594133c08e482a2861e0d4ff66c0eb97b9a2cb Mon Sep 17 00:00:00 2001 From: jl777 Date: Wed, 15 Nov 2017 22:46:12 +0200 Subject: [PATCH 0844/1664] Test --- iguana/exchanges/LP_nativeDEX.c | 7 +++++++ iguana/exchanges/mm.c | 2 ++ 2 files changed, 9 insertions(+) diff --git a/iguana/exchanges/LP_nativeDEX.c b/iguana/exchanges/LP_nativeDEX.c index 0828a393a..4834fd8e8 100644 --- a/iguana/exchanges/LP_nativeDEX.c +++ b/iguana/exchanges/LP_nativeDEX.c @@ -1190,6 +1190,7 @@ void LP_fromjs_iter() #undef calloc #undef free +#undef clonestr struct LP_memory_list { @@ -1236,4 +1237,10 @@ void LP_free(void *ptr) } //else printf("cJSON_unregister of unknown %p %u\n",item,item->cjsonid); } +char *LP_clonestr(char *str) +{ + char *retstr = LP_alloc(strlen(str)+1); + strcpy(retstr,str); + return(retstr); +} diff --git a/iguana/exchanges/mm.c b/iguana/exchanges/mm.c index e199b6bfd..f10241da7 100644 --- a/iguana/exchanges/mm.c +++ b/iguana/exchanges/mm.c @@ -42,9 +42,11 @@ void PNACL_message(char *arg,...) #define malloc(n) LP_alloc(n) #define calloc(a,b) LP_alloc((uint64_t)(a) * (b)) #define free(ptr) LP_free(ptr) +#define clonestr(str) LP_clonestr(str) void *LP_alloc(uint64_t len); void LP_free(void *ptr); +char *LP_clonestr(char *str); #define MAX(a,b) ((a) > (b) ? (a) : (b)) char *stats_JSON(void *ctx,char *myipaddr,int32_t pubsock,cJSON *argjson,char *remoteaddr,uint16_t port); From abec32f1b69c8655ad3d2f3415b130fc042d0d83 Mon Sep 17 00:00:00 2001 From: jl777 Date: Wed, 15 Nov 2017 22:48:56 +0200 Subject: [PATCH 0845/1664] Test --- crypto777/bitcoind_RPC.c | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/crypto777/bitcoind_RPC.c b/crypto777/bitcoind_RPC.c index 98c7e7eb0..0a9157b84 100755 --- a/crypto777/bitcoind_RPC.c +++ b/crypto777/bitcoind_RPC.c @@ -13,6 +13,12 @@ * * ******************************************************************************/ + +#define malloc(n) LP_alloc(n) +#define calloc(a,b) LP_alloc((uint64_t)(a) * (b)) +#define free(ptr) LP_free(ptr) +#define clonestr(str) LP_clonestr(str) + #ifndef FROM_JS #include "OS_portable.h" #define LIQUIDITY_PROVIDER 1 From edefcaffe16e55c94da50f49aedf36910bc66469 Mon Sep 17 00:00:00 2001 From: jl777 Date: Wed, 15 Nov 2017 22:49:39 +0200 Subject: [PATCH 0846/1664] Test --- crypto777/bitcoind_RPC.c | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/crypto777/bitcoind_RPC.c b/crypto777/bitcoind_RPC.c index 0a9157b84..22c6ebceb 100755 --- a/crypto777/bitcoind_RPC.c +++ b/crypto777/bitcoind_RPC.c @@ -14,15 +14,16 @@ ******************************************************************************/ -#define malloc(n) LP_alloc(n) -#define calloc(a,b) LP_alloc((uint64_t)(a) * (b)) -#define free(ptr) LP_free(ptr) -#define clonestr(str) LP_clonestr(str) #ifndef FROM_JS #include "OS_portable.h" #define LIQUIDITY_PROVIDER 1 +#define malloc(n) LP_alloc(n) +#define calloc(a,b) LP_alloc((uint64_t)(a) * (b)) +#define free(ptr) LP_free(ptr) +#define clonestr(str) LP_clonestr(str) + #if LIQUIDITY_PROVIDER #include #include From eaaaea9d67537414a1767d481bdbff7bc0dacb2f Mon Sep 17 00:00:00 2001 From: jl777 Date: Wed, 15 Nov 2017 22:50:49 +0200 Subject: [PATCH 0847/1664] Test --- crypto777/bitcoind_RPC.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/crypto777/bitcoind_RPC.c b/crypto777/bitcoind_RPC.c index 22c6ebceb..05144b82a 100755 --- a/crypto777/bitcoind_RPC.c +++ b/crypto777/bitcoind_RPC.c @@ -23,6 +23,9 @@ #define calloc(a,b) LP_alloc((uint64_t)(a) * (b)) #define free(ptr) LP_free(ptr) #define clonestr(str) LP_clonestr(str) +void *LP_alloc(uint64_t len); +void LP_free(void *ptr); +char *LP_clonestr(char *str); #if LIQUIDITY_PROVIDER #include From da58c22fda6440b59f856ee4bce2ea765f397832 Mon Sep 17 00:00:00 2001 From: jl777 Date: Wed, 15 Nov 2017 22:58:23 +0200 Subject: [PATCH 0848/1664] Test --- crypto777/bitcoind_RPC.c | 4 ++++ iguana/exchanges/LP_nativeDEX.c | 11 +++++++++++ iguana/exchanges/mm.c | 2 ++ 3 files changed, 17 insertions(+) diff --git a/crypto777/bitcoind_RPC.c b/crypto777/bitcoind_RPC.c index 05144b82a..a3488aeae 100755 --- a/crypto777/bitcoind_RPC.c +++ b/crypto777/bitcoind_RPC.c @@ -20,13 +20,17 @@ #define LIQUIDITY_PROVIDER 1 #define malloc(n) LP_alloc(n) +#define realloc(ptr,n) LP_realloc(ptr,n) #define calloc(a,b) LP_alloc((uint64_t)(a) * (b)) #define free(ptr) LP_free(ptr) #define clonestr(str) LP_clonestr(str) + +void *LP_realloc(void *ptr,uint64_t len); void *LP_alloc(uint64_t len); void LP_free(void *ptr); char *LP_clonestr(char *str); + #if LIQUIDITY_PROVIDER #include #include diff --git a/iguana/exchanges/LP_nativeDEX.c b/iguana/exchanges/LP_nativeDEX.c index 4834fd8e8..cf18369f2 100644 --- a/iguana/exchanges/LP_nativeDEX.c +++ b/iguana/exchanges/LP_nativeDEX.c @@ -1190,6 +1190,7 @@ void LP_fromjs_iter() #undef calloc #undef free +#undef realloc #undef clonestr struct LP_memory_list @@ -1211,6 +1212,16 @@ void *LP_alloc(uint64_t len) return(&mp[1]); } +void *LP_realloc(void *ptr,uint64_t len) +{ + struct LP_memory_list *mp = ptr; + --mp; + mp = realloc(mp,len + sizeof(*mp)); + mp->timestamp = (uint32_t)time(NULL); + mp->len = (uint32_t)len; + return(&mp[1]); +} + void LP_free(void *ptr) { static uint32_t lasttime; diff --git a/iguana/exchanges/mm.c b/iguana/exchanges/mm.c index f10241da7..d8ce0ed0d 100644 --- a/iguana/exchanges/mm.c +++ b/iguana/exchanges/mm.c @@ -40,10 +40,12 @@ void PNACL_message(char *arg,...) #endif // !_WIN_32 #define malloc(n) LP_alloc(n) +#define realloc(ptr,n) LP_realloc(ptr,n) #define calloc(a,b) LP_alloc((uint64_t)(a) * (b)) #define free(ptr) LP_free(ptr) #define clonestr(str) LP_clonestr(str) +void *LP_realloc(void *ptr,uint64_t len); void *LP_alloc(uint64_t len); void LP_free(void *ptr); char *LP_clonestr(char *str); From b6366f824ce0e9d0c7c66806170bcf6a10842a4b Mon Sep 17 00:00:00 2001 From: jl777 Date: Wed, 15 Nov 2017 23:00:48 +0200 Subject: [PATCH 0849/1664] Test --- iguana/exchanges/LP_nativeDEX.c | 14 +++++++++----- 1 file changed, 9 insertions(+), 5 deletions(-) diff --git a/iguana/exchanges/LP_nativeDEX.c b/iguana/exchanges/LP_nativeDEX.c index cf18369f2..91eadb613 100644 --- a/iguana/exchanges/LP_nativeDEX.c +++ b/iguana/exchanges/LP_nativeDEX.c @@ -1215,11 +1215,15 @@ void *LP_alloc(uint64_t len) void *LP_realloc(void *ptr,uint64_t len) { struct LP_memory_list *mp = ptr; - --mp; - mp = realloc(mp,len + sizeof(*mp)); - mp->timestamp = (uint32_t)time(NULL); - mp->len = (uint32_t)len; - return(&mp[1]); + if ( mp != 0 ) + { + --mp; + printf("\n>>>>>>>>>>> LP_realloc mp.%p ptr.%p len.%llu\n",mp,&mp[1],(long long)len); + mp = realloc(mp,len + sizeof(*mp)); + mp->timestamp = (uint32_t)time(NULL); + mp->len = (uint32_t)len; + return(&mp[1]); + } else return(LP_alloc(len)); } void LP_free(void *ptr) From 1b5bd6e2ea96136ac374203253cf38abd1081653 Mon Sep 17 00:00:00 2001 From: jl777 Date: Wed, 15 Nov 2017 23:04:30 +0200 Subject: [PATCH 0850/1664] Test --- iguana/exchanges/LP_nativeDEX.c | 14 ++++++++++---- 1 file changed, 10 insertions(+), 4 deletions(-) diff --git a/iguana/exchanges/LP_nativeDEX.c b/iguana/exchanges/LP_nativeDEX.c index 91eadb613..b7489c3f3 100644 --- a/iguana/exchanges/LP_nativeDEX.c +++ b/iguana/exchanges/LP_nativeDEX.c @@ -1243,13 +1243,19 @@ void LP_free(void *ptr) printf("total %d allocated total %llu\n",n,(long long)total); lasttime = (uint32_t)time(NULL); } - if ( freemp != 0 ) + DL_FOREACH_SAFE(LP_memory_list,mp,tmp) + { + if ( mp == freemp ) + break; + mp = 0; + } + if ( mp != 0 ) { portable_mutex_lock(&LP_cJSONmutex); - DL_DELETE(LP_memory_list,freemp); + DL_DELETE(LP_memory_list,mp); portable_mutex_unlock(&LP_cJSONmutex); - free(freemp); - } //else printf("cJSON_unregister of unknown %p %u\n",item,item->cjsonid); + free(mp); + } // free from source file with #define redirect for alloc that wasnt } char *LP_clonestr(char *str) From c75d6641712214a0ebc0f17754cc2420d8bc2508 Mon Sep 17 00:00:00 2001 From: jl777 Date: Wed, 15 Nov 2017 23:08:31 +0200 Subject: [PATCH 0851/1664] Test --- iguana/exchanges/LP_nativeDEX.c | 25 +++++++++---------------- 1 file changed, 9 insertions(+), 16 deletions(-) diff --git a/iguana/exchanges/LP_nativeDEX.c b/iguana/exchanges/LP_nativeDEX.c index b7489c3f3..05d9a36fd 100644 --- a/iguana/exchanges/LP_nativeDEX.c +++ b/iguana/exchanges/LP_nativeDEX.c @@ -1197,41 +1197,33 @@ struct LP_memory_list { struct LP_memory_list *next,*prev; uint32_t timestamp,len; + void *ptr; } *LP_memory_list; void *LP_alloc(uint64_t len) { struct LP_memory_list *mp; - mp = calloc(1,sizeof(*mp) + len); + mp = calloc(1,sizeof(*mp)); printf("\n>>>>>>>>>>> LP_alloc mp.%p ptr.%p len.%llu\n",mp,&mp[1],(long long)len); mp->timestamp = (uint32_t)time(NULL); mp->len = (uint32_t)len; + mp->ptr = calloc(1,len); portable_mutex_lock(&LP_cJSONmutex); DL_APPEND(LP_memory_list,mp); portable_mutex_unlock(&LP_cJSONmutex); - return(&mp[1]); + return(mp->ptr); } void *LP_realloc(void *ptr,uint64_t len) { - struct LP_memory_list *mp = ptr; - if ( mp != 0 ) - { - --mp; - printf("\n>>>>>>>>>>> LP_realloc mp.%p ptr.%p len.%llu\n",mp,&mp[1],(long long)len); - mp = realloc(mp,len + sizeof(*mp)); - mp->timestamp = (uint32_t)time(NULL); - mp->len = (uint32_t)len; - return(&mp[1]); - } else return(LP_alloc(len)); + return(realloc(ptr,len)); } void LP_free(void *ptr) { static uint32_t lasttime; - uint32_t now; int32_t n; uint64_t total = 0; struct LP_memory_list *mp,*tmp,*freemp = ptr; - --freemp; - printf("\n>>>>>>>>>>> LP_free freemp.%p\n",freemp); + uint32_t now; int32_t n; uint64_t total = 0; struct LP_memory_list *mp,*tmp; + printf("\n>>>>>>>>>>> LP_free ptr.%p\n",ptr); if ( (now= (uint32_t)time(NULL)) > lasttime+6 ) { n = 0; @@ -1245,7 +1237,7 @@ void LP_free(void *ptr) } DL_FOREACH_SAFE(LP_memory_list,mp,tmp) { - if ( mp == freemp ) + if ( mp->ptr == ptr ) break; mp = 0; } @@ -1254,6 +1246,7 @@ void LP_free(void *ptr) portable_mutex_lock(&LP_cJSONmutex); DL_DELETE(LP_memory_list,mp); portable_mutex_unlock(&LP_cJSONmutex); + free(mp->ptr); free(mp); } // free from source file with #define redirect for alloc that wasnt } From 3e0217af2bfe48433a01d1d55562fffe3eca2cd8 Mon Sep 17 00:00:00 2001 From: jl777 Date: Wed, 15 Nov 2017 23:11:15 +0200 Subject: [PATCH 0852/1664] Test --- iguana/exchanges/LP_nativeDEX.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/iguana/exchanges/LP_nativeDEX.c b/iguana/exchanges/LP_nativeDEX.c index 05d9a36fd..ae0491bd2 100644 --- a/iguana/exchanges/LP_nativeDEX.c +++ b/iguana/exchanges/LP_nativeDEX.c @@ -1204,7 +1204,7 @@ void *LP_alloc(uint64_t len) { struct LP_memory_list *mp; mp = calloc(1,sizeof(*mp)); - printf("\n>>>>>>>>>>> LP_alloc mp.%p ptr.%p len.%llu\n",mp,&mp[1],(long long)len); + //printf("\n>>>>>>>>>>> LP_alloc mp.%p ptr.%p len.%llu\n",mp,mp->ptr,(long long)len); mp->timestamp = (uint32_t)time(NULL); mp->len = (uint32_t)len; mp->ptr = calloc(1,len); @@ -1223,7 +1223,6 @@ void LP_free(void *ptr) { static uint32_t lasttime; uint32_t now; int32_t n; uint64_t total = 0; struct LP_memory_list *mp,*tmp; - printf("\n>>>>>>>>>>> LP_free ptr.%p\n",ptr); if ( (now= (uint32_t)time(NULL)) > lasttime+6 ) { n = 0; @@ -1246,6 +1245,7 @@ void LP_free(void *ptr) portable_mutex_lock(&LP_cJSONmutex); DL_DELETE(LP_memory_list,mp); portable_mutex_unlock(&LP_cJSONmutex); + printf(">>>>>>>>>>> LP_free ptr.%p mp.%p len.%u\n",ptr,mp,mp->len); free(mp->ptr); free(mp); } // free from source file with #define redirect for alloc that wasnt From 2f9c6d37f033bbfa47e2caaae1ad56114157d7d5 Mon Sep 17 00:00:00 2001 From: jl777 Date: Wed, 15 Nov 2017 23:14:20 +0200 Subject: [PATCH 0853/1664] Test --- iguana/exchanges/LP_nativeDEX.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/iguana/exchanges/LP_nativeDEX.c b/iguana/exchanges/LP_nativeDEX.c index ae0491bd2..15f431a6f 100644 --- a/iguana/exchanges/LP_nativeDEX.c +++ b/iguana/exchanges/LP_nativeDEX.c @@ -1228,6 +1228,7 @@ void LP_free(void *ptr) n = 0; DL_FOREACH_SAFE(LP_memory_list,mp,tmp) { + printf("%d ",mp->len); total += mp->len; n++; } @@ -1245,7 +1246,7 @@ void LP_free(void *ptr) portable_mutex_lock(&LP_cJSONmutex); DL_DELETE(LP_memory_list,mp); portable_mutex_unlock(&LP_cJSONmutex); - printf(">>>>>>>>>>> LP_free ptr.%p mp.%p len.%u\n",ptr,mp,mp->len); + //printf(">>>>>>>>>>> LP_free ptr.%p mp.%p len.%u\n",ptr,mp,mp->len); free(mp->ptr); free(mp); } // free from source file with #define redirect for alloc that wasnt From 52f6758c4da6cbada73cf6fce0ed2a07fe8dcca3 Mon Sep 17 00:00:00 2001 From: jl777 Date: Wed, 15 Nov 2017 23:25:50 +0200 Subject: [PATCH 0854/1664] Test --- crypto777/bitcoind_RPC.c | 2 +- iguana/exchanges/LP_nativeDEX.c | 6 +++--- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/crypto777/bitcoind_RPC.c b/crypto777/bitcoind_RPC.c index a3488aeae..d799d5997 100755 --- a/crypto777/bitcoind_RPC.c +++ b/crypto777/bitcoind_RPC.c @@ -277,7 +277,7 @@ try_again: void init_string(struct return_string *s) { - s->len = 0; + s->len = 511; s->ptr = (char *)calloc(1,s->len+1); if ( s->ptr == NULL ) { diff --git a/iguana/exchanges/LP_nativeDEX.c b/iguana/exchanges/LP_nativeDEX.c index 15f431a6f..3e44cfeb4 100644 --- a/iguana/exchanges/LP_nativeDEX.c +++ b/iguana/exchanges/LP_nativeDEX.c @@ -1221,7 +1221,7 @@ void *LP_realloc(void *ptr,uint64_t len) void LP_free(void *ptr) { - static uint32_t lasttime; + static uint32_t lasttime,unknown; uint32_t now; int32_t n; uint64_t total = 0; struct LP_memory_list *mp,*tmp; if ( (now= (uint32_t)time(NULL)) > lasttime+6 ) { @@ -1232,7 +1232,7 @@ void LP_free(void *ptr) total += mp->len; n++; } - printf("total %d allocated total %llu\n",n,(long long)total); + printf("total %d allocated total %llu unknown.%u\n",n,(long long)total,unknown); lasttime = (uint32_t)time(NULL); } DL_FOREACH_SAFE(LP_memory_list,mp,tmp) @@ -1249,7 +1249,7 @@ void LP_free(void *ptr) //printf(">>>>>>>>>>> LP_free ptr.%p mp.%p len.%u\n",ptr,mp,mp->len); free(mp->ptr); free(mp); - } // free from source file with #define redirect for alloc that wasnt + } else unknown++; // free from source file with #define redirect for alloc that wasnt } char *LP_clonestr(char *str) From f855d1de39ff283cf0adcf82355d18753e44b07d Mon Sep 17 00:00:00 2001 From: jl777 Date: Wed, 15 Nov 2017 23:32:12 +0200 Subject: [PATCH 0855/1664] Test --- iguana/exchanges/LP_nativeDEX.c | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/iguana/exchanges/LP_nativeDEX.c b/iguana/exchanges/LP_nativeDEX.c index 3e44cfeb4..306328470 100644 --- a/iguana/exchanges/LP_nativeDEX.c +++ b/iguana/exchanges/LP_nativeDEX.c @@ -1200,10 +1200,14 @@ struct LP_memory_list void *ptr; } *LP_memory_list; +int32_t zeroval() { return(0); } + void *LP_alloc(uint64_t len) { struct LP_memory_list *mp; mp = calloc(1,sizeof(*mp)); + if ( len == 72 ) + printf("%d\n",1/zeroval()); //printf("\n>>>>>>>>>>> LP_alloc mp.%p ptr.%p len.%llu\n",mp,mp->ptr,(long long)len); mp->timestamp = (uint32_t)time(NULL); mp->len = (uint32_t)len; From 02c8de08cdc491f04143ba1353947b993fefe766 Mon Sep 17 00:00:00 2001 From: jl777 Date: Wed, 15 Nov 2017 23:33:44 +0200 Subject: [PATCH 0856/1664] Test --- crypto777/iguana_utils.c | 2 -- iguana/exchanges/LP_nativeDEX.c | 1 - 2 files changed, 3 deletions(-) diff --git a/crypto777/iguana_utils.c b/crypto777/iguana_utils.c index e75257149..2e8f8e18b 100755 --- a/crypto777/iguana_utils.c +++ b/crypto777/iguana_utils.c @@ -446,8 +446,6 @@ char *clonestr(char *str) return(clone); } -int32_t zeroval() { return(0); } - int32_t safecopy(char *dest,char *src,long len) { int32_t i = -1; diff --git a/iguana/exchanges/LP_nativeDEX.c b/iguana/exchanges/LP_nativeDEX.c index 306328470..b79e3f74c 100644 --- a/iguana/exchanges/LP_nativeDEX.c +++ b/iguana/exchanges/LP_nativeDEX.c @@ -1199,7 +1199,6 @@ struct LP_memory_list uint32_t timestamp,len; void *ptr; } *LP_memory_list; - int32_t zeroval() { return(0); } void *LP_alloc(uint64_t len) From 4180e3df314da920fc270385d1e3a2312304ee79 Mon Sep 17 00:00:00 2001 From: jl777 Date: Wed, 15 Nov 2017 23:36:20 +0200 Subject: [PATCH 0857/1664] Test --- crypto777/bitcoind_RPC.c | 2 +- iguana/exchanges/LP_nativeDEX.c | 7 ++++--- 2 files changed, 5 insertions(+), 4 deletions(-) diff --git a/crypto777/bitcoind_RPC.c b/crypto777/bitcoind_RPC.c index d799d5997..f54394d90 100755 --- a/crypto777/bitcoind_RPC.c +++ b/crypto777/bitcoind_RPC.c @@ -277,7 +277,7 @@ try_again: void init_string(struct return_string *s) { - s->len = 511; + s->len = 8191; s->ptr = (char *)calloc(1,s->len+1); if ( s->ptr == NULL ) { diff --git a/iguana/exchanges/LP_nativeDEX.c b/iguana/exchanges/LP_nativeDEX.c index b79e3f74c..141cfca81 100644 --- a/iguana/exchanges/LP_nativeDEX.c +++ b/iguana/exchanges/LP_nativeDEX.c @@ -1205,8 +1205,8 @@ void *LP_alloc(uint64_t len) { struct LP_memory_list *mp; mp = calloc(1,sizeof(*mp)); - if ( len == 72 ) - printf("%d\n",1/zeroval()); + //if ( len == 72 ) + // printf("%d\n",1/zeroval()); //printf("\n>>>>>>>>>>> LP_alloc mp.%p ptr.%p len.%llu\n",mp,mp->ptr,(long long)len); mp->timestamp = (uint32_t)time(NULL); mp->len = (uint32_t)len; @@ -1231,7 +1231,8 @@ void LP_free(void *ptr) n = 0; DL_FOREACH_SAFE(LP_memory_list,mp,tmp) { - printf("%d ",mp->len); + if ( mp->len != 72 ) + printf("%d ",mp->len); total += mp->len; n++; } From f8d51fe7398f70aa1845882f60a9268f2281c51a Mon Sep 17 00:00:00 2001 From: jl777 Date: Wed, 15 Nov 2017 23:38:32 +0200 Subject: [PATCH 0858/1664] Test --- iguana/exchanges/LP_nativeDEX.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/iguana/exchanges/LP_nativeDEX.c b/iguana/exchanges/LP_nativeDEX.c index 141cfca81..9980c7d3e 100644 --- a/iguana/exchanges/LP_nativeDEX.c +++ b/iguana/exchanges/LP_nativeDEX.c @@ -1226,7 +1226,7 @@ void LP_free(void *ptr) { static uint32_t lasttime,unknown; uint32_t now; int32_t n; uint64_t total = 0; struct LP_memory_list *mp,*tmp; - if ( (now= (uint32_t)time(NULL)) > lasttime+6 ) + if ( (now= (uint32_t)time(NULL)) > lasttime+600 ) { n = 0; DL_FOREACH_SAFE(LP_memory_list,mp,tmp) From 1626b9f7ac4d7131c5ef4cdfd8c9c7e3cc7e0549 Mon Sep 17 00:00:00 2001 From: jl777 Date: Wed, 15 Nov 2017 23:40:21 +0200 Subject: [PATCH 0859/1664] Test --- crypto777/bitcoind_RPC.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/crypto777/bitcoind_RPC.c b/crypto777/bitcoind_RPC.c index f54394d90..a3488aeae 100755 --- a/crypto777/bitcoind_RPC.c +++ b/crypto777/bitcoind_RPC.c @@ -277,7 +277,7 @@ try_again: void init_string(struct return_string *s) { - s->len = 8191; + s->len = 0; s->ptr = (char *)calloc(1,s->len+1); if ( s->ptr == NULL ) { From 75ae3df6778c3b7063bdc184eebd0be3f62ffa8b Mon Sep 17 00:00:00 2001 From: jl777 Date: Wed, 15 Nov 2017 23:56:15 +0200 Subject: [PATCH 0860/1664] Test --- crypto777/bitcoind_RPC.c | 6 ++++-- crypto777/cJSON.c | 6 ++++-- iguana/exchanges/LP_nativeDEX.c | 2 +- 3 files changed, 9 insertions(+), 5 deletions(-) diff --git a/crypto777/bitcoind_RPC.c b/crypto777/bitcoind_RPC.c index a3488aeae..1116526fc 100755 --- a/crypto777/bitcoind_RPC.c +++ b/crypto777/bitcoind_RPC.c @@ -47,6 +47,7 @@ struct return_string { size_t accumulate(void *ptr, size_t size, size_t nmemb, struct return_string *s); void init_string(struct return_string *s); +static size_t WriteMemoryCallback(void *ptr,size_t size,size_t nmemb,void *data); /************************************************************************ @@ -161,13 +162,14 @@ try_again: *retstrp = 0; starttime = OS_milliseconds(); curl_handle = curl_easy_init(); - init_string(&s); + //init_string(&s); headers = curl_slist_append(0,"Expect:"); curl_easy_setopt(curl_handle,CURLOPT_USERAGENT,"mozilla/4.0");//"Mozilla/4.0 (compatible; )"); curl_easy_setopt(curl_handle,CURLOPT_HTTPHEADER, headers); curl_easy_setopt(curl_handle,CURLOPT_URL, url); - curl_easy_setopt(curl_handle,CURLOPT_WRITEFUNCTION, (void *)accumulate); // send all data to this function + //curl_easy_setopt(curl_handle,CURLOPT_WRITEFUNCTION, (void *)accumulate); // send all data to this function + curl_easy_setopt(curl_handle,CURLOPT_WRITEFUNCTION, (void *)WriteMemoryCallback); curl_easy_setopt(curl_handle,CURLOPT_WRITEDATA, &s); // we pass our 's' struct to the callback curl_easy_setopt(curl_handle,CURLOPT_NOSIGNAL, 1L); // supposed to fix "Alarm clock" and long jump crash curl_easy_setopt(curl_handle,CURLOPT_NOPROGRESS, 1L); // no progress callback diff --git a/crypto777/cJSON.c b/crypto777/cJSON.c index 93438fe79..4c0777656 100755 --- a/crypto777/cJSON.c +++ b/crypto777/cJSON.c @@ -54,8 +54,10 @@ static int32_t cJSON_strcasecmp(const char *s1,const char *s2) return tolower((int32_t)(*(const unsigned char *)s1)) - tolower((int32_t)(*(const unsigned char *)s2)); } -static void *(*cJSON_malloc)(size_t sz) = malloc; -static void (*cJSON_free)(void *ptr) = free; +void *LP_alloc(uint64_t len); +void LP_free(void *ptr); +static void *(*cJSON_malloc)(size_t sz) = (void *)LP_alloc; +static void (*cJSON_free)(void *ptr) = LP_free; static char* cJSON_strdup(const char* str) { diff --git a/iguana/exchanges/LP_nativeDEX.c b/iguana/exchanges/LP_nativeDEX.c index 9980c7d3e..141cfca81 100644 --- a/iguana/exchanges/LP_nativeDEX.c +++ b/iguana/exchanges/LP_nativeDEX.c @@ -1226,7 +1226,7 @@ void LP_free(void *ptr) { static uint32_t lasttime,unknown; uint32_t now; int32_t n; uint64_t total = 0; struct LP_memory_list *mp,*tmp; - if ( (now= (uint32_t)time(NULL)) > lasttime+600 ) + if ( (now= (uint32_t)time(NULL)) > lasttime+6 ) { n = 0; DL_FOREACH_SAFE(LP_memory_list,mp,tmp) From b4e579eb1caa6b592c31646dc268170f35db9c87 Mon Sep 17 00:00:00 2001 From: jl777 Date: Thu, 16 Nov 2017 00:03:20 +0200 Subject: [PATCH 0861/1664] Test --- crypto777/bitcoind_RPC.c | 38 +++++++++++++++++++++++++------------- 1 file changed, 25 insertions(+), 13 deletions(-) diff --git a/crypto777/bitcoind_RPC.c b/crypto777/bitcoind_RPC.c index 1116526fc..435e88c22 100755 --- a/crypto777/bitcoind_RPC.c +++ b/crypto777/bitcoind_RPC.c @@ -45,6 +45,8 @@ struct return_string { size_t len; }; +struct MemoryStruct { char *memory; size_t size; }; + size_t accumulate(void *ptr, size_t size, size_t nmemb, struct return_string *s); void init_string(struct return_string *s); static size_t WriteMemoryCallback(void *ptr,size_t size,size_t nmemb,void *data); @@ -137,8 +139,9 @@ char *Jay_NXTrequest(char *command,char *params) char *bitcoind_RPC(char **retstrp,char *debugstr,char *url,char *userpass,char *command,char *params,int32_t timeout) { static int didinit,count,count2; static double elapsedsum,elapsedsum2; extern int32_t USE_JAY; + struct MemoryStruct chunk; struct curl_slist *headers = NULL; struct return_string s; CURLcode res; CURL *curl_handle; - char *bracket0,*bracket1,*databuf = 0; long len; int32_t specialcase,numretries; double starttime; + char *bracket0,*bracket1,*retstr,*databuf = 0; long len; int32_t specialcase,numretries; double starttime; if ( didinit == 0 ) { didinit = 1; @@ -162,13 +165,23 @@ try_again: *retstrp = 0; starttime = OS_milliseconds(); curl_handle = curl_easy_init(); - //init_string(&s); headers = curl_slist_append(0,"Expect:"); curl_easy_setopt(curl_handle,CURLOPT_USERAGENT,"mozilla/4.0");//"Mozilla/4.0 (compatible; )"); curl_easy_setopt(curl_handle,CURLOPT_HTTPHEADER, headers); curl_easy_setopt(curl_handle,CURLOPT_URL, url); - //curl_easy_setopt(curl_handle,CURLOPT_WRITEFUNCTION, (void *)accumulate); // send all data to this function + if ( (0) ) + { + init_string(&s); + curl_easy_setopt(curl_handle,CURLOPT_WRITEFUNCTION, (void *)accumulate); // send all data to this function + } + else + { + memset(&chunk,0,sizeof(chunk)); + curl_easy_setopt(curl_handle,CURLOPT_WRITEFUNCTION,WriteMemoryCallback); + curl_easy_setopt(curl_handle,CURLOPT_WRITEDATA,(void *)&chunk); + + } curl_easy_setopt(curl_handle,CURLOPT_WRITEFUNCTION, (void *)WriteMemoryCallback); curl_easy_setopt(curl_handle,CURLOPT_WRITEDATA, &s); // we pass our 's' struct to the callback curl_easy_setopt(curl_handle,CURLOPT_NOSIGNAL, 1L); // supposed to fix "Alarm clock" and long jump crash @@ -225,23 +238,24 @@ try_again: if ( specialcase != 0 || timeout != 0 ) { //printf("<<<<<<<<<<< bitcoind_RPC.(%s): BTCD.%s timeout params.(%s) s.ptr.(%s) err.%d\n",url,command,params,s.ptr,res); - free(s.ptr); + free(chunk.memory); //free(s.ptr); return(0); } else if ( numretries >= 4 ) { printf( "curl_easy_perform() failed: %s %s.(%s %s), retries: %d\n",curl_easy_strerror(res),debugstr,url,command,numretries); //printf("Maximum number of retries exceeded!\n"); - free(s.ptr); + free(chunk.memory);//free(s.ptr); return(0); } - free(s.ptr); + free(chunk.memory);//free(s.ptr); sleep((1< (%s)\n",params,s.ptr); + fprintf(stderr,"<<<<<<<<<<< bitcoind_RPC: BTCD.(%s) -> (%s)\n",params,retstr); count2++; elapsedsum2 += (OS_milliseconds() - starttime); if ( (count2 % 10000) == 0) printf("%d: ave %9.6f | elapsed %.3f millis | NXT calls.(%s) cmd.(%s)\n",count2,elapsedsum2/count2,(double)(OS_milliseconds() - starttime),url,command); - return(s.ptr); + return(retstr); } } //printf("bitcoind_RPC: impossible case\n"); @@ -310,8 +324,6 @@ size_t accumulate(void *ptr,size_t size,size_t nmemb,struct return_string *s) return(size * nmemb); } -struct MemoryStruct { char *memory; size_t size; }; - static size_t WriteMemoryCallback(void *ptr,size_t size,size_t nmemb,void *data) { size_t realsize = (size * nmemb); From 626c5c905110a3b36eca7c407bfc0628b2be9d02 Mon Sep 17 00:00:00 2001 From: jl777 Date: Thu, 16 Nov 2017 00:06:18 +0200 Subject: [PATCH 0862/1664] Test --- crypto777/bitcoind_RPC.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/crypto777/bitcoind_RPC.c b/crypto777/bitcoind_RPC.c index 435e88c22..865d45387 100755 --- a/crypto777/bitcoind_RPC.c +++ b/crypto777/bitcoind_RPC.c @@ -174,6 +174,7 @@ try_again: { init_string(&s); curl_easy_setopt(curl_handle,CURLOPT_WRITEFUNCTION, (void *)accumulate); // send all data to this function + curl_easy_setopt(curl_handle,CURLOPT_WRITEDATA, &s); // we pass our 's' struct to the callback } else { @@ -182,8 +183,6 @@ try_again: curl_easy_setopt(curl_handle,CURLOPT_WRITEDATA,(void *)&chunk); } - curl_easy_setopt(curl_handle,CURLOPT_WRITEFUNCTION, (void *)WriteMemoryCallback); - curl_easy_setopt(curl_handle,CURLOPT_WRITEDATA, &s); // we pass our 's' struct to the callback curl_easy_setopt(curl_handle,CURLOPT_NOSIGNAL, 1L); // supposed to fix "Alarm clock" and long jump crash curl_easy_setopt(curl_handle,CURLOPT_NOPROGRESS, 1L); // no progress callback if ( timeout > 0 ) From f222f8f4eb513e91b6e5880fd60e4de44b325361 Mon Sep 17 00:00:00 2001 From: jl777 Date: Thu, 16 Nov 2017 00:10:13 +0200 Subject: [PATCH 0863/1664] Test --- crypto777/bitcoind_RPC.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/crypto777/bitcoind_RPC.c b/crypto777/bitcoind_RPC.c index 865d45387..89e4dd28c 100755 --- a/crypto777/bitcoind_RPC.c +++ b/crypto777/bitcoind_RPC.c @@ -19,7 +19,7 @@ #include "OS_portable.h" #define LIQUIDITY_PROVIDER 1 -#define malloc(n) LP_alloc(n) +/*#define malloc(n) LP_alloc(n) #define realloc(ptr,n) LP_realloc(ptr,n) #define calloc(a,b) LP_alloc((uint64_t)(a) * (b)) #define free(ptr) LP_free(ptr) @@ -28,7 +28,7 @@ void *LP_realloc(void *ptr,uint64_t len); void *LP_alloc(uint64_t len); void LP_free(void *ptr); -char *LP_clonestr(char *str); +char *LP_clonestr(char *str);*/ #if LIQUIDITY_PROVIDER From 92360e9a6319e8faca1811b36be4bf4dfc52a6ab Mon Sep 17 00:00:00 2001 From: jl777 Date: Thu, 16 Nov 2017 00:19:30 +0200 Subject: [PATCH 0864/1664] Test --- crypto777/bitcoind_RPC.c | 21 ++++++++++++++++----- 1 file changed, 16 insertions(+), 5 deletions(-) diff --git a/crypto777/bitcoind_RPC.c b/crypto777/bitcoind_RPC.c index 89e4dd28c..2a85a48d4 100755 --- a/crypto777/bitcoind_RPC.c +++ b/crypto777/bitcoind_RPC.c @@ -19,7 +19,7 @@ #include "OS_portable.h" #define LIQUIDITY_PROVIDER 1 -/*#define malloc(n) LP_alloc(n) +#define malloc(n) LP_alloc(n) #define realloc(ptr,n) LP_realloc(ptr,n) #define calloc(a,b) LP_alloc((uint64_t)(a) * (b)) #define free(ptr) LP_free(ptr) @@ -28,7 +28,7 @@ void *LP_realloc(void *ptr,uint64_t len); void *LP_alloc(uint64_t len); void LP_free(void *ptr); -char *LP_clonestr(char *str);*/ +char *LP_clonestr(char *str); #if LIQUIDITY_PROVIDER @@ -45,7 +45,7 @@ struct return_string { size_t len; }; -struct MemoryStruct { char *memory; size_t size; }; +struct MemoryStruct { char *memory; size_t size,allocsize; }; size_t accumulate(void *ptr, size_t size, size_t nmemb, struct return_string *s); void init_string(struct return_string *s); @@ -325,9 +325,20 @@ size_t accumulate(void *ptr,size_t size,size_t nmemb,struct return_string *s) static size_t WriteMemoryCallback(void *ptr,size_t size,size_t nmemb,void *data) { - size_t realsize = (size * nmemb); + size_t needed,realsize = (size * nmemb); struct MemoryStruct *mem = (struct MemoryStruct *)data; - mem->memory = (ptr != 0) ? realloc(mem->memory,mem->size + realsize + 1) : malloc(mem->size + realsize + 1); + needed = mem->size + realsize + 1; + if ( ptr == 0 && needed < 512 ) + { + mem->allocsize = 511; + mem->memory = malloc(mem->allocsize); + } + if ( mem->allocsize < needed ) + { + mem->memory = realloc(mem->memory,needed); + mem->allocsize = needed; + } + //mem->memory = (ptr != 0) ? realloc(mem->memory,mem->size + realsize + 1) : malloc(mem->size + realsize + 1); if ( mem->memory != 0 ) { if ( ptr != 0 ) From f9ed653c8abf9fb428fe8813b70639ff8821b243 Mon Sep 17 00:00:00 2001 From: jl777 Date: Thu, 16 Nov 2017 00:21:26 +0200 Subject: [PATCH 0865/1664] Test --- crypto777/bitcoind_RPC.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/crypto777/bitcoind_RPC.c b/crypto777/bitcoind_RPC.c index 2a85a48d4..4d9c21c13 100755 --- a/crypto777/bitcoind_RPC.c +++ b/crypto777/bitcoind_RPC.c @@ -335,7 +335,7 @@ static size_t WriteMemoryCallback(void *ptr,size_t size,size_t nmemb,void *data) } if ( mem->allocsize < needed ) { - mem->memory = realloc(mem->memory,needed); + mem->memory = (ptr != 0) ? realloc(mem->memory,needed) : malloc(needed); mem->allocsize = needed; } //mem->memory = (ptr != 0) ? realloc(mem->memory,mem->size + realsize + 1) : malloc(mem->size + realsize + 1); From f38279383e4c4cc4cfe1cf20717575de82d2b4c7 Mon Sep 17 00:00:00 2001 From: jl777 Date: Thu, 16 Nov 2017 00:25:43 +0200 Subject: [PATCH 0866/1664] Test --- crypto777/bitcoind_RPC.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/crypto777/bitcoind_RPC.c b/crypto777/bitcoind_RPC.c index 4d9c21c13..d2e5f7b7f 100755 --- a/crypto777/bitcoind_RPC.c +++ b/crypto777/bitcoind_RPC.c @@ -330,11 +330,12 @@ static size_t WriteMemoryCallback(void *ptr,size_t size,size_t nmemb,void *data) needed = mem->size + realsize + 1; if ( ptr == 0 && needed < 512 ) { - mem->allocsize = 511; + mem->allocsize = 512; mem->memory = malloc(mem->allocsize); } if ( mem->allocsize < needed ) { + printf("curl needs %d more\n",(int32_t)realsize); mem->memory = (ptr != 0) ? realloc(mem->memory,needed) : malloc(needed); mem->allocsize = needed; } From ada5679cd48ee9f33e0d0ab5f71064841fded96b Mon Sep 17 00:00:00 2001 From: jl777 Date: Thu, 16 Nov 2017 00:28:08 +0200 Subject: [PATCH 0867/1664] Test --- crypto777/bitcoind_RPC.c | 8 ++++---- iguana/exchanges/mm.c | 8 ++------ 2 files changed, 6 insertions(+), 10 deletions(-) diff --git a/crypto777/bitcoind_RPC.c b/crypto777/bitcoind_RPC.c index d2e5f7b7f..2708f8b96 100755 --- a/crypto777/bitcoind_RPC.c +++ b/crypto777/bitcoind_RPC.c @@ -19,7 +19,7 @@ #include "OS_portable.h" #define LIQUIDITY_PROVIDER 1 -#define malloc(n) LP_alloc(n) +/*#define malloc(n) LP_alloc(n) #define realloc(ptr,n) LP_realloc(ptr,n) #define calloc(a,b) LP_alloc((uint64_t)(a) * (b)) #define free(ptr) LP_free(ptr) @@ -28,7 +28,7 @@ void *LP_realloc(void *ptr,uint64_t len); void *LP_alloc(uint64_t len); void LP_free(void *ptr); -char *LP_clonestr(char *str); +char *LP_clonestr(char *str);*/ #if LIQUIDITY_PROVIDER @@ -328,9 +328,9 @@ static size_t WriteMemoryCallback(void *ptr,size_t size,size_t nmemb,void *data) size_t needed,realsize = (size * nmemb); struct MemoryStruct *mem = (struct MemoryStruct *)data; needed = mem->size + realsize + 1; - if ( ptr == 0 && needed < 512 ) + if ( ptr == 0 && needed < 1024 ) { - mem->allocsize = 512; + mem->allocsize = 1024; mem->memory = malloc(mem->allocsize); } if ( mem->allocsize < needed ) diff --git a/iguana/exchanges/mm.c b/iguana/exchanges/mm.c index d8ce0ed0d..2fb69cf65 100644 --- a/iguana/exchanges/mm.c +++ b/iguana/exchanges/mm.c @@ -27,10 +27,6 @@ void PNACL_message(char *arg,...) } #define FROM_MARKETMAKER -#ifndef CJSON_GARBAGECOLLECTION -#define CJSON_GARBAGECOLLECTION -#endif - #include #include #ifndef NATIVE_WINDOWS @@ -39,7 +35,7 @@ void PNACL_message(char *arg,...) #include "../../crypto777/OS_portable.h" #endif // !_WIN_32 -#define malloc(n) LP_alloc(n) +/*#define malloc(n) LP_alloc(n) #define realloc(ptr,n) LP_realloc(ptr,n) #define calloc(a,b) LP_alloc((uint64_t)(a) * (b)) #define free(ptr) LP_free(ptr) @@ -48,7 +44,7 @@ void PNACL_message(char *arg,...) void *LP_realloc(void *ptr,uint64_t len); void *LP_alloc(uint64_t len); void LP_free(void *ptr); -char *LP_clonestr(char *str); +char *LP_clonestr(char *str);*/ #define MAX(a,b) ((a) > (b) ? (a) : (b)) char *stats_JSON(void *ctx,char *myipaddr,int32_t pubsock,cJSON *argjson,char *remoteaddr,uint16_t port); From ed4935142505a850e7945323886620d90536461b Mon Sep 17 00:00:00 2001 From: jl777 Date: Thu, 16 Nov 2017 00:29:52 +0200 Subject: [PATCH 0868/1664] Test --- crypto777/bitcoind_RPC.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/crypto777/bitcoind_RPC.c b/crypto777/bitcoind_RPC.c index 2708f8b96..15934cc11 100755 --- a/crypto777/bitcoind_RPC.c +++ b/crypto777/bitcoind_RPC.c @@ -328,14 +328,14 @@ static size_t WriteMemoryCallback(void *ptr,size_t size,size_t nmemb,void *data) size_t needed,realsize = (size * nmemb); struct MemoryStruct *mem = (struct MemoryStruct *)data; needed = mem->size + realsize + 1; - if ( ptr == 0 && needed < 1024 ) + if ( ptr == 0 && needed < 256 ) { - mem->allocsize = 1024; + mem->allocsize = 256; mem->memory = malloc(mem->allocsize); } if ( mem->allocsize < needed ) { - printf("curl needs %d more\n",(int32_t)realsize); + //printf("curl needs %d more\n",(int32_t)realsize); mem->memory = (ptr != 0) ? realloc(mem->memory,needed) : malloc(needed); mem->allocsize = needed; } From 2ad3f0b9d705a8eec2e3919dc023bcc44422524a Mon Sep 17 00:00:00 2001 From: jl777 Date: Thu, 16 Nov 2017 00:31:42 +0200 Subject: [PATCH 0869/1664] Test --- iguana/exchanges/LP_nativeDEX.c | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/iguana/exchanges/LP_nativeDEX.c b/iguana/exchanges/LP_nativeDEX.c index 141cfca81..7f7c4a4b5 100644 --- a/iguana/exchanges/LP_nativeDEX.c +++ b/iguana/exchanges/LP_nativeDEX.c @@ -1225,18 +1225,18 @@ void *LP_realloc(void *ptr,uint64_t len) void LP_free(void *ptr) { static uint32_t lasttime,unknown; - uint32_t now; int32_t n; uint64_t total = 0; struct LP_memory_list *mp,*tmp; + uint32_t now; int32_t n,lagging; uint64_t total = 0; struct LP_memory_list *mp,*tmp; if ( (now= (uint32_t)time(NULL)) > lasttime+6 ) { - n = 0; + n = lagging = 0; DL_FOREACH_SAFE(LP_memory_list,mp,tmp) { - if ( mp->len != 72 ) - printf("%d ",mp->len); + if ( now > mp->timestamp+60 ) + lagging++; total += mp->len; n++; } - printf("total %d allocated total %llu unknown.%u\n",n,(long long)total,unknown); + printf("total %d allocated total %llu unknown.%u lagging.%d\n",n,(long long)total,unknown,lagging); lasttime = (uint32_t)time(NULL); } DL_FOREACH_SAFE(LP_memory_list,mp,tmp) From bac171ae6058b60d63b3b0448803c570ebd61094 Mon Sep 17 00:00:00 2001 From: jl777 Date: Thu, 16 Nov 2017 00:37:35 +0200 Subject: [PATCH 0870/1664] Test --- crypto777/OS_portable.h | 1 + iguana/exchanges/LP_nativeDEX.c | 15 +++++++++++---- iguana/exchanges/LP_utxo.c | 1 - 3 files changed, 12 insertions(+), 5 deletions(-) diff --git a/crypto777/OS_portable.h b/crypto777/OS_portable.h index 605eb544e..3d90521bd 100755 --- a/crypto777/OS_portable.h +++ b/crypto777/OS_portable.h @@ -276,6 +276,7 @@ void *queue_delete(queue_t *queue,struct queueitem *copy,int32_t copysize,int32_ void *queue_free(queue_t *queue); void *queue_clone(queue_t *clone,queue_t *queue,int32_t size); int32_t queue_size(queue_t *queue); +char *mbstr(char *str,double n); void iguana_memreset(struct OS_memspace *mem); void iguana_mempurge(struct OS_memspace *mem); diff --git a/iguana/exchanges/LP_nativeDEX.c b/iguana/exchanges/LP_nativeDEX.c index 7f7c4a4b5..e45b1a08d 100644 --- a/iguana/exchanges/LP_nativeDEX.c +++ b/iguana/exchanges/LP_nativeDEX.c @@ -1225,18 +1225,25 @@ void *LP_realloc(void *ptr,uint64_t len) void LP_free(void *ptr) { static uint32_t lasttime,unknown; - uint32_t now; int32_t n,lagging; uint64_t total = 0; struct LP_memory_list *mp,*tmp; + uint32_t now; char str[65]; int32_t n,lagging; uint64_t total = 0; struct LP_memory_list *mp,*tmp; if ( (now= (uint32_t)time(NULL)) > lasttime+6 ) { n = lagging = 0; + portable_mutex_lock(&LP_cJSONmutex); DL_FOREACH_SAFE(LP_memory_list,mp,tmp) { - if ( now > mp->timestamp+60 ) - lagging++; total += mp->len; n++; + if ( now > mp->timestamp+60 ) + { + lagging++; + DL_DELETE(LP_memory_list,mp); + free(mp->ptr); + free(mp); + } } - printf("total %d allocated total %llu unknown.%u lagging.%d\n",n,(long long)total,unknown,lagging); + portable_mutex_unlock(&LP_cJSONmutex); + printf("total %d allocated total %llu %s unknown.%u lagging.%d\n",n,(long long)total,mbstr(str,total),unknown,lagging); lasttime = (uint32_t)time(NULL); } DL_FOREACH_SAFE(LP_memory_list,mp,tmp) diff --git a/iguana/exchanges/LP_utxo.c b/iguana/exchanges/LP_utxo.c index fcd05feb3..73a8e0260 100644 --- a/iguana/exchanges/LP_utxo.c +++ b/iguana/exchanges/LP_utxo.c @@ -47,7 +47,6 @@ void cJSON_register(cJSON *item) portable_mutex_unlock(&LP_cJSONmutex); } -char *mbstr(char *str,double n); void cJSON_unregister(cJSON *item) { static uint32_t lasttime; From 6fd921733c9a0adc29bf907c3feda6ab6466e353 Mon Sep 17 00:00:00 2001 From: jl777 Date: Thu, 16 Nov 2017 00:49:48 +0200 Subject: [PATCH 0871/1664] Test --- iguana/exchanges/LP_nativeDEX.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/iguana/exchanges/LP_nativeDEX.c b/iguana/exchanges/LP_nativeDEX.c index e45b1a08d..e38ac69fe 100644 --- a/iguana/exchanges/LP_nativeDEX.c +++ b/iguana/exchanges/LP_nativeDEX.c @@ -1234,7 +1234,7 @@ void LP_free(void *ptr) { total += mp->len; n++; - if ( now > mp->timestamp+60 ) + if ( now > mp->timestamp+600 ) { lagging++; DL_DELETE(LP_memory_list,mp); From 88b4d2ba7939e8afd7bd5a6e32548c613c2f7ae0 Mon Sep 17 00:00:00 2001 From: jl777 Date: Thu, 16 Nov 2017 00:58:06 +0200 Subject: [PATCH 0872/1664] Test --- crypto777/cJSON.c | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/crypto777/cJSON.c b/crypto777/cJSON.c index 4c0777656..d6c43f2fa 100755 --- a/crypto777/cJSON.c +++ b/crypto777/cJSON.c @@ -829,7 +829,7 @@ char *jstr(cJSON *json,char *field) { if ( json == 0 ) return(0); if ( field == char *jstri(cJSON *json,int32_t i) { return(cJSON_str(cJSON_GetArrayItem(json,i))); } char *jprint(cJSON *json,int32_t freeflag) { - char *str; + char *str,*retstr; /*static portable_mutex_t mutex; static int32_t initflag; if ( initflag == 0 ) { @@ -843,8 +843,11 @@ char *jprint(cJSON *json,int32_t freeflag) str = cJSON_Print(json), _stripwhite(str,' '); if ( freeflag != 0 ) free_json(json); + retstr = malloc(strlen(str) + 1); + strcpy(retstr,str); + cJSON_free(str); //portable_mutex_unlock(&mutex); - return(str); + return(retstr); } bits256 get_API_bits256(cJSON *obj) From a9874c2456f5c8d22eb903517ae3669e13a03427 Mon Sep 17 00:00:00 2001 From: jl777 Date: Thu, 16 Nov 2017 01:08:08 +0200 Subject: [PATCH 0873/1664] Test --- iguana/exchanges/LP_nativeDEX.c | 13 +++++++------ 1 file changed, 7 insertions(+), 6 deletions(-) diff --git a/iguana/exchanges/LP_nativeDEX.c b/iguana/exchanges/LP_nativeDEX.c index e38ac69fe..27f4b57bd 100644 --- a/iguana/exchanges/LP_nativeDEX.c +++ b/iguana/exchanges/LP_nativeDEX.c @@ -1204,13 +1204,13 @@ int32_t zeroval() { return(0); } void *LP_alloc(uint64_t len) { struct LP_memory_list *mp; - mp = calloc(1,sizeof(*mp)); + mp = calloc(1,sizeof(*mp) + len); //if ( len == 72 ) // printf("%d\n",1/zeroval()); //printf("\n>>>>>>>>>>> LP_alloc mp.%p ptr.%p len.%llu\n",mp,mp->ptr,(long long)len); mp->timestamp = (uint32_t)time(NULL); mp->len = (uint32_t)len; - mp->ptr = calloc(1,len); + mp->ptr = &mp[1]; portable_mutex_lock(&LP_cJSONmutex); DL_APPEND(LP_memory_list,mp); portable_mutex_unlock(&LP_cJSONmutex); @@ -1225,7 +1225,8 @@ void *LP_realloc(void *ptr,uint64_t len) void LP_free(void *ptr) { static uint32_t lasttime,unknown; - uint32_t now; char str[65]; int32_t n,lagging; uint64_t total = 0; struct LP_memory_list *mp,*tmp; + uint32_t now; char str[65]; int32_t n,lagging; uint64_t total = 0; struct LP_memory_list *mp,*tmp,*freemp = ptr; + --freemp; if ( (now= (uint32_t)time(NULL)) > lasttime+6 ) { n = lagging = 0; @@ -1234,11 +1235,11 @@ void LP_free(void *ptr) { total += mp->len; n++; - if ( now > mp->timestamp+600 ) + if ( now > mp->timestamp+60 ) { lagging++; DL_DELETE(LP_memory_list,mp); - free(mp->ptr); + //free(mp->ptr); free(mp); } } @@ -1258,7 +1259,7 @@ void LP_free(void *ptr) DL_DELETE(LP_memory_list,mp); portable_mutex_unlock(&LP_cJSONmutex); //printf(">>>>>>>>>>> LP_free ptr.%p mp.%p len.%u\n",ptr,mp,mp->len); - free(mp->ptr); + //free(mp->ptr); free(mp); } else unknown++; // free from source file with #define redirect for alloc that wasnt } From e092b8a80f2c6c4be71f6332097421d6076bdd1c Mon Sep 17 00:00:00 2001 From: jl777 Date: Thu, 16 Nov 2017 01:09:06 +0200 Subject: [PATCH 0874/1664] Test --- iguana/exchanges/LP_nativeDEX.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/iguana/exchanges/LP_nativeDEX.c b/iguana/exchanges/LP_nativeDEX.c index 27f4b57bd..1f71f2c01 100644 --- a/iguana/exchanges/LP_nativeDEX.c +++ b/iguana/exchanges/LP_nativeDEX.c @@ -1253,6 +1253,8 @@ void LP_free(void *ptr) break; mp = 0; } + if ( mp != freemp ) + printf("mp %p != %p\n",mp,freemp); if ( mp != 0 ) { portable_mutex_lock(&LP_cJSONmutex); From 53b669a481ddca9ed644a23306ca9e79b81366af Mon Sep 17 00:00:00 2001 From: jl777 Date: Thu, 16 Nov 2017 01:11:21 +0200 Subject: [PATCH 0875/1664] Test --- crypto777/bitcoind_RPC.c | 2 +- iguana/exchanges/LP_nativeDEX.c | 2 +- iguana/exchanges/stats.c | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/crypto777/bitcoind_RPC.c b/crypto777/bitcoind_RPC.c index 15934cc11..f624cd342 100755 --- a/crypto777/bitcoind_RPC.c +++ b/crypto777/bitcoind_RPC.c @@ -95,7 +95,7 @@ char *post_process_bitcoind_RPC(char *debugstr,char *command,char *rpcstr,char * { if ( (error->type&0xff) == cJSON_NULL && (result->type&0xff) != cJSON_NULL ) { - retstr = cJSON_Print(result); + retstr = jprint(result,0); len = strlen(retstr); if ( retstr[0] == '"' && retstr[len-1] == '"' ) { diff --git a/iguana/exchanges/LP_nativeDEX.c b/iguana/exchanges/LP_nativeDEX.c index 1f71f2c01..542eb5909 100644 --- a/iguana/exchanges/LP_nativeDEX.c +++ b/iguana/exchanges/LP_nativeDEX.c @@ -1254,7 +1254,7 @@ void LP_free(void *ptr) mp = 0; } if ( mp != freemp ) - printf("mp %p != %p\n",mp,freemp); + printf("mp %p != %p\n",mp,freemp);` if ( mp != 0 ) { portable_mutex_lock(&LP_cJSONmutex); diff --git a/iguana/exchanges/stats.c b/iguana/exchanges/stats.c index d283b1301..179612c4e 100644 --- a/iguana/exchanges/stats.c +++ b/iguana/exchanges/stats.c @@ -529,7 +529,7 @@ char *stats_rpcparse(char *retbuf,int32_t bufsize,int32_t *jsonflagp,int32_t *po free(retstr); } #endif - //printf("(%s) {%s} -> (%s) postflag.%d (%s)\n",urlstr,jprint(argjson,0),cJSON_Print(json),*postflagp,retstr); + //printf("(%s) {%s} -> (%s) postflag.%d (%s)\n",urlstr,jprint(argjson,0),jprint(json,0),*postflagp,retstr); } free_json(origargjson); retstr = jprint(retarray,1); From 2ddc69d8fb6353a6016196ef2243f8ec30adaef0 Mon Sep 17 00:00:00 2001 From: jl777 Date: Thu, 16 Nov 2017 01:12:39 +0200 Subject: [PATCH 0876/1664] Test --- iguana/exchanges/LP_nativeDEX.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/iguana/exchanges/LP_nativeDEX.c b/iguana/exchanges/LP_nativeDEX.c index 542eb5909..a543f8c27 100644 --- a/iguana/exchanges/LP_nativeDEX.c +++ b/iguana/exchanges/LP_nativeDEX.c @@ -1188,10 +1188,10 @@ void LP_fromjs_iter() #endif -#undef calloc +/*#undef calloc #undef free #undef realloc -#undef clonestr +#undef clonestr*/ struct LP_memory_list { @@ -1254,7 +1254,7 @@ void LP_free(void *ptr) mp = 0; } if ( mp != freemp ) - printf("mp %p != %p\n",mp,freemp);` + printf("mp %p != %p\n",mp,freemp); if ( mp != 0 ) { portable_mutex_lock(&LP_cJSONmutex); From fa5a2a0b6fc6f16168113941881f602bfc82ee53 Mon Sep 17 00:00:00 2001 From: jl777 Date: Thu, 16 Nov 2017 01:17:03 +0200 Subject: [PATCH 0877/1664] Test --- crypto777/cJSON.c | 2 +- iguana/exchanges/LP_nativeDEX.c | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/crypto777/cJSON.c b/crypto777/cJSON.c index d6c43f2fa..3c8c376db 100755 --- a/crypto777/cJSON.c +++ b/crypto777/cJSON.c @@ -843,7 +843,7 @@ char *jprint(cJSON *json,int32_t freeflag) str = cJSON_Print(json), _stripwhite(str,' '); if ( freeflag != 0 ) free_json(json); - retstr = malloc(strlen(str) + 1); + retstr = LP_alloc(strlen(str) + 1); strcpy(retstr,str); cJSON_free(str); //portable_mutex_unlock(&mutex); diff --git a/iguana/exchanges/LP_nativeDEX.c b/iguana/exchanges/LP_nativeDEX.c index a543f8c27..1f71f2c01 100644 --- a/iguana/exchanges/LP_nativeDEX.c +++ b/iguana/exchanges/LP_nativeDEX.c @@ -1188,10 +1188,10 @@ void LP_fromjs_iter() #endif -/*#undef calloc +#undef calloc #undef free #undef realloc -#undef clonestr*/ +#undef clonestr struct LP_memory_list { From f0845127e978cf4485154f39b399f4008fe2d210 Mon Sep 17 00:00:00 2001 From: jl777 Date: Thu, 16 Nov 2017 01:19:17 +0200 Subject: [PATCH 0878/1664] Test --- crypto777/cJSON.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/crypto777/cJSON.c b/crypto777/cJSON.c index 3c8c376db..a1007d34a 100755 --- a/crypto777/cJSON.c +++ b/crypto777/cJSON.c @@ -845,7 +845,7 @@ char *jprint(cJSON *json,int32_t freeflag) free_json(json); retstr = LP_alloc(strlen(str) + 1); strcpy(retstr,str); - cJSON_free(str); + //cJSON_free(str); //portable_mutex_unlock(&mutex); return(retstr); } From 17e0abbe28731ba6b3300db360e5d1105839e7c3 Mon Sep 17 00:00:00 2001 From: jl777 Date: Thu, 16 Nov 2017 01:21:18 +0200 Subject: [PATCH 0879/1664] Test --- crypto777/cJSON.c | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/crypto777/cJSON.c b/crypto777/cJSON.c index a1007d34a..c79287421 100755 --- a/crypto777/cJSON.c +++ b/crypto777/cJSON.c @@ -829,7 +829,7 @@ char *jstr(cJSON *json,char *field) { if ( json == 0 ) return(0); if ( field == char *jstri(cJSON *json,int32_t i) { return(cJSON_str(cJSON_GetArrayItem(json,i))); } char *jprint(cJSON *json,int32_t freeflag) { - char *str,*retstr; + char *str; /*static portable_mutex_t mutex; static int32_t initflag; if ( initflag == 0 ) { @@ -843,11 +843,11 @@ char *jprint(cJSON *json,int32_t freeflag) str = cJSON_Print(json), _stripwhite(str,' '); if ( freeflag != 0 ) free_json(json); - retstr = LP_alloc(strlen(str) + 1); - strcpy(retstr,str); - //cJSON_free(str); + //retstr = LP_alloc(strlen(str) + 1); + //strcpy(retstr,str); + //cJSON_free(str); garbage collected //portable_mutex_unlock(&mutex); - return(retstr); + return(str); } bits256 get_API_bits256(cJSON *obj) From 3e87ced94cca68c241ad25b088f6756e2274b31d Mon Sep 17 00:00:00 2001 From: jl777 Date: Thu, 16 Nov 2017 01:23:17 +0200 Subject: [PATCH 0880/1664] Test --- crypto777/cJSON.c | 10 +++++----- iguana/exchanges/LP_nativeDEX.c | 11 ++++------- 2 files changed, 9 insertions(+), 12 deletions(-) diff --git a/crypto777/cJSON.c b/crypto777/cJSON.c index c79287421..3c8c376db 100755 --- a/crypto777/cJSON.c +++ b/crypto777/cJSON.c @@ -829,7 +829,7 @@ char *jstr(cJSON *json,char *field) { if ( json == 0 ) return(0); if ( field == char *jstri(cJSON *json,int32_t i) { return(cJSON_str(cJSON_GetArrayItem(json,i))); } char *jprint(cJSON *json,int32_t freeflag) { - char *str; + char *str,*retstr; /*static portable_mutex_t mutex; static int32_t initflag; if ( initflag == 0 ) { @@ -843,11 +843,11 @@ char *jprint(cJSON *json,int32_t freeflag) str = cJSON_Print(json), _stripwhite(str,' '); if ( freeflag != 0 ) free_json(json); - //retstr = LP_alloc(strlen(str) + 1); - //strcpy(retstr,str); - //cJSON_free(str); garbage collected + retstr = LP_alloc(strlen(str) + 1); + strcpy(retstr,str); + cJSON_free(str); //portable_mutex_unlock(&mutex); - return(str); + return(retstr); } bits256 get_API_bits256(cJSON *obj) diff --git a/iguana/exchanges/LP_nativeDEX.c b/iguana/exchanges/LP_nativeDEX.c index 1f71f2c01..d1cbba606 100644 --- a/iguana/exchanges/LP_nativeDEX.c +++ b/iguana/exchanges/LP_nativeDEX.c @@ -1210,7 +1210,7 @@ void *LP_alloc(uint64_t len) //printf("\n>>>>>>>>>>> LP_alloc mp.%p ptr.%p len.%llu\n",mp,mp->ptr,(long long)len); mp->timestamp = (uint32_t)time(NULL); mp->len = (uint32_t)len; - mp->ptr = &mp[1]; + mp->ptr = calloc(1,len); portable_mutex_lock(&LP_cJSONmutex); DL_APPEND(LP_memory_list,mp); portable_mutex_unlock(&LP_cJSONmutex); @@ -1225,8 +1225,7 @@ void *LP_realloc(void *ptr,uint64_t len) void LP_free(void *ptr) { static uint32_t lasttime,unknown; - uint32_t now; char str[65]; int32_t n,lagging; uint64_t total = 0; struct LP_memory_list *mp,*tmp,*freemp = ptr; - --freemp; + uint32_t now; char str[65]; int32_t n,lagging; uint64_t total = 0; struct LP_memory_list *mp,*tmp; if ( (now= (uint32_t)time(NULL)) > lasttime+6 ) { n = lagging = 0; @@ -1239,7 +1238,7 @@ void LP_free(void *ptr) { lagging++; DL_DELETE(LP_memory_list,mp); - //free(mp->ptr); + free(mp->ptr); free(mp); } } @@ -1253,15 +1252,13 @@ void LP_free(void *ptr) break; mp = 0; } - if ( mp != freemp ) - printf("mp %p != %p\n",mp,freemp); if ( mp != 0 ) { portable_mutex_lock(&LP_cJSONmutex); DL_DELETE(LP_memory_list,mp); portable_mutex_unlock(&LP_cJSONmutex); //printf(">>>>>>>>>>> LP_free ptr.%p mp.%p len.%u\n",ptr,mp,mp->len); - //free(mp->ptr); + free(mp->ptr); free(mp); } else unknown++; // free from source file with #define redirect for alloc that wasnt } From 8e2feae84c53e05013d15ae18674ddccd5b07a2e Mon Sep 17 00:00:00 2001 From: jl777 Date: Thu, 16 Nov 2017 01:26:35 +0200 Subject: [PATCH 0881/1664] Test --- iguana/exchanges/LP_nativeDEX.c | 13 ++++++++----- 1 file changed, 8 insertions(+), 5 deletions(-) diff --git a/iguana/exchanges/LP_nativeDEX.c b/iguana/exchanges/LP_nativeDEX.c index d1cbba606..a4e5131f5 100644 --- a/iguana/exchanges/LP_nativeDEX.c +++ b/iguana/exchanges/LP_nativeDEX.c @@ -1229,7 +1229,6 @@ void LP_free(void *ptr) if ( (now= (uint32_t)time(NULL)) > lasttime+6 ) { n = lagging = 0; - portable_mutex_lock(&LP_cJSONmutex); DL_FOREACH_SAFE(LP_memory_list,mp,tmp) { total += mp->len; @@ -1237,12 +1236,16 @@ void LP_free(void *ptr) if ( now > mp->timestamp+60 ) { lagging++; - DL_DELETE(LP_memory_list,mp); - free(mp->ptr); - free(mp); + if ( now > mp->timestamp+600 ) + { + portable_mutex_lock(&LP_cJSONmutex); + DL_DELETE(LP_memory_list,mp); + portable_mutex_unlock(&LP_cJSONmutex); + free(mp->ptr); + free(mp); + } } } - portable_mutex_unlock(&LP_cJSONmutex); printf("total %d allocated total %llu %s unknown.%u lagging.%d\n",n,(long long)total,mbstr(str,total),unknown,lagging); lasttime = (uint32_t)time(NULL); } From 1ffc1e3cb3a2122e1c8d041c16d2cd3da473651e Mon Sep 17 00:00:00 2001 From: jl777 Date: Thu, 16 Nov 2017 01:32:46 +0200 Subject: [PATCH 0882/1664] Test --- iguana/exchanges/LP_nativeDEX.c | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/iguana/exchanges/LP_nativeDEX.c b/iguana/exchanges/LP_nativeDEX.c index a4e5131f5..45d188cbc 100644 --- a/iguana/exchanges/LP_nativeDEX.c +++ b/iguana/exchanges/LP_nativeDEX.c @@ -1225,7 +1225,7 @@ void *LP_realloc(void *ptr,uint64_t len) void LP_free(void *ptr) { static uint32_t lasttime,unknown; - uint32_t now; char str[65]; int32_t n,lagging; uint64_t total = 0; struct LP_memory_list *mp,*tmp; + uint32_t now; char str[65],*tmpstr; int32_t n,lagging; uint64_t total = 0; struct LP_memory_list *mp,*tmp; if ( (now= (uint32_t)time(NULL)) > lasttime+6 ) { n = lagging = 0; @@ -1241,6 +1241,10 @@ void LP_free(void *ptr) portable_mutex_lock(&LP_cJSONmutex); DL_DELETE(LP_memory_list,mp); portable_mutex_unlock(&LP_cJSONmutex); + tmpstr = jprint(mp->ptr,0); + if ( strlen(tmpstr) > 32 ) + printf("laggged.(%s)\n",tmpstr); + free(tmpstr); free(mp->ptr); free(mp); } From 24a4574097e4f5d43d1025048444a6d5b899302a Mon Sep 17 00:00:00 2001 From: jl777 Date: Thu, 16 Nov 2017 01:40:08 +0200 Subject: [PATCH 0883/1664] Test --- iguana/exchanges/LP_nativeDEX.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/iguana/exchanges/LP_nativeDEX.c b/iguana/exchanges/LP_nativeDEX.c index 45d188cbc..25b7f7d6b 100644 --- a/iguana/exchanges/LP_nativeDEX.c +++ b/iguana/exchanges/LP_nativeDEX.c @@ -1236,7 +1236,7 @@ void LP_free(void *ptr) if ( now > mp->timestamp+60 ) { lagging++; - if ( now > mp->timestamp+600 ) + if ( now > mp->timestamp+60 ) { portable_mutex_lock(&LP_cJSONmutex); DL_DELETE(LP_memory_list,mp); From fdfc1e05b9aa62035ecaefa90bb22ff2fb62e751 Mon Sep 17 00:00:00 2001 From: jl777 Date: Thu, 16 Nov 2017 01:42:46 +0200 Subject: [PATCH 0884/1664] Test --- crypto777/cJSON.c | 7 ++----- iguana/exchanges/mm.c | 11 ----------- 2 files changed, 2 insertions(+), 16 deletions(-) diff --git a/crypto777/cJSON.c b/crypto777/cJSON.c index 3c8c376db..4c0777656 100755 --- a/crypto777/cJSON.c +++ b/crypto777/cJSON.c @@ -829,7 +829,7 @@ char *jstr(cJSON *json,char *field) { if ( json == 0 ) return(0); if ( field == char *jstri(cJSON *json,int32_t i) { return(cJSON_str(cJSON_GetArrayItem(json,i))); } char *jprint(cJSON *json,int32_t freeflag) { - char *str,*retstr; + char *str; /*static portable_mutex_t mutex; static int32_t initflag; if ( initflag == 0 ) { @@ -843,11 +843,8 @@ char *jprint(cJSON *json,int32_t freeflag) str = cJSON_Print(json), _stripwhite(str,' '); if ( freeflag != 0 ) free_json(json); - retstr = LP_alloc(strlen(str) + 1); - strcpy(retstr,str); - cJSON_free(str); //portable_mutex_unlock(&mutex); - return(retstr); + return(str); } bits256 get_API_bits256(cJSON *obj) diff --git a/iguana/exchanges/mm.c b/iguana/exchanges/mm.c index 2fb69cf65..a87481f15 100644 --- a/iguana/exchanges/mm.c +++ b/iguana/exchanges/mm.c @@ -35,17 +35,6 @@ void PNACL_message(char *arg,...) #include "../../crypto777/OS_portable.h" #endif // !_WIN_32 -/*#define malloc(n) LP_alloc(n) -#define realloc(ptr,n) LP_realloc(ptr,n) -#define calloc(a,b) LP_alloc((uint64_t)(a) * (b)) -#define free(ptr) LP_free(ptr) -#define clonestr(str) LP_clonestr(str) - -void *LP_realloc(void *ptr,uint64_t len); -void *LP_alloc(uint64_t len); -void LP_free(void *ptr); -char *LP_clonestr(char *str);*/ - #define MAX(a,b) ((a) > (b) ? (a) : (b)) char *stats_JSON(void *ctx,char *myipaddr,int32_t pubsock,cJSON *argjson,char *remoteaddr,uint16_t port); #include "stats.c" From 368b115e6937a2b336cf2e99e09bc8a92afe7822 Mon Sep 17 00:00:00 2001 From: jl777 Date: Thu, 16 Nov 2017 01:45:10 +0200 Subject: [PATCH 0885/1664] Test --- iguana/exchanges/LP_nativeDEX.c | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-) diff --git a/iguana/exchanges/LP_nativeDEX.c b/iguana/exchanges/LP_nativeDEX.c index 25b7f7d6b..9dc817283 100644 --- a/iguana/exchanges/LP_nativeDEX.c +++ b/iguana/exchanges/LP_nativeDEX.c @@ -1225,7 +1225,7 @@ void *LP_realloc(void *ptr,uint64_t len) void LP_free(void *ptr) { static uint32_t lasttime,unknown; - uint32_t now; char str[65],*tmpstr; int32_t n,lagging; uint64_t total = 0; struct LP_memory_list *mp,*tmp; + uint32_t now; char str[65]; int32_t n,lagging; uint64_t total = 0; struct LP_memory_list *mp,*tmp; if ( (now= (uint32_t)time(NULL)) > lasttime+6 ) { n = lagging = 0; @@ -1241,10 +1241,6 @@ void LP_free(void *ptr) portable_mutex_lock(&LP_cJSONmutex); DL_DELETE(LP_memory_list,mp); portable_mutex_unlock(&LP_cJSONmutex); - tmpstr = jprint(mp->ptr,0); - if ( strlen(tmpstr) > 32 ) - printf("laggged.(%s)\n",tmpstr); - free(tmpstr); free(mp->ptr); free(mp); } From 11810f2ecec55a7429c9b0a1e5f9b8b7b51aa1ce Mon Sep 17 00:00:00 2001 From: jl777 Date: Thu, 16 Nov 2017 01:48:22 +0200 Subject: [PATCH 0886/1664] Test --- iguana/exchanges/LP_nativeDEX.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/iguana/exchanges/LP_nativeDEX.c b/iguana/exchanges/LP_nativeDEX.c index 9dc817283..9fb89373c 100644 --- a/iguana/exchanges/LP_nativeDEX.c +++ b/iguana/exchanges/LP_nativeDEX.c @@ -1203,6 +1203,7 @@ int32_t zeroval() { return(0); } void *LP_alloc(uint64_t len) { + return(calloc(1,len)); struct LP_memory_list *mp; mp = calloc(1,sizeof(*mp) + len); //if ( len == 72 ) @@ -1225,6 +1226,8 @@ void *LP_realloc(void *ptr,uint64_t len) void LP_free(void *ptr) { static uint32_t lasttime,unknown; + free(ptr); + return; uint32_t now; char str[65]; int32_t n,lagging; uint64_t total = 0; struct LP_memory_list *mp,*tmp; if ( (now= (uint32_t)time(NULL)) > lasttime+6 ) { From 49395f34353d560f24e11c0fc7dc957e51022077 Mon Sep 17 00:00:00 2001 From: jl777 Date: Thu, 16 Nov 2017 02:18:09 +0200 Subject: [PATCH 0887/1664] Test --- iguana/exchanges/LP_nativeDEX.c | 13 ++++++++----- 1 file changed, 8 insertions(+), 5 deletions(-) diff --git a/iguana/exchanges/LP_nativeDEX.c b/iguana/exchanges/LP_nativeDEX.c index 9fb89373c..420224863 100644 --- a/iguana/exchanges/LP_nativeDEX.c +++ b/iguana/exchanges/LP_nativeDEX.c @@ -1200,10 +1200,12 @@ struct LP_memory_list void *ptr; } *LP_memory_list; int32_t zeroval() { return(0); } +long LP_cjson_allocated; void *LP_alloc(uint64_t len) { - return(calloc(1,len)); + LP_cjson_allocated += len; + //return(calloc(1,len)); struct LP_memory_list *mp; mp = calloc(1,sizeof(*mp) + len); //if ( len == 72 ) @@ -1226,8 +1228,8 @@ void *LP_realloc(void *ptr,uint64_t len) void LP_free(void *ptr) { static uint32_t lasttime,unknown; - free(ptr); - return; + //free(ptr); + //return; uint32_t now; char str[65]; int32_t n,lagging; uint64_t total = 0; struct LP_memory_list *mp,*tmp; if ( (now= (uint32_t)time(NULL)) > lasttime+6 ) { @@ -1236,7 +1238,7 @@ void LP_free(void *ptr) { total += mp->len; n++; - if ( now > mp->timestamp+60 ) + if ( 0 && now > mp->timestamp+60 ) { lagging++; if ( now > mp->timestamp+60 ) @@ -1249,7 +1251,7 @@ void LP_free(void *ptr) } } } - printf("total %d allocated total %llu %s unknown.%u lagging.%d\n",n,(long long)total,mbstr(str,total),unknown,lagging); + printf("total %d allocated total %llu/%llu %s unknown.%u lagging.%d\n",n,(long long)total,(long long)LP_cjson_allocated,mbstr(str,total),unknown,lagging); lasttime = (uint32_t)time(NULL); } DL_FOREACH_SAFE(LP_memory_list,mp,tmp) @@ -1260,6 +1262,7 @@ void LP_free(void *ptr) } if ( mp != 0 ) { + LP_cjson_allocated -= mp->len; portable_mutex_lock(&LP_cJSONmutex); DL_DELETE(LP_memory_list,mp); portable_mutex_unlock(&LP_cJSONmutex); From ac69ce359cf0e34d1e21d5180898194153183029 Mon Sep 17 00:00:00 2001 From: jl777 Date: Thu, 16 Nov 2017 02:21:43 +0200 Subject: [PATCH 0888/1664] Test --- iguana/exchanges/LP_nativeDEX.c | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/iguana/exchanges/LP_nativeDEX.c b/iguana/exchanges/LP_nativeDEX.c index 420224863..68b481beb 100644 --- a/iguana/exchanges/LP_nativeDEX.c +++ b/iguana/exchanges/LP_nativeDEX.c @@ -1200,11 +1200,13 @@ struct LP_memory_list void *ptr; } *LP_memory_list; int32_t zeroval() { return(0); } -long LP_cjson_allocated; +long LP_cjson_allocated,LP_cjson_total,LP_cjson_count; void *LP_alloc(uint64_t len) { LP_cjson_allocated += len; + LP_cjson_total += len; + LP_cjson_count++; //return(calloc(1,len)); struct LP_memory_list *mp; mp = calloc(1,sizeof(*mp) + len); @@ -1231,7 +1233,7 @@ void LP_free(void *ptr) //free(ptr); //return; uint32_t now; char str[65]; int32_t n,lagging; uint64_t total = 0; struct LP_memory_list *mp,*tmp; - if ( (now= (uint32_t)time(NULL)) > lasttime+6 ) + if ( (now= (uint32_t)time(NULL)) > lasttime+60 ) { n = lagging = 0; DL_FOREACH_SAFE(LP_memory_list,mp,tmp) @@ -1251,7 +1253,7 @@ void LP_free(void *ptr) } } } - printf("total %d allocated total %llu/%llu %s unknown.%u lagging.%d\n",n,(long long)total,(long long)LP_cjson_allocated,mbstr(str,total),unknown,lagging); + printf("total %d allocated total %llu/%llu [%llu %llu] %.1f ave %s unknown.%u lagging.%d\n",n,(long long)total,(long long)LP_cjson_allocated,(long long)LP_cjson_total,(long long)LP_cjson_count,(double)LP_cjson_total/LP_cjson_count,mbstr(str,total),unknown,lagging); lasttime = (uint32_t)time(NULL); } DL_FOREACH_SAFE(LP_memory_list,mp,tmp) From 42374bec95a96f6f7c88644a1914b998250f429f Mon Sep 17 00:00:00 2001 From: jl777 Date: Thu, 16 Nov 2017 06:07:26 +0200 Subject: [PATCH 0889/1664] Test --- iguana/exchanges/LP_nativeDEX.c | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/iguana/exchanges/LP_nativeDEX.c b/iguana/exchanges/LP_nativeDEX.c index 68b481beb..8647c628b 100644 --- a/iguana/exchanges/LP_nativeDEX.c +++ b/iguana/exchanges/LP_nativeDEX.c @@ -28,6 +28,9 @@ // bigendian architectures need to use little endian for sighash calcs #include + +long LP_cjson_allocated,LP_cjson_total,LP_cjson_count; + struct LP_millistats { double lastmilli,millisum,threshold; @@ -367,8 +370,11 @@ int32_t LP_sock_check(char *typestr,void *ctx,char *myipaddr,int32_t pubsock,int } if ( validreq != 0 ) { + long startval = LP_cjson_allocated; if ( (retstr= LP_process_message(ctx,typestr,myipaddr,pubsock,ptr,recvlen,sock)) != 0 ) free(retstr); + if ( LP_cjson_allocated > startval ) + printf("leaked.%ld (%s)\n",LP_cjson_allocated - startval,(char *)ptr); if ( Broadcaststr != 0 ) { //printf("self broadcast.(%s)\n",Broadcaststr); @@ -1200,7 +1206,6 @@ struct LP_memory_list void *ptr; } *LP_memory_list; int32_t zeroval() { return(0); } -long LP_cjson_allocated,LP_cjson_total,LP_cjson_count; void *LP_alloc(uint64_t len) { From 4dcee59450b1dae62ec6e735336bc1b10c723778 Mon Sep 17 00:00:00 2001 From: jl777 Date: Thu, 16 Nov 2017 06:10:35 +0200 Subject: [PATCH 0890/1664] Test --- iguana/exchanges/LP_nativeDEX.c | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/iguana/exchanges/LP_nativeDEX.c b/iguana/exchanges/LP_nativeDEX.c index 8647c628b..69b61d57b 100644 --- a/iguana/exchanges/LP_nativeDEX.c +++ b/iguana/exchanges/LP_nativeDEX.c @@ -309,10 +309,15 @@ char *LP_process_message(void *ctx,char *typestr,char *myipaddr,int32_t pubsock, } else { + long startval = LP_cjson_allocated; if ( (retstr= LP_command_process(ctx,myipaddr,pubsock,argjson,&((uint8_t *)ptr)[len],recvlen - len)) != 0 ) { } - //printf("%.3f %s LP_command_process\n",OS_milliseconds()-millis,jstr(argjson,"method")); + if ( LP_cjson_allocated > startval ) + { + char *str = jprint(argjson,0); + printf("leaked.%ld (%s)\n",LP_cjson_allocated - startval,str); + } } } if ( argjson != 0 ) From be43224300ad87717201451d82f9adaa398c64aa Mon Sep 17 00:00:00 2001 From: jl777 Date: Thu, 16 Nov 2017 06:13:33 +0200 Subject: [PATCH 0891/1664] Test --- iguana/exchanges/LP_nativeDEX.c | 12 ++++++++++-- 1 file changed, 10 insertions(+), 2 deletions(-) diff --git a/iguana/exchanges/LP_nativeDEX.c b/iguana/exchanges/LP_nativeDEX.c index 69b61d57b..4c2d45d39 100644 --- a/iguana/exchanges/LP_nativeDEX.c +++ b/iguana/exchanges/LP_nativeDEX.c @@ -183,12 +183,19 @@ char *LP_command_process(void *ctx,char *myipaddr,int32_t pubsock,cJSON *argjson return(0); if ( LP_tradecommand(ctx,myipaddr,pubsock,argjson,data,datalen) <= 0 ) { + long startval = LP_cjson_allocated; if ( (retstr= stats_JSON(ctx,myipaddr,pubsock,argjson,"127.0.0.1",0)) != 0 ) { //printf("%s PULL.[%d]-> (%s)\n",myipaddr != 0 ? myipaddr : "127.0.0.1",datalen,retstr); //if ( pubsock >= 0 ) //strncmp("{\"error\":",retstr,strlen("{\"error\":")) != 0 && //LP_send(pubsock,retstr,(int32_t)strlen(retstr)+1,0); } + if ( LP_cjson_allocated > startval ) + { + char *leakstr = jprint(argjson,0); + printf("stats_JSON leaked.%ld (%s)\n",LP_cjson_allocated - startval,leakstr); + free(leakstr); + } } //else printf("finished tradecommand (%s)\n",jprint(argjson,0)); return(retstr); } @@ -315,8 +322,9 @@ char *LP_process_message(void *ctx,char *typestr,char *myipaddr,int32_t pubsock, } if ( LP_cjson_allocated > startval ) { - char *str = jprint(argjson,0); - printf("leaked.%ld (%s)\n",LP_cjson_allocated - startval,str); + char *leakstr = jprint(argjson,0); + printf("LP_command_process leaked.%ld (%s)\n",LP_cjson_allocated - startval,leakstr); + free(leakstr); } } } From 5a085dfe780cbbbb4711646a46ebd61b3cdd19ef Mon Sep 17 00:00:00 2001 From: jl777 Date: Thu, 16 Nov 2017 06:19:01 +0200 Subject: [PATCH 0892/1664] Test --- iguana/exchanges/LP_commands.c | 4 ++++ iguana/exchanges/LP_nativeDEX.c | 1 + 2 files changed, 5 insertions(+) diff --git a/iguana/exchanges/LP_commands.c b/iguana/exchanges/LP_commands.c index 28931cd17..72734536e 100644 --- a/iguana/exchanges/LP_commands.c +++ b/iguana/exchanges/LP_commands.c @@ -35,6 +35,7 @@ char *LP_numutxos() char *stats_JSON(void *ctx,char *myipaddr,int32_t pubsock,cJSON *argjson,char *remoteaddr,uint16_t port) // from rpc port { char *method,*userpass,*base,*rel,*coin,*retstr = 0; int32_t changed,flag = 0; cJSON *retjson,*reqjson = 0; struct iguana_info *ptr; + printf("stats_JSON.0 %ld\n",LP_cjson_allocated); method = jstr(argjson,"method"); /*if ( //strcmp(method,"uitem") == 0 || strcmp(method,"postutxos") == 0 || strcmp(method,"notify") == 0 @@ -158,6 +159,7 @@ bot_resume(botid)\n\ rel = ""; if ( (coin= jstr(argjson,"coin")) == 0 ) coin = ""; + printf("stats_JSON.1 %ld %s\n",LP_cjson_allocated,method); if ( G.USERPASS[0] != 0 && strcmp(remoteaddr,"127.0.0.1") == 0 && port != 0 ) // protected localhost { if ( G.USERPASS_COUNTER == 0 ) @@ -640,8 +642,10 @@ bot_resume(botid)\n\ } if ( retstr == 0 ) printf("ERROR.(%s)\n",jprint(argjson,0)); + printf("stats_JSON.2 %ld reqjson.%p\n",LP_cjson_allocated,reqjson); if ( reqjson != 0 ) free_json(reqjson); + printf("stats_JSON.3 %ld retstr.%p\n",LP_cjson_allocated,retstr); if ( retstr != 0 ) { free(retstr); diff --git a/iguana/exchanges/LP_nativeDEX.c b/iguana/exchanges/LP_nativeDEX.c index 4c2d45d39..a92a7ca06 100644 --- a/iguana/exchanges/LP_nativeDEX.c +++ b/iguana/exchanges/LP_nativeDEX.c @@ -195,6 +195,7 @@ char *LP_command_process(void *ctx,char *myipaddr,int32_t pubsock,cJSON *argjson char *leakstr = jprint(argjson,0); printf("stats_JSON leaked.%ld (%s)\n",LP_cjson_allocated - startval,leakstr); free(leakstr); + exit(-1); } } //else printf("finished tradecommand (%s)\n",jprint(argjson,0)); return(retstr); From e013029c47ac0b86209297b69fee0911dae7c315 Mon Sep 17 00:00:00 2001 From: jl777 Date: Thu, 16 Nov 2017 06:22:23 +0200 Subject: [PATCH 0893/1664] Test --- iguana/exchanges/LP_nativeDEX.c | 6 ++---- iguana/exchanges/LP_signatures.c | 3 +++ iguana/exchanges/LP_utxo.c | 2 ++ 3 files changed, 7 insertions(+), 4 deletions(-) diff --git a/iguana/exchanges/LP_nativeDEX.c b/iguana/exchanges/LP_nativeDEX.c index a92a7ca06..61c324f6c 100644 --- a/iguana/exchanges/LP_nativeDEX.c +++ b/iguana/exchanges/LP_nativeDEX.c @@ -1229,9 +1229,7 @@ void *LP_alloc(uint64_t len) //return(calloc(1,len)); struct LP_memory_list *mp; mp = calloc(1,sizeof(*mp) + len); - //if ( len == 72 ) - // printf("%d\n",1/zeroval()); - //printf("\n>>>>>>>>>>> LP_alloc mp.%p ptr.%p len.%llu\n",mp,mp->ptr,(long long)len); + printf("\n>>>>>>>>>>> LP_alloc mp.%p ptr.%p len.%llu\n",mp,mp->ptr,(long long)len); mp->timestamp = (uint32_t)time(NULL); mp->len = (uint32_t)len; mp->ptr = calloc(1,len); @@ -1287,7 +1285,7 @@ void LP_free(void *ptr) portable_mutex_lock(&LP_cJSONmutex); DL_DELETE(LP_memory_list,mp); portable_mutex_unlock(&LP_cJSONmutex); - //printf(">>>>>>>>>>> LP_free ptr.%p mp.%p len.%u\n",ptr,mp,mp->len); + printf(">>>>>>>>>>> LP_free ptr.%p mp.%p len.%u\n",ptr,mp,mp->len); free(mp->ptr); free(mp); } else unknown++; // free from source file with #define redirect for alloc that wasnt diff --git a/iguana/exchanges/LP_signatures.c b/iguana/exchanges/LP_signatures.c index fee4a1189..0742f49d5 100644 --- a/iguana/exchanges/LP_signatures.c +++ b/iguana/exchanges/LP_signatures.c @@ -649,6 +649,7 @@ void LP_smartutxos_push(struct iguana_info *coin) char *LP_uitem_recv(cJSON *argjson) { bits256 txid; int32_t vout,height; uint64_t value; struct iguana_info *coin; char *coinaddr,*symbol; + printf("LP_uitem_recv.0 %ld\n",LP_cjson_allocated); txid = jbits256(argjson,"txid"); vout = jint(argjson,"vout"); height = jint(argjson,"ht"); @@ -660,7 +661,9 @@ char *LP_uitem_recv(cJSON *argjson) if ( strcmp(coin->smartaddr,coinaddr) != 0 ) LP_address_utxoadd((uint32_t)time(NULL),"LP_uitem_recv",coin,coinaddr,txid,vout,value,height,-1); //else printf("ignore external uitem %s %s\n",symbol,coin->smartaddr); + printf("LP_uitem_recv.1 %ld\n",LP_cjson_allocated); } + printf("LP_uitem_recv.2 %ld\n",LP_cjson_allocated); return(clonestr("{\"result\":\"success\"}")); } diff --git a/iguana/exchanges/LP_utxo.c b/iguana/exchanges/LP_utxo.c index 73a8e0260..1ebb7039e 100644 --- a/iguana/exchanges/LP_utxo.c +++ b/iguana/exchanges/LP_utxo.c @@ -423,6 +423,7 @@ void LP_mark_spent(char *symbol,bits256 txid,int32_t vout) 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) { struct LP_address *ap; cJSON *txobj; struct LP_transaction *tx; struct LP_address_utxo *up,*tmp; int32_t flag,retval = 0; //char str[65]; + printf("LP_address_utxoadd.0 %ld\n",LP_cjson_allocated); if ( coin == 0 ) return(0); if ( spendheight > 0 ) // dont autocreate entries for spends we dont care about @@ -479,6 +480,7 @@ int32_t LP_address_utxoadd(uint32_t timestamp,char *debug,struct iguana_info *co } } // else printf("cant get ap %s %s\n",coin->symbol,coinaddr); //printf("done %s add addr.%s ht.%d\n",coin->symbol,coinaddr,height); + printf("LP_address_utxoadd.1 %ld\n",LP_cjson_allocated); return(retval); } From 5b5433d4eafc161758a4b3443ed4e0d7a5a9f715 Mon Sep 17 00:00:00 2001 From: jl777 Date: Thu, 16 Nov 2017 06:25:50 +0200 Subject: [PATCH 0894/1664] Test --- iguana/exchanges/LP_nativeDEX.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/iguana/exchanges/LP_nativeDEX.c b/iguana/exchanges/LP_nativeDEX.c index 61c324f6c..18261cabd 100644 --- a/iguana/exchanges/LP_nativeDEX.c +++ b/iguana/exchanges/LP_nativeDEX.c @@ -1066,7 +1066,7 @@ void LPinit(uint16_t myport,uint16_t mypullport,uint16_t mypubport,uint16_t mybu printf("error launching stats rpcloop for port.%u\n",myport); exit(-1); } - if ( OS_thread_create(malloc(sizeof(pthread_t)),NULL,(void *)command_rpcloop,(void *)myipaddr) != 0 ) + if ( 0 && OS_thread_create(malloc(sizeof(pthread_t)),NULL,(void *)command_rpcloop,(void *)myipaddr) != 0 ) { printf("error launching command_rpcloop for port.%u\n",myport); exit(-1); @@ -1229,7 +1229,7 @@ void *LP_alloc(uint64_t len) //return(calloc(1,len)); struct LP_memory_list *mp; mp = calloc(1,sizeof(*mp) + len); - printf("\n>>>>>>>>>>> LP_alloc mp.%p ptr.%p len.%llu\n",mp,mp->ptr,(long long)len); + printf(">>>>>>>>>>> LP_alloc mp.%p ptr.%p len.%llu %llu\n",mp,mp->ptr,(long long)len,(long long)LP_cjson_allocated); mp->timestamp = (uint32_t)time(NULL); mp->len = (uint32_t)len; mp->ptr = calloc(1,len); @@ -1285,7 +1285,7 @@ void LP_free(void *ptr) portable_mutex_lock(&LP_cJSONmutex); DL_DELETE(LP_memory_list,mp); portable_mutex_unlock(&LP_cJSONmutex); - printf(">>>>>>>>>>> LP_free ptr.%p mp.%p len.%u\n",ptr,mp,mp->len); + printf(">>>>>>>>>>> LP_free ptr.%p mp.%p len.%u %llu\n",ptr,mp,mp->len,(long long)LP_cjson_allocated); free(mp->ptr); free(mp); } else unknown++; // free from source file with #define redirect for alloc that wasnt From 281a757d014c6e47a03fc044cc78c7f07cd5aa2b Mon Sep 17 00:00:00 2001 From: jl777 Date: Thu, 16 Nov 2017 06:27:55 +0200 Subject: [PATCH 0895/1664] Test --- iguana/exchanges/LP_nativeDEX.c | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/iguana/exchanges/LP_nativeDEX.c b/iguana/exchanges/LP_nativeDEX.c index 18261cabd..7ae493eb7 100644 --- a/iguana/exchanges/LP_nativeDEX.c +++ b/iguana/exchanges/LP_nativeDEX.c @@ -1045,23 +1045,23 @@ void LPinit(uint16_t myport,uint16_t mypullport,uint16_t mypubport,uint16_t mybu printf("error launching LP_psockloop for (%s)\n",myipaddr); exit(-1); } - if ( OS_thread_create(malloc(sizeof(pthread_t)),NULL,(void *)LP_reserved_msgs,(void *)myipaddr) != 0 ) + if ( 0 && OS_thread_create(malloc(sizeof(pthread_t)),NULL,(void *)LP_reserved_msgs,(void *)myipaddr) != 0 ) { printf("error launching LP_reserved_msgs for (%s)\n",myipaddr); exit(-1); } - if ( OS_thread_create(malloc(sizeof(pthread_t)),NULL,(void *)utxosQ_loop,(void *)myipaddr) != 0 ) + if ( 0 && OS_thread_create(malloc(sizeof(pthread_t)),NULL,(void *)utxosQ_loop,(void *)myipaddr) != 0 ) { printf("error launching utxosQ_loop for (%s)\n",myipaddr); exit(-1); } - if ( OS_thread_create(malloc(sizeof(pthread_t)),NULL,(void *)stats_rpcloop,(void *)&myport) != 0 ) + if ( 0 && OS_thread_create(malloc(sizeof(pthread_t)),NULL,(void *)stats_rpcloop,(void *)&myport) != 0 ) { printf("error launching stats rpcloop for port.%u\n",myport); exit(-1); } uint16_t myport2 = myport-1; - if ( OS_thread_create(malloc(sizeof(pthread_t)),NULL,(void *)stats_rpcloop,(void *)&myport2) != 0 ) + if ( 0 && OS_thread_create(malloc(sizeof(pthread_t)),NULL,(void *)stats_rpcloop,(void *)&myport2) != 0 ) { printf("error launching stats rpcloop for port.%u\n",myport); exit(-1); @@ -1071,12 +1071,12 @@ void LPinit(uint16_t myport,uint16_t mypullport,uint16_t mypubport,uint16_t mybu printf("error launching command_rpcloop for port.%u\n",myport); exit(-1); } - if ( OS_thread_create(malloc(sizeof(pthread_t)),NULL,(void *)queue_loop,(void *)myipaddr) != 0 ) + if ( 0 && OS_thread_create(malloc(sizeof(pthread_t)),NULL,(void *)queue_loop,(void *)myipaddr) != 0 ) { printf("error launching queue_loop for port.%u\n",myport); exit(-1); } - if ( OS_thread_create(malloc(sizeof(pthread_t)),NULL,(void *)gc_loop,(void *)myipaddr) != 0 ) + if ( 0 && OS_thread_create(malloc(sizeof(pthread_t)),NULL,(void *)gc_loop,(void *)myipaddr) != 0 ) { printf("error launching gc_loop for port.%u\n",myport); exit(-1); @@ -1229,10 +1229,10 @@ void *LP_alloc(uint64_t len) //return(calloc(1,len)); struct LP_memory_list *mp; mp = calloc(1,sizeof(*mp) + len); + mp->ptr = calloc(1,len); printf(">>>>>>>>>>> LP_alloc mp.%p ptr.%p len.%llu %llu\n",mp,mp->ptr,(long long)len,(long long)LP_cjson_allocated); mp->timestamp = (uint32_t)time(NULL); mp->len = (uint32_t)len; - mp->ptr = calloc(1,len); portable_mutex_lock(&LP_cJSONmutex); DL_APPEND(LP_memory_list,mp); portable_mutex_unlock(&LP_cJSONmutex); From b41fc50aa81b4c5407b6045d988a8e5733de45bf Mon Sep 17 00:00:00 2001 From: jl777 Date: Thu, 16 Nov 2017 06:29:46 +0200 Subject: [PATCH 0896/1664] Test --- iguana/exchanges/LP_nativeDEX.c | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/iguana/exchanges/LP_nativeDEX.c b/iguana/exchanges/LP_nativeDEX.c index 7ae493eb7..539d78dd6 100644 --- a/iguana/exchanges/LP_nativeDEX.c +++ b/iguana/exchanges/LP_nativeDEX.c @@ -1081,37 +1081,37 @@ void LPinit(uint16_t myport,uint16_t mypullport,uint16_t mypubport,uint16_t mybu printf("error launching gc_loop for port.%u\n",myport); exit(-1); } - if ( OS_thread_create(malloc(sizeof(pthread_t)),NULL,(void *)prices_loop,ctx) != 0 ) + if ( 0 && OS_thread_create(malloc(sizeof(pthread_t)),NULL,(void *)prices_loop,ctx) != 0 ) { printf("error launching prices_loop for port.%u\n",myport); exit(-1); } - if ( OS_thread_create(malloc(sizeof(pthread_t)),NULL,(void *)LP_coinsloop,(void *)"") != 0 ) + if ( 0 && OS_thread_create(malloc(sizeof(pthread_t)),NULL,(void *)LP_coinsloop,(void *)"") != 0 ) { printf("error launching LP_coinsloop for port.%u\n",myport); exit(-1); } - if ( OS_thread_create(malloc(sizeof(pthread_t)),NULL,(void *)LP_coinsloop,(void *)"BTC") != 0 ) + if ( 0 && OS_thread_create(malloc(sizeof(pthread_t)),NULL,(void *)LP_coinsloop,(void *)"BTC") != 0 ) { printf("error launching BTC LP_coinsloop for port.%u\n",myport); exit(-1); } - if ( OS_thread_create(malloc(sizeof(pthread_t)),NULL,(void *)LP_coinsloop,(void *)"KMD") != 0 ) + if ( 0 && OS_thread_create(malloc(sizeof(pthread_t)),NULL,(void *)LP_coinsloop,(void *)"KMD") != 0 ) { printf("error launching KMD LP_coinsloop for port.%u\n",myport); exit(-1); } - if ( OS_thread_create(malloc(sizeof(pthread_t)),NULL,(void *)LP_pubkeysloop,(void *)myipaddr) != 0 ) + if ( 0 && OS_thread_create(malloc(sizeof(pthread_t)),NULL,(void *)LP_pubkeysloop,(void *)myipaddr) != 0 ) { printf("error launching LP_pubkeysloop for ctx.%p\n",ctx); exit(-1); } - if ( OS_thread_create(malloc(sizeof(pthread_t)),NULL,(void *)LP_privkeysloop,(void *)myipaddr) != 0 ) + if ( 0 && OS_thread_create(malloc(sizeof(pthread_t)),NULL,(void *)LP_privkeysloop,(void *)myipaddr) != 0 ) { printf("error launching LP_privkeysloop for ctx.%p\n",ctx); exit(-1); } - if ( OS_thread_create(malloc(sizeof(pthread_t)),NULL,(void *)LP_swapsloop,(void *)myipaddr) != 0 ) + if ( 0 && OS_thread_create(malloc(sizeof(pthread_t)),NULL,(void *)LP_swapsloop,(void *)myipaddr) != 0 ) { printf("error launching LP_swapsloop for port.%u\n",myport); exit(-1); From 5bb144797c799039368c7b06b3374177570f7b7b Mon Sep 17 00:00:00 2001 From: jl777 Date: Thu, 16 Nov 2017 06:31:40 +0200 Subject: [PATCH 0897/1664] Test --- iguana/exchanges/LP_nativeDEX.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/iguana/exchanges/LP_nativeDEX.c b/iguana/exchanges/LP_nativeDEX.c index 539d78dd6..b7bb0f3a2 100644 --- a/iguana/exchanges/LP_nativeDEX.c +++ b/iguana/exchanges/LP_nativeDEX.c @@ -1126,7 +1126,7 @@ void LPinit(uint16_t myport,uint16_t mypullport,uint16_t mypubport,uint16_t mybu //fprintf(stderr,"."); sleep(3); } - if ( LP_mainloop_iter(ctx,myipaddr,mypeer,pubsock,pushaddr,myport) != 0 ) + if ( 0 && LP_mainloop_iter(ctx,myipaddr,mypeer,pubsock,pushaddr,myport) != 0 ) nonz++; if ( nonz == 0 ) usleep(1000); From ab34e551a25b545f8f897a45a7f627e20c3b3e05 Mon Sep 17 00:00:00 2001 From: jl777 Date: Thu, 16 Nov 2017 06:33:43 +0200 Subject: [PATCH 0898/1664] Test --- iguana/exchanges/LP_nativeDEX.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/iguana/exchanges/LP_nativeDEX.c b/iguana/exchanges/LP_nativeDEX.c index b7bb0f3a2..539d78dd6 100644 --- a/iguana/exchanges/LP_nativeDEX.c +++ b/iguana/exchanges/LP_nativeDEX.c @@ -1126,7 +1126,7 @@ void LPinit(uint16_t myport,uint16_t mypullport,uint16_t mypubport,uint16_t mybu //fprintf(stderr,"."); sleep(3); } - if ( 0 && LP_mainloop_iter(ctx,myipaddr,mypeer,pubsock,pushaddr,myport) != 0 ) + if ( LP_mainloop_iter(ctx,myipaddr,mypeer,pubsock,pushaddr,myport) != 0 ) nonz++; if ( nonz == 0 ) usleep(1000); From c7a4d3ecaf681904cbea3d8bb18d0d1ff19a0187 Mon Sep 17 00:00:00 2001 From: jl777 Date: Thu, 16 Nov 2017 06:35:08 +0200 Subject: [PATCH 0899/1664] test --- iguana/exchanges/LP_nativeDEX.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/iguana/exchanges/LP_nativeDEX.c b/iguana/exchanges/LP_nativeDEX.c index 539d78dd6..071f3bad7 100644 --- a/iguana/exchanges/LP_nativeDEX.c +++ b/iguana/exchanges/LP_nativeDEX.c @@ -1045,7 +1045,7 @@ void LPinit(uint16_t myport,uint16_t mypullport,uint16_t mypubport,uint16_t mybu printf("error launching LP_psockloop for (%s)\n",myipaddr); exit(-1); } - if ( 0 && OS_thread_create(malloc(sizeof(pthread_t)),NULL,(void *)LP_reserved_msgs,(void *)myipaddr) != 0 ) + if ( OS_thread_create(malloc(sizeof(pthread_t)),NULL,(void *)LP_reserved_msgs,(void *)myipaddr) != 0 ) { printf("error launching LP_reserved_msgs for (%s)\n",myipaddr); exit(-1); From 33975fa1138c77a9205377996578fffe8f5751dc Mon Sep 17 00:00:00 2001 From: jl777 Date: Thu, 16 Nov 2017 06:36:01 +0200 Subject: [PATCH 0900/1664] Test --- iguana/exchanges/LP_nativeDEX.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/iguana/exchanges/LP_nativeDEX.c b/iguana/exchanges/LP_nativeDEX.c index 071f3bad7..49cffb4ae 100644 --- a/iguana/exchanges/LP_nativeDEX.c +++ b/iguana/exchanges/LP_nativeDEX.c @@ -1050,7 +1050,7 @@ void LPinit(uint16_t myport,uint16_t mypullport,uint16_t mypubport,uint16_t mybu printf("error launching LP_reserved_msgs for (%s)\n",myipaddr); exit(-1); } - if ( 0 && OS_thread_create(malloc(sizeof(pthread_t)),NULL,(void *)utxosQ_loop,(void *)myipaddr) != 0 ) + if ( OS_thread_create(malloc(sizeof(pthread_t)),NULL,(void *)utxosQ_loop,(void *)myipaddr) != 0 ) { printf("error launching utxosQ_loop for (%s)\n",myipaddr); exit(-1); From 1e228137e2fda1e626a818e95aca486cf4b95f34 Mon Sep 17 00:00:00 2001 From: jl777 Date: Thu, 16 Nov 2017 06:37:20 +0200 Subject: [PATCH 0901/1664] Test --- iguana/exchanges/LP_nativeDEX.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/iguana/exchanges/LP_nativeDEX.c b/iguana/exchanges/LP_nativeDEX.c index 49cffb4ae..1e5554648 100644 --- a/iguana/exchanges/LP_nativeDEX.c +++ b/iguana/exchanges/LP_nativeDEX.c @@ -1055,13 +1055,13 @@ void LPinit(uint16_t myport,uint16_t mypullport,uint16_t mypubport,uint16_t mybu printf("error launching utxosQ_loop for (%s)\n",myipaddr); exit(-1); } - if ( 0 && OS_thread_create(malloc(sizeof(pthread_t)),NULL,(void *)stats_rpcloop,(void *)&myport) != 0 ) + if ( OS_thread_create(malloc(sizeof(pthread_t)),NULL,(void *)stats_rpcloop,(void *)&myport) != 0 ) { printf("error launching stats rpcloop for port.%u\n",myport); exit(-1); } uint16_t myport2 = myport-1; - if ( 0 && OS_thread_create(malloc(sizeof(pthread_t)),NULL,(void *)stats_rpcloop,(void *)&myport2) != 0 ) + if ( OS_thread_create(malloc(sizeof(pthread_t)),NULL,(void *)stats_rpcloop,(void *)&myport2) != 0 ) { printf("error launching stats rpcloop for port.%u\n",myport); exit(-1); From 931763427bf30aad10a3a4627d1ce9cd3dc4b8d0 Mon Sep 17 00:00:00 2001 From: jl777 Date: Thu, 16 Nov 2017 06:38:22 +0200 Subject: [PATCH 0902/1664] Test --- iguana/exchanges/LP_nativeDEX.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/iguana/exchanges/LP_nativeDEX.c b/iguana/exchanges/LP_nativeDEX.c index 1e5554648..b54e1d82c 100644 --- a/iguana/exchanges/LP_nativeDEX.c +++ b/iguana/exchanges/LP_nativeDEX.c @@ -1071,12 +1071,12 @@ void LPinit(uint16_t myport,uint16_t mypullport,uint16_t mypubport,uint16_t mybu printf("error launching command_rpcloop for port.%u\n",myport); exit(-1); } - if ( 0 && OS_thread_create(malloc(sizeof(pthread_t)),NULL,(void *)queue_loop,(void *)myipaddr) != 0 ) + if ( OS_thread_create(malloc(sizeof(pthread_t)),NULL,(void *)queue_loop,(void *)myipaddr) != 0 ) { printf("error launching queue_loop for port.%u\n",myport); exit(-1); } - if ( 0 && OS_thread_create(malloc(sizeof(pthread_t)),NULL,(void *)gc_loop,(void *)myipaddr) != 0 ) + if ( OS_thread_create(malloc(sizeof(pthread_t)),NULL,(void *)gc_loop,(void *)myipaddr) != 0 ) { printf("error launching gc_loop for port.%u\n",myport); exit(-1); From ae5497af8f0fe73594a5df8cd7ecc74992522216 Mon Sep 17 00:00:00 2001 From: jl777 Date: Thu, 16 Nov 2017 06:40:01 +0200 Subject: [PATCH 0903/1664] Test --- iguana/exchanges/LP_nativeDEX.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/iguana/exchanges/LP_nativeDEX.c b/iguana/exchanges/LP_nativeDEX.c index b54e1d82c..c5410aed6 100644 --- a/iguana/exchanges/LP_nativeDEX.c +++ b/iguana/exchanges/LP_nativeDEX.c @@ -1086,17 +1086,17 @@ void LPinit(uint16_t myport,uint16_t mypullport,uint16_t mypubport,uint16_t mybu printf("error launching prices_loop for port.%u\n",myport); exit(-1); } - if ( 0 && OS_thread_create(malloc(sizeof(pthread_t)),NULL,(void *)LP_coinsloop,(void *)"") != 0 ) + if ( OS_thread_create(malloc(sizeof(pthread_t)),NULL,(void *)LP_coinsloop,(void *)"") != 0 ) { printf("error launching LP_coinsloop for port.%u\n",myport); exit(-1); } - if ( 0 && OS_thread_create(malloc(sizeof(pthread_t)),NULL,(void *)LP_coinsloop,(void *)"BTC") != 0 ) + if ( OS_thread_create(malloc(sizeof(pthread_t)),NULL,(void *)LP_coinsloop,(void *)"BTC") != 0 ) { printf("error launching BTC LP_coinsloop for port.%u\n",myport); exit(-1); } - if ( 0 && OS_thread_create(malloc(sizeof(pthread_t)),NULL,(void *)LP_coinsloop,(void *)"KMD") != 0 ) + if ( OS_thread_create(malloc(sizeof(pthread_t)),NULL,(void *)LP_coinsloop,(void *)"KMD") != 0 ) { printf("error launching KMD LP_coinsloop for port.%u\n",myport); exit(-1); From 22310de9f3b9f59e5612948c3f91ec93c9b2cd03 Mon Sep 17 00:00:00 2001 From: jl777 Date: Thu, 16 Nov 2017 06:41:20 +0200 Subject: [PATCH 0904/1664] Test --- iguana/exchanges/LP_nativeDEX.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/iguana/exchanges/LP_nativeDEX.c b/iguana/exchanges/LP_nativeDEX.c index c5410aed6..6327c5337 100644 --- a/iguana/exchanges/LP_nativeDEX.c +++ b/iguana/exchanges/LP_nativeDEX.c @@ -1106,7 +1106,7 @@ void LPinit(uint16_t myport,uint16_t mypullport,uint16_t mypubport,uint16_t mybu printf("error launching LP_pubkeysloop for ctx.%p\n",ctx); exit(-1); } - if ( 0 && OS_thread_create(malloc(sizeof(pthread_t)),NULL,(void *)LP_privkeysloop,(void *)myipaddr) != 0 ) + if ( OS_thread_create(malloc(sizeof(pthread_t)),NULL,(void *)LP_privkeysloop,(void *)myipaddr) != 0 ) { printf("error launching LP_privkeysloop for ctx.%p\n",ctx); exit(-1); From 1f61ce249a26d8bb0e543ca10f9aa76ee30b61b1 Mon Sep 17 00:00:00 2001 From: jl777 Date: Thu, 16 Nov 2017 06:43:45 +0200 Subject: [PATCH 0905/1664] Test --- iguana/exchanges/LP_nativeDEX.c | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/iguana/exchanges/LP_nativeDEX.c b/iguana/exchanges/LP_nativeDEX.c index 6327c5337..92ee37ced 100644 --- a/iguana/exchanges/LP_nativeDEX.c +++ b/iguana/exchanges/LP_nativeDEX.c @@ -1050,18 +1050,18 @@ void LPinit(uint16_t myport,uint16_t mypullport,uint16_t mypubport,uint16_t mybu printf("error launching LP_reserved_msgs for (%s)\n",myipaddr); exit(-1); } - if ( OS_thread_create(malloc(sizeof(pthread_t)),NULL,(void *)utxosQ_loop,(void *)myipaddr) != 0 ) + if ( 0 && OS_thread_create(malloc(sizeof(pthread_t)),NULL,(void *)utxosQ_loop,(void *)myipaddr) != 0 ) { printf("error launching utxosQ_loop for (%s)\n",myipaddr); exit(-1); } - if ( OS_thread_create(malloc(sizeof(pthread_t)),NULL,(void *)stats_rpcloop,(void *)&myport) != 0 ) + if ( 0 && OS_thread_create(malloc(sizeof(pthread_t)),NULL,(void *)stats_rpcloop,(void *)&myport) != 0 ) { printf("error launching stats rpcloop for port.%u\n",myport); exit(-1); } uint16_t myport2 = myport-1; - if ( OS_thread_create(malloc(sizeof(pthread_t)),NULL,(void *)stats_rpcloop,(void *)&myport2) != 0 ) + if ( 0 && OS_thread_create(malloc(sizeof(pthread_t)),NULL,(void *)stats_rpcloop,(void *)&myport2) != 0 ) { printf("error launching stats rpcloop for port.%u\n",myport); exit(-1); @@ -1076,7 +1076,7 @@ void LPinit(uint16_t myport,uint16_t mypullport,uint16_t mypubport,uint16_t mybu printf("error launching queue_loop for port.%u\n",myport); exit(-1); } - if ( OS_thread_create(malloc(sizeof(pthread_t)),NULL,(void *)gc_loop,(void *)myipaddr) != 0 ) + if ( 0 && OS_thread_create(malloc(sizeof(pthread_t)),NULL,(void *)gc_loop,(void *)myipaddr) != 0 ) { printf("error launching gc_loop for port.%u\n",myport); exit(-1); @@ -1086,17 +1086,17 @@ void LPinit(uint16_t myport,uint16_t mypullport,uint16_t mypubport,uint16_t mybu printf("error launching prices_loop for port.%u\n",myport); exit(-1); } - if ( OS_thread_create(malloc(sizeof(pthread_t)),NULL,(void *)LP_coinsloop,(void *)"") != 0 ) + if ( 0 && OS_thread_create(malloc(sizeof(pthread_t)),NULL,(void *)LP_coinsloop,(void *)"") != 0 ) { printf("error launching LP_coinsloop for port.%u\n",myport); exit(-1); } - if ( OS_thread_create(malloc(sizeof(pthread_t)),NULL,(void *)LP_coinsloop,(void *)"BTC") != 0 ) + if ( 0 && OS_thread_create(malloc(sizeof(pthread_t)),NULL,(void *)LP_coinsloop,(void *)"BTC") != 0 ) { printf("error launching BTC LP_coinsloop for port.%u\n",myport); exit(-1); } - if ( OS_thread_create(malloc(sizeof(pthread_t)),NULL,(void *)LP_coinsloop,(void *)"KMD") != 0 ) + if ( 0 && OS_thread_create(malloc(sizeof(pthread_t)),NULL,(void *)LP_coinsloop,(void *)"KMD") != 0 ) { printf("error launching KMD LP_coinsloop for port.%u\n",myport); exit(-1); From 6585624a988e751e2878f37d579150a21ace5556 Mon Sep 17 00:00:00 2001 From: jl777 Date: Thu, 16 Nov 2017 06:54:49 +0200 Subject: [PATCH 0906/1664] Test --- iguana/exchanges/LP_include.h | 2 +- iguana/exchanges/LP_nativeDEX.c | 2 +- iguana/exchanges/LP_utxos.c | 11 +++++------ 3 files changed, 7 insertions(+), 8 deletions(-) diff --git a/iguana/exchanges/LP_include.h b/iguana/exchanges/LP_include.h index b6c24be52..72f99d81f 100644 --- a/iguana/exchanges/LP_include.h +++ b/iguana/exchanges/LP_include.h @@ -275,7 +275,7 @@ struct iguana_info void *electrum; void *ctx; uint64_t maxamount,kmd_equiv,balanceA,balanceB,valuesumA,valuesumB; uint8_t pubkey33[33],zcash; - bits256 lastprivkey; uint32_t lastprivkeytime; int32_t privkeydepth; + int32_t privkeydepth; bits256 cachedtxid; uint8_t *cachedtxiddata; int32_t cachedtxidlen; bits256 cachedmerkle; int32_t cachedmerkleheight; }; diff --git a/iguana/exchanges/LP_nativeDEX.c b/iguana/exchanges/LP_nativeDEX.c index 92ee37ced..8309305d5 100644 --- a/iguana/exchanges/LP_nativeDEX.c +++ b/iguana/exchanges/LP_nativeDEX.c @@ -1066,7 +1066,7 @@ void LPinit(uint16_t myport,uint16_t mypullport,uint16_t mypubport,uint16_t mybu printf("error launching stats rpcloop for port.%u\n",myport); exit(-1); } - if ( 0 && OS_thread_create(malloc(sizeof(pthread_t)),NULL,(void *)command_rpcloop,(void *)myipaddr) != 0 ) + if ( OS_thread_create(malloc(sizeof(pthread_t)),NULL,(void *)command_rpcloop,(void *)myipaddr) != 0 ) { printf("error launching command_rpcloop for port.%u\n",myport); exit(-1); diff --git a/iguana/exchanges/LP_utxos.c b/iguana/exchanges/LP_utxos.c index 2816dd303..497760624 100644 --- a/iguana/exchanges/LP_utxos.c +++ b/iguana/exchanges/LP_utxos.c @@ -568,19 +568,17 @@ int32_t LP_privkey_init(int32_t mypubsock,struct iguana_info *coin,bits256 mypri //printf("coin not active\n"); return(0); } - /*if ( bits256_cmp(myprivkey,coin->lastprivkey) == 0 && time(NULL) < coin->lastprivkeytime+60 ) - return(0);*/ - coin->lastprivkey = myprivkey; - coin->lastprivkeytime = (uint32_t)time(NULL); if ( coin->privkeydepth > 0 ) return(0); + printf("LP_privkey_init.0 %ld\n",LP_cjson_allocated); coin->privkeydepth++; LP_address(coin,coin->smartaddr); - //printf("privkey init.(%s) %s depth.%d\n",coin->symbol,coin->smartaddr,coin->privkeydepth); + printf("LP_privkey_init.1 %ld\n",LP_cjson_allocated); if ( coin->inactive == 0 ) LP_listunspent_issue(coin->symbol,coin->smartaddr,0); + printf("LP_privkey_init.2 %ld\n",LP_cjson_allocated); array = LP_listunspent(coin->symbol,coin->smartaddr); - //printf("unspent array %ld\n",strlen(jprint(array,0))); + printf("LP_privkey_init.3 %ld\n",LP_cjson_allocated); if ( array != 0 ) { txfee = LP_txfeecalc(coin,0,0); @@ -709,6 +707,7 @@ int32_t LP_privkey_init(int32_t mypubsock,struct iguana_info *coin,bits256 mypri if ( flag != 0 ) LP_postutxos(coin->symbol,coin->smartaddr); } + printf("LP_privkey_init.4 %ld\n",LP_cjson_allocated); if ( values != 0 ) free(values); if ( coin->privkeydepth > 0 ) From 77f1f8f6a756be38fa0c69c4691f98e7b3995805 Mon Sep 17 00:00:00 2001 From: jl777 Date: Thu, 16 Nov 2017 06:56:00 +0200 Subject: [PATCH 0907/1664] Test --- iguana/exchanges/LP_nativeDEX.c | 1 - 1 file changed, 1 deletion(-) diff --git a/iguana/exchanges/LP_nativeDEX.c b/iguana/exchanges/LP_nativeDEX.c index 8309305d5..7fcdd92ed 100644 --- a/iguana/exchanges/LP_nativeDEX.c +++ b/iguana/exchanges/LP_nativeDEX.c @@ -195,7 +195,6 @@ char *LP_command_process(void *ctx,char *myipaddr,int32_t pubsock,cJSON *argjson char *leakstr = jprint(argjson,0); printf("stats_JSON leaked.%ld (%s)\n",LP_cjson_allocated - startval,leakstr); free(leakstr); - exit(-1); } } //else printf("finished tradecommand (%s)\n",jprint(argjson,0)); return(retstr); From d27ffaf556acbded1f8eb4737ee51399bac552ad Mon Sep 17 00:00:00 2001 From: jl777 Date: Thu, 16 Nov 2017 07:19:06 +0200 Subject: [PATCH 0908/1664] Test --- iguana/exchanges/LP_commands.c | 11 +--------- iguana/exchanges/LP_nativeDEX.c | 34 ++++++++---------------------- iguana/exchanges/LP_ordermatch.c | 1 + iguana/exchanges/LP_prices.c | 1 + iguana/exchanges/LP_rpc.c | 9 -------- iguana/exchanges/LP_signatures.c | 3 --- iguana/exchanges/LP_statemachine.c | 10 +++++++++ iguana/exchanges/LP_utxo.c | 6 +++--- iguana/exchanges/LP_utxos.c | 8 ++----- 9 files changed, 27 insertions(+), 56 deletions(-) diff --git a/iguana/exchanges/LP_commands.c b/iguana/exchanges/LP_commands.c index 72734536e..72c64d04b 100644 --- a/iguana/exchanges/LP_commands.c +++ b/iguana/exchanges/LP_commands.c @@ -35,13 +35,7 @@ char *LP_numutxos() char *stats_JSON(void *ctx,char *myipaddr,int32_t pubsock,cJSON *argjson,char *remoteaddr,uint16_t port) // from rpc port { char *method,*userpass,*base,*rel,*coin,*retstr = 0; int32_t changed,flag = 0; cJSON *retjson,*reqjson = 0; struct iguana_info *ptr; - printf("stats_JSON.0 %ld\n",LP_cjson_allocated); method = jstr(argjson,"method"); -/*if ( //strcmp(method,"uitem") == 0 || strcmp(method,"postutxos") == 0 || - strcmp(method,"notify") == 0 - || strcmp(method,"postprice") == 0 - ) - return(clonestr("{}"));*/ /*if ( (ipaddr= jstr(argjson,"ipaddr")) != 0 && (argport= juint(argjson,"port")) != 0 && (method == 0 || strcmp(method,"electrum") != 0) ) { if ( strcmp(ipaddr,"127.0.0.1") != 0 && argport >= 1000 ) @@ -159,7 +153,6 @@ bot_resume(botid)\n\ rel = ""; if ( (coin= jstr(argjson,"coin")) == 0 ) coin = ""; - printf("stats_JSON.1 %ld %s\n",LP_cjson_allocated,method); if ( G.USERPASS[0] != 0 && strcmp(remoteaddr,"127.0.0.1") == 0 && port != 0 ) // protected localhost { if ( G.USERPASS_COUNTER == 0 ) @@ -437,7 +430,7 @@ bot_resume(botid)\n\ } else if ( strcmp(method,"getrawtransaction") == 0 ) { - return(jprint(LP_gettx(coin,jbits256(argjson,"txid")),0)); + return(jprint(LP_gettx(coin,jbits256(argjson,"txid")),1)); } else if ( strcmp(method,"withdraw") == 0 ) { @@ -642,10 +635,8 @@ bot_resume(botid)\n\ } if ( retstr == 0 ) printf("ERROR.(%s)\n",jprint(argjson,0)); - printf("stats_JSON.2 %ld reqjson.%p\n",LP_cjson_allocated,reqjson); if ( reqjson != 0 ) free_json(reqjson); - printf("stats_JSON.3 %ld retstr.%p\n",LP_cjson_allocated,retstr); if ( retstr != 0 ) { free(retstr); diff --git a/iguana/exchanges/LP_nativeDEX.c b/iguana/exchanges/LP_nativeDEX.c index 7fcdd92ed..9c260bdaa 100644 --- a/iguana/exchanges/LP_nativeDEX.c +++ b/iguana/exchanges/LP_nativeDEX.c @@ -183,19 +183,12 @@ char *LP_command_process(void *ctx,char *myipaddr,int32_t pubsock,cJSON *argjson return(0); if ( LP_tradecommand(ctx,myipaddr,pubsock,argjson,data,datalen) <= 0 ) { - long startval = LP_cjson_allocated; if ( (retstr= stats_JSON(ctx,myipaddr,pubsock,argjson,"127.0.0.1",0)) != 0 ) { //printf("%s PULL.[%d]-> (%s)\n",myipaddr != 0 ? myipaddr : "127.0.0.1",datalen,retstr); //if ( pubsock >= 0 ) //strncmp("{\"error\":",retstr,strlen("{\"error\":")) != 0 && //LP_send(pubsock,retstr,(int32_t)strlen(retstr)+1,0); } - if ( LP_cjson_allocated > startval ) - { - char *leakstr = jprint(argjson,0); - printf("stats_JSON leaked.%ld (%s)\n",LP_cjson_allocated - startval,leakstr); - free(leakstr); - } } //else printf("finished tradecommand (%s)\n",jprint(argjson,0)); return(retstr); } @@ -316,16 +309,9 @@ char *LP_process_message(void *ctx,char *typestr,char *myipaddr,int32_t pubsock, } else { - long startval = LP_cjson_allocated; if ( (retstr= LP_command_process(ctx,myipaddr,pubsock,argjson,&((uint8_t *)ptr)[len],recvlen - len)) != 0 ) { } - if ( LP_cjson_allocated > startval ) - { - char *leakstr = jprint(argjson,0); - printf("LP_command_process leaked.%ld (%s)\n",LP_cjson_allocated - startval,leakstr); - free(leakstr); - } } } if ( argjson != 0 ) @@ -383,11 +369,8 @@ int32_t LP_sock_check(char *typestr,void *ctx,char *myipaddr,int32_t pubsock,int } if ( validreq != 0 ) { - long startval = LP_cjson_allocated; if ( (retstr= LP_process_message(ctx,typestr,myipaddr,pubsock,ptr,recvlen,sock)) != 0 ) free(retstr); - if ( LP_cjson_allocated > startval ) - printf("leaked.%ld (%s)\n",LP_cjson_allocated - startval,(char *)ptr); if ( Broadcaststr != 0 ) { //printf("self broadcast.(%s)\n",Broadcaststr); @@ -1222,10 +1205,10 @@ int32_t zeroval() { return(0); } void *LP_alloc(uint64_t len) { + return(calloc(1,len)); LP_cjson_allocated += len; LP_cjson_total += len; LP_cjson_count++; - //return(calloc(1,len)); struct LP_memory_list *mp; mp = calloc(1,sizeof(*mp) + len); mp->ptr = calloc(1,len); @@ -1238,16 +1221,11 @@ void *LP_alloc(uint64_t len) return(mp->ptr); } -void *LP_realloc(void *ptr,uint64_t len) -{ - return(realloc(ptr,len)); -} - void LP_free(void *ptr) { static uint32_t lasttime,unknown; - //free(ptr); - //return; + free(ptr); + return; uint32_t now; char str[65]; int32_t n,lagging; uint64_t total = 0; struct LP_memory_list *mp,*tmp; if ( (now= (uint32_t)time(NULL)) > lasttime+60 ) { @@ -1297,3 +1275,9 @@ char *LP_clonestr(char *str) return(retstr); } +void *LP_realloc(void *ptr,uint64_t len) +{ + return(realloc(ptr,len)); +} + + diff --git a/iguana/exchanges/LP_ordermatch.c b/iguana/exchanges/LP_ordermatch.c index 04faf3715..b541200a1 100644 --- a/iguana/exchanges/LP_ordermatch.c +++ b/iguana/exchanges/LP_ordermatch.c @@ -718,6 +718,7 @@ int32_t LP_listunspent_both(char *symbol,char *coinaddr,int32_t fullflag) LP_address_utxoadd(now,"LP_listunspent_both",coin,coinaddr,txid,v,value,height,-1); } } + free_json(array); } } } //else printf("%s coin.%p inactive.%d\n",symbol,coin,coin!=0?coin->inactive:-1); diff --git a/iguana/exchanges/LP_prices.c b/iguana/exchanges/LP_prices.c index 7313c733b..d299b8368 100644 --- a/iguana/exchanges/LP_prices.c +++ b/iguana/exchanges/LP_prices.c @@ -265,6 +265,7 @@ uint64_t LP_unspents_metric(struct iguana_info *coin,char *coinaddr) } } metric = _LP_unspents_metric(total,n); + free_json(array); } return(metric); } diff --git a/iguana/exchanges/LP_rpc.c b/iguana/exchanges/LP_rpc.c index 2a66c9b94..320eec701 100644 --- a/iguana/exchanges/LP_rpc.c +++ b/iguana/exchanges/LP_rpc.c @@ -682,15 +682,6 @@ int32_t LP_listunspent_issue(char *symbol,char *coinaddr,int32_t fullflag) { //printf("LP_listunspent_query.(%s %s)\n",symbol,coinaddr); 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 ) { diff --git a/iguana/exchanges/LP_signatures.c b/iguana/exchanges/LP_signatures.c index 0742f49d5..fee4a1189 100644 --- a/iguana/exchanges/LP_signatures.c +++ b/iguana/exchanges/LP_signatures.c @@ -649,7 +649,6 @@ void LP_smartutxos_push(struct iguana_info *coin) char *LP_uitem_recv(cJSON *argjson) { bits256 txid; int32_t vout,height; uint64_t value; struct iguana_info *coin; char *coinaddr,*symbol; - printf("LP_uitem_recv.0 %ld\n",LP_cjson_allocated); txid = jbits256(argjson,"txid"); vout = jint(argjson,"vout"); height = jint(argjson,"ht"); @@ -661,9 +660,7 @@ char *LP_uitem_recv(cJSON *argjson) if ( strcmp(coin->smartaddr,coinaddr) != 0 ) LP_address_utxoadd((uint32_t)time(NULL),"LP_uitem_recv",coin,coinaddr,txid,vout,value,height,-1); //else printf("ignore external uitem %s %s\n",symbol,coin->smartaddr); - printf("LP_uitem_recv.1 %ld\n",LP_cjson_allocated); } - printf("LP_uitem_recv.2 %ld\n",LP_cjson_allocated); return(clonestr("{\"result\":\"success\"}")); } diff --git a/iguana/exchanges/LP_statemachine.c b/iguana/exchanges/LP_statemachine.c index 3c32b8cad..86997fcd5 100644 --- a/iguana/exchanges/LP_statemachine.c +++ b/iguana/exchanges/LP_statemachine.c @@ -355,6 +355,16 @@ char *issue_LP_getprices(char *destip,uint16_t destport) return(LP_issue_curl("getprices",destip,destport,url)); //return(issue_curlt(url,LP_HTTP_TIMEOUT)); } +/*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"); + }*/ + void issue_LP_listunspent(char *destip,uint16_t destport,char *symbol,char *coinaddr) { cJSON *reqjson = cJSON_CreateObject(); diff --git a/iguana/exchanges/LP_utxo.c b/iguana/exchanges/LP_utxo.c index 1ebb7039e..c93f5e0fc 100644 --- a/iguana/exchanges/LP_utxo.c +++ b/iguana/exchanges/LP_utxo.c @@ -423,7 +423,6 @@ void LP_mark_spent(char *symbol,bits256 txid,int32_t vout) 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) { struct LP_address *ap; cJSON *txobj; struct LP_transaction *tx; struct LP_address_utxo *up,*tmp; int32_t flag,retval = 0; //char str[65]; - printf("LP_address_utxoadd.0 %ld\n",LP_cjson_allocated); if ( coin == 0 ) return(0); if ( spendheight > 0 ) // dont autocreate entries for spends we dont care about @@ -480,7 +479,6 @@ int32_t LP_address_utxoadd(uint32_t timestamp,char *debug,struct iguana_info *co } } // else printf("cant get ap %s %s\n",coin->symbol,coinaddr); //printf("done %s add addr.%s ht.%d\n",coin->symbol,coinaddr,height); - printf("LP_address_utxoadd.1 %ld\n",LP_cjson_allocated); return(retval); } @@ -505,7 +503,7 @@ struct LP_address *LP_address_utxo_reset(struct iguana_info *coin) up->spendheight = (int32_t)time(NULL); DL_APPEND(LP_garbage_collector2,up); portable_mutex_unlock(&LP_gcmutex); - } + } now = (uint32_t)time(NULL); if ( (n= cJSON_GetArraySize(array)) > 0 ) { @@ -636,6 +634,7 @@ cJSON *LP_address_balance(struct iguana_info *coin,char *coinaddr,int32_t electr balance += LP_value_extract(item,1); } } + free_json(array); } } else @@ -654,6 +653,7 @@ cJSON *LP_address_balance(struct iguana_info *coin,char *coinaddr,int32_t electr balance += j64bits(item,"value"); } } + free_json(array); } } } diff --git a/iguana/exchanges/LP_utxos.c b/iguana/exchanges/LP_utxos.c index 497760624..2498d4da4 100644 --- a/iguana/exchanges/LP_utxos.c +++ b/iguana/exchanges/LP_utxos.c @@ -570,15 +570,11 @@ int32_t LP_privkey_init(int32_t mypubsock,struct iguana_info *coin,bits256 mypri } if ( coin->privkeydepth > 0 ) return(0); - printf("LP_privkey_init.0 %ld\n",LP_cjson_allocated); coin->privkeydepth++; LP_address(coin,coin->smartaddr); - printf("LP_privkey_init.1 %ld\n",LP_cjson_allocated); if ( coin->inactive == 0 ) LP_listunspent_issue(coin->symbol,coin->smartaddr,0); - printf("LP_privkey_init.2 %ld\n",LP_cjson_allocated); array = LP_listunspent(coin->symbol,coin->smartaddr); - printf("LP_privkey_init.3 %ld\n",LP_cjson_allocated); if ( array != 0 ) { txfee = LP_txfeecalc(coin,0,0); @@ -707,7 +703,6 @@ int32_t LP_privkey_init(int32_t mypubsock,struct iguana_info *coin,bits256 mypri if ( flag != 0 ) LP_postutxos(coin->symbol,coin->smartaddr); } - printf("LP_privkey_init.4 %ld\n",LP_cjson_allocated); if ( values != 0 ) free(values); if ( coin->privkeydepth > 0 ) @@ -819,7 +814,8 @@ bits256 LP_privkeycalc(void *ctx,uint8_t *pubkey33,bits256 *pubkeyp,struct iguan printf("cant importprivkey.%s -> (%s), abort session\n",coin->symbol,jprint(retjson,1)); exit(-1); } - } else free_json(retjson); + free_json(retjson); + } coin->importedprivkey = (uint32_t)time(NULL); } vcalc_sha256(0,checkkey.bytes,privkey.bytes,sizeof(privkey)); From d596bcfc940bd1683894a5a6573be71084529108 Mon Sep 17 00:00:00 2001 From: jl777 Date: Thu, 16 Nov 2017 07:21:01 +0200 Subject: [PATCH 0909/1664] Test --- iguana/exchanges/LP_nativeDEX.c | 20 ++++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) diff --git a/iguana/exchanges/LP_nativeDEX.c b/iguana/exchanges/LP_nativeDEX.c index 9c260bdaa..9fb48bb7f 100644 --- a/iguana/exchanges/LP_nativeDEX.c +++ b/iguana/exchanges/LP_nativeDEX.c @@ -1032,18 +1032,18 @@ void LPinit(uint16_t myport,uint16_t mypullport,uint16_t mypubport,uint16_t mybu printf("error launching LP_reserved_msgs for (%s)\n",myipaddr); exit(-1); } - if ( 0 && OS_thread_create(malloc(sizeof(pthread_t)),NULL,(void *)utxosQ_loop,(void *)myipaddr) != 0 ) + if ( OS_thread_create(malloc(sizeof(pthread_t)),NULL,(void *)utxosQ_loop,(void *)myipaddr) != 0 ) { printf("error launching utxosQ_loop for (%s)\n",myipaddr); exit(-1); } - if ( 0 && OS_thread_create(malloc(sizeof(pthread_t)),NULL,(void *)stats_rpcloop,(void *)&myport) != 0 ) + if ( OS_thread_create(malloc(sizeof(pthread_t)),NULL,(void *)stats_rpcloop,(void *)&myport) != 0 ) { printf("error launching stats rpcloop for port.%u\n",myport); exit(-1); } uint16_t myport2 = myport-1; - if ( 0 && OS_thread_create(malloc(sizeof(pthread_t)),NULL,(void *)stats_rpcloop,(void *)&myport2) != 0 ) + if ( OS_thread_create(malloc(sizeof(pthread_t)),NULL,(void *)stats_rpcloop,(void *)&myport2) != 0 ) { printf("error launching stats rpcloop for port.%u\n",myport); exit(-1); @@ -1058,32 +1058,32 @@ void LPinit(uint16_t myport,uint16_t mypullport,uint16_t mypubport,uint16_t mybu printf("error launching queue_loop for port.%u\n",myport); exit(-1); } - if ( 0 && OS_thread_create(malloc(sizeof(pthread_t)),NULL,(void *)gc_loop,(void *)myipaddr) != 0 ) + if ( OS_thread_create(malloc(sizeof(pthread_t)),NULL,(void *)gc_loop,(void *)myipaddr) != 0 ) { printf("error launching gc_loop for port.%u\n",myport); exit(-1); } - if ( 0 && OS_thread_create(malloc(sizeof(pthread_t)),NULL,(void *)prices_loop,ctx) != 0 ) + if ( OS_thread_create(malloc(sizeof(pthread_t)),NULL,(void *)prices_loop,ctx) != 0 ) { printf("error launching prices_loop for port.%u\n",myport); exit(-1); } - if ( 0 && OS_thread_create(malloc(sizeof(pthread_t)),NULL,(void *)LP_coinsloop,(void *)"") != 0 ) + if ( OS_thread_create(malloc(sizeof(pthread_t)),NULL,(void *)LP_coinsloop,(void *)"") != 0 ) { printf("error launching LP_coinsloop for port.%u\n",myport); exit(-1); } - if ( 0 && OS_thread_create(malloc(sizeof(pthread_t)),NULL,(void *)LP_coinsloop,(void *)"BTC") != 0 ) + if ( OS_thread_create(malloc(sizeof(pthread_t)),NULL,(void *)LP_coinsloop,(void *)"BTC") != 0 ) { printf("error launching BTC LP_coinsloop for port.%u\n",myport); exit(-1); } - if ( 0 && OS_thread_create(malloc(sizeof(pthread_t)),NULL,(void *)LP_coinsloop,(void *)"KMD") != 0 ) + if ( OS_thread_create(malloc(sizeof(pthread_t)),NULL,(void *)LP_coinsloop,(void *)"KMD") != 0 ) { printf("error launching KMD LP_coinsloop for port.%u\n",myport); exit(-1); } - if ( 0 && OS_thread_create(malloc(sizeof(pthread_t)),NULL,(void *)LP_pubkeysloop,(void *)myipaddr) != 0 ) + if ( OS_thread_create(malloc(sizeof(pthread_t)),NULL,(void *)LP_pubkeysloop,(void *)myipaddr) != 0 ) { printf("error launching LP_pubkeysloop for ctx.%p\n",ctx); exit(-1); @@ -1093,7 +1093,7 @@ void LPinit(uint16_t myport,uint16_t mypullport,uint16_t mypubport,uint16_t mybu printf("error launching LP_privkeysloop for ctx.%p\n",ctx); exit(-1); } - if ( 0 && OS_thread_create(malloc(sizeof(pthread_t)),NULL,(void *)LP_swapsloop,(void *)myipaddr) != 0 ) + if ( OS_thread_create(malloc(sizeof(pthread_t)),NULL,(void *)LP_swapsloop,(void *)myipaddr) != 0 ) { printf("error launching LP_swapsloop for port.%u\n",myport); exit(-1); From dce7ba29d7d29fff92dde3e0be9e7c306dcd32c9 Mon Sep 17 00:00:00 2001 From: jl777 Date: Thu, 16 Nov 2017 09:53:37 +0200 Subject: [PATCH 0910/1664] Test --- iguana/exchanges/LP_RTmetrics.c | 2 +- iguana/exchanges/LP_nativeDEX.c | 3 +- iguana/exchanges/LP_ordermatch.c | 2 +- iguana/exchanges/LP_remember.c | 23 ------- iguana/exchanges/LP_rpc.c | 61 +++++++++--------- iguana/exchanges/LP_scan.c | 2 +- iguana/exchanges/LP_socket.c | 2 +- iguana/exchanges/LP_statemachine.c | 100 +++++++++++++++++++++++++++++ iguana/exchanges/LP_transaction.c | 11 ---- iguana/exchanges/LP_utxo.c | 66 ------------------- 10 files changed, 138 insertions(+), 134 deletions(-) diff --git a/iguana/exchanges/LP_RTmetrics.c b/iguana/exchanges/LP_RTmetrics.c index ac01d3025..53466e5e7 100644 --- a/iguana/exchanges/LP_RTmetrics.c +++ b/iguana/exchanges/LP_RTmetrics.c @@ -161,7 +161,7 @@ void LP_RTmetrics_update(char *base,char *rel) { if ( (swaps= jarray(&numswaps,statsjson,"swaps")) != 0 ) { - printf("LP_RTmetrics_update for (%s)\n",jprint(swaps,0)); + //printf("LP_RTmetrics_update for (%s)\n",jprint(swaps,0)); if ( numswaps > 0 ) LP_RTmetrics_swapsinfo(base,rel,swaps,numswaps); } diff --git a/iguana/exchanges/LP_nativeDEX.c b/iguana/exchanges/LP_nativeDEX.c index 9fb48bb7f..b265c8d7b 100644 --- a/iguana/exchanges/LP_nativeDEX.c +++ b/iguana/exchanges/LP_nativeDEX.c @@ -19,10 +19,11 @@ // // if ( G.LP_pendingswaps != 0 ) return(-1); // bot safe to exit? -// +// 324744 and 50mb // BCH signing // single utxo allocations alice // alice waiting for bestprice +// // previously, it used to show amount, kmd equiv, perc // dPoW security -> 4: KMD notarized, 5: BTC notarized, after next notary elections // bigendian architectures need to use little endian for sighash calcs diff --git a/iguana/exchanges/LP_ordermatch.c b/iguana/exchanges/LP_ordermatch.c index b541200a1..e1f7bf62e 100644 --- a/iguana/exchanges/LP_ordermatch.c +++ b/iguana/exchanges/LP_ordermatch.c @@ -889,7 +889,7 @@ int32_t LP_tradecommand(void *ctx,char *myipaddr,int32_t pubsock,cJSON *argjson, price += (r * range) / 100.; bestprice = LP_bob_competition(&counter,aliceid,price,0); printf(">>>>>>>>>>>>> price %.8f qprice %.8f r.%d range %.8f -> %.8f, bestprice %.8f counter.%d\n",ask,qprice,r,range,price,bestprice,counter); - if ( counter > 5 || price > bestprice*1.1 ) // skip if late or bad price + if ( counter > 3 || price > bestprice ) // skip if late or bad price return(retval); } else return(retval); LP_RTmetrics_update(Q.srccoin,Q.destcoin); diff --git a/iguana/exchanges/LP_remember.c b/iguana/exchanges/LP_remember.c index c0ef0efd7..7889181bf 100644 --- a/iguana/exchanges/LP_remember.c +++ b/iguana/exchanges/LP_remember.c @@ -1247,29 +1247,6 @@ char *basilisk_swapentry(uint32_t requestid,uint32_t quoteid) if ( (item= basilisk_remember(KMDtotals,BTCtotals,requestid,quoteid)) != 0 ) return(jprint(item,1)); else return(clonestr("{\"error\":\"cant find requestid-quoteid\"}")); - /*if ( (liststr= basilisk_swaplist(requestid,quoteid)) != 0 ) - { - //printf("swapentry.(%s)\n",liststr); - if ( (retjson= cJSON_Parse(liststr)) != 0 ) - { - if ( (array= jarray(&n,retjson,"swaps")) != 0 ) - { - for (i=0; iserverport,coin->userpass,"signrawtransaction",paramstr)) != 0 ) + if ( (0) ) { - if ( (json= cJSON_Parse(retstr)) != 0 ) + array = cJSON_CreateArray(); + jaddistr(array,rawtx); + jaddi(array,jduplicate(vins)); + jaddi(array,jduplicate(privkeys)); + paramstr = jprint(array,1); + //printf("signrawtransaction\n"); + if ( (retstr= bitcoind_passthru(symbol,coin->serverport,coin->userpass,"signrawtransaction",paramstr)) != 0 ) { - if ( (hexstr= jstr(json,"hex")) != 0 ) + if ( (json= cJSON_Parse(retstr)) != 0 ) { - len = (int32_t)strlen(hexstr); - signedtx = calloc(1,len+1); - strcpy(signedtx,hexstr); - *completedp = is_cJSON_True(jobj(json,"complete")); - len >>= 1; - data = malloc(len); - decode_hex(data,len,hexstr); - *signedtxidp = bits256_doublesha256(0,data,len); + if ( (hexstr= jstr(json,"hex")) != 0 ) + { + len = (int32_t)strlen(hexstr); + signedtx = calloc(1,len+1); + strcpy(signedtx,hexstr); + *completedp = is_cJSON_True(jobj(json,"complete")); + len >>= 1; + data = malloc(len); + decode_hex(data,len,hexstr); + *signedtxidp = bits256_doublesha256(0,data,len); + } + //else + printf("%s signrawtransaction.(%s) params.(%s)\n",coin->symbol,retstr,paramstr); + free_json(json); } - //else - printf("%s signrawtransaction.(%s) params.(%s)\n",coin->symbol,retstr,paramstr); - free_json(json); + free(retstr); } - free(retstr); + free(paramstr); + return(signedtx); } - free(paramstr); - return(signedtx); } cJSON *LP_getblock(char *symbol,bits256 txid) @@ -1032,7 +1035,7 @@ uint32_t LP_heighttime(char *symbol,int32_t height) { if ( (retjson= cJSON_Parse(blockhashstr)) != 0 ) { - printf("height.(%s)\n",jprint(retjson,0)); + //printf("height.(%s)\n",jprint(retjson,0)); timestamp = juint(retjson,"time"); free_json(retjson); } @@ -1043,7 +1046,7 @@ uint32_t LP_heighttime(char *symbol,int32_t height) { if ( (retjson= electrum_getheader(coin->symbol,ep,&retjson,height)) != 0 ) { - printf("%s\n",jprint(retjson,0)); + //printf("%s\n",jprint(retjson,0)); timestamp = juint(retjson,"timestamp"); free_json(retjson); } @@ -1074,7 +1077,7 @@ cJSON *LP_blockjson(int32_t *heightp,char *symbol,char *blockhashstr,int32_t hei *heightp = juint(json,"height"); if ( height >= 0 && *heightp != height ) { - printf("unexpected height %d vs %d for %s (%s)\n",*heightp,height,blockhashstr,jprint(json,0)); + //printf("unexpected height %d vs %d for %s (%s)\n",*heightp,height,blockhashstr,jprint(json,0)); *heightp = -1; free_json(json); json = 0; @@ -1255,7 +1258,7 @@ int32_t LP_notarization_latest(int32_t *bestheightp,struct iguana_info *coin) blockhash = jbits256(blockjson,"previousblockhash"); if ( bits256_nonz(blockhash) == 0 ) { - printf("null prev.(%s)\n",jprint(blockjson,0)); + //printf("null prev.(%s)\n",jprint(blockjson,0)); free_json(blockjson); break; } diff --git a/iguana/exchanges/LP_scan.c b/iguana/exchanges/LP_scan.c index 5a5a12051..f3b67476b 100644 --- a/iguana/exchanges/LP_scan.c +++ b/iguana/exchanges/LP_scan.c @@ -466,7 +466,7 @@ int32_t LP_waitmempool(char *symbol,char *coinaddr,bits256 txid,int32_t vout,int { if ( (array= electrum_address_getmempool(symbol,coin->electrum,&array,coinaddr)) != 0 ) { - char str[65]; printf("check %s mempool.(%s)\n",bits256_str(str,txid),jprint(array,0)); + //char str[65]; printf("check %s mempool.(%s)\n",bits256_str(str,txid),jprint(array,0)); if ( (n= cJSON_GetArraySize(array)) > 0 ) { for (i=0; i lasthello+600 ) { char *hellostr,*retstr; cJSON *retjson; int32_t allgood,sock = LP_bindsock; @@ -347,6 +359,94 @@ void issue_LP_uitem(char *destip,uint16_t destport,char *symbol,char *coinaddr,b return(retstr);*/ } +/*if ( (liststr= basilisk_swaplist(requestid,quoteid)) != 0 ) + { + //printf("swapentry.(%s)\n",liststr); + if ( (retjson= cJSON_Parse(liststr)) != 0 ) + { + if ( (array= jarray(&n,retjson,"swaps")) != 0 ) + { + for (i=0; itimestamp = (uint32_t)time(NULL); + ptr->item = item; + item->cjsonid = rand(); + ptr->cjsonid = item->cjsonid; + portable_mutex_lock(&LP_cJSONmutex); + DL_APPEND(LP_cJSONlist,ptr); + portable_mutex_unlock(&LP_cJSONmutex); + } + + void cJSON_unregister(cJSON *item) + { + static uint32_t lasttime; + int32_t n; char *tmpstr; uint64_t total = 0; struct cJSON_list *ptr,*tmp; uint32_t now; + if ( (now= (uint32_t)time(NULL)) > lasttime+6 ) + { + n = 0; + DL_FOREACH_SAFE(LP_cJSONlist,ptr,tmp) + { + if ( ptr->item != 0 && ptr->item->child != 0 && ptr->cjsonid != 0 ) + { + if ( (tmpstr= jprint(ptr->item,0)) != 0 ) + { + total += strlen(tmpstr); + free(tmpstr); + } + } + n++; + } + printf("total %d cJSON pending\n",n); + lasttime = (uint32_t)time(NULL); + } + DL_FOREACH_SAFE(LP_cJSONlist,ptr,tmp) + { + if ( ptr->cjsonid == item->cjsonid ) + break; + else if ( now > ptr->timestamp+60 && item->cjsonid != 0 ) + { + portable_mutex_lock(&LP_cJSONmutex); + DL_DELETE(LP_cJSONlist,ptr); + portable_mutex_unlock(&LP_cJSONmutex); + printf("free expired\n"); + cJSON_Delete(ptr->item); + free(ptr); + } + ptr = 0; + } + if ( ptr != 0 ) + { + portable_mutex_lock(&LP_cJSONmutex); + DL_DELETE(LP_cJSONlist,ptr); + free(ptr); + portable_mutex_unlock(&LP_cJSONmutex); + } //else printf("cJSON_unregister of unknown %p %u\n",item,item->cjsonid); + }*/ char *issue_LP_getprices(char *destip,uint16_t destport) { char url[512]; diff --git a/iguana/exchanges/LP_transaction.c b/iguana/exchanges/LP_transaction.c index cfd1a6060..f90a87170 100644 --- a/iguana/exchanges/LP_transaction.c +++ b/iguana/exchanges/LP_transaction.c @@ -1651,17 +1651,6 @@ void LP_swap_coinaddr(struct iguana_info *coin,char *coinaddr,uint64_t *valuep,u vout = jitem(vouts,v); if ( valuep != 0 ) *valuep = LP_value_extract(vout,1); - //printf("VOUT.(%s)\n",jprint(vout,0)); - /*if ( (skey= jobj(vout,"scriptPubKey")) != 0 && (addresses= jarray(&m,skey,"addresses")) != 0 ) - { - item = jitem(addresses,0); - //printf("item.(%s)\n",jprint(item,0)); - if ( (addr= jstr(item,0)) != 0 ) - { - safecopy(coinaddr,addr,64); - //printf("extracted.(%s)\n",coinaddr); - } - }*/ LP_destaddr(coinaddr,vout); } free_json(txobj); diff --git a/iguana/exchanges/LP_utxo.c b/iguana/exchanges/LP_utxo.c index c93f5e0fc..59b8b8b8e 100644 --- a/iguana/exchanges/LP_utxo.c +++ b/iguana/exchanges/LP_utxo.c @@ -27,72 +27,6 @@ struct LP_inuse_info } LP_inuse[1024]; int32_t LP_numinuse; -/*struct cJSON_list -{ - struct cJSON_list *next,*prev; - cJSON *item; - uint32_t timestamp,cjsonid; -} *LP_cJSONlist; - -void cJSON_register(cJSON *item) -{ - struct cJSON_list *ptr; - ptr = calloc(1,sizeof(*ptr)); - ptr->timestamp = (uint32_t)time(NULL); - ptr->item = item; - item->cjsonid = rand(); - ptr->cjsonid = item->cjsonid; - portable_mutex_lock(&LP_cJSONmutex); - DL_APPEND(LP_cJSONlist,ptr); - portable_mutex_unlock(&LP_cJSONmutex); -} - -void cJSON_unregister(cJSON *item) -{ - static uint32_t lasttime; - int32_t n; char *tmpstr; uint64_t total = 0; struct cJSON_list *ptr,*tmp; uint32_t now; - if ( (now= (uint32_t)time(NULL)) > lasttime+6 ) - { - n = 0; - DL_FOREACH_SAFE(LP_cJSONlist,ptr,tmp) - { - if ( ptr->item != 0 && ptr->item->child != 0 && ptr->cjsonid != 0 ) - { - if ( (tmpstr= jprint(ptr->item,0)) != 0 ) - { - total += strlen(tmpstr); - free(tmpstr); - } - } - n++; - } - printf("total %d cJSON pending\n",n); - lasttime = (uint32_t)time(NULL); - } - DL_FOREACH_SAFE(LP_cJSONlist,ptr,tmp) - { - if ( ptr->cjsonid == item->cjsonid ) - break; - else if ( now > ptr->timestamp+60 && item->cjsonid != 0 ) - { - portable_mutex_lock(&LP_cJSONmutex); - DL_DELETE(LP_cJSONlist,ptr); - portable_mutex_unlock(&LP_cJSONmutex); - printf("free expired\n"); - cJSON_Delete(ptr->item); - free(ptr); - } - ptr = 0; - } - if ( ptr != 0 ) - { - portable_mutex_lock(&LP_cJSONmutex); - DL_DELETE(LP_cJSONlist,ptr); - free(ptr); - portable_mutex_unlock(&LP_cJSONmutex); - } //else printf("cJSON_unregister of unknown %p %u\n",item,item->cjsonid); -}*/ - struct LP_inuse_info *_LP_inuse_find(bits256 txid,int32_t vout) { int32_t i; From 838df594ae564cefd091bd7e5bc673edfbb61c18 Mon Sep 17 00:00:00 2001 From: jl777 Date: Thu, 16 Nov 2017 10:33:10 +0200 Subject: [PATCH 0911/1664] Test --- crypto777/cJSON.c | 93 +++++++++++++++++++++++---------- iguana/exchanges/LP_nativeDEX.c | 11 ++-- 2 files changed, 69 insertions(+), 35 deletions(-) diff --git a/crypto777/cJSON.c b/crypto777/cJSON.c index 4c0777656..901e6fc98 100755 --- a/crypto777/cJSON.c +++ b/crypto777/cJSON.c @@ -59,13 +59,46 @@ void LP_free(void *ptr); static void *(*cJSON_malloc)(size_t sz) = (void *)LP_alloc; static void (*cJSON_free)(void *ptr) = LP_free; +static void *cJSON_mallocstr(int32_t len) +{ + return(cJSON_malloc(len)); +} + +static char **cJSON_mallocptrs(int32_t num,char **space,int32_t max) +{ + if ( num < max ) + return(space); + else return(cJSON_malloc(num * sizeof(char *))); +} + +static void *cJSON_mallocnode() +{ + return(cJSON_malloc(sizeof(cJSON))); +} + +static void cJSON_freeptrs(char **ptrs,int32_t num,char **space) +{ + if ( ptrs != space ) + cJSON_free(ptrs); +} + +static void cJSON_freestr(char *str) +{ + cJSON_free(str); +} + +static void cJSON_freenode(cJSON *item) +{ + cJSON_free(item); +} + static char* cJSON_strdup(const char* str) { size_t len; char* copy; len = strlen(str) + 1; - if (!(copy = (char*)cJSON_malloc(len+1))) return 0; + if (!(copy = (char*)cJSON_mallocstr((int32_t)len+1))) return 0; memcpy(copy,str,len); return copy; } @@ -78,14 +111,14 @@ void cJSON_InitHooks(cJSON_Hooks* hooks) return; } - cJSON_malloc = (hooks->malloc_fn)?hooks->malloc_fn:malloc; - cJSON_free = (hooks->free_fn)?hooks->free_fn:free; + cJSON_malloc = (hooks->malloc_fn)?hooks->malloc_fn:malloc; + cJSON_free = (hooks->free_fn)?hooks->free_fn:free; } /* Internal constructor. */ static cJSON *cJSON_New_Item(void) { - cJSON* node = (cJSON*)cJSON_malloc(sizeof(cJSON)); + cJSON* node = (cJSON*)cJSON_mallocnode(); if (node) memset(node,0,sizeof(cJSON)); return node; } @@ -98,9 +131,9 @@ void cJSON_Delete(cJSON *c) { next=c->next; if (!(c->type&cJSON_IsReference) && c->child) cJSON_Delete(c->child); - if (!(c->type&cJSON_IsReference) && c->valuestring) cJSON_free(c->valuestring); - if (c->string) cJSON_free(c->string); - cJSON_free(c); + if (!(c->type&cJSON_IsReference) && c->valuestring) cJSON_freestr(c->valuestring); + if (c->string) cJSON_freestr(c->string); + cJSON_freenode(c); c=next; } } @@ -134,13 +167,13 @@ static char *print_number(cJSON *item) double d = item->valuedouble; if ( fabs(((double)item->valueint) - d) <= DBL_EPSILON && d >= (1. - DBL_EPSILON) && d < (1LL << 62) )//d <= INT_MAX && d >= INT_MIN ) { - str = (char *)cJSON_malloc(24); /* 2^64+1 can be represented in 21 chars + sign. */ + str = (char *)cJSON_mallocstr(24); /* 2^64+1 can be represented in 21 chars + sign. */ if ( str != 0 ) sprintf(str,"%lld",(long long)item->valueint); } else { - str = (char *)cJSON_malloc(66); /* This is a nice tradeoff. */ + str = (char *)cJSON_mallocstr(66); /* This is a nice tradeoff. */ if ( str != 0 ) { if ( fabs(floor(d) - d) <= DBL_EPSILON && fabs(d) < 1.0e60 ) @@ -175,7 +208,7 @@ static const char *parse_string(cJSON *item,const char *str) while (*ptr!='\"' && *ptr && ++len) if (*ptr++ == '\\') ptr++; // Skip escaped quotes - out=(char*)cJSON_malloc(len+2); /* This is how long we need for the string, roughly. */ + out=(char*)cJSON_mallocstr(len+2); /* This is how long we need for the string, roughly. */ if (!out) return 0; ptr=str+1;ptr2=out; @@ -240,7 +273,7 @@ static char *print_string_ptr(const char *str) if (!str) return cJSON_strdup(""); ptr=str;while ((token=*ptr) && ++len) {if (strchr("\"\\\b\f\n\r\t",token)) len++; else if (token<32) len+=5;ptr++;} - out=(char*)cJSON_malloc(len+3+1); + out=(char*)cJSON_mallocstr(len+3+1); if (!out) return 0; ptr2=out;ptr=str; @@ -374,7 +407,7 @@ static const char *parse_array(cJSON *item,const char *value) /* Render an array to text */ static char *print_array(cJSON *item,int32_t depth,int32_t fmt) { - char **entries; + char **entries,*space_entries[512]; char *out=0,*ptr,*ret;int32_t len=5; cJSON *child=item->child; int32_t numentries=0,i=0,fail=0; @@ -384,12 +417,12 @@ static char *print_array(cJSON *item,int32_t depth,int32_t fmt) /* Explicitly handle numentries==0 */ if (!numentries) { - out=(char*)cJSON_malloc(3+1); + out=(char*)cJSON_mallocstr(3+1); if (out) strcpy(out,"[]"); return out; } /* Allocate an array to hold the values for each */ - entries=(char**)cJSON_malloc((1+numentries)*sizeof(char*)); + entries=cJSON_mallocptrs(1+numentries,space_entries,sizeof(space_entries)/sizeof(*space_entries)); if (!entries) return 0; memset(entries,0,numentries*sizeof(char*)); /* Retrieve all the results: */ @@ -403,15 +436,15 @@ static char *print_array(cJSON *item,int32_t depth,int32_t fmt) } /* If we didn't fail, try to malloc the output string */ - if (!fail) out=(char*)cJSON_malloc(len+1); + if (!fail) out=(char*)cJSON_mallocstr(len+1); /* If that fails, we fail. */ if (!out) fail=1; /* Handle failure. */ if (fail) { - for (i=0;ichild,*firstchild; int32_t numentries=0,fail=0; @@ -487,7 +520,7 @@ static char *print_object(cJSON *item,int32_t depth,int32_t fmt) /* Explicitly handle empty object case */ if (!numentries) { - out=(char*)cJSON_malloc(fmt?depth+4+1:3+1); + out=(char*)cJSON_mallocstr(fmt?depth+4+1:3+1); if (!out) return 0; ptr=out;*ptr++='{'; if (fmt) {*ptr++='\n';for (i=0;i 32 && cipherlen <= sizeof(decoded)*2 ) + if ( 0 && (cipherstr= jstr(argjson,"cipher")) != 0 && (cipherlen= is_hexstr(cipherstr,0)) > 32 && cipherlen <= sizeof(decoded)*2 ) { method2 = jstr(argjson,"method2"); if ( (method= jstr(argjson,"method")) != 0 && (strcmp(method,"encrypted") == 0 ||(method2 != 0 && strcmp(method2,"encrypted") == 0)) ) @@ -1206,14 +1206,14 @@ int32_t zeroval() { return(0); } void *LP_alloc(uint64_t len) { - return(calloc(1,len)); + //return(calloc(1,len)); LP_cjson_allocated += len; LP_cjson_total += len; LP_cjson_count++; struct LP_memory_list *mp; mp = calloc(1,sizeof(*mp) + len); mp->ptr = calloc(1,len); - printf(">>>>>>>>>>> LP_alloc mp.%p ptr.%p len.%llu %llu\n",mp,mp->ptr,(long long)len,(long long)LP_cjson_allocated); + //printf(">>>>>>>>>>> LP_alloc mp.%p ptr.%p len.%llu %llu\n",mp,mp->ptr,(long long)len,(long long)LP_cjson_allocated); mp->timestamp = (uint32_t)time(NULL); mp->len = (uint32_t)len; portable_mutex_lock(&LP_cJSONmutex); @@ -1225,8 +1225,7 @@ void *LP_alloc(uint64_t len) void LP_free(void *ptr) { static uint32_t lasttime,unknown; - free(ptr); - return; + // free(ptr); return; uint32_t now; char str[65]; int32_t n,lagging; uint64_t total = 0; struct LP_memory_list *mp,*tmp; if ( (now= (uint32_t)time(NULL)) > lasttime+60 ) { @@ -1263,7 +1262,7 @@ void LP_free(void *ptr) portable_mutex_lock(&LP_cJSONmutex); DL_DELETE(LP_memory_list,mp); portable_mutex_unlock(&LP_cJSONmutex); - printf(">>>>>>>>>>> LP_free ptr.%p mp.%p len.%u %llu\n",ptr,mp,mp->len,(long long)LP_cjson_allocated); + //printf(">>>>>>>>>>> LP_free ptr.%p mp.%p len.%u %llu\n",ptr,mp,mp->len,(long long)LP_cjson_allocated); free(mp->ptr); free(mp); } else unknown++; // free from source file with #define redirect for alloc that wasnt From ef31b37fce7919122c121f751f4f6b3a9dbd5146 Mon Sep 17 00:00:00 2001 From: jl777 Date: Thu, 16 Nov 2017 10:35:53 +0200 Subject: [PATCH 0912/1664] Test --- iguana/exchanges/LP_nativeDEX.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/iguana/exchanges/LP_nativeDEX.c b/iguana/exchanges/LP_nativeDEX.c index e10ce33be..93f37280e 100644 --- a/iguana/exchanges/LP_nativeDEX.c +++ b/iguana/exchanges/LP_nativeDEX.c @@ -250,7 +250,7 @@ char *LP_process_message(void *ctx,char *typestr,char *myipaddr,int32_t pubsock, uint8_t decoded[LP_ENCRYPTED_MAXSIZE + crypto_box_ZEROBYTES]; //printf("[%s]\n",jsonstr); cipherlen = 0; - if ( 0 && (cipherstr= jstr(argjson,"cipher")) != 0 && (cipherlen= is_hexstr(cipherstr,0)) > 32 && cipherlen <= sizeof(decoded)*2 ) + if ( (cipherstr= jstr(argjson,"cipher")) != 0 && (cipherlen= is_hexstr(cipherstr,0)) > 32 && cipherlen <= sizeof(decoded)*2 ) { method2 = jstr(argjson,"method2"); if ( (method= jstr(argjson,"method")) != 0 && (strcmp(method,"encrypted") == 0 ||(method2 != 0 && strcmp(method2,"encrypted") == 0)) ) @@ -1084,17 +1084,17 @@ void LPinit(uint16_t myport,uint16_t mypullport,uint16_t mypubport,uint16_t mybu printf("error launching KMD LP_coinsloop for port.%u\n",myport); exit(-1); } - if ( OS_thread_create(malloc(sizeof(pthread_t)),NULL,(void *)LP_pubkeysloop,(void *)myipaddr) != 0 ) + if ( 0 && OS_thread_create(malloc(sizeof(pthread_t)),NULL,(void *)LP_pubkeysloop,(void *)myipaddr) != 0 ) { printf("error launching LP_pubkeysloop for ctx.%p\n",ctx); exit(-1); } - if ( OS_thread_create(malloc(sizeof(pthread_t)),NULL,(void *)LP_privkeysloop,(void *)myipaddr) != 0 ) + if ( 0 && OS_thread_create(malloc(sizeof(pthread_t)),NULL,(void *)LP_privkeysloop,(void *)myipaddr) != 0 ) { printf("error launching LP_privkeysloop for ctx.%p\n",ctx); exit(-1); } - if ( OS_thread_create(malloc(sizeof(pthread_t)),NULL,(void *)LP_swapsloop,(void *)myipaddr) != 0 ) + if ( 0 && OS_thread_create(malloc(sizeof(pthread_t)),NULL,(void *)LP_swapsloop,(void *)myipaddr) != 0 ) { printf("error launching LP_swapsloop for port.%u\n",myport); exit(-1); From 83bb9a061b7de944c876e586dd40540d9965f0cc Mon Sep 17 00:00:00 2001 From: jl777 Date: Thu, 16 Nov 2017 10:39:33 +0200 Subject: [PATCH 0913/1664] Test --- iguana/exchanges/LP_commands.c | 2 +- iguana/exchanges/LP_nativeDEX.c | 14 +++++++------- 2 files changed, 8 insertions(+), 8 deletions(-) diff --git a/iguana/exchanges/LP_commands.c b/iguana/exchanges/LP_commands.c index 72c64d04b..c7b2b84fb 100644 --- a/iguana/exchanges/LP_commands.c +++ b/iguana/exchanges/LP_commands.c @@ -542,7 +542,7 @@ bot_resume(botid)\n\ return(LP_postprice_recv(argjson)); else if ( strcmp(method,"postutxos") == 0 ) return(LP_postutxos_recv(argjson)); - else if ( strcmp(method,"uitem") == 0 ) + else if ( 0 && strcmp(method,"uitem") == 0 ) return(LP_uitem_recv(argjson)); else if ( strcmp(method,"notify") == 0 ) return(LP_notify_recv(argjson)); diff --git a/iguana/exchanges/LP_nativeDEX.c b/iguana/exchanges/LP_nativeDEX.c index 93f37280e..30548d1c6 100644 --- a/iguana/exchanges/LP_nativeDEX.c +++ b/iguana/exchanges/LP_nativeDEX.c @@ -327,7 +327,7 @@ char *LP_process_message(void *ctx,char *typestr,char *myipaddr,int32_t pubsock, int32_t LP_sock_check(char *typestr,void *ctx,char *myipaddr,int32_t pubsock,int32_t sock,char *remoteaddr,int32_t maxdepth) { - int32_t recvlen=1,nonz = 0; cJSON *argjson; void *ptr,*buf; char methodstr[64],*retstr,*str; struct nn_pollfd pfd; + int32_t recvlen=1,nonz = 0; cJSON *argjson; void *ptr; char methodstr[64],*retstr,*str; struct nn_pollfd pfd; if ( sock >= 0 ) { while ( nonz < maxdepth && recvlen > 0 ) @@ -339,11 +339,11 @@ int32_t LP_sock_check(char *typestr,void *ctx,char *myipaddr,int32_t pubsock,int if ( nn_poll(&pfd,1,1) != 1 ) break; ptr = 0; - buf = malloc(1000000); - if ( (recvlen= nn_recv(sock,buf,1000000,0)) > 0 ) - //if ( (recvlen= nn_recv(sock,&ptr,NN_MSG,0)) > 0 ) + //buf = malloc(1000000); + //if ( (recvlen= nn_recv(sock,buf,1000000,0)) > 0 ) + if ( (recvlen= nn_recv(sock,&ptr,NN_MSG,0)) > 0 ) { - ptr = buf; + //ptr = buf; methodstr[0] = 0; //printf("%s.(%s)\n",typestr,(char *)ptr); if ( 0 ) @@ -394,8 +394,8 @@ int32_t LP_sock_check(char *typestr,void *ctx,char *myipaddr,int32_t pubsock,int } if ( ptr != 0 ) { - //nn_freemsg(ptr), ptr = 0; - free(buf); + nn_freemsg(ptr), ptr = 0; + //free(buf); } } } From ce6dd7022046a38b3187243f35396c2d6678fe12 Mon Sep 17 00:00:00 2001 From: jl777 Date: Thu, 16 Nov 2017 10:48:30 +0200 Subject: [PATCH 0914/1664] Test --- iguana/exchanges/LP_commands.c | 2 +- iguana/exchanges/LP_nativeDEX.c | 16 ++++++++-------- 2 files changed, 9 insertions(+), 9 deletions(-) diff --git a/iguana/exchanges/LP_commands.c b/iguana/exchanges/LP_commands.c index c7b2b84fb..72c64d04b 100644 --- a/iguana/exchanges/LP_commands.c +++ b/iguana/exchanges/LP_commands.c @@ -542,7 +542,7 @@ bot_resume(botid)\n\ return(LP_postprice_recv(argjson)); else if ( strcmp(method,"postutxos") == 0 ) return(LP_postutxos_recv(argjson)); - else if ( 0 && strcmp(method,"uitem") == 0 ) + else if ( strcmp(method,"uitem") == 0 ) return(LP_uitem_recv(argjson)); else if ( strcmp(method,"notify") == 0 ) return(LP_notify_recv(argjson)); diff --git a/iguana/exchanges/LP_nativeDEX.c b/iguana/exchanges/LP_nativeDEX.c index 30548d1c6..dce105e65 100644 --- a/iguana/exchanges/LP_nativeDEX.c +++ b/iguana/exchanges/LP_nativeDEX.c @@ -1028,23 +1028,23 @@ void LPinit(uint16_t myport,uint16_t mypullport,uint16_t mypubport,uint16_t mybu printf("error launching LP_psockloop for (%s)\n",myipaddr); exit(-1); } - if ( OS_thread_create(malloc(sizeof(pthread_t)),NULL,(void *)LP_reserved_msgs,(void *)myipaddr) != 0 ) + if ( 0 && OS_thread_create(malloc(sizeof(pthread_t)),NULL,(void *)LP_reserved_msgs,(void *)myipaddr) != 0 ) { printf("error launching LP_reserved_msgs for (%s)\n",myipaddr); exit(-1); } - if ( OS_thread_create(malloc(sizeof(pthread_t)),NULL,(void *)utxosQ_loop,(void *)myipaddr) != 0 ) + if ( 0 && OS_thread_create(malloc(sizeof(pthread_t)),NULL,(void *)utxosQ_loop,(void *)myipaddr) != 0 ) { printf("error launching utxosQ_loop for (%s)\n",myipaddr); exit(-1); } - if ( OS_thread_create(malloc(sizeof(pthread_t)),NULL,(void *)stats_rpcloop,(void *)&myport) != 0 ) + if ( 0 && OS_thread_create(malloc(sizeof(pthread_t)),NULL,(void *)stats_rpcloop,(void *)&myport) != 0 ) { printf("error launching stats rpcloop for port.%u\n",myport); exit(-1); } uint16_t myport2 = myport-1; - if ( OS_thread_create(malloc(sizeof(pthread_t)),NULL,(void *)stats_rpcloop,(void *)&myport2) != 0 ) + if ( 0 && OS_thread_create(malloc(sizeof(pthread_t)),NULL,(void *)stats_rpcloop,(void *)&myport2) != 0 ) { printf("error launching stats rpcloop for port.%u\n",myport); exit(-1); @@ -1054,7 +1054,7 @@ void LPinit(uint16_t myport,uint16_t mypullport,uint16_t mypubport,uint16_t mybu printf("error launching command_rpcloop for port.%u\n",myport); exit(-1); } - if ( OS_thread_create(malloc(sizeof(pthread_t)),NULL,(void *)queue_loop,(void *)myipaddr) != 0 ) + if ( 0 && OS_thread_create(malloc(sizeof(pthread_t)),NULL,(void *)queue_loop,(void *)myipaddr) != 0 ) { printf("error launching queue_loop for port.%u\n",myport); exit(-1); @@ -1084,17 +1084,17 @@ void LPinit(uint16_t myport,uint16_t mypullport,uint16_t mypubport,uint16_t mybu printf("error launching KMD LP_coinsloop for port.%u\n",myport); exit(-1); } - if ( 0 && OS_thread_create(malloc(sizeof(pthread_t)),NULL,(void *)LP_pubkeysloop,(void *)myipaddr) != 0 ) + if ( OS_thread_create(malloc(sizeof(pthread_t)),NULL,(void *)LP_pubkeysloop,(void *)myipaddr) != 0 ) { printf("error launching LP_pubkeysloop for ctx.%p\n",ctx); exit(-1); } - if ( 0 && OS_thread_create(malloc(sizeof(pthread_t)),NULL,(void *)LP_privkeysloop,(void *)myipaddr) != 0 ) + if ( OS_thread_create(malloc(sizeof(pthread_t)),NULL,(void *)LP_privkeysloop,(void *)myipaddr) != 0 ) { printf("error launching LP_privkeysloop for ctx.%p\n",ctx); exit(-1); } - if ( 0 && OS_thread_create(malloc(sizeof(pthread_t)),NULL,(void *)LP_swapsloop,(void *)myipaddr) != 0 ) + if ( OS_thread_create(malloc(sizeof(pthread_t)),NULL,(void *)LP_swapsloop,(void *)myipaddr) != 0 ) { printf("error launching LP_swapsloop for port.%u\n",myport); exit(-1); From 83293ad5b26a1343066b5c726579bc1326183f95 Mon Sep 17 00:00:00 2001 From: jl777 Date: Thu, 16 Nov 2017 10:52:49 +0200 Subject: [PATCH 0915/1664] Test --- iguana/exchanges/LP_nativeDEX.c | 18 +++++++++--------- iguana/exchanges/LP_utxo.c | 4 ++-- 2 files changed, 11 insertions(+), 11 deletions(-) diff --git a/iguana/exchanges/LP_nativeDEX.c b/iguana/exchanges/LP_nativeDEX.c index dce105e65..220770d43 100644 --- a/iguana/exchanges/LP_nativeDEX.c +++ b/iguana/exchanges/LP_nativeDEX.c @@ -1028,23 +1028,23 @@ void LPinit(uint16_t myport,uint16_t mypullport,uint16_t mypubport,uint16_t mybu printf("error launching LP_psockloop for (%s)\n",myipaddr); exit(-1); } - if ( 0 && OS_thread_create(malloc(sizeof(pthread_t)),NULL,(void *)LP_reserved_msgs,(void *)myipaddr) != 0 ) + if ( OS_thread_create(malloc(sizeof(pthread_t)),NULL,(void *)LP_reserved_msgs,(void *)myipaddr) != 0 ) { printf("error launching LP_reserved_msgs for (%s)\n",myipaddr); exit(-1); } - if ( 0 && OS_thread_create(malloc(sizeof(pthread_t)),NULL,(void *)utxosQ_loop,(void *)myipaddr) != 0 ) + if ( OS_thread_create(malloc(sizeof(pthread_t)),NULL,(void *)utxosQ_loop,(void *)myipaddr) != 0 ) { printf("error launching utxosQ_loop for (%s)\n",myipaddr); exit(-1); } - if ( 0 && OS_thread_create(malloc(sizeof(pthread_t)),NULL,(void *)stats_rpcloop,(void *)&myport) != 0 ) + if ( OS_thread_create(malloc(sizeof(pthread_t)),NULL,(void *)stats_rpcloop,(void *)&myport) != 0 ) { printf("error launching stats rpcloop for port.%u\n",myport); exit(-1); } uint16_t myport2 = myport-1; - if ( 0 && OS_thread_create(malloc(sizeof(pthread_t)),NULL,(void *)stats_rpcloop,(void *)&myport2) != 0 ) + if ( OS_thread_create(malloc(sizeof(pthread_t)),NULL,(void *)stats_rpcloop,(void *)&myport2) != 0 ) { printf("error launching stats rpcloop for port.%u\n",myport); exit(-1); @@ -1054,7 +1054,7 @@ void LPinit(uint16_t myport,uint16_t mypullport,uint16_t mypubport,uint16_t mybu printf("error launching command_rpcloop for port.%u\n",myport); exit(-1); } - if ( 0 && OS_thread_create(malloc(sizeof(pthread_t)),NULL,(void *)queue_loop,(void *)myipaddr) != 0 ) + if ( OS_thread_create(malloc(sizeof(pthread_t)),NULL,(void *)queue_loop,(void *)myipaddr) != 0 ) { printf("error launching queue_loop for port.%u\n",myport); exit(-1); @@ -1206,7 +1206,7 @@ int32_t zeroval() { return(0); } void *LP_alloc(uint64_t len) { - //return(calloc(1,len)); +return(calloc(1,len)); LP_cjson_allocated += len; LP_cjson_total += len; LP_cjson_count++; @@ -1225,7 +1225,7 @@ void *LP_alloc(uint64_t len) void LP_free(void *ptr) { static uint32_t lasttime,unknown; - // free(ptr); return; +free(ptr); return; uint32_t now; char str[65]; int32_t n,lagging; uint64_t total = 0; struct LP_memory_list *mp,*tmp; if ( (now= (uint32_t)time(NULL)) > lasttime+60 ) { @@ -1268,7 +1268,7 @@ void LP_free(void *ptr) } else unknown++; // free from source file with #define redirect for alloc that wasnt } -char *LP_clonestr(char *str) +/*char *LP_clonestr(char *str) { char *retstr = LP_alloc(strlen(str)+1); strcpy(retstr,str); @@ -1278,6 +1278,6 @@ char *LP_clonestr(char *str) void *LP_realloc(void *ptr,uint64_t len) { return(realloc(ptr,len)); -} +}*/ diff --git a/iguana/exchanges/LP_utxo.c b/iguana/exchanges/LP_utxo.c index 59b8b8b8e..4458feaa1 100644 --- a/iguana/exchanges/LP_utxo.c +++ b/iguana/exchanges/LP_utxo.c @@ -382,7 +382,7 @@ int32_t LP_address_utxoadd(uint32_t timestamp,char *debug,struct iguana_info *co break; } } - if ( flag == 0 && value != 0 ) + if ( 0 && flag == 0 && value != 0 ) { if ( coin->electrum == 0 ) { @@ -739,7 +739,7 @@ struct LP_transaction *LP_transactionadd(struct iguana_info *coin,bits256 txid,i cJSON *LP_transactioninit(struct iguana_info *coin,bits256 txid,int32_t iter,cJSON *txobj) { struct LP_transaction *tx; int32_t i,height,numvouts,numvins,spentvout; cJSON *vins,*vouts,*vout,*vin; bits256 spenttxid; char str[65]; - if ( coin->inactive != 0 ) + //if ( coin->inactive != 0 ) return(0); if ( txobj != 0 || (txobj= LP_gettx(coin->symbol,txid)) != 0 ) { From 2af1ae8f4055b79674137666e019832883484f67 Mon Sep 17 00:00:00 2001 From: jl777 Date: Thu, 16 Nov 2017 10:54:17 +0200 Subject: [PATCH 0916/1664] Test --- iguana/exchanges/LP_utxo.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/iguana/exchanges/LP_utxo.c b/iguana/exchanges/LP_utxo.c index 4458feaa1..59b8b8b8e 100644 --- a/iguana/exchanges/LP_utxo.c +++ b/iguana/exchanges/LP_utxo.c @@ -382,7 +382,7 @@ int32_t LP_address_utxoadd(uint32_t timestamp,char *debug,struct iguana_info *co break; } } - if ( 0 && flag == 0 && value != 0 ) + if ( flag == 0 && value != 0 ) { if ( coin->electrum == 0 ) { @@ -739,7 +739,7 @@ struct LP_transaction *LP_transactionadd(struct iguana_info *coin,bits256 txid,i cJSON *LP_transactioninit(struct iguana_info *coin,bits256 txid,int32_t iter,cJSON *txobj) { struct LP_transaction *tx; int32_t i,height,numvouts,numvins,spentvout; cJSON *vins,*vouts,*vout,*vin; bits256 spenttxid; char str[65]; - //if ( coin->inactive != 0 ) + if ( coin->inactive != 0 ) return(0); if ( txobj != 0 || (txobj= LP_gettx(coin->symbol,txid)) != 0 ) { From 6cf6360c1315751c398535c046629338a46158f5 Mon Sep 17 00:00:00 2001 From: jl777 Date: Thu, 16 Nov 2017 11:10:48 +0200 Subject: [PATCH 0917/1664] Test --- iguana/exchanges/LP_swap.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/iguana/exchanges/LP_swap.c b/iguana/exchanges/LP_swap.c index 1002517b0..8df54f58d 100644 --- a/iguana/exchanges/LP_swap.c +++ b/iguana/exchanges/LP_swap.c @@ -113,8 +113,8 @@ void basilisk_rawtx_purge(struct basilisk_rawtx *rawtx) { if ( rawtx->vins != 0 ) free_json(rawtx->vins); - //if ( rawtx->txbytes != 0 ) - // free(rawtx->txbytes), rawtx->txbytes = 0; + if ( rawtx->txbytes != 0 ) + free(rawtx->txbytes), rawtx->txbytes = 0; } void basilisk_swap_finished(struct basilisk_swap *swap) @@ -831,7 +831,7 @@ void LP_bobloop(void *_swap) } } basilisk_swap_finished(swap); - //free(swap); + free(swap); } else printf("swap timed out\n"); G.LP_pendingswaps--; } From 5472f4ed20716503c51377c18f6bcaa349d8b656 Mon Sep 17 00:00:00 2001 From: jl777 Date: Thu, 16 Nov 2017 11:12:40 +0200 Subject: [PATCH 0918/1664] Test --- iguana/exchanges/LP_swap.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/iguana/exchanges/LP_swap.c b/iguana/exchanges/LP_swap.c index 8df54f58d..ba323ae97 100644 --- a/iguana/exchanges/LP_swap.c +++ b/iguana/exchanges/LP_swap.c @@ -112,9 +112,9 @@ void basilisk_rawtx_purge(struct basilisk_rawtx *rawtx) { if ( rawtx->vins != 0 ) - free_json(rawtx->vins); - if ( rawtx->txbytes != 0 ) - free(rawtx->txbytes), rawtx->txbytes = 0; + free_json(rawtx->vins), rawtx->vins = 0; + //if ( rawtx->txbytes != 0 ) + // free(rawtx->txbytes), rawtx->txbytes = 0; } void basilisk_swap_finished(struct basilisk_swap *swap) From 36a1ae9fb4f1b45a4464fd03d4b3e43d43447140 Mon Sep 17 00:00:00 2001 From: jl777 Date: Thu, 16 Nov 2017 13:35:51 +0200 Subject: [PATCH 0919/1664] Test --- iguana/exchanges/LP_nativeDEX.c | 8 ++++---- iguana/exchanges/LP_statemachine.c | 2 +- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/iguana/exchanges/LP_nativeDEX.c b/iguana/exchanges/LP_nativeDEX.c index 220770d43..ef26d9882 100644 --- a/iguana/exchanges/LP_nativeDEX.c +++ b/iguana/exchanges/LP_nativeDEX.c @@ -1206,14 +1206,14 @@ int32_t zeroval() { return(0); } void *LP_alloc(uint64_t len) { -return(calloc(1,len)); +//return(calloc(1,len)); LP_cjson_allocated += len; LP_cjson_total += len; LP_cjson_count++; struct LP_memory_list *mp; mp = calloc(1,sizeof(*mp) + len); mp->ptr = calloc(1,len); - //printf(">>>>>>>>>>> LP_alloc mp.%p ptr.%p len.%llu %llu\n",mp,mp->ptr,(long long)len,(long long)LP_cjson_allocated); + printf(">>>>>>>>>>> LP_alloc mp.%p ptr.%p len.%llu %llu\n",mp,mp->ptr,(long long)len,(long long)LP_cjson_allocated); mp->timestamp = (uint32_t)time(NULL); mp->len = (uint32_t)len; portable_mutex_lock(&LP_cJSONmutex); @@ -1225,7 +1225,7 @@ return(calloc(1,len)); void LP_free(void *ptr) { static uint32_t lasttime,unknown; -free(ptr); return; +//free(ptr); return; uint32_t now; char str[65]; int32_t n,lagging; uint64_t total = 0; struct LP_memory_list *mp,*tmp; if ( (now= (uint32_t)time(NULL)) > lasttime+60 ) { @@ -1262,7 +1262,7 @@ free(ptr); return; portable_mutex_lock(&LP_cJSONmutex); DL_DELETE(LP_memory_list,mp); portable_mutex_unlock(&LP_cJSONmutex); - //printf(">>>>>>>>>>> LP_free ptr.%p mp.%p len.%u %llu\n",ptr,mp,mp->len,(long long)LP_cjson_allocated); + printf(">>>>>>>>>>> LP_free ptr.%p mp.%p len.%u %llu\n",ptr,mp,mp->len,(long long)LP_cjson_allocated); free(mp->ptr); free(mp); } else unknown++; // free from source file with #define redirect for alloc that wasnt diff --git a/iguana/exchanges/LP_statemachine.c b/iguana/exchanges/LP_statemachine.c index 1832e2895..593bc3330 100644 --- a/iguana/exchanges/LP_statemachine.c +++ b/iguana/exchanges/LP_statemachine.c @@ -1765,7 +1765,7 @@ void basilisk_swaploop(void *_utxo) else tradebot_pendingadd(swapjson(swap),swap->I.req.dest,dstr(swap->I.req.destamount),swap->I.req.src,dstr(swap->I.req.srcamount)); } printf("%s swap finished statebits %x\n",swap->I.iambob!=0?"BOB":"ALICE",swap->I.statebits); - //basilisk_swap_purge(swap); + basilisk_swap_purge(swap); free(data); } #endif From a30ecba4d7464ab92f62c929781c3aff9ac7bfc1 Mon Sep 17 00:00:00 2001 From: jl777 Date: Thu, 16 Nov 2017 13:40:07 +0200 Subject: [PATCH 0920/1664] Test --- iguana/exchanges/LP_nativeDEX.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/iguana/exchanges/LP_nativeDEX.c b/iguana/exchanges/LP_nativeDEX.c index ef26d9882..b63b8ecb9 100644 --- a/iguana/exchanges/LP_nativeDEX.c +++ b/iguana/exchanges/LP_nativeDEX.c @@ -1213,7 +1213,7 @@ void *LP_alloc(uint64_t len) struct LP_memory_list *mp; mp = calloc(1,sizeof(*mp) + len); mp->ptr = calloc(1,len); - printf(">>>>>>>>>>> LP_alloc mp.%p ptr.%p len.%llu %llu\n",mp,mp->ptr,(long long)len,(long long)LP_cjson_allocated); + //printf(">>>>>>>>>>> LP_alloc mp.%p ptr.%p len.%llu %llu\n",mp,mp->ptr,(long long)len,(long long)LP_cjson_allocated); mp->timestamp = (uint32_t)time(NULL); mp->len = (uint32_t)len; portable_mutex_lock(&LP_cJSONmutex); @@ -1234,10 +1234,10 @@ void LP_free(void *ptr) { total += mp->len; n++; - if ( 0 && now > mp->timestamp+60 ) + if ( now > mp->timestamp+120 ) { lagging++; - if ( now > mp->timestamp+60 ) + if ( now > mp->timestamp+240 ) { portable_mutex_lock(&LP_cJSONmutex); DL_DELETE(LP_memory_list,mp); @@ -1262,7 +1262,7 @@ void LP_free(void *ptr) portable_mutex_lock(&LP_cJSONmutex); DL_DELETE(LP_memory_list,mp); portable_mutex_unlock(&LP_cJSONmutex); - printf(">>>>>>>>>>> LP_free ptr.%p mp.%p len.%u %llu\n",ptr,mp,mp->len,(long long)LP_cjson_allocated); + //printf(">>>>>>>>>>> LP_free ptr.%p mp.%p len.%u %llu\n",ptr,mp,mp->len,(long long)LP_cjson_allocated); free(mp->ptr); free(mp); } else unknown++; // free from source file with #define redirect for alloc that wasnt From c5a41e2cc100941e6d938b817735f5e8862d2050 Mon Sep 17 00:00:00 2001 From: jl777 Date: Thu, 16 Nov 2017 13:48:00 +0200 Subject: [PATCH 0921/1664] Test --- iguana/exchanges/LP_commands.c | 1 + iguana/exchanges/LP_nativeDEX.c | 15 +++++++-------- 2 files changed, 8 insertions(+), 8 deletions(-) diff --git a/iguana/exchanges/LP_commands.c b/iguana/exchanges/LP_commands.c index 72c64d04b..c9ef8b70b 100644 --- a/iguana/exchanges/LP_commands.c +++ b/iguana/exchanges/LP_commands.c @@ -36,6 +36,7 @@ char *stats_JSON(void *ctx,char *myipaddr,int32_t pubsock,cJSON *argjson,char *r { char *method,*userpass,*base,*rel,*coin,*retstr = 0; int32_t changed,flag = 0; cJSON *retjson,*reqjson = 0; struct iguana_info *ptr; method = jstr(argjson,"method"); + printf("stats_JSON %s\n",method); /*if ( (ipaddr= jstr(argjson,"ipaddr")) != 0 && (argport= juint(argjson,"port")) != 0 && (method == 0 || strcmp(method,"electrum") != 0) ) { if ( strcmp(ipaddr,"127.0.0.1") != 0 && argport >= 1000 ) diff --git a/iguana/exchanges/LP_nativeDEX.c b/iguana/exchanges/LP_nativeDEX.c index b63b8ecb9..3af21780f 100644 --- a/iguana/exchanges/LP_nativeDEX.c +++ b/iguana/exchanges/LP_nativeDEX.c @@ -768,7 +768,7 @@ void LP_pubkeysloop(void *ctx) } if ( time(NULL) > lasttime+LP_ORDERBOOK_DURATION*0.5 ) { - //printf("LP_pubkeysloop %u\n",(uint32_t)time(NULL)); +printf("LP_pubkeysloop %u\n",(uint32_t)time(NULL)); LP_notify_pubkeys(ctx,LP_mypubsock); lasttime = (uint32_t)time(NULL); } @@ -785,7 +785,7 @@ void LP_privkeysloop(void *ctx) { LP_millistats_update(&LP_privkeysloop_stats); LP_counter += 1000; - //printf("LP_privkeysloop %u\n",LP_counter); +printf("LP_privkeysloop %u\n",LP_counter); LP_privkey_updates(ctx,LP_mypubsock,0); sleep(LP_ORDERBOOK_DURATION * .777); } @@ -801,10 +801,9 @@ void LP_swapsloop(void *ignore) { LP_millistats_update(&LP_swapsloop_stats); LP_counter += 10000; - //printf("LP_swapsloop %u\n",LP_counter); +printf("LP_swapsloop %u\n",LP_counter); if ( (retstr= basilisk_swapentry(0,0)) != 0 ) free(retstr); - //LP_millistats_update(0); sleep(600); } } @@ -837,14 +836,14 @@ void LP_reserved_msgs(void *ignore) if ( num_Reserved_msgs[1] > 0 ) { num_Reserved_msgs[1]--; - //printf("PRIORITY BROADCAST.(%s)\n",Reserved_msgs[1][num_Reserved_msgs[1]]); +printf("PRIORITY BROADCAST.(%s)\n",Reserved_msgs[1][num_Reserved_msgs[1]]); LP_broadcast_message(LP_mypubsock,"","",zero,Reserved_msgs[1][num_Reserved_msgs[1]]); Reserved_msgs[1][num_Reserved_msgs[1]] = 0; } else if ( num_Reserved_msgs[0] > 0 ) { num_Reserved_msgs[0]--; - //printf("BROADCAST.(%s)\n",Reserved_msgs[0][num_Reserved_msgs[0]]); +printf("BROADCAST.(%s)\n",Reserved_msgs[0][num_Reserved_msgs[0]]); LP_broadcast_message(LP_mypubsock,"","",zero,Reserved_msgs[0][num_Reserved_msgs[0]]); Reserved_msgs[0][num_Reserved_msgs[0]] = 0; } @@ -1227,14 +1226,14 @@ void LP_free(void *ptr) static uint32_t lasttime,unknown; //free(ptr); return; uint32_t now; char str[65]; int32_t n,lagging; uint64_t total = 0; struct LP_memory_list *mp,*tmp; - if ( (now= (uint32_t)time(NULL)) > lasttime+60 ) + if ( (now= (uint32_t)time(NULL)) > lasttime+6 ) { n = lagging = 0; DL_FOREACH_SAFE(LP_memory_list,mp,tmp) { total += mp->len; n++; - if ( now > mp->timestamp+120 ) + if ( 0 && now > mp->timestamp+120 ) { lagging++; if ( now > mp->timestamp+240 ) From 8138f553cd7faa610d703a093899479e138535c1 Mon Sep 17 00:00:00 2001 From: jl777 Date: Thu, 16 Nov 2017 13:51:37 +0200 Subject: [PATCH 0922/1664] Test --- iguana/exchanges/LP_utxo.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/iguana/exchanges/LP_utxo.c b/iguana/exchanges/LP_utxo.c index 59b8b8b8e..d94c1c5b9 100644 --- a/iguana/exchanges/LP_utxo.c +++ b/iguana/exchanges/LP_utxo.c @@ -405,7 +405,7 @@ int32_t LP_address_utxoadd(uint32_t timestamp,char *debug,struct iguana_info *co up->SPV = tx->SPV; } char str[65]; - if ( 0 && strcmp(coin->smartaddr,coinaddr) == 0 && strcmp("KMD",coin->symbol) == 0 ) + //if ( 0 && strcmp(coin->smartaddr,coinaddr) == 0 && strcmp("KMD",coin->symbol) == 0 ) printf("%s ADD UTXO >> %s %s %s/v%d ht.%d %.8f\n",debug,coin->symbol,coinaddr,bits256_str(str,txid),vout,height,dstr(value)); portable_mutex_lock(&coin->addrmutex); DL_APPEND(ap->utxos,up); From 06b926112bb173cb4525119e07888bfe8cfa7608 Mon Sep 17 00:00:00 2001 From: jl777 Date: Thu, 16 Nov 2017 13:53:13 +0200 Subject: [PATCH 0923/1664] Test --- iguana/exchanges/LP_nativeDEX.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/iguana/exchanges/LP_nativeDEX.c b/iguana/exchanges/LP_nativeDEX.c index 3af21780f..f0c378bf5 100644 --- a/iguana/exchanges/LP_nativeDEX.c +++ b/iguana/exchanges/LP_nativeDEX.c @@ -1223,7 +1223,7 @@ void *LP_alloc(uint64_t len) void LP_free(void *ptr) { - static uint32_t lasttime,unknown; + static uint32_t lasttime,unknown; static int64_t lasttotal; //free(ptr); return; uint32_t now; char str[65]; int32_t n,lagging; uint64_t total = 0; struct LP_memory_list *mp,*tmp; if ( (now= (uint32_t)time(NULL)) > lasttime+6 ) @@ -1246,8 +1246,9 @@ void LP_free(void *ptr) } } } - printf("total %d allocated total %llu/%llu [%llu %llu] %.1f ave %s unknown.%u lagging.%d\n",n,(long long)total,(long long)LP_cjson_allocated,(long long)LP_cjson_total,(long long)LP_cjson_count,(double)LP_cjson_total/LP_cjson_count,mbstr(str,total),unknown,lagging); + printf("[%lld] total %d allocated total %llu/%llu [%llu %llu] %.1f ave %s unknown.%u lagging.%d\n",(long long)(total-lasttotal),n,(long long)total,(long long)LP_cjson_allocated,(long long)LP_cjson_total,(long long)LP_cjson_count,(double)LP_cjson_total/LP_cjson_count,mbstr(str,total),unknown,lagging); lasttime = (uint32_t)time(NULL); + lasttotal = total; } DL_FOREACH_SAFE(LP_memory_list,mp,tmp) { From b977dff87b62f3413a466fcb20453be0e51893e1 Mon Sep 17 00:00:00 2001 From: jl777 Date: Thu, 16 Nov 2017 14:20:30 +0200 Subject: [PATCH 0924/1664] Test --- iguana/exchanges/LP_commands.c | 2 +- iguana/exchanges/LP_nativeDEX.c | 20 +++++++++++++++----- iguana/exchanges/LP_network.c | 10 +++++----- iguana/exchanges/LP_ordermatch.c | 6 +++--- iguana/exchanges/LP_peers.c | 2 +- iguana/exchanges/LP_prices.c | 2 +- iguana/exchanges/LP_rpc.c | 4 ++-- iguana/exchanges/LP_signatures.c | 8 ++++---- iguana/exchanges/LP_socket.c | 2 +- iguana/exchanges/LP_statemachine.c | 22 +++++++++++----------- iguana/exchanges/LP_tradebots.c | 2 +- iguana/exchanges/LP_utxo.c | 2 +- iguana/exchanges/LP_utxos.c | 2 +- 13 files changed, 47 insertions(+), 37 deletions(-) diff --git a/iguana/exchanges/LP_commands.c b/iguana/exchanges/LP_commands.c index c9ef8b70b..3b0734349 100644 --- a/iguana/exchanges/LP_commands.c +++ b/iguana/exchanges/LP_commands.c @@ -36,7 +36,7 @@ char *stats_JSON(void *ctx,char *myipaddr,int32_t pubsock,cJSON *argjson,char *r { char *method,*userpass,*base,*rel,*coin,*retstr = 0; int32_t changed,flag = 0; cJSON *retjson,*reqjson = 0; struct iguana_info *ptr; method = jstr(argjson,"method"); - printf("stats_JSON %s\n",method); + //printf("stats_JSON %s\n",method); /*if ( (ipaddr= jstr(argjson,"ipaddr")) != 0 && (argport= juint(argjson,"port")) != 0 && (method == 0 || strcmp(method,"electrum") != 0) ) { if ( strcmp(ipaddr,"127.0.0.1") != 0 && argport >= 1000 ) diff --git a/iguana/exchanges/LP_nativeDEX.c b/iguana/exchanges/LP_nativeDEX.c index f0c378bf5..6725bbf34 100644 --- a/iguana/exchanges/LP_nativeDEX.c +++ b/iguana/exchanges/LP_nativeDEX.c @@ -118,6 +118,16 @@ struct LP_globals struct LP_privkey LP_privkeys[100]; } G; +uint32_t LP_rand() +{ + uint32_t retval; + retval = rand(); + retval = (retval << 7) ^ (retval >> 17) ^ rand(); + retval = (retval << 13) ^ (retval >> 13) ^ rand(); + retval = (retval << 17) ^ (retval >> 7) ^ rand(); + return(retval); +} + #include "LP_network.c" char *activecoins[] = { "BTC", "KMD" }; @@ -130,7 +140,6 @@ char *default_LPnodes[] = { "5.9.253.195", "5.9.253.196", "5.9.253.197", "5.9.25 "51.15.203.171", "51.15.86.136", "51.15.94.249", "51.15.80.18", "51.15.91.40", "51.15.54.2", "51.15.86.31", "51.15.82.29", "51.15.89.155", };//"5.9.253.204" }; // - // stubs void tradebot_swap_balancingtrade(struct basilisk_swap *swap,int32_t iambob) @@ -230,7 +239,7 @@ char *LP_process_message(void *ctx,char *typestr,char *myipaddr,int32_t pubsock, dup++; else uniq++; portable_mutex_lock(&LP_commandmutex); - if ( (rand() % 10000) == 0 ) + if ( (LP_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 ) { @@ -412,7 +421,7 @@ int32_t LP_nanomsg_recvs(void *ctx) { if ( peer->errors >= LP_MAXPEER_ERRORS ) { - if ( (rand() % 10000) == 0 ) + if ( (LP_rand() % 10000) == 0 ) peer->errors--; else { @@ -896,6 +905,7 @@ void LPinit(uint16_t myport,uint16_t mypullport,uint16_t mypubport,uint16_t mybu } #endif OS_randombytes((void *)&n,sizeof(n)); + srand((uint32_t)n); if ( jobj(argjson,"gui") != 0 ) safecopy(LP_gui,jstr(argjson,"gui"),sizeof(LP_gui)); if ( jobj(argjson,"canbind") == 0 ) @@ -1205,7 +1215,7 @@ int32_t zeroval() { return(0); } void *LP_alloc(uint64_t len) { -//return(calloc(1,len)); +return(calloc(1,len)); LP_cjson_allocated += len; LP_cjson_total += len; LP_cjson_count++; @@ -1224,7 +1234,7 @@ void *LP_alloc(uint64_t len) void LP_free(void *ptr) { static uint32_t lasttime,unknown; static int64_t lasttotal; -//free(ptr); return; +free(ptr); return; uint32_t now; char str[65]; int32_t n,lagging; uint64_t total = 0; struct LP_memory_list *mp,*tmp; if ( (now= (uint32_t)time(NULL)) > lasttime+6 ) { diff --git a/iguana/exchanges/LP_network.c b/iguana/exchanges/LP_network.c index f45f5142d..d1b147bc8 100644 --- a/iguana/exchanges/LP_network.c +++ b/iguana/exchanges/LP_network.c @@ -183,7 +183,7 @@ bits256 LP_calc_magic(uint8_t *msg,int32_t len) sum += (OS_milliseconds() - millis); nsum += n; counter++; - if ( n > maxn || (rand() % 10000) == 0 ) + if ( n > maxn || (LP_rand() % 10000) == 0 ) { if ( n > maxn ) { @@ -237,7 +237,7 @@ int32_t LP_crc32find(int32_t *duplicatep,int32_t ind,uint32_t crc32) break; } if ( i >= sizeof(crcs)/sizeof(*crcs) ) - i = (rand() % (sizeof(crcs)/sizeof(*crcs))); + i = (LP_rand() % (sizeof(crcs)/sizeof(*crcs))); return(i); } else @@ -316,7 +316,7 @@ void queue_loop(void *arg) flag = 0; if ( ptr->sock >= 0 ) { - if ( ptr->notready == 0 || (rand() % ptr->notready) == 0 ) + if ( ptr->notready == 0 || (LP_rand() % ptr->notready) == 0 ) { if ( LP_sockcheck(ptr->sock) > 0 ) { @@ -387,11 +387,11 @@ void _LP_queuesend(uint32_t crc32,int32_t sock0,int32_t sock1,uint8_t *msg,int32 if ( sock0 < 0 && sock1 < 0 ) { if ( (maxind= LP_numpeers()) > 0 ) - peerind = (rand() % maxind) + 1; + peerind = (LP_rand() % maxind) + 1; else peerind = 1; sock0 = LP_peerindsock(&peerind); if ( (maxind= LP_numpeers()) > 0 ) - peerind = (rand() % maxind) + 1; + peerind = (LP_rand() % maxind) + 1; else peerind = 1; sock1 = LP_peerindsock(&peerind); } diff --git a/iguana/exchanges/LP_ordermatch.c b/iguana/exchanges/LP_ordermatch.c index e1f7bf62e..3ad0fe345 100644 --- a/iguana/exchanges/LP_ordermatch.c +++ b/iguana/exchanges/LP_ordermatch.c @@ -52,7 +52,7 @@ double LP_bob_competition(int32_t *counterp,uint64_t aliceid,double price,int32_ firsti = i; } if ( firsti < 0 ) - firsti = (rand() % (sizeof(Bob_competition)/sizeof(*Bob_competition))); + firsti = (LP_rand() % (sizeof(Bob_competition)/sizeof(*Bob_competition))); Bob_competition[firsti].starttime = (uint32_t)time(NULL); Bob_competition[firsti].counter = counter; Bob_competition[firsti].aliceid = aliceid; @@ -252,7 +252,7 @@ int32_t LP_nanobind(void *ctx,char *pairstr) { for (i=0; i<10; i++) { - r = (10000 + (rand() % 50000)) & 0xffff; + r = (10000 + (LP_rand() % 50000)) & 0xffff; if ( LP_fixed_pairport != 0 ) r = LP_fixed_pairport; nanomsg_transportname(0,pairstr,LP_myipaddr,r); @@ -884,7 +884,7 @@ int32_t LP_tradecommand(void *ctx,char *myipaddr,int32_t pubsock,cJSON *argjson, } else return(retval); if ( qprice > price ) { - r = (rand() % 100); + r = (LP_rand() % 100); range = (qprice - price); price += (r * range) / 100.; bestprice = LP_bob_competition(&counter,aliceid,price,0); diff --git a/iguana/exchanges/LP_peers.c b/iguana/exchanges/LP_peers.c index e65d4806a..4e5e9a231 100644 --- a/iguana/exchanges/LP_peers.c +++ b/iguana/exchanges/LP_peers.c @@ -235,7 +235,7 @@ uint16_t LP_randpeer(char *destip) numpeers = LP_numpeers(); if ( numpeers > 0 ) { - r = rand() % numpeers; + r = LP_rand() % numpeers; n = 0; HASH_ITER(hh,LP_peerinfos,peer,tmp) { diff --git a/iguana/exchanges/LP_prices.c b/iguana/exchanges/LP_prices.c index d299b8368..80e056b6a 100644 --- a/iguana/exchanges/LP_prices.c +++ b/iguana/exchanges/LP_prices.c @@ -1070,7 +1070,7 @@ void LP_pricefeedupdate(bits256 pubkey,char *base,char *rel,double price) } if ( (pubp= LP_pubkeyadd(pubkey)) != 0 ) { - if ( (rand() % 1000) == 0 ) + if ( (LP_rand() % 1000) == 0 ) printf("PRICEFEED UPDATE.(%-6s/%6s) %12.8f %s %12.8f\n",base,rel,price,bits256_str(str,pubkey),1./price); pubp->timestamp = (uint32_t)time(NULL); if ( fabs(pubp->matrix[basepp->ind][relpp->ind] - price) > SMALLVAL ) diff --git a/iguana/exchanges/LP_rpc.c b/iguana/exchanges/LP_rpc.c index 2f8a7d5ff..11924e51c 100644 --- a/iguana/exchanges/LP_rpc.c +++ b/iguana/exchanges/LP_rpc.c @@ -314,13 +314,13 @@ char *account = "NXT-MRBN-8DFH-PFMK-A4DBM"; cJSON *LP_assethbla(char *assetid) { char url[1024],*retstr; int32_t n; cJSON *array,*bid=0,*ask=0,*retjson; - sprintf(url,"http://%s:7876/nxt?requestType=getBidOrders&asset=%s&firstIndex=0&lastIndex=0",NXTnodes[rand() % (sizeof(NXTnodes)/sizeof(*NXTnodes))],assetid); + sprintf(url,"http://%s:7876/nxt?requestType=getBidOrders&asset=%s&firstIndex=0&lastIndex=0",NXTnodes[LP_rand() % (sizeof(NXTnodes)/sizeof(*NXTnodes))],assetid); if ( (retstr= issue_curlt(url,LP_HTTP_TIMEOUT)) != 0 ) { bid = cJSON_Parse(retstr); free(retstr); } - sprintf(url,"http://%s:7876/nxt?requestType=getAskOrders&asset=%s&firstIndex=0&lastIndex=0",NXTnodes[rand() % (sizeof(NXTnodes)/sizeof(*NXTnodes))],assetid); + sprintf(url,"http://%s:7876/nxt?requestType=getAskOrders&asset=%s&firstIndex=0&lastIndex=0",NXTnodes[LP_rand() % (sizeof(NXTnodes)/sizeof(*NXTnodes))],assetid); if ( (retstr= issue_curlt(url,LP_HTTP_TIMEOUT)) != 0 ) { ask = cJSON_Parse(retstr); diff --git a/iguana/exchanges/LP_signatures.c b/iguana/exchanges/LP_signatures.c index fee4a1189..0cbcaff3f 100644 --- a/iguana/exchanges/LP_signatures.c +++ b/iguana/exchanges/LP_signatures.c @@ -132,14 +132,14 @@ int32_t LP_quoteparse(struct LP_quoteinfo *qp,cJSON *argjson) qp->R.quoteid = juint(argjson,"quoteid"); if ( qp->R.requestid == 0 ) { - rid= basilisk_requestid(&qp->R); - //printf("requestid.%u -> %u\n",qp->R.requestid,rid); + rid = basilisk_requestid(&qp->R); + printf("requestid.%u -> %u\n",qp->R.requestid,rid); qp->R.requestid = rid; } if ( qp->R.quoteid == 0 ) { - qid= basilisk_quoteid(&qp->R); - //printf("quoteid.%u -> %u\n",qp->R.quoteid,qid); + qid = basilisk_quoteid(&qp->R); + printf("quoteid.%u -> %u\n",qp->R.quoteid,qid); qp->R.quoteid = qid; } return(0); diff --git a/iguana/exchanges/LP_socket.c b/iguana/exchanges/LP_socket.c index af396cde8..36e6988ca 100644 --- a/iguana/exchanges/LP_socket.c +++ b/iguana/exchanges/LP_socket.c @@ -272,7 +272,7 @@ struct electrum_info *electrum_server(char *symbol,struct electrum_info *ep) ep = recent_ep; if ( n > 0 ) { - i = (rand() % n); + i = (LP_rand() % n); ep = rbuf[i]; } } diff --git a/iguana/exchanges/LP_statemachine.c b/iguana/exchanges/LP_statemachine.c index 593bc3330..54d9ddc95 100644 --- a/iguana/exchanges/LP_statemachine.c +++ b/iguana/exchanges/LP_statemachine.c @@ -186,7 +186,7 @@ FILE *basilisk_swap_save(struct basilisk_swap *swap,bits256 privkey,struct basil { if ( peer->errors >= LP_MAXPEER_ERRORS ) { - if ( (rand() % 10000) == 0 ) + if ( (LP_rand() % 10000) == 0 ) { peer->errors--; if ( peer->errors < LP_MAXPEER_ERRORS ) @@ -195,7 +195,7 @@ FILE *basilisk_swap_save(struct basilisk_swap *swap,bits256 privkey,struct basil if ( IAMLP == 0 ) continue; } - if ( now > peer->lastpeers+LP_ORDERBOOK_DURATION*.777 || (rand() % 100000) == 0 ) + if ( now > peer->lastpeers+LP_ORDERBOOK_DURATION*.777 || (LP_rand() % 100000) == 0 ) { if ( strcmp(peer->ipaddr,myipaddr) != 0 ) { @@ -241,7 +241,7 @@ int32_t LP_peersparse(struct LP_peerinfo *mypeer,int32_t mypubsock,char *destipa if ( (peer= LP_peerfind(argipbits,argport)) == 0 ) { numpeers = LP_numpeers(); - if ( IAMLP != 0 || numpeers < LP_MIN_PEERS || (IAMLP == 0 && (rand() % LP_MAX_PEERS) > numpeers) ) + if ( IAMLP != 0 || numpeers < LP_MIN_PEERS || (IAMLP == 0 && (LP_rand() % LP_MAX_PEERS) > numpeers) ) peer = LP_addpeer(mypeer,mypubsock,argipaddr,argport,pushport,subport,jint(item,"numpeers"),jint(item,"numutxos"),juint(item,"session")); } if ( peer != 0 ) @@ -395,7 +395,7 @@ void issue_LP_uitem(char *destip,uint16_t destport,char *symbol,char *coinaddr,b ptr = calloc(1,sizeof(*ptr)); ptr->timestamp = (uint32_t)time(NULL); ptr->item = item; - item->cjsonid = rand(); + item->cjsonid = LP_rand(); ptr->cjsonid = item->cjsonid; portable_mutex_lock(&LP_cJSONmutex); DL_APPEND(LP_cJSONlist,ptr); @@ -955,7 +955,7 @@ int32_t _basilisk_rawtx_gen(char *str,uint32_t swapstarted,uint8_t *pubkey33,int { char scriptstr[1024],wifstr[256],coinaddr[64],*signedtx,*rawtxbytes; uint32_t basilisktag; int32_t retval = -1; cJSON *vins,*privkeys,*addresses,*valsobj; struct vin_info *V; init_hexbytes_noT(scriptstr,script,scriptlen); - basilisktag = (uint32_t)rand(); + basilisktag = (uint32_t)LP_rand(); valsobj = cJSON_CreateObject(); jaddstr(valsobj,"coin",rawtx->coin->symbol); jaddstr(valsobj,"spendscript",scriptstr); @@ -1195,7 +1195,7 @@ int32_t basilisk_swapiteration(struct basilisk_swap *swap,uint8_t *data,int32_t basilisk_swap_saveupdate(swap); if ( swap->connected == 0 ) basilisk_psockinit(swap,swap->I.iambob != 0); - //if ( (rand() % 30) == 0 ) + //if ( (LP_rand() % 30) == 0 ) printf("E r%u/q%u swapstate.%x otherstate.%x remaining %d\n",swap->I.req.requestid,swap->I.req.quoteid,swap->I.statebits,swap->I.otherstatebits,(int32_t)(swap->I.expiration-time(NULL))); if ( swap->I.iambob != 0 ) { @@ -1369,7 +1369,7 @@ int32_t basilisk_swapiteration(struct basilisk_swap *swap,uint8_t *data,int32_t } } } - if ( (rand() % 30) == 0 ) + if ( (LP_rand() % 30) == 0 ) printf("finished swapstate.%x other.%x\n",swap->I.statebits,swap->I.otherstatebits); if ( swap->I.statebits == savestatebits && swap->I.otherstatebits == saveotherbits ) sleep(DEX_SLEEP + (swap->I.iambob == 0)*1); @@ -2792,7 +2792,7 @@ void LP_price_broadcastloop(void *ctx) minprice = LP_pricevol_invert(&basevol,bot->maxprice,bot->totalrelvolume - bot->relsum); printf("simulated trade sell %s/%s minprice %.8f volume %.8f, %.8f %s -> %s price %.8f relvol %.8f\n",bot->rel,bot->base,minprice,basevol,v,bot->base,bot->rel,p,relvol); } - if ( (rand() % 2) == 0 ) + if ( (LP_rand() % 2) == 0 ) { bot->relsum += relvol; bot->basesum += v; @@ -2809,7 +2809,7 @@ void LP_price_broadcastloop(void *ctx) #ifdef FROM_JS int32_t sentbytes,sock,peerind,maxind; if ( (maxind= LP_numpeers()) > 0 ) -peerind = (rand() % maxind) + 1; +peerind = (LP_rand() % maxind) + 1; else peerind = 1; sock = LP_peerindsock(&peerind); if ( sock >= 0 ) @@ -2851,11 +2851,11 @@ void _LP_queuesend(uint32_t crc32,int32_t sock0,int32_t sock1,uint8_t *msg,int32 else { if ( (maxind= LP_numpeers()) > 0 ) - peerind = (rand() % maxind) + 1; + peerind = (LP_rand() % maxind) + 1; else peerind = 1; sock0 = LP_peerindsock(&peerind); if ( (maxind= LP_numpeers()) > 0 ) - peerind = (rand() % maxind) + 1; + peerind = (LP_rand() % maxind) + 1; else peerind = 1; sock1 = LP_peerindsock(&peerind); } diff --git a/iguana/exchanges/LP_tradebots.c b/iguana/exchanges/LP_tradebots.c index 762a5c6bf..ec00553e4 100644 --- a/iguana/exchanges/LP_tradebots.c +++ b/iguana/exchanges/LP_tradebots.c @@ -324,7 +324,7 @@ void LP_tradebot_timeslice(void *ctx,struct LP_tradebot *bot) printf("try autobuy %s/%s remaining %.8f maxprice %.8f maxrel %.8f\n",bot->base,bot->rel,remaining,bot->maxprice,maxrel); if ( maxrel < remaining ) remaining = maxrel; - tradeid = rand(); + tradeid = LP_rand(); for (i=1; i<=maxiters; i++) { if ( remaining < 0.001 ) diff --git a/iguana/exchanges/LP_utxo.c b/iguana/exchanges/LP_utxo.c index d94c1c5b9..59b8b8b8e 100644 --- a/iguana/exchanges/LP_utxo.c +++ b/iguana/exchanges/LP_utxo.c @@ -405,7 +405,7 @@ int32_t LP_address_utxoadd(uint32_t timestamp,char *debug,struct iguana_info *co up->SPV = tx->SPV; } char str[65]; - //if ( 0 && strcmp(coin->smartaddr,coinaddr) == 0 && strcmp("KMD",coin->symbol) == 0 ) + if ( 0 && strcmp(coin->smartaddr,coinaddr) == 0 && strcmp("KMD",coin->symbol) == 0 ) printf("%s ADD UTXO >> %s %s %s/v%d ht.%d %.8f\n",debug,coin->symbol,coinaddr,bits256_str(str,txid),vout,height,dstr(value)); portable_mutex_lock(&coin->addrmutex); DL_APPEND(ap->utxos,up); diff --git a/iguana/exchanges/LP_utxos.c b/iguana/exchanges/LP_utxos.c index 2498d4da4..fc05779cb 100644 --- a/iguana/exchanges/LP_utxos.c +++ b/iguana/exchanges/LP_utxos.c @@ -848,7 +848,7 @@ void LP_privkey_updates(void *ctx,int32_t pubsock,char *passphrase) else if ( IAMLP == 0 || coin->inactive == 0 ) { //printf("from updates %s\n",coin->symbol); - if ( LP_privkey_init(pubsock,coin,G.LP_privkey,G.LP_mypub25519) == 0 && (rand() % 10) == 0 ) + if ( LP_privkey_init(pubsock,coin,G.LP_privkey,G.LP_mypub25519) == 0 && (LP_rand() % 10) == 0 ) LP_postutxos(coin->symbol,coin->smartaddr); } } From 146ebb01bd470b5644732c0c9e3256d2fc6e807d Mon Sep 17 00:00:00 2001 From: jl777 Date: Thu, 16 Nov 2017 14:22:17 +0200 Subject: [PATCH 0925/1664] Test --- iguana/exchanges/LP_nativeDEX.c | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/iguana/exchanges/LP_nativeDEX.c b/iguana/exchanges/LP_nativeDEX.c index 6725bbf34..9ba577394 100644 --- a/iguana/exchanges/LP_nativeDEX.c +++ b/iguana/exchanges/LP_nativeDEX.c @@ -777,7 +777,7 @@ void LP_pubkeysloop(void *ctx) } if ( time(NULL) > lasttime+LP_ORDERBOOK_DURATION*0.5 ) { -printf("LP_pubkeysloop %u\n",(uint32_t)time(NULL)); +//printf("LP_pubkeysloop %u\n",(uint32_t)time(NULL)); LP_notify_pubkeys(ctx,LP_mypubsock); lasttime = (uint32_t)time(NULL); } @@ -794,7 +794,7 @@ void LP_privkeysloop(void *ctx) { LP_millistats_update(&LP_privkeysloop_stats); LP_counter += 1000; -printf("LP_privkeysloop %u\n",LP_counter); +//printf("LP_privkeysloop %u\n",LP_counter); LP_privkey_updates(ctx,LP_mypubsock,0); sleep(LP_ORDERBOOK_DURATION * .777); } @@ -810,7 +810,7 @@ void LP_swapsloop(void *ignore) { LP_millistats_update(&LP_swapsloop_stats); LP_counter += 10000; -printf("LP_swapsloop %u\n",LP_counter); +//printf("LP_swapsloop %u\n",LP_counter); if ( (retstr= basilisk_swapentry(0,0)) != 0 ) free(retstr); sleep(600); @@ -845,14 +845,14 @@ void LP_reserved_msgs(void *ignore) if ( num_Reserved_msgs[1] > 0 ) { num_Reserved_msgs[1]--; -printf("PRIORITY BROADCAST.(%s)\n",Reserved_msgs[1][num_Reserved_msgs[1]]); +//printf("PRIORITY BROADCAST.(%s)\n",Reserved_msgs[1][num_Reserved_msgs[1]]); LP_broadcast_message(LP_mypubsock,"","",zero,Reserved_msgs[1][num_Reserved_msgs[1]]); Reserved_msgs[1][num_Reserved_msgs[1]] = 0; } else if ( num_Reserved_msgs[0] > 0 ) { num_Reserved_msgs[0]--; -printf("BROADCAST.(%s)\n",Reserved_msgs[0][num_Reserved_msgs[0]]); +//printf("BROADCAST.(%s)\n",Reserved_msgs[0][num_Reserved_msgs[0]]); LP_broadcast_message(LP_mypubsock,"","",zero,Reserved_msgs[0][num_Reserved_msgs[0]]); Reserved_msgs[0][num_Reserved_msgs[0]] = 0; } From 2054f886dcc1c7c11876b7f757596f5212243e38 Mon Sep 17 00:00:00 2001 From: jl777 Date: Thu, 16 Nov 2017 14:23:41 +0200 Subject: [PATCH 0926/1664] Test --- iguana/exchanges/LP_signatures.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/iguana/exchanges/LP_signatures.c b/iguana/exchanges/LP_signatures.c index 0cbcaff3f..651e9c0e8 100644 --- a/iguana/exchanges/LP_signatures.c +++ b/iguana/exchanges/LP_signatures.c @@ -133,13 +133,15 @@ int32_t LP_quoteparse(struct LP_quoteinfo *qp,cJSON *argjson) if ( qp->R.requestid == 0 ) { rid = basilisk_requestid(&qp->R); - printf("requestid.%u -> %u\n",qp->R.requestid,rid); + if ( qp->R.requestid != 0 && qp->R.requestid != rid ) + printf("requestid.%u -> %u\n",qp->R.requestid,rid); qp->R.requestid = rid; } if ( qp->R.quoteid == 0 ) { qid = basilisk_quoteid(&qp->R); - printf("quoteid.%u -> %u\n",qp->R.quoteid,qid); + if ( qp->R.quoteid != 0 && qp->R.quoteid != qid ) + printf("quoteid.%u -> %u\n",qp->R.quoteid,qid); qp->R.quoteid = qid; } return(0); From 0dff7d0e183a7c849029c005e6c2480b9567c46d Mon Sep 17 00:00:00 2001 From: jl777 Date: Thu, 16 Nov 2017 14:45:37 +0200 Subject: [PATCH 0927/1664] Test --- iguana/exchanges/LP_ordermatch.c | 5 +++-- iguana/exchanges/LP_swap.c | 2 +- 2 files changed, 4 insertions(+), 3 deletions(-) diff --git a/iguana/exchanges/LP_ordermatch.c b/iguana/exchanges/LP_ordermatch.c index 3ad0fe345..2711f7f42 100644 --- a/iguana/exchanges/LP_ordermatch.c +++ b/iguana/exchanges/LP_ordermatch.c @@ -572,6 +572,8 @@ char *LP_connectedalice(cJSON *argjson) // alice return(clonestr("{\"result\",\"update stats\"}")); } printf("CONNECTED.(%s) numpending.%d tradeid.%u requestid.%u quoteid.%u\n",jprint(argjson,0),G.LP_pendingswaps,Q.tradeid,Q.R.requestid,Q.R.quoteid); + LP_requestinit(&Q.R,Q.srchash,Q.desthash,Q.srccoin,Q.satoshis-Q.txfee,Q.destcoin,Q.destsatoshis-Q.desttxfee,Q.timestamp,Q.quotetime,DEXselector); + printf("calculated requestid.%u quoteid.%u\n",Q.R.requestid,Q.R.quoteid); if ( LP_pendingswap(Q.R.requestid,Q.R.quoteid) > 0 ) { printf("requestid.%u quoteid.%u is already in progres\n",Q.R.requestid,Q.R.quoteid); @@ -622,7 +624,6 @@ char *LP_connectedalice(cJSON *argjson) // alice if ( bits256_nonz(Q.privkey) != 0 )//&& Q.quotetime >= Q.timestamp-3 ) { retjson = cJSON_CreateObject(); - LP_requestinit(&Q.R,Q.srchash,Q.desthash,Q.srccoin,Q.satoshis-Q.txfee,Q.destcoin,Q.destsatoshis-Q.desttxfee,Q.timestamp,Q.quotetime,DEXselector); if ( (swap= LP_swapinit(0,0,Q.privkey,&Q.R,&Q)) == 0 ) { jaddstr(retjson,"error","couldnt swapinit"); @@ -771,7 +772,7 @@ int32_t LP_tradecommand(void *ctx,char *myipaddr,int32_t pubsock,cJSON *argjson, LP_quoteparse(&Q,argjson); LP_requestinit(&Q.R,Q.srchash,Q.desthash,Q.srccoin,Q.satoshis-Q.txfee,Q.destcoin,Q.destsatoshis-Q.desttxfee,Q.timestamp,Q.quotetime,DEXselector); LP_tradecommand_log(argjson); - printf("LP_tradecommand: received %12s aliceid.%22llu %5s/%-5s %12.8f -> %12.8f price %12.8f\n",method,(long long)Q.aliceid,Q.srccoin,Q.destcoin,dstr(Q.satoshis),dstr(Q.destsatoshis),(double)Q.destsatoshis/Q.satoshis); + printf("(%u-%u): received %12s aliceid.%22llu %5s/%-5s %12.8f -> %12.8f price %12.8f\n",Q.R.requestid,Q.R.quoteid,method,(long long)Q.aliceid,Q.srccoin,Q.destcoin,dstr(Q.satoshis),dstr(Q.destsatoshis),(double)Q.destsatoshis/Q.satoshis); retval = 1; autxo = &A; butxo = &B; diff --git a/iguana/exchanges/LP_swap.c b/iguana/exchanges/LP_swap.c index ba323ae97..23f8d0a39 100644 --- a/iguana/exchanges/LP_swap.c +++ b/iguana/exchanges/LP_swap.c @@ -1189,7 +1189,7 @@ struct basilisk_swap *LP_swapinit(int32_t iambob,int32_t optionduration,bits256 G.LP_skipstatus[G.LP_numskips] = ((uint64_t)rp->requestid << 32) | rp->quoteid; if ( G.LP_numskips < sizeof(G.LP_skipstatus)/sizeof(*G.LP_skipstatus) ) G.LP_numskips++; - printf("basilisk_thread_start request.%u iambob.%d (%s/%s) quoteid.%u\n",rp->requestid,iambob,rp->src,rp->dest,rp->quoteid); + printf("LP_swapinit request.%u iambob.%d (%s/%s) quoteid.%u\n",rp->requestid,iambob,rp->src,rp->dest,rp->quoteid); bitcoin_pubkey33(swap->ctx,pubkey33,privkey); pubkey25519 = curve25519(privkey,curve25519_basepoint9()); swap->persistent_pubkey = pubkey25519; From 14cafd3da616ea973f415ef4fbd0c441d75db176 Mon Sep 17 00:00:00 2001 From: jl777 Date: Thu, 16 Nov 2017 15:04:35 +0200 Subject: [PATCH 0928/1664] Test --- iguana/exchanges/LP_nativeDEX.c | 5 +++-- iguana/exchanges/LP_ordermatch.c | 8 +------- 2 files changed, 4 insertions(+), 9 deletions(-) diff --git a/iguana/exchanges/LP_nativeDEX.c b/iguana/exchanges/LP_nativeDEX.c index 9ba577394..2159505ec 100644 --- a/iguana/exchanges/LP_nativeDEX.c +++ b/iguana/exchanges/LP_nativeDEX.c @@ -888,8 +888,9 @@ int32_t LP_reserved_msg(int32_t priority,char *base,char *rel,bits256 pubkey,cha 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 valid,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(); - printf("Marketmaker %s.%s %s\n",LP_MAJOR_VERSION,LP_MINOR_VERSION,LP_BUILD_NUMBER); + char *myipaddr=0,version[64]; long filesize,n; int32_t valid,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(); + sprintf(version,"Marketmaker %s.%s %s",LP_MAJOR_VERSION,LP_MINOR_VERSION,LP_BUILD_NUMBER); + printf("%s %u\n",version,calc_crc32(0,version,(int32_t)strlen(version))); LP_showwif = juint(argjson,"wif"); if ( passphrase == 0 || passphrase[0] == 0 ) { diff --git a/iguana/exchanges/LP_ordermatch.c b/iguana/exchanges/LP_ordermatch.c index 2711f7f42..d0641e578 100644 --- a/iguana/exchanges/LP_ordermatch.c +++ b/iguana/exchanges/LP_ordermatch.c @@ -587,12 +587,6 @@ char *LP_connectedalice(cJSON *argjson) // alice LP_aliceid(Q.tradeid,Q.aliceid,"error2",0,0); return(clonestr("{\"error\":\"cant find autxo\"}")); } - /*if ( autxo->S.swap != 0 ) - { - printf("ignore duplicate swap\n"); - LP_aliceid(Q.tradeid,Q.aliceid,"error3",0,0); - return(clonestr("{\"error\":\"ignore duplicate swap\"}")); - }*/ LP_aliceid(Q.tradeid,Q.aliceid,"connected",Q.R.requestid,Q.R.quoteid); butxo = &B; memset(butxo,0,sizeof(*butxo)); @@ -772,7 +766,7 @@ int32_t LP_tradecommand(void *ctx,char *myipaddr,int32_t pubsock,cJSON *argjson, LP_quoteparse(&Q,argjson); LP_requestinit(&Q.R,Q.srchash,Q.desthash,Q.srccoin,Q.satoshis-Q.txfee,Q.destcoin,Q.destsatoshis-Q.desttxfee,Q.timestamp,Q.quotetime,DEXselector); LP_tradecommand_log(argjson); - printf("(%u-%u): received %12s aliceid.%22llu %5s/%-5s %12.8f -> %12.8f price %12.8f\n",Q.R.requestid,Q.R.quoteid,method,(long long)Q.aliceid,Q.srccoin,Q.destcoin,dstr(Q.satoshis),dstr(Q.destsatoshis),(double)Q.destsatoshis/Q.satoshis); + printf("(%-10u %10u) %12s aliceid.%22llu %5s/%-5s %12.8f -> %12.8f price %12.8f\n",Q.R.requestid,Q.R.quoteid,method,(long long)Q.aliceid,Q.srccoin,Q.destcoin,dstr(Q.satoshis),dstr(Q.destsatoshis),(double)Q.destsatoshis/Q.satoshis); retval = 1; autxo = &A; butxo = &B; From 48464283c7d754cb5f082d300a29f83f515692ee Mon Sep 17 00:00:00 2001 From: jl777 Date: Thu, 16 Nov 2017 15:10:56 +0200 Subject: [PATCH 0929/1664] Test --- iguana/exchanges/LP_nativeDEX.c | 2 +- iguana/exchanges/LP_swap.c | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/iguana/exchanges/LP_nativeDEX.c b/iguana/exchanges/LP_nativeDEX.c index 2159505ec..00eabb24a 100644 --- a/iguana/exchanges/LP_nativeDEX.c +++ b/iguana/exchanges/LP_nativeDEX.c @@ -889,7 +889,7 @@ int32_t LP_reserved_msg(int32_t priority,char *base,char *rel,bits256 pubkey,cha 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,version[64]; long filesize,n; int32_t valid,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(); - sprintf(version,"Marketmaker %s.%s %s",LP_MAJOR_VERSION,LP_MINOR_VERSION,LP_BUILD_NUMBER); + sprintf(version,"Marketmaker %s.%s %s rsize.%ld",LP_MAJOR_VERSION,LP_MINOR_VERSION,LP_BUILD_NUMBER,sizeof(struct basilisk_request)); printf("%s %u\n",version,calc_crc32(0,version,(int32_t)strlen(version))); LP_showwif = juint(argjson,"wif"); if ( passphrase == 0 || passphrase[0] == 0 ) diff --git a/iguana/exchanges/LP_swap.c b/iguana/exchanges/LP_swap.c index 23f8d0a39..e1c80d505 100644 --- a/iguana/exchanges/LP_swap.c +++ b/iguana/exchanges/LP_swap.c @@ -1127,7 +1127,7 @@ struct basilisk_swap *bitcoin_swapinit(bits256 privkey,uint8_t *pubkey33,bits256 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,bobcoin->taddr,alicecoin->taddr); + printf(">>>>>>>>>> jumblrflag.%d <<<<<<<<< r.%u q.%u, %.8f bobconfs.%d, %.8f aliceconfs.%d taddr.%d %d\n",jumblrflag,swap->I.req.requestid,swap->I.req.quoteid,dstr(swap->I.bobsatoshis),swap->I.bobconfirms,dstr(swap->I.alicesatoshis),swap->I.aliceconfirms,bobcoin->taddr,alicecoin->taddr); if ( swap->I.iambob != 0 ) { basilisk_rawtx_setparms("myfee",swap->I.req.quoteid,&swap->myfee,bobcoin,0,0,LP_DEXFEE(swap->I.bobsatoshis) + 0*bobcoin->txfee,0,0,jumblrflag); From 05c5e9078cf7350f505950dba74a71d2eb58b8f3 Mon Sep 17 00:00:00 2001 From: jl777 Date: Thu, 16 Nov 2017 15:30:17 +0200 Subject: [PATCH 0930/1664] Test --- iguana/exchanges/LP_signatures.c | 1 + iguana/exchanges/LP_socket.c | 5 ++++- iguana/exchanges/LP_utxos.c | 6 ++++-- 3 files changed, 9 insertions(+), 3 deletions(-) diff --git a/iguana/exchanges/LP_signatures.c b/iguana/exchanges/LP_signatures.c index 651e9c0e8..0d013b68e 100644 --- a/iguana/exchanges/LP_signatures.c +++ b/iguana/exchanges/LP_signatures.c @@ -616,6 +616,7 @@ char *LP_notify_recv(cJSON *argjson) void LP_smartutxos_push(struct iguana_info *coin) { uint64_t value; bits256 zero,txid; int32_t i,vout,height,n; cJSON *array,*item,*req; + return; if ( coin->smartaddr[0] == 0 ) return; //LP_notify_pubkeys(coin->ctx,LP_mypubsock); diff --git a/iguana/exchanges/LP_socket.c b/iguana/exchanges/LP_socket.c index 36e6988ca..723a61a92 100644 --- a/iguana/exchanges/LP_socket.c +++ b/iguana/exchanges/LP_socket.c @@ -602,7 +602,10 @@ cJSON *electrum_address_listunspent(char *symbol,struct electrum_info *ep,cJSON printf("%s.%d u.%u/%d t.%ld %s LISTUNSPENT.(%d)\n",coin->symbol,height,ap->unspenttime,ap->unspentheight,time(NULL),addr,(int32_t)strlen(jprint(retjson,0))); updatedflag = 0; if ( electrum_process_array(coin,ep,addr,retjson,electrumflag) != 0 ) - LP_postutxos(coin->symbol,addr), updatedflag = 1; + { + //LP_postutxos(coin->symbol,addr); + updatedflag = 1; + } if ( strcmp(addr,coin->smartaddr) == 0 ) { retstr = jprint(retjson,0); diff --git a/iguana/exchanges/LP_utxos.c b/iguana/exchanges/LP_utxos.c index fc05779cb..90e0aafc8 100644 --- a/iguana/exchanges/LP_utxos.c +++ b/iguana/exchanges/LP_utxos.c @@ -700,7 +700,7 @@ int32_t LP_privkey_init(int32_t mypubsock,struct iguana_info *coin,bits256 mypri } } free_json(array); - if ( flag != 0 ) + if ( 0 && flag != 0 ) LP_postutxos(coin->symbol,coin->smartaddr); } if ( values != 0 ) @@ -849,7 +849,9 @@ void LP_privkey_updates(void *ctx,int32_t pubsock,char *passphrase) { //printf("from updates %s\n",coin->symbol); if ( LP_privkey_init(pubsock,coin,G.LP_privkey,G.LP_mypub25519) == 0 && (LP_rand() % 10) == 0 ) - LP_postutxos(coin->symbol,coin->smartaddr); + { + //LP_postutxos(coin->symbol,coin->smartaddr); + } } } } From 7ba7a49601e62c8e48a4f78d8af653c35e3f10ec Mon Sep 17 00:00:00 2001 From: jl777 Date: Thu, 16 Nov 2017 15:37:42 +0200 Subject: [PATCH 0931/1664] Test --- iguana/exchanges/LP_commands.c | 2 +- iguana/exchanges/LP_nativeDEX.c | 6 +++--- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/iguana/exchanges/LP_commands.c b/iguana/exchanges/LP_commands.c index 3b0734349..9155291fb 100644 --- a/iguana/exchanges/LP_commands.c +++ b/iguana/exchanges/LP_commands.c @@ -36,7 +36,7 @@ char *stats_JSON(void *ctx,char *myipaddr,int32_t pubsock,cJSON *argjson,char *r { char *method,*userpass,*base,*rel,*coin,*retstr = 0; int32_t changed,flag = 0; cJSON *retjson,*reqjson = 0; struct iguana_info *ptr; method = jstr(argjson,"method"); - //printf("stats_JSON %s\n",method); +printf("stats_JSON %s\n",method); /*if ( (ipaddr= jstr(argjson,"ipaddr")) != 0 && (argport= juint(argjson,"port")) != 0 && (method == 0 || strcmp(method,"electrum") != 0) ) { if ( strcmp(ipaddr,"127.0.0.1") != 0 && argport >= 1000 ) diff --git a/iguana/exchanges/LP_nativeDEX.c b/iguana/exchanges/LP_nativeDEX.c index 00eabb24a..f73c9474f 100644 --- a/iguana/exchanges/LP_nativeDEX.c +++ b/iguana/exchanges/LP_nativeDEX.c @@ -1216,7 +1216,7 @@ int32_t zeroval() { return(0); } void *LP_alloc(uint64_t len) { -return(calloc(1,len)); +//return(calloc(1,len)); LP_cjson_allocated += len; LP_cjson_total += len; LP_cjson_count++; @@ -1235,9 +1235,9 @@ return(calloc(1,len)); void LP_free(void *ptr) { static uint32_t lasttime,unknown; static int64_t lasttotal; -free(ptr); return; +//free(ptr); return; uint32_t now; char str[65]; int32_t n,lagging; uint64_t total = 0; struct LP_memory_list *mp,*tmp; - if ( (now= (uint32_t)time(NULL)) > lasttime+6 ) + if ( (now= (uint32_t)time(NULL)) > lasttime+1 ) { n = lagging = 0; DL_FOREACH_SAFE(LP_memory_list,mp,tmp) From e8b2923ffcbb893601023034bea777778173804e Mon Sep 17 00:00:00 2001 From: jl777 Date: Thu, 16 Nov 2017 15:49:52 +0200 Subject: [PATCH 0932/1664] Test --- iguana/exchanges/LP_nativeDEX.c | 4 ++-- iguana/exchanges/LP_signatures.c | 2 +- iguana/exchanges/stats.c | 2 +- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/iguana/exchanges/LP_nativeDEX.c b/iguana/exchanges/LP_nativeDEX.c index f73c9474f..681f8a907 100644 --- a/iguana/exchanges/LP_nativeDEX.c +++ b/iguana/exchanges/LP_nativeDEX.c @@ -1216,7 +1216,7 @@ int32_t zeroval() { return(0); } void *LP_alloc(uint64_t len) { -//return(calloc(1,len)); +return(calloc(1,len)); LP_cjson_allocated += len; LP_cjson_total += len; LP_cjson_count++; @@ -1235,7 +1235,7 @@ void *LP_alloc(uint64_t len) void LP_free(void *ptr) { static uint32_t lasttime,unknown; static int64_t lasttotal; -//free(ptr); return; +free(ptr); return; uint32_t now; char str[65]; int32_t n,lagging; uint64_t total = 0; struct LP_memory_list *mp,*tmp; if ( (now= (uint32_t)time(NULL)) > lasttime+1 ) { diff --git a/iguana/exchanges/LP_signatures.c b/iguana/exchanges/LP_signatures.c index 0d013b68e..647daa1ba 100644 --- a/iguana/exchanges/LP_signatures.c +++ b/iguana/exchanges/LP_signatures.c @@ -616,7 +616,7 @@ char *LP_notify_recv(cJSON *argjson) void LP_smartutxos_push(struct iguana_info *coin) { uint64_t value; bits256 zero,txid; int32_t i,vout,height,n; cJSON *array,*item,*req; - return; +return; if ( coin->smartaddr[0] == 0 ) return; //LP_notify_pubkeys(coin->ctx,LP_mypubsock); diff --git a/iguana/exchanges/stats.c b/iguana/exchanges/stats.c index 179612c4e..681da52d2 100644 --- a/iguana/exchanges/stats.c +++ b/iguana/exchanges/stats.c @@ -32,7 +32,7 @@ char *stats_JSON(void *ctx,char *myipaddr,int32_t mypubsock,cJSON *argjson,char char *stats_validmethods[] = { - "psock", "getprices", "listunspent", "notify", "getpeers", "uitem", // from issue_ + "psock", "getprices", "notify", "getpeers", // from issue_ "uitem", "listunspent", "orderbook", "help", "getcoins", "pricearray", "balance", "tradestatus" }; From b89adb55f6634f2e6f735efb2798e4fe5d1b397e Mon Sep 17 00:00:00 2001 From: jl777 Date: Thu, 16 Nov 2017 15:54:06 +0200 Subject: [PATCH 0933/1664] Test --- iguana/exchanges/LP_commands.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/iguana/exchanges/LP_commands.c b/iguana/exchanges/LP_commands.c index 9155291fb..53ff69f19 100644 --- a/iguana/exchanges/LP_commands.c +++ b/iguana/exchanges/LP_commands.c @@ -36,6 +36,8 @@ char *stats_JSON(void *ctx,char *myipaddr,int32_t pubsock,cJSON *argjson,char *r { char *method,*userpass,*base,*rel,*coin,*retstr = 0; int32_t changed,flag = 0; cJSON *retjson,*reqjson = 0; struct iguana_info *ptr; method = jstr(argjson,"method"); + if ( method != 0 && strcmp(method,"uitem") == 0 ) + return(0); printf("stats_JSON %s\n",method); /*if ( (ipaddr= jstr(argjson,"ipaddr")) != 0 && (argport= juint(argjson,"port")) != 0 && (method == 0 || strcmp(method,"electrum") != 0) ) { From 14b6e3acc7f0894cf2ec3157d9dba8c15a6e35e4 Mon Sep 17 00:00:00 2001 From: jl777 Date: Thu, 16 Nov 2017 15:57:39 +0200 Subject: [PATCH 0934/1664] Test --- iguana/exchanges/LP_commands.c | 2 +- iguana/exchanges/LP_nativeDEX.c | 2 +- iguana/exchanges/LP_signatures.c | 3 +++ 3 files changed, 5 insertions(+), 2 deletions(-) diff --git a/iguana/exchanges/LP_commands.c b/iguana/exchanges/LP_commands.c index 53ff69f19..0ec77c466 100644 --- a/iguana/exchanges/LP_commands.c +++ b/iguana/exchanges/LP_commands.c @@ -36,7 +36,7 @@ char *stats_JSON(void *ctx,char *myipaddr,int32_t pubsock,cJSON *argjson,char *r { char *method,*userpass,*base,*rel,*coin,*retstr = 0; int32_t changed,flag = 0; cJSON *retjson,*reqjson = 0; struct iguana_info *ptr; method = jstr(argjson,"method"); - if ( method != 0 && strcmp(method,"uitem") == 0 ) + if ( method != 0 && (strcmp(method,"uitem") == 0 || strcmp(method,"postutxos") == 0) ) return(0); printf("stats_JSON %s\n",method); /*if ( (ipaddr= jstr(argjson,"ipaddr")) != 0 && (argport= juint(argjson,"port")) != 0 && (method == 0 || strcmp(method,"electrum") != 0) ) diff --git a/iguana/exchanges/LP_nativeDEX.c b/iguana/exchanges/LP_nativeDEX.c index 681f8a907..30e1d9753 100644 --- a/iguana/exchanges/LP_nativeDEX.c +++ b/iguana/exchanges/LP_nativeDEX.c @@ -1043,7 +1043,7 @@ void LPinit(uint16_t myport,uint16_t mypullport,uint16_t mypubport,uint16_t mybu printf("error launching LP_reserved_msgs for (%s)\n",myipaddr); exit(-1); } - if ( OS_thread_create(malloc(sizeof(pthread_t)),NULL,(void *)utxosQ_loop,(void *)myipaddr) != 0 ) + if ( 0 && OS_thread_create(malloc(sizeof(pthread_t)),NULL,(void *)utxosQ_loop,(void *)myipaddr) != 0 ) { printf("error launching utxosQ_loop for (%s)\n",myipaddr); exit(-1); diff --git a/iguana/exchanges/LP_signatures.c b/iguana/exchanges/LP_signatures.c index 647daa1ba..0008ee1b5 100644 --- a/iguana/exchanges/LP_signatures.c +++ b/iguana/exchanges/LP_signatures.c @@ -330,6 +330,7 @@ int32_t LP_utxos_sigadd(cJSON *item,uint32_t timestamp,bits256 priv,uint8_t *pub void LP_postutxos(char *symbol,char *coinaddr) { bits256 zero; uint32_t timestamp; bits256 utxoshash; char pubsecpstr[67]; struct iguana_info *coin; cJSON *array,*reqjson = cJSON_CreateObject(); +return; 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); @@ -362,6 +363,7 @@ struct LP_utxos_qitem { struct queueitem DL; cJSON *argjson; }; char *LP_postutxos_recv(cJSON *argjson) { struct LP_utxos_qitem *uitem; struct iguana_info *coin; char *coinaddr,*symbol; bits256 utxoshash,pubkey; cJSON *obj; struct LP_pubkeyinfo *pubp; +printf("LP_postutxos_recv deprecated\n"); pubkey = jbits256(argjson,"pubkey"); pubp = LP_pubkeyfind(pubkey); if ( pubp != 0 && pubp->numerrors > LP_MAXPUBKEY_ERRORS ) @@ -652,6 +654,7 @@ return; char *LP_uitem_recv(cJSON *argjson) { bits256 txid; int32_t vout,height; uint64_t value; struct iguana_info *coin; char *coinaddr,*symbol; +printf("LP_uitem_recv deprecated\n"); txid = jbits256(argjson,"txid"); vout = jint(argjson,"vout"); height = jint(argjson,"ht"); From e2e6c5091986361c155870bb6f384a8b350078c2 Mon Sep 17 00:00:00 2001 From: DeckerSU Date: Thu, 16 Nov 2017 17:10:45 +0300 Subject: [PATCH 0935/1664] fix structure alignment issue on Windows (error LP_sendwait pubkeys) structure alignment on Windows should be same as on Unix, when you have to start compiled marketmaker first line should be: Marketmaker 0.1 15000 rsize.248 451196191 rsize = 248. otherwise you will get this error on every swap: waitfor timedout didnt get pubkeys error LP_sendwait pubkeys finish swap.0000008AC93A3100 --- marketmaker.vcxproj | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/marketmaker.vcxproj b/marketmaker.vcxproj index 0dbe62279..7d3862568 100644 --- a/marketmaker.vcxproj +++ b/marketmaker.vcxproj @@ -87,7 +87,7 @@ Level2 Disabled _CRT_SECURE_NO_WARNINGS;NATIVE_WINDOWS;WIN32;_DEBUG;_CONSOLE;IGUANA_LOG2PACKETSIZE=20;IGUANA_MAXPACKETSIZE=1572864;%(PreprocessorDefinitions) - 1Byte + 8Bytes .\iguana;%(AdditionalIncludeDirectories) @@ -104,7 +104,7 @@ Level3 Disabled _DEBUG;_CONSOLE;NATIVE_WINDOWS;WIN32;IGUANA_LOG2PACKETSIZE=20;IGUANA_MAXPACKETSIZE=1572864;%(PreprocessorDefinitions) - 1Byte + 8Bytes Console @@ -122,7 +122,7 @@ true true _CRT_SECURE_NO_WARNINGS;NATIVE_WINDOWS;WIN32;_CONSOLE;NDEBUG;IGUANA_LOG2PACKETSIZE=20;IGUANA_MAXPACKETSIZE=1572864;%(PreprocessorDefinitions) - 1Byte + 8Bytes MachineX86 @@ -142,7 +142,7 @@ true true WIN64;_WIN64;_CRT_SECURE_NO_WARNINGS;NATIVE_WINDOWS;WIN32;WIN32_LEAN_AND_MEAN;_CONSOLE;NDEBUG;IGUANA_LOG2PACKETSIZE=20;IGUANA_MAXPACKETSIZE=1572864;%(PreprocessorDefinitions) - 1Byte + 8Bytes MultiThreaded From 1e10b2c083800e7f9338f89641ef9eac13ea968e Mon Sep 17 00:00:00 2001 From: jl777 Date: Thu, 16 Nov 2017 16:14:09 +0200 Subject: [PATCH 0936/1664] Test --- iguana/exchanges/LP_commands.c | 2 +- iguana/exchanges/LP_ordermatch.c | 2 +- iguana/exchanges/LP_prices.c | 4 ++-- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/iguana/exchanges/LP_commands.c b/iguana/exchanges/LP_commands.c index 0ec77c466..e5f232d4b 100644 --- a/iguana/exchanges/LP_commands.c +++ b/iguana/exchanges/LP_commands.c @@ -36,7 +36,7 @@ char *stats_JSON(void *ctx,char *myipaddr,int32_t pubsock,cJSON *argjson,char *r { char *method,*userpass,*base,*rel,*coin,*retstr = 0; int32_t changed,flag = 0; cJSON *retjson,*reqjson = 0; struct iguana_info *ptr; method = jstr(argjson,"method"); - if ( method != 0 && (strcmp(method,"uitem") == 0 || strcmp(method,"postutxos") == 0) ) + if ( method != 0 && (strcmp(method,"addr_unspents") == 0 || strcmp(method,"uitem") == 0 || strcmp(method,"postutxos") == 0) ) return(0); printf("stats_JSON %s\n",method); /*if ( (ipaddr= jstr(argjson,"ipaddr")) != 0 && (argport= juint(argjson,"port")) != 0 && (method == 0 || strcmp(method,"electrum") != 0) ) diff --git a/iguana/exchanges/LP_ordermatch.c b/iguana/exchanges/LP_ordermatch.c index d0641e578..9dbb4e210 100644 --- a/iguana/exchanges/LP_ordermatch.c +++ b/iguana/exchanges/LP_ordermatch.c @@ -1046,7 +1046,7 @@ struct LP_utxoinfo *LP_buyutxo(double *ordermatchpricep,int64_t *bestsatoshisp,i { bitcoin_address(coinaddr,basecoin->taddr,basecoin->pubtype,pubp->rmd160,sizeof(pubp->rmd160)); asatoshis = autxo->S.satoshis; - LP_listunspent_query(base,coinaddr); + //LP_listunspent_query(base,coinaddr); for (j=0; jpubkey,gui)) != 0 ) diff --git a/iguana/exchanges/LP_prices.c b/iguana/exchanges/LP_prices.c index 80e056b6a..ade6b75f5 100644 --- a/iguana/exchanges/LP_prices.c +++ b/iguana/exchanges/LP_prices.c @@ -818,7 +818,7 @@ char *LP_orderbook(char *base,char *rel,int32_t duration) { //printf("bid ping %s %s\n",rel,bids[i]->coinaddr); LP_address(relcoin,bids[i]->coinaddr); - if ( relcoin->electrum == 0 ) + if ( 0 && relcoin->electrum == 0 ) { LP_listunspent_issue(rel,bids[i]->coinaddr,0); //else if ( (tmpjson= LP_listunspent(rel,bids[i]->coinaddr)) != 0 ) @@ -842,7 +842,7 @@ char *LP_orderbook(char *base,char *rel,int32_t duration) { //printf("ask ping %s %s\n",base,asks[i]->coinaddr); LP_address(basecoin,asks[i]->coinaddr); - if ( basecoin->electrum == 0 ) + if ( 0 && basecoin->electrum == 0 ) { LP_listunspent_issue(base,asks[i]->coinaddr,0); //else if ( (tmpjson= LP_listunspent(base,asks[i]->coinaddr)) != 0 ) From f1dba700fc3a07d57f6b1ca12600291d8fe7590e Mon Sep 17 00:00:00 2001 From: jl777 Date: Thu, 16 Nov 2017 16:21:53 +0200 Subject: [PATCH 0937/1664] Test --- iguana/exchanges/LP_commands.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/iguana/exchanges/LP_commands.c b/iguana/exchanges/LP_commands.c index e5f232d4b..d2f72406d 100644 --- a/iguana/exchanges/LP_commands.c +++ b/iguana/exchanges/LP_commands.c @@ -38,7 +38,7 @@ char *stats_JSON(void *ctx,char *myipaddr,int32_t pubsock,cJSON *argjson,char *r method = jstr(argjson,"method"); if ( method != 0 && (strcmp(method,"addr_unspents") == 0 || strcmp(method,"uitem") == 0 || strcmp(method,"postutxos") == 0) ) return(0); -printf("stats_JSON %s\n",method); +//printf("stats_JSON %s\n",method); /*if ( (ipaddr= jstr(argjson,"ipaddr")) != 0 && (argport= juint(argjson,"port")) != 0 && (method == 0 || strcmp(method,"electrum") != 0) ) { if ( strcmp(ipaddr,"127.0.0.1") != 0 && argport >= 1000 ) From 597f9cdafceb291693526750fb0022cfe3c740f5 Mon Sep 17 00:00:00 2001 From: jl777 Date: Thu, 16 Nov 2017 16:32:30 +0200 Subject: [PATCH 0938/1664] Test --- iguana/exchanges/LP_ordermatch.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/iguana/exchanges/LP_ordermatch.c b/iguana/exchanges/LP_ordermatch.c index 9dbb4e210..f28c779bd 100644 --- a/iguana/exchanges/LP_ordermatch.c +++ b/iguana/exchanges/LP_ordermatch.c @@ -126,7 +126,7 @@ double LP_quote_validate(struct LP_utxoinfo *autxo,struct LP_utxoinfo *butxo,str { if ( LP_iseligible(&srcvalue,&srcvalue2,1,qp->srccoin,qp->txid,qp->vout,qp->satoshis,qp->txid2,qp->vout2) == 0 ) { - printf("bob not eligible %s (%.8f %.8f)\n",jprint(LP_quotejson(qp),1),dstr(srcvalue),dstr(srcvalue2)); + //printf("bob not eligible %s (%.8f %.8f)\n",jprint(LP_quotejson(qp),1),dstr(srcvalue),dstr(srcvalue2)); return(-2); } if ( (txout= LP_gettxout(qp->srccoin,qp->coinaddr,qp->txid,qp->vout)) != 0 ) @@ -159,7 +159,7 @@ double LP_quote_validate(struct LP_utxoinfo *autxo,struct LP_utxoinfo *butxo,str if ( LP_iseligible(&destvalue,&destvalue2,0,qp->destcoin,qp->desttxid,qp->destvout,qp->destsatoshis,qp->feetxid,qp->feevout) == 0 ) { //alice not eligible 0.36893923 -> dest 0.55020000 1.49130251 (0.61732249 0.00104324) 14b8b74808d2d34a70e5eddd1cad47d855858f8b23cac802576d4d37b5f8af8f/v1 abec6e76169bcb738235ca67fab02cc55390f39e422aa71f1badf8747c290cc4/v1 - char str[65],str2[65]; printf("alice not eligible %.8f -> dest %.8f %.8f (%.8f %.8f) %s/v%d %s/v%d\n",dstr(qp->satoshis),dstr(qp->destsatoshis),(double)qp->destsatoshis/qp->satoshis,dstr(destvalue),dstr(destvalue2),bits256_str(str,qp->desttxid),qp->destvout,bits256_str(str2,qp->feetxid),qp->feevout); + //char str[65],str2[65]; printf("alice not eligible %.8f -> dest %.8f %.8f (%.8f %.8f) %s/v%d %s/v%d\n",dstr(qp->satoshis),dstr(qp->destsatoshis),(double)qp->destsatoshis/qp->satoshis,dstr(destvalue),dstr(destvalue2),bits256_str(str,qp->desttxid),qp->destvout,bits256_str(str2,qp->feetxid),qp->feevout); return(-3); } if ( (txout= LP_gettxout(qp->destcoin,qp->destaddr,qp->desttxid,qp->destvout)) != 0 ) @@ -321,7 +321,7 @@ int32_t LP_nearest_utxovalue(struct iguana_info *coin,char *coinaddr,struct LP_a } if ( replacei >= 0 ) { - printf("REPLACE bestdist %.8f height %d with dist %.8f height %d\n",dstr(bestdist),bestup->U.height,dstr(utxos[replacei]->U.value - targetval),utxos[replacei]->U.height); + //printf("REPLACE bestdist %.8f height %d with dist %.8f height %d\n",dstr(bestdist),bestup->U.height,dstr(utxos[replacei]->U.value - targetval),utxos[replacei]->U.height); return(replacei); } } @@ -396,7 +396,7 @@ struct LP_utxoinfo *LP_address_myutxopair(struct LP_utxoinfo *butxo,int32_t iamb { if ( (m= LP_address_utxo_ptrs(coin,iambob,utxos,max,ap,coinaddr)) > 1 ) { - if ( 1 ) + if ( 0 ) { int32_t i; for (i=0; i Date: Thu, 16 Nov 2017 17:32:03 +0200 Subject: [PATCH 0939/1664] Test --- iguana/exchanges/LP_include.h | 2 +- iguana/exchanges/LP_utxo.c | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/iguana/exchanges/LP_include.h b/iguana/exchanges/LP_include.h index 72f99d81f..7ccde2a10 100644 --- a/iguana/exchanges/LP_include.h +++ b/iguana/exchanges/LP_include.h @@ -23,7 +23,7 @@ #define LP_MAJOR_VERSION "0" #define LP_MINOR_VERSION "1" -#define LP_BUILD_NUMBER "15000" +#define LP_BUILD_NUMBER "15096" #ifdef FROM_JS #include diff --git a/iguana/exchanges/LP_utxo.c b/iguana/exchanges/LP_utxo.c index 59b8b8b8e..90a6d016e 100644 --- a/iguana/exchanges/LP_utxo.c +++ b/iguana/exchanges/LP_utxo.c @@ -999,7 +999,7 @@ int32_t LP_iseligible(uint64_t *valp,uint64_t *val2p,int32_t iambob,char *symbol strcpy(destaddr,destaddr2); if ( coin != 0 ) { - if ( coin->electrum != 0 ) + /*if ( coin->electrum != 0 ) { if ( (tx= LP_transactionfind(coin,txid)) != 0 && vout < tx->numvouts && tx->outpoints[vout].spendheight > 0 ) { @@ -1022,7 +1022,7 @@ int32_t LP_iseligible(uint64_t *valp,uint64_t *val2p,int32_t iambob,char *symbol return(0); } } - else + else*/ { if ( (txobj= LP_gettxout(coin->symbol,destaddr,txid,vout)) == 0 ) return(0); From 4b8b1553227da5c9cd0a4827a4c5134185c6e98a Mon Sep 17 00:00:00 2001 From: jl777 Date: Thu, 16 Nov 2017 17:48:46 +0200 Subject: [PATCH 0940/1664] Test --- iguana/exchanges/LP_ordermatch.c | 1 + 1 file changed, 1 insertion(+) diff --git a/iguana/exchanges/LP_ordermatch.c b/iguana/exchanges/LP_ordermatch.c index f28c779bd..0d1590bfc 100644 --- a/iguana/exchanges/LP_ordermatch.c +++ b/iguana/exchanges/LP_ordermatch.c @@ -1126,6 +1126,7 @@ char *LP_autobuy(void *ctx,char *myipaddr,int32_t mypubsock,char *base,char *rel memset(pubkeys,0,sizeof(pubkeys)); LP_txfees(&txfee,&desttxfee,base,rel); destsatoshis = SATOSHIDEN * relvolume; + LP_address_utxo_reset(relcoin); if ( (autxo= LP_utxo_bestfit(rel,destsatoshis + 2*desttxfee)) == 0 ) return(clonestr("{\"error\":\"cant find alice utxo that is big enough\"}")); //printf("bestfit selected alice (%.8f %.8f) for %.8f sats %.8f\n",dstr(autxo->payment.value),dstr(autxo->fee.value),dstr(destsatoshis),dstr(autxo->S.satoshis)); From 5c15665ca64091e9ec5e30f4836a6e79c73bb98f Mon Sep 17 00:00:00 2001 From: jl777 Date: Thu, 16 Nov 2017 17:56:47 +0200 Subject: [PATCH 0941/1664] Test --- iguana/exchanges/LP_signatures.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/iguana/exchanges/LP_signatures.c b/iguana/exchanges/LP_signatures.c index 0008ee1b5..e729421ad 100644 --- a/iguana/exchanges/LP_signatures.c +++ b/iguana/exchanges/LP_signatures.c @@ -704,7 +704,7 @@ void LP_query(void *ctx,char *myipaddr,int32_t mypubsock,char *method,struct LP_ jaddnum(reqjson,"timestamp",time(NULL)); msg = jprint(reqjson,1); msg2 = clonestr(msg); - //printf("QUERY.(%s)\n",msg); + printf("QUERY.(%s)\n",msg); memset(&zero,0,sizeof(zero)); portable_mutex_lock(&LP_reservedmutex); if ( num_Reserved_msgs[1] < sizeof(Reserved_msgs[1])/sizeof(*Reserved_msgs[1])-2 ) From 380c7d0ec24d71c982074dd8b11f16860df77f8c Mon Sep 17 00:00:00 2001 From: jl777 Date: Thu, 16 Nov 2017 18:01:04 +0200 Subject: [PATCH 0942/1664] Test --- iguana/exchanges/LP_utxo.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/iguana/exchanges/LP_utxo.c b/iguana/exchanges/LP_utxo.c index 90a6d016e..21e89c92a 100644 --- a/iguana/exchanges/LP_utxo.c +++ b/iguana/exchanges/LP_utxo.c @@ -405,7 +405,7 @@ int32_t LP_address_utxoadd(uint32_t timestamp,char *debug,struct iguana_info *co up->SPV = tx->SPV; } char str[65]; - if ( 0 && strcmp(coin->smartaddr,coinaddr) == 0 && strcmp("KMD",coin->symbol) == 0 ) + if ( strcmp(coin->smartaddr,coinaddr) == 0 && strcmp("KMD",coin->symbol) == 0 ) printf("%s ADD UTXO >> %s %s %s/v%d ht.%d %.8f\n",debug,coin->symbol,coinaddr,bits256_str(str,txid),vout,height,dstr(value)); portable_mutex_lock(&coin->addrmutex); DL_APPEND(ap->utxos,up); @@ -464,7 +464,7 @@ struct LP_address *LP_address_utxo_reset(struct iguana_info *coin) if ( (up= LP_address_utxofind(coin,coin->smartaddr,txid,vout)) == 0 ) printf("couldnt find just added %s/%d ht.%d %.8f\n",bits256_str(str,txid),vout,height,dstr(value)); } - //printf("added %d from listunspents\n",n); + printf("added %d from listunspents\n",n); } free_json(array); } From 6c24e6c05656cbb5e112906f9d7c3fc2ea0f2592 Mon Sep 17 00:00:00 2001 From: jl777 Date: Thu, 16 Nov 2017 18:06:18 +0200 Subject: [PATCH 0943/1664] Test --- iguana/exchanges/LP_ordermatch.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/iguana/exchanges/LP_ordermatch.c b/iguana/exchanges/LP_ordermatch.c index 0d1590bfc..48fea4b1f 100644 --- a/iguana/exchanges/LP_ordermatch.c +++ b/iguana/exchanges/LP_ordermatch.c @@ -791,6 +791,7 @@ int32_t LP_tradecommand(void *ctx,char *myipaddr,int32_t pubsock,cJSON *argjson, } if ( bits256_cmp(G.LP_mypub25519,Q.desthash) == 0 && bits256_cmp(G.LP_mypub25519,Q.srchash) != 0 && LP_alice_eligible() > 0 ) { + printf("alice %s received RESERVED.(%s)\n",bits256_str(str,G.LP_mypub25519),jprint(argjson,0)); if ( (qprice= LP_quote_validate(autxo,butxo,&Q,0)) <= SMALLVAL ) { printf("reserved quote validate error %.0f\n",qprice); @@ -807,7 +808,6 @@ int32_t LP_tradecommand(void *ctx,char *myipaddr,int32_t pubsock,cJSON *argjson, return(retval); } LP_aliceid(Q.tradeid,Q.aliceid,"reserved",0,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); From da4fe5720ad21b6b4abc89da7fcc04773524f782 Mon Sep 17 00:00:00 2001 From: jl777 Date: Thu, 16 Nov 2017 18:12:07 +0200 Subject: [PATCH 0944/1664] Test --- iguana/exchanges/LP_ordermatch.c | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/iguana/exchanges/LP_ordermatch.c b/iguana/exchanges/LP_ordermatch.c index 48fea4b1f..c00ef313a 100644 --- a/iguana/exchanges/LP_ordermatch.c +++ b/iguana/exchanges/LP_ordermatch.c @@ -532,9 +532,9 @@ void LP_alicequery_clear() Alice_expiration = 0; } -int32_t LP_alice_eligible() +int32_t LP_alice_eligible(uint32_t quotetime) { - if ( Alice_expiration != 0 && time(NULL) > Alice_expiration ) + if ( Alice_expiration != 0 && quotetime > Alice_expiration ) { printf("time expired for Alice_request\n"); LP_alicequery_clear(); @@ -545,7 +545,7 @@ int32_t LP_alice_eligible() void LP_reserved(void *ctx,char *myipaddr,int32_t mypubsock,struct LP_quoteinfo *qp) { double price=0.,maxprice = LP_Alicemaxprice; - if ( LP_alice_eligible() > 0 && LP_quotecmp(qp,&LP_Alicequery) == 0 ) + 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 ) @@ -555,7 +555,7 @@ void LP_reserved(void *ctx,char *myipaddr,int32_t mypubsock,struct LP_quoteinfo printf("send CONNECT\n"); LP_query(ctx,myipaddr,mypubsock,"connect",qp); } else printf("LP_reserved price %.8f vs maxprice %.8f\n",price,maxprice*1.005); - } else printf("probably a timeout, reject reserved due to not eligible.%d or mismatched quote price %.8f vs maxprice %.8f\n",LP_alice_eligible(),price,maxprice); + } else printf("probably a timeout, reject reserved due to not eligible.%d or mismatched quote price %.8f vs maxprice %.8f\n",LP_alice_eligible(qp->quotetime),price,maxprice); } char *LP_connectedalice(cJSON *argjson) // alice @@ -789,7 +789,7 @@ int32_t LP_tradecommand(void *ctx,char *myipaddr,int32_t pubsock,cJSON *argjson, return(retval); } else printf("got reserved response from destpubkey %s\n",bits256_str(str,Q.srchash)); } - if ( bits256_cmp(G.LP_mypub25519,Q.desthash) == 0 && bits256_cmp(G.LP_mypub25519,Q.srchash) != 0 && LP_alice_eligible() > 0 ) + if ( bits256_cmp(G.LP_mypub25519,Q.desthash) == 0 && bits256_cmp(G.LP_mypub25519,Q.srchash) != 0 && Q.quotetime > time(NULL)-20 && LP_alice_eligible(Q.quotetime) > 0 ) { printf("alice %s received RESERVED.(%s)\n",bits256_str(str,G.LP_mypub25519),jprint(argjson,0)); if ( (qprice= LP_quote_validate(autxo,butxo,&Q,0)) <= SMALLVAL ) From dc259fe34f9894d027d37d346ead41597beaa8ed Mon Sep 17 00:00:00 2001 From: jl777 Date: Thu, 16 Nov 2017 18:13:25 +0200 Subject: [PATCH 0945/1664] Test --- iguana/exchanges/LP_utxo.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/iguana/exchanges/LP_utxo.c b/iguana/exchanges/LP_utxo.c index 21e89c92a..e9ff90d3a 100644 --- a/iguana/exchanges/LP_utxo.c +++ b/iguana/exchanges/LP_utxo.c @@ -405,7 +405,7 @@ int32_t LP_address_utxoadd(uint32_t timestamp,char *debug,struct iguana_info *co up->SPV = tx->SPV; } char str[65]; - if ( strcmp(coin->smartaddr,coinaddr) == 0 && strcmp("KMD",coin->symbol) == 0 ) + if ( 0 && strcmp(coin->smartaddr,coinaddr) == 0 && strcmp("KMD",coin->symbol) == 0 ) printf("%s ADD UTXO >> %s %s %s/v%d ht.%d %.8f\n",debug,coin->symbol,coinaddr,bits256_str(str,txid),vout,height,dstr(value)); portable_mutex_lock(&coin->addrmutex); DL_APPEND(ap->utxos,up); From 77ffa9bfaa3b64cce3abaefc7fe79da8617cea1c Mon Sep 17 00:00:00 2001 From: jl777 Date: Thu, 16 Nov 2017 18:22:41 +0200 Subject: [PATCH 0946/1664] Test --- crypto777/cJSON.c | 4 ++-- iguana/exchanges/LP_nativeDEX.c | 6 +++--- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/crypto777/cJSON.c b/crypto777/cJSON.c index 901e6fc98..54df964f5 100755 --- a/crypto777/cJSON.c +++ b/crypto777/cJSON.c @@ -56,8 +56,8 @@ static int32_t cJSON_strcasecmp(const char *s1,const char *s2) void *LP_alloc(uint64_t len); void LP_free(void *ptr); -static void *(*cJSON_malloc)(size_t sz) = (void *)LP_alloc; -static void (*cJSON_free)(void *ptr) = LP_free; +static void *(*cJSON_malloc)(size_t sz) = (void *)malloc;//LP_alloc; +static void (*cJSON_free)(void *ptr) = free;//LP_free; static void *cJSON_mallocstr(int32_t len) { diff --git a/iguana/exchanges/LP_nativeDEX.c b/iguana/exchanges/LP_nativeDEX.c index 30e1d9753..f73c9474f 100644 --- a/iguana/exchanges/LP_nativeDEX.c +++ b/iguana/exchanges/LP_nativeDEX.c @@ -1043,7 +1043,7 @@ void LPinit(uint16_t myport,uint16_t mypullport,uint16_t mypubport,uint16_t mybu printf("error launching LP_reserved_msgs for (%s)\n",myipaddr); exit(-1); } - if ( 0 && OS_thread_create(malloc(sizeof(pthread_t)),NULL,(void *)utxosQ_loop,(void *)myipaddr) != 0 ) + if ( OS_thread_create(malloc(sizeof(pthread_t)),NULL,(void *)utxosQ_loop,(void *)myipaddr) != 0 ) { printf("error launching utxosQ_loop for (%s)\n",myipaddr); exit(-1); @@ -1216,7 +1216,7 @@ int32_t zeroval() { return(0); } void *LP_alloc(uint64_t len) { -return(calloc(1,len)); +//return(calloc(1,len)); LP_cjson_allocated += len; LP_cjson_total += len; LP_cjson_count++; @@ -1235,7 +1235,7 @@ return(calloc(1,len)); void LP_free(void *ptr) { static uint32_t lasttime,unknown; static int64_t lasttotal; -free(ptr); return; +//free(ptr); return; uint32_t now; char str[65]; int32_t n,lagging; uint64_t total = 0; struct LP_memory_list *mp,*tmp; if ( (now= (uint32_t)time(NULL)) > lasttime+1 ) { From 5d0933752975bcc44ae8297761e755b57247bcfd Mon Sep 17 00:00:00 2001 From: jl777 Date: Thu, 16 Nov 2017 18:28:46 +0200 Subject: [PATCH 0947/1664] Test --- iguana/exchanges/LP_ordermatch.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/iguana/exchanges/LP_ordermatch.c b/iguana/exchanges/LP_ordermatch.c index c00ef313a..fb294d2dc 100644 --- a/iguana/exchanges/LP_ordermatch.c +++ b/iguana/exchanges/LP_ordermatch.c @@ -505,7 +505,7 @@ char *LP_trade(void *ctx,char *myipaddr,int32_t mypubsock,struct LP_quoteinfo *q qp->tradeid = tradeid; LP_query(ctx,myipaddr,mypubsock,"request",qp); LP_Alicequery = *qp, LP_Alicemaxprice = maxprice, Alice_expiration = qp->timestamp + timeout, LP_Alicedestpubkey = destpubkey; - char str[65]; printf("LP_trade %s/%s %.8f vol %.8f dest.(%s)\n",qp->srccoin,qp->destcoin,dstr(qp->satoshis),dstr(qp->destsatoshis),bits256_str(str,LP_Alicedestpubkey)); + char str[65]; printf("LP_trade %s/%s %.8f vol %.8f dest.(%s) maxprice %.8f\n",qp->srccoin,qp->destcoin,dstr(qp->satoshis),dstr(qp->destsatoshis),bits256_str(str,LP_Alicedestpubkey),maxprice); return(LP_recent_swaps(0)); } @@ -778,7 +778,7 @@ int32_t LP_tradecommand(void *ctx,char *myipaddr,int32_t pubsock,cJSON *argjson, if ( strcmp(method,"reserved") == 0 ) { bestprice = LP_bob_competition(&counter,aliceid,qprice,1); - //printf("aliceid.%llu price %.8f -> bestprice %.8f\n",(long long)aliceid,qprice,bestprice); + printf("aliceid.%llu price %.8f -> bestprice %.8f Alice max %.8f\n",(long long)aliceid,qprice,bestprice,LP_Alicemaxprice); if ( LP_Alicemaxprice == 0. ) return(retval); if ( bits256_nonz(LP_Alicedestpubkey) != 0 ) From d00e0b0e8be5264babf39084d0cc165efc74f799 Mon Sep 17 00:00:00 2001 From: jl777 Date: Thu, 16 Nov 2017 18:32:07 +0200 Subject: [PATCH 0948/1664] Test --- iguana/exchanges/LP_ordermatch.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/iguana/exchanges/LP_ordermatch.c b/iguana/exchanges/LP_ordermatch.c index fb294d2dc..a8d8f98c8 100644 --- a/iguana/exchanges/LP_ordermatch.c +++ b/iguana/exchanges/LP_ordermatch.c @@ -778,7 +778,7 @@ int32_t LP_tradecommand(void *ctx,char *myipaddr,int32_t pubsock,cJSON *argjson, if ( strcmp(method,"reserved") == 0 ) { bestprice = LP_bob_competition(&counter,aliceid,qprice,1); - printf("aliceid.%llu price %.8f -> bestprice %.8f Alice max %.8f\n",(long long)aliceid,qprice,bestprice,LP_Alicemaxprice); + printf("%s lag %ld: aliceid.%llu price %.8f -> bestprice %.8f Alice max %.8f\n",jprint(argjson,0),Q.quotetime - (time(NULL)-20),(long long)aliceid,qprice,bestprice,LP_Alicemaxprice); if ( LP_Alicemaxprice == 0. ) return(retval); if ( bits256_nonz(LP_Alicedestpubkey) != 0 ) From f3794fe375cff809f3d251e5546b4e875886aaa3 Mon Sep 17 00:00:00 2001 From: jl777 Date: Thu, 16 Nov 2017 18:34:14 +0200 Subject: [PATCH 0949/1664] Test --- iguana/exchanges/LP_ordermatch.c | 1 + 1 file changed, 1 insertion(+) diff --git a/iguana/exchanges/LP_ordermatch.c b/iguana/exchanges/LP_ordermatch.c index a8d8f98c8..0927b5222 100644 --- a/iguana/exchanges/LP_ordermatch.c +++ b/iguana/exchanges/LP_ordermatch.c @@ -904,6 +904,7 @@ int32_t LP_tradecommand(void *ctx,char *myipaddr,int32_t pubsock,cJSON *argjson, Q.txid2 = butxo->deposit.txid; Q.vout2 = butxo->deposit.vout; Q.satoshis = butxo->S.satoshis; + Q.quotetime = (uint32_t)time(NULL); printf("found %.8f -> %.8f newprice %.8f vs ask %.8f += %.8f qprice %.8f\n",dstr(Q.satoshis),dstr(Q.destsatoshis),(double)Q.destsatoshis/Q.satoshis,ask,price,qprice); } else From 271ef52511e436f219dc12b0a53a3c3ad2d1252c Mon Sep 17 00:00:00 2001 From: jl777 Date: Thu, 16 Nov 2017 18:34:41 +0200 Subject: [PATCH 0950/1664] Test --- iguana/exchanges/LP_include.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/iguana/exchanges/LP_include.h b/iguana/exchanges/LP_include.h index 7ccde2a10..e1a8c933d 100644 --- a/iguana/exchanges/LP_include.h +++ b/iguana/exchanges/LP_include.h @@ -24,6 +24,8 @@ #define LP_MAJOR_VERSION "0" #define LP_MINOR_VERSION "1" #define LP_BUILD_NUMBER "15096" +#define LP_BARTERDEX_VERSION 2 +#define LP_MAGICBITS 8 #ifdef FROM_JS #include @@ -38,8 +40,6 @@ void emscripten_usleep(int32_t x); // returns immediate, no sense for sleeping #endif //#define LP_STRICTPEERS -#define LP_BARTERDEX_VERSION 1 -#define LP_MAGICBITS 8 #define LP_MAXVINS 64 #define LP_HTTP_TIMEOUT 3 // 1 is too small due to edge cases of time(NULL) From 367b9b0dfa37cdae981204509bfd666f3183c8df Mon Sep 17 00:00:00 2001 From: jl777 Date: Thu, 16 Nov 2017 18:35:21 +0200 Subject: [PATCH 0951/1664] Test --- iguana/exchanges/LP_include.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/iguana/exchanges/LP_include.h b/iguana/exchanges/LP_include.h index e1a8c933d..c728dee1f 100644 --- a/iguana/exchanges/LP_include.h +++ b/iguana/exchanges/LP_include.h @@ -180,7 +180,7 @@ struct basilisk_request int64_t srcamount,unused; // 16 to 31 bits256 srchash; // 32 to 63 bits256 desthash; - char src[65],dest[65]; + char src[68],dest[68]; uint64_t destamount; int32_t optionhours,DEXselector; }; From 05e76ee08b8547895ed5e54a5a8cf626c461101e Mon Sep 17 00:00:00 2001 From: jl777 Date: Thu, 16 Nov 2017 18:36:55 +0200 Subject: [PATCH 0952/1664] Test --- iguana/exchanges/LP_network.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/iguana/exchanges/LP_network.c b/iguana/exchanges/LP_network.c index d1b147bc8..5449dc7d7 100644 --- a/iguana/exchanges/LP_network.c +++ b/iguana/exchanges/LP_network.c @@ -204,8 +204,8 @@ int32_t LP_magic_check(uint8_t *msg,int32_t recvlen,char *remoteaddr) vcalc_sha256(0,hash.bytes,msg,recvlen); memcpy(magic.bytes,&msg[recvlen],sizeof(magic)); val = _LP_magic_check(hash,magic); - if ( val != LP_BARTERDEX_VERSION ) - printf("magicval = %x from %s\n",val,remoteaddr); + //if ( val != LP_BARTERDEX_VERSION ) + // printf("magicval = %x from %s\n",val,remoteaddr); return(val == LP_BARTERDEX_VERSION); } return(-1); From ff2c4f62256a7526086ee4b225fb8984687aff21 Mon Sep 17 00:00:00 2001 From: jl777 Date: Thu, 16 Nov 2017 18:41:38 +0200 Subject: [PATCH 0953/1664] Test --- iguana/exchanges/LP_include.h | 2 +- iguana/exchanges/LP_network.c | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/iguana/exchanges/LP_include.h b/iguana/exchanges/LP_include.h index c728dee1f..f66fcc9c1 100644 --- a/iguana/exchanges/LP_include.h +++ b/iguana/exchanges/LP_include.h @@ -24,7 +24,7 @@ #define LP_MAJOR_VERSION "0" #define LP_MINOR_VERSION "1" #define LP_BUILD_NUMBER "15096" -#define LP_BARTERDEX_VERSION 2 +#define LP_BARTERDEX_VERSION 1 #define LP_MAGICBITS 8 #ifdef FROM_JS diff --git a/iguana/exchanges/LP_network.c b/iguana/exchanges/LP_network.c index 5449dc7d7..d1b147bc8 100644 --- a/iguana/exchanges/LP_network.c +++ b/iguana/exchanges/LP_network.c @@ -204,8 +204,8 @@ int32_t LP_magic_check(uint8_t *msg,int32_t recvlen,char *remoteaddr) vcalc_sha256(0,hash.bytes,msg,recvlen); memcpy(magic.bytes,&msg[recvlen],sizeof(magic)); val = _LP_magic_check(hash,magic); - //if ( val != LP_BARTERDEX_VERSION ) - // printf("magicval = %x from %s\n",val,remoteaddr); + if ( val != LP_BARTERDEX_VERSION ) + printf("magicval = %x from %s\n",val,remoteaddr); return(val == LP_BARTERDEX_VERSION); } return(-1); From 070cc756eccb63a296fc4fa14d88eeab2a6b3cd7 Mon Sep 17 00:00:00 2001 From: jl777 Date: Thu, 16 Nov 2017 18:55:33 +0200 Subject: [PATCH 0954/1664] Test --- iguana/exchanges/LP_ordermatch.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/iguana/exchanges/LP_ordermatch.c b/iguana/exchanges/LP_ordermatch.c index 0927b5222..6ae82acf0 100644 --- a/iguana/exchanges/LP_ordermatch.c +++ b/iguana/exchanges/LP_ordermatch.c @@ -778,7 +778,7 @@ int32_t LP_tradecommand(void *ctx,char *myipaddr,int32_t pubsock,cJSON *argjson, if ( strcmp(method,"reserved") == 0 ) { bestprice = LP_bob_competition(&counter,aliceid,qprice,1); - printf("%s lag %ld: aliceid.%llu price %.8f -> bestprice %.8f Alice max %.8f\n",jprint(argjson,0),Q.quotetime - (time(NULL)-20),(long long)aliceid,qprice,bestprice,LP_Alicemaxprice); + //printf("%s lag %ld: aliceid.%llu price %.8f -> bestprice %.8f Alice max %.8f\n",jprint(argjson,0),Q.quotetime - (time(NULL)-20),(long long)aliceid,qprice,bestprice,LP_Alicemaxprice); if ( LP_Alicemaxprice == 0. ) return(retval); if ( bits256_nonz(LP_Alicedestpubkey) != 0 ) @@ -948,9 +948,11 @@ int32_t LP_tradecommand(void *ctx,char *myipaddr,int32_t pubsock,cJSON *argjson, retjson = LP_quotejson(&Q); LP_unavailableset(Q.txid,Q.vout,Q.timestamp + LP_RESERVETIME,Q.desthash); LP_unavailableset(Q.txid2,Q.vout2,Q.timestamp + LP_RESERVETIME,Q.desthash); + if ( Q.quotetime == 0 ) + Q.quotetime = (uint32_t)time(NULL); jaddnum(retjson,"quotetime",Q.quotetime); jaddnum(retjson,"pending",Q.timestamp + LP_RESERVETIME); - jaddbits256(retjson,"desthash",Q.desthash); + //jaddbits256(retjson,"desthash",Q.desthash); jaddstr(retjson,"method","reserved"); msg = jprint(retjson,0); printf("return after queued RESERVED: set swappending.%u accept qprice %.8f, min %.8f\n(%s)\n",Q.timestamp + LP_RESERVETIME,qprice,ask,msg); From eb3d5667eded61cd05aa66b33c24791680549a3a Mon Sep 17 00:00:00 2001 From: jl777 Date: Thu, 16 Nov 2017 19:03:47 +0200 Subject: [PATCH 0955/1664] Test --- iguana/exchanges/LP_ordermatch.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/iguana/exchanges/LP_ordermatch.c b/iguana/exchanges/LP_ordermatch.c index 6ae82acf0..435e32cb1 100644 --- a/iguana/exchanges/LP_ordermatch.c +++ b/iguana/exchanges/LP_ordermatch.c @@ -502,7 +502,8 @@ char *LP_trade(void *ctx,char *myipaddr,int32_t mypubsock,struct LP_quoteinfo *q memset(qp->txid.bytes,0,sizeof(qp->txid)); qp->txid2 = qp->txid; qp->aliceid = LP_aliceid_calc(qp->desttxid,qp->destvout,qp->feetxid,qp->feevout); - qp->tradeid = tradeid; + if ( (qp->tradeid= tradeid) == 0 ) + qp->tradeid = LP_rand(); LP_query(ctx,myipaddr,mypubsock,"request",qp); LP_Alicequery = *qp, LP_Alicemaxprice = maxprice, Alice_expiration = qp->timestamp + timeout, LP_Alicedestpubkey = destpubkey; char str[65]; printf("LP_trade %s/%s %.8f vol %.8f dest.(%s) maxprice %.8f\n",qp->srccoin,qp->destcoin,dstr(qp->satoshis),dstr(qp->destsatoshis),bits256_str(str,LP_Alicedestpubkey),maxprice); From 1b9d12dd71075c0e859a609edf9aeb9b4d89705f Mon Sep 17 00:00:00 2001 From: jl777 Date: Thu, 16 Nov 2017 19:40:03 +0200 Subject: [PATCH 0956/1664] Test --- iguana/exchanges/LP_ordermatch.c | 32 +++++++++++++++++++------------- iguana/exchanges/LP_tradebots.c | 2 +- iguana/exchanges/LP_utxo.c | 2 +- 3 files changed, 21 insertions(+), 15 deletions(-) diff --git a/iguana/exchanges/LP_ordermatch.c b/iguana/exchanges/LP_ordermatch.c index 435e32cb1..60de857a8 100644 --- a/iguana/exchanges/LP_ordermatch.c +++ b/iguana/exchanges/LP_ordermatch.c @@ -18,7 +18,7 @@ // LP_ordermatch.c // marketmaker // -struct LP_quoteinfo LP_Alicequery; +struct LP_quoteinfo LP_Alicequery,LP_Alicereserved; double LP_Alicemaxprice; bits256 LP_Alicedestpubkey; uint32_t Alice_expiration; @@ -510,7 +510,7 @@ char *LP_trade(void *ctx,char *myipaddr,int32_t mypubsock,struct LP_quoteinfo *q return(LP_recent_swaps(0)); } -int32_t LP_quotecmp(struct LP_quoteinfo *qp,struct LP_quoteinfo *qp2) +int32_t LP_quotecmp(int32_t strictflag,struct LP_quoteinfo *qp,struct LP_quoteinfo *qp2) { if ( bits256_nonz(LP_Alicedestpubkey) != 0 ) { @@ -520,9 +520,13 @@ int32_t LP_quotecmp(struct LP_quoteinfo *qp,struct LP_quoteinfo *qp2) return(-1); } else printf("dont reject quote from destpubkey\n"); } - if ( 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 ) //bits256_cmp(qp->srchash,qp2->srchash) == 0 && - return(0); - else return(-1); + if ( 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 ) + { + if ( strictflag == 0 || (qp->aliceid == qp2->aliceid && qp->R.requestid == qp2->R.requestid && qp->R.quoteid == qp2->R.quoteid && qp->vout == qp2->vout && qp->vout2 == qp2->vout2 && qp->satoshis == qp2->satoshis && bits256_cmp(qp->txid,qp2->txid) == 0 && bits256_cmp(qp->txid2,qp2->txid2) == 0 && bits256_cmp(qp->srchash,qp2->srchash) == 0) ) + return(0); + else printf("strict compare failure\n"); + } + return(-1); } void LP_alicequery_clear() @@ -546,12 +550,13 @@ int32_t LP_alice_eligible(uint32_t quotetime) void LP_reserved(void *ctx,char *myipaddr,int32_t mypubsock,struct LP_quoteinfo *qp) { double price=0.,maxprice = LP_Alicemaxprice; - if ( LP_quotecmp(qp,&LP_Alicequery) == 0 ) + if ( LP_quotecmp(0,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 ) { qp->tradeid = LP_Alicequery.tradeid; + LP_Alicereserved = *qp; LP_alicequery_clear(); printf("send CONNECT\n"); LP_query(ctx,myipaddr,mypubsock,"connect",qp); @@ -561,7 +566,7 @@ void LP_reserved(void *ctx,char *myipaddr,int32_t mypubsock,struct LP_quoteinfo char *LP_connectedalice(cJSON *argjson) // alice { - cJSON *retjson; double bid,ask,price,qprice; int32_t pairsock = -1; char *pairstr; int32_t DEXselector = 0; struct LP_utxoinfo *autxo,B,*butxo; struct LP_quoteinfo Q; struct basilisk_swap *swap; struct iguana_info *coin; //uint64_t value,value2; + cJSON *retjson; double bid,ask,price,qprice; int32_t pairsock = -1; char *pairstr; int32_t DEXselector = 0; struct LP_utxoinfo *autxo,A,B,*butxo; struct LP_quoteinfo Q; struct basilisk_swap *swap; struct iguana_info *coin; if ( LP_quoteparse(&Q,argjson) < 0 ) { LP_aliceid(Q.tradeid,Q.aliceid,"error0",0,0); @@ -572,7 +577,7 @@ char *LP_connectedalice(cJSON *argjson) // alice LP_aliceid(Q.tradeid,Q.aliceid,"error1",0,0); return(clonestr("{\"result\",\"update stats\"}")); } - printf("CONNECTED.(%s) numpending.%d tradeid.%u requestid.%u quoteid.%u\n",jprint(argjson,0),G.LP_pendingswaps,Q.tradeid,Q.R.requestid,Q.R.quoteid); + printf("CONNECTED.(%s) numpending.%d tradeid.%u requestid.%u quoteid.%u\n",jprint(argjson,0),G.LP_pendingswaps,Q.tradeid,Q.R.requestid,Q.R.quoteid); LP_requestinit(&Q.R,Q.srchash,Q.desthash,Q.srccoin,Q.satoshis-Q.txfee,Q.destcoin,Q.destsatoshis-Q.desttxfee,Q.timestamp,Q.quotetime,DEXselector); printf("calculated requestid.%u quoteid.%u\n",Q.R.requestid,Q.R.quoteid); if ( LP_pendingswap(Q.R.requestid,Q.R.quoteid) > 0 ) @@ -582,16 +587,17 @@ char *LP_connectedalice(cJSON *argjson) // alice jaddstr(retjson,"error","swap already in progress"); return(jprint(retjson,1)); } - if ( (autxo= LP_utxopairfind(0,Q.desttxid,Q.destvout,Q.feetxid,Q.feevout)) == 0 ) + if ( LP_quotecmp(1,&Q,&LP_Alicereserved) == 0 ) { - printf("cant find autxo\n"); - LP_aliceid(Q.tradeid,Q.aliceid,"error2",0,0); - return(clonestr("{\"error\":\"cant find autxo\"}")); + printf("mismatched between reserved and connected\n"); } + memset(&LP_Alicereserved,0,sizeof(LP_Alicereserved)); LP_aliceid(Q.tradeid,Q.aliceid,"connected",Q.R.requestid,Q.R.quoteid); + autxo = &A; butxo = &B; + memset(autxo,0,sizeof(*autxo)); memset(butxo,0,sizeof(*butxo)); - LP_abutxo_set(0,butxo,&Q); + LP_abutxo_set(autxo,butxo,&Q); if ( (qprice= LP_quote_validate(autxo,butxo,&Q,0)) <= SMALLVAL ) { LP_availableset(Q.desttxid,Q.vout); diff --git a/iguana/exchanges/LP_tradebots.c b/iguana/exchanges/LP_tradebots.c index ec00553e4..d4a2fdfd5 100644 --- a/iguana/exchanges/LP_tradebots.c +++ b/iguana/exchanges/LP_tradebots.c @@ -386,7 +386,7 @@ void LP_aliceid(uint32_t tradeid,uint64_t aliceid,char *event,uint32_t requestid if ( matched != 0 ) break; } - if ( matched == 0 ) + if ( 0 && matched == 0 ) printf("NO MATCH: bot event tradeid.%u aliceid.%llu (%s) r.%u q.%u\n",tradeid,(long long)aliceid,event,requestid,quoteid); } diff --git a/iguana/exchanges/LP_utxo.c b/iguana/exchanges/LP_utxo.c index e9ff90d3a..8ea1d2db5 100644 --- a/iguana/exchanges/LP_utxo.c +++ b/iguana/exchanges/LP_utxo.c @@ -966,7 +966,7 @@ uint64_t LP_txvalue(char *coinaddr,char *symbol,bits256 txid,int32_t vout) 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) { - uint64_t val,val2=0,txfee,threshold=0; cJSON *txobj; int32_t bypass = 0; char destaddr[64],destaddr2[64]; struct LP_transaction *tx; struct LP_address_utxo *up; struct iguana_info *coin = LP_coinfind(symbol); + uint64_t val,val2=0,txfee,threshold=0; cJSON *txobj; int32_t bypass = 0; char destaddr[64],destaddr2[64]; struct iguana_info *coin = LP_coinfind(symbol); if ( bits256_nonz(txid) == 0 || bits256_nonz(txid2) == 0 ) { printf("null txid not eligible\n"); From 3174532f3c380659a5e09599ba8244fd738b7bff Mon Sep 17 00:00:00 2001 From: jl777 Date: Thu, 16 Nov 2017 20:08:36 +0200 Subject: [PATCH 0957/1664] Test --- iguana/exchanges/LP_nativeDEX.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/iguana/exchanges/LP_nativeDEX.c b/iguana/exchanges/LP_nativeDEX.c index f73c9474f..6edb2f03d 100644 --- a/iguana/exchanges/LP_nativeDEX.c +++ b/iguana/exchanges/LP_nativeDEX.c @@ -624,7 +624,9 @@ void LP_coinsloop(void *_coins) { if ( LP_blockinit(coin,coin->lastscanht) < 0 ) { - printf("blockinit.%s %d error\n",coin->symbol,coin->lastscanht); + static uint32_t counter; + if ( counter++ < 3 ) + printf("blockinit.%s %d error\n",coin->symbol,coin->lastscanht); break; } coin->lastscanht++; From c0c36f2076ad4964daddcbaf8e0a268f2933d142 Mon Sep 17 00:00:00 2001 From: jl777 Date: Fri, 17 Nov 2017 12:45:44 +0200 Subject: [PATCH 0958/1664] Test --- iguana/exchanges/LP_cache.c | 2 +- iguana/exchanges/LP_nativeDEX.c | 3 +-- iguana/exchanges/LP_ordermatch.c | 15 ++++++++++++++- iguana/exchanges/LP_rpc.c | 4 ++-- iguana/exchanges/LP_socket.c | 21 ++++++++++++++++++--- iguana/exchanges/LP_transaction.c | 2 +- 6 files changed, 37 insertions(+), 10 deletions(-) diff --git a/iguana/exchanges/LP_cache.c b/iguana/exchanges/LP_cache.c index fdc734fe9..fbce9ddff 100644 --- a/iguana/exchanges/LP_cache.c +++ b/iguana/exchanges/LP_cache.c @@ -235,7 +235,7 @@ int32_t LP_merkleproof(struct iguana_info *coin,char *coinaddr,struct electrum_i return(0); if ( (tx= LP_transactionfind(coin,txid)) == 0 && strcmp(coinaddr,coin->smartaddr) == 0 ) { - if ( (retjson= electrum_transaction(coin->symbol,ep,&retjson,txid)) != 0 ) + if ( (retjson= electrum_transaction(coin->symbol,ep,&retjson,txid,0)) != 0 ) free_json(retjson); } if ( tx != 0 ) diff --git a/iguana/exchanges/LP_nativeDEX.c b/iguana/exchanges/LP_nativeDEX.c index 6edb2f03d..3ca6cb879 100644 --- a/iguana/exchanges/LP_nativeDEX.c +++ b/iguana/exchanges/LP_nativeDEX.c @@ -17,11 +17,10 @@ // LP_nativeDEX.c // marketmaker // +// destpubkey // if ( G.LP_pendingswaps != 0 ) return(-1); // bot safe to exit? -// 324744 and 50mb // BCH signing -// single utxo allocations alice // alice waiting for bestprice // // previously, it used to show amount, kmd equiv, perc diff --git a/iguana/exchanges/LP_ordermatch.c b/iguana/exchanges/LP_ordermatch.c index 60de857a8..7e440d990 100644 --- a/iguana/exchanges/LP_ordermatch.c +++ b/iguana/exchanges/LP_ordermatch.c @@ -746,10 +746,23 @@ int32_t LP_aliceonly(char *symbol) int32_t LP_validSPV(char *symbol,char *coinaddr,bits256 txid,int32_t vout) { - struct electrum_info *ep,*backupep; struct LP_address_utxo *up; struct iguana_info *coin; + struct electrum_info *ep,*backupep; cJSON *txobj; struct LP_address_utxo *up; struct iguana_info *coin; 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 ) + free_json(txobj); + if ( (tx= LP_transactionfind(coin,txid)) != 0 ) + { + if ( vout < tx->numvouts && tx->height > 0 ) + LP_address_utxoadd((uint32_t)time(NULL),"LP_validSPV",coin,coinaddr,txid,vout,tx->outpoints[vout].value,tx->height,-1); + if ( tx->SPV <= 0 ) + return(-1); + return(0); + } + } if ( (up= LP_address_utxofind(coin,coinaddr,txid,vout)) != 0 ) { if ( up->SPV < 0 ) diff --git a/iguana/exchanges/LP_rpc.c b/iguana/exchanges/LP_rpc.c index 11924e51c..8639646ee 100644 --- a/iguana/exchanges/LP_rpc.c +++ b/iguana/exchanges/LP_rpc.c @@ -429,7 +429,7 @@ cJSON *LP_gettx(char *symbol,bits256 txid) } else { - if ( (retjson= electrum_transaction(symbol,coin->electrum,&retjson,txid)) != 0 ) + if ( (retjson= electrum_transaction(symbol,coin->electrum,&retjson,txid,0)) != 0 ) return(retjson); else printf("failed blockchain.transaction.get %s %s\n",coin->symbol,bits256_str(str,txid)); return(cJSON_Parse("{\"error\":\"no transaction bytes\"}")); @@ -507,7 +507,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 ) + if ( (txobj= electrum_transaction(symbol,coin->electrum,&txobj,txid,0)) != 0 ) { if ( (vouts= jarray(&n,txobj,"vout")) != 0 && n > 0 ) LP_destaddr(coinaddr,jitem(vouts,vout)); diff --git a/iguana/exchanges/LP_socket.c b/iguana/exchanges/LP_socket.c index 723a61a92..f1a895b38 100644 --- a/iguana/exchanges/LP_socket.c +++ b/iguana/exchanges/LP_socket.c @@ -742,12 +742,27 @@ 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) +cJSON *electrum_transaction(char *symbol,struct electrum_info *ep,cJSON **retjsonp,bits256 txid,char *SPVcheck) { - cJSON *retjson; + cJSON *retjson,*array; struct LP_transaction *tx; struct iguana_info *coin; + coin = LP_coinfind(symbol); 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->height <= 0 ) + { + if ( (array= electrum_address_listunspent(symbol,ep,&array,SPVcheck,2)) != 0 ) + { + printf("SPVcheck.%s got %d unspents\n",SPVcheck,cJSON_GetArraySize(array)); + free_json(array); + } + } + if ( tx->height > 0 ) + tx->SPV = LP_merkleproof(coin,SPVcheck,ep,txid,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); + } if ( ep != 0 ) portable_mutex_unlock(&ep->txmutex); return(retjson); @@ -789,7 +804,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 ) + if ( (retjson= electrum_transaction(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)) != 0 ) diff --git a/iguana/exchanges/LP_transaction.c b/iguana/exchanges/LP_transaction.c index f90a87170..133ee6c41 100644 --- a/iguana/exchanges/LP_transaction.c +++ b/iguana/exchanges/LP_transaction.c @@ -118,7 +118,7 @@ bits256 LP_broadcast(char *txname,char *symbol,char *txbytes,bits256 expectedtxi } else if ( (errstr= jstr(retjson,"error")) != 0 && strcmp(errstr,"timeout") == 0 && coin != 0 && coin->electrum != 0 ) { - if ( totalretries < 10 ) + if ( totalretries < 4 ) { printf("time error with electrum, retry.%d\n",totalretries); totalretries++; From 10dac4ab97796051d8c7c8540348a9b28abc8b2b Mon Sep 17 00:00:00 2001 From: jl777 Date: Fri, 17 Nov 2017 15:57:19 +0200 Subject: [PATCH 0959/1664] Add back utxo info --- iguana/exchanges/LP_include.h | 11 +++- iguana/exchanges/LP_nativeDEX.c | 7 +- iguana/exchanges/LP_prices.c | 110 +++++++++++++++++++++++++------ iguana/exchanges/LP_signatures.c | 15 ++++- 4 files changed, 119 insertions(+), 24 deletions(-) diff --git a/iguana/exchanges/LP_include.h b/iguana/exchanges/LP_include.h index f66fcc9c1..2d928676f 100644 --- a/iguana/exchanges/LP_include.h +++ b/iguana/exchanges/LP_include.h @@ -364,12 +364,21 @@ struct basilisk_swap }; +struct LP_pubkey_quote +{ + struct LP_pubkey_quote *next,*prev; + float price; + uint32_t maxutxo,aveutxo; + uint8_t baseind,relind,numutxos,scale; +}; + #define LP_MAXPRICEINFOS 256 struct LP_pubkeyinfo { UT_hash_handle hh; bits256 pubkey; - float matrix[LP_MAXPRICEINFOS][LP_MAXPRICEINFOS]; + struct LP_pubkey_quote *quotes; + //float matrix[LP_MAXPRICEINFOS][LP_MAXPRICEINFOS]; //uint32_t timestamps[LP_MAXPRICEINFOS][LP_MAXPRICEINFOS]; uint32_t timestamp,numerrors,lasttime; int32_t istrusted; diff --git a/iguana/exchanges/LP_nativeDEX.c b/iguana/exchanges/LP_nativeDEX.c index 3ca6cb879..5b44da252 100644 --- a/iguana/exchanges/LP_nativeDEX.c +++ b/iguana/exchanges/LP_nativeDEX.c @@ -533,8 +533,6 @@ void LP_coinsloop(void *_coins) { if ( (backupep= ep->prev) == 0 ) backupep = ep; - // skip cLP_address MNZ bXcSsYBiVKtTzYErqxvma4UsojZTEf5L6H - //printf("electrum %s\n",coin->symbol); if ( (ap= LP_addressfind(coin,coin->smartaddr)) != 0 ) { if ( (retjson= electrum_address_listunspent(coin->symbol,ep,&retjson,ap->coinaddr,1)) != 0 ) @@ -892,6 +890,11 @@ void LPinit(uint16_t myport,uint16_t mypullport,uint16_t mypubport,uint16_t mybu char *myipaddr=0,version[64]; long filesize,n; int32_t valid,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(); sprintf(version,"Marketmaker %s.%s %s rsize.%ld",LP_MAJOR_VERSION,LP_MINOR_VERSION,LP_BUILD_NUMBER,sizeof(struct basilisk_request)); printf("%s %u\n",version,calc_crc32(0,version,(int32_t)strlen(version))); + if ( LP_MAXPRICEINFOS > 256 ) + { + printf("LP_MAXPRICEINFOS %d wont fit in a uint8_t, need to increase the width of the baseind and relind for struct LP_pubkey_quote\n",LP_MAXPRICEINFOS); + exit(-1); + } LP_showwif = juint(argjson,"wif"); if ( passphrase == 0 || passphrase[0] == 0 ) { diff --git a/iguana/exchanges/LP_prices.c b/iguana/exchanges/LP_prices.c index ade6b75f5..4962d2972 100644 --- a/iguana/exchanges/LP_prices.c +++ b/iguana/exchanges/LP_prices.c @@ -18,7 +18,7 @@ // marketmaker // -struct LP_orderbookentry { bits256 pubkey; double price; uint64_t minsatoshis,maxsatoshis,depth; uint32_t timestamp; int32_t numutxos; char coinaddr[64]; }; +struct LP_orderbookentry { bits256 pubkey; double price; uint64_t avesatoshis,maxsatoshis,depth; uint32_t timestamp; int32_t numutxos; char coinaddr[64]; }; struct LP_priceinfo { @@ -48,6 +48,75 @@ struct LP_cacheinfo uint32_t timestamp; } *LP_cacheinfos; + +float LP_pubkey_price(int32_t *numutxosp,int64_t *avesatoshisp,int64_t *maxsatoshisp,struct LP_pubkeyinfo *pubp,uint32_t baseind,uint32_t relind) +{ + struct LP_pubkey_quote *pq,*tmp; int32_t scale; int64_t scale64; + *numutxosp = 0; + *avesatoshisp = *maxsatoshisp = 0; + DL_FOREACH_SAFE(pubp->quotes,pq,tmp) + { + if ( baseind == pq->baseind && relind == pq->relind ) + { + if ( (scale= pq->scale) == 0 ) + pq->scale = scale = 6; + scale64 = 1; + while ( scale > 0 ) + { + scale64 *= 10; + scale--; + } + *numutxosp = pq->numutxos; + *avesatoshisp = pq->aveutxo * scale64; + *maxsatoshisp = pq->maxutxo * scale64; + return(pq->price); + } + } + return(0); +} + +void LP_pubkey_update(struct LP_pubkeyinfo *pubp,uint32_t baseind,uint32_t relind,float price,int64_t balance,int32_t numutxos,int64_t minutxo,int64_t maxutxo) +{ + struct LP_pubkey_quote *pq,*tmp; int64_t aveutxo,scale64,ave64,max64; int32_t scale; + DL_FOREACH_SAFE(pubp->quotes,pq,tmp) + { + if ( baseind == pq->baseind && relind == pq->relind ) + break; + pq = 0; + } + if ( pq == 0 ) + { + pq = calloc(1,sizeof(*pq)); + pq->baseind = baseind; + pq->relind = relind; + pq->scale = 6; // millions of SATOSHIS, ie. 0.01 + DL_APPEND(pubp->quotes,pq); // already serialized as only path is via stats_JSON() + } + pq->price = price; + if ( numutxos != 0 ) + { + if ( (scale= pq->scale) == 0 ) + pq->scale = scale = 6; + scale64 = 1; + while ( scale > 0 ) + { + scale64 *= 10; + scale--; + } + if ( numutxos > (1L << sizeof(pq->numutxos)) ) + pq->numutxos = (1L << sizeof(pq->numutxos)) - 1; + else pq->numutxos = numutxos; + aveutxo = balance / numutxos; + if ( (ave64= (aveutxo / scale64)) > (1LL << 32) ) + ave64 = (1LL << 32) - 1; + if ( (max64= (maxutxo / scale64)) > (1LL << 32) ) + max64 = (1LL << 32) - 1; + pq->aveutxo = (uint32_t)ave64; + pq->maxutxo = (uint32_t)max64; + printf("scale64 = %llu, ave %llu, ave32 %u (%llu) max32 %u (%llu)\n",(long long)scale64,(long long)aveutxo,pq->aveutxo,(long long)pq->aveutxo * scale64,pq->maxutxo,(long long)pq->maxutxo * scale64); + } +} + struct LP_priceinfo *LP_priceinfo(int32_t ind) { if ( ind < 0 || ind >= LP_MAXPRICEINFOS ) @@ -272,7 +341,7 @@ uint64_t LP_unspents_metric(struct iguana_info *coin,char *coinaddr) cJSON *LP_pubkeyjson(struct LP_pubkeyinfo *pubp) { - int32_t baseid,relid; char *base,hexstr[67],hexstr2[67],sigstr[256]; double price; cJSON *item,*array,*obj; + int32_t baseid,relid,numutxos; int64_t avesatoshis,maxsatoshis; char *base,hexstr[67],hexstr2[67],sigstr[256]; double price; cJSON *item,*array,*obj; obj = cJSON_CreateObject(); array = cJSON_CreateArray(); for (baseid=0; baseidmatrix[baseid][relid]; + price = LP_pubkey_price(&numutxos,&avesatoshis,&maxsatoshis,pubp,baseid,relid);//pubp->matrix[baseid][relid]; if ( LP_pricevalid(price) > 0 ) { item = cJSON_CreateArray(); @@ -495,7 +564,8 @@ int32_t LP_mypriceset(int32_t *changedp,char *base,char *rel,double price) if ( (pubp= LP_pubkeyadd(G.LP_mypub25519)) != 0 ) { pubp->timestamp = (uint32_t)time(NULL); - pubp->matrix[basepp->ind][relpp->ind] = price; + LP_pubkey_update(pubp,basepp->ind,relpp->ind,price,0,0,0,0); + //pubp->matrix[basepp->ind][relpp->ind] = price; //pubp->timestamps[basepp->ind][relpp->ind] = pubp->timestamp; //pubp->matrix[relpp->ind][basepp->ind] = (1. / price); } @@ -671,7 +741,7 @@ 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)*0.8); + jaddnum(item,"avevolume",dstr(op->avesatoshis)*0.8); jaddnum(item,"maxvolume",dstr(op->maxsatoshis)*0.8); jaddnum(item,"depth",dstr(op->depth)*0.8); jaddbits256(item,"pubkey",op->pubkey); @@ -680,7 +750,7 @@ cJSON *LP_orderbookjson(char *symbol,struct LP_orderbookentry *op) return(item); } -struct LP_orderbookentry *LP_orderbookentry(char *address,char *base,char *rel,double price,int32_t numutxos,uint64_t minsatoshis,uint64_t maxsatoshis,bits256 pubkey,uint32_t timestamp,uint64_t balance) +struct LP_orderbookentry *LP_orderbookentry(char *address,char *base,char *rel,double price,int32_t numutxos,uint64_t avesatoshis,uint64_t maxsatoshis,bits256 pubkey,uint32_t timestamp,uint64_t balance) { struct LP_orderbookentry *op; if ( (op= calloc(1,sizeof(*op))) != 0 ) @@ -688,8 +758,8 @@ struct LP_orderbookentry *LP_orderbookentry(char *address,char *base,char *rel,d safecopy(op->coinaddr,address,sizeof(op->coinaddr)); op->price = price; op->numutxos = numutxos; - op->minsatoshis = minsatoshis; - op->maxsatoshis = maxsatoshis; + op->avesatoshis = avesatoshis; + op->maxsatoshis = avesatoshis; op->pubkey = pubkey; op->timestamp = timestamp; op->depth = balance; @@ -718,7 +788,7 @@ void LP_pubkeys_query() int32_t LP_orderbook_utxoentries(uint32_t now,int32_t polarity,char *base,char *rel,struct LP_orderbookentry *(**arrayp),int32_t num,int32_t cachednum,int32_t duration) { - char coinaddr[64]; uint8_t zeroes[20]; struct LP_pubkeyinfo *pubp=0,*tmp; struct LP_priceinfo *basepp; struct LP_orderbookentry *op; struct LP_address *ap; struct iguana_info *basecoin; uint32_t oldest; double price; int32_t baseid,relid,n; uint64_t minsatoshis,maxsatoshis,balance; + char coinaddr[64]; uint8_t zeroes[20]; struct LP_pubkeyinfo *pubp=0,*tmp; struct LP_priceinfo *basepp; struct LP_orderbookentry *op; struct LP_address *ap; struct iguana_info *basecoin; uint32_t oldest; double price; int32_t baseid,relid,n; int64_t maxsatoshis,balance,avesatoshis; if ( (basepp= LP_priceinfoptr(&relid,base,rel)) != 0 ) baseid = basepp->ind; else return(num); @@ -737,23 +807,23 @@ int32_t LP_orderbook_utxoentries(uint32_t now,int32_t polarity,char *base,char * if ( pubp->timestamp < oldest ) continue; bitcoin_address(coinaddr,basecoin->taddr,basecoin->pubtype,pubp->rmd160,sizeof(pubp->rmd160)); - minsatoshis = maxsatoshis = n = 0; + avesatoshis = maxsatoshis = n = 0; ap = 0; - if ( (price= pubp->matrix[baseid][relid]) > SMALLVAL )//&& pubp->timestamps[baseid][relid] >= oldest ) + if ( (price= LP_pubkey_price(&n,&avesatoshis,&maxsatoshis,pubp,baseid,relid)) > SMALLVAL ) //pubp->matrix[baseid][relid]) > SMALLVAL )//&& pubp->timestamps[baseid][relid] >= oldest ) { - balance = 0; - if ( (ap= LP_addressfind(basecoin,coinaddr)) != 0 ) + balance = avesatoshis * n; + //if ( (ap= LP_addressfind(basecoin,coinaddr)) != 0 ) { - n = LP_address_minmax(&balance,&minsatoshis,&maxsatoshis,ap); + //n = LP_address_minmax(&balance,&minsatoshis,&maxsatoshis,ap); if ( polarity > 0 ) { balance *= price; - minsatoshis *= price; + avesatoshis *= price; maxsatoshis *= price; } //printf("%s/%s %s n.%d ap->n.%d %.8f\n",base,rel,coinaddr,n,ap->n,dstr(ap->total)); } - if ( (op= LP_orderbookentry(coinaddr,base,rel,polarity > 0 ? price : 1./price,n,minsatoshis,maxsatoshis,pubp->pubkey,pubp->timestamp,balance)) != 0 ) + if ( (op= LP_orderbookentry(coinaddr,base,rel,polarity > 0 ? price : 1./price,n,avesatoshis,maxsatoshis,pubp->pubkey,pubp->timestamp,balance)) != 0 ) { *arrayp = realloc(*arrayp,sizeof(*(*arrayp)) * (num+1)); (*arrayp)[num++] = op; @@ -1036,7 +1106,7 @@ cJSON *LP_pricearray(char *base,char *rel,uint32_t firsttime,uint32_t lasttime,i return(retarray); } -void LP_pricefeedupdate(bits256 pubkey,char *base,char *rel,double price) +void LP_pricefeedupdate(bits256 pubkey,char *base,char *rel,double price,int32_t numutxos,int64_t balance,int64_t minutxo,int64_t maxutxo) { struct LP_priceinfo *basepp,*relpp; uint32_t now; uint64_t price64; struct LP_pubkeyinfo *pubp; char str[65],fname[512]; FILE *fp; //printf("check PRICEFEED UPDATE.(%s/%s) %.8f %s\n",base,rel,price,bits256_str(str,pubkey)); @@ -1073,9 +1143,11 @@ void LP_pricefeedupdate(bits256 pubkey,char *base,char *rel,double price) if ( (LP_rand() % 1000) == 0 ) printf("PRICEFEED UPDATE.(%-6s/%6s) %12.8f %s %12.8f\n",base,rel,price,bits256_str(str,pubkey),1./price); pubp->timestamp = (uint32_t)time(NULL); - if ( fabs(pubp->matrix[basepp->ind][relpp->ind] - price) > SMALLVAL ) + LP_pubkey_update(pubp,basepp->ind,relpp->ind,price,balance,numutxos,minutxo,maxutxo); + //pubp->depthinfo[basepp->ind][relpp->ind] = LP_depthinfo_compact(); + //if ( fabs(pubp->matrix[basepp->ind][relpp->ind] - price) > SMALLVAL ) { - pubp->matrix[basepp->ind][relpp->ind] = price; + //pubp->matrix[basepp->ind][relpp->ind] = price; //pubp->timestamps[basepp->ind][relpp->ind] = pubp->timestamp; dxblend(&basepp->relvals[relpp->ind],price,0.9); dxblend(&relpp->relvals[basepp->ind],1. / price,0.9); diff --git a/iguana/exchanges/LP_signatures.c b/iguana/exchanges/LP_signatures.c index e729421ad..5a7ab184d 100644 --- a/iguana/exchanges/LP_signatures.c +++ b/iguana/exchanges/LP_signatures.c @@ -451,7 +451,8 @@ int32_t LP_price_sigadd(cJSON *item,uint32_t timestamp,bits256 priv,uint8_t *pub char *LP_pricepings(void *ctx,char *myipaddr,int32_t pubsock,char *base,char *rel,double price) { - struct iguana_info *basecoin,*relcoin; char pubsecpstr[67]; uint32_t timestamp; uint64_t price64; bits256 zero; cJSON *reqjson = cJSON_CreateObject(); + struct iguana_info *basecoin,*relcoin; struct LP_address *ap; char pubsecpstr[67]; uint32_t numutxos,timestamp; uint64_t price64,balance,minsize,maxsize; bits256 zero; cJSON *reqjson; + reqjson = cJSON_CreateObject(); // LP_addsig if ( (basecoin= LP_coinfind(base)) != 0 && (relcoin= LP_coinfind(rel)) != 0 && basecoin->electrum == 0 )//&& relcoin->electrum == 0 ) { @@ -467,6 +468,16 @@ char *LP_pricepings(void *ctx,char *myipaddr,int32_t pubsock,char *base,char *re jaddnum(reqjson,"timestamp",timestamp); init_hexbytes_noT(pubsecpstr,G.LP_pubsecp,33); jaddstr(reqjson,"pubsecp",pubsecpstr); + if ( (ap= LP_address(basecoin,basecoin->smartaddr)) != 0 ) + { + if ( (numutxos= LP_address_minmax(&balance,&minsize,&maxsize,ap)) != 0 ) + { + jaddnum(reqjson,"n",numutxos); + jaddnum(reqjson,"bal",dstr(balance)); + jaddnum(reqjson,"min",dstr(minsize)); + jaddnum(reqjson,"max",dstr(maxsize)); + } + } LP_price_sigadd(reqjson,timestamp,G.LP_privkey,G.LP_pubsecp,G.LP_mypub25519,base,rel,price64); LP_reserved_msg(0,base,rel,zero,jprint(reqjson,1)); return(clonestr("{\"result\":\"success\"}")); @@ -484,7 +495,7 @@ char *LP_postprice_recv(cJSON *argjson) { if ( LP_price_sigcheck(juint(argjson,"timestamp"),jstr(argjson,"sig"),jstr(argjson,"pubsecp"),pubkey,base,rel,j64bits(argjson,"price64")) == 0 ) { - LP_pricefeedupdate(pubkey,base,rel,price); + LP_pricefeedupdate(pubkey,base,rel,price,jint(argjson,"n"),jdouble(argjson,"bal")*SATOSHIDEN,jdouble(argjson,"min")*SATOSHIDEN,jdouble(argjson,"max")*SATOSHIDEN); return(clonestr("{\"result\":\"success\"}")); } else return(clonestr("{\"error\":\"sig failure\"}")); } From eb6d6fe7f0d5b11e59ade3c71d1e1d805fdfdae5 Mon Sep 17 00:00:00 2001 From: jl777 Date: Fri, 17 Nov 2017 16:10:25 +0200 Subject: [PATCH 0960/1664] Test --- iguana/exchanges/LP_prices.c | 7 ++++--- iguana/exchanges/LP_signatures.c | 1 + 2 files changed, 5 insertions(+), 3 deletions(-) diff --git a/iguana/exchanges/LP_prices.c b/iguana/exchanges/LP_prices.c index 4962d2972..4db3df60d 100644 --- a/iguana/exchanges/LP_prices.c +++ b/iguana/exchanges/LP_prices.c @@ -106,14 +106,15 @@ void LP_pubkey_update(struct LP_pubkeyinfo *pubp,uint32_t baseind,uint32_t relin if ( numutxos > (1L << sizeof(pq->numutxos)) ) pq->numutxos = (1L << sizeof(pq->numutxos)) - 1; else pq->numutxos = numutxos; - aveutxo = balance / numutxos; + aveutxo = (balance + (scale64>>1)) / numutxos; if ( (ave64= (aveutxo / scale64)) > (1LL << 32) ) ave64 = (1LL << 32) - 1; - if ( (max64= (maxutxo / scale64)) > (1LL << 32) ) + max64 = ((maxutxo + (scale64>>1)) / scale64); + if ( max64 > (1LL << 32) ) max64 = (1LL << 32) - 1; pq->aveutxo = (uint32_t)ave64; pq->maxutxo = (uint32_t)max64; - printf("scale64 = %llu, ave %llu, ave32 %u (%llu) max32 %u (%llu)\n",(long long)scale64,(long long)aveutxo,pq->aveutxo,(long long)pq->aveutxo * scale64,pq->maxutxo,(long long)pq->maxutxo * scale64); + printf("base.%s scale64 = %llu, ave %llu, ave32 %u (%llu) max32 %u (%llu)\n",LP_priceinfos[baseind].symbol,(long long)scale64,(long long)aveutxo,pq->aveutxo,(long long)pq->aveutxo * scale64,pq->maxutxo,(long long)pq->maxutxo * scale64); } } diff --git a/iguana/exchanges/LP_signatures.c b/iguana/exchanges/LP_signatures.c index 5a7ab184d..6089e8366 100644 --- a/iguana/exchanges/LP_signatures.c +++ b/iguana/exchanges/LP_signatures.c @@ -472,6 +472,7 @@ char *LP_pricepings(void *ctx,char *myipaddr,int32_t pubsock,char *base,char *re { if ( (numutxos= LP_address_minmax(&balance,&minsize,&maxsize,ap)) != 0 ) { + printf("%s numutxos.%d balance %.8f min %.8f max %.8f\n",base,numutxos,dstr(balance),dstr(minsize),dstr(maxsize)); jaddnum(reqjson,"n",numutxos); jaddnum(reqjson,"bal",dstr(balance)); jaddnum(reqjson,"min",dstr(minsize)); From b38e6f678a31bf9dd812c206a3b07928d5be40c5 Mon Sep 17 00:00:00 2001 From: jl777 Date: Fri, 17 Nov 2017 16:16:19 +0200 Subject: [PATCH 0961/1664] Test --- iguana/exchanges/LP_include.h | 2 +- iguana/exchanges/LP_prices.c | 22 +++++++++++----------- iguana/exchanges/LP_signatures.c | 4 ++-- 3 files changed, 14 insertions(+), 14 deletions(-) diff --git a/iguana/exchanges/LP_include.h b/iguana/exchanges/LP_include.h index 2d928676f..7d9b1d9ab 100644 --- a/iguana/exchanges/LP_include.h +++ b/iguana/exchanges/LP_include.h @@ -369,7 +369,7 @@ struct LP_pubkey_quote struct LP_pubkey_quote *next,*prev; float price; uint32_t maxutxo,aveutxo; - uint8_t baseind,relind,numutxos,scale; + uint8_t baseind,relind,numrelutxos,scale; }; #define LP_MAXPRICEINFOS 256 diff --git a/iguana/exchanges/LP_prices.c b/iguana/exchanges/LP_prices.c index 4db3df60d..b058e1c18 100644 --- a/iguana/exchanges/LP_prices.c +++ b/iguana/exchanges/LP_prices.c @@ -49,10 +49,10 @@ struct LP_cacheinfo } *LP_cacheinfos; -float LP_pubkey_price(int32_t *numutxosp,int64_t *avesatoshisp,int64_t *maxsatoshisp,struct LP_pubkeyinfo *pubp,uint32_t baseind,uint32_t relind) +float LP_pubkey_price(int32_t *numrelutxosp,int64_t *avesatoshisp,int64_t *maxsatoshisp,struct LP_pubkeyinfo *pubp,uint32_t baseind,uint32_t relind) { struct LP_pubkey_quote *pq,*tmp; int32_t scale; int64_t scale64; - *numutxosp = 0; + *numrelutxosp = 0; *avesatoshisp = *maxsatoshisp = 0; DL_FOREACH_SAFE(pubp->quotes,pq,tmp) { @@ -66,7 +66,7 @@ float LP_pubkey_price(int32_t *numutxosp,int64_t *avesatoshisp,int64_t *maxsatos scale64 *= 10; scale--; } - *numutxosp = pq->numutxos; + *numrelutxosp = pq->numrelutxos; *avesatoshisp = pq->aveutxo * scale64; *maxsatoshisp = pq->maxutxo * scale64; return(pq->price); @@ -75,7 +75,7 @@ float LP_pubkey_price(int32_t *numutxosp,int64_t *avesatoshisp,int64_t *maxsatos return(0); } -void LP_pubkey_update(struct LP_pubkeyinfo *pubp,uint32_t baseind,uint32_t relind,float price,int64_t balance,int32_t numutxos,int64_t minutxo,int64_t maxutxo) +void LP_pubkey_update(struct LP_pubkeyinfo *pubp,uint32_t baseind,uint32_t relind,float price,int64_t balance,int32_t numrelutxos,int64_t minutxo,int64_t maxutxo) { struct LP_pubkey_quote *pq,*tmp; int64_t aveutxo,scale64,ave64,max64; int32_t scale; DL_FOREACH_SAFE(pubp->quotes,pq,tmp) @@ -93,7 +93,7 @@ void LP_pubkey_update(struct LP_pubkeyinfo *pubp,uint32_t baseind,uint32_t relin DL_APPEND(pubp->quotes,pq); // already serialized as only path is via stats_JSON() } pq->price = price; - if ( numutxos != 0 ) + if ( numrelutxos != 0 ) { if ( (scale= pq->scale) == 0 ) pq->scale = scale = 6; @@ -103,9 +103,9 @@ void LP_pubkey_update(struct LP_pubkeyinfo *pubp,uint32_t baseind,uint32_t relin scale64 *= 10; scale--; } - if ( numutxos > (1L << sizeof(pq->numutxos)) ) - pq->numutxos = (1L << sizeof(pq->numutxos)) - 1; - else pq->numutxos = numutxos; + if ( numrelutxos > (1L << sizeof(pq->numutxos)) ) + pq->numrelutxos = (1L << sizeof(pq->numutxos)) - 1; + else pq->numrelutxos = numrelutxos; aveutxo = (balance + (scale64>>1)) / numutxos; if ( (ave64= (aveutxo / scale64)) > (1LL << 32) ) ave64 = (1LL << 32) - 1; @@ -114,7 +114,7 @@ void LP_pubkey_update(struct LP_pubkeyinfo *pubp,uint32_t baseind,uint32_t relin max64 = (1LL << 32) - 1; pq->aveutxo = (uint32_t)ave64; pq->maxutxo = (uint32_t)max64; - printf("base.%s scale64 = %llu, ave %llu, ave32 %u (%llu) max32 %u (%llu)\n",LP_priceinfos[baseind].symbol,(long long)scale64,(long long)aveutxo,pq->aveutxo,(long long)pq->aveutxo * scale64,pq->maxutxo,(long long)pq->maxutxo * scale64); + printf("base.%s numutxos.%u %u scale64 = %llu, ave %llu, ave32 %u (%llu) max32 %u (%llu)\n",LP_priceinfos[relind].symbol,numrelutxos,pq->numrelutxos,(long long)scale64,(long long)aveutxo,pq->aveutxo,(long long)pq->aveutxo * scale64,pq->maxutxo,(long long)pq->maxutxo * scale64); } } @@ -1107,7 +1107,7 @@ cJSON *LP_pricearray(char *base,char *rel,uint32_t firsttime,uint32_t lasttime,i return(retarray); } -void LP_pricefeedupdate(bits256 pubkey,char *base,char *rel,double price,int32_t numutxos,int64_t balance,int64_t minutxo,int64_t maxutxo) +void LP_pricefeedupdate(bits256 pubkey,char *base,char *rel,double price,int32_t numrelutxos,int64_t balance,int64_t minutxo,int64_t maxutxo) { struct LP_priceinfo *basepp,*relpp; uint32_t now; uint64_t price64; struct LP_pubkeyinfo *pubp; char str[65],fname[512]; FILE *fp; //printf("check PRICEFEED UPDATE.(%s/%s) %.8f %s\n",base,rel,price,bits256_str(str,pubkey)); @@ -1144,7 +1144,7 @@ void LP_pricefeedupdate(bits256 pubkey,char *base,char *rel,double price,int32_t if ( (LP_rand() % 1000) == 0 ) printf("PRICEFEED UPDATE.(%-6s/%6s) %12.8f %s %12.8f\n",base,rel,price,bits256_str(str,pubkey),1./price); pubp->timestamp = (uint32_t)time(NULL); - LP_pubkey_update(pubp,basepp->ind,relpp->ind,price,balance,numutxos,minutxo,maxutxo); + LP_pubkey_update(pubp,basepp->ind,relpp->ind,price,balance,numrelutxos,minutxo,maxutxo); //pubp->depthinfo[basepp->ind][relpp->ind] = LP_depthinfo_compact(); //if ( fabs(pubp->matrix[basepp->ind][relpp->ind] - price) > SMALLVAL ) { diff --git a/iguana/exchanges/LP_signatures.c b/iguana/exchanges/LP_signatures.c index 6089e8366..252d19df4 100644 --- a/iguana/exchanges/LP_signatures.c +++ b/iguana/exchanges/LP_signatures.c @@ -468,11 +468,11 @@ char *LP_pricepings(void *ctx,char *myipaddr,int32_t pubsock,char *base,char *re jaddnum(reqjson,"timestamp",timestamp); init_hexbytes_noT(pubsecpstr,G.LP_pubsecp,33); jaddstr(reqjson,"pubsecp",pubsecpstr); - if ( (ap= LP_address(basecoin,basecoin->smartaddr)) != 0 ) + if ( (ap= LP_address(relcoin,relcoin->smartaddr)) != 0 ) { if ( (numutxos= LP_address_minmax(&balance,&minsize,&maxsize,ap)) != 0 ) { - printf("%s numutxos.%d balance %.8f min %.8f max %.8f\n",base,numutxos,dstr(balance),dstr(minsize),dstr(maxsize)); + printf("%s numutxos.%d balance %.8f min %.8f max %.8f\n",rel,numutxos,dstr(balance),dstr(minsize),dstr(maxsize)); jaddnum(reqjson,"n",numutxos); jaddnum(reqjson,"bal",dstr(balance)); jaddnum(reqjson,"min",dstr(minsize)); From 7ee7fbdca53581ee984dbcfc528b0882babce99f Mon Sep 17 00:00:00 2001 From: jl777 Date: Fri, 17 Nov 2017 16:18:25 +0200 Subject: [PATCH 0962/1664] Test --- iguana/exchanges/LP_prices.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/iguana/exchanges/LP_prices.c b/iguana/exchanges/LP_prices.c index b058e1c18..f1b312de8 100644 --- a/iguana/exchanges/LP_prices.c +++ b/iguana/exchanges/LP_prices.c @@ -103,10 +103,10 @@ void LP_pubkey_update(struct LP_pubkeyinfo *pubp,uint32_t baseind,uint32_t relin scale64 *= 10; scale--; } - if ( numrelutxos > (1L << sizeof(pq->numutxos)) ) - pq->numrelutxos = (1L << sizeof(pq->numutxos)) - 1; + if ( numrelutxos > (1L << sizeof(pq->numrelutxos)) ) + pq->numrelutxos = (1L << sizeof(pq->numrelutxos)) - 1; else pq->numrelutxos = numrelutxos; - aveutxo = (balance + (scale64>>1)) / numutxos; + aveutxo = (balance + (scale64>>1)) / numrelutxos; if ( (ave64= (aveutxo / scale64)) > (1LL << 32) ) ave64 = (1LL << 32) - 1; max64 = ((maxutxo + (scale64>>1)) / scale64); From dd77fb3331a6b7d666b746fe07524b98d3ba25ad Mon Sep 17 00:00:00 2001 From: jl777 Date: Fri, 17 Nov 2017 16:29:15 +0200 Subject: [PATCH 0963/1664] Test --- iguana/exchanges/LP_prices.c | 16 ++++++++-------- iguana/exchanges/LP_signatures.c | 7 ++++--- 2 files changed, 12 insertions(+), 11 deletions(-) diff --git a/iguana/exchanges/LP_prices.c b/iguana/exchanges/LP_prices.c index f1b312de8..5042955b1 100644 --- a/iguana/exchanges/LP_prices.c +++ b/iguana/exchanges/LP_prices.c @@ -75,7 +75,7 @@ float LP_pubkey_price(int32_t *numrelutxosp,int64_t *avesatoshisp,int64_t *maxsa return(0); } -void LP_pubkey_update(struct LP_pubkeyinfo *pubp,uint32_t baseind,uint32_t relind,float price,int64_t balance,int32_t numrelutxos,int64_t minutxo,int64_t maxutxo) +void LP_pubkey_update(struct LP_pubkeyinfo *pubp,uint32_t baseind,uint32_t relind,float price,int64_t balance,char *utxocoin,int32_t numutxos,int64_t minutxo,int64_t maxutxo) { struct LP_pubkey_quote *pq,*tmp; int64_t aveutxo,scale64,ave64,max64; int32_t scale; DL_FOREACH_SAFE(pubp->quotes,pq,tmp) @@ -93,7 +93,7 @@ void LP_pubkey_update(struct LP_pubkeyinfo *pubp,uint32_t baseind,uint32_t relin DL_APPEND(pubp->quotes,pq); // already serialized as only path is via stats_JSON() } pq->price = price; - if ( numrelutxos != 0 ) + if ( numutxos != 0 ) { if ( (scale= pq->scale) == 0 ) pq->scale = scale = 6; @@ -103,10 +103,10 @@ void LP_pubkey_update(struct LP_pubkeyinfo *pubp,uint32_t baseind,uint32_t relin scale64 *= 10; scale--; } - if ( numrelutxos > (1L << sizeof(pq->numrelutxos)) ) + if ( numutxos > (1L << sizeof(pq->numrelutxos)) ) pq->numrelutxos = (1L << sizeof(pq->numrelutxos)) - 1; - else pq->numrelutxos = numrelutxos; - aveutxo = (balance + (scale64>>1)) / numrelutxos; + else pq->numrelutxos = numutxos; + aveutxo = (balance + (scale64>>1)) / numutxos; if ( (ave64= (aveutxo / scale64)) > (1LL << 32) ) ave64 = (1LL << 32) - 1; max64 = ((maxutxo + (scale64>>1)) / scale64); @@ -114,7 +114,7 @@ void LP_pubkey_update(struct LP_pubkeyinfo *pubp,uint32_t baseind,uint32_t relin max64 = (1LL << 32) - 1; pq->aveutxo = (uint32_t)ave64; pq->maxutxo = (uint32_t)max64; - printf("base.%s numutxos.%u %u scale64 = %llu, ave %llu, ave32 %u (%llu) max32 %u (%llu)\n",LP_priceinfos[relind].symbol,numrelutxos,pq->numrelutxos,(long long)scale64,(long long)aveutxo,pq->aveutxo,(long long)pq->aveutxo * scale64,pq->maxutxo,(long long)pq->maxutxo * scale64); + printf("base.%s rel.%s utxocoin.%s numutxos.%u %u scale64 = %llu, ave %llu, ave32 %u (%llu) max32 %u (%llu)\n",LP_priceinfos[baseind].symbol,LP_priceinfos[relind].symbol,utxocoin,numutxos,pq->numrelutxos,(long long)scale64,(long long)aveutxo,pq->aveutxo,(long long)pq->aveutxo * scale64,pq->maxutxo,(long long)pq->maxutxo * scale64); } } @@ -1107,7 +1107,7 @@ cJSON *LP_pricearray(char *base,char *rel,uint32_t firsttime,uint32_t lasttime,i return(retarray); } -void LP_pricefeedupdate(bits256 pubkey,char *base,char *rel,double price,int32_t numrelutxos,int64_t balance,int64_t minutxo,int64_t maxutxo) +void LP_pricefeedupdate(bits256 pubkey,char *base,char *rel,double price,char *utxocoin,int32_t numrelutxos,int64_t balance,int64_t minutxo,int64_t maxutxo) { struct LP_priceinfo *basepp,*relpp; uint32_t now; uint64_t price64; struct LP_pubkeyinfo *pubp; char str[65],fname[512]; FILE *fp; //printf("check PRICEFEED UPDATE.(%s/%s) %.8f %s\n",base,rel,price,bits256_str(str,pubkey)); @@ -1144,7 +1144,7 @@ void LP_pricefeedupdate(bits256 pubkey,char *base,char *rel,double price,int32_t if ( (LP_rand() % 1000) == 0 ) printf("PRICEFEED UPDATE.(%-6s/%6s) %12.8f %s %12.8f\n",base,rel,price,bits256_str(str,pubkey),1./price); pubp->timestamp = (uint32_t)time(NULL); - LP_pubkey_update(pubp,basepp->ind,relpp->ind,price,balance,numrelutxos,minutxo,maxutxo); + LP_pubkey_update(pubp,basepp->ind,relpp->ind,price,balance,utxocoin,numrelutxos,minutxo,maxutxo); //pubp->depthinfo[basepp->ind][relpp->ind] = LP_depthinfo_compact(); //if ( fabs(pubp->matrix[basepp->ind][relpp->ind] - price) > SMALLVAL ) { diff --git a/iguana/exchanges/LP_signatures.c b/iguana/exchanges/LP_signatures.c index 252d19df4..2253bcc09 100644 --- a/iguana/exchanges/LP_signatures.c +++ b/iguana/exchanges/LP_signatures.c @@ -468,11 +468,12 @@ char *LP_pricepings(void *ctx,char *myipaddr,int32_t pubsock,char *base,char *re jaddnum(reqjson,"timestamp",timestamp); init_hexbytes_noT(pubsecpstr,G.LP_pubsecp,33); jaddstr(reqjson,"pubsecp",pubsecpstr); - if ( (ap= LP_address(relcoin,relcoin->smartaddr)) != 0 ) + if ( (ap= LP_address(basecoin,basecoin->smartaddr)) != 0 ) { if ( (numutxos= LP_address_minmax(&balance,&minsize,&maxsize,ap)) != 0 ) { - printf("%s numutxos.%d balance %.8f min %.8f max %.8f\n",rel,numutxos,dstr(balance),dstr(minsize),dstr(maxsize)); + printf("%s numutxos.%d balance %.8f min %.8f max %.8f\n",base,numutxos,dstr(balance),dstr(minsize),dstr(maxsize)); + jaddstr(reqjson,"utxocoin",base); jaddnum(reqjson,"n",numutxos); jaddnum(reqjson,"bal",dstr(balance)); jaddnum(reqjson,"min",dstr(minsize)); @@ -496,7 +497,7 @@ char *LP_postprice_recv(cJSON *argjson) { if ( LP_price_sigcheck(juint(argjson,"timestamp"),jstr(argjson,"sig"),jstr(argjson,"pubsecp"),pubkey,base,rel,j64bits(argjson,"price64")) == 0 ) { - LP_pricefeedupdate(pubkey,base,rel,price,jint(argjson,"n"),jdouble(argjson,"bal")*SATOSHIDEN,jdouble(argjson,"min")*SATOSHIDEN,jdouble(argjson,"max")*SATOSHIDEN); + LP_pricefeedupdate(pubkey,base,rel,price,jstr(argjson,"utxocoin"),jint(argjson,"n"),jdouble(argjson,"bal")*SATOSHIDEN,jdouble(argjson,"min")*SATOSHIDEN,jdouble(argjson,"max")*SATOSHIDEN); return(clonestr("{\"result\":\"success\"}")); } else return(clonestr("{\"error\":\"sig failure\"}")); } From c4410b76974237ec9ad25622c6fa3e7474edf5ee Mon Sep 17 00:00:00 2001 From: jl777 Date: Fri, 17 Nov 2017 16:30:49 +0200 Subject: [PATCH 0964/1664] Test --- iguana/exchanges/LP_prices.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/iguana/exchanges/LP_prices.c b/iguana/exchanges/LP_prices.c index 5042955b1..52ec96ee6 100644 --- a/iguana/exchanges/LP_prices.c +++ b/iguana/exchanges/LP_prices.c @@ -93,7 +93,7 @@ void LP_pubkey_update(struct LP_pubkeyinfo *pubp,uint32_t baseind,uint32_t relin DL_APPEND(pubp->quotes,pq); // already serialized as only path is via stats_JSON() } pq->price = price; - if ( numutxos != 0 ) + if ( utxocoin != 0 && utxocoin[0] != 0 ) { if ( (scale= pq->scale) == 0 ) pq->scale = scale = 6; @@ -565,7 +565,7 @@ int32_t LP_mypriceset(int32_t *changedp,char *base,char *rel,double price) if ( (pubp= LP_pubkeyadd(G.LP_mypub25519)) != 0 ) { pubp->timestamp = (uint32_t)time(NULL); - LP_pubkey_update(pubp,basepp->ind,relpp->ind,price,0,0,0,0); + LP_pubkey_update(pubp,basepp->ind,relpp->ind,price,0,0,0,0,0); //pubp->matrix[basepp->ind][relpp->ind] = price; //pubp->timestamps[basepp->ind][relpp->ind] = pubp->timestamp; //pubp->matrix[relpp->ind][basepp->ind] = (1. / price); From f13ac23ce93df70f14f49ebfe39248cbf7402540 Mon Sep 17 00:00:00 2001 From: jl777 Date: Fri, 17 Nov 2017 16:37:22 +0200 Subject: [PATCH 0965/1664] Test --- iguana/exchanges/LP_include.h | 2 +- iguana/exchanges/LP_prices.c | 14 +++++++------- iguana/exchanges/LP_signatures.c | 2 +- 3 files changed, 9 insertions(+), 9 deletions(-) diff --git a/iguana/exchanges/LP_include.h b/iguana/exchanges/LP_include.h index 7d9b1d9ab..2d928676f 100644 --- a/iguana/exchanges/LP_include.h +++ b/iguana/exchanges/LP_include.h @@ -369,7 +369,7 @@ struct LP_pubkey_quote struct LP_pubkey_quote *next,*prev; float price; uint32_t maxutxo,aveutxo; - uint8_t baseind,relind,numrelutxos,scale; + uint8_t baseind,relind,numutxos,scale; }; #define LP_MAXPRICEINFOS 256 diff --git a/iguana/exchanges/LP_prices.c b/iguana/exchanges/LP_prices.c index 52ec96ee6..7245c19b2 100644 --- a/iguana/exchanges/LP_prices.c +++ b/iguana/exchanges/LP_prices.c @@ -49,10 +49,10 @@ struct LP_cacheinfo } *LP_cacheinfos; -float LP_pubkey_price(int32_t *numrelutxosp,int64_t *avesatoshisp,int64_t *maxsatoshisp,struct LP_pubkeyinfo *pubp,uint32_t baseind,uint32_t relind) +float LP_pubkey_price(int32_t *numutxosp,int64_t *avesatoshisp,int64_t *maxsatoshisp,struct LP_pubkeyinfo *pubp,uint32_t baseind,uint32_t relind) { struct LP_pubkey_quote *pq,*tmp; int32_t scale; int64_t scale64; - *numrelutxosp = 0; + *numutxosp = 0; *avesatoshisp = *maxsatoshisp = 0; DL_FOREACH_SAFE(pubp->quotes,pq,tmp) { @@ -66,7 +66,7 @@ float LP_pubkey_price(int32_t *numrelutxosp,int64_t *avesatoshisp,int64_t *maxsa scale64 *= 10; scale--; } - *numrelutxosp = pq->numrelutxos; + *numutxosp = pq->numutxos; *avesatoshisp = pq->aveutxo * scale64; *maxsatoshisp = pq->maxutxo * scale64; return(pq->price); @@ -103,9 +103,9 @@ void LP_pubkey_update(struct LP_pubkeyinfo *pubp,uint32_t baseind,uint32_t relin scale64 *= 10; scale--; } - if ( numutxos > (1L << sizeof(pq->numrelutxos)) ) - pq->numrelutxos = (1L << sizeof(pq->numrelutxos)) - 1; - else pq->numrelutxos = numutxos; + if ( numutxos > (1L << sizeof(pq->numutxos)) ) + pq->numutxos = (1L << sizeof(pq->numutxos)) - 1; + else pq->numutxos = numutxos; aveutxo = (balance + (scale64>>1)) / numutxos; if ( (ave64= (aveutxo / scale64)) > (1LL << 32) ) ave64 = (1LL << 32) - 1; @@ -114,7 +114,7 @@ void LP_pubkey_update(struct LP_pubkeyinfo *pubp,uint32_t baseind,uint32_t relin max64 = (1LL << 32) - 1; pq->aveutxo = (uint32_t)ave64; pq->maxutxo = (uint32_t)max64; - printf("base.%s rel.%s utxocoin.%s numutxos.%u %u scale64 = %llu, ave %llu, ave32 %u (%llu) max32 %u (%llu)\n",LP_priceinfos[baseind].symbol,LP_priceinfos[relind].symbol,utxocoin,numutxos,pq->numrelutxos,(long long)scale64,(long long)aveutxo,pq->aveutxo,(long long)pq->aveutxo * scale64,pq->maxutxo,(long long)pq->maxutxo * scale64); + //printf("base.%s rel.%s utxocoin.%s numutxos.%u %u scale64 = %llu, ave %llu, ave32 %u (%llu) max32 %u (%llu)\n",LP_priceinfos[baseind].symbol,LP_priceinfos[relind].symbol,utxocoin,numutxos,pq->numutxos,(long long)scale64,(long long)aveutxo,pq->aveutxo,(long long)pq->aveutxo * scale64,pq->maxutxo,(long long)pq->maxutxo * scale64); } } diff --git a/iguana/exchanges/LP_signatures.c b/iguana/exchanges/LP_signatures.c index 2253bcc09..6e99495cb 100644 --- a/iguana/exchanges/LP_signatures.c +++ b/iguana/exchanges/LP_signatures.c @@ -472,7 +472,7 @@ char *LP_pricepings(void *ctx,char *myipaddr,int32_t pubsock,char *base,char *re { if ( (numutxos= LP_address_minmax(&balance,&minsize,&maxsize,ap)) != 0 ) { - printf("%s numutxos.%d balance %.8f min %.8f max %.8f\n",base,numutxos,dstr(balance),dstr(minsize),dstr(maxsize)); + //printf("%s numutxos.%d balance %.8f min %.8f max %.8f\n",base,numutxos,dstr(balance),dstr(minsize),dstr(maxsize)); jaddstr(reqjson,"utxocoin",base); jaddnum(reqjson,"n",numutxos); jaddnum(reqjson,"bal",dstr(balance)); From 0c5bb4bf96f15e2993bdebe138bf2f30c7b5c33a Mon Sep 17 00:00:00 2001 From: jl777 Date: Fri, 17 Nov 2017 16:45:24 +0200 Subject: [PATCH 0966/1664] Test --- iguana/exchanges/LP_prices.c | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/iguana/exchanges/LP_prices.c b/iguana/exchanges/LP_prices.c index 7245c19b2..6dcdedb52 100644 --- a/iguana/exchanges/LP_prices.c +++ b/iguana/exchanges/LP_prices.c @@ -114,7 +114,11 @@ void LP_pubkey_update(struct LP_pubkeyinfo *pubp,uint32_t baseind,uint32_t relin max64 = (1LL << 32) - 1; pq->aveutxo = (uint32_t)ave64; pq->maxutxo = (uint32_t)max64; - //printf("base.%s rel.%s utxocoin.%s numutxos.%u %u scale64 = %llu, ave %llu, ave32 %u (%llu) max32 %u (%llu)\n",LP_priceinfos[baseind].symbol,LP_priceinfos[relind].symbol,utxocoin,numutxos,pq->numutxos,(long long)scale64,(long long)aveutxo,pq->aveutxo,(long long)pq->aveutxo * scale64,pq->maxutxo,(long long)pq->maxutxo * scale64); + printf("base.%s rel.%s utxocoin.%s balance %.8f numutxos.%u %u scale64 = %llu, ave %llu, ave32 %u (%llu) max32 %u (%llu)\n",LP_priceinfos[baseind].symbol,LP_priceinfos[relind].symbol,utxocoin,dstr(balance),numutxos,pq->numutxos,(long long)scale64,(long long)aveutxo,pq->aveutxo,(long long)pq->aveutxo * scale64,pq->maxutxo,(long long)pq->maxutxo * scale64); + int64_t avesatoshis,maxsatoshis; + price = LP_pubkey_price(&numutxos,&avesatoshis,&maxsatoshis,pubp,baseind,relind); + printf("checkprice %.8f numutxos.%d ave %.8f max %.8f\n",price,numutxos,dstr(avesatoshis),dstr(maxsatoshis)); + } } From 33bf3c8a3cbd6ddf058c1bf3fa9cc45bf1515fb9 Mon Sep 17 00:00:00 2001 From: jl777 Date: Fri, 17 Nov 2017 16:51:15 +0200 Subject: [PATCH 0967/1664] Test --- iguana/exchanges/LP_prices.c | 11 +++++------ 1 file changed, 5 insertions(+), 6 deletions(-) diff --git a/iguana/exchanges/LP_prices.c b/iguana/exchanges/LP_prices.c index 6dcdedb52..53d3acc34 100644 --- a/iguana/exchanges/LP_prices.c +++ b/iguana/exchanges/LP_prices.c @@ -103,22 +103,21 @@ void LP_pubkey_update(struct LP_pubkeyinfo *pubp,uint32_t baseind,uint32_t relin scale64 *= 10; scale--; } - if ( numutxos > (1L << sizeof(pq->numutxos)) ) - pq->numutxos = (1L << sizeof(pq->numutxos)) - 1; + if ( numutxos >= 256 ) + pq->numutxos = 255; else pq->numutxos = numutxos; aveutxo = (balance + (scale64>>1)) / numutxos; - if ( (ave64= (aveutxo / scale64)) > (1LL << 32) ) + if ( (ave64= (aveutxo / scale64)) >= (1LL << 32) ) ave64 = (1LL << 32) - 1; max64 = ((maxutxo + (scale64>>1)) / scale64); - if ( max64 > (1LL << 32) ) + if ( max64 >= (1LL << 32) ) max64 = (1LL << 32) - 1; pq->aveutxo = (uint32_t)ave64; pq->maxutxo = (uint32_t)max64; - printf("base.%s rel.%s utxocoin.%s balance %.8f numutxos.%u %u scale64 = %llu, ave %llu, ave32 %u (%llu) max32 %u (%llu)\n",LP_priceinfos[baseind].symbol,LP_priceinfos[relind].symbol,utxocoin,dstr(balance),numutxos,pq->numutxos,(long long)scale64,(long long)aveutxo,pq->aveutxo,(long long)pq->aveutxo * scale64,pq->maxutxo,(long long)pq->maxutxo * scale64); + printf("price %.8f base.%s rel.%s utxocoin.%s balance %.8f numutxos.%u %u scale64 = %llu, ave %llu, ave32 %u (%llu) max32 %u (%llu)\n",price,LP_priceinfos[baseind].symbol,LP_priceinfos[relind].symbol,utxocoin,dstr(balance),numutxos,pq->numutxos,(long long)scale64,(long long)aveutxo,pq->aveutxo,(long long)pq->aveutxo * scale64,pq->maxutxo,(long long)pq->maxutxo * scale64); int64_t avesatoshis,maxsatoshis; price = LP_pubkey_price(&numutxos,&avesatoshis,&maxsatoshis,pubp,baseind,relind); printf("checkprice %.8f numutxos.%d ave %.8f max %.8f\n",price,numutxos,dstr(avesatoshis),dstr(maxsatoshis)); - } } From 9e568b10659713d03ba9e1b5c9f7412f2483c0e5 Mon Sep 17 00:00:00 2001 From: jl777 Date: Fri, 17 Nov 2017 16:53:00 +0200 Subject: [PATCH 0968/1664] Test --- iguana/exchanges/LP_prices.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/iguana/exchanges/LP_prices.c b/iguana/exchanges/LP_prices.c index 53d3acc34..c18403704 100644 --- a/iguana/exchanges/LP_prices.c +++ b/iguana/exchanges/LP_prices.c @@ -114,10 +114,10 @@ void LP_pubkey_update(struct LP_pubkeyinfo *pubp,uint32_t baseind,uint32_t relin max64 = (1LL << 32) - 1; pq->aveutxo = (uint32_t)ave64; pq->maxutxo = (uint32_t)max64; - printf("price %.8f base.%s rel.%s utxocoin.%s balance %.8f numutxos.%u %u scale64 = %llu, ave %llu, ave32 %u (%llu) max32 %u (%llu)\n",price,LP_priceinfos[baseind].symbol,LP_priceinfos[relind].symbol,utxocoin,dstr(balance),numutxos,pq->numutxos,(long long)scale64,(long long)aveutxo,pq->aveutxo,(long long)pq->aveutxo * scale64,pq->maxutxo,(long long)pq->maxutxo * scale64); - int64_t avesatoshis,maxsatoshis; - price = LP_pubkey_price(&numutxos,&avesatoshis,&maxsatoshis,pubp,baseind,relind); - printf("checkprice %.8f numutxos.%d ave %.8f max %.8f\n",price,numutxos,dstr(avesatoshis),dstr(maxsatoshis)); + //printf("price %.8f base.%s rel.%s utxocoin.%s balance %.8f numutxos.%u %u scale64 = %llu, ave %llu, ave32 %u (%llu) max32 %u (%llu)\n",price,LP_priceinfos[baseind].symbol,LP_priceinfos[relind].symbol,utxocoin,dstr(balance),numutxos,pq->numutxos,(long long)scale64,(long long)aveutxo,pq->aveutxo,(long long)pq->aveutxo * scale64,pq->maxutxo,(long long)pq->maxutxo * scale64); + //int64_t avesatoshis,maxsatoshis; + //price = LP_pubkey_price(&numutxos,&avesatoshis,&maxsatoshis,pubp,baseind,relind); + //printf("checkprice %.8f numutxos.%d ave %.8f max %.8f\n",price,numutxos,dstr(avesatoshis),dstr(maxsatoshis)); } } From df2fd85218add8aca41ea3f639a6428098179eee Mon Sep 17 00:00:00 2001 From: jl777 Date: Fri, 17 Nov 2017 17:04:03 +0200 Subject: [PATCH 0969/1664] Test --- iguana/exchanges/LP_prices.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/iguana/exchanges/LP_prices.c b/iguana/exchanges/LP_prices.c index c18403704..7c91647aa 100644 --- a/iguana/exchanges/LP_prices.c +++ b/iguana/exchanges/LP_prices.c @@ -763,7 +763,7 @@ struct LP_orderbookentry *LP_orderbookentry(char *address,char *base,char *rel,d op->price = price; op->numutxos = numutxos; op->avesatoshis = avesatoshis; - op->maxsatoshis = avesatoshis; + op->maxsatoshis = maxsatoshis; op->pubkey = pubkey; op->timestamp = timestamp; op->depth = balance; From d30ca25ed7b4fe76c1eced37065e09251d0559a5 Mon Sep 17 00:00:00 2001 From: jl777 Date: Fri, 17 Nov 2017 17:17:56 +0200 Subject: [PATCH 0970/1664] Test --- iguana/exchanges/LP_ordermatch.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/iguana/exchanges/LP_ordermatch.c b/iguana/exchanges/LP_ordermatch.c index 7e440d990..d1ad77b2d 100644 --- a/iguana/exchanges/LP_ordermatch.c +++ b/iguana/exchanges/LP_ordermatch.c @@ -405,7 +405,7 @@ struct LP_utxoinfo *LP_address_myutxopair(struct LP_utxoinfo *butxo,int32_t iamb printf("targetval %.8f vol %.8f price %.8f txfee %.8f %s %s\n",dstr(targetval),relvolume,price,dstr(txfee),coin->symbol,coinaddr); } mini = -1; - if ( targetval != 0 && (mini= LP_nearest_utxovalue(coin,coinaddr,utxos,m,targetval)) >= 0 ) + if ( targetval != 0 && (mini= LP_nearest_utxovalue(coin,coinaddr,utxos,m,targetval+txfee)) >= 0 ) { up = utxos[mini]; utxos[mini] = 0; @@ -1170,7 +1170,7 @@ char *LP_autobuy(void *ctx,char *myipaddr,int32_t mypubsock,char *base,char *rel printf("destsatoshis %.8f vs utxo %.8f this would have triggered an quote error -13\n",dstr(destsatoshis),dstr(autxo->payment.value)); return(clonestr("{\"error\":\"cant find alice utxo that is small enough\"}")); } - bestsatoshis = LP_basesatoshis(dstr(destsatoshis),maxprice,txfee,desttxfee); + bestsatoshis = 1.001 * LP_basesatoshis(dstr(destsatoshis),maxprice,txfee,desttxfee); memset(&B,0,sizeof(B)); strcpy(B.coin,base); if ( LP_quoteinfoinit(&Q,&B,rel,maxprice,bestsatoshis,destsatoshis) < 0 ) From 746dc87850fdff4128f43147540c20f7dcb41f62 Mon Sep 17 00:00:00 2001 From: jl777 Date: Fri, 17 Nov 2017 17:35:39 +0200 Subject: [PATCH 0971/1664] Test --- iguana/exchanges/LP_nativeDEX.c | 2 +- iguana/exchanges/LP_remember.c | 6 ++++++ iguana/exchanges/LP_swap.c | 9 +++++++++ 3 files changed, 16 insertions(+), 1 deletion(-) diff --git a/iguana/exchanges/LP_nativeDEX.c b/iguana/exchanges/LP_nativeDEX.c index 5b44da252..5c10f50ba 100644 --- a/iguana/exchanges/LP_nativeDEX.c +++ b/iguana/exchanges/LP_nativeDEX.c @@ -96,7 +96,7 @@ struct LP_address_utxo *LP_garbage_collector2; //uint32_t LP_deadman_switch; uint16_t LP_fixed_pairport,LP_publicport; -uint32_t LP_lastnonce,LP_counter; +uint32_t LP_lastnonce,LP_counter,LP_swap_endcritical,LP_swap_critical; int32_t LP_mybussock = -1; int32_t LP_mypubsock = -1; int32_t LP_mypullsock = -1; diff --git a/iguana/exchanges/LP_remember.c b/iguana/exchanges/LP_remember.c index 7889181bf..f5ea3229a 100644 --- a/iguana/exchanges/LP_remember.c +++ b/iguana/exchanges/LP_remember.c @@ -456,6 +456,12 @@ cJSON *LP_swap_json(struct LP_swap_remember *rswap) { cJSON *item,*array; int32_t i; item = cJSON_CreateObject(); + if ( LP_swap_endcritical < LP_swap_critical ) + { + jaddstr(item,"warning","swaps in critical section"); + jaddnum(item,"critical",LP_swap_critical); + jaddnum(item,"endcritical",LP_swap_endcritical); + } jaddnum(item,"expiration",rswap->expiration);// - INSTANTDEX_LOCKTIME*2); jaddnum(item,"tradeid",rswap->tradeid); jaddnum(item,"requestid",rswap->requestid); diff --git a/iguana/exchanges/LP_swap.c b/iguana/exchanges/LP_swap.c index e1c80d505..30329c864 100644 --- a/iguana/exchanges/LP_swap.c +++ b/iguana/exchanges/LP_swap.c @@ -796,6 +796,7 @@ void LP_bobloop(void *_swap) basilisk_bobdeposit_refund(swap,swap->I.putduration); //printf("depositlen.%d\n",swap->bobdeposit.I.datalen); LP_swapsfp_update(&swap->I.req); + LP_swap_critical = (uint32_t)time(NULL); if ( LP_waitfor(swap->N.pair,swap,LP_SWAPSTEP_TIMEOUT*10,LP_verify_otherfee) < 0 ) printf("error waiting for alicefee\n"); else if ( LP_swapdata_rawtxsend(swap->N.pair,swap,0x200,data,maxlen,&swap->bobdeposit,0x100,0) == 0 ) @@ -804,6 +805,7 @@ void LP_bobloop(void *_swap) printf("error waiting for alicepayment\n"); else { + LP_swap_critical = (uint32_t)time(NULL); if ( basilisk_bobscripts_set(swap,0,1) < 0 ) printf("error bobscripts payment\n"); else @@ -813,9 +815,11 @@ void LP_bobloop(void *_swap) else m = swap->I.aliceconfirms; while ( (n= LP_numconfirms(swap->I.alicestr,swap->alicepayment.I.destaddr,swap->alicepayment.I.signedtxid,0,1)) < m ) // sync with alice { + LP_swap_critical = (uint32_t)time(NULL); char str[65];printf("%d wait for alicepayment %s numconfs.%d %s %s\n",n,swap->alicepayment.I.destaddr,m,swap->I.alicestr,bits256_str(str,swap->alicepayment.I.signedtxid)); sleep(10); } + LP_swap_critical = (uint32_t)time(NULL); 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 ) @@ -826,6 +830,7 @@ void LP_bobloop(void *_swap) basilisk_bobpayment_reclaim(swap,swap->I.callduration); if ( swap->N.pair >= 0 ) nn_close(swap->N.pair), swap->N.pair = -1; + LP_swap_endcritical = (uint32_t)time(NULL); LP_swapwait(swap->I.req.requestid,swap->I.req.quoteid,LP_atomic_locktime(swap->I.bobstr,swap->I.alicestr)*2,30); } } @@ -857,6 +862,7 @@ void LP_aliceloop(void *_swap) else { LP_swapsfp_update(&swap->I.req); + LP_swap_critical = (uint32_t)time(NULL); if ( LP_swapdata_rawtxsend(swap->N.pair,swap,0x80,data,maxlen,&swap->myfee,0x40,0) == 0 ) printf("error sending alicefee\n"); else if ( LP_waitfor(swap->N.pair,swap,1800,LP_verify_bobdeposit) < 0 ) @@ -870,14 +876,17 @@ void LP_aliceloop(void *_swap) else m = swap->I.aliceconfirms; while ( (n= LP_numconfirms(swap->I.alicestr,swap->alicepayment.I.destaddr,swap->alicepayment.I.signedtxid,0,1)) < m ) { + LP_swap_critical = (uint32_t)time(NULL); char str[65];printf("%d wait for alicepayment %s numconfs.%d %s %s\n",n,swap->alicepayment.I.destaddr,m,swap->I.alicestr,bits256_str(str,swap->alicepayment.I.signedtxid)); sleep(10); } swap->sentflag = 1; + LP_swap_critical = (uint32_t)time(NULL); if ( LP_waitfor(swap->N.pair,swap,1800,LP_verify_bobpayment) < 0 ) printf("error waiting for bobpayment\n"); else { + LP_swap_endcritical = (uint32_t)time(NULL); while ( (n= LP_numconfirms(swap->I.bobstr,swap->bobpayment.I.destaddr,swap->bobpayment.I.signedtxid,0,1)) < swap->I.bobconfirms ) { char str[65];printf("%d wait for bobpayment %s numconfs.%d %s %s\n",n,swap->bobpayment.I.destaddr,swap->I.bobconfirms,swap->I.bobstr,bits256_str(str,swap->bobpayment.I.signedtxid)); From 547c86257e1ee82b05d47d58ab6a0d32a2f20f2a Mon Sep 17 00:00:00 2001 From: jl777 Date: Fri, 17 Nov 2017 17:53:31 +0200 Subject: [PATCH 0972/1664] Test --- iguana/exchanges/LP_nativeDEX.c | 3 --- 1 file changed, 3 deletions(-) diff --git a/iguana/exchanges/LP_nativeDEX.c b/iguana/exchanges/LP_nativeDEX.c index 5c10f50ba..bc988e680 100644 --- a/iguana/exchanges/LP_nativeDEX.c +++ b/iguana/exchanges/LP_nativeDEX.c @@ -17,9 +17,6 @@ // LP_nativeDEX.c // marketmaker // -// destpubkey -// if ( G.LP_pendingswaps != 0 ) return(-1); -// bot safe to exit? // BCH signing // alice waiting for bestprice // From c73392d51567a618b3e78195a08315d9f12569e8 Mon Sep 17 00:00:00 2001 From: jl777 Date: Fri, 17 Nov 2017 17:54:16 +0200 Subject: [PATCH 0973/1664] Test --- iguana/exchanges/LP_include.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/iguana/exchanges/LP_include.h b/iguana/exchanges/LP_include.h index 2d928676f..163408e7d 100644 --- a/iguana/exchanges/LP_include.h +++ b/iguana/exchanges/LP_include.h @@ -23,7 +23,7 @@ #define LP_MAJOR_VERSION "0" #define LP_MINOR_VERSION "1" -#define LP_BUILD_NUMBER "15096" +#define LP_BUILD_NUMBER "15256" #define LP_BARTERDEX_VERSION 1 #define LP_MAGICBITS 8 From ca982683cb04f51a4a3f072d501791fb4768ce11 Mon Sep 17 00:00:00 2001 From: jl777 Date: Fri, 17 Nov 2017 19:38:14 +0200 Subject: [PATCH 0974/1664] BCH fix? --- iguana/exchanges/LP_bitcoin.c | 10 +++++++--- iguana/exchanges/LP_nativeDEX.c | 5 ++++- iguana/exchanges/LP_transaction.c | 2 +- 3 files changed, 12 insertions(+), 5 deletions(-) diff --git a/iguana/exchanges/LP_bitcoin.c b/iguana/exchanges/LP_bitcoin.c index a9aa5751b..7c90807b1 100644 --- a/iguana/exchanges/LP_bitcoin.c +++ b/iguana/exchanges/LP_bitcoin.c @@ -2340,7 +2340,7 @@ int32_t iguana_scriptgen(uint8_t taddr,uint8_t pubtype,uint8_t p2shtype,int32_t return(scriptlen); } -int32_t bitcoin_scriptget(uint8_t taddr,uint8_t pubtype,uint8_t p2shtype,int32_t *hashtypep,uint32_t *sigsizep,uint32_t *pubkeysizep,uint8_t **userdatap,uint32_t *userdatalenp,struct vin_info *vp,uint8_t *scriptsig,int32_t len,int32_t spendtype) +int32_t bitcoin_scriptget(uint8_t taddr,uint8_t pubtype,uint8_t p2shtype,uint32_t *hashtypep,uint32_t *sigsizep,uint32_t *pubkeysizep,uint8_t **userdatap,uint32_t *userdatalenp,struct vin_info *vp,uint8_t *scriptsig,int32_t len,int32_t spendtype) { int32_t j,n,siglen,plen; uint8_t *p2shscript; j = n = 0; @@ -3248,7 +3248,7 @@ int32_t iguana_vinarray_check(cJSON *vinarray,bits256 txid,int32_t vout) int32_t iguana_rwmsgtx(uint8_t taddr,uint8_t pubtype,uint8_t p2shtype,uint8_t isPoS,int32_t height,int32_t rwflag,cJSON *json,uint8_t *serialized,int32_t maxsize,struct iguana_msgtx *msg,bits256 *txidp,char *vpnstr,uint8_t *extraspace,int32_t extralen,cJSON *vins,int32_t suppress_pubkeys,int32_t zcash); -bits256 bitcoin_sigtxid(uint8_t taddr,uint8_t pubtype,uint8_t p2shtype,uint8_t isPoS,int32_t height,uint8_t *serialized,int32_t maxlen,struct iguana_msgtx *msgtx,int32_t vini,uint8_t *spendscript,int32_t spendlen,int32_t hashtype,char *vpnstr,int32_t suppress_pubkeys,int32_t zcash) +bits256 bitcoin_sigtxid(uint8_t taddr,uint8_t pubtype,uint8_t p2shtype,uint8_t isPoS,int32_t height,uint8_t *serialized,int32_t maxlen,struct iguana_msgtx *msgtx,int32_t vini,uint8_t *spendscript,int32_t spendlen,uint32_t hashtype,char *vpnstr,int32_t suppress_pubkeys,int32_t zcash) { int32_t i,len; bits256 sigtxid,txid,revsigtxid; struct iguana_msgtx dest; dest = *msgtx; @@ -3500,8 +3500,12 @@ int32_t iguana_rwmsgtx(uint8_t taddr,uint8_t pubtype,uint8_t p2shtype,uint8_t is memset(sigtxid.bytes,0,sizeof(sigtxid)); if ( vins != 0 && jitem(vins,i) != 0 ) { + uint32_t sighash; iguana_vinobjset(&msg->vins[i],jitem(vins,i),spendscript,sizeof(spendscript)); - sigtxid = bitcoin_sigtxid(taddr,pubtype,p2shtype,isPoS,height,sigser,maxsize*2,msg,i,msg->vins[i].spendscript,msg->vins[i].spendlen,SIGHASH_ALL,vpnstr,suppress_pubkeys,zcash); + sighash = SIGHASH_ALL; + if ( zcash == LP_IS_BITCOINCASH ) + sighash |= SIGHASH_FORKID; + sigtxid = bitcoin_sigtxid(taddr,pubtype,p2shtype,isPoS,height,sigser,maxsize*2,msg,i,msg->vins[i].spendscript,msg->vins[i].spendlen,sighash,vpnstr,suppress_pubkeys,zcash); //printf("after vini.%d vinscript.%p spendscript.%p spendlen.%d (%s)\n",i,msg->vins[i].vinscript,msg->vins[i].spendscript,msg->vins[i].spendlen,jprint(jitem(vins,i),0)); if ( iguana_vinarray_check(vinarray,msg->vins[i].prev_hash,msg->vins[i].prev_vout) < 0 ) jaddi(vinarray,iguana_vinjson(&msg->vins[i],sigtxid)); diff --git a/iguana/exchanges/LP_nativeDEX.c b/iguana/exchanges/LP_nativeDEX.c index bc988e680..7de806d8a 100644 --- a/iguana/exchanges/LP_nativeDEX.c +++ b/iguana/exchanges/LP_nativeDEX.c @@ -19,7 +19,9 @@ // // BCH signing // alice waiting for bestprice -// +// MNZ getcoin strangeness +// improve critical section detection when parallel trades +// reduce mem: dont redundant store pubkey utxo info // previously, it used to show amount, kmd equiv, perc // dPoW security -> 4: KMD notarized, 5: BTC notarized, after next notary elections // bigendian architectures need to use little endian for sighash calcs @@ -887,6 +889,7 @@ void LPinit(uint16_t myport,uint16_t mypullport,uint16_t mypubport,uint16_t mybu char *myipaddr=0,version[64]; long filesize,n; int32_t valid,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(); sprintf(version,"Marketmaker %s.%s %s rsize.%ld",LP_MAJOR_VERSION,LP_MINOR_VERSION,LP_BUILD_NUMBER,sizeof(struct basilisk_request)); printf("%s %u\n",version,calc_crc32(0,version,(int32_t)strlen(version))); + //test_validate("02000000010e62f95ff5881de8853ce1a5ddbaad731a62879d719367f539103600f1895477010000006b483045022100c684a0871689519bd97f2e61275752124f0f1498360750c87cf99a8acf06fd8c022047e7e62a7bfd481599130e6f40c95833f6ed6f44aa8b6ead7b0ec86a738b98a041210361857e1ba609aadff520a2ca9886fe7548c7154fab2cbe108c3b0e1e7635eb1ffeffffff02a0860100000000001976a9146cfa0a987f4c8f2ffee7e9944ef0c86fcda9671d88ac1e6f0700000000001976a9147f4b7113f9e26d84b150f2cc6d219baaf27f884488ace6b00700"); if ( LP_MAXPRICEINFOS > 256 ) { printf("LP_MAXPRICEINFOS %d wont fit in a uint8_t, need to increase the width of the baseind and relind for struct LP_pubkey_quote\n",LP_MAXPRICEINFOS); diff --git a/iguana/exchanges/LP_transaction.c b/iguana/exchanges/LP_transaction.c index 133ee6c41..c1c3ab5bb 100644 --- a/iguana/exchanges/LP_transaction.c +++ b/iguana/exchanges/LP_transaction.c @@ -535,7 +535,7 @@ int32_t iguana_signrawtransaction(void *ctx,char *symbol,uint8_t wiftaddr,uint8_ { if ( msgtx->vins[i].p2shlen != 0 ) { - char coinaddr[64]; uint32_t userdatalen,sigsize,pubkeysize; uint8_t *userdata; int32_t j,k,hashtype,type,flag; struct vin_info mvin,mainvin; bits256 zero; + char coinaddr[64]; uint32_t userdatalen,hashtype,sigsize,pubkeysize; uint8_t *userdata; int32_t j,k,type,flag; struct vin_info mvin,mainvin; bits256 zero; memset(zero.bytes,0,sizeof(zero)); coinaddr[0] = 0; sigsize = 0; From 9501c31536bd464972d144906b4292f3c2b89940 Mon Sep 17 00:00:00 2001 From: jl777 Date: Sun, 19 Nov 2017 11:49:26 +0400 Subject: [PATCH 0975/1664] Test --- .gitignore | 4 ++ iguana/exchanges/LP_bitcoin.c | 33 +++++++++ iguana/exchanges/LP_include.h | 4 +- iguana/exchanges/LP_nativeDEX.c | 6 +- iguana/exchanges/LP_ordermatch.c | 6 +- iguana/exchanges/LP_transaction.c | 111 +++++++++++++++++++++++++++++- 6 files changed, 155 insertions(+), 9 deletions(-) diff --git a/.gitignore b/.gitignore index f6a9cbe17..c7962cf39 100755 --- a/.gitignore +++ b/.gitignore @@ -489,3 +489,7 @@ iguana/DB/PRICES/.tmpmarker iguana/DB/KMD/0/.tmpmarker *.swp + +iguana/myipaddr + +iguana/DB/UNSPENTS/.tmpmarker diff --git a/iguana/exchanges/LP_bitcoin.c b/iguana/exchanges/LP_bitcoin.c index 7c90807b1..1444658c9 100644 --- a/iguana/exchanges/LP_bitcoin.c +++ b/iguana/exchanges/LP_bitcoin.c @@ -2583,6 +2583,39 @@ int32_t iguana_calcrmd160(uint8_t taddr,uint8_t pubtype,uint8_t p2shtype,char *a return(vp->type); } +uint32_t iguana_vinscriptparse(uint8_t taddr,uint8_t pubtype,uint8_t p2shtype,struct vin_info *vp,uint32_t *sigsizep,uint32_t *pubkeysizep,uint32_t *p2shsizep,uint32_t *userdatalenp,uint8_t *vinscript,int32_t scriptlen) +{ + uint32_t hashtype; uint8_t *userdata = 0; + *sigsizep = *pubkeysizep = *p2shsizep = *userdatalenp = 0; + if ( bitcoin_scriptget(taddr,pubtype,p2shtype,&hashtype,sigsizep,pubkeysizep,&userdata,userdatalenp,vp,vinscript,scriptlen,0) < 0 ) + { + printf("iguana_vinscriptparse: error parsing vinscript?\n"); + return(-1); + } + if ( userdata != 0 && *userdatalenp > 0 ) + memcpy(vp->userdata,userdata,*userdatalenp); + if ( vp->type == IGUANA_SCRIPT_P2SH ) + { + *p2shsizep = vp->p2shlen + 1 + (vp->p2shlen >= 0xfd)*2; + //printf("P2SHSIZE.%d\n",*p2shsizep); + } + return(hashtype); +} + +/*char *iguana_scriptget(struct iguana_info *coin,char *scriptstr,char *asmstr,int32_t max,int32_t hdrsi,uint32_t unspentind,bits256 txid,int32_t vout,uint8_t *rmd160,int32_t type,uint8_t *pubkey33) +{ + int32_t scriptlen; uint8_t script[IGUANA_MAXSCRIPTSIZE]; struct vin_info V,*vp = &V; + memset(vp,0,sizeof(*vp)); + scriptstr[0] = 0; + if ( asmstr != 0 ) + asmstr[0] = 0; + if ( pubkey33 != 0 && bitcoin_pubkeylen(pubkey33) > 0 ) + memcpy(vp->signers[0].pubkey,pubkey33,33); + scriptlen = iguana_scriptgen(coin,&vp->M,&vp->N,vp->coinaddr,script,asmstr,rmd160,type,(const struct vin_info *)vp,vout); + init_hexbytes_noT(scriptstr,script,scriptlen); + return(scriptstr); +}*/ + cJSON *bitcoin_txscript(char *asmstr,char **vardata,int32_t numvars) { int32_t i; cJSON *scriptjson,*array; diff --git a/iguana/exchanges/LP_include.h b/iguana/exchanges/LP_include.h index 163408e7d..3bea50380 100644 --- a/iguana/exchanges/LP_include.h +++ b/iguana/exchanges/LP_include.h @@ -150,8 +150,8 @@ struct vin_signer { bits256 privkey; char coinaddr[64]; uint8_t siglen,sig[80],r struct vin_info { struct iguana_msgvin vin; uint64_t amount; cJSON *extras; bits256 sigtxid; - int32_t M,N,validmask,spendlen,type,p2shlen,numpubkeys,numsigs,height,hashtype,userdatalen,suppress_pubkeys,ignore_cltverr; - uint32_t sequence,unspentind; struct vin_signer signers[16]; char coinaddr[65]; + int32_t M,N,validmask,spendlen,type,p2shlen,numpubkeys,numsigs,height,userdatalen,suppress_pubkeys,ignore_cltverr; + uint32_t sequence,unspentind,hashtype; struct vin_signer signers[16]; char coinaddr[65]; uint8_t rmd160[20],spendscript[10000],p2shscript[10000],userdata[10000]; }; diff --git a/iguana/exchanges/LP_nativeDEX.c b/iguana/exchanges/LP_nativeDEX.c index 7de806d8a..f1b89a40b 100644 --- a/iguana/exchanges/LP_nativeDEX.c +++ b/iguana/exchanges/LP_nativeDEX.c @@ -17,7 +17,7 @@ // LP_nativeDEX.c // marketmaker // -// BCH signing +// BCH signing: FORKID_BCC = 0, FORKID_BTG = 79, // Atomic number AU // alice waiting for bestprice // MNZ getcoin strangeness // improve critical section detection when parallel trades @@ -679,6 +679,8 @@ void LP_initcoins(void *ctx,int32_t pubsock,cJSON *coins) printf("%s ",activecoins[i]); LP_coinfind(activecoins[i]); LP_priceinfoadd(activecoins[i]); + //test_validate("02000000010e62f95ff5881de8853ce1a5ddbaad731a62879d719367f539103600f1895477010000006b483045022100c684a0871689519bd97f2e61275752124f0f1498360750c87cf99a8acf06fd8c022047e7e62a7bfd481599130e6f40c95833f6ed6f44aa8b6ead7b0ec86a738b98a041210361857e1ba609aadff520a2ca9886fe7548c7154fab2cbe108c3b0e1e7635eb1ffeffffff02a0860100000000001976a9146cfa0a987f4c8f2ffee7e9944ef0c86fcda9671d88ac1e6f0700000000001976a9147f4b7113f9e26d84b150f2cc6d219baaf27f884488ace6b00700"); + //getchar(); if ( (coin= LP_coinfind(activecoins[i])) != 0 ) { if ( LP_getheight(coin) <= 0 ) @@ -889,7 +891,6 @@ void LPinit(uint16_t myport,uint16_t mypullport,uint16_t mypubport,uint16_t mybu char *myipaddr=0,version[64]; long filesize,n; int32_t valid,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(); sprintf(version,"Marketmaker %s.%s %s rsize.%ld",LP_MAJOR_VERSION,LP_MINOR_VERSION,LP_BUILD_NUMBER,sizeof(struct basilisk_request)); printf("%s %u\n",version,calc_crc32(0,version,(int32_t)strlen(version))); - //test_validate("02000000010e62f95ff5881de8853ce1a5ddbaad731a62879d719367f539103600f1895477010000006b483045022100c684a0871689519bd97f2e61275752124f0f1498360750c87cf99a8acf06fd8c022047e7e62a7bfd481599130e6f40c95833f6ed6f44aa8b6ead7b0ec86a738b98a041210361857e1ba609aadff520a2ca9886fe7548c7154fab2cbe108c3b0e1e7635eb1ffeffffff02a0860100000000001976a9146cfa0a987f4c8f2ffee7e9944ef0c86fcda9671d88ac1e6f0700000000001976a9147f4b7113f9e26d84b150f2cc6d219baaf27f884488ace6b00700"); if ( LP_MAXPRICEINFOS > 256 ) { printf("LP_MAXPRICEINFOS %d wont fit in a uint8_t, need to increase the width of the baseind and relind for struct LP_pubkey_quote\n",LP_MAXPRICEINFOS); @@ -1034,6 +1035,7 @@ void LPinit(uint16_t myport,uint16_t mypullport,uint16_t mypubport,uint16_t mybu exit(-1); } LP_initcoins(ctx,pubsock,coinsjson); + G.waiting = 1; LP_passphrase_init(passphrase,jstr(argjson,"gui")); #ifndef FROM_JS diff --git a/iguana/exchanges/LP_ordermatch.c b/iguana/exchanges/LP_ordermatch.c index d1ad77b2d..bc73ee840 100644 --- a/iguana/exchanges/LP_ordermatch.c +++ b/iguana/exchanges/LP_ordermatch.c @@ -757,10 +757,10 @@ int32_t LP_validSPV(char *symbol,char *coinaddr,bits256 txid,int32_t vout) if ( (tx= LP_transactionfind(coin,txid)) != 0 ) { if ( vout < tx->numvouts && tx->height > 0 ) + { + printf("added missing utxo for SPV checking\n"); LP_address_utxoadd((uint32_t)time(NULL),"LP_validSPV",coin,coinaddr,txid,vout,tx->outpoints[vout].value,tx->height,-1); - if ( tx->SPV <= 0 ) - return(-1); - return(0); + } } } if ( (up= LP_address_utxofind(coin,coinaddr,txid,vout)) != 0 ) diff --git a/iguana/exchanges/LP_transaction.c b/iguana/exchanges/LP_transaction.c index c1c3ab5bb..d61940855 100644 --- a/iguana/exchanges/LP_transaction.c +++ b/iguana/exchanges/LP_transaction.c @@ -619,6 +619,100 @@ int32_t iguana_signrawtransaction(void *ctx,char *symbol,uint8_t wiftaddr,uint8_ return(complete); } +char *iguana_validaterawtx(void *ctx,struct iguana_info *coin,struct iguana_msgtx *msgtx,uint8_t *extraspace,int32_t extralen,char *rawtx,int32_t mempool,int32_t suppress_pubkeys,int32_t zcash) +{ + bits256 signedtxid; struct iguana_msgvin vin; cJSON *log,*vins,*vouts,*txobj,*retjson; char *signedtx; int32_t plen,height,finalized = 1,i,len,maxsize,numinputs,numoutputs,complete; struct vin_info *V; uint8_t *serialized,*serialized2; uint32_t sigsize,pubkeysize,p2shsize,suffixlen; int64_t inputsum,outputsum; struct iguana_msgvout vout; + char *symbol; uint8_t wiftaddr,taddr,pubtype,p2shtype,isPoS; + height = coin->longestchain; + symbol = coin->symbol; + wiftaddr = coin->wiftaddr; + taddr = coin->taddr; + pubtype = coin->pubtype; + p2shtype = coin->p2shtype; + isPoS = coin->isPoS; + retjson = cJSON_CreateObject(); + inputsum = outputsum = numinputs = numoutputs = 0; + if ( rawtx != 0 && rawtx[0] != 0 ) + { + if ( (strlen(rawtx) & 1) != 0 ) + return(clonestr("{\"error\":\"rawtx hex has odd length\"}")); + memset(msgtx,0,sizeof(*msgtx)); + if ( (txobj= bitcoin_hex2json(taddr,pubtype,p2shtype,isPoS,height,&msgtx->txid,msgtx,rawtx,extraspace,extralen,0,0,suppress_pubkeys,zcash)) != 0 ) + { + maxsize = (int32_t)strlen(rawtx); + serialized = malloc(maxsize); + serialized2 = malloc(maxsize); + V = calloc(numinputs,sizeof(*V)); + if ( (vouts= jarray(&numoutputs,txobj,"vout")) > 0 ) + { + for (i=0; i 0 ) + outputsum += vout.value; + } + } + if ( (vins= jarray(&numinputs,txobj,"vin")) > 0 ) + { + len = 0; + for (i=0; ivins[i].spendscript = V[i].spendscript; + if ( (msgtx->vins[i].spendlen= V[i].spendlen) == 35 ) + { + if ( (plen= bitcoin_pubkeylen(msgtx->vins[i].spendscript+1)) > 0 ) + { + memcpy(V[i].signers[0].pubkey,msgtx->vins[i].spendscript+1,plen); + V[i].suppress_pubkeys = 1; + } + } + V[i].hashtype = iguana_vinscriptparse(taddr,pubtype,p2shtype,&V[i],&sigsize,&pubkeysize,&p2shsize,&suffixlen,msgtx->vins[i].vinscript,msgtx->vins[i].scriptlen); + if ( (V[i].signers[0].siglen= sigsize) > 0 ) + memcpy(V[i].signers[0].sig,msgtx->vins[i].vinscript+1,sigsize); + V[i].userdatalen = suffixlen; + memcpy(V[i].spendscript,msgtx->vins[i].spendscript,msgtx->vins[i].spendlen); + V[i].spendlen = msgtx->vins[i].spendlen; + if ( msgtx->vins[i].sequence < IGUANA_SEQUENCEID_FINAL ) + finalized = 0; + if ( V[i].M == 0 ) + V[i].M = 1; + if ( V[i].N < V[i].M ) + V[i].N = V[i].M; + printf("V %dof%d %.8f (%s) spendscript.[%d] scriptlen.%d\n",V[i].M,V[i].N,dstr(V[i].amount),V[i].coinaddr,V[i].spendlen,V[i].spendlen); + } + complete = bitcoin_verifyvins(ctx,symbol,taddr,pubtype,p2shtype,isPoS,height,&signedtxid,&signedtx,msgtx,serialized2,maxsize,V,SIGHASH_ALL,1,V->suppress_pubkeys,LP_IS_BITCOINCASH); + msgtx->txid = signedtxid; + log = cJSON_CreateArray(); + if ( iguana_interpreter(ctx,log,0,V,numinputs) < 0 ) + jaddstr(retjson,"error","interpreter rejects tx"); + else complete = 1; + jadd(retjson,"interpreter",log); + jaddnum(retjson,"complete",complete); + free(serialized), free(serialized2); + if ( signedtx != 0 ) + free(signedtx); + free(V); + } + } + //char str[65]; printf("got txid.(%s)\n",bits256_str(str,txid)); + } + msgtx->inputsum = inputsum; + msgtx->numinputs = numinputs; + msgtx->outputsum = outputsum; + msgtx->numoutputs = numoutputs; + msgtx->txfee = (inputsum - outputsum); + return(jprint(retjson,1)); +} + +void test_validate(char *signedtx) +{ + char *retstr; uint8_t extraspace[8192]; int32_t mempool=0; struct iguana_msgtx msgtx; struct iguana_info *coin = LP_coinfind("BTC"); + retstr = iguana_validaterawtx(bitcoin_ctx(),coin,&msgtx,extraspace,sizeof(extraspace),signedtx,mempool,0,coin->zcash); + printf("validate test.(%s)\n",retstr); +} + char *basilisk_swap_bobtxspend(bits256 *signedtxidp,uint64_t txfee,char *name,char *symbol,uint8_t wiftaddr,uint8_t taddr,uint8_t pubtype,uint8_t p2shtype,uint8_t isPoS,uint8_t wiftype,void *ctx,bits256 privkey,bits256 *privkey2p,uint8_t *redeemscript,int32_t redeemlen,uint8_t *userdata,int32_t userdatalen,bits256 utxotxid,int32_t utxovout,char *destaddr,uint8_t *pubkey33,int32_t finalseqid,uint32_t expiration,int64_t *destamountp,uint64_t satoshis,char *changeaddr,char *vinaddr,int32_t suppress_pubkeys,int32_t zcash) { char *rawtxbytes=0,*signedtx=0,str[65],tmpaddr[64],hexstr[999],wifstr[128],_destaddr[64]; uint8_t spendscript[512],addrtype,rmd160[20]; cJSON *txobj,*vins,*obj,*vouts,*item,*privkeys; int32_t completed,spendlen,n,ignore_cltverr=1; struct vin_info V[8]; uint32_t timestamp,locktime = 0,sequenceid = 0xffffffff * finalseqid; bits256 txid; uint64_t value=0,change = 0; struct iguana_msgtx msgtx; struct iguana_info *coin; @@ -933,11 +1027,24 @@ int32_t LP_vins_select(void *ctx,struct iguana_info *coin,int64_t *totalp,int64_ } } if ( dustcombine >= 1 && min0 != 0 && min0->U.value < LP_DUSTCOMBINE_THRESHOLD && (coin->electrum == 0 || min0->SPV > 0) ) - preselected[numpre++] = min0; + { + for (j=0; j= 2 && min1 != 0 && min1->U.value < LP_DUSTCOMBINE_THRESHOLD && (coin->electrum == 0 || min1->SPV > 0) ) - preselected[numpre++] = min1; + { + for (j=0; j Date: Sun, 19 Nov 2017 15:52:13 +0400 Subject: [PATCH 0976/1664] Test --- iguana/exchanges/LP_nativeDEX.c | 4 ++-- iguana/exchanges/LP_transaction.c | 1 + 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/iguana/exchanges/LP_nativeDEX.c b/iguana/exchanges/LP_nativeDEX.c index f1b89a40b..b5338922d 100644 --- a/iguana/exchanges/LP_nativeDEX.c +++ b/iguana/exchanges/LP_nativeDEX.c @@ -679,8 +679,8 @@ void LP_initcoins(void *ctx,int32_t pubsock,cJSON *coins) printf("%s ",activecoins[i]); LP_coinfind(activecoins[i]); LP_priceinfoadd(activecoins[i]); - //test_validate("02000000010e62f95ff5881de8853ce1a5ddbaad731a62879d719367f539103600f1895477010000006b483045022100c684a0871689519bd97f2e61275752124f0f1498360750c87cf99a8acf06fd8c022047e7e62a7bfd481599130e6f40c95833f6ed6f44aa8b6ead7b0ec86a738b98a041210361857e1ba609aadff520a2ca9886fe7548c7154fab2cbe108c3b0e1e7635eb1ffeffffff02a0860100000000001976a9146cfa0a987f4c8f2ffee7e9944ef0c86fcda9671d88ac1e6f0700000000001976a9147f4b7113f9e26d84b150f2cc6d219baaf27f884488ace6b00700"); - //getchar(); + test_validate("02000000010e62f95ff5881de8853ce1a5ddbaad731a62879d719367f539103600f1895477010000006b483045022100c684a0871689519bd97f2e61275752124f0f1498360750c87cf99a8acf06fd8c022047e7e62a7bfd481599130e6f40c95833f6ed6f44aa8b6ead7b0ec86a738b98a041210361857e1ba609aadff520a2ca9886fe7548c7154fab2cbe108c3b0e1e7635eb1ffeffffff02a0860100000000001976a9146cfa0a987f4c8f2ffee7e9944ef0c86fcda9671d88ac1e6f0700000000001976a9147f4b7113f9e26d84b150f2cc6d219baaf27f884488ace6b00700"); + getchar(); if ( (coin= LP_coinfind(activecoins[i])) != 0 ) { if ( LP_getheight(coin) <= 0 ) diff --git a/iguana/exchanges/LP_transaction.c b/iguana/exchanges/LP_transaction.c index d61940855..84ea96cd8 100644 --- a/iguana/exchanges/LP_transaction.c +++ b/iguana/exchanges/LP_transaction.c @@ -656,6 +656,7 @@ char *iguana_validaterawtx(void *ctx,struct iguana_info *coin,struct iguana_msgt len = 0; for (i=0; i Date: Sun, 19 Nov 2017 16:16:11 +0400 Subject: [PATCH 0977/1664] Test --- iguana/exchanges/LP_transaction.c | 17 ++++++++++++++--- 1 file changed, 14 insertions(+), 3 deletions(-) diff --git a/iguana/exchanges/LP_transaction.c b/iguana/exchanges/LP_transaction.c index 84ea96cd8..0b9eccda1 100644 --- a/iguana/exchanges/LP_transaction.c +++ b/iguana/exchanges/LP_transaction.c @@ -621,7 +621,7 @@ int32_t iguana_signrawtransaction(void *ctx,char *symbol,uint8_t wiftaddr,uint8_ char *iguana_validaterawtx(void *ctx,struct iguana_info *coin,struct iguana_msgtx *msgtx,uint8_t *extraspace,int32_t extralen,char *rawtx,int32_t mempool,int32_t suppress_pubkeys,int32_t zcash) { - bits256 signedtxid; struct iguana_msgvin vin; cJSON *log,*vins,*vouts,*txobj,*retjson; char *signedtx; int32_t plen,height,finalized = 1,i,len,maxsize,numinputs,numoutputs,complete; struct vin_info *V; uint8_t *serialized,*serialized2; uint32_t sigsize,pubkeysize,p2shsize,suffixlen; int64_t inputsum,outputsum; struct iguana_msgvout vout; + bits256 signedtxid; struct iguana_msgvin vin; cJSON *log,*item,*vins,*vouts,*txobj,*retjson; char *signedtx; int32_t plen,height,finalized = 1,i,len,maxsize,numinputs,numoutputs,complete; struct vin_info *V; uint8_t *serialized,*serialized2; uint32_t sigsize,pubkeysize,p2shsize,suffixlen; int64_t inputsum,outputsum; struct iguana_msgvout vout; char *symbol; uint8_t wiftaddr,taddr,pubtype,p2shtype,isPoS; height = coin->longestchain; symbol = coin->symbol; @@ -656,8 +656,15 @@ char *iguana_validaterawtx(void *ctx,struct iguana_info *coin,struct iguana_msgt len = 0; for (i=0; ivins[i].spendscript = V[i].spendscript; @@ -669,6 +676,10 @@ char *iguana_validaterawtx(void *ctx,struct iguana_info *coin,struct iguana_msgt V[i].suppress_pubkeys = 1; } } + else if ( msgtx->vins[i].spendlen == 25 ) + { + V[i].suppress_pubkeys = 0; + } V[i].hashtype = iguana_vinscriptparse(taddr,pubtype,p2shtype,&V[i],&sigsize,&pubkeysize,&p2shsize,&suffixlen,msgtx->vins[i].vinscript,msgtx->vins[i].scriptlen); if ( (V[i].signers[0].siglen= sigsize) > 0 ) memcpy(V[i].signers[0].sig,msgtx->vins[i].vinscript+1,sigsize); @@ -681,7 +692,7 @@ char *iguana_validaterawtx(void *ctx,struct iguana_info *coin,struct iguana_msgt V[i].M = 1; if ( V[i].N < V[i].M ) V[i].N = V[i].M; - printf("V %dof%d %.8f (%s) spendscript.[%d] scriptlen.%d\n",V[i].M,V[i].N,dstr(V[i].amount),V[i].coinaddr,V[i].spendlen,V[i].spendlen); + printf("V %dof%d %.8f (%s) spendscript.[%d] scriptlen.%d siglen.%d hashtype.%d\n",V[i].M,V[i].N,dstr(V[i].amount),V[i].coinaddr,V[i].spendlen,V[i].spendlen,sigsize,V[i].hashtype); } complete = bitcoin_verifyvins(ctx,symbol,taddr,pubtype,p2shtype,isPoS,height,&signedtxid,&signedtx,msgtx,serialized2,maxsize,V,SIGHASH_ALL,1,V->suppress_pubkeys,LP_IS_BITCOINCASH); msgtx->txid = signedtxid; From 06995b5fd93346d440637d90e3517037aa6d717c Mon Sep 17 00:00:00 2001 From: jl777 Date: Sun, 19 Nov 2017 16:21:43 +0400 Subject: [PATCH 0978/1664] Test --- iguana/exchanges/LP_bitcoin.c | 12 +++--------- 1 file changed, 3 insertions(+), 9 deletions(-) diff --git a/iguana/exchanges/LP_bitcoin.c b/iguana/exchanges/LP_bitcoin.c index 1444658c9..3f78f63f0 100644 --- a/iguana/exchanges/LP_bitcoin.c +++ b/iguana/exchanges/LP_bitcoin.c @@ -2353,13 +2353,13 @@ int32_t bitcoin_scriptget(uint8_t taddr,uint8_t pubtype,uint8_t p2shtype,uint32_ memcpy(vp->signers[j].sig,&scriptsig[n+1],siglen); if ( j == 0 ) *hashtypep = vp->signers[j].sig[siglen-1]; - else if ( vp->signers[j].sig[siglen-1] != *hashtypep ) + else if ( vp->signers[j].sig[siglen-1] != (*hashtypep & (~SIGHASH_FORKID)) ) { //printf("SIGHASH.%d mismatch %d vs %d\n",j,vp->signers[j].sig[siglen-1],*hashtypep); break; } (*sigsizep) += siglen; - //printf("sigsize %d [%02x]\n",*sigsizep,vp->signers[j].sig[siglen-1]); + printf("sigsize %d [%02x]\n",*sigsizep,vp->signers[j].sig[siglen-1]); n += (siglen + 1); j++; if ( spendtype == 0 && j > 1 ) @@ -2408,14 +2408,8 @@ int32_t bitcoin_scriptget(uint8_t taddr,uint8_t pubtype,uint8_t p2shtype,uint32_ } if ( *userdatap == p2shscript ) *userdatap = 0; - /*if ( len == 0 ) - { - // txid.(eccf7e3034189b851985d871f91384b8ee357cd47c3024736e5676eb2debb3f2).v1 - decode_hex(vp->rmd160,20,"010966776006953d5567439e5e39f86a0d273bee");//3564a74f9ddb4372301c49154605573d7d1a88fe"); - vp->type = IGUANA_SCRIPT_76A988AC; - }*/ vp->spendlen = iguana_scriptgen(taddr,pubtype,p2shtype,&vp->M,&vp->N,vp->coinaddr,vp->spendscript,0,vp->rmd160,vp->type,(const struct vin_info *)vp,vp->vin.prev_vout); - //printf("type.%d asmstr.(%s) spendlen.%d\n",vp->type,asmstr,vp->spendlen); +printf("type.%d asmstr.(%s) spendlen.%d\n",vp->type,asmstr,vp->spendlen); return(vp->spendlen); } From e044e0f96448ae7110332e08dc55b951ecc9bb22 Mon Sep 17 00:00:00 2001 From: jl777 Date: Sun, 19 Nov 2017 16:29:07 +0400 Subject: [PATCH 0979/1664] Test --- iguana/exchanges/LP_bitcoin.c | 1 - 1 file changed, 1 deletion(-) diff --git a/iguana/exchanges/LP_bitcoin.c b/iguana/exchanges/LP_bitcoin.c index 3f78f63f0..415c8cb4d 100644 --- a/iguana/exchanges/LP_bitcoin.c +++ b/iguana/exchanges/LP_bitcoin.c @@ -2409,7 +2409,6 @@ int32_t bitcoin_scriptget(uint8_t taddr,uint8_t pubtype,uint8_t p2shtype,uint32_ if ( *userdatap == p2shscript ) *userdatap = 0; vp->spendlen = iguana_scriptgen(taddr,pubtype,p2shtype,&vp->M,&vp->N,vp->coinaddr,vp->spendscript,0,vp->rmd160,vp->type,(const struct vin_info *)vp,vp->vin.prev_vout); -printf("type.%d asmstr.(%s) spendlen.%d\n",vp->type,asmstr,vp->spendlen); return(vp->spendlen); } From 1416694671e74882f7244cdc050043195df083d9 Mon Sep 17 00:00:00 2001 From: jl777 Date: Sun, 19 Nov 2017 16:32:53 +0400 Subject: [PATCH 0980/1664] Test --- iguana/exchanges/LP_bitcoin.c | 2 +- iguana/exchanges/LP_transaction.c | 4 +++- 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/iguana/exchanges/LP_bitcoin.c b/iguana/exchanges/LP_bitcoin.c index 415c8cb4d..5336ef23c 100644 --- a/iguana/exchanges/LP_bitcoin.c +++ b/iguana/exchanges/LP_bitcoin.c @@ -2355,7 +2355,7 @@ int32_t bitcoin_scriptget(uint8_t taddr,uint8_t pubtype,uint8_t p2shtype,uint32_ *hashtypep = vp->signers[j].sig[siglen-1]; else if ( vp->signers[j].sig[siglen-1] != (*hashtypep & (~SIGHASH_FORKID)) ) { - //printf("SIGHASH.%d mismatch %d vs %d\n",j,vp->signers[j].sig[siglen-1],*hashtypep); + printf("SIGHASH.%d mismatch %d vs %d\n",j,vp->signers[j].sig[siglen-1],*hashtypep); break; } (*sigsizep) += siglen; diff --git a/iguana/exchanges/LP_transaction.c b/iguana/exchanges/LP_transaction.c index 0b9eccda1..2e30a6aeb 100644 --- a/iguana/exchanges/LP_transaction.c +++ b/iguana/exchanges/LP_transaction.c @@ -662,7 +662,8 @@ char *iguana_validaterawtx(void *ctx,struct iguana_info *coin,struct iguana_msgt len += iguana_parsevinobj(&serialized[len],maxsize-len,&vin,jitem(vins,i),&V[i]); if ( strcmp(jstr(item,"txid"),"775489f100361039f56793719d87621a73adbadda5e13c85e81d88f55ff9620e") == 0 && jint(item,"vout") == 1 ) { - decode_hex(V[i].spendscript,25,"761914aa27d0ccbdcdd0f30fdbad3fa397b15b43e4c45688ac"); + V[i].spendlen = 25; + decode_hex(V[i].spendscript,V[i].spendlen,"761914aa27d0ccbdcdd0f30fdbad3fa397b15b43e4c45688ac"); V[i].amount = SATOSHIDEN * 0.00587427; } V[i].suppress_pubkeys = suppress_pubkeys; @@ -683,6 +684,7 @@ char *iguana_validaterawtx(void *ctx,struct iguana_info *coin,struct iguana_msgt V[i].hashtype = iguana_vinscriptparse(taddr,pubtype,p2shtype,&V[i],&sigsize,&pubkeysize,&p2shsize,&suffixlen,msgtx->vins[i].vinscript,msgtx->vins[i].scriptlen); if ( (V[i].signers[0].siglen= sigsize) > 0 ) memcpy(V[i].signers[0].sig,msgtx->vins[i].vinscript+1,sigsize); + printf("sigsize.%d hashtype.%d\n",sigsize,V[i].hashtype); V[i].userdatalen = suffixlen; memcpy(V[i].spendscript,msgtx->vins[i].spendscript,msgtx->vins[i].spendlen); V[i].spendlen = msgtx->vins[i].spendlen; From 08bd2f994e3da77be9b823a4bd509efc99c4ecad Mon Sep 17 00:00:00 2001 From: jl777 Date: Sun, 19 Nov 2017 16:43:43 +0400 Subject: [PATCH 0981/1664] Test --- iguana/exchanges/LP_bitcoin.c | 1 + iguana/exchanges/LP_transaction.c | 5 +++-- 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/iguana/exchanges/LP_bitcoin.c b/iguana/exchanges/LP_bitcoin.c index 5336ef23c..255d753a2 100644 --- a/iguana/exchanges/LP_bitcoin.c +++ b/iguana/exchanges/LP_bitcoin.c @@ -2347,6 +2347,7 @@ int32_t bitcoin_scriptget(uint8_t taddr,uint8_t pubtype,uint8_t p2shtype,uint32_ *userdatap = 0; *userdatalenp = *pubkeysizep = *sigsizep = 0; *hashtypep = SIGHASH_ALL; + printf("siglen.%d\n",scriptsig[0]); while ( (siglen= scriptsig[n]) >= 70 && siglen <= 73 && n+siglen < len && j < 16 ) { vp->signers[j].siglen = siglen; diff --git a/iguana/exchanges/LP_transaction.c b/iguana/exchanges/LP_transaction.c index 2e30a6aeb..e35eb1dd6 100644 --- a/iguana/exchanges/LP_transaction.c +++ b/iguana/exchanges/LP_transaction.c @@ -658,14 +658,15 @@ char *iguana_validaterawtx(void *ctx,struct iguana_info *coin,struct iguana_msgt { item = jitem(vins,i); //vin.0 ({"sequence":4294967294,"txid":"775489f100361039f56793719d87621a73adbadda5e13c85e81d88f55ff9620e","vout":1,"scriptSig":{"hex":"483045022100c684a0871689519bd97f2e61275752124f0f1498360750c87cf99a8acf06fd8c022047e7e62a7bfd481599130e6f40c95833f6ed6f44aa8b6ead7b0ec86a738b98a041210361857e1ba609aadff520a2ca9886fe7548c7154fab2cbe108c3b0e1e7635eb1f","asm":"3045022100c684a0871689519bd97f2e61275752124f0f1498360750c87cf99a8acf06fd8c022047e7e62a7bfd481599130e6f40c95833f6ed6f44aa8b6ead7b0ec86a738b98a041 0361857e1ba609aadff520a2ca9886fe7548c7154fab2cbe108c3b0e1e7635eb1f"}}) - printf("vin.%d (%s)\n",i,jprint(item,0)); - len += iguana_parsevinobj(&serialized[len],maxsize-len,&vin,jitem(vins,i),&V[i]); + len += iguana_parsevinobj(&serialized[len],maxsize-len,&msgtx->vins[i],jitem(vins,i),&V[i]); if ( strcmp(jstr(item,"txid"),"775489f100361039f56793719d87621a73adbadda5e13c85e81d88f55ff9620e") == 0 && jint(item,"vout") == 1 ) { V[i].spendlen = 25; decode_hex(V[i].spendscript,V[i].spendlen,"761914aa27d0ccbdcdd0f30fdbad3fa397b15b43e4c45688ac"); V[i].amount = SATOSHIDEN * 0.00587427; + strcpy(V[i].coinaddr,"19MnNLzxNTNXWUdfxpQvWK3CPwFXJbmLb8"); } + printf("vin.%d (%s)\n",i,jprint(item,0)); V[i].suppress_pubkeys = suppress_pubkeys; inputsum += V[i].amount; msgtx->vins[i].spendscript = V[i].spendscript; From e4efb626e2b81ca4a20565f853ed6781455570a0 Mon Sep 17 00:00:00 2001 From: jl777 Date: Sun, 19 Nov 2017 16:52:06 +0400 Subject: [PATCH 0982/1664] Test --- iguana/exchanges/LP_transaction.c | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/iguana/exchanges/LP_transaction.c b/iguana/exchanges/LP_transaction.c index e35eb1dd6..6339f2096 100644 --- a/iguana/exchanges/LP_transaction.c +++ b/iguana/exchanges/LP_transaction.c @@ -621,7 +621,7 @@ int32_t iguana_signrawtransaction(void *ctx,char *symbol,uint8_t wiftaddr,uint8_ char *iguana_validaterawtx(void *ctx,struct iguana_info *coin,struct iguana_msgtx *msgtx,uint8_t *extraspace,int32_t extralen,char *rawtx,int32_t mempool,int32_t suppress_pubkeys,int32_t zcash) { - bits256 signedtxid; struct iguana_msgvin vin; cJSON *log,*item,*vins,*vouts,*txobj,*retjson; char *signedtx; int32_t plen,height,finalized = 1,i,len,maxsize,numinputs,numoutputs,complete; struct vin_info *V; uint8_t *serialized,*serialized2; uint32_t sigsize,pubkeysize,p2shsize,suffixlen; int64_t inputsum,outputsum; struct iguana_msgvout vout; + bits256 signedtxid; cJSON *log,*item,*vins,*vouts,*txobj,*retjson; char *scriptsig,*signedtx; int32_t plen,height,finalized = 1,i,len,maxsize,numinputs,numoutputs,complete; struct vin_info *V; uint8_t *serialized,*serialized2,sigspace[256]; uint32_t sigsize,pubkeysize,p2shsize,suffixlen; int64_t inputsum,outputsum; struct iguana_msgvout vout; char *symbol; uint8_t wiftaddr,taddr,pubtype,p2shtype,isPoS; height = coin->longestchain; symbol = coin->symbol; @@ -666,7 +666,7 @@ char *iguana_validaterawtx(void *ctx,struct iguana_info *coin,struct iguana_msgt V[i].amount = SATOSHIDEN * 0.00587427; strcpy(V[i].coinaddr,"19MnNLzxNTNXWUdfxpQvWK3CPwFXJbmLb8"); } - printf("vin.%d (%s)\n",i,jprint(item,0)); + printf("vin.%d (%s) scriptlen.%d\n",i,jprint(item,0),msgtx->vins[i].scriptlen); V[i].suppress_pubkeys = suppress_pubkeys; inputsum += V[i].amount; msgtx->vins[i].spendscript = V[i].spendscript; @@ -682,11 +682,11 @@ char *iguana_validaterawtx(void *ctx,struct iguana_info *coin,struct iguana_msgt { V[i].suppress_pubkeys = 0; } - V[i].hashtype = iguana_vinscriptparse(taddr,pubtype,p2shtype,&V[i],&sigsize,&pubkeysize,&p2shsize,&suffixlen,msgtx->vins[i].vinscript,msgtx->vins[i].scriptlen); - if ( (V[i].signers[0].siglen= sigsize) > 0 ) - memcpy(V[i].signers[0].sig,msgtx->vins[i].vinscript+1,sigsize); - printf("sigsize.%d hashtype.%d\n",sigsize,V[i].hashtype); - V[i].userdatalen = suffixlen; + //V[i].hashtype = iguana_vinscriptparse(taddr,pubtype,p2shtype,&V[i],&sigsize,&pubkeysize,&p2shsize,&suffixlen,msgtx->vins[i].vinscript,msgtx->vins[i].scriptlen); + //if ( (V[i].signers[0].siglen= sigsize) > 0 ) + // memcpy(V[i].signers[0].sig,msgtx->vins[i].vinscript+1,sigsize); + //printf("sigsize.%d hashtype.%d\n",sigsize,V[i].hashtype); + //V[i].userdatalen = suffixlen; memcpy(V[i].spendscript,msgtx->vins[i].spendscript,msgtx->vins[i].spendlen); V[i].spendlen = msgtx->vins[i].spendlen; if ( msgtx->vins[i].sequence < IGUANA_SEQUENCEID_FINAL ) @@ -695,7 +695,7 @@ char *iguana_validaterawtx(void *ctx,struct iguana_info *coin,struct iguana_msgt V[i].M = 1; if ( V[i].N < V[i].M ) V[i].N = V[i].M; - printf("V %dof%d %.8f (%s) spendscript.[%d] scriptlen.%d siglen.%d hashtype.%d\n",V[i].M,V[i].N,dstr(V[i].amount),V[i].coinaddr,V[i].spendlen,V[i].spendlen,sigsize,V[i].hashtype); + printf("V %dof%d %.8f (%s) spendscript.[%d] scriptlen.%d siglen.%d hashtype.%d\n",V[i].M,V[i].N,dstr(V[i].amount),V[i].coinaddr,V[i].spendlen,V[i].spendlen,msgtx->vins[i].vinscript[0],V[i].hashtype); } complete = bitcoin_verifyvins(ctx,symbol,taddr,pubtype,p2shtype,isPoS,height,&signedtxid,&signedtx,msgtx,serialized2,maxsize,V,SIGHASH_ALL,1,V->suppress_pubkeys,LP_IS_BITCOINCASH); msgtx->txid = signedtxid; From 1b5d611df44d85c74dc905827954b360aeec6a24 Mon Sep 17 00:00:00 2001 From: jl777 Date: Sun, 19 Nov 2017 16:59:54 +0400 Subject: [PATCH 0983/1664] Test --- iguana/exchanges/LP_transaction.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/iguana/exchanges/LP_transaction.c b/iguana/exchanges/LP_transaction.c index 6339f2096..5979e5c54 100644 --- a/iguana/exchanges/LP_transaction.c +++ b/iguana/exchanges/LP_transaction.c @@ -666,7 +666,6 @@ char *iguana_validaterawtx(void *ctx,struct iguana_info *coin,struct iguana_msgt V[i].amount = SATOSHIDEN * 0.00587427; strcpy(V[i].coinaddr,"19MnNLzxNTNXWUdfxpQvWK3CPwFXJbmLb8"); } - printf("vin.%d (%s) scriptlen.%d\n",i,jprint(item,0),msgtx->vins[i].scriptlen); V[i].suppress_pubkeys = suppress_pubkeys; inputsum += V[i].amount; msgtx->vins[i].spendscript = V[i].spendscript; @@ -687,14 +686,15 @@ char *iguana_validaterawtx(void *ctx,struct iguana_info *coin,struct iguana_msgt // memcpy(V[i].signers[0].sig,msgtx->vins[i].vinscript+1,sigsize); //printf("sigsize.%d hashtype.%d\n",sigsize,V[i].hashtype); //V[i].userdatalen = suffixlen; - memcpy(V[i].spendscript,msgtx->vins[i].spendscript,msgtx->vins[i].spendlen); - V[i].spendlen = msgtx->vins[i].spendlen; + //memcpy(V[i].spendscript,msgtx->vins[i].spendscript,msgtx->vins[i].spendlen); + //V[i].spendlen = msgtx->vins[i].spendlen; if ( msgtx->vins[i].sequence < IGUANA_SEQUENCEID_FINAL ) finalized = 0; if ( V[i].M == 0 ) V[i].M = 1; if ( V[i].N < V[i].M ) - V[i].N = V[i].M; + V[i].N = V[i].M; + printf("vin.%d (%s) scriptlen.%d spendlen.%d finalize.%d\n",i,jprint(item,0),msgtx->vins[i].scriptlen,V[i].spendlen,finalized); printf("V %dof%d %.8f (%s) spendscript.[%d] scriptlen.%d siglen.%d hashtype.%d\n",V[i].M,V[i].N,dstr(V[i].amount),V[i].coinaddr,V[i].spendlen,V[i].spendlen,msgtx->vins[i].vinscript[0],V[i].hashtype); } complete = bitcoin_verifyvins(ctx,symbol,taddr,pubtype,p2shtype,isPoS,height,&signedtxid,&signedtx,msgtx,serialized2,maxsize,V,SIGHASH_ALL,1,V->suppress_pubkeys,LP_IS_BITCOINCASH); From 124f6c5a954edda23d6078e8fca57e041d2aa47c Mon Sep 17 00:00:00 2001 From: jl777 Date: Sun, 19 Nov 2017 17:12:01 +0400 Subject: [PATCH 0984/1664] Test --- iguana/exchanges/LP_transaction.c | 37 +++++++++++++++++++++++++++---- 1 file changed, 33 insertions(+), 4 deletions(-) diff --git a/iguana/exchanges/LP_transaction.c b/iguana/exchanges/LP_transaction.c index 5979e5c54..431eb72c3 100644 --- a/iguana/exchanges/LP_transaction.c +++ b/iguana/exchanges/LP_transaction.c @@ -621,7 +621,7 @@ int32_t iguana_signrawtransaction(void *ctx,char *symbol,uint8_t wiftaddr,uint8_ char *iguana_validaterawtx(void *ctx,struct iguana_info *coin,struct iguana_msgtx *msgtx,uint8_t *extraspace,int32_t extralen,char *rawtx,int32_t mempool,int32_t suppress_pubkeys,int32_t zcash) { - bits256 signedtxid; cJSON *log,*item,*vins,*vouts,*txobj,*retjson; char *scriptsig,*signedtx; int32_t plen,height,finalized = 1,i,len,maxsize,numinputs,numoutputs,complete; struct vin_info *V; uint8_t *serialized,*serialized2,sigspace[256]; uint32_t sigsize,pubkeysize,p2shsize,suffixlen; int64_t inputsum,outputsum; struct iguana_msgvout vout; + bits256 signedtxid; cJSON *log,*item,*vins,*vouts,*txobj,*retjson,*sigobj; char *scriptsig,*signedtx; int32_t plen,sigsize,slen,height,finalized = 1,i,len,maxsize,numinputs,numoutputs,complete; struct vin_info *V; uint8_t *serialized,*serialized2,scriptbuf[256]; int64_t inputsum,outputsum; struct iguana_msgvout vout; char *symbol; uint8_t wiftaddr,taddr,pubtype,p2shtype,isPoS; height = coin->longestchain; symbol = coin->symbol; @@ -658,7 +658,6 @@ char *iguana_validaterawtx(void *ctx,struct iguana_info *coin,struct iguana_msgt { item = jitem(vins,i); //vin.0 ({"sequence":4294967294,"txid":"775489f100361039f56793719d87621a73adbadda5e13c85e81d88f55ff9620e","vout":1,"scriptSig":{"hex":"483045022100c684a0871689519bd97f2e61275752124f0f1498360750c87cf99a8acf06fd8c022047e7e62a7bfd481599130e6f40c95833f6ed6f44aa8b6ead7b0ec86a738b98a041210361857e1ba609aadff520a2ca9886fe7548c7154fab2cbe108c3b0e1e7635eb1f","asm":"3045022100c684a0871689519bd97f2e61275752124f0f1498360750c87cf99a8acf06fd8c022047e7e62a7bfd481599130e6f40c95833f6ed6f44aa8b6ead7b0ec86a738b98a041 0361857e1ba609aadff520a2ca9886fe7548c7154fab2cbe108c3b0e1e7635eb1f"}}) - len += iguana_parsevinobj(&serialized[len],maxsize-len,&msgtx->vins[i],jitem(vins,i),&V[i]); if ( strcmp(jstr(item,"txid"),"775489f100361039f56793719d87621a73adbadda5e13c85e81d88f55ff9620e") == 0 && jint(item,"vout") == 1 ) { V[i].spendlen = 25; @@ -666,6 +665,29 @@ char *iguana_validaterawtx(void *ctx,struct iguana_info *coin,struct iguana_msgt V[i].amount = SATOSHIDEN * 0.00587427; strcpy(V[i].coinaddr,"19MnNLzxNTNXWUdfxpQvWK3CPwFXJbmLb8"); } + msgtx->vins[i].spendscript = V[i].spendscript; + msgtx->vins[i].spendlen = V[i].spendlen; + if ( (sigobj= jobj(item,"scriptSig")) != 0 ) + { + if ( (scriptsig= jstr(sigobj,"hex")) != 0 ) + { + slen = (int32_t)strlen(scriptsig) >> 1; + if ( slen <= sizeof(scriptsig) ) + { + decode_hex(scriptbuf,slen,scriptsig); + if ( (sigsize= scriptbuf[0]) >= 72 && sigsize < 76 ) + { + memcpy(V[i].signers[0].sig,scriptbuf+1,sigsize-1); + V[i].signers[0].siglen = sigsize - 1; + V[i].hashtype = scriptbuf[sigsize-1]; + if ( scriptbuf[sigsize] == 33 ) + { + memcpy(V[i].signers[0].pubkey,&scriptbuf[sigsize+1],33); + } + } + } + } + } V[i].suppress_pubkeys = suppress_pubkeys; inputsum += V[i].amount; msgtx->vins[i].spendscript = V[i].spendscript; @@ -681,7 +703,14 @@ char *iguana_validaterawtx(void *ctx,struct iguana_info *coin,struct iguana_msgt { V[i].suppress_pubkeys = 0; } - //V[i].hashtype = iguana_vinscriptparse(taddr,pubtype,p2shtype,&V[i],&sigsize,&pubkeysize,&p2shsize,&suffixlen,msgtx->vins[i].vinscript,msgtx->vins[i].scriptlen); + /*struct vin_info + { + struct iguana_msgvin vin; uint64_t amount; cJSON *extras; bits256 sigtxid; + int32_t M,N,validmask,spendlen,type,p2shlen,numpubkeys,numsigs,height,userdatalen,suppress_pubkeys,ignore_cltverr; + uint32_t sequence,unspentind,hashtype; struct vin_signer signers[16]; char coinaddr[65]; + uint8_t rmd160[20],spendscript[10000],p2shscript[10000],userdata[10000]; + };*/ + //V[i].hashtype = iguana_vinscriptparse(taddr,pubtype,p2shtype,&V[i],&sigsize,&pubkeysize,&p2shsize,&suffixlen,msgtx->vins[i].vinscript,msgtx->vins[i].scriptlen); //if ( (V[i].signers[0].siglen= sigsize) > 0 ) // memcpy(V[i].signers[0].sig,msgtx->vins[i].vinscript+1,sigsize); //printf("sigsize.%d hashtype.%d\n",sigsize,V[i].hashtype); @@ -693,7 +722,7 @@ char *iguana_validaterawtx(void *ctx,struct iguana_info *coin,struct iguana_msgt if ( V[i].M == 0 ) V[i].M = 1; if ( V[i].N < V[i].M ) - V[i].N = V[i].M; + V[i].N = V[i].M; printf("vin.%d (%s) scriptlen.%d spendlen.%d finalize.%d\n",i,jprint(item,0),msgtx->vins[i].scriptlen,V[i].spendlen,finalized); printf("V %dof%d %.8f (%s) spendscript.[%d] scriptlen.%d siglen.%d hashtype.%d\n",V[i].M,V[i].N,dstr(V[i].amount),V[i].coinaddr,V[i].spendlen,V[i].spendlen,msgtx->vins[i].vinscript[0],V[i].hashtype); } From b69e450f57705dab4d8b2dc7dbb55c7fe54a1afd Mon Sep 17 00:00:00 2001 From: jl777 Date: Sun, 19 Nov 2017 17:14:08 +0400 Subject: [PATCH 0985/1664] Test --- iguana/exchanges/LP_transaction.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/iguana/exchanges/LP_transaction.c b/iguana/exchanges/LP_transaction.c index 431eb72c3..ff342bddb 100644 --- a/iguana/exchanges/LP_transaction.c +++ b/iguana/exchanges/LP_transaction.c @@ -674,6 +674,8 @@ char *iguana_validaterawtx(void *ctx,struct iguana_info *coin,struct iguana_msgt slen = (int32_t)strlen(scriptsig) >> 1; if ( slen <= sizeof(scriptsig) ) { + msgtx->vins[i].scriptlen = slen; + msgtx->vins[i].vinscript = scriptbuf; decode_hex(scriptbuf,slen,scriptsig); if ( (sigsize= scriptbuf[0]) >= 72 && sigsize < 76 ) { From 3866ec18a7cb0e82b2cde8f19e794bde42e8acf5 Mon Sep 17 00:00:00 2001 From: jl777 Date: Sun, 19 Nov 2017 17:27:38 +0400 Subject: [PATCH 0986/1664] Test --- iguana/exchanges/LP_transaction.c | 18 +++--------------- 1 file changed, 3 insertions(+), 15 deletions(-) diff --git a/iguana/exchanges/LP_transaction.c b/iguana/exchanges/LP_transaction.c index ff342bddb..450aaca4a 100644 --- a/iguana/exchanges/LP_transaction.c +++ b/iguana/exchanges/LP_transaction.c @@ -402,6 +402,7 @@ int32_t bitcoin_verifyvins(void *ctx,char *symbol,uint8_t taddr,uint8_t pubtype, vpnstr[0] = 0; *signedtx = 0; memset(signedtxidp,0,sizeof(*signedtxidp)); + printf("numvins.%d numvouts.%d\n",msgtx->tx_in,numvouts); for (vini=0; vinitx_in; vini++) { if ( V->p2shscript[0] != 0 && V->p2shlen != 0 ) @@ -420,6 +421,7 @@ int32_t bitcoin_verifyvins(void *ctx,char *symbol,uint8_t taddr,uint8_t pubtype, if ( zcash == LP_IS_BITCOINCASH ) sighash |= SIGHASH_FORKID; sigtxid = bitcoin_sigtxid(taddr,pubtype,p2shtype,isPoS,height,serialized,maxlen,msgtx,vini,script,scriptlen,sighash,vpnstr,suppress_pubkeys,zcash); + printf("scriptlen.%d siglen.%d\n",scriptlen,V[vini].signers[0].siglen); if ( bits256_nonz(sigtxid) != 0 ) { vp = &V[vini]; @@ -664,6 +666,7 @@ char *iguana_validaterawtx(void *ctx,struct iguana_info *coin,struct iguana_msgt decode_hex(V[i].spendscript,V[i].spendlen,"761914aa27d0ccbdcdd0f30fdbad3fa397b15b43e4c45688ac"); V[i].amount = SATOSHIDEN * 0.00587427; strcpy(V[i].coinaddr,"19MnNLzxNTNXWUdfxpQvWK3CPwFXJbmLb8"); + V[i].suppress_pubkeys = 0; } msgtx->vins[i].spendscript = V[i].spendscript; msgtx->vins[i].spendlen = V[i].spendlen; @@ -690,21 +693,7 @@ char *iguana_validaterawtx(void *ctx,struct iguana_info *coin,struct iguana_msgt } } } - V[i].suppress_pubkeys = suppress_pubkeys; inputsum += V[i].amount; - msgtx->vins[i].spendscript = V[i].spendscript; - if ( (msgtx->vins[i].spendlen= V[i].spendlen) == 35 ) - { - if ( (plen= bitcoin_pubkeylen(msgtx->vins[i].spendscript+1)) > 0 ) - { - memcpy(V[i].signers[0].pubkey,msgtx->vins[i].spendscript+1,plen); - V[i].suppress_pubkeys = 1; - } - } - else if ( msgtx->vins[i].spendlen == 25 ) - { - V[i].suppress_pubkeys = 0; - } /*struct vin_info { struct iguana_msgvin vin; uint64_t amount; cJSON *extras; bits256 sigtxid; @@ -726,7 +715,6 @@ char *iguana_validaterawtx(void *ctx,struct iguana_info *coin,struct iguana_msgt if ( V[i].N < V[i].M ) V[i].N = V[i].M; printf("vin.%d (%s) scriptlen.%d spendlen.%d finalize.%d\n",i,jprint(item,0),msgtx->vins[i].scriptlen,V[i].spendlen,finalized); - printf("V %dof%d %.8f (%s) spendscript.[%d] scriptlen.%d siglen.%d hashtype.%d\n",V[i].M,V[i].N,dstr(V[i].amount),V[i].coinaddr,V[i].spendlen,V[i].spendlen,msgtx->vins[i].vinscript[0],V[i].hashtype); } complete = bitcoin_verifyvins(ctx,symbol,taddr,pubtype,p2shtype,isPoS,height,&signedtxid,&signedtx,msgtx,serialized2,maxsize,V,SIGHASH_ALL,1,V->suppress_pubkeys,LP_IS_BITCOINCASH); msgtx->txid = signedtxid; From f1a97f4490989b18c9653f3d3fc8fd3e519e655a Mon Sep 17 00:00:00 2001 From: jl777 Date: Sun, 19 Nov 2017 17:31:55 +0400 Subject: [PATCH 0987/1664] Test --- iguana/exchanges/LP_transaction.c | 1 + 1 file changed, 1 insertion(+) diff --git a/iguana/exchanges/LP_transaction.c b/iguana/exchanges/LP_transaction.c index 450aaca4a..5e53fa46e 100644 --- a/iguana/exchanges/LP_transaction.c +++ b/iguana/exchanges/LP_transaction.c @@ -716,6 +716,7 @@ char *iguana_validaterawtx(void *ctx,struct iguana_info *coin,struct iguana_msgt V[i].N = V[i].M; printf("vin.%d (%s) scriptlen.%d spendlen.%d finalize.%d\n",i,jprint(item,0),msgtx->vins[i].scriptlen,V[i].spendlen,finalized); } + finalized = iguana_vininfo_create(taddr,pubtype,p2shtype,isPoS,serialized2,maxsize,msgtx,vins,numinputs,V); complete = bitcoin_verifyvins(ctx,symbol,taddr,pubtype,p2shtype,isPoS,height,&signedtxid,&signedtx,msgtx,serialized2,maxsize,V,SIGHASH_ALL,1,V->suppress_pubkeys,LP_IS_BITCOINCASH); msgtx->txid = signedtxid; log = cJSON_CreateArray(); From 887a16fca9c2f7817d66ed9375ac962a06189ebe Mon Sep 17 00:00:00 2001 From: jl777 Date: Sun, 19 Nov 2017 17:37:16 +0400 Subject: [PATCH 0988/1664] Test --- iguana/exchanges/LP_bitcoin.c | 2 +- iguana/exchanges/LP_transaction.c | 6 ++++-- 2 files changed, 5 insertions(+), 3 deletions(-) diff --git a/iguana/exchanges/LP_bitcoin.c b/iguana/exchanges/LP_bitcoin.c index 255d753a2..d687b409f 100644 --- a/iguana/exchanges/LP_bitcoin.c +++ b/iguana/exchanges/LP_bitcoin.c @@ -3411,7 +3411,7 @@ int32_t iguana_rwmsgtx(uint8_t taddr,uint8_t pubtype,uint8_t p2shtype,uint8_t is } for (i=0; itx_in; i++) { - //printf("vin.%d starts offset.%d numvins.%d\n",i,len,msg->tx_in); + printf("vin.%d starts offset.%d numvins.%d\n",i,len,msg->tx_in); if ( vins != 0 && jitem(vins,i) != 0 ) iguana_vinobjset(&msg->vins[i],jitem(vins,i),spendscript,sizeof(spendscript)); if ( (n= iguana_vinparse(rwflag,&serialized[len],&msg->vins[i])) < 0 ) diff --git a/iguana/exchanges/LP_transaction.c b/iguana/exchanges/LP_transaction.c index 5e53fa46e..28f42fac1 100644 --- a/iguana/exchanges/LP_transaction.c +++ b/iguana/exchanges/LP_transaction.c @@ -623,7 +623,7 @@ int32_t iguana_signrawtransaction(void *ctx,char *symbol,uint8_t wiftaddr,uint8_ char *iguana_validaterawtx(void *ctx,struct iguana_info *coin,struct iguana_msgtx *msgtx,uint8_t *extraspace,int32_t extralen,char *rawtx,int32_t mempool,int32_t suppress_pubkeys,int32_t zcash) { - bits256 signedtxid; cJSON *log,*item,*vins,*vouts,*txobj,*retjson,*sigobj; char *scriptsig,*signedtx; int32_t plen,sigsize,slen,height,finalized = 1,i,len,maxsize,numinputs,numoutputs,complete; struct vin_info *V; uint8_t *serialized,*serialized2,scriptbuf[256]; int64_t inputsum,outputsum; struct iguana_msgvout vout; + bits256 signedtxid; cJSON *log,*item,*vins,*vouts,*txobj,*retjson,*sigobj; char *scriptsig,*signedtx; int32_t j,plen,sigsize,slen,height,finalized = 1,i,len,maxsize,numinputs,numoutputs,complete; struct vin_info *V; uint8_t *serialized,*serialized2,scriptbuf[256]; int64_t inputsum,outputsum; struct iguana_msgvout vout; char *symbol; uint8_t wiftaddr,taddr,pubtype,p2shtype,isPoS; height = coin->longestchain; symbol = coin->symbol; @@ -714,7 +714,9 @@ char *iguana_validaterawtx(void *ctx,struct iguana_info *coin,struct iguana_msgt V[i].M = 1; if ( V[i].N < V[i].M ) V[i].N = V[i].M; - printf("vin.%d (%s) scriptlen.%d spendlen.%d finalize.%d\n",i,jprint(item,0),msgtx->vins[i].scriptlen,V[i].spendlen,finalized); + for (j=0; jvins[i].scriptlen; j++) + printf("%02x",msgtx->vins[i].vinscript[j]); + printf(" vin.%d (%s) scriptlen.%d spendlen.%d finalize.%d\n",i,jprint(item,0),msgtx->vins[i].scriptlen,V[i].spendlen,finalized); } finalized = iguana_vininfo_create(taddr,pubtype,p2shtype,isPoS,serialized2,maxsize,msgtx,vins,numinputs,V); complete = bitcoin_verifyvins(ctx,symbol,taddr,pubtype,p2shtype,isPoS,height,&signedtxid,&signedtx,msgtx,serialized2,maxsize,V,SIGHASH_ALL,1,V->suppress_pubkeys,LP_IS_BITCOINCASH); From d6f0fafd6b047ebe12215825002c3b89dbf68670 Mon Sep 17 00:00:00 2001 From: jl777 Date: Sun, 19 Nov 2017 17:44:36 +0400 Subject: [PATCH 0989/1664] Test --- iguana/exchanges/LP_bitcoin.c | 14 +++++++------- iguana/exchanges/LP_transaction.c | 5 +++-- 2 files changed, 10 insertions(+), 9 deletions(-) diff --git a/iguana/exchanges/LP_bitcoin.c b/iguana/exchanges/LP_bitcoin.c index d687b409f..26dfd22f6 100644 --- a/iguana/exchanges/LP_bitcoin.c +++ b/iguana/exchanges/LP_bitcoin.c @@ -3295,9 +3295,9 @@ bits256 bitcoin_sigtxid(uint8_t taddr,uint8_t pubtype,uint8_t p2shtype,uint8_t i { dest.vins[i].vinscript = spendscript; dest.vins[i].scriptlen = spendlen; - //int32_t j; for (j=0; j 0 ) // (dest.tx_in != 1 || bits256_nonz(dest.vins[0].prev_hash) != 0) && dest.vins[0].scriptlen > 0 && { #ifdef BTC2_VERSION @@ -3323,7 +3323,7 @@ bits256 bitcoin_sigtxid(uint8_t taddr,uint8_t pubtype,uint8_t p2shtype,uint8_t i revsigtxid = bits256_doublesha256(0,serialized,len); for (i=0; ilongestchain; symbol = coin->symbol; @@ -718,7 +718,8 @@ char *iguana_validaterawtx(void *ctx,struct iguana_info *coin,struct iguana_msgt printf("%02x",msgtx->vins[i].vinscript[j]); printf(" vin.%d (%s) scriptlen.%d spendlen.%d finalize.%d\n",i,jprint(item,0),msgtx->vins[i].scriptlen,V[i].spendlen,finalized); } - finalized = iguana_vininfo_create(taddr,pubtype,p2shtype,isPoS,serialized2,maxsize,msgtx,vins,numinputs,V); + if ( (txobj= bitcoin_hex2json(taddr,pubtype,p2shtype,isPoS,height,&msgtx->txid,msgtx,rawtx,extraspace,extralen,0,0,suppress_pubkeys,zcash)) != 0 ) + printf("updated.(%s)\n",jprint(txobj,0)); complete = bitcoin_verifyvins(ctx,symbol,taddr,pubtype,p2shtype,isPoS,height,&signedtxid,&signedtx,msgtx,serialized2,maxsize,V,SIGHASH_ALL,1,V->suppress_pubkeys,LP_IS_BITCOINCASH); msgtx->txid = signedtxid; log = cJSON_CreateArray(); From ed600d8592b2334d65e634c3d7a6c2800c7e9338 Mon Sep 17 00:00:00 2001 From: jl777 Date: Sun, 19 Nov 2017 17:55:43 +0400 Subject: [PATCH 0990/1664] Test --- iguana/exchanges/LP_transaction.c | 22 +++++++++++++--------- 1 file changed, 13 insertions(+), 9 deletions(-) diff --git a/iguana/exchanges/LP_transaction.c b/iguana/exchanges/LP_transaction.c index a97625b35..27a8dc293 100644 --- a/iguana/exchanges/LP_transaction.c +++ b/iguana/exchanges/LP_transaction.c @@ -402,7 +402,7 @@ int32_t bitcoin_verifyvins(void *ctx,char *symbol,uint8_t taddr,uint8_t pubtype, vpnstr[0] = 0; *signedtx = 0; memset(signedtxidp,0,sizeof(*signedtxidp)); - printf("numvins.%d numvouts.%d\n",msgtx->tx_in,numvouts); + printf("bitcoin_verifyvins numvins.%d numvouts.%d\n",msgtx->tx_in,numvouts); for (vini=0; vinitx_in; vini++) { if ( V->p2shscript[0] != 0 && V->p2shlen != 0 ) @@ -420,8 +420,9 @@ int32_t bitcoin_verifyvins(void *ctx,char *symbol,uint8_t taddr,uint8_t pubtype, } if ( zcash == LP_IS_BITCOINCASH ) sighash |= SIGHASH_FORKID; + printf("bitcoin_verifyvins scriptlen.%d siglen.%d\n",scriptlen,V[vini].signers[0].siglen); sigtxid = bitcoin_sigtxid(taddr,pubtype,p2shtype,isPoS,height,serialized,maxlen,msgtx,vini,script,scriptlen,sighash,vpnstr,suppress_pubkeys,zcash); - printf("scriptlen.%d siglen.%d\n",scriptlen,V[vini].signers[0].siglen); + printf("bitcoin_verifyvins scriptlen.%d siglen.%d\n",scriptlen,V[vini].signers[0].siglen); if ( bits256_nonz(sigtxid) != 0 ) { vp = &V[vini]; @@ -461,14 +462,14 @@ int32_t bitcoin_verifyvins(void *ctx,char *symbol,uint8_t taddr,uint8_t pubtype, { flag++; numsigs++; - /*int32_t z; char tmpaddr[64]; + int32_t z; char tmpaddr[64]; for (z=0; zsigners[j].pubkey[z]); bitcoin_address(tmpaddr,60,vp->signers[j].pubkey,33); - printf(" <- pub, SIG.%d.%d VERIFIED numsigs.%d vs M.%d %s\n",vini,j,numsigs,vp->M,tmpaddr);*/ + printf(" <- pub, SIG.%d.%d VERIFIED numsigs.%d vs M.%d %s\n",vini,j,numsigs,vp->M,tmpaddr); } } if ( numsigs >= vp->M ) @@ -623,7 +624,7 @@ int32_t iguana_signrawtransaction(void *ctx,char *symbol,uint8_t wiftaddr,uint8_ char *iguana_validaterawtx(void *ctx,struct iguana_info *coin,struct iguana_msgtx *msgtx,uint8_t *extraspace,int32_t extralen,char *rawtx,int32_t mempool,int32_t suppress_pubkeys,int32_t zcash) { - bits256 signedtxid; cJSON *log,*item,*vins,*vouts,*txobj,*retjson,*sigobj; char *scriptsig,*signedtx; int32_t j,sigsize,slen,height,finalized = 1,i,len,maxsize,numinputs,numoutputs,complete; struct vin_info *V; uint8_t *serialized,*serialized2,scriptbuf[256]; int64_t inputsum,outputsum; struct iguana_msgvout vout; + bits256 signedtxid; cJSON *log,*item,*vins,*vouts,*txobj,*retjson,*sobj; char *scriptsig,*signedtx; int32_t j,sigsize,slen,height,finalized = 1,i,len,maxsize,numinputs,numoutputs,complete; struct vin_info *V; uint8_t *serialized,*serialized2,scriptbuf[256]; int64_t inputsum,outputsum; struct iguana_msgvout vout; char *symbol; uint8_t wiftaddr,taddr,pubtype,p2shtype,isPoS; height = coin->longestchain; symbol = coin->symbol; @@ -667,12 +668,15 @@ char *iguana_validaterawtx(void *ctx,struct iguana_info *coin,struct iguana_msgt V[i].amount = SATOSHIDEN * 0.00587427; strcpy(V[i].coinaddr,"19MnNLzxNTNXWUdfxpQvWK3CPwFXJbmLb8"); V[i].suppress_pubkeys = 0; + sobj = cJSON_CreateObject(); + jaddstr(sobj,"hex","761914aa27d0ccbdcdd0f30fdbad3fa397b15b43e4c45688ac"); + jadd(item,"scriptPubKey",sobj); } msgtx->vins[i].spendscript = V[i].spendscript; msgtx->vins[i].spendlen = V[i].spendlen; - if ( (sigobj= jobj(item,"scriptSig")) != 0 ) + if ( (sobj= jobj(item,"scriptSig")) != 0 ) { - if ( (scriptsig= jstr(sigobj,"hex")) != 0 ) + if ( (scriptsig= jstr(sobj,"hex")) != 0 ) { slen = (int32_t)strlen(scriptsig) >> 1; if ( slen <= sizeof(scriptsig) ) @@ -716,11 +720,11 @@ char *iguana_validaterawtx(void *ctx,struct iguana_info *coin,struct iguana_msgt V[i].N = V[i].M; for (j=0; jvins[i].scriptlen; j++) printf("%02x",msgtx->vins[i].vinscript[j]); - printf(" vin.%d (%s) scriptlen.%d spendlen.%d finalize.%d\n",i,jprint(item,0),msgtx->vins[i].scriptlen,V[i].spendlen,finalized); + printf(" vin.%d (%s) scriptlen.%d spendlen.%d:%d finalize.%d\n",i,jprint(item,0),msgtx->vins[i].scriptlen,V[i].spendlen,msgtx->vins[i].spendlen,finalized); } if ( (txobj= bitcoin_hex2json(taddr,pubtype,p2shtype,isPoS,height,&msgtx->txid,msgtx,rawtx,extraspace,extralen,0,0,suppress_pubkeys,zcash)) != 0 ) printf("updated.(%s)\n",jprint(txobj,0)); - complete = bitcoin_verifyvins(ctx,symbol,taddr,pubtype,p2shtype,isPoS,height,&signedtxid,&signedtx,msgtx,serialized2,maxsize,V,SIGHASH_ALL,1,V->suppress_pubkeys,LP_IS_BITCOINCASH); + complete = bitcoin_verifyvins(ctx,symbol,taddr,pubtype,p2shtype,isPoS,height,&signedtxid,&signedtx,msgtx,serialized2,maxsize,V,SIGHASH_ALL,1,V[0].suppress_pubkeys,LP_IS_BITCOINCASH); msgtx->txid = signedtxid; log = cJSON_CreateArray(); if ( iguana_interpreter(ctx,log,0,V,numinputs) < 0 ) From 34cf4a326362775917c6da913bb0498cc703f01b Mon Sep 17 00:00:00 2001 From: jl777 Date: Sun, 19 Nov 2017 17:59:47 +0400 Subject: [PATCH 0991/1664] Test --- iguana/exchanges/LP_transaction.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/iguana/exchanges/LP_transaction.c b/iguana/exchanges/LP_transaction.c index 27a8dc293..3408a701d 100644 --- a/iguana/exchanges/LP_transaction.c +++ b/iguana/exchanges/LP_transaction.c @@ -468,7 +468,7 @@ int32_t bitcoin_verifyvins(void *ctx,char *symbol,uint8_t taddr,uint8_t pubtype, printf(" <- sig[%d]\n",j); for (z=0; z<33; z++) printf("%02x",vp->signers[j].pubkey[z]); - bitcoin_address(tmpaddr,60,vp->signers[j].pubkey,33); + bitcoin_address(tmpaddr,0,0,vp->signers[j].pubkey,33); printf(" <- pub, SIG.%d.%d VERIFIED numsigs.%d vs M.%d %s\n",vini,j,numsigs,vp->M,tmpaddr); } } From 32fbae71883cea149c5d34f746daa3cbfcbee273 Mon Sep 17 00:00:00 2001 From: jl777 Date: Sun, 19 Nov 2017 18:04:52 +0400 Subject: [PATCH 0992/1664] Test --- iguana/exchanges/LP_bitcoin.c | 21 ++++++++++----------- iguana/exchanges/LP_transaction.c | 10 +++++----- 2 files changed, 15 insertions(+), 16 deletions(-) diff --git a/iguana/exchanges/LP_bitcoin.c b/iguana/exchanges/LP_bitcoin.c index 26dfd22f6..4f9d60859 100644 --- a/iguana/exchanges/LP_bitcoin.c +++ b/iguana/exchanges/LP_bitcoin.c @@ -2347,7 +2347,6 @@ int32_t bitcoin_scriptget(uint8_t taddr,uint8_t pubtype,uint8_t p2shtype,uint32_ *userdatap = 0; *userdatalenp = *pubkeysizep = *sigsizep = 0; *hashtypep = SIGHASH_ALL; - printf("siglen.%d\n",scriptsig[0]); while ( (siglen= scriptsig[n]) >= 70 && siglen <= 73 && n+siglen < len && j < 16 ) { vp->signers[j].siglen = siglen; @@ -2356,11 +2355,11 @@ int32_t bitcoin_scriptget(uint8_t taddr,uint8_t pubtype,uint8_t p2shtype,uint32_ *hashtypep = vp->signers[j].sig[siglen-1]; else if ( vp->signers[j].sig[siglen-1] != (*hashtypep & (~SIGHASH_FORKID)) ) { - printf("SIGHASH.%d mismatch %d vs %d\n",j,vp->signers[j].sig[siglen-1],*hashtypep); + //printf("SIGHASH.%d mismatch %d vs %d\n",j,vp->signers[j].sig[siglen-1],*hashtypep); break; } (*sigsizep) += siglen; - printf("sigsize %d [%02x]\n",*sigsizep,vp->signers[j].sig[siglen-1]); + //printf("sigsize %d [%02x]\n",*sigsizep,vp->signers[j].sig[siglen-1]); n += (siglen + 1); j++; if ( spendtype == 0 && j > 1 ) @@ -3295,9 +3294,9 @@ bits256 bitcoin_sigtxid(uint8_t taddr,uint8_t pubtype,uint8_t p2shtype,uint8_t i { dest.vins[i].vinscript = spendscript; dest.vins[i].scriptlen = spendlen; - int32_t j; for (j=0; j 0 ) // (dest.tx_in != 1 || bits256_nonz(dest.vins[0].prev_hash) != 0) && dest.vins[0].scriptlen > 0 && { #ifdef BTC2_VERSION @@ -3323,7 +3322,7 @@ bits256 bitcoin_sigtxid(uint8_t taddr,uint8_t pubtype,uint8_t p2shtype,uint8_t i revsigtxid = bits256_doublesha256(0,serialized,len); for (i=0; itx_in; i++) { - printf("vin.%d starts offset.%d numvins.%d\n",i,len,msg->tx_in); + //printf("vin.%d starts offset.%d numvins.%d\n",i,len,msg->tx_in); if ( vins != 0 && jitem(vins,i) != 0 ) iguana_vinobjset(&msg->vins[i],jitem(vins,i),spendscript,sizeof(spendscript)); if ( (n= iguana_vinparse(rwflag,&serialized[len],&msg->vins[i])) < 0 ) diff --git a/iguana/exchanges/LP_transaction.c b/iguana/exchanges/LP_transaction.c index 3408a701d..f75c0b935 100644 --- a/iguana/exchanges/LP_transaction.c +++ b/iguana/exchanges/LP_transaction.c @@ -402,7 +402,7 @@ int32_t bitcoin_verifyvins(void *ctx,char *symbol,uint8_t taddr,uint8_t pubtype, vpnstr[0] = 0; *signedtx = 0; memset(signedtxidp,0,sizeof(*signedtxidp)); - printf("bitcoin_verifyvins numvins.%d numvouts.%d\n",msgtx->tx_in,numvouts); + //printf("bitcoin_verifyvins numvins.%d numvouts.%d\n",msgtx->tx_in,numvouts); for (vini=0; vinitx_in; vini++) { if ( V->p2shscript[0] != 0 && V->p2shlen != 0 ) @@ -420,9 +420,9 @@ int32_t bitcoin_verifyvins(void *ctx,char *symbol,uint8_t taddr,uint8_t pubtype, } if ( zcash == LP_IS_BITCOINCASH ) sighash |= SIGHASH_FORKID; - printf("bitcoin_verifyvins scriptlen.%d siglen.%d\n",scriptlen,V[vini].signers[0].siglen); + //printf("bitcoin_verifyvins scriptlen.%d siglen.%d\n",scriptlen,V[vini].signers[0].siglen); sigtxid = bitcoin_sigtxid(taddr,pubtype,p2shtype,isPoS,height,serialized,maxlen,msgtx,vini,script,scriptlen,sighash,vpnstr,suppress_pubkeys,zcash); - printf("bitcoin_verifyvins scriptlen.%d siglen.%d\n",scriptlen,V[vini].signers[0].siglen); + //printf("bitcoin_verifyvins scriptlen.%d siglen.%d\n",scriptlen,V[vini].signers[0].siglen); if ( bits256_nonz(sigtxid) != 0 ) { vp = &V[vini]; @@ -462,14 +462,14 @@ int32_t bitcoin_verifyvins(void *ctx,char *symbol,uint8_t taddr,uint8_t pubtype, { flag++; numsigs++; - int32_t z; char tmpaddr[64]; + /*int32_t z; char tmpaddr[64]; for (z=0; zsigners[j].pubkey[z]); bitcoin_address(tmpaddr,0,0,vp->signers[j].pubkey,33); - printf(" <- pub, SIG.%d.%d VERIFIED numsigs.%d vs M.%d %s\n",vini,j,numsigs,vp->M,tmpaddr); + printf(" <- pub, SIG.%d.%d VERIFIED numsigs.%d vs M.%d %s\n",vini,j,numsigs,vp->M,tmpaddr);*/ } } if ( numsigs >= vp->M ) From 635c8db17c7fc0cf527be7790fbeb19288826017 Mon Sep 17 00:00:00 2001 From: jl777 Date: Sun, 19 Nov 2017 18:06:06 +0400 Subject: [PATCH 0993/1664] Test --- iguana/exchanges/LP_nativeDEX.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/iguana/exchanges/LP_nativeDEX.c b/iguana/exchanges/LP_nativeDEX.c index b5338922d..488cdebbc 100644 --- a/iguana/exchanges/LP_nativeDEX.c +++ b/iguana/exchanges/LP_nativeDEX.c @@ -678,9 +678,9 @@ void LP_initcoins(void *ctx,int32_t pubsock,cJSON *coins) { printf("%s ",activecoins[i]); LP_coinfind(activecoins[i]); - LP_priceinfoadd(activecoins[i]); + //LP_priceinfoadd(activecoins[i]); test_validate("02000000010e62f95ff5881de8853ce1a5ddbaad731a62879d719367f539103600f1895477010000006b483045022100c684a0871689519bd97f2e61275752124f0f1498360750c87cf99a8acf06fd8c022047e7e62a7bfd481599130e6f40c95833f6ed6f44aa8b6ead7b0ec86a738b98a041210361857e1ba609aadff520a2ca9886fe7548c7154fab2cbe108c3b0e1e7635eb1ffeffffff02a0860100000000001976a9146cfa0a987f4c8f2ffee7e9944ef0c86fcda9671d88ac1e6f0700000000001976a9147f4b7113f9e26d84b150f2cc6d219baaf27f884488ace6b00700"); - getchar(); + //getchar(); if ( (coin= LP_coinfind(activecoins[i])) != 0 ) { if ( LP_getheight(coin) <= 0 ) From d58a8869c7bc34ca13d9aabcd0988b0e3ca0ad1f Mon Sep 17 00:00:00 2001 From: jl777 Date: Sun, 19 Nov 2017 18:19:33 +0400 Subject: [PATCH 0994/1664] BCH and BTG support (if signing works) --- iguana/exchanges/LP_bitcoin.c | 40 +++++++++++++++---------------- iguana/exchanges/LP_cache.c | 2 +- iguana/exchanges/LP_coins.c | 19 +++++++++++++++ iguana/exchanges/LP_include.h | 4 +++- iguana/exchanges/LP_swap.c | 2 +- iguana/exchanges/LP_transaction.c | 28 +++++++++++----------- 6 files changed, 57 insertions(+), 38 deletions(-) diff --git a/iguana/exchanges/LP_bitcoin.c b/iguana/exchanges/LP_bitcoin.c index 4f9d60859..ce483208f 100644 --- a/iguana/exchanges/LP_bitcoin.c +++ b/iguana/exchanges/LP_bitcoin.c @@ -2340,13 +2340,13 @@ int32_t iguana_scriptgen(uint8_t taddr,uint8_t pubtype,uint8_t p2shtype,int32_t return(scriptlen); } -int32_t bitcoin_scriptget(uint8_t taddr,uint8_t pubtype,uint8_t p2shtype,uint32_t *hashtypep,uint32_t *sigsizep,uint32_t *pubkeysizep,uint8_t **userdatap,uint32_t *userdatalenp,struct vin_info *vp,uint8_t *scriptsig,int32_t len,int32_t spendtype) +int32_t bitcoin_scriptget(char *symbol,uint8_t taddr,uint8_t pubtype,uint8_t p2shtype,uint32_t *hashtypep,uint32_t *sigsizep,uint32_t *pubkeysizep,uint8_t **userdatap,uint32_t *userdatalenp,struct vin_info *vp,uint8_t *scriptsig,int32_t len,int32_t spendtype,int32_t zcash) { int32_t j,n,siglen,plen; uint8_t *p2shscript; j = n = 0; *userdatap = 0; *userdatalenp = *pubkeysizep = *sigsizep = 0; - *hashtypep = SIGHASH_ALL; + *hashtypep = LP_sighash(symbol,zcash); while ( (siglen= scriptsig[n]) >= 70 && siglen <= 73 && n+siglen < len && j < 16 ) { vp->signers[j].siglen = siglen; @@ -2576,11 +2576,11 @@ int32_t iguana_calcrmd160(uint8_t taddr,uint8_t pubtype,uint8_t p2shtype,char *a return(vp->type); } -uint32_t iguana_vinscriptparse(uint8_t taddr,uint8_t pubtype,uint8_t p2shtype,struct vin_info *vp,uint32_t *sigsizep,uint32_t *pubkeysizep,uint32_t *p2shsizep,uint32_t *userdatalenp,uint8_t *vinscript,int32_t scriptlen) +/*uint32_t iguana_vinscriptparse(char *symbol,uint8_t taddr,uint8_t pubtype,uint8_t p2shtype,struct vin_info *vp,uint32_t *sigsizep,uint32_t *pubkeysizep,uint32_t *p2shsizep,uint32_t *userdatalenp,uint8_t *vinscript,int32_t scriptlen,int32_t zcash) { uint32_t hashtype; uint8_t *userdata = 0; *sigsizep = *pubkeysizep = *p2shsizep = *userdatalenp = 0; - if ( bitcoin_scriptget(taddr,pubtype,p2shtype,&hashtype,sigsizep,pubkeysizep,&userdata,userdatalenp,vp,vinscript,scriptlen,0) < 0 ) + if ( bitcoin_scriptget(symbol,taddr,pubtype,p2shtype,&hashtype,sigsizep,pubkeysizep,&userdata,userdatalenp,vp,vinscript,scriptlen,0,zcash) < 0 ) { printf("iguana_vinscriptparse: error parsing vinscript?\n"); return(-1); @@ -2593,7 +2593,7 @@ uint32_t iguana_vinscriptparse(uint8_t taddr,uint8_t pubtype,uint8_t p2shtype,st //printf("P2SHSIZE.%d\n",*p2shsizep); } return(hashtype); -} +}*/ /*char *iguana_scriptget(struct iguana_info *coin,char *scriptstr,char *asmstr,int32_t max,int32_t hdrsi,uint32_t unspentind,bits256 txid,int32_t vout,uint8_t *rmd160,int32_t type,uint8_t *pubkey33) { @@ -3033,7 +3033,7 @@ int32_t iguana_parsevinobj(uint8_t *serialized,int32_t maxsize,struct iguana_msg siglen = serialized[len + m++]; //if ( i == 0 && m == 1 && siglen == 0 ) // multisig backward compatible // continue; - if ( serialized[len + m + siglen - 1] == SIGHASH_ALL ) + if ( ((serialized[len + m + siglen - 1] & ~SIGHASH_FORKID) & 0xff) == SIGHASH_ALL ) memcpy(V->signers[i++].sig,&serialized[len + m],siglen); if ( (0) ) { @@ -3272,9 +3272,9 @@ int32_t iguana_vinarray_check(cJSON *vinarray,bits256 txid,int32_t vout) return(-1); } -int32_t iguana_rwmsgtx(uint8_t taddr,uint8_t pubtype,uint8_t p2shtype,uint8_t isPoS,int32_t height,int32_t rwflag,cJSON *json,uint8_t *serialized,int32_t maxsize,struct iguana_msgtx *msg,bits256 *txidp,char *vpnstr,uint8_t *extraspace,int32_t extralen,cJSON *vins,int32_t suppress_pubkeys,int32_t zcash); +int32_t iguana_rwmsgtx(char *symbol,uint8_t taddr,uint8_t pubtype,uint8_t p2shtype,uint8_t isPoS,int32_t height,int32_t rwflag,cJSON *json,uint8_t *serialized,int32_t maxsize,struct iguana_msgtx *msg,bits256 *txidp,char *vpnstr,uint8_t *extraspace,int32_t extralen,cJSON *vins,int32_t suppress_pubkeys,int32_t zcash); -bits256 bitcoin_sigtxid(uint8_t taddr,uint8_t pubtype,uint8_t p2shtype,uint8_t isPoS,int32_t height,uint8_t *serialized,int32_t maxlen,struct iguana_msgtx *msgtx,int32_t vini,uint8_t *spendscript,int32_t spendlen,uint32_t hashtype,char *vpnstr,int32_t suppress_pubkeys,int32_t zcash) +bits256 bitcoin_sigtxid(char *symbol,uint8_t taddr,uint8_t pubtype,uint8_t p2shtype,uint8_t isPoS,int32_t height,uint8_t *serialized,int32_t maxlen,struct iguana_msgtx *msgtx,int32_t vini,uint8_t *spendscript,int32_t spendlen,uint32_t hashtype,char *vpnstr,int32_t suppress_pubkeys,int32_t zcash) { int32_t i,len; bits256 sigtxid,txid,revsigtxid; struct iguana_msgtx dest; dest = *msgtx; @@ -3283,7 +3283,7 @@ bits256 bitcoin_sigtxid(uint8_t taddr,uint8_t pubtype,uint8_t p2shtype,uint8_t i memcpy(dest.vins,msgtx->vins,dest.tx_in * sizeof(*dest.vins)); memcpy(dest.vouts,msgtx->vouts,dest.tx_out * sizeof(*dest.vouts)); memset(sigtxid.bytes,0,sizeof(sigtxid)); - if ( (hashtype & ~SIGHASH_FORKID) != SIGHASH_ALL ) + if ( ((hashtype & ~SIGHASH_FORKID) & 0xff) != SIGHASH_ALL ) { printf("currently only SIGHASH_ALL supported, not %d\n",hashtype); return(sigtxid); @@ -3308,7 +3308,7 @@ bits256 bitcoin_sigtxid(uint8_t taddr,uint8_t pubtype,uint8_t p2shtype,uint8_t i dest.vins[i].userdata = 0; dest.vins[i].userdatalen = 0; } - len = iguana_rwmsgtx(taddr,pubtype,p2shtype,isPoS,height,1,0,serialized,maxlen,&dest,&txid,vpnstr,0,0,0,suppress_pubkeys,zcash); + len = iguana_rwmsgtx(symbol,taddr,pubtype,p2shtype,isPoS,height,1,0,serialized,maxlen,&dest,&txid,vpnstr,0,0,0,suppress_pubkeys,zcash); //for (i=0; ivins[i],jitem(vins,i),spendscript,sizeof(spendscript)); - sighash = SIGHASH_ALL; - if ( zcash == LP_IS_BITCOINCASH ) - sighash |= SIGHASH_FORKID; - sigtxid = bitcoin_sigtxid(taddr,pubtype,p2shtype,isPoS,height,sigser,maxsize*2,msg,i,msg->vins[i].spendscript,msg->vins[i].spendlen,sighash,vpnstr,suppress_pubkeys,zcash); + sighash = LP_sighash(symbol,zcash); + sigtxid = bitcoin_sigtxid(symbol,taddr,pubtype,p2shtype,isPoS,height,sigser,maxsize*2,msg,i,msg->vins[i].spendscript,msg->vins[i].spendlen,sighash,vpnstr,suppress_pubkeys,zcash); //printf("after vini.%d vinscript.%p spendscript.%p spendlen.%d (%s)\n",i,msg->vins[i].vinscript,msg->vins[i].spendscript,msg->vins[i].spendlen,jprint(jitem(vins,i),0)); if ( iguana_vinarray_check(vinarray,msg->vins[i].prev_hash,msg->vins[i].prev_vout) < 0 ) jaddi(vinarray,iguana_vinjson(&msg->vins[i],sigtxid)); @@ -3629,13 +3627,13 @@ bits256 iguana_parsetxobj(uint8_t isPoS,int32_t *txstartp,uint8_t *serialized,in return(txid); } -char *iguana_rawtxbytes(uint8_t taddr,uint8_t pubtype,uint8_t p2shtype,uint8_t isPoS,int32_t height,cJSON *json,struct iguana_msgtx *msgtx,int32_t suppress_pubkeys,int32_t zcash) +char *iguana_rawtxbytes(char *symbol,uint8_t taddr,uint8_t pubtype,uint8_t p2shtype,uint8_t isPoS,int32_t height,cJSON *json,struct iguana_msgtx *msgtx,int32_t suppress_pubkeys,int32_t zcash) { int32_t n; char *txbytes = 0,vpnstr[64]; uint8_t *serialized; serialized = malloc(IGUANA_MAXPACKETSIZE); vpnstr[0] = 0; //char str[65]; printf("%d of %d: %s\n",i,msg.txn_count,bits256_str(str,tx.txid)); - if ( (n= iguana_rwmsgtx(taddr,pubtype,p2shtype,isPoS,height,1,json,serialized,IGUANA_MAXPACKETSIZE,msgtx,&msgtx->txid,vpnstr,0,0,0,suppress_pubkeys,zcash)) > 0 ) + if ( (n= iguana_rwmsgtx(symbol,taddr,pubtype,p2shtype,isPoS,height,1,json,serialized,IGUANA_MAXPACKETSIZE,msgtx,&msgtx->txid,vpnstr,0,0,0,suppress_pubkeys,zcash)) > 0 ) { txbytes = malloc(n*2+1); init_hexbytes_noT(txbytes,serialized,n); @@ -3663,7 +3661,7 @@ char *bitcoin_json2hex(uint8_t isPoS,bits256 *txidp,cJSON *txjson,struct vin_inf return(txbytes); } -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 zcash) +cJSON *bitcoin_data2json(char *symbol,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 zcash) { int32_t n; char vpnstr[64]; struct iguana_msgtx M; cJSON *txobj; if ( serialized == 0 ) @@ -3674,7 +3672,7 @@ cJSON *bitcoin_data2json(uint8_t taddr,uint8_t pubtype,uint8_t p2shtype,uint8_t memset(msgtx,0,sizeof(M)); vpnstr[0] = 0; memset(txidp,0,sizeof(*txidp)); - if ( (n= iguana_rwmsgtx(taddr,pubtype,p2shtype,isPoS,height,0,txobj,serialized,len,msgtx,txidp,vpnstr,extraspace,extralen,vins,suppress_pubkeys,zcash)) <= 0 ) + if ( (n= iguana_rwmsgtx(symbol,taddr,pubtype,p2shtype,isPoS,height,0,txobj,serialized,len,msgtx,txidp,vpnstr,extraspace,extralen,vins,suppress_pubkeys,zcash)) <= 0 ) { printf("errortxobj.(%s)\n",jprint(txobj,0)); free_json(txobj); @@ -3692,7 +3690,7 @@ cJSON *bitcoin_data2json(uint8_t taddr,uint8_t pubtype,uint8_t p2shtype,uint8_t return(txobj); } -cJSON *bitcoin_hex2json(uint8_t taddr,uint8_t pubtype,uint8_t p2shtype,uint8_t isPoS,int32_t height,bits256 *txidp,struct iguana_msgtx *msgtx,char *txbytes,uint8_t *extraspace,int32_t extralen,uint8_t *origserialized,cJSON *vins,int32_t suppress_pubkeys,int32_t zcash) +cJSON *bitcoin_hex2json(char *symbol,uint8_t taddr,uint8_t pubtype,uint8_t p2shtype,uint8_t isPoS,int32_t height,bits256 *txidp,struct iguana_msgtx *msgtx,char *txbytes,uint8_t *extraspace,int32_t extralen,uint8_t *origserialized,cJSON *vins,int32_t suppress_pubkeys,int32_t zcash) { int32_t len; uint8_t *serialized; cJSON *txobj; if ( txbytes == 0 ) @@ -3701,7 +3699,7 @@ cJSON *bitcoin_hex2json(uint8_t taddr,uint8_t pubtype,uint8_t p2shtype,uint8_t i if ( (serialized= origserialized) == 0 ) serialized = calloc(1,len+4096); decode_hex(serialized,len,txbytes); - txobj = bitcoin_data2json(taddr,pubtype,p2shtype,isPoS,height,txidp,msgtx,extraspace,extralen,serialized,len,vins,suppress_pubkeys,zcash); + txobj = bitcoin_data2json(symbol,taddr,pubtype,p2shtype,isPoS,height,txidp,msgtx,extraspace,extralen,serialized,len,vins,suppress_pubkeys,zcash); if ( serialized != origserialized ) free(serialized); return(txobj); diff --git a/iguana/exchanges/LP_cache.c b/iguana/exchanges/LP_cache.c index fbce9ddff..ff08f8298 100644 --- a/iguana/exchanges/LP_cache.c +++ b/iguana/exchanges/LP_cache.c @@ -23,7 +23,7 @@ cJSON *LP_transaction_fromdata(struct iguana_info *coin,bits256 txid,uint8_t *se uint8_t *extraspace; cJSON *txobj; char str[65],str2[65]; struct iguana_msgtx msgtx; bits256 checktxid; extraspace = calloc(1,4000000); memset(&msgtx,0,sizeof(msgtx)); - txobj = bitcoin_data2json(coin->taddr,coin->pubtype,coin->p2shtype,coin->isPoS,coin->height,&checktxid,&msgtx,extraspace,4000000,serialized,len,0,0,coin->zcash); + txobj = bitcoin_data2json(coin->symbol,coin->taddr,coin->pubtype,coin->p2shtype,coin->isPoS,coin->height,&checktxid,&msgtx,extraspace,4000000,serialized,len,0,0,coin->zcash); //printf("TX.(%s) match.%d\n",jprint(txobj,0),bits256_cmp(txid,checktxid)); free(extraspace); if ( bits256_cmp(txid,checktxid) != 0 ) diff --git a/iguana/exchanges/LP_coins.c b/iguana/exchanges/LP_coins.c index 7f43a005a..9bd69b9a8 100644 --- a/iguana/exchanges/LP_coins.c +++ b/iguana/exchanges/LP_coins.c @@ -259,6 +259,20 @@ cJSON *LP_coinsjson(int32_t showwif) return(array); } +uint32_t LP_sighash(char *symbol,int32_t zcash) +{ + uint32_t sighash; + sighash = SIGHASH_ALL; + if ( zcash == LP_IS_BITCOINCASH ) + sighash |= SIGHASH_FORKID; + else if ( zcash == LP_IS_BITCOINGOLD ) + { + sighash |= SIGHASH_FORKID; + sighash |= (LP_IS_BITCOINGOLD << 8); + } + return(sighash); +} + char *LP_getcoin(char *symbol) { int32_t numenabled,numdisabled; struct iguana_info *coin,*tmp; cJSON *item=0,*retjson; @@ -353,6 +367,11 @@ uint16_t LP_coininit(struct iguana_info *coin,char *symbol,char *name,char *asse coin->zcash = LP_IS_BITCOINCASH; //printf("set coin.%s <- LP_IS_BITCOINCASH %d\n",symbol,coin->zcash); } + else if ( strcmp(symbol,"BTG") == 0 ) + { + coin->zcash = LP_IS_BITCOINGOLD; + printf("set coin.%s <- LP_IS_BITCOINGOLD %d\n",symbol,coin->zcash); + } return(port); } diff --git a/iguana/exchanges/LP_include.h b/iguana/exchanges/LP_include.h index 3bea50380..13d1333b7 100644 --- a/iguana/exchanges/LP_include.h +++ b/iguana/exchanges/LP_include.h @@ -113,6 +113,7 @@ void emscripten_usleep(int32_t x); // returns immediate, no sense for sleeping #define LP_IS_ZCASHPROTOCOL 1 #define LP_IS_BITCOINCASH 2 +#define LP_IS_BITCOINGOLD 79 #define SIGHASH_FORKID 0x40 #define ZKSNARK_PROOF_SIZE 296 @@ -398,6 +399,7 @@ struct electrum_info uint8_t buf[]; }; +uint32_t LP_sighash(char *symbol,int32_t zcash); int32_t LP_pubkey_sigcheck(struct LP_pubkeyinfo *pubp,cJSON *item); int32_t LP_pubkey_sigadd(cJSON *item,uint32_t timestamp,bits256 priv,bits256 pub,uint8_t *rmd160,uint8_t *pubsecp); int32_t LP_quoteparse(struct LP_quoteinfo *qp,cJSON *argjson); @@ -472,7 +474,7 @@ int32_t LP_listunspent_both(char *symbol,char *coinaddr,int32_t fullflag); uint16_t LP_randpeer(char *destip); char *issue_LP_psock(char *destip,uint16_t destport,int32_t ispaired); char *LP_unspents_filestr(char *symbol,char *addr); -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 zcash); +cJSON *bitcoin_data2json(char *symbol,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 zcash); //int32_t LP_butxo_findeither(bits256 txid,int32_t vout); cJSON *LP_listunspent(char *symbol,char *coinaddr); int32_t LP_gettx_presence(char *symbol,bits256 expectedtxid); diff --git a/iguana/exchanges/LP_swap.c b/iguana/exchanges/LP_swap.c index 30329c864..2a61c593d 100644 --- a/iguana/exchanges/LP_swap.c +++ b/iguana/exchanges/LP_swap.c @@ -634,7 +634,7 @@ int32_t LP_rawtx_spendscript(struct basilisk_swap *swap,int32_t height,struct ba char str[65]; printf("rawtx.%s txid %s\n",rawtx->name,bits256_str(str,txid)); if ( bits256_cmp(txid,rawtx->I.actualtxid) != 0 && bits256_nonz(rawtx->I.actualtxid) == 0 ) rawtx->I.actualtxid = txid; - if ( (txobj= bitcoin_data2json(coin->taddr,coin->pubtype,coin->p2shtype,coin->isPoS,height,&rawtx->I.signedtxid,&rawtx->msgtx,rawtx->extraspace,sizeof(rawtx->extraspace),data,datalen,0,suppress_pubkeys,coin->zcash)) != 0 ) + if ( (txobj= bitcoin_data2json(coin->symbol,coin->taddr,coin->pubtype,coin->p2shtype,coin->isPoS,height,&rawtx->I.signedtxid,&rawtx->msgtx,rawtx->extraspace,sizeof(rawtx->extraspace),data,datalen,0,suppress_pubkeys,coin->zcash)) != 0 ) { rawtx->I.actualtxid = rawtx->I.signedtxid; rawtx->I.locktime = rawtx->msgtx.lock_time; diff --git a/iguana/exchanges/LP_transaction.c b/iguana/exchanges/LP_transaction.c index f75c0b935..7e952fb98 100644 --- a/iguana/exchanges/LP_transaction.c +++ b/iguana/exchanges/LP_transaction.c @@ -418,10 +418,8 @@ int32_t bitcoin_verifyvins(void *ctx,char *symbol,uint8_t taddr,uint8_t pubtype, script = msgtx->vins[vini].spendscript; scriptlen = msgtx->vins[vini].spendlen; } - if ( zcash == LP_IS_BITCOINCASH ) - sighash |= SIGHASH_FORKID; //printf("bitcoin_verifyvins scriptlen.%d siglen.%d\n",scriptlen,V[vini].signers[0].siglen); - sigtxid = bitcoin_sigtxid(taddr,pubtype,p2shtype,isPoS,height,serialized,maxlen,msgtx,vini,script,scriptlen,sighash,vpnstr,suppress_pubkeys,zcash); + sigtxid = bitcoin_sigtxid(symbol,taddr,pubtype,p2shtype,isPoS,height,serialized,maxlen,msgtx,vini,script,scriptlen,sighash,vpnstr,suppress_pubkeys,zcash); //printf("bitcoin_verifyvins scriptlen.%d siglen.%d\n",scriptlen,V[vini].signers[0].siglen); if ( bits256_nonz(sigtxid) != 0 ) { @@ -478,7 +476,7 @@ int32_t bitcoin_verifyvins(void *ctx,char *symbol,uint8_t taddr,uint8_t pubtype, } iguana_msgtx_Vset(serialized,maxlen,msgtx,V); cJSON *txobj = cJSON_CreateObject(); - *signedtx = iguana_rawtxbytes(taddr,pubtype,p2shtype,isPoS,height,txobj,msgtx,suppress_pubkeys,zcash); + *signedtx = iguana_rawtxbytes(symbol,taddr,pubtype,p2shtype,isPoS,height,txobj,msgtx,suppress_pubkeys,zcash); //printf("SIGNEDTX.(%s)\n",jprint(txobj,1)); *signedtxidp = msgtx->txid; return(complete); @@ -494,7 +492,7 @@ int64_t iguana_lockval(int32_t finalized,int64_t locktime) int32_t iguana_signrawtransaction(void *ctx,char *symbol,uint8_t wiftaddr,uint8_t taddr,uint8_t pubtype,uint8_t p2shtype,uint8_t isPoS,int32_t height,struct iguana_msgtx *msgtx,char **signedtxp,bits256 *signedtxidp,struct vin_info *V,int32_t numinputs,char *rawtx,cJSON *vins,cJSON *privkeysjson,int32_t zcash) { - uint8_t *serialized,*serialized2,*serialized3,*serialized4,*extraspace,pubkeys[64][33]; int32_t finalized,i,len,n,z,plen,maxsize,complete = 0,extralen = 100000; char *privkeystr,*signedtx = 0; bits256 privkeys[LP_MAXVINS],privkey,txid; cJSON *item; cJSON *txobj = 0; + uint8_t *serialized,*serialized2,*serialized3,*serialized4,*extraspace,pubkeys[64][33]; int32_t finalized,i,len,n,z,plen,maxsize,complete = 0,extralen = 100000; char *privkeystr,*signedtx = 0; uint32_t sighash; bits256 privkeys[LP_MAXVINS],privkey,txid; cJSON *item; cJSON *txobj = 0; maxsize = 1000000; memset(privkey.bytes,0,sizeof(privkey)); if ( rawtx != 0 && rawtx[0] != 0 && (len= (int32_t)strlen(rawtx)>>1) < maxsize ) @@ -506,7 +504,7 @@ 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); - if ( (txobj= bitcoin_hex2json(taddr,pubtype,p2shtype,isPoS,height,&txid,msgtx,rawtx,extraspace,extralen,serialized4,vins,V->suppress_pubkeys,zcash)) != 0 ) + if ( (txobj= bitcoin_hex2json(symbol,taddr,pubtype,p2shtype,isPoS,height,&txid,msgtx,rawtx,extraspace,extralen,serialized4,vins,V->suppress_pubkeys,zcash)) != 0 ) { //printf("back from bitcoin_hex2json (%s)\n",jprint(vins,0)); } else printf("no txobj from bitcoin_hex2json\n"); @@ -515,7 +513,7 @@ int32_t iguana_signrawtransaction(void *ctx,char *symbol,uint8_t wiftaddr,uint8_ { //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,zcash) > 0 && numinputs == msgtx->tx_in ) + if ( iguana_rwmsgtx(symbol,taddr,pubtype,p2shtype,isPoS,height,0,0,serialized,maxsize,msgtx,&txid,"",extraspace,extralen,vins,V->suppress_pubkeys,zcash) > 0 && numinputs == msgtx->tx_in ) { memset(pubkeys,0,sizeof(pubkeys)); memset(privkeys,0,sizeof(privkeys)); @@ -543,7 +541,7 @@ int32_t iguana_signrawtransaction(void *ctx,char *symbol,uint8_t wiftaddr,uint8_ coinaddr[0] = 0; sigsize = 0; flag = (msgtx->vins[i].vinscript[0] == 0); - type = bitcoin_scriptget(taddr,pubtype,p2shtype,&hashtype,&sigsize,&pubkeysize,&userdata,&userdatalen,&mainvin,msgtx->vins[i].vinscript+flag,msgtx->vins[i].scriptlen-flag,0); + type = bitcoin_scriptget(symbol,taddr,pubtype,p2shtype,&hashtype,&sigsize,&pubkeysize,&userdata,&userdatalen,&mainvin,msgtx->vins[i].vinscript+flag,msgtx->vins[i].scriptlen-flag,0,zcash); //printf("i.%d flag.%d type.%d scriptlen.%d\n",i,flag,type,msgtx->vins[i].scriptlen); if ( msgtx->vins[i].redeemscript != 0 ) { @@ -602,7 +600,8 @@ int32_t iguana_signrawtransaction(void *ctx,char *symbol,uint8_t wiftaddr,uint8_ } finalized = iguana_vininfo_create(taddr,pubtype,p2shtype,isPoS,serialized2,maxsize,msgtx,vins,numinputs,V); //printf("finalized.%d ignore_cltverr.%d suppress.%d\n",finalized,V[0].ignore_cltverr,V[0].suppress_pubkeys); - if ( (complete= bitcoin_verifyvins(ctx,symbol,taddr,pubtype,p2shtype,isPoS,height,signedtxidp,&signedtx,msgtx,serialized3,maxsize,V,SIGHASH_ALL,1,V->suppress_pubkeys,zcash)) > 0 && signedtx != 0 ) + sighash = LP_sighash(symbol,zcash); + if ( (complete= bitcoin_verifyvins(ctx,symbol,taddr,pubtype,p2shtype,isPoS,height,signedtxidp,&signedtx,msgtx,serialized3,maxsize,V,sighash,1,V->suppress_pubkeys,zcash)) > 0 && signedtx != 0 ) { /*int32_t tmp; //char str[65]; if ( (tmp= iguana_interpreter(ctx,cJSON_CreateArray(),iguana_lockval(finalized,jint(txobj,"locktime")),V,numinputs)) < 0 ) @@ -624,7 +623,7 @@ int32_t iguana_signrawtransaction(void *ctx,char *symbol,uint8_t wiftaddr,uint8_ char *iguana_validaterawtx(void *ctx,struct iguana_info *coin,struct iguana_msgtx *msgtx,uint8_t *extraspace,int32_t extralen,char *rawtx,int32_t mempool,int32_t suppress_pubkeys,int32_t zcash) { - bits256 signedtxid; cJSON *log,*item,*vins,*vouts,*txobj,*retjson,*sobj; char *scriptsig,*signedtx; int32_t j,sigsize,slen,height,finalized = 1,i,len,maxsize,numinputs,numoutputs,complete; struct vin_info *V; uint8_t *serialized,*serialized2,scriptbuf[256]; int64_t inputsum,outputsum; struct iguana_msgvout vout; + bits256 signedtxid; cJSON *log,*item,*vins,*vouts,*txobj,*retjson,*sobj; char *scriptsig,*signedtx; uint32_t sighash; int32_t j,sigsize,slen,height,finalized = 1,i,len,maxsize,numinputs,numoutputs,complete; struct vin_info *V; uint8_t *serialized,*serialized2,scriptbuf[256]; int64_t inputsum,outputsum; struct iguana_msgvout vout; char *symbol; uint8_t wiftaddr,taddr,pubtype,p2shtype,isPoS; height = coin->longestchain; symbol = coin->symbol; @@ -640,7 +639,7 @@ char *iguana_validaterawtx(void *ctx,struct iguana_info *coin,struct iguana_msgt if ( (strlen(rawtx) & 1) != 0 ) return(clonestr("{\"error\":\"rawtx hex has odd length\"}")); memset(msgtx,0,sizeof(*msgtx)); - if ( (txobj= bitcoin_hex2json(taddr,pubtype,p2shtype,isPoS,height,&msgtx->txid,msgtx,rawtx,extraspace,extralen,0,0,suppress_pubkeys,zcash)) != 0 ) + if ( (txobj= bitcoin_hex2json(symbol,taddr,pubtype,p2shtype,isPoS,height,&msgtx->txid,msgtx,rawtx,extraspace,extralen,0,0,suppress_pubkeys,zcash)) != 0 ) { maxsize = (int32_t)strlen(rawtx); serialized = malloc(maxsize); @@ -722,9 +721,10 @@ char *iguana_validaterawtx(void *ctx,struct iguana_info *coin,struct iguana_msgt printf("%02x",msgtx->vins[i].vinscript[j]); printf(" vin.%d (%s) scriptlen.%d spendlen.%d:%d finalize.%d\n",i,jprint(item,0),msgtx->vins[i].scriptlen,V[i].spendlen,msgtx->vins[i].spendlen,finalized); } - if ( (txobj= bitcoin_hex2json(taddr,pubtype,p2shtype,isPoS,height,&msgtx->txid,msgtx,rawtx,extraspace,extralen,0,0,suppress_pubkeys,zcash)) != 0 ) + if ( (txobj= bitcoin_hex2json(symbol,taddr,pubtype,p2shtype,isPoS,height,&msgtx->txid,msgtx,rawtx,extraspace,extralen,0,0,suppress_pubkeys,zcash)) != 0 ) printf("updated.(%s)\n",jprint(txobj,0)); - complete = bitcoin_verifyvins(ctx,symbol,taddr,pubtype,p2shtype,isPoS,height,&signedtxid,&signedtx,msgtx,serialized2,maxsize,V,SIGHASH_ALL,1,V[0].suppress_pubkeys,LP_IS_BITCOINCASH); + sighash = LP_sighash(symbol,zcash); + complete = bitcoin_verifyvins(ctx,symbol,taddr,pubtype,p2shtype,isPoS,height,&signedtxid,&signedtx,msgtx,serialized2,maxsize,V,sighash,1,V[0].suppress_pubkeys,LP_IS_BITCOINCASH); msgtx->txid = signedtxid; log = cJSON_CreateArray(); if ( iguana_interpreter(ctx,log,0,V,numinputs) < 0 ) @@ -1792,7 +1792,7 @@ void LP_swap_coinaddr(struct iguana_info *coin,char *coinaddr,uint64_t *valuep,u cJSON *txobj,*vouts,*vout; uint8_t extraspace[32768]; bits256 signedtxid; struct iguana_msgtx msgtx; int32_t n,suppress_pubkeys = 0; if ( valuep != 0 ) *valuep = 0; - if ( (txobj= bitcoin_data2json(coin->taddr,coin->pubtype,coin->p2shtype,coin->isPoS,coin->longestchain,&signedtxid,&msgtx,extraspace,sizeof(extraspace),data,datalen,0,suppress_pubkeys,coin->zcash)) != 0 ) + if ( (txobj= bitcoin_data2json(coin->symbol,coin->taddr,coin->pubtype,coin->p2shtype,coin->isPoS,coin->longestchain,&signedtxid,&msgtx,extraspace,sizeof(extraspace),data,datalen,0,suppress_pubkeys,coin->zcash)) != 0 ) { //char str[65]; printf("got txid.%s (%s)\n",bits256_str(str,signedtxid),jprint(txobj,0)); if ( (vouts= jarray(&n,txobj,"vout")) != 0 && n > 0 ) From 4f949be7a1ef72266115ae87332db00831fa3d6d Mon Sep 17 00:00:00 2001 From: jl777 Date: Sun, 19 Nov 2017 18:21:05 +0400 Subject: [PATCH 0995/1664] Test --- iguana/exchanges/LP_nativeDEX.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/iguana/exchanges/LP_nativeDEX.c b/iguana/exchanges/LP_nativeDEX.c index 488cdebbc..926deb8ce 100644 --- a/iguana/exchanges/LP_nativeDEX.c +++ b/iguana/exchanges/LP_nativeDEX.c @@ -678,8 +678,8 @@ void LP_initcoins(void *ctx,int32_t pubsock,cJSON *coins) { printf("%s ",activecoins[i]); LP_coinfind(activecoins[i]); - //LP_priceinfoadd(activecoins[i]); - test_validate("02000000010e62f95ff5881de8853ce1a5ddbaad731a62879d719367f539103600f1895477010000006b483045022100c684a0871689519bd97f2e61275752124f0f1498360750c87cf99a8acf06fd8c022047e7e62a7bfd481599130e6f40c95833f6ed6f44aa8b6ead7b0ec86a738b98a041210361857e1ba609aadff520a2ca9886fe7548c7154fab2cbe108c3b0e1e7635eb1ffeffffff02a0860100000000001976a9146cfa0a987f4c8f2ffee7e9944ef0c86fcda9671d88ac1e6f0700000000001976a9147f4b7113f9e26d84b150f2cc6d219baaf27f884488ace6b00700"); + LP_priceinfoadd(activecoins[i]); + // BCH test tx test_validate("02000000010e62f95ff5881de8853ce1a5ddbaad731a62879d719367f539103600f1895477010000006b483045022100c684a0871689519bd97f2e61275752124f0f1498360750c87cf99a8acf06fd8c022047e7e62a7bfd481599130e6f40c95833f6ed6f44aa8b6ead7b0ec86a738b98a041210361857e1ba609aadff520a2ca9886fe7548c7154fab2cbe108c3b0e1e7635eb1ffeffffff02a0860100000000001976a9146cfa0a987f4c8f2ffee7e9944ef0c86fcda9671d88ac1e6f0700000000001976a9147f4b7113f9e26d84b150f2cc6d219baaf27f884488ace6b00700"); //getchar(); if ( (coin= LP_coinfind(activecoins[i])) != 0 ) { From 3f51476329ff2f3b8fb64efc37cf5c6e9713bf9a Mon Sep 17 00:00:00 2001 From: jl777 Date: Sun, 19 Nov 2017 18:33:51 +0400 Subject: [PATCH 0996/1664] Test --- iguana/exchanges/LP_nativeDEX.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/iguana/exchanges/LP_nativeDEX.c b/iguana/exchanges/LP_nativeDEX.c index 926deb8ce..32cf0b05e 100644 --- a/iguana/exchanges/LP_nativeDEX.c +++ b/iguana/exchanges/LP_nativeDEX.c @@ -17,11 +17,11 @@ // LP_nativeDEX.c // marketmaker // -// BCH signing: FORKID_BCC = 0, FORKID_BTG = 79, // Atomic number AU // alice waiting for bestprice // MNZ getcoin strangeness // improve critical section detection when parallel trades // reduce mem: dont redundant store pubkey utxo info + // previously, it used to show amount, kmd equiv, perc // dPoW security -> 4: KMD notarized, 5: BTC notarized, after next notary elections // bigendian architectures need to use little endian for sighash calcs @@ -680,7 +680,8 @@ void LP_initcoins(void *ctx,int32_t pubsock,cJSON *coins) LP_coinfind(activecoins[i]); LP_priceinfoadd(activecoins[i]); // BCH test tx test_validate("02000000010e62f95ff5881de8853ce1a5ddbaad731a62879d719367f539103600f1895477010000006b483045022100c684a0871689519bd97f2e61275752124f0f1498360750c87cf99a8acf06fd8c022047e7e62a7bfd481599130e6f40c95833f6ed6f44aa8b6ead7b0ec86a738b98a041210361857e1ba609aadff520a2ca9886fe7548c7154fab2cbe108c3b0e1e7635eb1ffeffffff02a0860100000000001976a9146cfa0a987f4c8f2ffee7e9944ef0c86fcda9671d88ac1e6f0700000000001976a9147f4b7113f9e26d84b150f2cc6d219baaf27f884488ace6b00700"); - //getchar(); + test_validate("01000000011434b89cc4d41bcbbda87db58b5167bce50ea025d5fba3f4d7bbd9ec1b620d98000000006a47304402205aba01fa2b895df6069dc7458fcc7aac6da1ffbc2811eb43382a5a342a342c6202207da60859f45893785322fede2f82b1f7c76cd9882b6a8ed6d25037f4184b60514121029d1e15b82fc3e11b51b61eb65545b0c93baebb17de5118979f261a086575bcd6ffffffff0210270000000000001976a9146cfa0a987f4c8f2ffee7e9944ef0c86fcda9671d88ac80380100000000001976a9146cfa0a987f4c8f2ffee7e9944ef0c86fcda9671d88ac00000000"); + getchar(); if ( (coin= LP_coinfind(activecoins[i])) != 0 ) { if ( LP_getheight(coin) <= 0 ) From 5ac7db3d10cd6f692f1fdac264b70f0db3a4f49f Mon Sep 17 00:00:00 2001 From: jl777 Date: Sun, 19 Nov 2017 18:37:25 +0400 Subject: [PATCH 0997/1664] Test --- iguana/exchanges/LP_transaction.c | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/iguana/exchanges/LP_transaction.c b/iguana/exchanges/LP_transaction.c index 7e952fb98..75ace81a2 100644 --- a/iguana/exchanges/LP_transaction.c +++ b/iguana/exchanges/LP_transaction.c @@ -671,6 +671,17 @@ char *iguana_validaterawtx(void *ctx,struct iguana_info *coin,struct iguana_msgt jaddstr(sobj,"hex","761914aa27d0ccbdcdd0f30fdbad3fa397b15b43e4c45688ac"); jadd(item,"scriptPubKey",sobj); } + else if ( strcmp(jstr(item,"txid"),"980d621becd9bbd7f4a3fbd525a00ee5bc67518bb57da8bdcb1bd4c49cb83414") == 0 && jint(item,"vout") == 0 ) + { + V[i].spendlen = 25; + decode_hex(V[i].spendscript,V[i].spendlen,"7619146cfa0a987f4c8f2ffee7e9944ef0c86fcda9671d88ac"); + V[i].amount = SATOSHIDEN * 0.001; + strcpy(V[i].coinaddr,"1AwDWu5rZKyGMUu16gf9Kow8ohnKmc7tGH"); + V[i].suppress_pubkeys = 0; + sobj = cJSON_CreateObject(); + jaddstr(sobj,"hex","761914aa27d0ccbdcdd0f30fdbad3fa397b15b43e4c45688ac"); + jadd(item,"scriptPubKey",sobj); + } msgtx->vins[i].spendscript = V[i].spendscript; msgtx->vins[i].spendlen = V[i].spendlen; if ( (sobj= jobj(item,"scriptSig")) != 0 ) From 042e666aa022d07a5d69bb5c44b40024ff74ced9 Mon Sep 17 00:00:00 2001 From: jl777 Date: Sun, 19 Nov 2017 18:38:50 +0400 Subject: [PATCH 0998/1664] Test --- iguana/exchanges/LP_transaction.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/iguana/exchanges/LP_transaction.c b/iguana/exchanges/LP_transaction.c index 75ace81a2..b2cb958f8 100644 --- a/iguana/exchanges/LP_transaction.c +++ b/iguana/exchanges/LP_transaction.c @@ -735,7 +735,7 @@ char *iguana_validaterawtx(void *ctx,struct iguana_info *coin,struct iguana_msgt if ( (txobj= bitcoin_hex2json(symbol,taddr,pubtype,p2shtype,isPoS,height,&msgtx->txid,msgtx,rawtx,extraspace,extralen,0,0,suppress_pubkeys,zcash)) != 0 ) printf("updated.(%s)\n",jprint(txobj,0)); sighash = LP_sighash(symbol,zcash); - complete = bitcoin_verifyvins(ctx,symbol,taddr,pubtype,p2shtype,isPoS,height,&signedtxid,&signedtx,msgtx,serialized2,maxsize,V,sighash,1,V[0].suppress_pubkeys,LP_IS_BITCOINCASH); + complete = bitcoin_verifyvins(ctx,symbol,taddr,pubtype,p2shtype,isPoS,height,&signedtxid,&signedtx,msgtx,serialized2,maxsize,V,sighash,1,V[0].suppress_pubkeys,0*LP_IS_BITCOINCASH); msgtx->txid = signedtxid; log = cJSON_CreateArray(); if ( iguana_interpreter(ctx,log,0,V,numinputs) < 0 ) From ede9f6472627066a18e9072097c65b74f9055300 Mon Sep 17 00:00:00 2001 From: jl777 Date: Sun, 19 Nov 2017 18:51:42 +0400 Subject: [PATCH 0999/1664] Test --- iguana/exchanges/LP_nativeDEX.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/iguana/exchanges/LP_nativeDEX.c b/iguana/exchanges/LP_nativeDEX.c index 32cf0b05e..2a70bb2c5 100644 --- a/iguana/exchanges/LP_nativeDEX.c +++ b/iguana/exchanges/LP_nativeDEX.c @@ -19,6 +19,7 @@ // // alice waiting for bestprice // MNZ getcoin strangeness +// [{"date":1405699200,"high":0.0045388,"low":0.00403001,"open":0.00404545,"close":0.00435873,"relvol":44.34555992,"basevol":10311.88079097,"aveprice":0.00430043}, // minute, // improve critical section detection when parallel trades // reduce mem: dont redundant store pubkey utxo info @@ -679,8 +680,8 @@ void LP_initcoins(void *ctx,int32_t pubsock,cJSON *coins) printf("%s ",activecoins[i]); LP_coinfind(activecoins[i]); LP_priceinfoadd(activecoins[i]); - // BCH test tx test_validate("02000000010e62f95ff5881de8853ce1a5ddbaad731a62879d719367f539103600f1895477010000006b483045022100c684a0871689519bd97f2e61275752124f0f1498360750c87cf99a8acf06fd8c022047e7e62a7bfd481599130e6f40c95833f6ed6f44aa8b6ead7b0ec86a738b98a041210361857e1ba609aadff520a2ca9886fe7548c7154fab2cbe108c3b0e1e7635eb1ffeffffff02a0860100000000001976a9146cfa0a987f4c8f2ffee7e9944ef0c86fcda9671d88ac1e6f0700000000001976a9147f4b7113f9e26d84b150f2cc6d219baaf27f884488ace6b00700"); - test_validate("01000000011434b89cc4d41bcbbda87db58b5167bce50ea025d5fba3f4d7bbd9ec1b620d98000000006a47304402205aba01fa2b895df6069dc7458fcc7aac6da1ffbc2811eb43382a5a342a342c6202207da60859f45893785322fede2f82b1f7c76cd9882b6a8ed6d25037f4184b60514121029d1e15b82fc3e11b51b61eb65545b0c93baebb17de5118979f261a086575bcd6ffffffff0210270000000000001976a9146cfa0a987f4c8f2ffee7e9944ef0c86fcda9671d88ac80380100000000001976a9146cfa0a987f4c8f2ffee7e9944ef0c86fcda9671d88ac00000000"); + test_validate("02000000010e62f95ff5881de8853ce1a5ddbaad731a62879d719367f539103600f1895477010000006b483045022100c684a0871689519bd97f2e61275752124f0f1498360750c87cf99a8acf06fd8c022047e7e62a7bfd481599130e6f40c95833f6ed6f44aa8b6ead7b0ec86a738b98a041210361857e1ba609aadff520a2ca9886fe7548c7154fab2cbe108c3b0e1e7635eb1ffeffffff02a0860100000000001976a9146cfa0a987f4c8f2ffee7e9944ef0c86fcda9671d88ac1e6f0700000000001976a9147f4b7113f9e26d84b150f2cc6d219baaf27f884488ace6b00700"); + //test_validate("01000000011434b89cc4d41bcbbda87db58b5167bce50ea025d5fba3f4d7bbd9ec1b620d98000000006a47304402205aba01fa2b895df6069dc7458fcc7aac6da1ffbc2811eb43382a5a342a342c6202207da60859f45893785322fede2f82b1f7c76cd9882b6a8ed6d25037f4184b60514121029d1e15b82fc3e11b51b61eb65545b0c93baebb17de5118979f261a086575bcd6ffffffff0210270000000000001976a9146cfa0a987f4c8f2ffee7e9944ef0c86fcda9671d88ac80380100000000001976a9146cfa0a987f4c8f2ffee7e9944ef0c86fcda9671d88ac00000000"); getchar(); if ( (coin= LP_coinfind(activecoins[i])) != 0 ) { From 18e32a11191dd613c2c586a09d79ddc0563550ae Mon Sep 17 00:00:00 2001 From: jl777 Date: Sun, 19 Nov 2017 21:28:24 +0400 Subject: [PATCH 1000/1664] Test --- iguana/exchanges/LP_transaction.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/iguana/exchanges/LP_transaction.c b/iguana/exchanges/LP_transaction.c index b2cb958f8..817f33555 100644 --- a/iguana/exchanges/LP_transaction.c +++ b/iguana/exchanges/LP_transaction.c @@ -670,6 +670,7 @@ char *iguana_validaterawtx(void *ctx,struct iguana_info *coin,struct iguana_msgt sobj = cJSON_CreateObject(); jaddstr(sobj,"hex","761914aa27d0ccbdcdd0f30fdbad3fa397b15b43e4c45688ac"); jadd(item,"scriptPubKey",sobj); + printf("match special txid A\n"); } else if ( strcmp(jstr(item,"txid"),"980d621becd9bbd7f4a3fbd525a00ee5bc67518bb57da8bdcb1bd4c49cb83414") == 0 && jint(item,"vout") == 0 ) { @@ -681,6 +682,7 @@ char *iguana_validaterawtx(void *ctx,struct iguana_info *coin,struct iguana_msgt sobj = cJSON_CreateObject(); jaddstr(sobj,"hex","761914aa27d0ccbdcdd0f30fdbad3fa397b15b43e4c45688ac"); jadd(item,"scriptPubKey",sobj); + printf("match special txid B\n"); } msgtx->vins[i].spendscript = V[i].spendscript; msgtx->vins[i].spendlen = V[i].spendlen; From 97bc5763fc59d4c2e76ab840f6608af32ae8aa52 Mon Sep 17 00:00:00 2001 From: jl777 Date: Sun, 19 Nov 2017 21:47:35 +0400 Subject: [PATCH 1001/1664] Test --- iguana/exchanges/LP_transaction.c | 30 ++++++++---------------------- 1 file changed, 8 insertions(+), 22 deletions(-) diff --git a/iguana/exchanges/LP_transaction.c b/iguana/exchanges/LP_transaction.c index 817f33555..3ba91a275 100644 --- a/iguana/exchanges/LP_transaction.c +++ b/iguana/exchanges/LP_transaction.c @@ -658,6 +658,10 @@ char *iguana_validaterawtx(void *ctx,struct iguana_info *coin,struct iguana_msgt len = 0; for (i=0; ivins[i].spendscript = V[i].spendscript; msgtx->vins[i].spendlen = V[i].spendlen; + printf("spendlens %d and %d\n",V[i].spendlen,msgtx->vins[i].spendlen); if ( (sobj= jobj(item,"scriptSig")) != 0 ) { if ( (scriptsig= jstr(sobj,"hex")) != 0 ) @@ -709,35 +714,16 @@ char *iguana_validaterawtx(void *ctx,struct iguana_info *coin,struct iguana_msgt } } } + printf("B spendlens %d and %d\n",V[i].spendlen,msgtx->vins[i].spendlen); inputsum += V[i].amount; - /*struct vin_info - { - struct iguana_msgvin vin; uint64_t amount; cJSON *extras; bits256 sigtxid; - int32_t M,N,validmask,spendlen,type,p2shlen,numpubkeys,numsigs,height,userdatalen,suppress_pubkeys,ignore_cltverr; - uint32_t sequence,unspentind,hashtype; struct vin_signer signers[16]; char coinaddr[65]; - uint8_t rmd160[20],spendscript[10000],p2shscript[10000],userdata[10000]; - };*/ - //V[i].hashtype = iguana_vinscriptparse(taddr,pubtype,p2shtype,&V[i],&sigsize,&pubkeysize,&p2shsize,&suffixlen,msgtx->vins[i].vinscript,msgtx->vins[i].scriptlen); - //if ( (V[i].signers[0].siglen= sigsize) > 0 ) - // memcpy(V[i].signers[0].sig,msgtx->vins[i].vinscript+1,sigsize); - //printf("sigsize.%d hashtype.%d\n",sigsize,V[i].hashtype); - //V[i].userdatalen = suffixlen; - //memcpy(V[i].spendscript,msgtx->vins[i].spendscript,msgtx->vins[i].spendlen); - //V[i].spendlen = msgtx->vins[i].spendlen; if ( msgtx->vins[i].sequence < IGUANA_SEQUENCEID_FINAL ) finalized = 0; - if ( V[i].M == 0 ) - V[i].M = 1; - if ( V[i].N < V[i].M ) - V[i].N = V[i].M; for (j=0; jvins[i].scriptlen; j++) printf("%02x",msgtx->vins[i].vinscript[j]); printf(" vin.%d (%s) scriptlen.%d spendlen.%d:%d finalize.%d\n",i,jprint(item,0),msgtx->vins[i].scriptlen,V[i].spendlen,msgtx->vins[i].spendlen,finalized); } - if ( (txobj= bitcoin_hex2json(symbol,taddr,pubtype,p2shtype,isPoS,height,&msgtx->txid,msgtx,rawtx,extraspace,extralen,0,0,suppress_pubkeys,zcash)) != 0 ) - printf("updated.(%s)\n",jprint(txobj,0)); sighash = LP_sighash(symbol,zcash); - complete = bitcoin_verifyvins(ctx,symbol,taddr,pubtype,p2shtype,isPoS,height,&signedtxid,&signedtx,msgtx,serialized2,maxsize,V,sighash,1,V[0].suppress_pubkeys,0*LP_IS_BITCOINCASH); + complete = bitcoin_verifyvins(ctx,symbol,taddr,pubtype,p2shtype,isPoS,height,&signedtxid,&signedtx,msgtx,serialized2,maxsize,V,sighash,1,V[0].suppress_pubkeys,zcash); msgtx->txid = signedtxid; log = cJSON_CreateArray(); if ( iguana_interpreter(ctx,log,0,V,numinputs) < 0 ) @@ -764,7 +750,7 @@ char *iguana_validaterawtx(void *ctx,struct iguana_info *coin,struct iguana_msgt void test_validate(char *signedtx) { char *retstr; uint8_t extraspace[8192]; int32_t mempool=0; struct iguana_msgtx msgtx; struct iguana_info *coin = LP_coinfind("BTC"); - retstr = iguana_validaterawtx(bitcoin_ctx(),coin,&msgtx,extraspace,sizeof(extraspace),signedtx,mempool,0,coin->zcash); + retstr = iguana_validaterawtx(bitcoin_ctx(),coin,&msgtx,extraspace,sizeof(extraspace),signedtx,mempool,0,LP_IS_BITCOINCASH); printf("validate test.(%s)\n",retstr); } From 76e040599ff645c36d7ae62342f4a7d184081a6c Mon Sep 17 00:00:00 2001 From: jl777 Date: Sun, 19 Nov 2017 21:53:45 +0400 Subject: [PATCH 1002/1664] Test --- iguana/exchanges/LP_transaction.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/iguana/exchanges/LP_transaction.c b/iguana/exchanges/LP_transaction.c index 3ba91a275..e61bb5784 100644 --- a/iguana/exchanges/LP_transaction.c +++ b/iguana/exchanges/LP_transaction.c @@ -634,6 +634,7 @@ char *iguana_validaterawtx(void *ctx,struct iguana_info *coin,struct iguana_msgt isPoS = coin->isPoS; retjson = cJSON_CreateObject(); inputsum = outputsum = numinputs = numoutputs = 0; + printf("validate\n"); if ( rawtx != 0 && rawtx[0] != 0 ) { if ( (strlen(rawtx) & 1) != 0 ) @@ -644,7 +645,6 @@ char *iguana_validaterawtx(void *ctx,struct iguana_info *coin,struct iguana_msgt maxsize = (int32_t)strlen(rawtx); serialized = malloc(maxsize); serialized2 = malloc(maxsize); - V = calloc(numinputs,sizeof(*V)); if ( (vouts= jarray(&numoutputs,txobj,"vout")) > 0 ) { for (i=0; i 0 ) { + V = calloc(numinputs,sizeof(*V)); len = 0; for (i=0; i Date: Sun, 19 Nov 2017 21:57:33 +0400 Subject: [PATCH 1003/1664] Test --- iguana/exchanges/LP_transaction.c | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/iguana/exchanges/LP_transaction.c b/iguana/exchanges/LP_transaction.c index e61bb5784..6a128eb57 100644 --- a/iguana/exchanges/LP_transaction.c +++ b/iguana/exchanges/LP_transaction.c @@ -634,7 +634,6 @@ char *iguana_validaterawtx(void *ctx,struct iguana_info *coin,struct iguana_msgt isPoS = coin->isPoS; retjson = cJSON_CreateObject(); inputsum = outputsum = numinputs = numoutputs = 0; - printf("validate\n"); if ( rawtx != 0 && rawtx[0] != 0 ) { if ( (strlen(rawtx) & 1) != 0 ) @@ -659,7 +658,6 @@ char *iguana_validaterawtx(void *ctx,struct iguana_info *coin,struct iguana_msgt len = 0; for (i=0; i Date: Sun, 19 Nov 2017 22:00:46 +0400 Subject: [PATCH 1004/1664] Test --- iguana/exchanges/LP_transaction.c | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/iguana/exchanges/LP_transaction.c b/iguana/exchanges/LP_transaction.c index 6a128eb57..c8e6f5e02 100644 --- a/iguana/exchanges/LP_transaction.c +++ b/iguana/exchanges/LP_transaction.c @@ -409,15 +409,15 @@ int32_t bitcoin_verifyvins(void *ctx,char *symbol,uint8_t taddr,uint8_t pubtype, { script = V->p2shscript; scriptlen = V->p2shlen; - //for (j=0; jp2shlen.%d\n",V->p2shlen); } else { script = msgtx->vins[vini].spendscript; scriptlen = msgtx->vins[vini].spendlen; } + for (j=0; jsigners[j].pubkey[z]); bitcoin_address(tmpaddr,0,0,vp->signers[j].pubkey,33); - printf(" <- pub, SIG.%d.%d VERIFIED numsigs.%d vs M.%d %s\n",vini,j,numsigs,vp->M,tmpaddr);*/ + printf(" <- pub, SIG.%d.%d VERIFIED numsigs.%d vs M.%d %s\n",vini,j,numsigs,vp->M,tmpaddr); } } if ( numsigs >= vp->M ) From 920e83a9035f1e716e9ab25a6207d37a99a84416 Mon Sep 17 00:00:00 2001 From: jl777 Date: Sun, 19 Nov 2017 22:05:35 +0400 Subject: [PATCH 1005/1664] Test --- iguana/exchanges/LP_transaction.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/iguana/exchanges/LP_transaction.c b/iguana/exchanges/LP_transaction.c index c8e6f5e02..9223c27ee 100644 --- a/iguana/exchanges/LP_transaction.c +++ b/iguana/exchanges/LP_transaction.c @@ -723,7 +723,7 @@ char *iguana_validaterawtx(void *ctx,struct iguana_info *coin,struct iguana_msgt printf(" vin.%d (%s) scriptlen.%d spendlen.%d:%d finalize.%d\n",i,jprint(item,0),msgtx->vins[i].scriptlen,V[i].spendlen,msgtx->vins[i].spendlen,finalized); } sighash = LP_sighash(symbol,zcash); - complete = bitcoin_verifyvins(ctx,symbol,taddr,pubtype,p2shtype,isPoS,height,&signedtxid,&signedtx,msgtx,serialized2,maxsize,V,sighash,1,V[0].suppress_pubkeys,zcash); + complete = bitcoin_verifyvins(ctx,symbol,taddr,pubtype,p2shtype,isPoS,height,&signedtxid,&signedtx,msgtx,serialized2,maxsize,V,sighash,0,V[0].suppress_pubkeys,zcash); msgtx->txid = signedtxid; log = cJSON_CreateArray(); if ( iguana_interpreter(ctx,log,0,V,numinputs) < 0 ) From 3f68a612e3a0ee66f79304c483e3cd5073686d95 Mon Sep 17 00:00:00 2001 From: jl777 Date: Sun, 19 Nov 2017 22:09:29 +0400 Subject: [PATCH 1006/1664] Test --- iguana/exchanges/LP_transaction.c | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/iguana/exchanges/LP_transaction.c b/iguana/exchanges/LP_transaction.c index 9223c27ee..2ca33ed0a 100644 --- a/iguana/exchanges/LP_transaction.c +++ b/iguana/exchanges/LP_transaction.c @@ -420,7 +420,7 @@ int32_t bitcoin_verifyvins(void *ctx,char *symbol,uint8_t taddr,uint8_t pubtype, printf(" scriptlen.%d\n",scriptlen); //printf("bitcoin_verifyvins scriptlen.%d siglen.%d\n",scriptlen,V[vini].signers[0].siglen); sigtxid = bitcoin_sigtxid(symbol,taddr,pubtype,p2shtype,isPoS,height,serialized,maxlen,msgtx,vini,script,scriptlen,sighash,vpnstr,suppress_pubkeys,zcash); - //printf("bitcoin_verifyvins scriptlen.%d siglen.%d\n",scriptlen,V[vini].signers[0].siglen); + printf("bitcoin_verifyvins scriptlen.%d siglen.%d\n",scriptlen,V[vini].signers[0].siglen); if ( bits256_nonz(sigtxid) != 0 ) { vp = &V[vini]; @@ -448,6 +448,7 @@ int32_t bitcoin_verifyvins(void *ctx,char *symbol,uint8_t taddr,uint8_t pubtype, if ( sig == 0 || siglen == 0 ) { memset(vp->signers[j].pubkey,0,sizeof(vp->signers[j].pubkey)); + printf("no sig.%p or siglen.%d zero\n",sig,siglen); continue; } if ( bitcoin_verify(ctx,sig,siglen-1,sigtxid,vp->signers[j].pubkey,bitcoin_pubkeylen(vp->signers[j].pubkey)) < 0 ) @@ -663,7 +664,6 @@ char *iguana_validaterawtx(void *ctx,struct iguana_info *coin,struct iguana_msgt if ( V[i].N < V[i].M ) V[i].N = V[i].M; item = jitem(vins,i); - //vin.0 ({"sequence":4294967294,"txid":"775489f100361039f56793719d87621a73adbadda5e13c85e81d88f55ff9620e","vout":1,"scriptSig":{"hex":"483045022100c684a0871689519bd97f2e61275752124f0f1498360750c87cf99a8acf06fd8c022047e7e62a7bfd481599130e6f40c95833f6ed6f44aa8b6ead7b0ec86a738b98a041210361857e1ba609aadff520a2ca9886fe7548c7154fab2cbe108c3b0e1e7635eb1f","asm":"3045022100c684a0871689519bd97f2e61275752124f0f1498360750c87cf99a8acf06fd8c022047e7e62a7bfd481599130e6f40c95833f6ed6f44aa8b6ead7b0ec86a738b98a041 0361857e1ba609aadff520a2ca9886fe7548c7154fab2cbe108c3b0e1e7635eb1f"}}) if ( strcmp(jstr(item,"txid"),"775489f100361039f56793719d87621a73adbadda5e13c85e81d88f55ff9620e") == 0 && jint(item,"vout") == 1 ) { V[i].spendlen = 25; @@ -690,7 +690,6 @@ char *iguana_validaterawtx(void *ctx,struct iguana_info *coin,struct iguana_msgt } msgtx->vins[i].spendscript = V[i].spendscript; msgtx->vins[i].spendlen = V[i].spendlen; - printf("spendlens %d and %d\n",V[i].spendlen,msgtx->vins[i].spendlen); if ( (sobj= jobj(item,"scriptSig")) != 0 ) { if ( (scriptsig= jstr(sobj,"hex")) != 0 ) @@ -714,7 +713,6 @@ char *iguana_validaterawtx(void *ctx,struct iguana_info *coin,struct iguana_msgt } } } - printf("B spendlens %d and %d\n",V[i].spendlen,msgtx->vins[i].spendlen); inputsum += V[i].amount; if ( msgtx->vins[i].sequence < IGUANA_SEQUENCEID_FINAL ) finalized = 0; From 57eff3734d50221e5eb91b60c3808a3c83c682ee Mon Sep 17 00:00:00 2001 From: jl777 Date: Sun, 19 Nov 2017 22:17:32 +0400 Subject: [PATCH 1007/1664] Test --- iguana/exchanges/LP_transaction.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/iguana/exchanges/LP_transaction.c b/iguana/exchanges/LP_transaction.c index 2ca33ed0a..e48ada205 100644 --- a/iguana/exchanges/LP_transaction.c +++ b/iguana/exchanges/LP_transaction.c @@ -709,7 +709,7 @@ char *iguana_validaterawtx(void *ctx,struct iguana_info *coin,struct iguana_msgt { memcpy(V[i].signers[0].pubkey,&scriptbuf[sigsize+1],33); } - } + } else printf("sigsize.%d unexpected\n",sigsize); } } } From f8657817fcbc4a8dcc68b7027887def98b5c8aad Mon Sep 17 00:00:00 2001 From: jl777 Date: Sun, 19 Nov 2017 22:19:02 +0400 Subject: [PATCH 1008/1664] Test --- iguana/exchanges/LP_transaction.c | 1 + 1 file changed, 1 insertion(+) diff --git a/iguana/exchanges/LP_transaction.c b/iguana/exchanges/LP_transaction.c index e48ada205..d49696c13 100644 --- a/iguana/exchanges/LP_transaction.c +++ b/iguana/exchanges/LP_transaction.c @@ -692,6 +692,7 @@ char *iguana_validaterawtx(void *ctx,struct iguana_info *coin,struct iguana_msgt msgtx->vins[i].spendlen = V[i].spendlen; if ( (sobj= jobj(item,"scriptSig")) != 0 ) { + printf("sobj.(%s)\n",jprint(sobj,0)); if ( (scriptsig= jstr(sobj,"hex")) != 0 ) { slen = (int32_t)strlen(scriptsig) >> 1; From 0ea00a6da12a85b09bdb811f281f8b92fa82aff2 Mon Sep 17 00:00:00 2001 From: jl777 Date: Sun, 19 Nov 2017 22:28:30 +0400 Subject: [PATCH 1009/1664] Test --- iguana/exchanges/LP_transaction.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/iguana/exchanges/LP_transaction.c b/iguana/exchanges/LP_transaction.c index d49696c13..d52b38f75 100644 --- a/iguana/exchanges/LP_transaction.c +++ b/iguana/exchanges/LP_transaction.c @@ -696,12 +696,13 @@ char *iguana_validaterawtx(void *ctx,struct iguana_info *coin,struct iguana_msgt if ( (scriptsig= jstr(sobj,"hex")) != 0 ) { slen = (int32_t)strlen(scriptsig) >> 1; + printf("slen.%d\n",slen); if ( slen <= sizeof(scriptsig) ) { msgtx->vins[i].scriptlen = slen; msgtx->vins[i].vinscript = scriptbuf; decode_hex(scriptbuf,slen,scriptsig); - if ( (sigsize= scriptbuf[0]) >= 72 && sigsize < 76 ) + if ( (sigsize= scriptbuf[0]) >= 70 && sigsize < 76 ) { memcpy(V[i].signers[0].sig,scriptbuf+1,sigsize-1); V[i].signers[0].siglen = sigsize - 1; From 0918583a282470d1d300c273012f3ed4e96c3257 Mon Sep 17 00:00:00 2001 From: jl777 Date: Sun, 19 Nov 2017 22:32:56 +0400 Subject: [PATCH 1010/1664] Test --- iguana/exchanges/LP_transaction.c | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/iguana/exchanges/LP_transaction.c b/iguana/exchanges/LP_transaction.c index d52b38f75..89860377b 100644 --- a/iguana/exchanges/LP_transaction.c +++ b/iguana/exchanges/LP_transaction.c @@ -696,20 +696,20 @@ char *iguana_validaterawtx(void *ctx,struct iguana_info *coin,struct iguana_msgt if ( (scriptsig= jstr(sobj,"hex")) != 0 ) { slen = (int32_t)strlen(scriptsig) >> 1; - printf("slen.%d\n",slen); if ( slen <= sizeof(scriptsig) ) { msgtx->vins[i].scriptlen = slen; msgtx->vins[i].vinscript = scriptbuf; decode_hex(scriptbuf,slen,scriptsig); - if ( (sigsize= scriptbuf[0]) >= 70 && sigsize < 76 ) + printf("slen.%d siglen.%d\n",slen,scriptbuf[1]); + if ( (sigsize= scriptbuf[1]) >= 70 && sigsize < 76 ) { - memcpy(V[i].signers[0].sig,scriptbuf+1,sigsize-1); + memcpy(V[i].signers[0].sig,scriptbuf+2,sigsize-1); V[i].signers[0].siglen = sigsize - 1; - V[i].hashtype = scriptbuf[sigsize-1]; + V[i].hashtype = scriptbuf[2 + sigsize-1]; if ( scriptbuf[sigsize] == 33 ) { - memcpy(V[i].signers[0].pubkey,&scriptbuf[sigsize+1],33); + memcpy(V[i].signers[0].pubkey,&scriptbuf[sigsize+2],33); } } else printf("sigsize.%d unexpected\n",sigsize); } From df1ac260adc89157c3a4b23a82bbf95392f2fd34 Mon Sep 17 00:00:00 2001 From: jl777 Date: Sun, 19 Nov 2017 22:36:59 +0400 Subject: [PATCH 1011/1664] Test --- iguana/exchanges/LP_transaction.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/iguana/exchanges/LP_transaction.c b/iguana/exchanges/LP_transaction.c index 89860377b..cd9cdf528 100644 --- a/iguana/exchanges/LP_transaction.c +++ b/iguana/exchanges/LP_transaction.c @@ -696,7 +696,7 @@ char *iguana_validaterawtx(void *ctx,struct iguana_info *coin,struct iguana_msgt if ( (scriptsig= jstr(sobj,"hex")) != 0 ) { slen = (int32_t)strlen(scriptsig) >> 1; - if ( slen <= sizeof(scriptsig) ) + if ( slen <= sizeof(scriptbuf) ) { msgtx->vins[i].scriptlen = slen; msgtx->vins[i].vinscript = scriptbuf; From 51831462c632d743840134ae8c9ec6cc459b8dff Mon Sep 17 00:00:00 2001 From: jl777 Date: Sun, 19 Nov 2017 22:39:01 +0400 Subject: [PATCH 1012/1664] Test --- iguana/exchanges/LP_transaction.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/iguana/exchanges/LP_transaction.c b/iguana/exchanges/LP_transaction.c index cd9cdf528..f216843a4 100644 --- a/iguana/exchanges/LP_transaction.c +++ b/iguana/exchanges/LP_transaction.c @@ -701,12 +701,12 @@ char *iguana_validaterawtx(void *ctx,struct iguana_info *coin,struct iguana_msgt msgtx->vins[i].scriptlen = slen; msgtx->vins[i].vinscript = scriptbuf; decode_hex(scriptbuf,slen,scriptsig); - printf("slen.%d siglen.%d\n",slen,scriptbuf[1]); - if ( (sigsize= scriptbuf[1]) >= 70 && sigsize < 76 ) + printf("slen.%d siglen.%d\n",slen,scriptbuf[0]); + if ( (sigsize= scriptbuf[0]) >= 70 && sigsize < 76 ) { - memcpy(V[i].signers[0].sig,scriptbuf+2,sigsize-1); + memcpy(V[i].signers[0].sig,scriptbuf+1,sigsize-1); V[i].signers[0].siglen = sigsize - 1; - V[i].hashtype = scriptbuf[2 + sigsize-1]; + V[i].hashtype = scriptbuf[1 + sigsize-1]; if ( scriptbuf[sigsize] == 33 ) { memcpy(V[i].signers[0].pubkey,&scriptbuf[sigsize+2],33); From 668343ce35baf4dba5a69670b7520d3ac7c427c1 Mon Sep 17 00:00:00 2001 From: jl777 Date: Sun, 19 Nov 2017 22:41:05 +0400 Subject: [PATCH 1013/1664] Test --- iguana/exchanges/LP_transaction.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/iguana/exchanges/LP_transaction.c b/iguana/exchanges/LP_transaction.c index f216843a4..ab9ec9cfd 100644 --- a/iguana/exchanges/LP_transaction.c +++ b/iguana/exchanges/LP_transaction.c @@ -707,7 +707,8 @@ char *iguana_validaterawtx(void *ctx,struct iguana_info *coin,struct iguana_msgt memcpy(V[i].signers[0].sig,scriptbuf+1,sigsize-1); V[i].signers[0].siglen = sigsize - 1; V[i].hashtype = scriptbuf[1 + sigsize-1]; - if ( scriptbuf[sigsize] == 33 ) + printf("hashtype.%d plen.%d\n",V[i].hashtype,scriptbuf[sigsize+1]); + if ( scriptbuf[sigsize+1] == 33 ) { memcpy(V[i].signers[0].pubkey,&scriptbuf[sigsize+2],33); } From 78a398883c1b3c929270568b79d6a3e5332c292b Mon Sep 17 00:00:00 2001 From: jl777 Date: Sun, 19 Nov 2017 22:45:58 +0400 Subject: [PATCH 1014/1664] Test --- iguana/exchanges/LP_transaction.c | 9 +++------ 1 file changed, 3 insertions(+), 6 deletions(-) diff --git a/iguana/exchanges/LP_transaction.c b/iguana/exchanges/LP_transaction.c index ab9ec9cfd..246de81dc 100644 --- a/iguana/exchanges/LP_transaction.c +++ b/iguana/exchanges/LP_transaction.c @@ -692,7 +692,6 @@ char *iguana_validaterawtx(void *ctx,struct iguana_info *coin,struct iguana_msgt msgtx->vins[i].spendlen = V[i].spendlen; if ( (sobj= jobj(item,"scriptSig")) != 0 ) { - printf("sobj.(%s)\n",jprint(sobj,0)); if ( (scriptsig= jstr(sobj,"hex")) != 0 ) { slen = (int32_t)strlen(scriptsig) >> 1; @@ -701,13 +700,11 @@ char *iguana_validaterawtx(void *ctx,struct iguana_info *coin,struct iguana_msgt msgtx->vins[i].scriptlen = slen; msgtx->vins[i].vinscript = scriptbuf; decode_hex(scriptbuf,slen,scriptsig); - printf("slen.%d siglen.%d\n",slen,scriptbuf[0]); if ( (sigsize= scriptbuf[0]) >= 70 && sigsize < 76 ) { memcpy(V[i].signers[0].sig,scriptbuf+1,sigsize-1); V[i].signers[0].siglen = sigsize - 1; V[i].hashtype = scriptbuf[1 + sigsize-1]; - printf("hashtype.%d plen.%d\n",V[i].hashtype,scriptbuf[sigsize+1]); if ( scriptbuf[sigsize+1] == 33 ) { memcpy(V[i].signers[0].pubkey,&scriptbuf[sigsize+2],33); @@ -719,9 +716,9 @@ char *iguana_validaterawtx(void *ctx,struct iguana_info *coin,struct iguana_msgt inputsum += V[i].amount; if ( msgtx->vins[i].sequence < IGUANA_SEQUENCEID_FINAL ) finalized = 0; - for (j=0; jvins[i].scriptlen; j++) - printf("%02x",msgtx->vins[i].vinscript[j]); - printf(" vin.%d (%s) scriptlen.%d spendlen.%d:%d finalize.%d\n",i,jprint(item,0),msgtx->vins[i].scriptlen,V[i].spendlen,msgtx->vins[i].spendlen,finalized); + for (j=0; jvins[i].spendlen; j++) + printf("%02x",msgtx->vins[i].spendscript[j]); + printf(" spendscript, vin.%d (%s) scriptlen.%d spendlen.%d:%d finalize.%d\n",i,jprint(item,0),msgtx->vins[i].scriptlen,V[i].spendlen,msgtx->vins[i].spendlen,finalized); } sighash = LP_sighash(symbol,zcash); complete = bitcoin_verifyvins(ctx,symbol,taddr,pubtype,p2shtype,isPoS,height,&signedtxid,&signedtx,msgtx,serialized2,maxsize,V,sighash,0,V[0].suppress_pubkeys,zcash); From e9846c19eb578b95332ed17c94e981fcf935c52f Mon Sep 17 00:00:00 2001 From: jl777 Date: Sun, 19 Nov 2017 22:54:25 +0400 Subject: [PATCH 1015/1664] Test --- iguana/exchanges/LP_transaction.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/iguana/exchanges/LP_transaction.c b/iguana/exchanges/LP_transaction.c index 246de81dc..1df7f9690 100644 --- a/iguana/exchanges/LP_transaction.c +++ b/iguana/exchanges/LP_transaction.c @@ -723,11 +723,11 @@ char *iguana_validaterawtx(void *ctx,struct iguana_info *coin,struct iguana_msgt sighash = LP_sighash(symbol,zcash); complete = bitcoin_verifyvins(ctx,symbol,taddr,pubtype,p2shtype,isPoS,height,&signedtxid,&signedtx,msgtx,serialized2,maxsize,V,sighash,0,V[0].suppress_pubkeys,zcash); msgtx->txid = signedtxid; - log = cJSON_CreateArray(); + /*log = cJSON_CreateArray(); if ( iguana_interpreter(ctx,log,0,V,numinputs) < 0 ) jaddstr(retjson,"error","interpreter rejects tx"); else complete = 1; - jadd(retjson,"interpreter",log); + jadd(retjson,"interpreter",log);*/ jaddnum(retjson,"complete",complete); free(serialized), free(serialized2); if ( signedtx != 0 ) From f283a165d4ef906738f622e2aeb10c2e024c1896 Mon Sep 17 00:00:00 2001 From: jl777 Date: Sun, 19 Nov 2017 22:56:22 +0400 Subject: [PATCH 1016/1664] Test --- iguana/exchanges/LP_transaction.c | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/iguana/exchanges/LP_transaction.c b/iguana/exchanges/LP_transaction.c index 1df7f9690..7e14ed5fa 100644 --- a/iguana/exchanges/LP_transaction.c +++ b/iguana/exchanges/LP_transaction.c @@ -624,7 +624,7 @@ int32_t iguana_signrawtransaction(void *ctx,char *symbol,uint8_t wiftaddr,uint8_ char *iguana_validaterawtx(void *ctx,struct iguana_info *coin,struct iguana_msgtx *msgtx,uint8_t *extraspace,int32_t extralen,char *rawtx,int32_t mempool,int32_t suppress_pubkeys,int32_t zcash) { - bits256 signedtxid; cJSON *log,*item,*vins,*vouts,*txobj,*retjson,*sobj; char *scriptsig,*signedtx; uint32_t sighash; int32_t j,sigsize,slen,height,finalized = 1,i,len,maxsize,numinputs,numoutputs,complete; struct vin_info *V; uint8_t *serialized,*serialized2,scriptbuf[256]; int64_t inputsum,outputsum; struct iguana_msgvout vout; + bits256 signedtxid; cJSON *item,*vins,*vouts,*txobj,*retjson,*sobj; char *scriptsig,*signedtx; uint32_t sighash; int32_t j,sigsize,slen,height,finalized = 1,i,len,maxsize,numinputs,numoutputs,complete; struct vin_info *V; uint8_t *serialized,*serialized2,scriptbuf[256]; int64_t inputsum,outputsum; struct iguana_msgvout vout; char *symbol; uint8_t wiftaddr,taddr,pubtype,p2shtype,isPoS; height = coin->longestchain; symbol = coin->symbol; @@ -716,9 +716,9 @@ char *iguana_validaterawtx(void *ctx,struct iguana_info *coin,struct iguana_msgt inputsum += V[i].amount; if ( msgtx->vins[i].sequence < IGUANA_SEQUENCEID_FINAL ) finalized = 0; - for (j=0; jvins[i].spendlen; j++) - printf("%02x",msgtx->vins[i].spendscript[j]); - printf(" spendscript, vin.%d (%s) scriptlen.%d spendlen.%d:%d finalize.%d\n",i,jprint(item,0),msgtx->vins[i].scriptlen,V[i].spendlen,msgtx->vins[i].spendlen,finalized); + //for (j=0; jvins[i].spendlen; j++) + // printf("%02x",msgtx->vins[i].spendscript[j]); + //printf(" spendscript, vin.%d (%s) scriptlen.%d spendlen.%d:%d finalize.%d\n",i,jprint(item,0),msgtx->vins[i].scriptlen,V[i].spendlen,msgtx->vins[i].spendlen,finalized); } sighash = LP_sighash(symbol,zcash); complete = bitcoin_verifyvins(ctx,symbol,taddr,pubtype,p2shtype,isPoS,height,&signedtxid,&signedtx,msgtx,serialized2,maxsize,V,sighash,0,V[0].suppress_pubkeys,zcash); @@ -748,7 +748,7 @@ char *iguana_validaterawtx(void *ctx,struct iguana_info *coin,struct iguana_msgt void test_validate(char *signedtx) { char *retstr; uint8_t extraspace[8192]; int32_t mempool=0; struct iguana_msgtx msgtx; struct iguana_info *coin = LP_coinfind("BTC"); - retstr = iguana_validaterawtx(bitcoin_ctx(),coin,&msgtx,extraspace,sizeof(extraspace),signedtx,mempool,0,LP_IS_BITCOINCASH*0); + retstr = iguana_validaterawtx(bitcoin_ctx(),coin,&msgtx,extraspace,sizeof(extraspace),signedtx,mempool,0,LP_IS_BITCOINCASH); printf("validate test.(%s)\n",retstr); } From 8a9de32b270a50fd856a8fa206e7f0898127ae8e Mon Sep 17 00:00:00 2001 From: jl777 Date: Sun, 19 Nov 2017 22:59:12 +0400 Subject: [PATCH 1017/1664] Test --- iguana/exchanges/LP_bitcoin.c | 8 ++++---- iguana/exchanges/LP_transaction.c | 6 +++--- 2 files changed, 7 insertions(+), 7 deletions(-) diff --git a/iguana/exchanges/LP_bitcoin.c b/iguana/exchanges/LP_bitcoin.c index ce483208f..15080f4e8 100644 --- a/iguana/exchanges/LP_bitcoin.c +++ b/iguana/exchanges/LP_bitcoin.c @@ -3309,9 +3309,9 @@ bits256 bitcoin_sigtxid(char *symbol,uint8_t taddr,uint8_t pubtype,uint8_t p2sht dest.vins[i].userdatalen = 0; } len = iguana_rwmsgtx(symbol,taddr,pubtype,p2shtype,isPoS,height,1,0,serialized,maxlen,&dest,&txid,vpnstr,0,0,0,suppress_pubkeys,zcash); - //for (i=0; i 0 ) // (dest.tx_in != 1 || bits256_nonz(dest.vins[0].prev_hash) != 0) && dest.vins[0].scriptlen > 0 && { #ifdef BTC2_VERSION @@ -3322,7 +3322,7 @@ bits256 bitcoin_sigtxid(char *symbol,uint8_t taddr,uint8_t pubtype,uint8_t p2sht revsigtxid = bits256_doublesha256(0,serialized,len); for (i=0; ivins[vini].spendscript; scriptlen = msgtx->vins[vini].spendlen; } - for (j=0; j Date: Sun, 19 Nov 2017 23:17:13 +0400 Subject: [PATCH 1018/1664] Test --- iguana/exchanges/LP_transaction.c | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/iguana/exchanges/LP_transaction.c b/iguana/exchanges/LP_transaction.c index 2241555c7..221b871db 100644 --- a/iguana/exchanges/LP_transaction.c +++ b/iguana/exchanges/LP_transaction.c @@ -624,7 +624,7 @@ int32_t iguana_signrawtransaction(void *ctx,char *symbol,uint8_t wiftaddr,uint8_ char *iguana_validaterawtx(void *ctx,struct iguana_info *coin,struct iguana_msgtx *msgtx,uint8_t *extraspace,int32_t extralen,char *rawtx,int32_t mempool,int32_t suppress_pubkeys,int32_t zcash) { - bits256 signedtxid; cJSON *item,*vins,*vouts,*txobj,*retjson,*sobj; char *scriptsig,*signedtx; uint32_t sighash; int32_t j,sigsize,slen,height,finalized = 1,i,len,maxsize,numinputs,numoutputs,complete; struct vin_info *V; uint8_t *serialized,*serialized2,scriptbuf[256]; int64_t inputsum,outputsum; struct iguana_msgvout vout; + bits256 signedtxid; cJSON *item,*vins,*vouts,*txobj,*retjson,*sobj; char *scriptsig,*signedtx; uint32_t sighash; int32_t sigsize,slen,height,finalized = 1,i,len,maxsize,numinputs,numoutputs,complete; struct vin_info *V; uint8_t *serialized,*serialized2,scriptbuf[256]; int64_t inputsum,outputsum; struct iguana_msgvout vout; char *symbol; uint8_t wiftaddr,taddr,pubtype,p2shtype,isPoS; height = coin->longestchain; symbol = coin->symbol; @@ -667,24 +667,24 @@ char *iguana_validaterawtx(void *ctx,struct iguana_info *coin,struct iguana_msgt if ( strcmp(jstr(item,"txid"),"775489f100361039f56793719d87621a73adbadda5e13c85e81d88f55ff9620e") == 0 && jint(item,"vout") == 1 ) { V[i].spendlen = 25; - decode_hex(V[i].spendscript,V[i].spendlen,"761914aa27d0ccbdcdd0f30fdbad3fa397b15b43e4c45688ac"); + decode_hex(V[i].spendscript,V[i].spendlen,"76a914aa27d0ccbdcdd0f30fdbad3fa397b15b43e4c45688ac"); V[i].amount = SATOSHIDEN * 0.00587427; strcpy(V[i].coinaddr,"19MnNLzxNTNXWUdfxpQvWK3CPwFXJbmLb8"); V[i].suppress_pubkeys = 0; sobj = cJSON_CreateObject(); - jaddstr(sobj,"hex","761914aa27d0ccbdcdd0f30fdbad3fa397b15b43e4c45688ac"); + jaddstr(sobj,"hex","76a914aa27d0ccbdcdd0f30fdbad3fa397b15b43e4c45688ac"); jadd(item,"scriptPubKey",sobj); printf("match special txid A\n"); } else if ( strcmp(jstr(item,"txid"),"980d621becd9bbd7f4a3fbd525a00ee5bc67518bb57da8bdcb1bd4c49cb83414") == 0 && jint(item,"vout") == 0 ) { V[i].spendlen = 25; - decode_hex(V[i].spendscript,V[i].spendlen,"7619146cfa0a987f4c8f2ffee7e9944ef0c86fcda9671d88ac"); + decode_hex(V[i].spendscript,V[i].spendlen,"76a9146cfa0a987f4c8f2ffee7e9944ef0c86fcda9671d88ac"); V[i].amount = SATOSHIDEN * 0.001; strcpy(V[i].coinaddr,"1AwDWu5rZKyGMUu16gf9Kow8ohnKmc7tGH"); V[i].suppress_pubkeys = 0; sobj = cJSON_CreateObject(); - jaddstr(sobj,"hex","761914aa27d0ccbdcdd0f30fdbad3fa397b15b43e4c45688ac"); + jaddstr(sobj,"hex","76a9146cfa0a987f4c8f2ffee7e9944ef0c86fcda9671d88ac"); jadd(item,"scriptPubKey",sobj); printf("match special txid B\n"); } @@ -723,11 +723,11 @@ char *iguana_validaterawtx(void *ctx,struct iguana_info *coin,struct iguana_msgt sighash = LP_sighash(symbol,zcash); complete = bitcoin_verifyvins(ctx,symbol,taddr,pubtype,p2shtype,isPoS,height,&signedtxid,&signedtx,msgtx,serialized2,maxsize,V,sighash,0,V[0].suppress_pubkeys,zcash); msgtx->txid = signedtxid; - /*log = cJSON_CreateArray(); + cJSON *log = cJSON_CreateArray(); if ( iguana_interpreter(ctx,log,0,V,numinputs) < 0 ) jaddstr(retjson,"error","interpreter rejects tx"); else complete = 1; - jadd(retjson,"interpreter",log);*/ + jadd(retjson,"interpreter",log); jaddnum(retjson,"complete",complete); free(serialized), free(serialized2); if ( signedtx != 0 ) From c9ffd6443fffcdd1c2a82c6a27e4e7ec36d4fda5 Mon Sep 17 00:00:00 2001 From: jl777 Date: Sun, 19 Nov 2017 23:22:35 +0400 Subject: [PATCH 1019/1664] Test --- iguana/exchanges/LP_transaction.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/iguana/exchanges/LP_transaction.c b/iguana/exchanges/LP_transaction.c index 221b871db..63b1ebce2 100644 --- a/iguana/exchanges/LP_transaction.c +++ b/iguana/exchanges/LP_transaction.c @@ -708,6 +708,9 @@ char *iguana_validaterawtx(void *ctx,struct iguana_info *coin,struct iguana_msgt if ( scriptbuf[sigsize+1] == 33 ) { memcpy(V[i].signers[0].pubkey,&scriptbuf[sigsize+2],33); + uint8_t rmd160[20]; char rmdstr[42]; + calc_rmd160(rmdstr,rmd160,V[i].signers[0].pubkey,33); + printf("RMD160.%s\n",rmdstr); } } else printf("sigsize.%d unexpected\n",sigsize); } From 7432910359db51f00b17c1e25edc415bad4036a2 Mon Sep 17 00:00:00 2001 From: jl777 Date: Sun, 19 Nov 2017 23:27:07 +0400 Subject: [PATCH 1020/1664] Test --- iguana/exchanges/LP_transaction.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/iguana/exchanges/LP_transaction.c b/iguana/exchanges/LP_transaction.c index 63b1ebce2..c9f699809 100644 --- a/iguana/exchanges/LP_transaction.c +++ b/iguana/exchanges/LP_transaction.c @@ -667,12 +667,12 @@ char *iguana_validaterawtx(void *ctx,struct iguana_info *coin,struct iguana_msgt if ( strcmp(jstr(item,"txid"),"775489f100361039f56793719d87621a73adbadda5e13c85e81d88f55ff9620e") == 0 && jint(item,"vout") == 1 ) { V[i].spendlen = 25; - decode_hex(V[i].spendscript,V[i].spendlen,"76a914aa27d0ccbdcdd0f30fdbad3fa397b15b43e4c45688ac"); + decode_hex(V[i].spendscript,V[i].spendlen,"76a9145baf32629848126250861381382d1117a3d6efaa 688ac"); V[i].amount = SATOSHIDEN * 0.00587427; strcpy(V[i].coinaddr,"19MnNLzxNTNXWUdfxpQvWK3CPwFXJbmLb8"); V[i].suppress_pubkeys = 0; sobj = cJSON_CreateObject(); - jaddstr(sobj,"hex","76a914aa27d0ccbdcdd0f30fdbad3fa397b15b43e4c45688ac"); + jaddstr(sobj,"hex","76a9145baf32629848126250861381382d1117a3d6efaa"); jadd(item,"scriptPubKey",sobj); printf("match special txid A\n"); } From 43668459da9ebcbc553877997ced5f110655e34e Mon Sep 17 00:00:00 2001 From: jl777 Date: Sun, 19 Nov 2017 23:29:21 +0400 Subject: [PATCH 1021/1664] Test --- iguana/exchanges/LP_transaction.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/iguana/exchanges/LP_transaction.c b/iguana/exchanges/LP_transaction.c index c9f699809..bd33f2573 100644 --- a/iguana/exchanges/LP_transaction.c +++ b/iguana/exchanges/LP_transaction.c @@ -667,12 +667,12 @@ char *iguana_validaterawtx(void *ctx,struct iguana_info *coin,struct iguana_msgt if ( strcmp(jstr(item,"txid"),"775489f100361039f56793719d87621a73adbadda5e13c85e81d88f55ff9620e") == 0 && jint(item,"vout") == 1 ) { V[i].spendlen = 25; - decode_hex(V[i].spendscript,V[i].spendlen,"76a9145baf32629848126250861381382d1117a3d6efaa 688ac"); + decode_hex(V[i].spendscript,V[i].spendlen,"76a9145baf32629848126250861381382d1117a3d6efaa688ac"); V[i].amount = SATOSHIDEN * 0.00587427; strcpy(V[i].coinaddr,"19MnNLzxNTNXWUdfxpQvWK3CPwFXJbmLb8"); V[i].suppress_pubkeys = 0; sobj = cJSON_CreateObject(); - jaddstr(sobj,"hex","76a9145baf32629848126250861381382d1117a3d6efaa"); + jaddstr(sobj,"hex","76a9145baf32629848126250861381382d1117a3d6efaa688ac"); jadd(item,"scriptPubKey",sobj); printf("match special txid A\n"); } From 06c7c44cb11e595dd160f6d05307cd6234a4cc78 Mon Sep 17 00:00:00 2001 From: jl777 Date: Sun, 19 Nov 2017 23:30:59 +0400 Subject: [PATCH 1022/1664] Test --- iguana/exchanges/LP_transaction.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/iguana/exchanges/LP_transaction.c b/iguana/exchanges/LP_transaction.c index bd33f2573..34bec55b9 100644 --- a/iguana/exchanges/LP_transaction.c +++ b/iguana/exchanges/LP_transaction.c @@ -667,12 +667,12 @@ char *iguana_validaterawtx(void *ctx,struct iguana_info *coin,struct iguana_msgt if ( strcmp(jstr(item,"txid"),"775489f100361039f56793719d87621a73adbadda5e13c85e81d88f55ff9620e") == 0 && jint(item,"vout") == 1 ) { V[i].spendlen = 25; - decode_hex(V[i].spendscript,V[i].spendlen,"76a9145baf32629848126250861381382d1117a3d6efaa688ac"); + decode_hex(V[i].spendscript,V[i].spendlen,"76a9145baf32629848126250861381382d1117a3d6efaa88ac"); V[i].amount = SATOSHIDEN * 0.00587427; strcpy(V[i].coinaddr,"19MnNLzxNTNXWUdfxpQvWK3CPwFXJbmLb8"); V[i].suppress_pubkeys = 0; sobj = cJSON_CreateObject(); - jaddstr(sobj,"hex","76a9145baf32629848126250861381382d1117a3d6efaa688ac"); + jaddstr(sobj,"hex","76a9145baf32629848126250861381382d1117a3d6efaa88ac"); jadd(item,"scriptPubKey",sobj); printf("match special txid A\n"); } From b6d41bd65f436ae42bb97f38772888aa110b45e1 Mon Sep 17 00:00:00 2001 From: jl777 Date: Sun, 19 Nov 2017 23:36:53 +0400 Subject: [PATCH 1023/1664] Test --- iguana/exchanges/LP_include.h | 2 +- iguana/exchanges/LP_nativeDEX.c | 7 ++++--- iguana/exchanges/LP_ordermatch.c | 4 ++-- 3 files changed, 7 insertions(+), 6 deletions(-) diff --git a/iguana/exchanges/LP_include.h b/iguana/exchanges/LP_include.h index 13d1333b7..c666ab1aa 100644 --- a/iguana/exchanges/LP_include.h +++ b/iguana/exchanges/LP_include.h @@ -44,7 +44,7 @@ void emscripten_usleep(int32_t x); // returns immediate, no sense for sleeping #define LP_MAXVINS 64 #define LP_HTTP_TIMEOUT 3 // 1 is too small due to edge cases of time(NULL) #define LP_AUTOTRADE_TIMEOUT 30 -#define LP_RESERVETIME (LP_AUTOTRADE_TIMEOUT * 2) +#define LP_RESERVETIME 600 #define ELECTRUM_TIMEOUT 7 #define LP_ELECTRUM_KEEPALIVE 60 #define LP_ELECTRUM_MAXERRORS 777 diff --git a/iguana/exchanges/LP_nativeDEX.c b/iguana/exchanges/LP_nativeDEX.c index 2a70bb2c5..55eeffb5a 100644 --- a/iguana/exchanges/LP_nativeDEX.c +++ b/iguana/exchanges/LP_nativeDEX.c @@ -19,7 +19,8 @@ // // alice waiting for bestprice // MNZ getcoin strangeness -// [{"date":1405699200,"high":0.0045388,"low":0.00403001,"open":0.00404545,"close":0.00435873,"relvol":44.34555992,"basevol":10311.88079097,"aveprice":0.00430043}, // minute, +// [{"date":1405699200,"high":0.0045388,"low":0.00403001,"open":0.00404545,"close":0.00435873,"relvol":44.34555992,"basevol":10311.88079097,"aveprice":0.00430043}, // minute, +// https://github.com/bitcoin/bips/blob/master/bip-0143.mediawiki for signing BCH/BTG // improve critical section detection when parallel trades // reduce mem: dont redundant store pubkey utxo info @@ -680,9 +681,9 @@ void LP_initcoins(void *ctx,int32_t pubsock,cJSON *coins) printf("%s ",activecoins[i]); LP_coinfind(activecoins[i]); LP_priceinfoadd(activecoins[i]); - test_validate("02000000010e62f95ff5881de8853ce1a5ddbaad731a62879d719367f539103600f1895477010000006b483045022100c684a0871689519bd97f2e61275752124f0f1498360750c87cf99a8acf06fd8c022047e7e62a7bfd481599130e6f40c95833f6ed6f44aa8b6ead7b0ec86a738b98a041210361857e1ba609aadff520a2ca9886fe7548c7154fab2cbe108c3b0e1e7635eb1ffeffffff02a0860100000000001976a9146cfa0a987f4c8f2ffee7e9944ef0c86fcda9671d88ac1e6f0700000000001976a9147f4b7113f9e26d84b150f2cc6d219baaf27f884488ace6b00700"); + //test_validate("02000000010e62f95ff5881de8853ce1a5ddbaad731a62879d719367f539103600f1895477010000006b483045022100c684a0871689519bd97f2e61275752124f0f1498360750c87cf99a8acf06fd8c022047e7e62a7bfd481599130e6f40c95833f6ed6f44aa8b6ead7b0ec86a738b98a041210361857e1ba609aadff520a2ca9886fe7548c7154fab2cbe108c3b0e1e7635eb1ffeffffff02a0860100000000001976a9146cfa0a987f4c8f2ffee7e9944ef0c86fcda9671d88ac1e6f0700000000001976a9147f4b7113f9e26d84b150f2cc6d219baaf27f884488ace6b00700"); //test_validate("01000000011434b89cc4d41bcbbda87db58b5167bce50ea025d5fba3f4d7bbd9ec1b620d98000000006a47304402205aba01fa2b895df6069dc7458fcc7aac6da1ffbc2811eb43382a5a342a342c6202207da60859f45893785322fede2f82b1f7c76cd9882b6a8ed6d25037f4184b60514121029d1e15b82fc3e11b51b61eb65545b0c93baebb17de5118979f261a086575bcd6ffffffff0210270000000000001976a9146cfa0a987f4c8f2ffee7e9944ef0c86fcda9671d88ac80380100000000001976a9146cfa0a987f4c8f2ffee7e9944ef0c86fcda9671d88ac00000000"); - getchar(); + //getchar(); if ( (coin= LP_coinfind(activecoins[i])) != 0 ) { if ( LP_getheight(coin) <= 0 ) diff --git a/iguana/exchanges/LP_ordermatch.c b/iguana/exchanges/LP_ordermatch.c index bc73ee840..a8922f36a 100644 --- a/iguana/exchanges/LP_ordermatch.c +++ b/iguana/exchanges/LP_ordermatch.c @@ -20,8 +20,8 @@ // struct LP_quoteinfo LP_Alicequery,LP_Alicereserved; double LP_Alicemaxprice; -bits256 LP_Alicedestpubkey; -uint32_t Alice_expiration; +bits256 LP_Alicedestpubkey,LP_bobs_reserved; +uint32_t Alice_expiration,Bob_expiration; struct { uint64_t aliceid; double bestprice; uint32_t starttime,counter; } Bob_competition[512]; double LP_bob_competition(int32_t *counterp,uint64_t aliceid,double price,int32_t counter) From 294e005161799717f1097ff9fb799a271af67f38 Mon Sep 17 00:00:00 2001 From: jl777 Date: Mon, 20 Nov 2017 00:56:01 +0400 Subject: [PATCH 1024/1664] Revert --- iguana/exchanges/LP_include.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/iguana/exchanges/LP_include.h b/iguana/exchanges/LP_include.h index c666ab1aa..13d1333b7 100644 --- a/iguana/exchanges/LP_include.h +++ b/iguana/exchanges/LP_include.h @@ -44,7 +44,7 @@ void emscripten_usleep(int32_t x); // returns immediate, no sense for sleeping #define LP_MAXVINS 64 #define LP_HTTP_TIMEOUT 3 // 1 is too small due to edge cases of time(NULL) #define LP_AUTOTRADE_TIMEOUT 30 -#define LP_RESERVETIME 600 +#define LP_RESERVETIME (LP_AUTOTRADE_TIMEOUT * 2) #define ELECTRUM_TIMEOUT 7 #define LP_ELECTRUM_KEEPALIVE 60 #define LP_ELECTRUM_MAXERRORS 777 From 2606ed803ac0ade4347b8003277f5288a0212bc5 Mon Sep 17 00:00:00 2001 From: jl777 Date: Mon, 20 Nov 2017 01:00:08 +0400 Subject: [PATCH 1025/1664] Test --- iguana/exchanges/LP_include.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/iguana/exchanges/LP_include.h b/iguana/exchanges/LP_include.h index 13d1333b7..e555a8c61 100644 --- a/iguana/exchanges/LP_include.h +++ b/iguana/exchanges/LP_include.h @@ -44,7 +44,7 @@ void emscripten_usleep(int32_t x); // returns immediate, no sense for sleeping #define LP_MAXVINS 64 #define LP_HTTP_TIMEOUT 3 // 1 is too small due to edge cases of time(NULL) #define LP_AUTOTRADE_TIMEOUT 30 -#define LP_RESERVETIME (LP_AUTOTRADE_TIMEOUT * 2) +#define LP_RESERVETIME 300 //(LP_AUTOTRADE_TIMEOUT * 2) #define ELECTRUM_TIMEOUT 7 #define LP_ELECTRUM_KEEPALIVE 60 #define LP_ELECTRUM_MAXERRORS 777 From cf3fb0ce544eb4bdf19cdcd263ad3756973a37fe Mon Sep 17 00:00:00 2001 From: DeckerSU Date: Mon, 20 Nov 2017 18:31:53 +0300 Subject: [PATCH 1026/1664] fix coin pathes on Windows in LP_statefname - fix coin paths for coins without confpath in coins.json - auto change `${process.env.HOME}` to LP_getdatadir() for coins with confpath in coins.json --- iguana/exchanges/LP_coins.c | 33 ++++++++++++++++++++++++++++++--- 1 file changed, 30 insertions(+), 3 deletions(-) diff --git a/iguana/exchanges/LP_coins.c b/iguana/exchanges/LP_coins.c index 7f43a005a..45b7f60da 100644 --- a/iguana/exchanges/LP_coins.c +++ b/iguana/exchanges/LP_coins.c @@ -99,7 +99,34 @@ void LP_statefname(char *fname,char *symbol,char *assetname,char *str,char *name { if ( confpath != 0 && confpath[0] != 0 ) { - strcpy(fname,confpath); + #if defined(NATIVE_WINDOWS) + // need to do something with "confpath":"`${process.env.HOME}`/.muecore/mue.conf" under Windows + char *ht = "`${process.env.HOME}`", *ht_start, *p_ht; + char ht_symbol[2]; + + ht_start = strstr(confpath, ht); + + if (ht_start) { + ht_start = ht_start + strlen(ht); + sprintf(fname, "%s\\", LP_getdatadir()); + p_ht = ht_start; + if (p_ht[0] == '/' && p_ht[1] == '.') { + p_ht += 2; + //printf("%s\n", p_ht); + while (p_ht[0] != '\0') { + if (p_ht[0] == '/') strcat(fname, "\\"); else + { + ht_symbol[0] = p_ht[0]; ht_symbol[1] = '\0'; + strcat(fname, ht_symbol); + } + p_ht++; + } + //printf("%s\n", fname); + } + } else strcpy(fname, confpath); + #else + strcpy(fname,confpath); + #endif return; } sprintf(fname,"%s",LP_getdatadir()); @@ -119,7 +146,7 @@ void LP_statefname(char *fname,char *symbol,char *assetname,char *str,char *name else if ( name != 0 ) { char name2[64]; -#ifdef __APPLE__ +#if defined(__APPLE__) || defined(NATIVE_WINDOWS) int32_t len; strcpy(name2,name); name2[0] = toupper(name2[0]); @@ -164,7 +191,7 @@ uint16_t LP_userpass(char *userpass,char *symbol,char *assetname,char *confroot, sprintf(confname,"%s.conf",confroot); if ( 0 ) printf("%s (%s) %s confname.(%s) confroot.(%s)\n",symbol,assetname,name,confname,confroot); -#ifdef __APPLE__ +#if defined(__APPLE__) || defined(NATIVE_WINDOWS) int32_t len; confname[0] = toupper(confname[0]); len = (int32_t)strlen(confname); From ff44a61af1c19db28a6974ef53950576209db108 Mon Sep 17 00:00:00 2001 From: jl777 Date: Mon, 20 Nov 2017 23:01:03 +0400 Subject: [PATCH 1027/1664] Test --- iguana/exchanges/LP_include.h | 2 +- iguana/exchanges/LP_nativeDEX.c | 6 ++++ iguana/exchanges/LP_swap.c | 56 ++++++++++++++++++++------------- 3 files changed, 41 insertions(+), 23 deletions(-) diff --git a/iguana/exchanges/LP_include.h b/iguana/exchanges/LP_include.h index e555a8c61..adc089b75 100644 --- a/iguana/exchanges/LP_include.h +++ b/iguana/exchanges/LP_include.h @@ -44,7 +44,7 @@ void emscripten_usleep(int32_t x); // returns immediate, no sense for sleeping #define LP_MAXVINS 64 #define LP_HTTP_TIMEOUT 3 // 1 is too small due to edge cases of time(NULL) #define LP_AUTOTRADE_TIMEOUT 30 -#define LP_RESERVETIME 300 //(LP_AUTOTRADE_TIMEOUT * 2) +#define LP_RESERVETIME 600 //(LP_AUTOTRADE_TIMEOUT * 2) #define ELECTRUM_TIMEOUT 7 #define LP_ELECTRUM_KEEPALIVE 60 #define LP_ELECTRUM_MAXERRORS 777 diff --git a/iguana/exchanges/LP_nativeDEX.c b/iguana/exchanges/LP_nativeDEX.c index 55eeffb5a..e0597dd41 100644 --- a/iguana/exchanges/LP_nativeDEX.c +++ b/iguana/exchanges/LP_nativeDEX.c @@ -20,6 +20,12 @@ // alice waiting for bestprice // MNZ getcoin strangeness // [{"date":1405699200,"high":0.0045388,"low":0.00403001,"open":0.00404545,"close":0.00435873,"relvol":44.34555992,"basevol":10311.88079097,"aveprice":0.00430043}, // minute, +// trying to do bot_sell and the output he sent me is this +//{"base":"KMD","rel":"MNZ","basevolume":"0.08","minprice":5.608418011097937,"gui":"gecko","method":"bot_sell","userpass":"4011dddbfd920f9fab037907c2a13ba7eec207245487efa61cd0c484f8b1d607"} +//{"error":"not enough funds","coin":"KMD","abalance":0.00204856,"balance":9.9999,"relvolume":0.08,"txfees":0.001,"shortfall":-9.9189,"withdraw": +//i assume bot_sell detected he didn't had the proper utxos, tried to make some with the withdraw-method and failed with "not enough funds" +// the reason: bot_sell uses basevolume:0.08 and the withdraw-method uses relvolume:0.08 + // https://github.com/bitcoin/bips/blob/master/bip-0143.mediawiki for signing BCH/BTG // improve critical section detection when parallel trades // reduce mem: dont redundant store pubkey utxo info diff --git a/iguana/exchanges/LP_swap.c b/iguana/exchanges/LP_swap.c index 2a61c593d..e9000f363 100644 --- a/iguana/exchanges/LP_swap.c +++ b/iguana/exchanges/LP_swap.c @@ -867,41 +867,53 @@ void LP_aliceloop(void *_swap) printf("error sending alicefee\n"); else if ( LP_waitfor(swap->N.pair,swap,1800,LP_verify_bobdeposit) < 0 ) printf("error waiting for bobdeposit\n"); - else if ( LP_swapdata_rawtxsend(swap->N.pair,swap,0x1000,data,maxlen,&swap->alicepayment,0x800,0) == 0 ) - printf("error sending alicepayment\n"); else { - if ( strcmp(swap->I.alicestr,"BTC") == 0 ) + if ( strcmp(swap->I.bobstr,"BTC") == 0 ) m = 0; - else m = swap->I.aliceconfirms; - while ( (n= LP_numconfirms(swap->I.alicestr,swap->alicepayment.I.destaddr,swap->alicepayment.I.signedtxid,0,1)) < m ) + else m = swap->I.bobconfirms; + while ( (n= LP_numconfirms(swap->I.bobstr,swap->bobpayment.I.destaddr,swap->bobpayment.I.signedtxid,0,1)) < m ) { LP_swap_critical = (uint32_t)time(NULL); - char str[65];printf("%d wait for alicepayment %s numconfs.%d %s %s\n",n,swap->alicepayment.I.destaddr,m,swap->I.alicestr,bits256_str(str,swap->alicepayment.I.signedtxid)); + char str[65];printf("%d wait for bobpayment %s numconfs.%d %s %s\n",n,swap->bobpayment.I.destaddr,m,swap->I.bobstr,bits256_str(str,swap->bobpayment.I.signedtxid)); sleep(10); } - swap->sentflag = 1; - LP_swap_critical = (uint32_t)time(NULL); - if ( LP_waitfor(swap->N.pair,swap,1800,LP_verify_bobpayment) < 0 ) - printf("error waiting for bobpayment\n"); + if ( LP_swapdata_rawtxsend(swap->N.pair,swap,0x1000,data,maxlen,&swap->alicepayment,0x800,0) == 0 ) + printf("error sending alicepayment\n"); else { - LP_swap_endcritical = (uint32_t)time(NULL); - while ( (n= LP_numconfirms(swap->I.bobstr,swap->bobpayment.I.destaddr,swap->bobpayment.I.signedtxid,0,1)) < swap->I.bobconfirms ) + if ( strcmp(swap->I.alicestr,"BTC") == 0 ) + m = 0; + else m = swap->I.aliceconfirms; + while ( (n= LP_numconfirms(swap->I.alicestr,swap->alicepayment.I.destaddr,swap->alicepayment.I.signedtxid,0,1)) < m ) { - char str[65];printf("%d wait for bobpayment %s numconfs.%d %s %s\n",n,swap->bobpayment.I.destaddr,swap->I.bobconfirms,swap->I.bobstr,bits256_str(str,swap->bobpayment.I.signedtxid)); + LP_swap_critical = (uint32_t)time(NULL); + char str[65];printf("%d wait for alicepayment %s numconfs.%d %s %s\n",n,swap->alicepayment.I.destaddr,m,swap->I.alicestr,bits256_str(str,swap->alicepayment.I.signedtxid)); sleep(10); } - /*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->I.alicestr,swap->alicespend.I.destaddr,swap->alicespend.I.signedtxid,0,1)) < swap->I.aliceconfirms ) + swap->sentflag = 1; + LP_swap_critical = (uint32_t)time(NULL); + if ( LP_waitfor(swap->N.pair,swap,1800,LP_verify_bobpayment) < 0 ) + printf("error waiting for bobpayment\n"); + else { - char str[65];printf("%d wait for alicespend %s numconfs.%d %s %s\n",n,swap->alicespend.I.destaddr,swap->I.aliceconfirms,swap->I.bobstr,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,LP_atomic_locktime(swap->I.bobstr,swap->I.alicestr)*2,30); + LP_swap_endcritical = (uint32_t)time(NULL); + while ( (n= LP_numconfirms(swap->I.bobstr,swap->bobpayment.I.destaddr,swap->bobpayment.I.signedtxid,0,1)) < swap->I.bobconfirms ) + { + char str[65];printf("%d wait for bobpayment %s numconfs.%d %s %s\n",n,swap->bobpayment.I.destaddr,swap->I.bobconfirms,swap->I.bobstr,bits256_str(str,swap->bobpayment.I.signedtxid)); + sleep(10); + } + /*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->I.alicestr,swap->alicespend.I.destaddr,swap->alicespend.I.signedtxid,0,1)) < swap->I.aliceconfirms ) + { + char str[65];printf("%d wait for alicespend %s numconfs.%d %s %s\n",n,swap->alicespend.I.destaddr,swap->I.aliceconfirms,swap->I.bobstr,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,LP_atomic_locktime(swap->I.bobstr,swap->I.alicestr)*2,30); + } } } } From 5ec62edf470147ca0911fe40068843dfe1babd98 Mon Sep 17 00:00:00 2001 From: jl777 Date: Mon, 20 Nov 2017 23:03:19 +0400 Subject: [PATCH 1028/1664] Test --- iguana/exchanges/LP_swap.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/iguana/exchanges/LP_swap.c b/iguana/exchanges/LP_swap.c index e9000f363..2461bfcf0 100644 --- a/iguana/exchanges/LP_swap.c +++ b/iguana/exchanges/LP_swap.c @@ -872,10 +872,10 @@ void LP_aliceloop(void *_swap) if ( strcmp(swap->I.bobstr,"BTC") == 0 ) m = 0; else m = swap->I.bobconfirms; - while ( (n= LP_numconfirms(swap->I.bobstr,swap->bobpayment.I.destaddr,swap->bobpayment.I.signedtxid,0,1)) < m ) + while ( (n= LP_numconfirms(swap->I.bobstr,swap->bobdeposit.I.destaddr,swap->bobdeposit.I.signedtxid,0,1)) < m ) { LP_swap_critical = (uint32_t)time(NULL); - char str[65];printf("%d wait for bobpayment %s numconfs.%d %s %s\n",n,swap->bobpayment.I.destaddr,m,swap->I.bobstr,bits256_str(str,swap->bobpayment.I.signedtxid)); + char str[65];printf("%d wait for bobdeposit %s numconfs.%d %s %s\n",n,swap->bobdeposit.I.destaddr,m,swap->I.bobstr,bits256_str(str,swap->bobdeposit.I.signedtxid)); sleep(10); } if ( LP_swapdata_rawtxsend(swap->N.pair,swap,0x1000,data,maxlen,&swap->alicepayment,0x800,0) == 0 ) From 10c84f35aa04ab23bcf6ad0c362114e69b616f6b Mon Sep 17 00:00:00 2001 From: jl777 Date: Tue, 21 Nov 2017 11:54:28 +0400 Subject: [PATCH 1029/1664] Test --- iguana/exchanges/LP_nativeDEX.c | 121 ++++++++++++++++++++++++++++++-- iguana/exchanges/LP_network.c | 116 ------------------------------ 2 files changed, 116 insertions(+), 121 deletions(-) diff --git a/iguana/exchanges/LP_nativeDEX.c b/iguana/exchanges/LP_nativeDEX.c index e0597dd41..66b0d49d0 100644 --- a/iguana/exchanges/LP_nativeDEX.c +++ b/iguana/exchanges/LP_nativeDEX.c @@ -20,11 +20,6 @@ // alice waiting for bestprice // MNZ getcoin strangeness // [{"date":1405699200,"high":0.0045388,"low":0.00403001,"open":0.00404545,"close":0.00435873,"relvol":44.34555992,"basevol":10311.88079097,"aveprice":0.00430043}, // minute, -// trying to do bot_sell and the output he sent me is this -//{"base":"KMD","rel":"MNZ","basevolume":"0.08","minprice":5.608418011097937,"gui":"gecko","method":"bot_sell","userpass":"4011dddbfd920f9fab037907c2a13ba7eec207245487efa61cd0c484f8b1d607"} -//{"error":"not enough funds","coin":"KMD","abalance":0.00204856,"balance":9.9999,"relvolume":0.08,"txfees":0.001,"shortfall":-9.9189,"withdraw": -//i assume bot_sell detected he didn't had the proper utxos, tried to make some with the withdraw-method and failed with "not enough funds" -// the reason: bot_sell uses basevolume:0.08 and the withdraw-method uses relvolume:0.08 // https://github.com/bitcoin/bips/blob/master/bip-0143.mediawiki for signing BCH/BTG // improve critical section detection when parallel trades @@ -826,6 +821,122 @@ void LP_swapsloop(void *ignore) } } +void gc_loop(void *arg) +{ + uint32_t now; struct LP_address_utxo *up,*utmp; struct rpcrequest_info *req,*rtmp; int32_t flag = 0; + strcpy(LP_gcloop_stats.name,"gc_loop"); + LP_gcloop_stats.threshold = 11000.; + while ( 1 ) + { + flag = 0; + LP_millistats_update(&LP_gcloop_stats); + portable_mutex_lock(&LP_gcmutex); + DL_FOREACH_SAFE(LP_garbage_collector,req,rtmp) + { + DL_DELETE(LP_garbage_collector,req); + //printf("garbage collect ipbits.%x\n",req->ipbits); + free(req); + flag++; + } + now = (uint32_t)time(NULL); + DL_FOREACH_SAFE(LP_garbage_collector2,up,utmp) + { + if ( now > (uint32_t)up->spendheight+120 ) + { + DL_DELETE(LP_garbage_collector2,up); + //char str[65]; printf("garbage collect %s/v%d lag.%d\n",bits256_str(str,up->U.txid),up->U.vout,now-up->spendheight); + free(up); + } + flag++; + } + portable_mutex_unlock(&LP_gcmutex); + if ( 0 && flag != 0 ) + printf("gc_loop.%d\n",flag); + sleep(10); + } +} + +void queue_loop(void *arg) +{ + struct LP_queue *ptr,*tmp; int32_t sentbytes,nonz,flag,duplicate,n=0; + strcpy(queue_loop_stats.name,"queue_loop"); + queue_loop_stats.threshold = 1000.; + while ( 1 ) + { + LP_millistats_update(&queue_loop_stats); + //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 = nonz = flag = 0; + DL_FOREACH_SAFE(LP_Q,ptr,tmp) + { + n++; + flag = 0; + if ( ptr->sock >= 0 ) + { + if ( ptr->notready == 0 || (LP_rand() % ptr->notready) == 0 ) + { + if ( LP_sockcheck(ptr->sock) > 0 ) + { + bits256 magic; + magic = LP_calc_magic(ptr->msg,(int32_t)(ptr->msglen - sizeof(bits256))); + memcpy(&ptr->msg[ptr->msglen - sizeof(bits256)],&magic,sizeof(magic)); + if ( (sentbytes= nn_send(ptr->sock,ptr->msg,ptr->msglen,0)) != ptr->msglen ) + printf("%d LP_send sent %d instead of %d\n",n,sentbytes,ptr->msglen); + else flag++; + ptr->sock = -1; + if ( ptr->peerind > 0 ) + ptr->starttime = (uint32_t)time(NULL); + } + else + { + if ( ptr->notready++ > 1000 ) + flag = 1; + } + } + } + else if ( 0 && time(NULL) > ptr->starttime+13 ) + { + LP_crc32find(&duplicate,-1,ptr->crc32); + if ( duplicate > 0 ) + { + LP_Qfound++; + if ( (LP_Qfound % 100) == 0 ) + printf("found.%u Q.%d err.%d match.%d\n",ptr->crc32,LP_Qenqueued,LP_Qerrors,LP_Qfound); + flag++; + } + else if ( 0 ) // too much beyond duplicate filter when network is busy + { + printf("couldnt find.%u peerind.%d Q.%d err.%d match.%d\n",ptr->crc32,ptr->peerind,LP_Qenqueued,LP_Qerrors,LP_Qfound); + ptr->peerind++; + if ( (ptr->sock= LP_peerindsock(&ptr->peerind)) < 0 ) + { + printf("%d no more peers to try at peerind.%d %p Q_LP.%p\n",n,ptr->peerind,ptr,LP_Q); + flag++; + LP_Qerrors++; + } + } + } + if ( flag != 0 ) + { + nonz++; + portable_mutex_lock(&LP_networkmutex); + DL_DELETE(LP_Q,ptr); + portable_mutex_unlock(&LP_networkmutex); + free(ptr); + ptr = 0; + break; + } + } + if ( arg == 0 ) + break; + if ( nonz == 0 ) + { + if ( IAMLP == 0 ) + usleep(50000); + else usleep(10000); + } + } +} + void LP_reserved_msgs(void *ignore) { bits256 zero; int32_t flag,nonz; struct nn_pollfd pfd; diff --git a/iguana/exchanges/LP_network.c b/iguana/exchanges/LP_network.c index d1b147bc8..0f680ad0b 100644 --- a/iguana/exchanges/LP_network.c +++ b/iguana/exchanges/LP_network.c @@ -265,122 +265,6 @@ int32_t LP_peerindsock(int32_t *peerindp) return(-1); } -void gc_loop(void *arg) -{ - uint32_t now; struct LP_address_utxo *up,*utmp; struct rpcrequest_info *req,*rtmp; int32_t flag = 0; - strcpy(LP_gcloop_stats.name,"gc_loop"); - LP_gcloop_stats.threshold = 11000.; - while ( 1 ) - { - flag = 0; - LP_millistats_update(&LP_gcloop_stats); - portable_mutex_lock(&LP_gcmutex); - DL_FOREACH_SAFE(LP_garbage_collector,req,rtmp) - { - DL_DELETE(LP_garbage_collector,req); - //printf("garbage collect ipbits.%x\n",req->ipbits); - free(req); - flag++; - } - now = (uint32_t)time(NULL); - DL_FOREACH_SAFE(LP_garbage_collector2,up,utmp) - { - if ( now > (uint32_t)up->spendheight+120 ) - { - DL_DELETE(LP_garbage_collector2,up); - //char str[65]; printf("garbage collect %s/v%d lag.%d\n",bits256_str(str,up->U.txid),up->U.vout,now-up->spendheight); - free(up); - } - flag++; - } - portable_mutex_unlock(&LP_gcmutex); - if ( 0 && flag != 0 ) - printf("gc_loop.%d\n",flag); - sleep(10); - } -} - -void queue_loop(void *arg) -{ - struct LP_queue *ptr,*tmp; int32_t sentbytes,nonz,flag,duplicate,n=0; - strcpy(queue_loop_stats.name,"queue_loop"); - queue_loop_stats.threshold = 1000.; - while ( 1 ) - { - LP_millistats_update(&queue_loop_stats); - //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 = nonz = flag = 0; - DL_FOREACH_SAFE(LP_Q,ptr,tmp) - { - n++; - flag = 0; - if ( ptr->sock >= 0 ) - { - if ( ptr->notready == 0 || (LP_rand() % ptr->notready) == 0 ) - { - if ( LP_sockcheck(ptr->sock) > 0 ) - { - bits256 magic; - magic = LP_calc_magic(ptr->msg,(int32_t)(ptr->msglen - sizeof(bits256))); - memcpy(&ptr->msg[ptr->msglen - sizeof(bits256)],&magic,sizeof(magic)); - if ( (sentbytes= nn_send(ptr->sock,ptr->msg,ptr->msglen,0)) != ptr->msglen ) - printf("%d LP_send sent %d instead of %d\n",n,sentbytes,ptr->msglen); - else flag++; - ptr->sock = -1; - if ( ptr->peerind > 0 ) - ptr->starttime = (uint32_t)time(NULL); - } - else - { - if ( ptr->notready++ > 1000 ) - flag = 1; - } - } - } - else if ( 0 && time(NULL) > ptr->starttime+13 ) - { - LP_crc32find(&duplicate,-1,ptr->crc32); - if ( duplicate > 0 ) - { - LP_Qfound++; - if ( (LP_Qfound % 100) == 0 ) - printf("found.%u Q.%d err.%d match.%d\n",ptr->crc32,LP_Qenqueued,LP_Qerrors,LP_Qfound); - flag++; - } - else if ( 0 ) // too much beyond duplicate filter when network is busy - { - printf("couldnt find.%u peerind.%d Q.%d err.%d match.%d\n",ptr->crc32,ptr->peerind,LP_Qenqueued,LP_Qerrors,LP_Qfound); - ptr->peerind++; - if ( (ptr->sock= LP_peerindsock(&ptr->peerind)) < 0 ) - { - printf("%d no more peers to try at peerind.%d %p Q_LP.%p\n",n,ptr->peerind,ptr,LP_Q); - flag++; - LP_Qerrors++; - } - } - } - if ( flag != 0 ) - { - nonz++; - portable_mutex_lock(&LP_networkmutex); - DL_DELETE(LP_Q,ptr); - portable_mutex_unlock(&LP_networkmutex); - free(ptr); - ptr = 0; - break; - } - } - if ( arg == 0 ) - break; - if ( nonz == 0 ) - { - if ( IAMLP == 0 ) - usleep(50000); - else usleep(10000); - } - } -} - void _LP_queuesend(uint32_t crc32,int32_t sock0,int32_t sock1,uint8_t *msg,int32_t msglen,int32_t needack) { int32_t maxind,peerind = 0; //sentbytes, From adb0f0ddf0100ce7326ca63b028ecb49f4c713a4 Mon Sep 17 00:00:00 2001 From: jl777 Date: Tue, 21 Nov 2017 11:58:14 +0400 Subject: [PATCH 1030/1664] Test --- iguana/exchanges/LP_bitcoin.c | 14 ++++++++++++++ iguana/exchanges/LP_coins.c | 14 -------------- 2 files changed, 14 insertions(+), 14 deletions(-) diff --git a/iguana/exchanges/LP_bitcoin.c b/iguana/exchanges/LP_bitcoin.c index 15080f4e8..0d1b0a5af 100644 --- a/iguana/exchanges/LP_bitcoin.c +++ b/iguana/exchanges/LP_bitcoin.c @@ -3355,6 +3355,20 @@ int32_t iguana_rwjoinsplit(int32_t rwflag,uint8_t *serialized,struct iguana_msgj return(len); } +uint32_t LP_sighash(char *symbol,int32_t zcash) +{ + uint32_t sighash; + sighash = SIGHASH_ALL; + if ( zcash == LP_IS_BITCOINCASH ) + sighash |= SIGHASH_FORKID; + else if ( zcash == LP_IS_BITCOINGOLD ) + { + sighash |= SIGHASH_FORKID; + sighash |= (LP_IS_BITCOINGOLD << 8); + } + return(sighash); +} + int32_t iguana_rwmsgtx(char *symbol,uint8_t taddr,uint8_t pubtype,uint8_t p2shtype,uint8_t isPoS,int32_t height,int32_t rwflag,cJSON *json,uint8_t *serialized,int32_t maxsize,struct iguana_msgtx *msg,bits256 *txidp,char *vpnstr,uint8_t *extraspace,int32_t extralen,cJSON *vins,int32_t suppress_pubkeys,int32_t zcash) { int32_t i,j,n,segtxlen,len = 0,extraused=0; uint32_t tmp,segitems; uint8_t *segtx=0,segwitflag=0,spendscript[IGUANA_MAXSCRIPTSIZE],*txstart = serialized,*sigser=0; char txidstr[65]; cJSON *vinarray=0,*voutarray=0; bits256 sigtxid; diff --git a/iguana/exchanges/LP_coins.c b/iguana/exchanges/LP_coins.c index cfc83e95f..0bf61e969 100644 --- a/iguana/exchanges/LP_coins.c +++ b/iguana/exchanges/LP_coins.c @@ -286,20 +286,6 @@ cJSON *LP_coinsjson(int32_t showwif) return(array); } -uint32_t LP_sighash(char *symbol,int32_t zcash) -{ - uint32_t sighash; - sighash = SIGHASH_ALL; - if ( zcash == LP_IS_BITCOINCASH ) - sighash |= SIGHASH_FORKID; - else if ( zcash == LP_IS_BITCOINGOLD ) - { - sighash |= SIGHASH_FORKID; - sighash |= (LP_IS_BITCOINGOLD << 8); - } - return(sighash); -} - char *LP_getcoin(char *symbol) { int32_t numenabled,numdisabled; struct iguana_info *coin,*tmp; cJSON *item=0,*retjson; From 5e62e55f2ba0382506779bfb292099fc51126b75 Mon Sep 17 00:00:00 2001 From: jl777 Date: Tue, 21 Nov 2017 21:45:15 +0400 Subject: [PATCH 1031/1664] Test --- iguana/exchanges/LP_RTmetrics.c | 32 ++-- iguana/exchanges/LP_bitcoin.c | 6 +- iguana/exchanges/LP_commands.c | 41 ++++- iguana/exchanges/LP_include.h | 16 +- iguana/exchanges/LP_nativeDEX.c | 26 +++- iguana/exchanges/LP_ordermatch.c | 5 +- iguana/exchanges/LP_prices.c | 10 ++ iguana/exchanges/LP_remember.c | 8 +- iguana/exchanges/LP_signatures.c | 20 +-- iguana/exchanges/LP_swap.c | 14 +- iguana/exchanges/LP_transaction.c | 2 +- iguana/exchanges/LP_utxo.c | 15 +- iguana/exchanges/LP_utxos.c | 35 +++-- iguana/exchanges/LP_zeroconf.c | 240 ++++++++++++++++++++++++++++++ iguana/exchanges/claim | 3 + iguana/exchanges/deposit | 3 + iguana/exchanges/install | 2 +- 17 files changed, 403 insertions(+), 75 deletions(-) create mode 100644 iguana/exchanges/LP_zeroconf.c create mode 100755 iguana/exchanges/claim create mode 100755 iguana/exchanges/deposit diff --git a/iguana/exchanges/LP_RTmetrics.c b/iguana/exchanges/LP_RTmetrics.c index 53466e5e7..a3485c9f9 100644 --- a/iguana/exchanges/LP_RTmetrics.c +++ b/iguana/exchanges/LP_RTmetrics.c @@ -27,11 +27,13 @@ struct LP_metricinfo int32_t ind,numutxos,age,pendingswaps; }; +#define LP_NUMRT 1024 struct LP_RTmetrics_pendings { - char refbase[65],refrel[65]; - int32_t numswaps,numavoidtxids,numwhitelist,numblacklist,numpendings,pending_swaps[1024]; - bits256 avoidtxids[8192],whitelist[1024],blacklist[1024],pending_pubkeys[1024]; + char refbase[128],refrel[128]; + int64_t pending_kmdvalue[LP_NUMRT]; + int32_t numswaps,numavoidtxids,numwhitelist,numblacklist,numpendings,pending_swaps[LP_NUMRT]; + bits256 avoidtxids[8192],whitelist[LP_NUMRT],blacklist[LP_NUMRT],pending_pubkeys[LP_NUMRT]; } LP_RTmetrics; int32_t LP_bits256_find(bits256 *list,int32_t num,bits256 val) @@ -72,11 +74,14 @@ int32_t LP_RTmetrics_blacklistadd(bits256 pubkey) return(LP_bits256_add("LP_RTmetrics_blacklistadd blacklist",LP_RTmetrics.blacklist,&LP_RTmetrics.numblacklist,(int32_t)(sizeof(LP_RTmetrics.blacklist)/sizeof(*LP_RTmetrics.blacklist)),pubkey)); } -int32_t LP_RTmetrics_pendingswap(bits256 pubkey) +int32_t LP_RTmetrics_pendingswap(bits256 pubkey,int64_t kmdvalue) { int32_t ind; if ( (ind= LP_bits256_add("LP_RTmetrics_pendingswap",LP_RTmetrics.pending_pubkeys,&LP_RTmetrics.numpendings,(int32_t)(sizeof(LP_RTmetrics.pending_pubkeys)/sizeof(*LP_RTmetrics.pending_pubkeys)),pubkey)) >= 0 ) + { LP_RTmetrics.pending_swaps[ind]++; + LP_RTmetrics.pending_kmdvalue[ind] += kmdvalue; + } return(ind); } @@ -123,8 +128,8 @@ void LP_RTmetrics_swapsinfo(char *refbase,char *refrel,cJSON *swaps,int32_t nums price = jdouble(item,"price"); requestid = juint(item,"requestid"); quoteid = juint(item,"quoteid"); - LP_RTmetrics_pendingswap(srcpub); - LP_RTmetrics_pendingswap(destpub); + 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 ( (swapjson= cJSON_Parse(retstr)) != 0 ) @@ -144,7 +149,7 @@ void LP_RTmetrics_swapsinfo(char *refbase,char *refrel,cJSON *swaps,int32_t nums void LP_RTmetrics_update(char *base,char *rel) { - struct LP_pubkeyinfo *pubp,*tmp; uint32_t futuretime; int32_t i,numswaps; bits256 zero; char *retstr; cJSON *statsjson,*swaps; + struct LP_pubkeyinfo *pubp,*tmp; uint32_t futuretime; int32_t i,numswaps; bits256 pubkey,zero; char *retstr; cJSON *statsjson,*swaps; memset(&LP_RTmetrics,0,sizeof(LP_RTmetrics)); HASH_ITER(hh,LP_pubkeyinfos,pubp,tmp) { @@ -152,6 +157,7 @@ void LP_RTmetrics_update(char *base,char *rel) LP_RTmetrics_whitelistadd(pubp->pubkey); else if ( pubp->istrusted < 0 ) LP_RTmetrics_blacklistadd(pubp->pubkey); + pubp->swaps_kmdvalue = 0; } futuretime = (uint32_t)time(NULL) + 3600*100; memset(zero.bytes,0,sizeof(zero)); @@ -170,11 +176,19 @@ void LP_RTmetrics_update(char *base,char *rel) free(retstr); } for (i=0; i LP_MAXPENDING_SWAPS ) { - char str[65]; printf("%s has %d pending swaps! which is more than %d\n",bits256_str(str,LP_RTmetrics.pending_pubkeys[i]),LP_RTmetrics.pending_swaps[i],LP_MAXPENDING_SWAPS); - LP_RTmetrics_blacklistadd(LP_RTmetrics.pending_pubkeys[i]); + char str[65]; printf("%s has %d pending swaps! which is more than %d\n",bits256_str(str,pubkey),LP_RTmetrics.pending_swaps[i],LP_MAXPENDING_SWAPS); + LP_RTmetrics_blacklistadd(pubkey); } + else if ( (pubp= LP_pubkeyfind(pubkey)) != 0 ) + { + char str[65]; printf("%s has %d pending swaps %.8f kmdvalue\n",bits256_str(str,pubkey),LP_RTmetrics.pending_swaps[i],dstr(LP_RTmetrics.pending_kmdvalue[i])); + pubp->swaps_kmdvalue = LP_RTmetrics.pending_kmdvalue[i]; + } + } //printf("%d pubkeys have pending swaps, whitelist.%d blacklist.%d avoidtxids.%d\n",LP_RTmetrics.numpendings,LP_RTmetrics.numwhitelist,LP_RTmetrics.numblacklist,LP_RTmetrics.numavoidtxids); } diff --git a/iguana/exchanges/LP_bitcoin.c b/iguana/exchanges/LP_bitcoin.c index 0d1b0a5af..7103b7c57 100644 --- a/iguana/exchanges/LP_bitcoin.c +++ b/iguana/exchanges/LP_bitcoin.c @@ -1959,13 +1959,13 @@ int32_t bitcoin_timelockspend(uint8_t *script,int32_t n,uint8_t rmd160[20],uint3 return(n); } -int32_t bitcoin_performancebond(uint8_t p2sh_rmd160[20],uint8_t *script,int32_t n,uint32_t unlocktimestamp,uint8_t cltv_rmd160[20],uint8_t anytime_rmd160[20]) +int32_t bitcoin_performancebond(uint8_t p2sh_rmd160[20],uint8_t *script,int32_t n,uint32_t unlocktimestamp,uint8_t *cltvpub33,uint8_t *elsepub33) { script[n++] = SCRIPT_OP_IF; n = bitcoin_checklocktimeverify(script,n,unlocktimestamp); - n = bitcoin_standardspend(script,n,cltv_rmd160); + n = bitcoin_pubkeyspend(script,n,cltvpub33); script[n++] = SCRIPT_OP_ELSE; - n = bitcoin_standardspend(script,n,anytime_rmd160); + n = bitcoin_pubkeyspend(script,n,elsepub33); script[n++] = SCRIPT_OP_ENDIF; calc_rmd160_sha256(p2sh_rmd160,script,n); return(n); diff --git a/iguana/exchanges/LP_commands.c b/iguana/exchanges/LP_commands.c index d2f72406d..68f54c48d 100644 --- a/iguana/exchanges/LP_commands.c +++ b/iguana/exchanges/LP_commands.c @@ -95,7 +95,7 @@ char *stats_JSON(void *ctx,char *myipaddr,int32_t pubsock,cJSON *argjson,char *r return(clonestr("{\"result\":\" \ available localhost RPC commands: \n \ pricearray(base, rel, starttime=0, endtime=-1, timescale=60) -> [timestamp, avebid, aveask, highbid, lowask]\n\ -setprice(base, rel, price)\n\ +setprice(base, rel, price, broadcast=1)\n\ autoprice(base, rel, fixed, minprice, margin, refbase, refrel, factor, offset)*\n\ goal(coin=*, val=)\n\ myprice(base, rel)\n\ @@ -146,7 +146,8 @@ bot_settings(botid, newprice, newvolume)\n\ bot_status(botid)\n\ bot_stop(botid)\n\ bot_pause(botid)\n\ -bot_resume(botid)\n\ +deposit_create(weeks, amount, broadcast=0)\n\ +deposit_claim(address, expiration=0)\n\ \"}")); //sell(base, rel, price, basevolume, timeout=10, duration=3600)\n\ @@ -183,6 +184,26 @@ bot_resume(botid)\n\ return(jprint(retjson,1)); } } + else if ( strcmp(method,"deposit_create") == 0 ) + { + if ( (ptr= LP_coinsearch("KMD")) != 0 ) + { + if ( jint(argjson,"weeks") < 0 || jdouble(argjson,"amount") < 10. ) + return(clonestr("{\"error\":\"deposit_create needs to have weeks and amount\"}")); + else return(LP_deposit_create(ptr,juint(argjson,"weeks"),jdouble(argjson,"amount"),jint(argjson,"broadcast"))); + } + return(clonestr("{\"error\":\"cant find KMD\"}")); + } + else if ( strcmp(method,"deposit_claim") == 0 ) + { + if ( (ptr= LP_coinsearch("KMD")) != 0 ) + { + if ( jstr(argjson,"address") == 0 ) + return(clonestr("{\"error\":\"deposit_claim needs to have address\"}")); + else return(LP_deposit_claim(ptr,jstr(argjson,"address"),juint(argjson,"expiration"))); + } + return(clonestr("{\"error\":\"cant find KMD\"}")); + } /*else if ( strcmp(method,"sendmessage") == 0 ) { if ( jobj(argjson,"method2") == 0 ) @@ -289,7 +310,9 @@ bot_resume(botid)\n\ return(clonestr("{\"error\":\"couldnt set price\"}")); //else if ( LP_mypriceset(&changed,rel,base,1./price) < 0 ) // return(clonestr("{\"error\":\"couldnt set price\"}")); - else return(LP_pricepings(ctx,myipaddr,LP_mypubsock,base,rel,price * LP_profitratio)); + else if ( jint(argjson,"broadcast") != 0 || jobj(argjson,"broadcast") == 0 ) + return(LP_pricepings(ctx,myipaddr,LP_mypubsock,base,rel,price * LP_profitratio)); + else return(clonestr("{\"result\":\"success\"}")); } else if ( strcmp(method,"pricearray") == 0 ) { @@ -361,13 +384,19 @@ bot_resume(botid)\n\ { ptr->inactive = 0; cJSON *array; - if ( ptr->smartaddr[0] != 0 ) - LP_unspents_load(coin,ptr->smartaddr); if ( LP_getheight(ptr) <= 0 ) { ptr->inactive = (uint32_t)time(NULL); return(clonestr("{\"error\":\"coin cant be activated till synced\"}")); - } else LP_unspents_load(coin,ptr->smartaddr); + } + else + { + if ( ptr->smartaddr[0] != 0 ) + LP_unspents_load(coin,ptr->smartaddr); + LP_unspents_load(coin,ptr->smartaddr); + if ( strcmp(ptr->symbol,"KMD") == 0 ) + LP_importaddress("KMD",BOTS_BONDADDRESS); + } array = cJSON_CreateArray(); jaddi(array,LP_coinjson(ptr,0)); return(jprint(array,1)); diff --git a/iguana/exchanges/LP_include.h b/iguana/exchanges/LP_include.h index adc089b75..c0453e460 100644 --- a/iguana/exchanges/LP_include.h +++ b/iguana/exchanges/LP_include.h @@ -23,7 +23,7 @@ #define LP_MAJOR_VERSION "0" #define LP_MINOR_VERSION "1" -#define LP_BUILD_NUMBER "15256" +#define LP_BUILD_NUMBER "15324" #define LP_BARTERDEX_VERSION 1 #define LP_MAGICBITS 8 @@ -82,7 +82,7 @@ void emscripten_usleep(int32_t x); // returns immediate, no sense for sleeping #define LP_SWAPSTEP_TIMEOUT 30 #define LP_MIN_TXFEE 10000 #define LP_MINVOL 20 -#define LP_MINCLIENTVOL 100 +#define LP_MINCLIENTVOL 20 #define LP_MINSIZE_TXFEEMULT 10 #define LP_REQUIRED_TXFEE 0.8 @@ -98,6 +98,10 @@ void emscripten_usleep(int32_t x); // returns immediate, no sense for sleeping #define TIERNOLAN_RMD160 "daedddd8dbe7a2439841ced40ba9c3d375f98146" #define INSTANTDEX_BTC "1KRhTPvoxyJmVALwHFXZdeeWFbcJSbkFPu" #define INSTANTDEX_KMD "RThtXup6Zo7LZAi8kRWgjAyi1s4u6U9Cpf" +#define BOTS_BONDADDRESS "RNdqHx26GWy9bk8MtmH1UiXjQcXE4RKK2P" +#define BOTS_BONDPUBKEY33 "03e641d22e1ff5a7d45c8880537e0b0a114d7b9fee2c18a6b4a8a80b6285292990" +#define LP_WEEKMULT (7 * 24 * 2600) +#define LP_FIRSTWEEKTIME 1510790400 // must be 0 mod LP_WEEKMULT //#define BASILISK_DISABLEWAITTX //#define BASILISK_DISABLESENDTX @@ -379,8 +383,7 @@ struct LP_pubkeyinfo UT_hash_handle hh; bits256 pubkey; struct LP_pubkey_quote *quotes; - //float matrix[LP_MAXPRICEINFOS][LP_MAXPRICEINFOS]; - //uint32_t timestamps[LP_MAXPRICEINFOS][LP_MAXPRICEINFOS]; + uint64_t bondvalue,swaps_kmdvalue; uint32_t timestamp,numerrors,lasttime; int32_t istrusted; uint8_t rmd160[20],sig[65],pubsecp[33],siglen; @@ -408,7 +411,7 @@ void LP_swap_coinaddr(struct iguana_info *coin,char *coinaddr,uint64_t *valuep,u void basilisk_dontforget_update(struct basilisk_swap *swap,struct basilisk_rawtx *rawtx); uint32_t basilisk_requestid(struct basilisk_request *rp); uint32_t basilisk_quoteid(struct basilisk_request *rp); -struct basilisk_swap *LP_swapinit(int32_t iambob,int32_t optionduration,bits256 privkey,struct basilisk_request *rp,struct LP_quoteinfo *qp); +struct basilisk_swap *LP_swapinit(int32_t iambob,int32_t optionduration,bits256 privkey,struct basilisk_request *rp,struct LP_quoteinfo *qp,int32_t dynamictrust); char *bitcoind_passthru(char *coinstr,char *serverport,char *userpass,char *method,char *params); uint32_t LP_swapdata_rawtxsend(int32_t pairsock,struct basilisk_swap *swap,uint32_t msgbits,uint8_t *data,int32_t maxlen,struct basilisk_rawtx *rawtx,uint32_t nextbits,int32_t suppress_swapsend); //double LP_query(char *method,struct LP_quoteinfo *qp,char *base,char *rel,bits256 mypub); @@ -421,10 +424,12 @@ 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); +int64_t LP_kmdvalue(char *symbol,int64_t satoshis); int64_t LP_komodo_interest(bits256 txid,int64_t value); void LP_availableset(bits256 txid,int32_t vout); 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); int32_t LP_pullsock_check(void *ctx,char **retstrp,char *myipaddr,int32_t pubsock,int32_t pullsock); +int64_t LP_listunspent_parseitem(struct iguana_info *coin,bits256 *txidp,int32_t *voutp,int32_t *heightp,cJSON *item); void LP_unspents_cache(char *symbol,char *addr,char *arraystr,int32_t updatedflag); uint16_t LP_psock_get(char *connectaddr,char *publicaddr,int32_t ispaired); //void LP_utxo_clientpublish(struct LP_utxoinfo *utxo); @@ -472,6 +477,7 @@ 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 fullflag); uint16_t LP_randpeer(char *destip); +struct LP_pubkeyinfo *LP_pubkeyfind(bits256 pubkey); char *issue_LP_psock(char *destip,uint16_t destport,int32_t ispaired); char *LP_unspents_filestr(char *symbol,char *addr); cJSON *bitcoin_data2json(char *symbol,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 zcash); diff --git a/iguana/exchanges/LP_nativeDEX.c b/iguana/exchanges/LP_nativeDEX.c index 66b0d49d0..7b81caa37 100644 --- a/iguana/exchanges/LP_nativeDEX.c +++ b/iguana/exchanges/LP_nativeDEX.c @@ -17,14 +17,19 @@ // LP_nativeDEX.c // marketmaker // +// feature requests // alice waiting for bestprice +// USD paxprice based USDvalue in portfolio +// portfolio value based on ask? +// cancel bid/ask +// https://github.com/bitcoin/bips/blob/master/bip-0143.mediawiki for signing BCH/BTG +// +// bugs, validations: // MNZ getcoin strangeness +// verify encrypted destpubkey, broadcast:0 setprice // [{"date":1405699200,"high":0.0045388,"low":0.00403001,"open":0.00404545,"close":0.00435873,"relvol":44.34555992,"basevol":10311.88079097,"aveprice":0.00430043}, // minute, -// https://github.com/bitcoin/bips/blob/master/bip-0143.mediawiki for signing BCH/BTG // improve critical section detection when parallel trades -// reduce mem: dont redundant store pubkey utxo info - // previously, it used to show amount, kmd equiv, perc // dPoW security -> 4: KMD notarized, 5: BTC notarized, after next notary elections // bigendian architectures need to use little endian for sighash calcs @@ -176,6 +181,7 @@ char *blocktrail_listtransactions(char *symbol,char *coinaddr,int32_t num,int32_ #include "LP_transaction.c" #include "LP_stats.c" #include "LP_remember.c" +#include "LP_zeroconf.c" #include "LP_swap.c" #include "LP_peers.c" #include "LP_utxos.c" @@ -642,7 +648,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; + static uint32_t counter,didzeroconf; struct iguana_info *coin,*ctmp; char *origipaddr; uint32_t now; int32_t height,nonz = 0; if ( (origipaddr= myipaddr) == 0 ) origipaddr = "127.0.0.1"; @@ -651,6 +657,11 @@ int32_t LP_mainloop_iter(void *ctx,char *myipaddr,struct LP_peerinfo *mypeer,int HASH_ITER(hh,LP_coins,coin,ctmp) // firstrefht,firstscanht,lastscanht { now = (uint32_t)time(NULL); + if ( didzeroconf == 0 && strcmp("KMD",coin->symbol) == 0 ) + { + LP_zeroconf_deposits(coin); + didzeroconf = now; + } 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); @@ -689,7 +700,12 @@ void LP_initcoins(void *ctx,int32_t pubsock,cJSON *coins) { if ( LP_getheight(coin) <= 0 ) coin->inactive = (uint32_t)time(NULL); - else LP_unspents_load(coin->symbol,coin->smartaddr); + else + { + LP_unspents_load(coin->symbol,coin->smartaddr); + if ( strcmp(coin->symbol,"KMD") == 0 ) + LP_importaddress("KMD",BOTS_BONDADDRESS); + } if ( coin->txfee == 0 && strcmp(coin->symbol,"BTC") != 0 ) coin->txfee = LP_MIN_TXFEE; } diff --git a/iguana/exchanges/LP_ordermatch.c b/iguana/exchanges/LP_ordermatch.c index a8922f36a..5bd75a9e2 100644 --- a/iguana/exchanges/LP_ordermatch.c +++ b/iguana/exchanges/LP_ordermatch.c @@ -454,7 +454,7 @@ int32_t LP_connectstartbob(void *ctx,int32_t pubsock,cJSON *argjson,char *base,c printf("requestid.%u quoteid.%u is already in progres\n",qp->R.requestid,qp->R.quoteid); return(-1); } - if ( (swap= LP_swapinit(1,0,privkey,&qp->R,qp)) == 0 ) + if ( (swap= LP_swapinit(1,0,privkey,&qp->R,qp,LP_dynamictrust(qp->desthash,LP_kmdvalue(qp->destcoin,qp->destsatoshis)))) == 0 ) { printf("cant initialize swap\n"); return(-1); @@ -614,6 +614,7 @@ char *LP_connectedalice(cJSON *argjson) // alice LP_aliceid(Q.tradeid,Q.aliceid,"error5",0,0); return(clonestr("{\"error\":\"no price set\"}")); } + LP_RTmetrics_update(Q.srccoin,Q.destcoin); printf("%s/%s bid %.8f ask %.8f values %.8f %.8f\n",Q.srccoin,Q.destcoin,bid,ask,dstr(butxo->payment.value),dstr(butxo->deposit.value)); price = bid; if ( (coin= LP_coinfind(Q.destcoin)) == 0 ) @@ -625,7 +626,7 @@ char *LP_connectedalice(cJSON *argjson) // alice if ( bits256_nonz(Q.privkey) != 0 )//&& Q.quotetime >= Q.timestamp-3 ) { retjson = cJSON_CreateObject(); - if ( (swap= LP_swapinit(0,0,Q.privkey,&Q.R,&Q)) == 0 ) + if ( (swap= LP_swapinit(0,0,Q.privkey,&Q.R,&Q,LP_dynamictrust(Q.srchash,LP_kmdvalue(Q.srccoin,Q.satoshis)))) == 0 ) { jaddstr(retjson,"error","couldnt swapinit"); LP_availableset(Q.desttxid,Q.vout); diff --git a/iguana/exchanges/LP_prices.c b/iguana/exchanges/LP_prices.c index 7c91647aa..e1d27492c 100644 --- a/iguana/exchanges/LP_prices.c +++ b/iguana/exchanges/LP_prices.c @@ -977,6 +977,16 @@ uint64_t LP_KMDvalue(struct iguana_info *coin,uint64_t balance) return(KMDvalue); } +int64_t LP_kmdvalue(char *symbol,int64_t satoshis) +{ + struct iguana_info *coin; int64_t kmdvalue = 0; + if ( (coin= LP_coinfind(symbol)) != 0 ) + kmdvalue = LP_KMDvalue(coin,satoshis); + if ( kmdvalue == 0 ) + kmdvalue = satoshis; + return(kmdvalue); +} + void LP_priceupdate(char *base,char *rel,double price,double avebid,double aveask,double highbid,double lowask,double PAXPRICES[32]) { LP_priceinfoupdate(base,rel,price); diff --git a/iguana/exchanges/LP_remember.c b/iguana/exchanges/LP_remember.c index f5ea3229a..3122dfab4 100644 --- a/iguana/exchanges/LP_remember.c +++ b/iguana/exchanges/LP_remember.c @@ -389,6 +389,7 @@ uint32_t LP_extract(uint32_t requestid,uint32_t quoteid,char *rootfname,char *fi t = (t << 8) | redeem[2]; //printf("extracted timestamp.%u\n",t); } + free_json(json); } free(filestr); } @@ -637,6 +638,7 @@ int32_t LP_rswap_init(struct LP_swap_remember *rswap,uint32_t requestid,uint32_t } } } + free_json(txobj); } rswap->origfinishedflag = basilisk_swap_isfinished(rswap->iambob,rswap->txids,rswap->sentflags,rswap->paymentspent,rswap->Apaymentspent,rswap->depositspent); rswap->finishedflag = rswap->origfinishedflag; @@ -773,6 +775,7 @@ int32_t LP_swap_load(struct LP_swap_remember *rswap) //printf("%s %s %.8f\n",txnames[i],bits256_str(str,txid),dstr(value)); } } + free_json(txobj); } //else printf("no symbol\n"); free(fstr); } else if ( 0 && rswap->finishedflag == 0 ) @@ -1150,7 +1153,10 @@ cJSON *basilisk_remember(int64_t *KMDtotals,int64_t *BTCtotals,uint32_t requesti fclose(fp); } } - return(item); + for (i=0; ielectrum == 0 )//&& relcoin->electrum == 0 ) + if ( (basecoin= LP_coinfind(base)) != 0 && (relcoin= LP_coinfind(rel)) != 0 )//&& basecoin->electrum == 0 )//&& relcoin->electrum == 0 ) { memset(zero.bytes,0,sizeof(zero)); jaddbits256(reqjson,"pubkey",G.LP_mypub25519); @@ -718,13 +718,15 @@ void LP_query(void *ctx,char *myipaddr,int32_t mypubsock,char *method,struct LP_ msg = jprint(reqjson,1); msg2 = clonestr(msg); printf("QUERY.(%s)\n",msg); - memset(&zero,0,sizeof(zero)); - portable_mutex_lock(&LP_reservedmutex); - if ( num_Reserved_msgs[1] < sizeof(Reserved_msgs[1])/sizeof(*Reserved_msgs[1])-2 ) - Reserved_msgs[1][num_Reserved_msgs[1]++] = msg; - if ( num_Reserved_msgs[0] < sizeof(Reserved_msgs[0])/sizeof(*Reserved_msgs[0])-2 ) - Reserved_msgs[0][num_Reserved_msgs[0]++] = msg2; - //LP_broadcast_message(LP_mypubsock,qp->srccoin,qp->destcoin,zero,msg2); - portable_mutex_unlock(&LP_reservedmutex); + if ( bits256_nonz(qp->srchash) == 0 || strcmp(method,"request") != 0 ) + { + memset(&zero,0,sizeof(zero)); + portable_mutex_lock(&LP_reservedmutex); + if ( num_Reserved_msgs[1] < sizeof(Reserved_msgs[1])/sizeof(*Reserved_msgs[1])-2 ) + Reserved_msgs[1][num_Reserved_msgs[1]++] = msg; + if ( num_Reserved_msgs[0] < sizeof(Reserved_msgs[0])/sizeof(*Reserved_msgs[0])-2 ) + Reserved_msgs[0][num_Reserved_msgs[0]++] = msg2; + portable_mutex_unlock(&LP_reservedmutex); + } else LP_broadcast_message(LP_mypubsock,qp->srccoin,qp->destcoin,qp->srchash,msg2); } diff --git a/iguana/exchanges/LP_swap.c b/iguana/exchanges/LP_swap.c index 2461bfcf0..ca1731292 100644 --- a/iguana/exchanges/LP_swap.c +++ b/iguana/exchanges/LP_swap.c @@ -1041,7 +1041,7 @@ void basilisk_rawtx_setparms(char *name,uint32_t quoteid,struct basilisk_rawtx * } else printf("%s vouttype.%d destaddr.(%s)\n",name,rawtx->I.vouttype,rawtx->I.destaddr); } -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) +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,int32_t dynamictrust) { //FILE *fp; char fname[512]; uint8_t *alicepub33=0,*bobpub33=0; int32_t jumblrflag=-2,x = -1; struct iguana_info *bobcoin,*alicecoin; @@ -1101,14 +1101,18 @@ struct basilisk_swap *bitcoin_swapinit(bits256 privkey,uint8_t *pubkey33,bits256 swap->I.iambob = 0; swap->I.otherhash = swap->I.req.desthash; swap->I.aliceistrusted = 1; - swap->I.otheristrusted = swap->I.bobistrusted = LP_pubkey_istrusted(swap->I.req.srchash); + if ( dynamictrust == 0 && LP_pubkey_istrusted(swap->I.req.srchash) != 0 ) + dynamictrust = 1; + swap->I.otheristrusted = swap->I.bobistrusted = dynamictrust; } else { swap->I.iambob = 1; swap->I.otherhash = swap->I.req.srchash; swap->I.bobistrusted = 1; - swap->I.otheristrusted = swap->I.aliceistrusted = LP_pubkey_istrusted(swap->I.req.desthash); + if ( dynamictrust == 0 && LP_pubkey_istrusted(swap->I.req.desthash) != 0 ) + dynamictrust = 1; + swap->I.otheristrusted = swap->I.aliceistrusted = dynamictrust; } if ( bits256_nonz(privkey) == 0 || (x= instantdex_pubkeyargs(swap,2 + INSTANTDEX_DECKSIZE,privkey,swap->I.orderhash,0x02+swap->I.iambob)) != 2 + INSTANTDEX_DECKSIZE ) { @@ -1198,7 +1202,7 @@ struct basilisk_swap *bitcoin_swapinit(bits256 privkey,uint8_t *pubkey33,bits256 return(swap); } -struct basilisk_swap *LP_swapinit(int32_t iambob,int32_t optionduration,bits256 privkey,struct basilisk_request *rp,struct LP_quoteinfo *qp) +struct basilisk_swap *LP_swapinit(int32_t iambob,int32_t optionduration,bits256 privkey,struct basilisk_request *rp,struct LP_quoteinfo *qp,int32_t dynamictrust) { struct basilisk_swap *swap; bits256 pubkey25519; uint8_t pubkey33[33]; swap = calloc(1,sizeof(*swap)); @@ -1217,7 +1221,7 @@ struct basilisk_swap *LP_swapinit(int32_t iambob,int32_t optionduration,bits256 swap->persistent_privkey = privkey; memcpy(swap->persistent_pubkey33,pubkey33,33); calc_rmd160_sha256(swap->changermd160,pubkey33,33); - if ( bitcoin_swapinit(privkey,pubkey33,pubkey25519,swap,optionduration,!iambob,qp) == 0 ) + if ( bitcoin_swapinit(privkey,pubkey33,pubkey25519,swap,optionduration,!iambob,qp,dynamictrust) == 0 ) { printf("error doing swapinit\n"); free(swap); diff --git a/iguana/exchanges/LP_transaction.c b/iguana/exchanges/LP_transaction.c index 34bec55b9..02415da85 100644 --- a/iguana/exchanges/LP_transaction.c +++ b/iguana/exchanges/LP_transaction.c @@ -1131,7 +1131,7 @@ int32_t LP_vins_select(void *ctx,struct iguana_info *coin,int64_t *totalp,int64_ interest = 0; if ( up->U.height < 7777777 && strcmp(coin->symbol,"KMD") == 0 ) { - if ( 0 && (interest= LP_komodo_interest(up->U.txid,up->U.value)) > 0 ) + if ( (interest= LP_komodo_interest(up->U.txid,up->U.value)) > 0 ) { interestsum += interest; char str[65]; printf("%s/%d %.8f interest %.8f -> sum %.8f\n",bits256_str(str,up->U.txid),up->U.vout,dstr(up->U.value),dstr(interest),dstr(interestsum)); diff --git a/iguana/exchanges/LP_utxo.c b/iguana/exchanges/LP_utxo.c index 8ea1d2db5..8295db767 100644 --- a/iguana/exchanges/LP_utxo.c +++ b/iguana/exchanges/LP_utxo.c @@ -446,20 +446,7 @@ struct LP_address *LP_address_utxo_reset(struct iguana_info *coin) { //{"tx_hash":"38d1b7c73015e1b1d6cb7fc314cae402a635b7d7ea294970ab857df8777a66f4","tx_pos":0,"height":577975,"value":238700} item = jitem(array,i); - if ( coin->electrum != 0 ) - { - txid = jbits256(item,"tx_hash"); - vout = juint(item,"tx_pos"); - value = j64bits(item,"value"); - height = jint(item,"height"); - } - else - { - txid = jbits256(item,"txid"); - vout = juint(item,"vout"); - value = LP_value_extract(item,0); - height = LP_txheight(coin,txid); - } + value = LP_listunspent_parseitem(coin,&txid,&vout,&height,item); LP_address_utxoadd(now,"withdraw",coin,coin->smartaddr,txid,vout,value,height,-1); if ( (up= LP_address_utxofind(coin,coin->smartaddr,txid,vout)) == 0 ) printf("couldnt find just added %s/%d ht.%d %.8f\n",bits256_str(str,txid),vout,height,dstr(value)); diff --git a/iguana/exchanges/LP_utxos.c b/iguana/exchanges/LP_utxos.c index 90e0aafc8..75af6c872 100644 --- a/iguana/exchanges/LP_utxos.c +++ b/iguana/exchanges/LP_utxos.c @@ -559,6 +559,26 @@ int32_t LP_nearestvalue(int32_t iambob,uint64_t *values,int32_t n,uint64_t targe return(mini); } +int64_t LP_listunspent_parseitem(struct iguana_info *coin,bits256 *txidp,int32_t *voutp,int32_t *heightp,cJSON *item) +{ + int64_t satoshis = 0; + if ( coin->electrum == 0 ) + { + *txidp = jbits256(item,"txid"); + *voutp = juint(item,"vout"); + satoshis = LP_value_extract(item,0); + *heightp = LP_txheight(coin,*txidp); + } + else + { + *txidp = jbits256(item,"tx_hash"); + *voutp = juint(item,"tx_pos"); + satoshis = j64bits(item,"value"); + *heightp = jint(item,"height"); + } + return(satoshis); +} + int32_t LP_privkey_init(int32_t mypubsock,struct iguana_info *coin,bits256 myprivkey,bits256 mypub) { int32_t enable_utxos = 0; @@ -591,20 +611,7 @@ int32_t LP_privkey_init(int32_t mypubsock,struct iguana_info *coin,bits256 mypri for (i=0; ielectrum == 0 ) - { - txid = jbits256(item,"txid"); - vout = juint(item,"vout"); - value = LP_value_extract(item,0); - height = LP_txheight(coin,txid);//LP_getheight(coin) - jint(item,"confirmations") + 1; - } - else - { - txid = jbits256(item,"tx_hash"); - vout = juint(item,"tx_pos"); - value = j64bits(item,"value"); - height = jint(item,"height"); - } + value = LP_listunspent_parseitem(coin,&txid,&vout,&height,item); satoshis = LP_txvalue(destaddr,coin->symbol,txid,vout); if ( satoshis != 0 && satoshis != value ) printf("%s %s privkey_init value %.8f vs %.8f (%s) %.8f %.8f\n",coin->symbol,coin->smartaddr,dstr(satoshis),dstr(value),jprint(item,0),jdouble(item,"amount"),jdouble(item,"interest")); diff --git a/iguana/exchanges/LP_zeroconf.c b/iguana/exchanges/LP_zeroconf.c new file mode 100644 index 000000000..bac4514fc --- /dev/null +++ b/iguana/exchanges/LP_zeroconf.c @@ -0,0 +1,240 @@ + +/****************************************************************************** + * Copyright © 2014-2017 The SuperNET Developers. * + * * + * See the AUTHORS, DEVELOPER-AGREEMENT and LICENSE files at * + * the top-level directory of this distribution for the individual copyright * + * holder information and the developer policies on copyright and licensing. * + * * + * Unless otherwise agreed in a custom licensing agreement, no part of the * + * SuperNET software, including this file may be copied, modified, propagated * + * or distributed except according to the terms contained in the LICENSE file * + * * + * Removal or modification of this copyright notice is prohibited. * + * * + ******************************************************************************/ + +// +// LP_zeroconf.c +// marketmaker +// + +int32_t LP_deposit_addr(char *depositaddr,uint8_t *script,uint32_t timestamp,uint8_t *pubsecp33) +{ + uint8_t elsepub33[33],p2sh_rmd160[20]; int32_t n; + decode_hex(elsepub33,33,BOTS_BONDPUBKEY33); + n = bitcoin_performancebond(p2sh_rmd160,script,0,timestamp,pubsecp33,elsepub33); + return(n); +} + +char *LP_deposit_create(struct iguana_info *coin,int32_t weeks,double amount,int32_t broadcast) +{ + char p2shaddr[64],*retstr,*hexstr; uint8_t script[512]; int32_t weeki,scriptlen; cJSON *argjson,*retjson,*array,*item; uint32_t timestamp; bits256 txid,sendtxid; uint64_t amount64; + if ( strcmp(coin->symbol,"KMD") != 0 ) + return(clonestr("{\"error\":\"zeroconf deposit must be in KMD\"}")); + if ( amount < 10.0 ) + return(clonestr("{\"error\":\"minimum zeroconf deposit is 10 KMD\"}")); + if ( weeks < 0 || weeks > 52 ) + return(clonestr("{\"error\":\"weeks must be between 0 and 52\"}")); + if ( weeks > 0 ) + { + timestamp = (uint32_t)time(NULL); + timestamp /= LP_WEEKMULT; + timestamp += weeks+1; + timestamp *= LP_WEEKMULT; + weeki = (timestamp - LP_FIRSTWEEKTIME) / LP_WEEKMULT; + if ( weeks >= 10000 ) + return(clonestr("{\"error\":\"numweeks must be less than 10000\"}")); + } else timestamp = (uint32_t)time(NULL) + 300, weeki = 0; + scriptlen = LP_deposit_addr(p2shaddr,script,timestamp,G.LP_pubsecp); + argjson = cJSON_CreateObject(); + array = cJSON_CreateArray(); + item = cJSON_CreateObject(); + jaddnum(item,p2shaddr,amount); + jaddi(array,item); + item = cJSON_CreateObject(); + amount64 = (amount * SATOSHIDEN) / 1000; + amount64 = (amount64 / 10000) * 10000 + weeki; + jaddnum(item,BOTS_BONDADDRESS,dstr(amount64)); + jaddi(array,item); + jadd(argjson,"outputs",array); + if ( (retstr= LP_withdraw(coin,argjson)) != 0 ) + { + if ( (retjson= cJSON_Parse(retstr)) != 0 ) + { + if ( jobj(retjson,"result") != 0 ) + jdelete(retjson,"result"); + jaddstr(retjson,"address",p2shaddr); + jaddnum(retjson,"expiration",timestamp); + if ( jint(retjson,"complete") > 0 && (hexstr= jstr(retjson,"hex")) != 0 ) + { + txid = jbits256(retjson,"txid"); + if ( broadcast != 0 ) + { + if (bits256_nonz(txid) != 0 ) + { + sendtxid = LP_broadcast("deposit","KMD",hexstr,txid); + if ( bits256_cmp(sendtxid,txid) != 0 ) + { + jaddstr(retjson,"error","broadcast txid mismatch"); + jaddbits256(retjson,"broadcast",sendtxid); + free(retstr); + return(jprint(retjson,1)); + } + else + { + jaddstr(retjson,"result","success"); + jaddbits256(retjson,"broadcast",sendtxid); + free(retstr); + return(jprint(retjson,1)); + } + } + else + { + jaddstr(retjson,"error","couldnt broadcast since no txid created"); + free(retstr); + return(jprint(retjson,1)); + } + } + else + { + jaddstr(retjson,"result","success"); + free(retstr); + return(jprint(retjson,1)); + } + } + else + { + jaddstr(retjson,"error","couldnt create deposit txid"); + free(retstr); + return(jprint(retjson,1)); + } + free_json(retjson); + } + free(retstr); + } + return(clonestr("{\"error\":\"error with LP_withdraw for zeroconf deposit\"}")); +} + +char *LP_deposit_claim(struct iguana_info *coin,char *depositaddr,uint32_t expiration) +{ + static void *ctx; + uint8_t redeemscript[512],userdata[64]; char vinaddr[64],str[65],*signedtx=0; uint32_t timestamp,now,redeemlen; int32_t i,n,height,utxovout,userdatalen; bits256 signedtxid,utxotxid,sendtxid; int64_t sum,destamount,satoshis; cJSON *array,*item,*txids,*retjson; + if ( ctx == 0 ) + ctx = bitcoin_ctx(); + if ( strcmp(coin->symbol,"KMD") != 0 ) + return(clonestr("{\"error\":\"zeroconf deposit must be in KMD\"}")); + now = (uint32_t)time(NULL); + sum = 0; + txids = cJSON_CreateArray(); + timestamp = (now / LP_WEEKMULT) * LP_WEEKMULT + LP_WEEKMULT; + while ( timestamp > LP_FIRSTWEEKTIME ) + { + if ( expiration != 0 ) + timestamp = expiration; + else timestamp -= LP_WEEKMULT; + redeemlen = LP_deposit_addr(vinaddr,redeemscript,timestamp,G.LP_pubsecp); + if ( strcmp(depositaddr,vinaddr) == 0 ) + { + printf("found %s at timestamp.%u\n",vinaddr,timestamp); + if ( (array= LP_listunspent(coin->symbol,vinaddr)) != 0 ) + { + userdata[0] = 0x51; + userdatalen = 1; + utxovout = 0; + if ( (n= cJSON_GetArraySize(array)) > 0 ) + { + for (i=0; isymbol,coin->wiftaddr,coin->taddr,coin->pubtype,coin->p2shtype,coin->isPoS,coin->wiftype,ctx,G.LP_privkey,0,redeemscript,redeemlen,userdata,userdatalen,utxotxid,utxovout,coin->smartaddr,G.LP_pubsecp,0xffffffff,0,&destamount,satoshis-coin->txfee,coin->smartaddr,vinaddr,0,coin->zcash)) != 0 ) + { + sendtxid = LP_broadcast("claim","KMD",signedtx,signedtxid); + if ( bits256_cmp(sendtxid,signedtxid) == 0 ) + { + jaddibits256(txids,sendtxid); + sum += (satoshis-coin->txfee); + } + else printf("error sending %s\n",bits256_str(str,signedtxid)); + free(signedtx); + } else printf("error claiming zeroconf deposit %s/v%d %.8f\n",bits256_str(str,utxotxid),utxovout,dstr(satoshis)); + } + } + free_json(array); + retjson = cJSON_CreateObject(); + jaddstr(retjson,"result","success"); + jaddnum(retjson,"claimed",dstr(sum)); + jadd(retjson,"txids",txids); + return(jprint(retjson,1)); + } + } + if ( expiration != 0 ) + break; + } + return(clonestr("{\"error\":\"no zeroconf deposits to claim\"}")); +} + +void LP_zeroconf_deposits(struct iguana_info *coin) +{ + cJSON *array,*item,*txjson,*vouts,*v,*sobj; uint32_t timestamp; int32_t i,n,redeemlen,len,numvouts,height,vout,weeki; bits256 txid; char *scriptstr,coinaddr[64],p2shaddr[64]; int64_t satoshis,amount64; uint8_t redeemscript[512],spendscript[512],*pub33; + if ( (array= LP_listunspent("KMD",BOTS_BONDADDRESS)) != 0 ) + { + if ( (n= cJSON_GetArraySize(array)) > 0 ) + { + for (i=0; i 0 && (txjson= LP_gettx(coin->symbol,txid)) != 0 ) + { + if ( (vouts= jarray(&numvouts,txjson,"vout")) > 0 ) + { + v = jitem(vouts,0); + satoshis = LP_value_extract(v,0); + if ( (sobj= jobj(v,"scriptPubKey")) != 0 ) + { + if ( (scriptstr= jstr(sobj,"hex")) != 0 ) + { + len = (int32_t)strlen(scriptstr) >> 1; + if ( len <= sizeof(spendscript)/sizeof(*spendscript) ) + { + decode_hex(spendscript,len,scriptstr); + if ( spendscript[11] == 33 ) + { + pub33 = &spendscript[12]; + redeemlen = LP_deposit_addr(p2shaddr,redeemscript,timestamp,pub33); + if ( len == redeemlen && (timestamp % LP_WEEKMULT) == 0 ) + { + bitcoin_address(coinaddr,coin->taddr,coin->pubtype,pub33,33); + printf("%s -> matched %s script t.%u weeki.%d deposit %.8f\n",coinaddr,p2shaddr,timestamp,(timestamp-LP_FIRSTWEEKTIME)/LP_WEEKMULT,dstr(satoshis)); + // add to pubp->credits; + } + } + } + } + } + } + } + } + } + } + free_json(array); + } +} + +int32_t LP_dynamictrust(bits256 pubkey,int64_t kmdvalue) +{ + struct LP_pubkeyinfo *pubp; + if ( (pubp= LP_pubkeyfind(pubkey)) != 0 ) + { + if ( pubp->bondvalue > pubp->swaps_kmdvalue+kmdvalue ) + return(1); + } + return(0); +} + diff --git a/iguana/exchanges/claim b/iguana/exchanges/claim new file mode 100755 index 000000000..20ec10c44 --- /dev/null +++ b/iguana/exchanges/claim @@ -0,0 +1,3 @@ +#!/bin/bash +source userpass +curl --url "http://127.0.0.1:7783" --data "{\"userpass\":\"$userpass\",\"method\":\"zeroconf_claim\",\"address\":\"$1\",\"expiration\":$2}" diff --git a/iguana/exchanges/deposit b/iguana/exchanges/deposit new file mode 100755 index 000000000..dae61c47a --- /dev/null +++ b/iguana/exchanges/deposit @@ -0,0 +1,3 @@ +#!/bin/bash +source userpass +curl --url "http://127.0.0.1:7783" --data "{\"userpass\":\"$userpass\",\"method\":\"zeroconf_deposit\",\"numweeks\":0,\"amount\":10.0,\"broadcast\":1}" diff --git a/iguana/exchanges/install b/iguana/exchanges/install index efb2c7a2e..a6c29cfea 100755 --- a/iguana/exchanges/install +++ b/iguana/exchanges/install @@ -1,5 +1,5 @@ #!/bin/bash -cp invreset sendrawtransaction processfiles stop millis mnzservers bot_buy bot_list bot_statuslist bot_pause bot_resume bot_sell bot_settings bot_status bot_stop guistats pubkeystats pendings coinswaps baserelswaps setpassphrase notarizations getrawtransaction parselog statsdisp m_js 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 claim deposit invreset sendrawtransaction processfiles stop millis mnzservers bot_buy bot_list bot_statuslist bot_pause bot_resume bot_sell bot_settings bot_status bot_stop guistats pubkeystats pendings coinswaps baserelswaps setpassphrase notarizations getrawtransaction parselog statsdisp m_js 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 . From 47d4f663d6fa9a6bd612d054e798b16cafa2b338 Mon Sep 17 00:00:00 2001 From: jl777 Date: Tue, 21 Nov 2017 21:48:36 +0400 Subject: [PATCH 1032/1664] Test --- iguana/exchanges/LP_remember.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/iguana/exchanges/LP_remember.c b/iguana/exchanges/LP_remember.c index 3122dfab4..de0c029fe 100644 --- a/iguana/exchanges/LP_remember.c +++ b/iguana/exchanges/LP_remember.c @@ -484,7 +484,7 @@ cJSON *LP_swap_json(struct LP_swap_remember *rswap) if ( rswap->sentflags[i] != 0 ) jaddistr(array,txnames[i]); if ( rswap->txbytes[i] != 0 ) - free(rswap->txbytes[i]); + free(rswap->txbytes[i]), rswap->txbytes[i] = 0; } jadd(item,"sentflags",array); array = cJSON_CreateArray(); From 6bfa0d0b6462cbd81afaca467762904a97be9e56 Mon Sep 17 00:00:00 2001 From: jl777 Date: Tue, 21 Nov 2017 22:17:36 +0400 Subject: [PATCH 1033/1664] test --- iguana/exchanges/LP_commands.c | 3 +++ iguana/exchanges/LP_remember.c | 7 ------- 2 files changed, 3 insertions(+), 7 deletions(-) diff --git a/iguana/exchanges/LP_commands.c b/iguana/exchanges/LP_commands.c index 68f54c48d..f6f3d1970 100644 --- a/iguana/exchanges/LP_commands.c +++ b/iguana/exchanges/LP_commands.c @@ -283,7 +283,10 @@ deposit_claim(address, expiration=0)\n\ { uint32_t requestid,quoteid; if ( (requestid= juint(argjson,"requestid")) != 0 && (quoteid= juint(argjson,"quoteid")) != 0 ) + { + return(clonestr("{\"result\":\"success\"}")); return(basilisk_swapentry(requestid,quoteid)); + } else if ( coin[0] != 0 ) return(basilisk_swapentries(coin,0,jint(argjson,"limit"))); else if ( base[0] != 0 && rel[0] != 0 ) diff --git a/iguana/exchanges/LP_remember.c b/iguana/exchanges/LP_remember.c index de0c029fe..3e95fc0e9 100644 --- a/iguana/exchanges/LP_remember.c +++ b/iguana/exchanges/LP_remember.c @@ -1240,13 +1240,6 @@ char *basilisk_swaplist(uint32_t origrequestid,uint32_t origquoteid) else if ( Ktotal < 0 && Btotal > 0 ) jaddnum(retjson,"avesell",(double)-Btotal/Ktotal); } - /*array = cJSON_CreateArray(); - for (i=0; ilinfos)/sizeof(*myinfo->linfos); i++) - { - if ( myinfo->linfos[i].base[0] != 0 && myinfo->linfos[i].rel[0] != 0 ) - jaddi(array,linfo_json(&myinfo->linfos[i])); - } - jadd(retjson,"quotes",array);*/ portable_mutex_unlock(&LP_swaplistmutex); return(jprint(retjson,1)); } From b4a6525e096d66f41deb4ffd9f1db34b692757d7 Mon Sep 17 00:00:00 2001 From: jl777 Date: Tue, 21 Nov 2017 22:22:51 +0400 Subject: [PATCH 1034/1664] Test --- iguana/exchanges/LP_commands.c | 1 - 1 file changed, 1 deletion(-) diff --git a/iguana/exchanges/LP_commands.c b/iguana/exchanges/LP_commands.c index f6f3d1970..a42524ddf 100644 --- a/iguana/exchanges/LP_commands.c +++ b/iguana/exchanges/LP_commands.c @@ -284,7 +284,6 @@ deposit_claim(address, expiration=0)\n\ uint32_t requestid,quoteid; if ( (requestid= juint(argjson,"requestid")) != 0 && (quoteid= juint(argjson,"quoteid")) != 0 ) { - return(clonestr("{\"result\":\"success\"}")); return(basilisk_swapentry(requestid,quoteid)); } else if ( coin[0] != 0 ) From c5eeea61e3a959680b5015adf3736cafa92ac02f Mon Sep 17 00:00:00 2001 From: jl777 Date: Tue, 21 Nov 2017 23:06:00 +0400 Subject: [PATCH 1035/1664] Test --- iguana/exchanges/LP_commands.c | 12 ++++++------ iguana/exchanges/LP_zeroconf.c | 4 ++-- 2 files changed, 8 insertions(+), 8 deletions(-) diff --git a/iguana/exchanges/LP_commands.c b/iguana/exchanges/LP_commands.c index a42524ddf..f7ca4ad50 100644 --- a/iguana/exchanges/LP_commands.c +++ b/iguana/exchanges/LP_commands.c @@ -146,8 +146,8 @@ bot_settings(botid, newprice, newvolume)\n\ bot_status(botid)\n\ bot_stop(botid)\n\ bot_pause(botid)\n\ -deposit_create(weeks, amount, broadcast=0)\n\ -deposit_claim(address, expiration=0)\n\ +zeroconf_deposit(weeks, amount, broadcast=0)\n\ +zeroconf_claim(address, expiration=0)\n\ \"}")); //sell(base, rel, price, basevolume, timeout=10, duration=3600)\n\ @@ -184,23 +184,23 @@ deposit_claim(address, expiration=0)\n\ return(jprint(retjson,1)); } } - else if ( strcmp(method,"deposit_create") == 0 ) + else if ( strcmp(method,"zeroconf_deposit") == 0 ) { if ( (ptr= LP_coinsearch("KMD")) != 0 ) { if ( jint(argjson,"weeks") < 0 || jdouble(argjson,"amount") < 10. ) return(clonestr("{\"error\":\"deposit_create needs to have weeks and amount\"}")); - else return(LP_deposit_create(ptr,juint(argjson,"weeks"),jdouble(argjson,"amount"),jint(argjson,"broadcast"))); + else return(LP_zeroconf_deposit(ptr,juint(argjson,"weeks"),jdouble(argjson,"amount"),jint(argjson,"broadcast"))); } return(clonestr("{\"error\":\"cant find KMD\"}")); } - else if ( strcmp(method,"deposit_claim") == 0 ) + else if ( strcmp(method,"zeroconf_claim") == 0 ) { if ( (ptr= LP_coinsearch("KMD")) != 0 ) { if ( jstr(argjson,"address") == 0 ) return(clonestr("{\"error\":\"deposit_claim needs to have address\"}")); - else return(LP_deposit_claim(ptr,jstr(argjson,"address"),juint(argjson,"expiration"))); + else return(LP_zeroconf_claim(ptr,jstr(argjson,"address"),juint(argjson,"expiration"))); } return(clonestr("{\"error\":\"cant find KMD\"}")); } diff --git a/iguana/exchanges/LP_zeroconf.c b/iguana/exchanges/LP_zeroconf.c index bac4514fc..ffa0220ef 100644 --- a/iguana/exchanges/LP_zeroconf.c +++ b/iguana/exchanges/LP_zeroconf.c @@ -27,7 +27,7 @@ int32_t LP_deposit_addr(char *depositaddr,uint8_t *script,uint32_t timestamp,uin return(n); } -char *LP_deposit_create(struct iguana_info *coin,int32_t weeks,double amount,int32_t broadcast) +char *LP_zeroconf_deposit(struct iguana_info *coin,int32_t weeks,double amount,int32_t broadcast) { char p2shaddr[64],*retstr,*hexstr; uint8_t script[512]; int32_t weeki,scriptlen; cJSON *argjson,*retjson,*array,*item; uint32_t timestamp; bits256 txid,sendtxid; uint64_t amount64; if ( strcmp(coin->symbol,"KMD") != 0 ) @@ -116,7 +116,7 @@ char *LP_deposit_create(struct iguana_info *coin,int32_t weeks,double amount,int return(clonestr("{\"error\":\"error with LP_withdraw for zeroconf deposit\"}")); } -char *LP_deposit_claim(struct iguana_info *coin,char *depositaddr,uint32_t expiration) +char *LP_zeroconf_claim(struct iguana_info *coin,char *depositaddr,uint32_t expiration) { static void *ctx; uint8_t redeemscript[512],userdata[64]; char vinaddr[64],str[65],*signedtx=0; uint32_t timestamp,now,redeemlen; int32_t i,n,height,utxovout,userdatalen; bits256 signedtxid,utxotxid,sendtxid; int64_t sum,destamount,satoshis; cJSON *array,*item,*txids,*retjson; From b05c5ba8c12af2232d9577f55e077e174ffa7267 Mon Sep 17 00:00:00 2001 From: jl777 Date: Tue, 21 Nov 2017 23:09:24 +0400 Subject: [PATCH 1036/1664] test --- iguana/exchanges/LP_rpc.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/iguana/exchanges/LP_rpc.c b/iguana/exchanges/LP_rpc.c index 8639646ee..e60d0ddca 100644 --- a/iguana/exchanges/LP_rpc.c +++ b/iguana/exchanges/LP_rpc.c @@ -625,7 +625,7 @@ int32_t LP_address_isvalid(char *symbol,char *address) 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 ismine (%s)\n",address,jprint(retjson,0)); } //printf("%s\n",jprint(retjson,0)); free_json(retjson); From 43f2729a340d2f92c4ee095fe62605379cb5e823 Mon Sep 17 00:00:00 2001 From: jl777 Date: Tue, 21 Nov 2017 23:15:36 +0400 Subject: [PATCH 1037/1664] Test --- iguana/exchanges/LP_rpc.c | 2 +- iguana/exchanges/LP_zeroconf.c | 10 ++++++---- 2 files changed, 7 insertions(+), 5 deletions(-) diff --git a/iguana/exchanges/LP_rpc.c b/iguana/exchanges/LP_rpc.c index e60d0ddca..8639646ee 100644 --- a/iguana/exchanges/LP_rpc.c +++ b/iguana/exchanges/LP_rpc.c @@ -625,7 +625,7 @@ int32_t LP_address_isvalid(char *symbol,char *address) 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 ismine (%s)\n",address,jprint(retjson,0)); } //printf("%s\n",jprint(retjson,0)); free_json(retjson); diff --git a/iguana/exchanges/LP_zeroconf.c b/iguana/exchanges/LP_zeroconf.c index ffa0220ef..2fa2393d8 100644 --- a/iguana/exchanges/LP_zeroconf.c +++ b/iguana/exchanges/LP_zeroconf.c @@ -19,11 +19,12 @@ // marketmaker // -int32_t LP_deposit_addr(char *depositaddr,uint8_t *script,uint32_t timestamp,uint8_t *pubsecp33) +int32_t LP_deposit_addr(char *depositaddr,uint8_t *script,uint8_t taddr,uint8_t pubtype,uint32_t timestamp,uint8_t *pubsecp33) { uint8_t elsepub33[33],p2sh_rmd160[20]; int32_t n; decode_hex(elsepub33,33,BOTS_BONDPUBKEY33); n = bitcoin_performancebond(p2sh_rmd160,script,0,timestamp,pubsecp33,elsepub33); + bitcoin_address(depositaddr,taddr,pubtype,pubsecp33,33); return(n); } @@ -46,7 +47,7 @@ char *LP_zeroconf_deposit(struct iguana_info *coin,int32_t weeks,double amount,i if ( weeks >= 10000 ) return(clonestr("{\"error\":\"numweeks must be less than 10000\"}")); } else timestamp = (uint32_t)time(NULL) + 300, weeki = 0; - scriptlen = LP_deposit_addr(p2shaddr,script,timestamp,G.LP_pubsecp); + scriptlen = LP_deposit_addr(p2shaddr,script,coin->taddr,coin->pubtype,timestamp,G.LP_pubsecp); argjson = cJSON_CreateObject(); array = cJSON_CreateArray(); item = cJSON_CreateObject(); @@ -58,6 +59,7 @@ char *LP_zeroconf_deposit(struct iguana_info *coin,int32_t weeks,double amount,i jaddnum(item,BOTS_BONDADDRESS,dstr(amount64)); jaddi(array,item); jadd(argjson,"outputs",array); + printf("deposit.(%s)\n",jprint(argjson,0)); if ( (retstr= LP_withdraw(coin,argjson)) != 0 ) { if ( (retjson= cJSON_Parse(retstr)) != 0 ) @@ -133,7 +135,7 @@ char *LP_zeroconf_claim(struct iguana_info *coin,char *depositaddr,uint32_t expi if ( expiration != 0 ) timestamp = expiration; else timestamp -= LP_WEEKMULT; - redeemlen = LP_deposit_addr(vinaddr,redeemscript,timestamp,G.LP_pubsecp); + redeemlen = LP_deposit_addr(vinaddr,redeemscript,coin->taddr,coin->pubtype,timestamp,G.LP_pubsecp); if ( strcmp(depositaddr,vinaddr) == 0 ) { printf("found %s at timestamp.%u\n",vinaddr,timestamp); @@ -207,7 +209,7 @@ void LP_zeroconf_deposits(struct iguana_info *coin) if ( spendscript[11] == 33 ) { pub33 = &spendscript[12]; - redeemlen = LP_deposit_addr(p2shaddr,redeemscript,timestamp,pub33); + redeemlen = LP_deposit_addr(p2shaddr,redeemscript,coin->taddr,coin->pubtype,timestamp,pub33); if ( len == redeemlen && (timestamp % LP_WEEKMULT) == 0 ) { bitcoin_address(coinaddr,coin->taddr,coin->pubtype,pub33,33); From a5835818ed5bd442f08fd36392a2382b0a0f93ef Mon Sep 17 00:00:00 2001 From: jl777 Date: Tue, 21 Nov 2017 23:20:01 +0400 Subject: [PATCH 1038/1664] Test --- iguana/exchanges/LP_zeroconf.c | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/iguana/exchanges/LP_zeroconf.c b/iguana/exchanges/LP_zeroconf.c index 2fa2393d8..a321cb0a3 100644 --- a/iguana/exchanges/LP_zeroconf.c +++ b/iguana/exchanges/LP_zeroconf.c @@ -19,12 +19,12 @@ // marketmaker // -int32_t LP_deposit_addr(char *depositaddr,uint8_t *script,uint8_t taddr,uint8_t pubtype,uint32_t timestamp,uint8_t *pubsecp33) +int32_t LP_deposit_addr(char *p2shaddr,uint8_t *script,uint8_t taddr,uint8_t p2shtype,uint32_t timestamp,uint8_t *pubsecp33) { uint8_t elsepub33[33],p2sh_rmd160[20]; int32_t n; decode_hex(elsepub33,33,BOTS_BONDPUBKEY33); n = bitcoin_performancebond(p2sh_rmd160,script,0,timestamp,pubsecp33,elsepub33); - bitcoin_address(depositaddr,taddr,pubtype,pubsecp33,33); + bitcoin_address(p2shaddr,taddr,p2shtype,script,n); return(n); } @@ -47,7 +47,7 @@ char *LP_zeroconf_deposit(struct iguana_info *coin,int32_t weeks,double amount,i if ( weeks >= 10000 ) return(clonestr("{\"error\":\"numweeks must be less than 10000\"}")); } else timestamp = (uint32_t)time(NULL) + 300, weeki = 0; - scriptlen = LP_deposit_addr(p2shaddr,script,coin->taddr,coin->pubtype,timestamp,G.LP_pubsecp); + scriptlen = LP_deposit_addr(p2shaddr,script,coin->taddr,coin->p2shtype,timestamp,G.LP_pubsecp); argjson = cJSON_CreateObject(); array = cJSON_CreateArray(); item = cJSON_CreateObject(); @@ -135,7 +135,7 @@ char *LP_zeroconf_claim(struct iguana_info *coin,char *depositaddr,uint32_t expi if ( expiration != 0 ) timestamp = expiration; else timestamp -= LP_WEEKMULT; - redeemlen = LP_deposit_addr(vinaddr,redeemscript,coin->taddr,coin->pubtype,timestamp,G.LP_pubsecp); + redeemlen = LP_deposit_addr(vinaddr,redeemscript,coin->taddr,coin->p2shtype,timestamp,G.LP_pubsecp); if ( strcmp(depositaddr,vinaddr) == 0 ) { printf("found %s at timestamp.%u\n",vinaddr,timestamp); @@ -209,7 +209,7 @@ void LP_zeroconf_deposits(struct iguana_info *coin) if ( spendscript[11] == 33 ) { pub33 = &spendscript[12]; - redeemlen = LP_deposit_addr(p2shaddr,redeemscript,coin->taddr,coin->pubtype,timestamp,pub33); + redeemlen = LP_deposit_addr(p2shaddr,redeemscript,coin->taddr,coin->p2shtype,timestamp,pub33); if ( len == redeemlen && (timestamp % LP_WEEKMULT) == 0 ) { bitcoin_address(coinaddr,coin->taddr,coin->pubtype,pub33,33); From c20adfb62e78234aa16af9167d8aa534641ec557 Mon Sep 17 00:00:00 2001 From: jl777 Date: Tue, 21 Nov 2017 23:28:41 +0400 Subject: [PATCH 1039/1664] Test --- iguana/exchanges/LP_bitcoin.c | 8 ++++---- iguana/exchanges/LP_tradebots.c | 2 +- iguana/exchanges/LP_transaction.c | 8 ++++---- iguana/exchanges/LP_zeroconf.c | 4 ++-- 4 files changed, 11 insertions(+), 11 deletions(-) diff --git a/iguana/exchanges/LP_bitcoin.c b/iguana/exchanges/LP_bitcoin.c index 7103b7c57..d76293234 100644 --- a/iguana/exchanges/LP_bitcoin.c +++ b/iguana/exchanges/LP_bitcoin.c @@ -3309,9 +3309,9 @@ bits256 bitcoin_sigtxid(char *symbol,uint8_t taddr,uint8_t pubtype,uint8_t p2sht dest.vins[i].userdatalen = 0; } len = iguana_rwmsgtx(symbol,taddr,pubtype,p2shtype,isPoS,height,1,0,serialized,maxlen,&dest,&txid,vpnstr,0,0,0,suppress_pubkeys,zcash); - for (i=0; i 0 ) // (dest.tx_in != 1 || bits256_nonz(dest.vins[0].prev_hash) != 0) && dest.vins[0].scriptlen > 0 && { #ifdef BTC2_VERSION @@ -3322,7 +3322,7 @@ bits256 bitcoin_sigtxid(char *symbol,uint8_t taddr,uint8_t pubtype,uint8_t p2sht revsigtxid = bits256_doublesha256(0,serialized,len); for (i=0; ibasesum > SMALLVAL && bot->relsum > SMALLVAL && bot->completed > 0 ) { - jaddnum(json,"completed",bot->completed); + jadd(json,"complete",bot->completed!=0?jtrue():jfalse()); jaddnum(json,"percentage",100. * (bot->relsum / bot->totalrelvolume)); if ( bot->dispdir > 0 ) { diff --git a/iguana/exchanges/LP_transaction.c b/iguana/exchanges/LP_transaction.c index 02415da85..d9d63ee3c 100644 --- a/iguana/exchanges/LP_transaction.c +++ b/iguana/exchanges/LP_transaction.c @@ -420,7 +420,7 @@ int32_t bitcoin_verifyvins(void *ctx,char *symbol,uint8_t taddr,uint8_t pubtype, //printf(" scriptlen.%d\n",scriptlen); //printf("bitcoin_verifyvins scriptlen.%d siglen.%d\n",scriptlen,V[vini].signers[0].siglen); sigtxid = bitcoin_sigtxid(symbol,taddr,pubtype,p2shtype,isPoS,height,serialized,maxlen,msgtx,vini,script,scriptlen,sighash,vpnstr,suppress_pubkeys,zcash); - printf("bitcoin_verifyvins scriptlen.%d siglen.%d\n",scriptlen,V[vini].signers[0].siglen); + //printf("bitcoin_verifyvins scriptlen.%d siglen.%d\n",scriptlen,V[vini].signers[0].siglen); if ( bits256_nonz(sigtxid) != 0 ) { vp = &V[vini]; @@ -461,14 +461,14 @@ int32_t bitcoin_verifyvins(void *ctx,char *symbol,uint8_t taddr,uint8_t pubtype, { flag++; numsigs++; - int32_t z; char tmpaddr[64]; + /*int32_t z; char tmpaddr[64]; for (z=0; zsigners[j].pubkey[z]); bitcoin_address(tmpaddr,0,0,vp->signers[j].pubkey,33); - printf(" <- pub, SIG.%d.%d VERIFIED numsigs.%d vs M.%d %s\n",vini,j,numsigs,vp->M,tmpaddr); + printf(" <- pub, SIG.%d.%d VERIFIED numsigs.%d vs M.%d %s\n",vini,j,numsigs,vp->M,tmpaddr);*/ } } if ( numsigs >= vp->M ) @@ -731,7 +731,7 @@ char *iguana_validaterawtx(void *ctx,struct iguana_info *coin,struct iguana_msgt jaddstr(retjson,"error","interpreter rejects tx"); else complete = 1; jadd(retjson,"interpreter",log); - jaddnum(retjson,"complete",complete); + jadd(retjson,"complete",complete!=0?jtrue():jfalse()); free(serialized), free(serialized2); if ( signedtx != 0 ) free(signedtx); diff --git a/iguana/exchanges/LP_zeroconf.c b/iguana/exchanges/LP_zeroconf.c index a321cb0a3..7ce230120 100644 --- a/iguana/exchanges/LP_zeroconf.c +++ b/iguana/exchanges/LP_zeroconf.c @@ -30,7 +30,7 @@ int32_t LP_deposit_addr(char *p2shaddr,uint8_t *script,uint8_t taddr,uint8_t p2s char *LP_zeroconf_deposit(struct iguana_info *coin,int32_t weeks,double amount,int32_t broadcast) { - char p2shaddr[64],*retstr,*hexstr; uint8_t script[512]; int32_t weeki,scriptlen; cJSON *argjson,*retjson,*array,*item; uint32_t timestamp; bits256 txid,sendtxid; uint64_t amount64; + char p2shaddr[64],*retstr,*hexstr; uint8_t script[512]; int32_t weeki,scriptlen; cJSON *argjson,*retjson,*array,*item,*obj; uint32_t timestamp; bits256 txid,sendtxid; uint64_t amount64; if ( strcmp(coin->symbol,"KMD") != 0 ) return(clonestr("{\"error\":\"zeroconf deposit must be in KMD\"}")); if ( amount < 10.0 ) @@ -68,7 +68,7 @@ char *LP_zeroconf_deposit(struct iguana_info *coin,int32_t weeks,double amount,i jdelete(retjson,"result"); jaddstr(retjson,"address",p2shaddr); jaddnum(retjson,"expiration",timestamp); - if ( jint(retjson,"complete") > 0 && (hexstr= jstr(retjson,"hex")) != 0 ) + if ( (obj= jobj(retjson,"complete")) != 0 && is_cJSON_True(obj) != 0 && (hexstr= jstr(retjson,"hex")) != 0 ) { txid = jbits256(retjson,"txid"); if ( broadcast != 0 ) From 64adecda3b9554d7b96a407f1b98833ad886e2b1 Mon Sep 17 00:00:00 2001 From: jl777 Date: Tue, 21 Nov 2017 23:38:33 +0400 Subject: [PATCH 1040/1664] Test --- iguana/exchanges/LP_nativeDEX.c | 1 + iguana/exchanges/LP_transaction.c | 1 + 2 files changed, 2 insertions(+) diff --git a/iguana/exchanges/LP_nativeDEX.c b/iguana/exchanges/LP_nativeDEX.c index 7b81caa37..23e3608f4 100644 --- a/iguana/exchanges/LP_nativeDEX.c +++ b/iguana/exchanges/LP_nativeDEX.c @@ -19,6 +19,7 @@ // // feature requests // alice waiting for bestprice +// pricearray [{"date":1405699200,"high":0.0045388,"low":0.00403001,"open":0.00404545,"close":0.00435873,"volume":44.34555992,"quoteVolume":10311.88079097,"weightedAverage":0.00430043}, // USD paxprice based USDvalue in portfolio // portfolio value based on ask? // cancel bid/ask diff --git a/iguana/exchanges/LP_transaction.c b/iguana/exchanges/LP_transaction.c index d9d63ee3c..f991b2f6d 100644 --- a/iguana/exchanges/LP_transaction.c +++ b/iguana/exchanges/LP_transaction.c @@ -982,6 +982,7 @@ uint64_t _komodo_interestnew(uint64_t nValue,uint32_t nLockTime,uint32_t tiptime int32_t minutes; uint64_t interest = 0; if ( (minutes= (tiptime - nLockTime) / 60) >= 60 ) { + printf("minutes.%d tiptime.%u locktime.%u\n",minutes,tiptime,nLockTime); if ( minutes > 365 * 24 * 60 ) minutes = 365 * 24 * 60; minutes -= 59; From 197e2212eadeacbb06be128a4c87161900ff65a0 Mon Sep 17 00:00:00 2001 From: jl777 Date: Tue, 21 Nov 2017 23:53:57 +0400 Subject: [PATCH 1041/1664] Test --- iguana/exchanges/LP_transaction.c | 3 ++- iguana/exchanges/LP_zeroconf.c | 1 + 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/iguana/exchanges/LP_transaction.c b/iguana/exchanges/LP_transaction.c index f991b2f6d..b6b5ce208 100644 --- a/iguana/exchanges/LP_transaction.c +++ b/iguana/exchanges/LP_transaction.c @@ -980,8 +980,9 @@ cJSON *LP_inputjson(bits256 txid,int32_t vout,char *spendscriptstr) uint64_t _komodo_interestnew(uint64_t nValue,uint32_t nLockTime,uint32_t tiptime) { int32_t minutes; uint64_t interest = 0; - if ( (minutes= (tiptime - nLockTime) / 60) >= 60 ) + if ( tiptime > nLockTime && (minutes= (tiptime - nLockTime) / 60) >= 60 ) { + //minutes.71582779 tiptime.1511292969 locktime.1511293505 printf("minutes.%d tiptime.%u locktime.%u\n",minutes,tiptime,nLockTime); if ( minutes > 365 * 24 * 60 ) minutes = 365 * 24 * 60; diff --git a/iguana/exchanges/LP_zeroconf.c b/iguana/exchanges/LP_zeroconf.c index 7ce230120..2a8d95d0c 100644 --- a/iguana/exchanges/LP_zeroconf.c +++ b/iguana/exchanges/LP_zeroconf.c @@ -68,6 +68,7 @@ char *LP_zeroconf_deposit(struct iguana_info *coin,int32_t weeks,double amount,i jdelete(retjson,"result"); jaddstr(retjson,"address",p2shaddr); jaddnum(retjson,"expiration",timestamp); + jaddnum(retjson,"deposit",amount); if ( (obj= jobj(retjson,"complete")) != 0 && is_cJSON_True(obj) != 0 && (hexstr= jstr(retjson,"hex")) != 0 ) { txid = jbits256(retjson,"txid"); From 768dddab5987a8f6e373beb03fb1548cb60c8de5 Mon Sep 17 00:00:00 2001 From: jl777 Date: Wed, 22 Nov 2017 00:01:31 +0400 Subject: [PATCH 1042/1664] Test --- iguana/exchanges/LP_zeroconf.c | 1 + 1 file changed, 1 insertion(+) diff --git a/iguana/exchanges/LP_zeroconf.c b/iguana/exchanges/LP_zeroconf.c index 2a8d95d0c..71116431e 100644 --- a/iguana/exchanges/LP_zeroconf.c +++ b/iguana/exchanges/LP_zeroconf.c @@ -183,6 +183,7 @@ void LP_zeroconf_deposits(struct iguana_info *coin) cJSON *array,*item,*txjson,*vouts,*v,*sobj; uint32_t timestamp; int32_t i,n,redeemlen,len,numvouts,height,vout,weeki; bits256 txid; char *scriptstr,coinaddr[64],p2shaddr[64]; int64_t satoshis,amount64; uint8_t redeemscript[512],spendscript[512],*pub33; if ( (array= LP_listunspent("KMD",BOTS_BONDADDRESS)) != 0 ) { + printf("ZEROCONF.(%s)\n",jprint(array,0)); if ( (n= cJSON_GetArraySize(array)) > 0 ) { for (i=0; i Date: Wed, 22 Nov 2017 00:02:36 +0400 Subject: [PATCH 1043/1664] Test --- iguana/exchanges/LP_commands.c | 10 +++------- 1 file changed, 3 insertions(+), 7 deletions(-) diff --git a/iguana/exchanges/LP_commands.c b/iguana/exchanges/LP_commands.c index f7ca4ad50..a57679f43 100644 --- a/iguana/exchanges/LP_commands.c +++ b/iguana/exchanges/LP_commands.c @@ -431,14 +431,10 @@ zeroconf_claim(address, expiration=0)\n\ LP_listunspent_issue(coin,coinaddr,2); LP_privkey_init(-1,ptr,G.LP_privkey,G.LP_mypub25519); //LP_smartutxos_push(ptr); - if ( ptr->electrum != 0 ) - return(LP_unspents_filestr(coin,ptr->smartaddr)); - else return(jprint(LP_address_utxos(ptr,coinaddr,1),1)); - } - else - { - return(clonestr("{\"error\":\"not my address\"}")); } + if ( ptr->electrum != 0 ) + return(LP_unspents_filestr(coin,ptr->smartaddr)); + else return(jprint(LP_address_utxos(ptr,coinaddr,1),1)); } return(jprint(LP_address_utxos(ptr,coinaddr,1),1)); } else return(clonestr("{\"error\":\"no address specified\"}")); From 3258dd85511b689a42d571aa6fd8b0862de06c97 Mon Sep 17 00:00:00 2001 From: jl777 Date: Wed, 22 Nov 2017 00:08:17 +0400 Subject: [PATCH 1044/1664] Test --- iguana/exchanges/LP_commands.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/iguana/exchanges/LP_commands.c b/iguana/exchanges/LP_commands.c index a57679f43..32c214791 100644 --- a/iguana/exchanges/LP_commands.c +++ b/iguana/exchanges/LP_commands.c @@ -426,14 +426,14 @@ zeroconf_claim(address, expiration=0)\n\ if ( coinaddr[0] != 0 ) { LP_address(ptr,coinaddr); + LP_listunspent_issue(coin,coinaddr,2); if ( strcmp(coinaddr,ptr->smartaddr) == 0 && bits256_nonz(G.LP_privkey) != 0 ) { - LP_listunspent_issue(coin,coinaddr,2); LP_privkey_init(-1,ptr,G.LP_privkey,G.LP_mypub25519); //LP_smartutxos_push(ptr); } if ( ptr->electrum != 0 ) - return(LP_unspents_filestr(coin,ptr->smartaddr)); + return(LP_unspents_filestr(coin,coinaddr)); else return(jprint(LP_address_utxos(ptr,coinaddr,1),1)); } return(jprint(LP_address_utxos(ptr,coinaddr,1),1)); From 583a440fbd76f560fe028f2a168ac4e1649a1289 Mon Sep 17 00:00:00 2001 From: jl777 Date: Wed, 22 Nov 2017 00:11:19 +0400 Subject: [PATCH 1045/1664] Test --- iguana/exchanges/LP_socket.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/iguana/exchanges/LP_socket.c b/iguana/exchanges/LP_socket.c index f1a895b38..48c05b355 100644 --- a/iguana/exchanges/LP_socket.c +++ b/iguana/exchanges/LP_socket.c @@ -598,7 +598,7 @@ cJSON *electrum_address_listunspent(char *symbol,struct electrum_info *ep,cJSON { if ( jobj(retjson,"error") == 0 && is_cJSON_Array(retjson) != 0 ) { - if ( 0 && electrumflag > 1 ) + if ( 1 && electrumflag > 1 ) printf("%s.%d u.%u/%d t.%ld %s LISTUNSPENT.(%d)\n",coin->symbol,height,ap->unspenttime,ap->unspentheight,time(NULL),addr,(int32_t)strlen(jprint(retjson,0))); updatedflag = 0; if ( electrum_process_array(coin,ep,addr,retjson,electrumflag) != 0 ) From fbd1ecceea1a510723717f5e98b0cc052394ac09 Mon Sep 17 00:00:00 2001 From: jl777 Date: Wed, 22 Nov 2017 00:16:25 +0400 Subject: [PATCH 1046/1664] Test --- iguana/exchanges/LP_rpc.c | 26 ++++++++++++++++++++++---- 1 file changed, 22 insertions(+), 4 deletions(-) diff --git a/iguana/exchanges/LP_rpc.c b/iguana/exchanges/LP_rpc.c index 8639646ee..1d52e3afb 100644 --- a/iguana/exchanges/LP_rpc.c +++ b/iguana/exchanges/LP_rpc.c @@ -599,12 +599,30 @@ cJSON *LP_validateaddress(char *symbol,char *address) int32_t LP_address_ismine(char *symbol,char *address) { - int32_t doneflag = 0; cJSON *retjson; + int32_t doneflag = 0; cJSON *retjson,*obj; if ( symbol == 0 || symbol[0] == 0 ) return(0); if ( (retjson= LP_validateaddress(symbol,address)) != 0 ) { - if ( jobj(retjson,"ismine") != 0 && is_cJSON_True(jobj(retjson,"ismine")) != 0 ) + if ( (obj= jobj(retjson,"ismine")) != 0 && is_cJSON_True(obj) != 0 ) + { + doneflag = 1; + //printf("%s ismine (%s)\n",address,jprint(retjson,0)); + } + //printf("%s\n",jprint(retjson,0)); + free_json(retjson); + } + return(doneflag); +} + +int32_t LP_address_iswatched(char *symbol,char *address) +{ + int32_t doneflag = 0; cJSON *retjson,*obj; + if ( symbol == 0 || symbol[0] == 0 ) + return(0); + if ( (retjson= LP_validateaddress(symbol,address)) != 0 ) + { + if ( (obj= jobj(retjson,"iswatched")) != 0 && is_cJSON_True(obj) != 0 ) { doneflag = 1; //printf("%s ismine (%s)\n",address,jprint(retjson,0)); @@ -644,7 +662,7 @@ cJSON *LP_listunspent(char *symbol,char *coinaddr) return(cJSON_Parse("{\"error\":\"no coin\"}")); if ( coin->electrum == 0 ) { - if ( LP_address_ismine(symbol,coinaddr) > 0 ) + if ( LP_address_ismine(symbol,coinaddr) > 0 || LP_address_iswatched(symbol,coinaddr) > 0 ) { if ( strcmp(symbol,"BTC") == 0 ) numconfs = 0; @@ -681,7 +699,7 @@ int32_t LP_listunspent_issue(char *symbol,char *coinaddr,int32_t fullflag) else if ( IAMLP == 0 ) { //printf("LP_listunspent_query.(%s %s)\n",symbol,coinaddr); - LP_listunspent_query(coin->symbol,coin->smartaddr); + LP_listunspent_query(coin->symbol,coinaddr); } if ( retjson != 0 ) { From 2e16c8b2ab40cfb351a31e0393e511a3bd409cdb Mon Sep 17 00:00:00 2001 From: jl777 Date: Wed, 22 Nov 2017 00:19:42 +0400 Subject: [PATCH 1047/1664] Test --- iguana/exchanges/LP_nativeDEX.c | 2 +- iguana/exchanges/LP_rpc.c | 17 ++++------------- 2 files changed, 5 insertions(+), 14 deletions(-) diff --git a/iguana/exchanges/LP_nativeDEX.c b/iguana/exchanges/LP_nativeDEX.c index 23e3608f4..ade8ee8eb 100644 --- a/iguana/exchanges/LP_nativeDEX.c +++ b/iguana/exchanges/LP_nativeDEX.c @@ -658,7 +658,7 @@ int32_t LP_mainloop_iter(void *ctx,char *myipaddr,struct LP_peerinfo *mypeer,int HASH_ITER(hh,LP_coins,coin,ctmp) // firstrefht,firstscanht,lastscanht { now = (uint32_t)time(NULL); - if ( didzeroconf == 0 && strcmp("KMD",coin->symbol) == 0 ) + if ( coin->inactive == 0 && didzeroconf == 0 && strcmp("KMD",coin->symbol) == 0 ) { LP_zeroconf_deposits(coin); didzeroconf = now; diff --git a/iguana/exchanges/LP_rpc.c b/iguana/exchanges/LP_rpc.c index 1d52e3afb..717dde38e 100644 --- a/iguana/exchanges/LP_rpc.c +++ b/iguana/exchanges/LP_rpc.c @@ -657,7 +657,7 @@ cJSON *LP_listunspent(char *symbol,char *coinaddr) if ( symbol == 0 || symbol[0] == 0 ) return(cJSON_Parse("{\"error\":\"null symbol\"}")); coin = LP_coinfind(symbol); - //printf("LP_listunspent.(%s %s)\n",symbol,coinaddr); + printf("LP_listunspent.(%s %s)\n",symbol,coinaddr); if ( coin == 0 || (IAMLP == 0 && coin->inactive != 0) ) return(cJSON_Parse("{\"error\":\"no coin\"}")); if ( coin->electrum == 0 ) @@ -682,7 +682,7 @@ int32_t LP_listunspent_issue(char *symbol,char *coinaddr,int32_t fullflag) { if ( coin->electrum != 0 ) { - if ( (retjson= electrum_address_listunspent(symbol,coin->electrum,&retjson,coinaddr,1)) != 0 ) + if ( (retjson= electrum_address_listunspent(symbol,coin->electrum,&retjson,coinaddr,fullflag)) != 0 ) { n = cJSON_GetArraySize(retjson); //printf("LP_listunspent_issue.%s %s.%d %s\n",symbol,coinaddr,n,jprint(retjson,0)); @@ -690,17 +690,8 @@ int32_t LP_listunspent_issue(char *symbol,char *coinaddr,int32_t fullflag) } else { - if ( strcmp(coin->smartaddr,coinaddr) == 0 ) - { - retjson = LP_listunspent(symbol,coinaddr); - coin->numutxos = cJSON_GetArraySize(retjson); - //printf("SELF_LISTUNSPENT.(%s %s)\n",symbol,coinaddr); - } - else if ( IAMLP == 0 ) - { - //printf("LP_listunspent_query.(%s %s)\n",symbol,coinaddr); - LP_listunspent_query(coin->symbol,coinaddr); - } + retjson = LP_listunspent(symbol,coinaddr); + coin->numutxos = cJSON_GetArraySize(retjson); if ( retjson != 0 ) { n = cJSON_GetArraySize(retjson); From df8b809bc1dbb64553cec1cde8e8e9201295847b Mon Sep 17 00:00:00 2001 From: jl777 Date: Wed, 22 Nov 2017 00:22:38 +0400 Subject: [PATCH 1048/1664] Test --- iguana/exchanges/LP_commands.c | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/iguana/exchanges/LP_commands.c b/iguana/exchanges/LP_commands.c index 32c214791..95f73e419 100644 --- a/iguana/exchanges/LP_commands.c +++ b/iguana/exchanges/LP_commands.c @@ -432,9 +432,10 @@ zeroconf_claim(address, expiration=0)\n\ LP_privkey_init(-1,ptr,G.LP_privkey,G.LP_mypub25519); //LP_smartutxos_push(ptr); } - if ( ptr->electrum != 0 ) - return(LP_unspents_filestr(coin,coinaddr)); - else return(jprint(LP_address_utxos(ptr,coinaddr,1),1)); + return(jprint(LP_listunspent(coin,coinaddr),0)); + //if ( ptr->electrum != 0 ) + //return(LP_unspents_filestr(coin,coinaddr)); + //else return(jprint(LP_address_utxos(ptr,coinaddr,1),1)); } return(jprint(LP_address_utxos(ptr,coinaddr,1),1)); } else return(clonestr("{\"error\":\"no address specified\"}")); From 4d7cbd6a2e18cf5457838ae70854e023e35e5f7d Mon Sep 17 00:00:00 2001 From: jl777 Date: Wed, 22 Nov 2017 00:26:40 +0400 Subject: [PATCH 1049/1664] Test --- iguana/exchanges/LP_socket.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/iguana/exchanges/LP_socket.c b/iguana/exchanges/LP_socket.c index 48c05b355..3dbf2ea33 100644 --- a/iguana/exchanges/LP_socket.c +++ b/iguana/exchanges/LP_socket.c @@ -606,7 +606,7 @@ cJSON *electrum_address_listunspent(char *symbol,struct electrum_info *ep,cJSON //LP_postutxos(coin->symbol,addr); updatedflag = 1; } - if ( strcmp(addr,coin->smartaddr) == 0 ) + //if ( strcmp(addr,coin->smartaddr) == 0 ) { retstr = jprint(retjson,0); LP_unspents_cache(coin->symbol,coin->smartaddr,retstr,1); @@ -627,7 +627,7 @@ cJSON *electrum_address_listunspent(char *symbol,struct electrum_info *ep,cJSON } if ( retjson == 0 ) { - if ( strcmp(addr,coin->smartaddr) == 0 && (retstr= LP_unspents_filestr(symbol,coin->smartaddr)) != 0 ) + if ( (retstr= LP_unspents_filestr(symbol,coin->smartaddr)) != 0 ) { retjson = cJSON_Parse(retstr); free(retstr); From 783c75892864cd2dcee2ea16092e3d74a2449c71 Mon Sep 17 00:00:00 2001 From: jl777 Date: Wed, 22 Nov 2017 00:34:04 +0400 Subject: [PATCH 1050/1664] Test --- iguana/exchanges/LP_cache.c | 2 +- iguana/exchanges/LP_rpc.c | 2 +- iguana/exchanges/LP_socket.c | 11 ++++------- iguana/exchanges/LP_utxo.c | 6 +++--- 4 files changed, 9 insertions(+), 12 deletions(-) diff --git a/iguana/exchanges/LP_cache.c b/iguana/exchanges/LP_cache.c index ff08f8298..d51e44922 100644 --- a/iguana/exchanges/LP_cache.c +++ b/iguana/exchanges/LP_cache.c @@ -330,7 +330,7 @@ uint64_t LP_unspents_load(char *symbol,char *addr) balance += j64bits(item,"value"); } } - electrum_process_array(coin,coin->electrum,coin->smartaddr,retjson,1); + electrum_process_array(coin,coin->electrum,addr,retjson,1); free_json(retjson); } free(arraystr); diff --git a/iguana/exchanges/LP_rpc.c b/iguana/exchanges/LP_rpc.c index 717dde38e..c76b37cdb 100644 --- a/iguana/exchanges/LP_rpc.c +++ b/iguana/exchanges/LP_rpc.c @@ -586,7 +586,7 @@ cJSON *LP_validateaddress(char *symbol,char *address) } bitcoin_address(coinaddr,coin->taddr,coin->pubtype,G.LP_myrmd160,20); jadd(retjson,"ismine",strcmp(address,coin->smartaddr) == 0 ? cJSON_CreateTrue() : cJSON_CreateFalse()); - jadd(retjson,"iswatchonly",cJSON_CreateFalse()); + jadd(retjson,"iswatchonly",cJSON_CreateTrue()); jadd(retjson,"isscript",addrtype == coin->p2shtype ? cJSON_CreateTrue() : cJSON_CreateFalse()); return(retjson); } diff --git a/iguana/exchanges/LP_socket.c b/iguana/exchanges/LP_socket.c index 3dbf2ea33..1d2163b7f 100644 --- a/iguana/exchanges/LP_socket.c +++ b/iguana/exchanges/LP_socket.c @@ -606,12 +606,9 @@ cJSON *electrum_address_listunspent(char *symbol,struct electrum_info *ep,cJSON //LP_postutxos(coin->symbol,addr); updatedflag = 1; } - //if ( strcmp(addr,coin->smartaddr) == 0 ) - { - retstr = jprint(retjson,0); - LP_unspents_cache(coin->symbol,coin->smartaddr,retstr,1); - free(retstr); - } + retstr = jprint(retjson,0); + LP_unspents_cache(coin->symbol,addr,retstr,1); + free(retstr); if ( ap != 0 ) { ap->unspenttime = (uint32_t)time(NULL); @@ -627,7 +624,7 @@ cJSON *electrum_address_listunspent(char *symbol,struct electrum_info *ep,cJSON } if ( retjson == 0 ) { - if ( (retstr= LP_unspents_filestr(symbol,coin->smartaddr)) != 0 ) + if ( (retstr= LP_unspents_filestr(symbol,addr)) != 0 ) { retjson = cJSON_Parse(retstr); free(retstr); diff --git a/iguana/exchanges/LP_utxo.c b/iguana/exchanges/LP_utxo.c index 8295db767..7e677c69b 100644 --- a/iguana/exchanges/LP_utxo.c +++ b/iguana/exchanges/LP_utxo.c @@ -560,9 +560,9 @@ cJSON *LP_address_balance(struct iguana_info *coin,char *coinaddr,int32_t electr } else { - if ( strcmp(coin->smartaddr,coinaddr) == 0 ) + //if ( strcmp(coin->smartaddr,coinaddr) == 0 ) balance = LP_unspents_load(coin->symbol,coinaddr); - else + /*else { if ( (array= LP_address_utxos(coin,coinaddr,1)) != 0 ) { @@ -576,7 +576,7 @@ cJSON *LP_address_balance(struct iguana_info *coin,char *coinaddr,int32_t electr } free_json(array); } - } + }*/ } retjson = cJSON_CreateObject(); jaddstr(retjson,"result","success"); From e4cae0a8c182416da7f486bb513d807cc64956a4 Mon Sep 17 00:00:00 2001 From: jl777 Date: Wed, 22 Nov 2017 00:38:47 +0400 Subject: [PATCH 1051/1664] Test --- iguana/exchanges/LP_utxos.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/iguana/exchanges/LP_utxos.c b/iguana/exchanges/LP_utxos.c index 75af6c872..f73bd42de 100644 --- a/iguana/exchanges/LP_utxos.c +++ b/iguana/exchanges/LP_utxos.c @@ -592,8 +592,8 @@ int32_t LP_privkey_init(int32_t mypubsock,struct iguana_info *coin,bits256 mypri return(0); coin->privkeydepth++; LP_address(coin,coin->smartaddr); - if ( coin->inactive == 0 ) - LP_listunspent_issue(coin->symbol,coin->smartaddr,0); + //if ( coin->inactive == 0 ) + // LP_listunspent_issue(coin->symbol,coin->smartaddr,0); array = LP_listunspent(coin->symbol,coin->smartaddr); if ( array != 0 ) { From 11f4784b4e181350275a884ab6295d2dd5ba28c5 Mon Sep 17 00:00:00 2001 From: jl777 Date: Wed, 22 Nov 2017 00:41:49 +0400 Subject: [PATCH 1052/1664] Test --- iguana/exchanges/LP_nativeDEX.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/iguana/exchanges/LP_nativeDEX.c b/iguana/exchanges/LP_nativeDEX.c index ade8ee8eb..11d542cb2 100644 --- a/iguana/exchanges/LP_nativeDEX.c +++ b/iguana/exchanges/LP_nativeDEX.c @@ -550,7 +550,7 @@ void LP_coinsloop(void *_coins) HASH_ITER(hh,coin->addresses,ap,atmp) { //printf("call unspent %s\n",ap->coinaddr); - if ( (retjson= electrum_address_listunspent(coin->symbol,ep,&retjson,ap->coinaddr,1)) != 0 ) + if ( strcmp(coin->smartaddr,ap->coinaddr) != 0 && (retjson= electrum_address_listunspent(coin->symbol,ep,&retjson,ap->coinaddr,1)) != 0 ) free_json(retjson); } if ( (ap= LP_addressfind(coin,coin->smartaddr)) != 0 ) From 0ddb676a88f75ad7643f34e15a2366031ea74432 Mon Sep 17 00:00:00 2001 From: jl777 Date: Wed, 22 Nov 2017 00:51:01 +0400 Subject: [PATCH 1053/1664] Test --- iguana/exchanges/LP_commands.c | 6 +++--- iguana/exchanges/LP_rpc.c | 2 +- iguana/exchanges/LP_socket.c | 2 +- 3 files changed, 5 insertions(+), 5 deletions(-) diff --git a/iguana/exchanges/LP_commands.c b/iguana/exchanges/LP_commands.c index 95f73e419..71fa7459b 100644 --- a/iguana/exchanges/LP_commands.c +++ b/iguana/exchanges/LP_commands.c @@ -426,7 +426,7 @@ zeroconf_claim(address, expiration=0)\n\ if ( coinaddr[0] != 0 ) { LP_address(ptr,coinaddr); - LP_listunspent_issue(coin,coinaddr,2); + //LP_listunspent_issue(coin,coinaddr,2); if ( strcmp(coinaddr,ptr->smartaddr) == 0 && bits256_nonz(G.LP_privkey) != 0 ) { LP_privkey_init(-1,ptr,G.LP_privkey,G.LP_mypub25519); @@ -437,8 +437,8 @@ zeroconf_claim(address, expiration=0)\n\ //return(LP_unspents_filestr(coin,coinaddr)); //else return(jprint(LP_address_utxos(ptr,coinaddr,1),1)); } - return(jprint(LP_address_utxos(ptr,coinaddr,1),1)); - } else return(clonestr("{\"error\":\"no address specified\"}")); + } + return(clonestr("{\"error\":\"no address specified\"}")); } else return(clonestr("{\"error\":\"cant find coind\"}")); } else if ( strcmp(method,"balance") == 0 ) diff --git a/iguana/exchanges/LP_rpc.c b/iguana/exchanges/LP_rpc.c index c76b37cdb..f728262aa 100644 --- a/iguana/exchanges/LP_rpc.c +++ b/iguana/exchanges/LP_rpc.c @@ -657,7 +657,7 @@ cJSON *LP_listunspent(char *symbol,char *coinaddr) if ( symbol == 0 || symbol[0] == 0 ) return(cJSON_Parse("{\"error\":\"null symbol\"}")); coin = LP_coinfind(symbol); - printf("LP_listunspent.(%s %s)\n",symbol,coinaddr); + //printf("LP_listunspent.(%s %s)\n",symbol,coinaddr); if ( coin == 0 || (IAMLP == 0 && coin->inactive != 0) ) return(cJSON_Parse("{\"error\":\"no coin\"}")); if ( coin->electrum == 0 ) diff --git a/iguana/exchanges/LP_socket.c b/iguana/exchanges/LP_socket.c index 1d2163b7f..d17930dc3 100644 --- a/iguana/exchanges/LP_socket.c +++ b/iguana/exchanges/LP_socket.c @@ -598,7 +598,7 @@ cJSON *electrum_address_listunspent(char *symbol,struct electrum_info *ep,cJSON { if ( jobj(retjson,"error") == 0 && is_cJSON_Array(retjson) != 0 ) { - if ( 1 && electrumflag > 1 ) + if ( 0 && electrumflag > 1 ) printf("%s.%d u.%u/%d t.%ld %s LISTUNSPENT.(%d)\n",coin->symbol,height,ap->unspenttime,ap->unspentheight,time(NULL),addr,(int32_t)strlen(jprint(retjson,0))); updatedflag = 0; if ( electrum_process_array(coin,ep,addr,retjson,electrumflag) != 0 ) From e4007d8cb7922dc83ffbb73e5e7de4a4c5290de0 Mon Sep 17 00:00:00 2001 From: jl777 Date: Wed, 22 Nov 2017 13:25:49 +0400 Subject: [PATCH 1054/1664] Trades array --- iguana/exchanges/LP_RTmetrics.c | 18 ++--- iguana/exchanges/LP_commands.c | 22 +++---- iguana/exchanges/LP_include.h | 4 +- iguana/exchanges/LP_nativeDEX.c | 8 ++- iguana/exchanges/LP_stats.c | 113 ++++++++++++++++++++++++++++---- iguana/exchanges/LP_swap.c | 7 ++ 6 files changed, 134 insertions(+), 38 deletions(-) diff --git a/iguana/exchanges/LP_RTmetrics.c b/iguana/exchanges/LP_RTmetrics.c index a3485c9f9..24d98eec8 100644 --- a/iguana/exchanges/LP_RTmetrics.c +++ b/iguana/exchanges/LP_RTmetrics.c @@ -149,7 +149,7 @@ void LP_RTmetrics_swapsinfo(char *refbase,char *refrel,cJSON *swaps,int32_t nums void LP_RTmetrics_update(char *base,char *rel) { - struct LP_pubkeyinfo *pubp,*tmp; uint32_t futuretime; int32_t i,numswaps; bits256 pubkey,zero; char *retstr; cJSON *statsjson,*swaps; + struct LP_pubkeyinfo *pubp,*tmp; uint32_t futuretime; int32_t i,numswaps; bits256 pubkey,zero; cJSON *statsjson,*swaps; memset(&LP_RTmetrics,0,sizeof(LP_RTmetrics)); HASH_ITER(hh,LP_pubkeyinfos,pubp,tmp) { @@ -161,19 +161,15 @@ void LP_RTmetrics_update(char *base,char *rel) } futuretime = (uint32_t)time(NULL) + 3600*100; memset(zero.bytes,0,sizeof(zero)); - if ( (retstr= LP_statslog_disp(100,futuretime,futuretime,"",zero)) != 0 ) + if ( (statsjson= LP_statslog_disp(futuretime,futuretime,"",zero,0,0)) != 0 ) { - if ( (statsjson= cJSON_Parse(retstr)) != 0 ) + if ( (swaps= jarray(&numswaps,statsjson,"swaps")) != 0 ) { - if ( (swaps= jarray(&numswaps,statsjson,"swaps")) != 0 ) - { - //printf("LP_RTmetrics_update for (%s)\n",jprint(swaps,0)); - if ( numswaps > 0 ) - LP_RTmetrics_swapsinfo(base,rel,swaps,numswaps); - } - free_json(statsjson); + //printf("LP_RTmetrics_update for (%s)\n",jprint(swaps,0)); + if ( numswaps > 0 ) + LP_RTmetrics_swapsinfo(base,rel,swaps,numswaps); } - free(retstr); + free_json(statsjson); } for (i=0; i [timestamp, avebid, aveask, highbid, lowask]\n\ setprice(base, rel, price, broadcast=1)\n\ autoprice(base, rel, fixed, minprice, margin, refbase, refrel, factor, offset)*\n\ goal(coin=*, val=)\n\ @@ -103,7 +102,9 @@ enable(coin)\n\ disable(coin)\n\ notarizations(coin)\n\ parselog()\n\ -statsdisp(starttime=0, endtime=0, gui="", pubkey="")\n\ +statsdisp(starttime=0, endtime=0, gui="", pubkey="", base="", rel="")\n\ +tradesarray(base, rel, starttime=-timescale*1024, endtime=, timescale=60) -> [timestamp, high, low, open, close, relvolume, basevolume, aveprice]\n\ +pricearray(base, rel, starttime=0, endtime=0, timescale=60) -> [timestamp, avebid, aveask, highbid, lowask]\n\ getrawtransaction(coin, txid)\n\ inventory(coin, reset=0, [passphrase=])\n\ bestfit(rel, relvolume)\n\ @@ -263,14 +264,13 @@ zeroconf_claim(address, expiration=0)\n\ } else if ( strcmp(method,"parselog") == 0 ) { - bits256 zero; int32_t n = LP_statslog_parse(); + bits256 zero; memset(zero.bytes,0,sizeof(zero)); - return(LP_statslog_disp(n,2000000000,2000000000,"",zero)); + return(jprint(LP_statslog_disp(2000000000,2000000000,"",zero,0,0),1)); } else if ( strcmp(method,"statsdisp") == 0 ) { - int32_t n = LP_statslog_parse(); - return(LP_statslog_disp(n,juint(argjson,"starttime"),juint(argjson,"endtime"),jstr(argjson,"gui"),jbits256(argjson,"pubkey"))); + return(jprint(LP_statslog_disp(juint(argjson,"starttime"),juint(argjson,"endtime"),jstr(argjson,"gui"),jbits256(argjson,"pubkey"),jstr(argjson,"base"),jstr(argjson,"rel")),1)); } else if ( strcmp(method,"secretaddresses") == 0 ) { @@ -321,15 +321,15 @@ zeroconf_claim(address, expiration=0)\n\ uint32_t firsttime; if ( base[0] != 0 && rel[0] != 0 ) { - if ( (firsttime= juint(argjson,"firsttime")) < time(NULL)-30*24*3600 ) + if ( (firsttime= juint(argjson,"starttime")) < time(NULL)-30*24*3600 ) firsttime = (uint32_t)(time(NULL)-30*24*3600); - return(jprint(LP_pricearray(base,rel,firsttime,juint(argjson,"lasttime"),jint(argjson,"timescale")),1)); + return(jprint(LP_pricearray(base,rel,firsttime,juint(argjson,"endtime"),jint(argjson,"timescale")),1)); } else return(clonestr("{\"error\":\"pricearray needs base and rel\"}")); } - /*else if ( strcmp(method,"pricearray") == 0 ) + else if ( strcmp(method,"tradesarray") == 0 ) { - return(jprint(LP_pricearray(base,rel,juint(argjson,"starttime"),juint(argjson,"endtime"),jint(argjson,"timescale")),1)); - }*/ + return(jprint(LP_tradesarray(base,rel,juint(argjson,"starttime"),juint(argjson,"endtime"),jint(argjson,"timescale")),1)); + } else if ( strcmp(method,"orderbook") == 0 ) return(LP_orderbook(base,rel,jint(argjson,"duration"))); else if ( strcmp(method,"myprice") == 0 ) diff --git a/iguana/exchanges/LP_include.h b/iguana/exchanges/LP_include.h index c0453e460..3961ca051 100644 --- a/iguana/exchanges/LP_include.h +++ b/iguana/exchanges/LP_include.h @@ -49,6 +49,7 @@ void emscripten_usleep(int32_t x); // returns immediate, no sense for sleeping #define LP_ELECTRUM_KEEPALIVE 60 #define LP_ELECTRUM_MAXERRORS 777 #define LP_MEMPOOL_TIMEINCR 10 +#define LP_SCREENWIDTH 1024 #define LP_MIN_PEERS 8 #define LP_MAX_PEERS 32 @@ -458,7 +459,7 @@ int32_t iguana_signrawtransaction(void *ctx,char *symbol,uint8_t wiftaddr,uint8_ struct LP_address_utxo *LP_address_utxofind(struct iguana_info *coin,char *coinaddr,bits256 txid,int32_t vout); int32_t LP_destaddr(char *destaddr,cJSON *item); int32_t LP_waitmempool(char *symbol,char *coinaddr,bits256 txid,int32_t vout,int32_t duration); -char *LP_statslog_disp(int32_t n,uint32_t starttime,uint32_t endtime,char *refgui,bits256 refpubkey); +cJSON *LP_statslog_disp(uint32_t starttime,uint32_t endtime,char *refgui,bits256 refpubkey,char *refbase,char *refrel); uint32_t LP_heighttime(char *symbol,int32_t height); uint64_t LP_unspents_load(char *symbol,char *addr); int32_t LP_validSPV(char *symbol,char *coinaddr,bits256 txid,int32_t vout); @@ -477,6 +478,7 @@ 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 fullflag); uint16_t LP_randpeer(char *destip); +uint32_t LP_atomic_locktime(char *base,char *rel); struct LP_pubkeyinfo *LP_pubkeyfind(bits256 pubkey); char *issue_LP_psock(char *destip,uint16_t destport,int32_t ispaired); char *LP_unspents_filestr(char *symbol,char *addr); diff --git a/iguana/exchanges/LP_nativeDEX.c b/iguana/exchanges/LP_nativeDEX.c index 11d542cb2..7858e91d9 100644 --- a/iguana/exchanges/LP_nativeDEX.c +++ b/iguana/exchanges/LP_nativeDEX.c @@ -17,16 +17,18 @@ // LP_nativeDEX.c // marketmaker // -// feature requests +// feature requests: // alice waiting for bestprice -// pricearray [{"date":1405699200,"high":0.0045388,"low":0.00403001,"open":0.00404545,"close":0.00435873,"volume":44.34555992,"quoteVolume":10311.88079097,"weightedAverage":0.00430043}, // USD paxprice based USDvalue in portfolio -// portfolio value based on ask? // cancel bid/ask // https://github.com/bitcoin/bips/blob/master/bip-0143.mediawiki for signing BCH/BTG // // bugs, validations: +// waiting for alice and alice disconnects // MNZ getcoin strangeness +// portfolio value based on ask? +// listunspent triplicate +// RTmetrics update from tradecommand // verify encrypted destpubkey, broadcast:0 setprice // [{"date":1405699200,"high":0.0045388,"low":0.00403001,"open":0.00404545,"close":0.00435873,"relvol":44.34555992,"basevol":10311.88079097,"aveprice":0.00430043}, // minute, diff --git a/iguana/exchanges/LP_stats.c b/iguana/exchanges/LP_stats.c index 40569f027..d37d5da56 100644 --- a/iguana/exchanges/LP_stats.c +++ b/iguana/exchanges/LP_stats.c @@ -34,13 +34,6 @@ int32_t LP_statslog_parsequote(char *method,cJSON *lineobj); char *LP_stats_methods[] = { "unknown", "request", "reserved", "connect", "connected", "tradestatus" }; -uint32_t LP_atomic_locktime(char *base,char *rel) -{ - if ( strcmp(base,"BTC") != 0 && strcmp(rel,"BTC") != 0 ) - return(INSTANTDEX_LOCKTIME); - else return(INSTANTDEX_LOCKTIME * 10); -} - static uint32_t LP_requests,LP_reserveds,LP_connects,LP_connecteds,LP_tradestatuses,LP_parse_errors,LP_unknowns,LP_duplicates,LP_aliceids; void LP_tradecommand_log(cJSON *argjson) @@ -330,11 +323,12 @@ int32_t LP_statslog_parsequote(char *method,cJSON *lineobj) return(duplicate == 0); } -char *LP_statslog_disp(int32_t n,uint32_t starttime,uint32_t endtime,char *refgui,bits256 refpubkey) +cJSON *LP_statslog_disp(uint32_t starttime,uint32_t endtime,char *refgui,bits256 refpubkey,char *refbase,char *refrel) { - cJSON *retjson,*array,*item; struct LP_swapstats *sp,*tmp; int32_t i,dispflag,numtrades[LP_MAXPRICEINFOS]; char line[1024]; uint64_t basevols[LP_MAXPRICEINFOS],relvols[LP_MAXPRICEINFOS]; + cJSON *retjson,*array,*item; struct LP_swapstats *sp,*tmp; int32_t i,n,dispflag,numtrades[LP_MAXPRICEINFOS]; uint64_t basevols[LP_MAXPRICEINFOS],relvols[LP_MAXPRICEINFOS]; if ( starttime > endtime ) starttime = endtime; + n = LP_statslog_parse(); memset(basevols,0,sizeof(basevols)); memset(relvols,0,sizeof(relvols)); memset(numtrades,0,sizeof(numtrades)); @@ -353,6 +347,10 @@ char *LP_statslog_disp(int32_t n,uint32_t starttime,uint32_t endtime,char *refgu dispflag = 1; else if ( sp->Q.timestamp >= starttime && sp->Q.timestamp <= endtime ) dispflag = 1; + if ( refbase != 0 && strcmp(refbase,sp->Q.srccoin) != 0 && strcmp(refbase,sp->Q.destcoin) != 0 ) + dispflag = 0; + if ( refrel != 0 && strcmp(refrel,sp->Q.srccoin) != 0 && strcmp(refrel,sp->Q.destcoin) != 0 ) + dispflag = 0; if ( dispflag != 0 ) { dispflag = 0; @@ -364,8 +362,9 @@ char *LP_statslog_disp(int32_t n,uint32_t starttime,uint32_t endtime,char *refgu } if ( dispflag != 0 ) { - LP_swapstats_line(numtrades,basevols,relvols,line,sp); + //LP_swapstats_line(numtrades,basevols,relvols,line,sp); item = cJSON_CreateObject(); + jaddnum(item,"timestamp",sp->Q.timestamp); jadd64bits(item,"aliceid",sp->aliceid); jaddbits256(item,"src",sp->Q.srchash); jaddstr(item,"base",sp->Q.srccoin); @@ -376,7 +375,7 @@ char *LP_statslog_disp(int32_t n,uint32_t starttime,uint32_t endtime,char *refgu jaddnum(item,"price",sp->qprice); jaddnum(item,"requestid",sp->Q.R.requestid); jaddnum(item,"quoteid",sp->Q.R.quoteid); - jaddstr(item,"line",line); + //jaddstr(item,"line",line); jaddi(array,item); } } @@ -405,7 +404,97 @@ char *LP_statslog_disp(int32_t n,uint32_t starttime,uint32_t endtime,char *refgu jaddnum(retjson,"uniques",LP_aliceids); jaddnum(retjson,"tradestatus",LP_tradestatuses); jaddnum(retjson,"unknown",LP_unknowns); - return(jprint(retjson,1)); + return(retjson); +} + +//tradesarray(base, rel, starttime=-timescale*1024, endtime=, timescale=60) -> [timestamp, high, low, open, close, relvolume, basevolume, aveprice, numtrades] + +struct LP_ohlc +{ + uint32_t timestamp,firsttime,lasttime,numtrades; + double high,low,open,close,relsum,basesum; +}; + +cJSON *LP_ohlc_json(struct LP_ohlc *bar) +{ + cJSON *item; + if ( bar->numtrades != 0 && bar->relsum > SMALLVAL && bar->basesum > SMALLVAL ) + { + item = cJSON_CreateArray(); + jaddinum(item,bar->timestamp); + jaddinum(item,bar->high); + jaddinum(item,bar->low); + jaddinum(item,bar->open); + jaddinum(item,bar->close); + jaddinum(item,bar->relsum); + jaddinum(item,bar->basesum); + jaddinum(item,bar->relsum / bar->basesum); + jaddinum(item,bar->numtrades); + } + return(0); } +void LP_ohlc_update(struct LP_ohlc *bar,uint32_t timestamp,double basevol,double relvol) +{ + double price; + if ( basevol > SMALLVAL && relvol > SMALLVAL ) + { + price = relvol / basevol; + if ( bar->firsttime == 0 || timestamp < bar->firsttime ) + { + bar->firsttime = timestamp; + bar->open = price; + } + if ( bar->lasttime == 0 || timestamp > bar->lasttime ) + { + bar->lasttime = timestamp; + bar->close = price; + } + if ( bar->low == 0. || price < bar->low ) + bar->low = price; + if ( bar->high == 0. || price > bar->high ) + bar->high = price; + bar->basesum += basevol; + bar->relsum += relvol; + bar->numtrades++; + } +} + +cJSON *LP_tradesarray(char *base,char *rel,uint32_t starttime,uint32_t endtime,int32_t timescale) +{ + struct LP_ohlc *bars; cJSON *array,*item,*statsjson,*swaps; uint32_t timestamp; bits256 zero; int32_t i,n,numbars,bari; + if ( timescale < 60 ) + return(cJSON_Parse("{\"error\":\"one minute is shortest timescale\"}")); + memset(zero.bytes,0,sizeof(zero)); + if ( endtime == 0 ) + endtime = (((uint32_t)time(NULL) / timescale) * timescale); + if ( starttime == 0 ) + starttime = (endtime - LP_SCREENWIDTH*timescale); + numbars = ((endtime - starttime) / timescale) + 1; + bars = calloc(numbars,sizeof(*bars)); + for (bari=0; bari= starttime && timestamp <= endtime ) + { + bari = (timestamp - starttime) / timescale; + LP_ohlc_update(&bars[bari],timestamp,jdouble(item,"basevol"),jdouble(item,"relvol")); + } + } + } + free_json(statsjson); + } + array = cJSON_CreateArray(); + for (bari=0; barivins != 0 ) From affb03ba5a88db35ccc238d0d8b35f7c5fb5dbc9 Mon Sep 17 00:00:00 2001 From: jl777 Date: Wed, 22 Nov 2017 14:20:37 +0400 Subject: [PATCH 1055/1664] Test --- iguana/exchanges/LP_RTmetrics.c | 10 ++++---- iguana/exchanges/LP_commands.c | 2 +- iguana/exchanges/LP_include.h | 20 +++++++++++++--- iguana/exchanges/LP_nativeDEX.c | 7 +++--- iguana/exchanges/LP_ordermatch.c | 8 +++---- iguana/exchanges/LP_prices.c | 40 ++++++++++++++++---------------- iguana/exchanges/LP_signatures.c | 10 ++++---- iguana/exchanges/LP_stats.c | 25 +++++++++++--------- iguana/exchanges/LP_zeroconf.c | 2 +- iguana/exchanges/tradesarray | 3 +++ 10 files changed, 74 insertions(+), 53 deletions(-) create mode 100755 iguana/exchanges/tradesarray diff --git a/iguana/exchanges/LP_RTmetrics.c b/iguana/exchanges/LP_RTmetrics.c index 24d98eec8..b37fe0db5 100644 --- a/iguana/exchanges/LP_RTmetrics.c +++ b/iguana/exchanges/LP_RTmetrics.c @@ -118,7 +118,9 @@ void LP_RTmetrics_swapsinfo(char *refbase,char *refrel,cJSON *swaps,int32_t nums base = ""; if ( (rel= jstr(item,"rel")) == 0 ) rel = ""; - if ( strcmp(base,refbase) != 0 && strcmp(base,refrel) != 0 && strcmp(rel,refbase) != 0 && strcmp(rel,refrel) != 0 ) + if ( refbase[0] != 0 && strcmp(base,refbase) != 0 && strcmp(base,refrel) != 0 ) + continue; + if ( refrel[0] != 0 && strcmp(rel,refbase) != 0 && strcmp(rel,refrel) != 0 ) continue; aliceid = j64bits(item,"aliceid"); basesatoshis = SATOSHIDEN * jdouble(item,"basevol"); @@ -147,9 +149,9 @@ void LP_RTmetrics_swapsinfo(char *refbase,char *refrel,cJSON *swaps,int32_t nums } } -void LP_RTmetrics_update(char *base,char *rel) +void LP_RTmetrics_init() { - struct LP_pubkeyinfo *pubp,*tmp; uint32_t futuretime; int32_t i,numswaps; bits256 pubkey,zero; cJSON *statsjson,*swaps; + struct LP_pubkey_info *pubp,*tmp; uint32_t futuretime; int32_t i,numswaps; bits256 pubkey,zero; cJSON *statsjson,*swaps; memset(&LP_RTmetrics,0,sizeof(LP_RTmetrics)); HASH_ITER(hh,LP_pubkeyinfos,pubp,tmp) { @@ -167,7 +169,7 @@ void LP_RTmetrics_update(char *base,char *rel) { //printf("LP_RTmetrics_update for (%s)\n",jprint(swaps,0)); if ( numswaps > 0 ) - LP_RTmetrics_swapsinfo(base,rel,swaps,numswaps); + LP_RTmetrics_swapsinfo("","",swaps,numswaps); } free_json(statsjson); } diff --git a/iguana/exchanges/LP_commands.c b/iguana/exchanges/LP_commands.c index 75ee8ef68..2f5754c51 100644 --- a/iguana/exchanges/LP_commands.c +++ b/iguana/exchanges/LP_commands.c @@ -103,7 +103,7 @@ disable(coin)\n\ notarizations(coin)\n\ parselog()\n\ statsdisp(starttime=0, endtime=0, gui="", pubkey="", base="", rel="")\n\ -tradesarray(base, rel, starttime=-timescale*1024, endtime=, timescale=60) -> [timestamp, high, low, open, close, relvolume, basevolume, aveprice]\n\ +tradesarray(base, rel, starttime=-timescale*1024, endtime=, timescale=60) -> [timestamp, high, low, open, close, relvolume, basevolume, aveprice, numtrades]\n\ pricearray(base, rel, starttime=0, endtime=0, timescale=60) -> [timestamp, avebid, aveask, highbid, lowask]\n\ getrawtransaction(coin, txid)\n\ inventory(coin, reset=0, [passphrase=])\n\ diff --git a/iguana/exchanges/LP_include.h b/iguana/exchanges/LP_include.h index 3961ca051..d4a227a92 100644 --- a/iguana/exchanges/LP_include.h +++ b/iguana/exchanges/LP_include.h @@ -378,12 +378,26 @@ struct LP_pubkey_quote uint8_t baseind,relind,numutxos,scale; }; +struct LP_swapstats +{ + UT_hash_handle hh; + struct LP_quoteinfo Q; + bits256 bobdeposit,alicepayment,bobpayment,paymentspent,Apaymentspent,depositspent; + double qprice; + uint64_t aliceid; + uint32_t ind,methodind,finished,expired; + char alicegui[32],bobgui[32]; +}; + +struct LP_pubswap { struct LP_pubswap *next,*prev; struct LP_swapstats *swap; }; + #define LP_MAXPRICEINFOS 256 -struct LP_pubkeyinfo +struct LP_pubkey_info { UT_hash_handle hh; bits256 pubkey; struct LP_pubkey_quote *quotes; + struct LP_pubswap *bobswaps,*aliceswaps; uint64_t bondvalue,swaps_kmdvalue; uint32_t timestamp,numerrors,lasttime; int32_t istrusted; @@ -404,7 +418,7 @@ struct electrum_info }; uint32_t LP_sighash(char *symbol,int32_t zcash); -int32_t LP_pubkey_sigcheck(struct LP_pubkeyinfo *pubp,cJSON *item); +int32_t LP_pubkey_sigcheck(struct LP_pubkey_info *pubp,cJSON *item); int32_t LP_pubkey_sigadd(cJSON *item,uint32_t timestamp,bits256 priv,bits256 pub,uint8_t *rmd160,uint8_t *pubsecp); int32_t LP_quoteparse(struct LP_quoteinfo *qp,cJSON *argjson); struct LP_address *LP_address(struct iguana_info *coin,char *coinaddr); @@ -479,7 +493,7 @@ void LP_postutxos(char *symbol,char *coinaddr); int32_t LP_listunspent_both(char *symbol,char *coinaddr,int32_t fullflag); uint16_t LP_randpeer(char *destip); uint32_t LP_atomic_locktime(char *base,char *rel); -struct LP_pubkeyinfo *LP_pubkeyfind(bits256 pubkey); +struct LP_pubkey_info *LP_pubkeyfind(bits256 pubkey); char *issue_LP_psock(char *destip,uint16_t destport,int32_t ispaired); char *LP_unspents_filestr(char *symbol,char *addr); cJSON *bitcoin_data2json(char *symbol,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 zcash); diff --git a/iguana/exchanges/LP_nativeDEX.c b/iguana/exchanges/LP_nativeDEX.c index 7858e91d9..c656e5513 100644 --- a/iguana/exchanges/LP_nativeDEX.c +++ b/iguana/exchanges/LP_nativeDEX.c @@ -28,9 +28,7 @@ // MNZ getcoin strangeness // portfolio value based on ask? // listunspent triplicate -// RTmetrics update from tradecommand // verify encrypted destpubkey, broadcast:0 setprice -// [{"date":1405699200,"high":0.0045388,"low":0.00403001,"open":0.00404545,"close":0.00435873,"relvol":44.34555992,"basevol":10311.88079097,"aveprice":0.00430043}, // minute, // improve critical section detection when parallel trades // previously, it used to show amount, kmd equiv, perc @@ -99,7 +97,7 @@ int32_t num_Reserved_msgs[2],max_Reserved_msgs[2]; struct LP_peerinfo *LP_peerinfos,*LP_mypeer; struct LP_forwardinfo *LP_forwardinfos; struct iguana_info *LP_coins; -struct LP_pubkeyinfo *LP_pubkeyinfos; +struct LP_pubkey_info *LP_pubkeyinfos; struct rpcrequest_info *LP_garbage_collector; struct LP_address_utxo *LP_garbage_collector2; @@ -209,7 +207,7 @@ char *LP_command_process(void *ctx,char *myipaddr,int32_t pubsock,cJSON *argjson //if ( pubsock >= 0 ) //strncmp("{\"error\":",retstr,strlen("{\"error\":")) != 0 && //LP_send(pubsock,retstr,(int32_t)strlen(retstr)+1,0); } - } //else printf("finished tradecommand (%s)\n",jprint(argjson,0)); + } else LP_statslog_parse(); return(retstr); } @@ -1255,6 +1253,7 @@ void LPinit(uint16_t myport,uint16_t mypullport,uint16_t mypubport,uint16_t mybu exit(-1); } int32_t nonz; + LP_statslog_parse(); while ( 1 ) { nonz = 0; diff --git a/iguana/exchanges/LP_ordermatch.c b/iguana/exchanges/LP_ordermatch.c index 5bd75a9e2..a05bfe7b4 100644 --- a/iguana/exchanges/LP_ordermatch.c +++ b/iguana/exchanges/LP_ordermatch.c @@ -614,7 +614,7 @@ char *LP_connectedalice(cJSON *argjson) // alice LP_aliceid(Q.tradeid,Q.aliceid,"error5",0,0); return(clonestr("{\"error\":\"no price set\"}")); } - LP_RTmetrics_update(Q.srccoin,Q.destcoin); + //LP_RTmetrics_update(Q.srccoin,Q.destcoin); printf("%s/%s bid %.8f ask %.8f values %.8f %.8f\n",Q.srccoin,Q.destcoin,bid,ask,dstr(butxo->payment.value),dstr(butxo->deposit.value)); price = bid; if ( (coin= LP_coinfind(Q.destcoin)) == 0 ) @@ -908,7 +908,7 @@ int32_t LP_tradecommand(void *ctx,char *myipaddr,int32_t pubsock,cJSON *argjson, if ( counter > 3 || price > bestprice ) // skip if late or bad price return(retval); } else return(retval); - LP_RTmetrics_update(Q.srccoin,Q.destcoin); + //LP_RTmetrics_update(Q.srccoin,Q.destcoin); if ( LP_RTmetrics_blacklisted(Q.desthash) >= 0 ) { printf("request from blacklisted %s, ignore\n",bits256_str(str,Q.desthash)); @@ -1020,7 +1020,7 @@ struct LP_utxoinfo *LP_ordermatch_iter(struct LP_address_utxo **utxos,int32_t ma struct LP_utxoinfo *LP_buyutxo(double *ordermatchpricep,int64_t *bestsatoshisp,int64_t *bestdestsatoshisp,struct LP_utxoinfo *autxo,char *base,double maxprice,int32_t duration,uint64_t txfee,uint64_t desttxfee,char *gui,bits256 *avoids,int32_t numavoids,bits256 destpubkey) { - bits256 pubkey; char *obookstr,coinaddr[64]; cJSON *orderbook,*asks,*rawasks,*item; int32_t maxiters,i,j,numasks,max; struct LP_address_utxo **utxos; double price; struct LP_pubkeyinfo *pubp; uint64_t asatoshis; struct iguana_info *basecoin; struct LP_utxoinfo *bestutxo = 0; + bits256 pubkey; char *obookstr,coinaddr[64]; cJSON *orderbook,*asks,*rawasks,*item; int32_t maxiters,i,j,numasks,max; struct LP_address_utxo **utxos; double price; struct LP_pubkey_info *pubp; uint64_t asatoshis; struct iguana_info *basecoin; struct LP_utxoinfo *bestutxo = 0; maxiters = 100; *ordermatchpricep = 0.; *bestsatoshisp = *bestdestsatoshisp = 0; @@ -1182,7 +1182,7 @@ char *LP_autobuy(void *ctx,char *myipaddr,int32_t mypubsock,char *base,char *rel LP_mypriceset(&changed,autxo->coin,base,1. / maxprice); return(LP_trade(ctx,myipaddr,mypubsock,&Q,maxprice,timeout,duration,tradeid,destpubkey)); #ifdef oldway - LP_RTmetrics_update(base,rel); + //LP_RTmetrics_update(base,rel); while ( 1 ) { if ( (bestutxo= LP_buyutxo(&ordermatchprice,&bestsatoshis,&bestdestsatoshis,autxo,base,maxprice,duration,txfee,desttxfee,gui,pubkeys,numpubs,destpubkey)) == 0 || ordermatchprice == 0. || bestdestsatoshis == 0 ) diff --git a/iguana/exchanges/LP_prices.c b/iguana/exchanges/LP_prices.c index e1d27492c..adb1e7e45 100644 --- a/iguana/exchanges/LP_prices.c +++ b/iguana/exchanges/LP_prices.c @@ -49,7 +49,7 @@ struct LP_cacheinfo } *LP_cacheinfos; -float LP_pubkey_price(int32_t *numutxosp,int64_t *avesatoshisp,int64_t *maxsatoshisp,struct LP_pubkeyinfo *pubp,uint32_t baseind,uint32_t relind) +float LP_pubkey_price(int32_t *numutxosp,int64_t *avesatoshisp,int64_t *maxsatoshisp,struct LP_pubkey_info *pubp,uint32_t baseind,uint32_t relind) { struct LP_pubkey_quote *pq,*tmp; int32_t scale; int64_t scale64; *numutxosp = 0; @@ -75,7 +75,7 @@ float LP_pubkey_price(int32_t *numutxosp,int64_t *avesatoshisp,int64_t *maxsatos return(0); } -void LP_pubkey_update(struct LP_pubkeyinfo *pubp,uint32_t baseind,uint32_t relind,float price,int64_t balance,char *utxocoin,int32_t numutxos,int64_t minutxo,int64_t maxutxo) +void LP_pubkey_update(struct LP_pubkey_info *pubp,uint32_t baseind,uint32_t relind,float price,int64_t balance,char *utxocoin,int32_t numutxos,int64_t minutxo,int64_t maxutxo) { struct LP_pubkey_quote *pq,*tmp; int64_t aveutxo,scale64,ave64,max64; int32_t scale; DL_FOREACH_SAFE(pubp->quotes,pq,tmp) @@ -214,9 +214,9 @@ struct LP_cacheinfo *LP_cachefind(char *base,char *rel,bits256 txid,int32_t vout return(ptr); } -struct LP_pubkeyinfo *LP_pubkey_rmd160find(uint8_t rmd160[20]) +struct LP_pubkey_info *LP_pubkey_rmd160find(uint8_t rmd160[20]) { - struct LP_pubkeyinfo *pubp=0,*tmp; + struct LP_pubkey_info *pubp=0,*tmp; portable_mutex_lock(&LP_pubkeymutex); HASH_ITER(hh,LP_pubkeyinfos,pubp,tmp) { @@ -230,7 +230,7 @@ struct LP_pubkeyinfo *LP_pubkey_rmd160find(uint8_t rmd160[20]) struct LP_address *_LP_addressfind(struct iguana_info *coin,char *coinaddr) { - uint8_t rmd160[20],addrtype; struct LP_address *ap; struct LP_pubkeyinfo *pubp; + uint8_t rmd160[20],addrtype; struct LP_address *ap; struct LP_pubkey_info *pubp; HASH_FIND(hh,coin->addresses,coinaddr,strlen(coinaddr),ap); if ( ap != 0 && bits256_nonz(ap->pubkey) == 0 ) { @@ -246,7 +246,7 @@ struct LP_address *_LP_addressfind(struct iguana_info *coin,char *coinaddr) struct LP_address *_LP_addressadd(struct iguana_info *coin,char *coinaddr) { - uint8_t rmd160[20],addrtype; struct LP_address *ap; struct LP_pubkeyinfo *pubp; + uint8_t rmd160[20],addrtype; struct LP_address *ap; struct LP_pubkey_info *pubp; ap = calloc(1,sizeof(*ap)); safecopy(ap->coinaddr,coinaddr,sizeof(ap->coinaddr)); bitcoin_addr2rmd160(coin->taddr,&addrtype,rmd160,coinaddr); @@ -260,18 +260,18 @@ struct LP_address *_LP_addressadd(struct iguana_info *coin,char *coinaddr) return(ap); } -struct LP_pubkeyinfo *LP_pubkeyfind(bits256 pubkey) +struct LP_pubkey_info *LP_pubkeyfind(bits256 pubkey) { - struct LP_pubkeyinfo *pubp=0; + struct LP_pubkey_info *pubp=0; portable_mutex_lock(&LP_pubkeymutex); HASH_FIND(hh,LP_pubkeyinfos,&pubkey,sizeof(pubkey),pubp); portable_mutex_unlock(&LP_pubkeymutex); return(pubp); } -struct LP_pubkeyinfo *LP_pubkeyadd(bits256 pubkey) +struct LP_pubkey_info *LP_pubkeyadd(bits256 pubkey) { - char str[65]; struct LP_pubkeyinfo *pubp=0; + char str[65]; struct LP_pubkey_info *pubp=0; portable_mutex_lock(&LP_pubkeymutex); HASH_FIND(hh,LP_pubkeyinfos,&pubkey,sizeof(pubkey),pubp); if ( pubp == 0 ) @@ -294,7 +294,7 @@ struct LP_pubkeyinfo *LP_pubkeyadd(bits256 pubkey) int32_t LP_pubkey_istrusted(bits256 pubkey) { - struct LP_pubkeyinfo *pubp; + struct LP_pubkey_info *pubp; if ( (pubp= LP_pubkeyadd(pubkey)) != 0 ) return(pubp->istrusted != 0); return(0); @@ -302,7 +302,7 @@ int32_t LP_pubkey_istrusted(bits256 pubkey) char *LP_pubkey_trustset(bits256 pubkey,uint32_t trustval) { - struct LP_pubkeyinfo *pubp; + struct LP_pubkey_info *pubp; if ( (pubp= LP_pubkeyadd(pubkey)) != 0 ) { pubp->istrusted = trustval; @@ -313,7 +313,7 @@ char *LP_pubkey_trustset(bits256 pubkey,uint32_t trustval) char *LP_pubkey_trusted() { - struct LP_pubkeyinfo *pubp,*tmp; cJSON *array = cJSON_CreateArray(); + struct LP_pubkey_info *pubp,*tmp; cJSON *array = cJSON_CreateArray(); HASH_ITER(hh,LP_pubkeyinfos,pubp,tmp) { if ( pubp->istrusted != 0 ) @@ -343,7 +343,7 @@ uint64_t LP_unspents_metric(struct iguana_info *coin,char *coinaddr) return(metric); } -cJSON *LP_pubkeyjson(struct LP_pubkeyinfo *pubp) +cJSON *LP_pubkeyjson(struct LP_pubkey_info *pubp) { int32_t baseid,relid,numutxos; int64_t avesatoshis,maxsatoshis; char *base,hexstr[67],hexstr2[67],sigstr[256]; double price; cJSON *item,*array,*obj; obj = cJSON_CreateObject(); @@ -380,7 +380,7 @@ cJSON *LP_pubkeyjson(struct LP_pubkeyinfo *pubp) char *LP_prices() { - struct LP_pubkeyinfo *pubp,*tmp; cJSON *array = cJSON_CreateArray(); + struct LP_pubkey_info *pubp,*tmp; cJSON *array = cJSON_CreateArray(); HASH_ITER(hh,LP_pubkeyinfos,pubp,tmp) { jaddi(array,LP_pubkeyjson(pubp)); @@ -390,7 +390,7 @@ char *LP_prices() /*void LP_prices_parse(struct LP_peerinfo *peer,cJSON *obj) { - struct LP_pubkeyinfo *pubp; struct LP_priceinfo *basepp,*relpp; uint32_t timestamp; bits256 pubkey; cJSON *asks,*item; uint8_t rmd160[20]; int32_t i,n,relid,mismatch; char *base,*rel,*hexstr; double askprice; uint32_t now; + struct LP_pubkey_info *pubp; struct LP_priceinfo *basepp,*relpp; uint32_t timestamp; bits256 pubkey; cJSON *asks,*item; uint8_t rmd160[20]; int32_t i,n,relid,mismatch; char *base,*rel,*hexstr; double askprice; uint32_t now; now = (uint32_t)time(NULL); pubkey = jbits256(obj,"pubkey"); if ( bits256_nonz(pubkey) != 0 && (pubp= LP_pubkeyadd(pubkey)) != 0 ) @@ -555,7 +555,7 @@ char *LP_myprices() int32_t LP_mypriceset(int32_t *changedp,char *base,char *rel,double price) { - struct LP_priceinfo *basepp,*relpp; struct LP_pubkeyinfo *pubp; + struct LP_priceinfo *basepp,*relpp; struct LP_pubkey_info *pubp; *changedp = 0; if ( base != 0 && rel != 0 && (basepp= LP_priceinfofind(base)) != 0 && (relpp= LP_priceinfofind(rel)) != 0 ) { @@ -773,7 +773,7 @@ struct LP_orderbookentry *LP_orderbookentry(char *address,char *base,char *rel,d void LP_pubkeys_query() { - uint8_t zeroes[20]; bits256 zero; cJSON *reqjson; struct LP_pubkeyinfo *pubp=0,*tmp; + uint8_t zeroes[20]; bits256 zero; cJSON *reqjson; struct LP_pubkey_info *pubp=0,*tmp; memset(zero.bytes,0,sizeof(zero)); memset(zeroes,0,sizeof(zeroes)); HASH_ITER(hh,LP_pubkeyinfos,pubp,tmp) @@ -792,7 +792,7 @@ void LP_pubkeys_query() int32_t LP_orderbook_utxoentries(uint32_t now,int32_t polarity,char *base,char *rel,struct LP_orderbookentry *(**arrayp),int32_t num,int32_t cachednum,int32_t duration) { - char coinaddr[64]; uint8_t zeroes[20]; struct LP_pubkeyinfo *pubp=0,*tmp; struct LP_priceinfo *basepp; struct LP_orderbookentry *op; struct LP_address *ap; struct iguana_info *basecoin; uint32_t oldest; double price; int32_t baseid,relid,n; int64_t maxsatoshis,balance,avesatoshis; + char coinaddr[64]; uint8_t zeroes[20]; struct LP_pubkey_info *pubp=0,*tmp; struct LP_priceinfo *basepp; struct LP_orderbookentry *op; struct LP_address *ap; struct iguana_info *basecoin; uint32_t oldest; double price; int32_t baseid,relid,n; int64_t maxsatoshis,balance,avesatoshis; if ( (basepp= LP_priceinfoptr(&relid,base,rel)) != 0 ) baseid = basepp->ind; else return(num); @@ -1122,7 +1122,7 @@ cJSON *LP_pricearray(char *base,char *rel,uint32_t firsttime,uint32_t lasttime,i void LP_pricefeedupdate(bits256 pubkey,char *base,char *rel,double price,char *utxocoin,int32_t numrelutxos,int64_t balance,int64_t minutxo,int64_t maxutxo) { - struct LP_priceinfo *basepp,*relpp; uint32_t now; uint64_t price64; struct LP_pubkeyinfo *pubp; char str[65],fname[512]; FILE *fp; + struct LP_priceinfo *basepp,*relpp; uint32_t now; uint64_t price64; struct LP_pubkey_info *pubp; char str[65],fname[512]; FILE *fp; //printf("check PRICEFEED UPDATE.(%s/%s) %.8f %s\n",base,rel,price,bits256_str(str,pubkey)); if ( LP_pricevalid(price) > 0 && (basepp= LP_priceinfofind(base)) != 0 && (relpp= LP_priceinfofind(rel)) != 0 ) { diff --git a/iguana/exchanges/LP_signatures.c b/iguana/exchanges/LP_signatures.c index a46e677ed..3fc10d7aa 100644 --- a/iguana/exchanges/LP_signatures.c +++ b/iguana/exchanges/LP_signatures.c @@ -276,7 +276,7 @@ bits256 LP_utxos_sighash(uint32_t timestamp,uint8_t *pubsecp,bits256 pubkey,bits int32_t LP_utxos_sigcheck(uint32_t timestamp,char *sigstr,char *pubsecpstr,bits256 pubkey,bits256 utxoshash) { - static void *ctx; int32_t retval=-1; uint8_t pub33[33],pubsecp[33],sig[65]; bits256 sighash; char str[65]; struct LP_pubkeyinfo *pubp; + static void *ctx; int32_t retval=-1; uint8_t pub33[33],pubsecp[33],sig[65]; bits256 sighash; char str[65]; struct LP_pubkey_info *pubp; if ( ctx == 0 ) ctx = bitcoin_ctx(); pubp = LP_pubkeyfind(pubkey); @@ -362,7 +362,7 @@ struct LP_utxos_qitem { struct queueitem DL; cJSON *argjson; }; char *LP_postutxos_recv(cJSON *argjson) { - struct LP_utxos_qitem *uitem; struct iguana_info *coin; char *coinaddr,*symbol; bits256 utxoshash,pubkey; cJSON *obj; struct LP_pubkeyinfo *pubp; + struct LP_utxos_qitem *uitem; struct iguana_info *coin; char *coinaddr,*symbol; bits256 utxoshash,pubkey; cJSON *obj; struct LP_pubkey_info *pubp; printf("LP_postutxos_recv deprecated\n"); pubkey = jbits256(argjson,"pubkey"); pubp = LP_pubkeyfind(pubkey); @@ -416,7 +416,7 @@ int32_t LP_utxosQ_process() int32_t LP_price_sigcheck(uint32_t timestamp,char *sigstr,char *pubsecpstr,bits256 pubkey,char *base,char *rel,uint64_t price64) { - static void *ctx; int32_t retval=-1; uint8_t pub33[33],pubsecp[33],sig[65]; bits256 sighash; struct LP_pubkeyinfo *pubp; + static void *ctx; int32_t retval=-1; uint8_t pub33[33],pubsecp[33],sig[65]; bits256 sighash; struct LP_pubkey_info *pubp; if ( ctx == 0 ) ctx = bitcoin_ctx(); pubp = LP_pubkeyfind(pubkey); @@ -521,7 +521,7 @@ int32_t LP_pubkey_sigadd(cJSON *item,uint32_t timestamp,bits256 priv,bits256 pub return(LP_bitcoinsig_add(item,priv,pubsecp,sighash)); } -int32_t LP_pubkey_sigcheck(struct LP_pubkeyinfo *pubp,cJSON *item) +int32_t LP_pubkey_sigcheck(struct LP_pubkey_info *pubp,cJSON *item) { int32_t i,len,siglen,retval=-1; uint8_t rmd160[20],checkrmd160[20],pubsecp[33],sig[65],zeroes[20]; char *sigstr,*hexstr,*pubsecpstr; if ( (hexstr= jstr(item,"rmd160")) != 0 && strlen(hexstr) == 2*sizeof(rmd160) ) @@ -603,7 +603,7 @@ void LP_notify_pubkeys(void *ctx,int32_t pubsock) char *LP_notify_recv(cJSON *argjson) { - bits256 pub; struct LP_pubkeyinfo *pubp; char *ipaddr; + bits256 pub; struct LP_pubkey_info *pubp; char *ipaddr; pub = jbits256(argjson,"pub"); if ( bits256_nonz(pub) != 0 ) { diff --git a/iguana/exchanges/LP_stats.c b/iguana/exchanges/LP_stats.c index d37d5da56..5b666b875 100644 --- a/iguana/exchanges/LP_stats.c +++ b/iguana/exchanges/LP_stats.c @@ -20,16 +20,7 @@ #define LP_STATSLOG_FNAME "stats.log" -struct LP_swapstats -{ - UT_hash_handle hh; - struct LP_quoteinfo Q; - bits256 bobdeposit,alicepayment,bobpayment,paymentspent,Apaymentspent,depositspent; - double qprice; - uint64_t aliceid; - uint32_t ind,methodind,finished,expired; - char alicegui[32],bobgui[32]; -} *LP_swapstats; +struct LP_swapstats *LP_swapstats; int32_t LP_statslog_parsequote(char *method,cJSON *lineobj); char *LP_stats_methods[] = { "unknown", "request", "reserved", "connect", "connected", "tradestatus" }; @@ -215,7 +206,7 @@ int32_t LP_swapstats_update(struct LP_swapstats *sp,struct LP_quoteinfo *qp,cJSO int32_t LP_statslog_parsequote(char *method,cJSON *lineobj) { static uint32_t unexpected; - struct LP_swapstats *sp,*tmp; double qprice; uint32_t requestid,quoteid,timestamp; int32_t i,flag,numtrades[LP_MAXPRICEINFOS],methodind,destvout,feevout,duplicate=0; char *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; struct LP_pubkey_info *pubp; struct LP_pubswap *ptr; double qprice; uint32_t requestid,quoteid,timestamp; int32_t i,flag,numtrades[LP_MAXPRICEINFOS],methodind,destvout,feevout,duplicate=0; char *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,6 +297,18 @@ int32_t LP_statslog_parsequote(char *method,cJSON *lineobj) sp->ind = LP_aliceids++; strcpy(sp->bobgui,"nogui"); strcpy(sp->alicegui,"nogui"); + 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); + } //LP_swapstats_line(numtrades,basevols,relvols,line,sp); //printf("%s\n",line); } else printf("unexpected LP_swapstats_add failure\n"); diff --git a/iguana/exchanges/LP_zeroconf.c b/iguana/exchanges/LP_zeroconf.c index 71116431e..4e2fe899d 100644 --- a/iguana/exchanges/LP_zeroconf.c +++ b/iguana/exchanges/LP_zeroconf.c @@ -233,7 +233,7 @@ void LP_zeroconf_deposits(struct iguana_info *coin) int32_t LP_dynamictrust(bits256 pubkey,int64_t kmdvalue) { - struct LP_pubkeyinfo *pubp; + struct LP_pubkey_info *pubp; if ( (pubp= LP_pubkeyfind(pubkey)) != 0 ) { if ( pubp->bondvalue > pubp->swaps_kmdvalue+kmdvalue ) diff --git a/iguana/exchanges/tradesarray b/iguana/exchanges/tradesarray new file mode 100755 index 000000000..982bdca7c --- /dev/null +++ b/iguana/exchanges/tradesarray @@ -0,0 +1,3 @@ +#!/bin/bash +source userpass +curl --url "http://127.0.0.1:7783" --data "{\"userpass\":\"$userpass\",\"method\":\"tradesarray\",\"base\":\"REVS\",\"rel\":\"KMD\",\"timescale\":3600}" From 06e2d6e4085e51175216f85519dceb9307da8eac Mon Sep 17 00:00:00 2001 From: jl777 Date: Wed, 22 Nov 2017 14:23:24 +0400 Subject: [PATCH 1056/1664] Test --- iguana/exchanges/LP_commands.c | 26 +++++++++++++------------- 1 file changed, 13 insertions(+), 13 deletions(-) diff --git a/iguana/exchanges/LP_commands.c b/iguana/exchanges/LP_commands.c index 2f5754c51..2ac67780c 100644 --- a/iguana/exchanges/LP_commands.c +++ b/iguana/exchanges/LP_commands.c @@ -303,19 +303,6 @@ zeroconf_claim(address, expiration=0)\n\ return(clonestr("{\"error\":\"couldnt set autoprice\"}")); else return(clonestr("{\"result\":\"success\"}")); } - if ( IAMLP == 0 && LP_isdisabled(base,rel) != 0 ) - return(clonestr("{\"error\":\"at least one of coins disabled\"}")); - price = jdouble(argjson,"price"); - if ( strcmp(method,"setprice") == 0 ) - { - if ( LP_mypriceset(&changed,base,rel,price) < 0 ) - return(clonestr("{\"error\":\"couldnt set price\"}")); - //else if ( LP_mypriceset(&changed,rel,base,1./price) < 0 ) - // return(clonestr("{\"error\":\"couldnt set price\"}")); - else if ( jint(argjson,"broadcast") != 0 || jobj(argjson,"broadcast") == 0 ) - return(LP_pricepings(ctx,myipaddr,LP_mypubsock,base,rel,price * LP_profitratio)); - else return(clonestr("{\"result\":\"success\"}")); - } else if ( strcmp(method,"pricearray") == 0 ) { uint32_t firsttime; @@ -330,6 +317,19 @@ zeroconf_claim(address, expiration=0)\n\ { return(jprint(LP_tradesarray(base,rel,juint(argjson,"starttime"),juint(argjson,"endtime"),jint(argjson,"timescale")),1)); } + if ( IAMLP == 0 && LP_isdisabled(base,rel) != 0 ) + return(clonestr("{\"error\":\"at least one of coins disabled\"}")); + price = jdouble(argjson,"price"); + if ( strcmp(method,"setprice") == 0 ) + { + if ( LP_mypriceset(&changed,base,rel,price) < 0 ) + return(clonestr("{\"error\":\"couldnt set price\"}")); + //else if ( LP_mypriceset(&changed,rel,base,1./price) < 0 ) + // return(clonestr("{\"error\":\"couldnt set price\"}")); + else if ( jint(argjson,"broadcast") != 0 || jobj(argjson,"broadcast") == 0 ) + return(LP_pricepings(ctx,myipaddr,LP_mypubsock,base,rel,price * LP_profitratio)); + else return(clonestr("{\"result\":\"success\"}")); + } else if ( strcmp(method,"orderbook") == 0 ) return(LP_orderbook(base,rel,jint(argjson,"duration"))); else if ( strcmp(method,"myprice") == 0 ) From d6645349d01dc0ee2628b3f418f5a0f96949c1a7 Mon Sep 17 00:00:00 2001 From: jl777 Date: Wed, 22 Nov 2017 14:26:02 +0400 Subject: [PATCH 1057/1664] Test --- iguana/exchanges/LP_stats.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/iguana/exchanges/LP_stats.c b/iguana/exchanges/LP_stats.c index 5b666b875..1c3c6e165 100644 --- a/iguana/exchanges/LP_stats.c +++ b/iguana/exchanges/LP_stats.c @@ -484,11 +484,11 @@ cJSON *LP_tradesarray(char *base,char *rel,uint32_t starttime,uint32_t endtime,i for (i=0; i= starttime && timestamp <= endtime ) + if ( (timestamp= juint(item,"quotetime")) != 0 && timestamp >= starttime && timestamp <= endtime ) { bari = (timestamp - starttime) / timescale; LP_ohlc_update(&bars[bari],timestamp,jdouble(item,"basevol"),jdouble(item,"relvol")); - } + } else printf("skip.(%s)\n",jprint(item,0)); } } free_json(statsjson); From 4bafd114157e2f5fc8a1c1f87bea28078cd84681 Mon Sep 17 00:00:00 2001 From: jl777 Date: Wed, 22 Nov 2017 14:32:16 +0400 Subject: [PATCH 1058/1664] Test --- iguana/exchanges/LP_stats.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/iguana/exchanges/LP_stats.c b/iguana/exchanges/LP_stats.c index 1c3c6e165..d124c3894 100644 --- a/iguana/exchanges/LP_stats.c +++ b/iguana/exchanges/LP_stats.c @@ -460,6 +460,7 @@ void LP_ohlc_update(struct LP_ohlc *bar,uint32_t timestamp,double basevol,double bar->basesum += basevol; bar->relsum += relvol; bar->numtrades++; + printf("%d %.8f/%.8f -> %.8f\n",bar->numtrades,basevol,relvol,price); } } @@ -484,7 +485,7 @@ cJSON *LP_tradesarray(char *base,char *rel,uint32_t starttime,uint32_t endtime,i for (i=0; i= starttime && timestamp <= endtime ) + if ( (timestamp= juint(item,"timestamp")) != 0 && timestamp >= starttime && timestamp <= endtime ) { bari = (timestamp - starttime) / timescale; LP_ohlc_update(&bars[bari],timestamp,jdouble(item,"basevol"),jdouble(item,"relvol")); From 2e5ba93fe0ba7c9fb4ea0e747b2df4cf3205bf3f Mon Sep 17 00:00:00 2001 From: jl777 Date: Wed, 22 Nov 2017 14:36:40 +0400 Subject: [PATCH 1059/1664] Test --- iguana/exchanges/LP_stats.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/iguana/exchanges/LP_stats.c b/iguana/exchanges/LP_stats.c index d124c3894..ea2b0a1d5 100644 --- a/iguana/exchanges/LP_stats.c +++ b/iguana/exchanges/LP_stats.c @@ -433,6 +433,7 @@ cJSON *LP_ohlc_json(struct LP_ohlc *bar) jaddinum(item,bar->basesum); jaddinum(item,bar->relsum / bar->basesum); jaddinum(item,bar->numtrades); + return(item); } return(0); } @@ -460,7 +461,7 @@ void LP_ohlc_update(struct LP_ohlc *bar,uint32_t timestamp,double basevol,double bar->basesum += basevol; bar->relsum += relvol; bar->numtrades++; - printf("%d %.8f/%.8f -> %.8f\n",bar->numtrades,basevol,relvol,price); + //printf("%d %.8f/%.8f -> %.8f\n",bar->numtrades,basevol,relvol,price); } } From 3bd8c67f1f188ef10d1695f8bbaa09a806e18064 Mon Sep 17 00:00:00 2001 From: jl777 Date: Wed, 22 Nov 2017 14:40:47 +0400 Subject: [PATCH 1060/1664] Test --- iguana/exchanges/LP_stats.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/iguana/exchanges/LP_stats.c b/iguana/exchanges/LP_stats.c index ea2b0a1d5..6bcec142c 100644 --- a/iguana/exchanges/LP_stats.c +++ b/iguana/exchanges/LP_stats.c @@ -173,7 +173,7 @@ int32_t LP_swapstats_update(struct LP_swapstats *sp,struct LP_quoteinfo *qp,cJSO quoteid = juint(lineobj,"quoteid"); satoshis = jdouble(lineobj,"srcamount") * SATOSHIDEN; destsatoshis = jdouble(lineobj,"destamount") * SATOSHIDEN; - if ( base != 0 && strcmp(base,sp->Q.srccoin) == 0 && rel != 0 && strcmp(rel,sp->Q.destcoin) == 0 && requestid == sp->Q.R.requestid && quoteid == sp->Q.R.quoteid && ((satoshis+2*sp->Q.txfee)|1) == (sp->Q.satoshis|1) && ((destsatoshis+2*sp->Q.desttxfee)|1) == (sp->Q.destsatoshis|1) ) + if ( base != 0 && strcmp(base,sp->Q.srccoin) == 0 && rel != 0 && strcmp(rel,sp->Q.destcoin) == 0 && requestid == sp->Q.R.requestid && quoteid == sp->Q.R.quoteid && llabs((int64_t)(satoshis+2*sp->Q.txfee) - (int64_t)sp->Q.satoshis) <= sp->Q.txfee && llabs((int64_t)(destsatoshis+2*sp->Q.desttxfee) - (int64_t)sp->Q.destsatoshis) <= sp->Q.desttxfee ) { sp->bobdeposit = LP_swapstats_txid(lineobj,"bobdeposit",sp->bobdeposit); sp->alicepayment = LP_swapstats_txid(lineobj,"alicepayment",sp->alicepayment); From 6cad73a7209d98c0b11b6b9ebdd0a1db09235591 Mon Sep 17 00:00:00 2001 From: jl777 Date: Wed, 22 Nov 2017 15:35:01 +0400 Subject: [PATCH 1061/1664] Test --- iguana/exchanges/LP_RTmetrics.c | 6 +- iguana/exchanges/LP_nativeDEX.c | 2 +- iguana/exchanges/LP_ordermatch.c | 2 +- iguana/exchanges/LP_stats.c | 143 +++++++++++++++++++------------ iguana/exchanges/install | 2 +- 5 files changed, 93 insertions(+), 62 deletions(-) diff --git a/iguana/exchanges/LP_RTmetrics.c b/iguana/exchanges/LP_RTmetrics.c index b37fe0db5..7bbab1c38 100644 --- a/iguana/exchanges/LP_RTmetrics.c +++ b/iguana/exchanges/LP_RTmetrics.c @@ -149,7 +149,7 @@ void LP_RTmetrics_swapsinfo(char *refbase,char *refrel,cJSON *swaps,int32_t nums } } -void LP_RTmetrics_init() +/*void LP_RTmetrics_init() { struct LP_pubkey_info *pubp,*tmp; uint32_t futuretime; int32_t i,numswaps; bits256 pubkey,zero; cJSON *statsjson,*swaps; memset(&LP_RTmetrics,0,sizeof(LP_RTmetrics)); @@ -188,7 +188,9 @@ void LP_RTmetrics_init() } } //printf("%d pubkeys have pending swaps, whitelist.%d blacklist.%d avoidtxids.%d\n",LP_RTmetrics.numpendings,LP_RTmetrics.numwhitelist,LP_RTmetrics.numblacklist,LP_RTmetrics.numavoidtxids); -} +}*/ + + double _LP_RTmetric_calc(struct LP_metricinfo *mp,double bestprice,double maxprice,double relvolume) { diff --git a/iguana/exchanges/LP_nativeDEX.c b/iguana/exchanges/LP_nativeDEX.c index c656e5513..a4b6db24d 100644 --- a/iguana/exchanges/LP_nativeDEX.c +++ b/iguana/exchanges/LP_nativeDEX.c @@ -104,7 +104,7 @@ struct LP_address_utxo *LP_garbage_collector2; //uint32_t LP_deadman_switch; uint16_t LP_fixed_pairport,LP_publicport; -uint32_t LP_lastnonce,LP_counter,LP_swap_endcritical,LP_swap_critical; +uint32_t LP_lastnonce,LP_counter,LP_swap_endcritical,LP_swap_critical,LP_RTcount,LP_swapscount; int32_t LP_mybussock = -1; int32_t LP_mypubsock = -1; int32_t LP_mypullsock = -1; diff --git a/iguana/exchanges/LP_ordermatch.c b/iguana/exchanges/LP_ordermatch.c index a05bfe7b4..0f6b4a879 100644 --- a/iguana/exchanges/LP_ordermatch.c +++ b/iguana/exchanges/LP_ordermatch.c @@ -787,7 +787,7 @@ int32_t LP_tradecommand(void *ctx,char *myipaddr,int32_t pubsock,cJSON *argjson, LP_quoteparse(&Q,argjson); LP_requestinit(&Q.R,Q.srchash,Q.desthash,Q.srccoin,Q.satoshis-Q.txfee,Q.destcoin,Q.destsatoshis-Q.desttxfee,Q.timestamp,Q.quotetime,DEXselector); LP_tradecommand_log(argjson); - printf("(%-10u %10u) %12s aliceid.%22llu %5s/%-5s %12.8f -> %12.8f price %12.8f\n",Q.R.requestid,Q.R.quoteid,method,(long long)Q.aliceid,Q.srccoin,Q.destcoin,dstr(Q.satoshis),dstr(Q.destsatoshis),(double)Q.destsatoshis/Q.satoshis); + printf("(%-10u %10u) %12s aliceid.%22llu %5s/%-5s %12.8f -> %12.8f price %12.8f | RT.%d %d\n",Q.R.requestid,Q.R.quoteid,method,(long long)Q.aliceid,Q.srccoin,Q.destcoin,dstr(Q.satoshis),dstr(Q.destsatoshis),(double)Q.destsatoshis/Q.satoshis,LP_RTcount,LP_swapscount); retval = 1; autxo = &A; butxo = &B; diff --git a/iguana/exchanges/LP_stats.c b/iguana/exchanges/LP_stats.c index 6bcec142c..9b50f29f9 100644 --- a/iguana/exchanges/LP_stats.c +++ b/iguana/exchanges/LP_stats.c @@ -20,7 +20,7 @@ #define LP_STATSLOG_FNAME "stats.log" -struct LP_swapstats *LP_swapstats; +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" }; @@ -114,18 +114,22 @@ int32_t LP_statslog_parse() struct LP_swapstats *LP_swapstats_find(uint64_t aliceid) { struct LP_swapstats *sp; - HASH_FIND(hh,LP_swapstats,&aliceid,sizeof(aliceid),sp); + HASH_FIND(hh,LP_RTstats,&aliceid,sizeof(aliceid),sp); + if ( sp == 0 ) + HASH_FIND(hh,LP_swapstats,&aliceid,sizeof(aliceid),sp); return(sp); } -struct LP_swapstats *LP_swapstats_add(uint64_t aliceid) +struct LP_swapstats *LP_swapstats_add(uint64_t aliceid,int32_t RTflag) { struct LP_swapstats *sp; if ( (sp= LP_swapstats_find(aliceid)) == 0 ) { sp = calloc(1,sizeof(*sp)); sp->aliceid = aliceid; - HASH_ADD(hh,LP_swapstats,aliceid,sizeof(aliceid),sp); + if ( RTflag != 0 ) + HASH_ADD(hh,LP_RTstats,aliceid,sizeof(aliceid),sp); + else HASH_ADD(hh,LP_swapstats,aliceid,sizeof(aliceid),sp); } return(LP_swapstats_find(aliceid)); } @@ -206,7 +210,7 @@ int32_t LP_swapstats_update(struct LP_swapstats *sp,struct LP_quoteinfo *qp,cJSO 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,flag,numtrades[LP_MAXPRICEINFOS],methodind,destvout,feevout,duplicate=0; char *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; 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]; memset(numtrades,0,sizeof(numtrades)); memset(basevols,0,sizeof(basevols)); memset(relvols,0,sizeof(relvols)); @@ -274,6 +278,9 @@ int32_t LP_statslog_parsequote(char *method,cJSON *lineobj) destvout = jint(lineobj,"destvout"); feetxid = jbits256(lineobj,"feetxid"); feevout = jint(lineobj,"feevout"); + if ( (statusstr= jstr(lineobj,"status")) != 0 && strcmp(statusstr,"finished") == 0 ) + RTflag = 0; + else RTflag = 1; qprice = ((double)destsatoshis / (satoshis - txfee)); //printf("%s/v%d %s/v%d\n",bits256_str(str,desttxid),destvout,bits256_str(str2,feetxid),feevout); aliceid = LP_aliceid_calc(desttxid,destvout,feetxid,feevout); @@ -289,7 +296,7 @@ int32_t LP_statslog_parsequote(char *method,cJSON *lineobj) } else { - if ( (sp= LP_swapstats_add(aliceid)) != 0 ) + if ( (sp= LP_swapstats_add(aliceid,RTflag)) != 0 ) { sp->Q = Q; sp->qprice = qprice; @@ -297,17 +304,20 @@ int32_t LP_statslog_parsequote(char *method,cJSON *lineobj) sp->ind = LP_aliceids++; strcpy(sp->bobgui,"nogui"); strcpy(sp->alicegui,"nogui"); - if ( (pubp= LP_pubkeyadd(sp->Q.srchash)) != 0 ) + if ( sp->finished == 0 && sp->expired == 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); + 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); + } } //LP_swapstats_line(numtrades,basevols,relvols,line,sp); //printf("%s\n",line); @@ -326,9 +336,57 @@ int32_t LP_statslog_parsequote(char *method,cJSON *lineobj) return(duplicate == 0); } +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) +{ + int32_t dispflag,retval = 0; cJSON *item; + 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 ) + retval = 1; + dispflag = 0; + if ( starttime == 0 && endtime == 0 ) + dispflag = 1; + else if ( starttime > time(NULL) && endtime == starttime && sp->finished == 0 && sp->expired == 0 ) + dispflag = 1; + else if ( sp->Q.timestamp >= starttime && sp->Q.timestamp <= endtime ) + dispflag = 1; + if ( refbase != 0 && strcmp(refbase,sp->Q.srccoin) != 0 && strcmp(refbase,sp->Q.destcoin) != 0 ) + dispflag = 0; + if ( refrel != 0 && strcmp(refrel,sp->Q.srccoin) != 0 && strcmp(refrel,sp->Q.destcoin) != 0 ) + dispflag = 0; + if ( dispflag != 0 ) + { + dispflag = 0; + if ( refgui == 0 || refgui[0] == 0 || strcmp(refgui,sp->bobgui) == 0 || strcmp(refgui,sp->alicegui) == 0 ) + { + if ( bits256_nonz(refpubkey) == 0 || bits256_cmp(refpubkey,sp->Q.srchash) == 0 || bits256_cmp(refpubkey,sp->Q.desthash) == 0 ) + dispflag = 1; + } + } + if ( dispflag != 0 ) + { + //LP_swapstats_line(numtrades,basevols,relvols,line,sp); + item = cJSON_CreateObject(); + jaddnum(item,"timestamp",sp->Q.timestamp); + jadd64bits(item,"aliceid",sp->aliceid); + jaddbits256(item,"src",sp->Q.srchash); + jaddstr(item,"base",sp->Q.srccoin); + jaddnum(item,"basevol",dstr(sp->Q.satoshis)); + jaddbits256(item,"dest",sp->Q.desthash); + jaddstr(item,"rel",sp->Q.destcoin); + jaddnum(item,"relvol",dstr(sp->Q.destsatoshis)); + jaddnum(item,"price",sp->qprice); + jaddnum(item,"requestid",sp->Q.R.requestid); + jaddnum(item,"quoteid",sp->Q.R.quoteid); + //jaddstr(item,"line",line); + jaddi(array,item); + } + return(retval); +} + cJSON *LP_statslog_disp(uint32_t starttime,uint32_t endtime,char *refgui,bits256 refpubkey,char *refbase,char *refrel) { - cJSON *retjson,*array,*item; struct LP_swapstats *sp,*tmp; int32_t i,n,dispflag,numtrades[LP_MAXPRICEINFOS]; uint64_t basevols[LP_MAXPRICEINFOS],relvols[LP_MAXPRICEINFOS]; + cJSON *retjson,*array,*item; struct LP_swapstats *sp,*tmp; int32_t i,n,numtrades[LP_MAXPRICEINFOS]; uint64_t basevols[LP_MAXPRICEINFOS],relvols[LP_MAXPRICEINFOS]; if ( starttime > endtime ) starttime = endtime; n = LP_statslog_parse(); @@ -339,48 +397,19 @@ cJSON *LP_statslog_disp(uint32_t starttime,uint32_t endtime,char *refgui,bits256 jaddstr(retjson,"result","success"); jaddnum(retjson,"newlines",n); array = cJSON_CreateArray(); - HASH_ITER(hh,LP_swapstats,sp,tmp) + LP_RTcount = LP_swapscount = 0; + HASH_ITER(hh,LP_RTstats,sp,tmp) { - if ( sp->finished == 0 && time(NULL) > sp->Q.timestamp+LP_atomic_locktime(sp->Q.srccoin,sp->Q.destcoin)*2 ) - sp->expired = (uint32_t)time(NULL); - dispflag = 0; - if ( starttime == 0 && endtime == 0 ) - dispflag = 1; - else if ( starttime > time(NULL) && endtime == starttime && sp->finished == 0 && sp->expired == 0 ) - dispflag = 1; - else if ( sp->Q.timestamp >= starttime && sp->Q.timestamp <= endtime ) - dispflag = 1; - if ( refbase != 0 && strcmp(refbase,sp->Q.srccoin) != 0 && strcmp(refbase,sp->Q.destcoin) != 0 ) - dispflag = 0; - if ( refrel != 0 && strcmp(refrel,sp->Q.srccoin) != 0 && strcmp(refrel,sp->Q.destcoin) != 0 ) - dispflag = 0; - if ( dispflag != 0 ) - { - dispflag = 0; - if ( refgui == 0 || refgui[0] == 0 || strcmp(refgui,sp->bobgui) == 0 || strcmp(refgui,sp->alicegui) == 0 ) - { - if ( bits256_nonz(refpubkey) == 0 || bits256_cmp(refpubkey,sp->Q.srchash) == 0 || bits256_cmp(refpubkey,sp->Q.desthash) == 0 ) - dispflag = 1; - } - } - if ( dispflag != 0 ) + if ( LP_stats_dispiter(array,sp,starttime,endtime,refbase,refrel,refgui,refpubkey) > 0 ) { - //LP_swapstats_line(numtrades,basevols,relvols,line,sp); - item = cJSON_CreateObject(); - jaddnum(item,"timestamp",sp->Q.timestamp); - jadd64bits(item,"aliceid",sp->aliceid); - jaddbits256(item,"src",sp->Q.srchash); - jaddstr(item,"base",sp->Q.srccoin); - jaddnum(item,"basevol",dstr(sp->Q.satoshis)); - jaddbits256(item,"dest",sp->Q.desthash); - jaddstr(item,"rel",sp->Q.destcoin); - jaddnum(item,"relvol",dstr(sp->Q.destsatoshis)); - jaddnum(item,"price",sp->qprice); - jaddnum(item,"requestid",sp->Q.R.requestid); - jaddnum(item,"quoteid",sp->Q.R.quoteid); - //jaddstr(item,"line",line); - jaddi(array,item); - } + HASH_DELETE(hh,LP_RTstats,sp); + HASH_ADD(hh,LP_swapstats,aliceid,sizeof(sp->aliceid),sp); + } else LP_RTcount++; + } + HASH_ITER(hh,LP_swapstats,sp,tmp) + { + LP_stats_dispiter(array,sp,starttime,endtime,refbase,refrel,refgui,refpubkey); + LP_swapscount++; } jadd(retjson,"swaps",array); array = cJSON_CreateArray(); diff --git a/iguana/exchanges/install b/iguana/exchanges/install index a6c29cfea..d01b5dd4a 100755 --- a/iguana/exchanges/install +++ b/iguana/exchanges/install @@ -1,5 +1,5 @@ #!/bin/bash -cp claim deposit invreset sendrawtransaction processfiles stop millis mnzservers bot_buy bot_list bot_statuslist bot_pause bot_resume bot_sell bot_settings bot_status bot_stop guistats pubkeystats pendings coinswaps baserelswaps setpassphrase notarizations getrawtransaction parselog statsdisp m_js 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 tradesarray claim deposit invreset sendrawtransaction processfiles stop millis mnzservers bot_buy bot_list bot_statuslist bot_pause bot_resume bot_sell bot_settings bot_status bot_stop guistats pubkeystats pendings coinswaps baserelswaps setpassphrase notarizations getrawtransaction parselog statsdisp m_js 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 . From a1362146a07a656d58ad9f29d0f35167621e4f83 Mon Sep 17 00:00:00 2001 From: jl777 Date: Wed, 22 Nov 2017 15:42:20 +0400 Subject: [PATCH 1062/1664] Test --- iguana/exchanges/LP_nativeDEX.c | 10 ++++++++-- iguana/exchanges/LP_stats.c | 2 +- 2 files changed, 9 insertions(+), 3 deletions(-) diff --git a/iguana/exchanges/LP_nativeDEX.c b/iguana/exchanges/LP_nativeDEX.c index a4b6db24d..3a6f71700 100644 --- a/iguana/exchanges/LP_nativeDEX.c +++ b/iguana/exchanges/LP_nativeDEX.c @@ -196,7 +196,7 @@ char *blocktrail_listtransactions(char *symbol,char *coinaddr,int32_t num,int32_ char *LP_command_process(void *ctx,char *myipaddr,int32_t pubsock,cJSON *argjson,uint8_t *data,int32_t datalen) { - char *retstr=0; + char *retstr=0; cJSON *retjson; bits256 zero; if ( jobj(argjson,"result") != 0 || jobj(argjson,"error") != 0 ) return(0); if ( LP_tradecommand(ctx,myipaddr,pubsock,argjson,data,datalen) <= 0 ) @@ -207,7 +207,13 @@ char *LP_command_process(void *ctx,char *myipaddr,int32_t pubsock,cJSON *argjson //if ( pubsock >= 0 ) //strncmp("{\"error\":",retstr,strlen("{\"error\":")) != 0 && //LP_send(pubsock,retstr,(int32_t)strlen(retstr)+1,0); } - } else LP_statslog_parse(); + } + else if ( LP_statslog_parse() > 0 ) + { + memset(zero.bytes,0,sizeof(zero)); + if ( (retjson= LP_statslog_disp(2000000000,2000000000,"",zero,0,0))) // pending swaps + free_json(retjson); + } return(retstr); } diff --git a/iguana/exchanges/LP_stats.c b/iguana/exchanges/LP_stats.c index 9b50f29f9..39f127548 100644 --- a/iguana/exchanges/LP_stats.c +++ b/iguana/exchanges/LP_stats.c @@ -502,7 +502,7 @@ cJSON *LP_tradesarray(char *base,char *rel,uint32_t starttime,uint32_t endtime,i memset(zero.bytes,0,sizeof(zero)); if ( endtime == 0 ) endtime = (((uint32_t)time(NULL) / timescale) * timescale); - if ( starttime == 0 ) + if ( starttime == 0 || starttime >= endtime ) starttime = (endtime - LP_SCREENWIDTH*timescale); numbars = ((endtime - starttime) / timescale) + 1; bars = calloc(numbars,sizeof(*bars)); From 9c428a2172dcced7243e961ae4114f80523d49ae Mon Sep 17 00:00:00 2001 From: jl777 Date: Wed, 22 Nov 2017 15:45:23 +0400 Subject: [PATCH 1063/1664] Test --- iguana/exchanges/LP_stats.c | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/iguana/exchanges/LP_stats.c b/iguana/exchanges/LP_stats.c index 39f127548..a02a14b02 100644 --- a/iguana/exchanges/LP_stats.c +++ b/iguana/exchanges/LP_stats.c @@ -306,6 +306,7 @@ int32_t LP_statslog_parsequote(char *method,cJSON *lineobj) strcpy(sp->alicegui,"nogui"); if ( sp->finished == 0 && sp->expired == 0 ) { + printf("add RT\n"); if ( (pubp= LP_pubkeyadd(sp->Q.srchash)) != 0 ) { ptr = calloc(1,sizeof(*ptr)); @@ -318,7 +319,7 @@ int32_t LP_statslog_parsequote(char *method,cJSON *lineobj) ptr->swap = sp; DL_APPEND(pubp->aliceswaps,ptr); } - } + } else printf("add completed\n"); //LP_swapstats_line(numtrades,basevols,relvols,line,sp); //printf("%s\n",line); } else printf("unexpected LP_swapstats_add failure\n"); @@ -411,7 +412,10 @@ cJSON *LP_statslog_disp(uint32_t starttime,uint32_t endtime,char *refgui,bits256 LP_stats_dispiter(array,sp,starttime,endtime,refbase,refrel,refgui,refpubkey); LP_swapscount++; } + printf("RT.%d completed.%d\n",LP_RTcount,LP_swapscount); jadd(retjson,"swaps",array); + jaddnum(retjson,"RTcount",LP_RTcount); + jaddnum(retjson,"swapscount",LP_swapscount); array = cJSON_CreateArray(); for (i=0; i Date: Wed, 22 Nov 2017 15:47:12 +0400 Subject: [PATCH 1064/1664] Test --- iguana/exchanges/LP_stats.c | 7 ++----- 1 file changed, 2 insertions(+), 5 deletions(-) diff --git a/iguana/exchanges/LP_stats.c b/iguana/exchanges/LP_stats.c index a02a14b02..24a9cf31c 100644 --- a/iguana/exchanges/LP_stats.c +++ b/iguana/exchanges/LP_stats.c @@ -306,7 +306,6 @@ int32_t LP_statslog_parsequote(char *method,cJSON *lineobj) strcpy(sp->alicegui,"nogui"); if ( sp->finished == 0 && sp->expired == 0 ) { - printf("add RT\n"); if ( (pubp= LP_pubkeyadd(sp->Q.srchash)) != 0 ) { ptr = calloc(1,sizeof(*ptr)); @@ -319,9 +318,7 @@ int32_t LP_statslog_parsequote(char *method,cJSON *lineobj) ptr->swap = sp; DL_APPEND(pubp->aliceswaps,ptr); } - } else printf("add completed\n"); - //LP_swapstats_line(numtrades,basevols,relvols,line,sp); - //printf("%s\n",line); + } } else printf("unexpected LP_swapstats_add failure\n"); } if ( sp != 0 ) @@ -412,7 +409,7 @@ cJSON *LP_statslog_disp(uint32_t starttime,uint32_t endtime,char *refgui,bits256 LP_stats_dispiter(array,sp,starttime,endtime,refbase,refrel,refgui,refpubkey); LP_swapscount++; } - printf("RT.%d completed.%d\n",LP_RTcount,LP_swapscount); + //printf("RT.%d completed.%d\n",LP_RTcount,LP_swapscount); jadd(retjson,"swaps",array); jaddnum(retjson,"RTcount",LP_RTcount); jaddnum(retjson,"swapscount",LP_swapscount); From d96814434af858d4527312bf5a4bf44578137b6f Mon Sep 17 00:00:00 2001 From: jl777 Date: Wed, 22 Nov 2017 15:58:15 +0400 Subject: [PATCH 1065/1664] Test --- iguana/exchanges/LP_commands.c | 7 +++++++ iguana/exchanges/LP_nativeDEX.c | 3 ++- iguana/exchanges/LP_stats.c | 2 ++ 3 files changed, 11 insertions(+), 1 deletion(-) diff --git a/iguana/exchanges/LP_commands.c b/iguana/exchanges/LP_commands.c index 2ac67780c..077fb3753 100644 --- a/iguana/exchanges/LP_commands.c +++ b/iguana/exchanges/LP_commands.c @@ -596,8 +596,15 @@ zeroconf_claim(address, expiration=0)\n\ else if ( strcmp(method,"tradestatus") == 0 ) { + bits256 zero; cJSON *tmpjson; LP_tradecommand_log(argjson); printf("GOT TRADESTATUS! %s\n",jprint(argjson,0)); + if ( LP_statslog_parse() > 0 ) + { + memset(zero.bytes,0,sizeof(zero)); + if ( (tmpjson= LP_statslog_disp(2000000000,2000000000,"",zero,0,0))) // pending swaps + free_json(tmpjson); + } retstr = clonestr("{\"result\":\"success\"}"); } else if ( strcmp(method,"wantnotify") == 0 ) diff --git a/iguana/exchanges/LP_nativeDEX.c b/iguana/exchanges/LP_nativeDEX.c index 3a6f71700..e851db8ed 100644 --- a/iguana/exchanges/LP_nativeDEX.c +++ b/iguana/exchanges/LP_nativeDEX.c @@ -90,7 +90,7 @@ void LP_millistats_update(struct LP_millistats *mp) } #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,LP_reservedmutex,LP_nanorecvsmutex,LP_tradebotsmutex,LP_gcmutex,LP_inusemutex,LP_cJSONmutex; +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,LP_tradebotsmutex,LP_gcmutex,LP_inusemutex,LP_cJSONmutex,LP_logmutex; int32_t LP_canbind; char *Broadcaststr,*Reserved_msgs[2][1000]; int32_t num_Reserved_msgs[2],max_Reserved_msgs[2]; @@ -1103,6 +1103,7 @@ void LPinit(uint16_t myport,uint16_t mypullport,uint16_t mypubport,uint16_t mybu portable_mutex_init(&LP_nanorecvsmutex); portable_mutex_init(&LP_tradebotsmutex); portable_mutex_init(&LP_cJSONmutex); + portable_mutex_init(&LP_logmutex); myipaddr = clonestr("127.0.0.1"); #ifndef _WIN32 #ifndef FROM_JS diff --git a/iguana/exchanges/LP_stats.c b/iguana/exchanges/LP_stats.c index 24a9cf31c..94effcc7c 100644 --- a/iguana/exchanges/LP_stats.c +++ b/iguana/exchanges/LP_stats.c @@ -30,6 +30,7 @@ static uint32_t LP_requests,LP_reserveds,LP_connects,LP_connecteds,LP_tradestatu void LP_tradecommand_log(cJSON *argjson) { static FILE *logfp; char *jsonstr; + portable_mutex_lock(&LP_logmutex); if ( logfp == 0 ) { if ( (logfp= fopen(LP_STATSLOG_FNAME,"rb+")) != 0 ) @@ -43,6 +44,7 @@ void LP_tradecommand_log(cJSON *argjson) free(jsonstr); fflush(logfp); } + portable_mutex_unlock(&LP_logmutex); } void LP_statslog_parseline(cJSON *lineobj) From 2ca8f8c5798b4a1e2a1c1e54a5b89fb810926f52 Mon Sep 17 00:00:00 2001 From: jl777 Date: Wed, 22 Nov 2017 16:10:00 +0400 Subject: [PATCH 1066/1664] Test --- iguana/exchanges/LP_nativeDEX.c | 4 ++-- iguana/exchanges/LP_remember.c | 2 ++ 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/iguana/exchanges/LP_nativeDEX.c b/iguana/exchanges/LP_nativeDEX.c index e851db8ed..4deb11744 100644 --- a/iguana/exchanges/LP_nativeDEX.c +++ b/iguana/exchanges/LP_nativeDEX.c @@ -323,8 +323,8 @@ char *LP_process_message(void *ctx,char *typestr,char *myipaddr,int32_t pubsock, else { memset(zero.bytes,0,sizeof(zero)); - /*if ( (method= jstr(reqjson,"method")) != 0 && (strcmp(method,"request") == 0 || strcmp(method,"requested") == 0 || strcmp(method,"connect") == 0 || strcmp(method,"connected") == 0) ) - printf("broadcast.(%s)\n",Broadcaststr);*/ + if ( (method= jstr(reqjson,"method")) != 0 && (strcmp(method,"tradestatus") == 0) ) + printf("broadcast.(%s)\n",Broadcaststr); LP_reserved_msg(0,"","",zero,jprint(reqjson,0)); } retstr = clonestr("{\"result\":\"success\"}"); diff --git a/iguana/exchanges/LP_remember.c b/iguana/exchanges/LP_remember.c index 3e95fc0e9..5d4f33b2c 100644 --- a/iguana/exchanges/LP_remember.c +++ b/iguana/exchanges/LP_remember.c @@ -1143,6 +1143,8 @@ cJSON *basilisk_remember(int64_t *KMDtotals,int64_t *BTCtotals,uint32_t requesti jaddstr(item,"method","tradestatus"); jaddnum(item,"finishtime",rswap.finishtime); jaddstr(item,"gui",G.gui); + //jaddbits256(item,"srchash",rswap.Q.srchash); + //jaddbits256(item,"desthash",rswap.desthash); itemstr = jprint(item,0); fprintf(fp,"%s\n",itemstr); LP_tradecommand_log(item); From 070202fca9d0d06d4016add95aaa760df9339cb5 Mon Sep 17 00:00:00 2001 From: jl777 Date: Wed, 22 Nov 2017 16:18:07 +0400 Subject: [PATCH 1067/1664] Test --- iguana/exchanges/LP_nativeDEX.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/iguana/exchanges/LP_nativeDEX.c b/iguana/exchanges/LP_nativeDEX.c index 4deb11744..f3552ac85 100644 --- a/iguana/exchanges/LP_nativeDEX.c +++ b/iguana/exchanges/LP_nativeDEX.c @@ -323,7 +323,7 @@ char *LP_process_message(void *ctx,char *typestr,char *myipaddr,int32_t pubsock, else { memset(zero.bytes,0,sizeof(zero)); - if ( (method= jstr(reqjson,"method")) != 0 && (strcmp(method,"tradestatus") == 0) ) + if ( 0 && (method= jstr(reqjson,"method")) != 0 && (strcmp(method,"tradestatus") == 0) ) printf("broadcast.(%s)\n",Broadcaststr); LP_reserved_msg(0,"","",zero,jprint(reqjson,0)); } From 25c1c038b87ab4da61e717aa0dc9be2a131ee283 Mon Sep 17 00:00:00 2001 From: jl777 Date: Wed, 22 Nov 2017 16:45:55 +0400 Subject: [PATCH 1068/1664] Test --- iguana/exchanges/LP_commands.c | 9 ++++- iguana/exchanges/LP_stats.c | 72 +++++++++++++++++++++++++--------- 2 files changed, 62 insertions(+), 19 deletions(-) diff --git a/iguana/exchanges/LP_commands.c b/iguana/exchanges/LP_commands.c index 077fb3753..de9e7740e 100644 --- a/iguana/exchanges/LP_commands.c +++ b/iguana/exchanges/LP_commands.c @@ -568,8 +568,15 @@ zeroconf_claim(address, expiration=0)\n\ argjson = reqjson; } } + else + { + if ( strcmp(method,"gettradestatus") == 0 ) + return(LP_gettradestatus(j64bits(argjson,"aliceid"))); + } // received response - if ( strcmp(method,"postprice") == 0 ) + if ( strcmp(method,"swapstatus") == 0 ) + return(LP_swapstatus_recv(argjson)); + else if ( strcmp(method,"postprice") == 0 ) return(LP_postprice_recv(argjson)); else if ( strcmp(method,"postutxos") == 0 ) return(LP_postutxos_recv(argjson)); diff --git a/iguana/exchanges/LP_stats.c b/iguana/exchanges/LP_stats.c index 94effcc7c..61d63942b 100644 --- a/iguana/exchanges/LP_stats.c +++ b/iguana/exchanges/LP_stats.c @@ -336,9 +336,61 @@ int32_t LP_statslog_parsequote(char *method,cJSON *lineobj) return(duplicate == 0); } +cJSON *LP_swapstats_json(struct LP_swapstats *sp) +{ + cJSON *item = cJSON_CreateObject(); + jaddnum(item,"timestamp",sp->Q.timestamp); + jadd64bits(item,"aliceid",sp->aliceid); + jaddbits256(item,"src",sp->Q.srchash); + jaddstr(item,"base",sp->Q.srccoin); + jaddnum(item,"basevol",dstr(sp->Q.satoshis)); + jaddbits256(item,"dest",sp->Q.desthash); + jaddstr(item,"rel",sp->Q.destcoin); + jaddnum(item,"relvol",dstr(sp->Q.destsatoshis)); + jaddnum(item,"price",sp->qprice); + jaddnum(item,"requestid",sp->Q.R.requestid); + jaddnum(item,"quoteid",sp->Q.R.quoteid); + jaddnum(item,"finished",sp->finished); + jaddnum(item,"expired",sp->expired); + jaddnum(item,"ind",sp->methodind); + //jaddstr(item,"line",line); + return(item); +} + +char *LP_swapstatus_recv(cJSON *argjson) +{ + struct LP_swapstats *sp; int32_t methodind; + if ( (sp= LP_swapstats_find(j64bits(argjson,"aliceid"))) != 0 ) + { + if ( (methodind= jint(argjson,"ind")) > sp->methodind && methodind < sizeof(LP_stats_methods)/sizeof(*LP_stats_methods) ) + { + sp->methodind = methodind; + sp->finished = juint(argjson,"finished"); + sp->expired = juint(argjson,"expired"); + printf("SWAPSTATUS updated %llu %s %u %u\n",(long long)sp->aliceid,LP_stats_methods[sp->methodind],sp->finished,sp->expired); + } + } + return(clonestr("{\"result\":\"success\"}")); +} + +char *LP_gettradestatus(uint64_t aliceid) +{ + struct LP_swapstats *sp; cJSON *reqjson; bits256 zero; + if ( (sp= LP_swapstats_find(aliceid)) != 0 ) + { + 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)); + } + } + return(clonestr("{\"error\":\"cant find aliceid\"}")); +} + 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) { - int32_t dispflag,retval = 0; cJSON *item; + 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 ) @@ -364,23 +416,7 @@ int32_t LP_stats_dispiter(cJSON *array,struct LP_swapstats *sp,uint32_t starttim } } if ( dispflag != 0 ) - { - //LP_swapstats_line(numtrades,basevols,relvols,line,sp); - item = cJSON_CreateObject(); - jaddnum(item,"timestamp",sp->Q.timestamp); - jadd64bits(item,"aliceid",sp->aliceid); - jaddbits256(item,"src",sp->Q.srchash); - jaddstr(item,"base",sp->Q.srccoin); - jaddnum(item,"basevol",dstr(sp->Q.satoshis)); - jaddbits256(item,"dest",sp->Q.desthash); - jaddstr(item,"rel",sp->Q.destcoin); - jaddnum(item,"relvol",dstr(sp->Q.destsatoshis)); - jaddnum(item,"price",sp->qprice); - jaddnum(item,"requestid",sp->Q.R.requestid); - jaddnum(item,"quoteid",sp->Q.R.quoteid); - //jaddstr(item,"line",line); - jaddi(array,item); - } + jaddi(array,LP_swapstats_json(sp)); return(retval); } From c5a60493b41ffd9e4500bd885e159801d9b39161 Mon Sep 17 00:00:00 2001 From: jl777 Date: Wed, 22 Nov 2017 16:59:42 +0400 Subject: [PATCH 1069/1664] Gettradestatus --- iguana/exchanges/LP_include.h | 2 +- iguana/exchanges/LP_stats.c | 27 ++++++++++++++++++++++++--- 2 files changed, 25 insertions(+), 4 deletions(-) diff --git a/iguana/exchanges/LP_include.h b/iguana/exchanges/LP_include.h index d4a227a92..8eb56d467 100644 --- a/iguana/exchanges/LP_include.h +++ b/iguana/exchanges/LP_include.h @@ -385,7 +385,7 @@ struct LP_swapstats bits256 bobdeposit,alicepayment,bobpayment,paymentspent,Apaymentspent,depositspent; double qprice; uint64_t aliceid; - uint32_t ind,methodind,finished,expired; + uint32_t ind,methodind,finished,expired,lasttime; char alicegui[32],bobgui[32]; }; diff --git a/iguana/exchanges/LP_stats.c b/iguana/exchanges/LP_stats.c index 61d63942b..e539b5f9a 100644 --- a/iguana/exchanges/LP_stats.c +++ b/iguana/exchanges/LP_stats.c @@ -170,6 +170,7 @@ bits256 LP_swapstats_txid(cJSON *argjson,char *name,bits256 oldtxid) int32_t LP_swapstats_update(struct LP_swapstats *sp,struct LP_quoteinfo *qp,cJSON *lineobj) { char *statusstr,*base,*rel,gui[64]; uint32_t requestid,quoteid; uint64_t satoshis,destsatoshis; + sp->lasttime = (uint32_t)time(NULL); safecopy(gui,sp->Q.gui,sizeof(gui)); if ( strcmp(LP_stats_methods[sp->methodind],"tradestatus") == 0 ) { @@ -304,6 +305,7 @@ int32_t LP_statslog_parsequote(char *method,cJSON *lineobj) 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 ) @@ -360,8 +362,10 @@ 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 ) { + sp->lasttime = (uint32_t)time(NULL); if ( (methodind= jint(argjson,"ind")) > sp->methodind && methodind < sizeof(LP_stats_methods)/sizeof(*LP_stats_methods) ) { sp->methodind = methodind; @@ -376,7 +380,8 @@ char *LP_swapstatus_recv(cJSON *argjson) char *LP_gettradestatus(uint64_t aliceid) { struct LP_swapstats *sp; cJSON *reqjson; bits256 zero; - if ( (sp= LP_swapstats_find(aliceid)) != 0 ) + printf("gettradestatus.(%llu)\n",(long long)aliceid); + if ( (sp= LP_swapstats_find(aliceid)) != 0 && time(NULL) > sp->lasttime+60 ) { if ( (reqjson= LP_swapstats_json(sp)) != 0 ) { @@ -422,7 +427,10 @@ int32_t LP_stats_dispiter(cJSON *array,struct LP_swapstats *sp,uint32_t starttim cJSON *LP_statslog_disp(uint32_t starttime,uint32_t endtime,char *refgui,bits256 refpubkey,char *refbase,char *refrel) { - cJSON *retjson,*array,*item; struct LP_swapstats *sp,*tmp; int32_t i,n,numtrades[LP_MAXPRICEINFOS]; uint64_t basevols[LP_MAXPRICEINFOS],relvols[LP_MAXPRICEINFOS]; + static int32_t rval; + cJSON *retjson,*array,*item,*reqjson; bits256 zero; uint32_t now; struct LP_swapstats *sp,*tmp; int32_t i,n,numtrades[LP_MAXPRICEINFOS]; uint64_t basevols[LP_MAXPRICEINFOS],relvols[LP_MAXPRICEINFOS]; + if ( rval == 0 ) + rval = (LP_rand() % 300) + 60; if ( starttime > endtime ) starttime = endtime; n = LP_statslog_parse(); @@ -434,13 +442,26 @@ cJSON *LP_statslog_disp(uint32_t starttime,uint32_t endtime,char *refgui,bits256 jaddnum(retjson,"newlines",n); array = cJSON_CreateArray(); LP_RTcount = LP_swapscount = 0; + now = (uint32_t)time(NULL); HASH_ITER(hh,LP_RTstats,sp,tmp) { if ( LP_stats_dispiter(array,sp,starttime,endtime,refbase,refrel,refgui,refpubkey) > 0 ) { HASH_DELETE(hh,LP_RTstats,sp); HASH_ADD(hh,LP_swapstats,aliceid,sizeof(sp->aliceid),sp); - } else LP_RTcount++; + } + else + { + LP_RTcount++; + if ( now > sp->lasttime+rval ) + { + 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)); + } + } } HASH_ITER(hh,LP_swapstats,sp,tmp) { From 945b8db84cbc4184b9083740545729c528261d0a Mon Sep 17 00:00:00 2001 From: jl777 Date: Wed, 22 Nov 2017 17:09:27 +0400 Subject: [PATCH 1070/1664] Test --- iguana/exchanges/LP_commands.c | 2 ++ iguana/exchanges/LP_stats.c | 4 ++-- 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/iguana/exchanges/LP_commands.c b/iguana/exchanges/LP_commands.c index de9e7740e..2c698b013 100644 --- a/iguana/exchanges/LP_commands.c +++ b/iguana/exchanges/LP_commands.c @@ -567,6 +567,8 @@ zeroconf_claim(address, expiration=0)\n\ } argjson = reqjson; } + else if ( strcmp(method,"gettradestatus") == 0 ) + retstr = clonestr("{\"result\":\"success\"}"); } else { diff --git a/iguana/exchanges/LP_stats.c b/iguana/exchanges/LP_stats.c index e539b5f9a..19f528850 100644 --- a/iguana/exchanges/LP_stats.c +++ b/iguana/exchanges/LP_stats.c @@ -362,7 +362,7 @@ 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)); + //printf("swapstatus.(%s)\n",jprint(argjson,0)); if ( (sp= LP_swapstats_find(j64bits(argjson,"aliceid"))) != 0 ) { sp->lasttime = (uint32_t)time(NULL); @@ -380,7 +380,7 @@ char *LP_swapstatus_recv(cJSON *argjson) char *LP_gettradestatus(uint64_t aliceid) { struct LP_swapstats *sp; cJSON *reqjson; bits256 zero; - printf("gettradestatus.(%llu)\n",(long long)aliceid); + //printf("gettradestatus.(%llu)\n",(long long)aliceid); if ( (sp= LP_swapstats_find(aliceid)) != 0 && time(NULL) > sp->lasttime+60 ) { if ( (reqjson= LP_swapstats_json(sp)) != 0 ) From 5beb874534b33aaf3bda7902ca469d7ced3519e8 Mon Sep 17 00:00:00 2001 From: jl777 Date: Wed, 22 Nov 2017 17:12:00 +0400 Subject: [PATCH 1071/1664] Test --- iguana/exchanges/LP_commands.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/iguana/exchanges/LP_commands.c b/iguana/exchanges/LP_commands.c index 2c698b013..67ace1054 100644 --- a/iguana/exchanges/LP_commands.c +++ b/iguana/exchanges/LP_commands.c @@ -567,7 +567,7 @@ zeroconf_claim(address, expiration=0)\n\ } argjson = reqjson; } - else if ( strcmp(method,"gettradestatus") == 0 ) + if ( strcmp(method,"gettradestatus") == 0 ) retstr = clonestr("{\"result\":\"success\"}"); } else From b9effd027be5b5a6fdf98677633118f3e3b50280 Mon Sep 17 00:00:00 2001 From: jl777 Date: Wed, 22 Nov 2017 17:27:07 +0400 Subject: [PATCH 1072/1664] Test --- iguana/exchanges/LP_ordermatch.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/iguana/exchanges/LP_ordermatch.c b/iguana/exchanges/LP_ordermatch.c index 0f6b4a879..b4186e1b6 100644 --- a/iguana/exchanges/LP_ordermatch.c +++ b/iguana/exchanges/LP_ordermatch.c @@ -734,7 +734,7 @@ char *LP_bestfit(char *rel,double relvolume) 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(clonestr("{\"error\":\"cant find utxo that close enough in size\"}")); return(jprint(LP_utxojson(autxo),1)); } @@ -1152,7 +1152,7 @@ char *LP_autobuy(void *ctx,char *myipaddr,int32_t mypubsock,char *base,char *rel destsatoshis = SATOSHIDEN * relvolume; LP_address_utxo_reset(relcoin); if ( (autxo= LP_utxo_bestfit(rel,destsatoshis + 2*desttxfee)) == 0 ) - return(clonestr("{\"error\":\"cant find alice utxo that is big enough\"}")); + 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->S.satoshis)); if ( destsatoshis - desttxfee < autxo->S.satoshis ) { From 249bf2f0dba9ac9355398e96c9345978073fbfc2 Mon Sep 17 00:00:00 2001 From: jl777 Date: Wed, 22 Nov 2017 17:27:47 +0400 Subject: [PATCH 1073/1664] Test --- iguana/exchanges/LP_ordermatch.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/iguana/exchanges/LP_ordermatch.c b/iguana/exchanges/LP_ordermatch.c index b4186e1b6..6266fb2bb 100644 --- a/iguana/exchanges/LP_ordermatch.c +++ b/iguana/exchanges/LP_ordermatch.c @@ -734,7 +734,7 @@ char *LP_bestfit(char *rel,double relvolume) 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 close enough in size\"}")); + return(clonestr("{\"error\":\"cant find utxo that is close enough in size\"}")); return(jprint(LP_utxojson(autxo),1)); } From 76c956508d483a5d7a1777980153d2633d71e456 Mon Sep 17 00:00:00 2001 From: jl777 Date: Wed, 22 Nov 2017 17:41:37 +0400 Subject: [PATCH 1074/1664] Test --- iguana/exchanges/LP_zeroconf.c | 1 + 1 file changed, 1 insertion(+) diff --git a/iguana/exchanges/LP_zeroconf.c b/iguana/exchanges/LP_zeroconf.c index 4e2fe899d..28f1485ec 100644 --- a/iguana/exchanges/LP_zeroconf.c +++ b/iguana/exchanges/LP_zeroconf.c @@ -190,6 +190,7 @@ void LP_zeroconf_deposits(struct iguana_info *coin) { item = jitem(array,i); amount64 = LP_listunspent_parseitem(coin,&txid,&vout,&height,item); + printf("amount64 %.8f vout.%d (%s)\n",dstr(amount64),vout,jprint(item,0)); if ( vout == 1 ) { weeki = (amount64 % 10000); From ea5555ac769b697a48824777c1b35921ca70f247 Mon Sep 17 00:00:00 2001 From: jl777 Date: Wed, 22 Nov 2017 17:45:58 +0400 Subject: [PATCH 1075/1664] Test --- iguana/exchanges/LP_zeroconf.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/iguana/exchanges/LP_zeroconf.c b/iguana/exchanges/LP_zeroconf.c index 28f1485ec..05c853929 100644 --- a/iguana/exchanges/LP_zeroconf.c +++ b/iguana/exchanges/LP_zeroconf.c @@ -195,7 +195,7 @@ void LP_zeroconf_deposits(struct iguana_info *coin) { weeki = (amount64 % 10000); timestamp = LP_FIRSTWEEKTIME + weeki*LP_WEEKMULT; - if ( weeki > 0 && (txjson= LP_gettx(coin->symbol,txid)) != 0 ) + if ( weeki >= 0 && (txjson= LP_gettx(coin->symbol,txid)) != 0 ) { if ( (vouts= jarray(&numvouts,txjson,"vout")) > 0 ) { @@ -205,6 +205,7 @@ void LP_zeroconf_deposits(struct iguana_info *coin) { if ( (scriptstr= jstr(sobj,"hex")) != 0 ) { + printf("amount64 %.8f vout.%d (%s) weeki.%d %.8f (%s)\n",dstr(amount64),vout,jprint(v,0),weeki,dstr(satoshis),scriptstr); len = (int32_t)strlen(scriptstr) >> 1; if ( len <= sizeof(spendscript)/sizeof(*spendscript) ) { From aaadf2ec337717d9ead05f272d91a843a67db2b8 Mon Sep 17 00:00:00 2001 From: jl777 Date: Wed, 22 Nov 2017 17:56:38 +0400 Subject: [PATCH 1076/1664] Test --- iguana/exchanges/LP_transaction.c | 8 +++++++- iguana/exchanges/LP_zeroconf.c | 3 +++ 2 files changed, 10 insertions(+), 1 deletion(-) diff --git a/iguana/exchanges/LP_transaction.c b/iguana/exchanges/LP_transaction.c index b6b5ce208..a739bf5dc 100644 --- a/iguana/exchanges/LP_transaction.c +++ b/iguana/exchanges/LP_transaction.c @@ -1231,7 +1231,7 @@ char *LP_createrawtransaction(cJSON **txobjp,int32_t *numvinsp,struct iguana_inf ignore_cltverr = 0; suppress_pubkeys = 1; - scriptlen = bitcoin_standardspend(script,0,G.LP_myrmd160); + scriptlen = bitcoin_pubkeyspend(script,0,G.LP_pubsecp); numvins = LP_vins_select(ctx,coin,&total,amount,V,utxos,numutxos,suppress_pubkeys,ignore_cltverr,privkey,privkeys,vins,script,scriptlen,utxotxid,utxovout,dustcombine); if ( numvins <= 0 || total < amount ) { @@ -1266,6 +1266,12 @@ char *LP_createrawtransaction(cJSON **txobjp,int32_t *numvinsp,struct iguana_inf if ( addrtype == coin->pubtype ) spendlen = bitcoin_standardspend(spendscript,0,rmd160); else spendlen = bitcoin_p2shspend(spendscript,0,rmd160); + if ( i == numvouts-1 && strcmp(coinaddr,coin->smartaddr) == 0 && change != 0 ) + { + printf("combine last vout %.8f with change %.8f\n",dstr(value+adjust),dstr(change)); + value += change; + change = 0; + } txobj = bitcoin_txoutput(txobj,spendscript,spendlen,value + adjust); } else diff --git a/iguana/exchanges/LP_zeroconf.c b/iguana/exchanges/LP_zeroconf.c index 05c853929..8ef280b1d 100644 --- a/iguana/exchanges/LP_zeroconf.c +++ b/iguana/exchanges/LP_zeroconf.c @@ -58,6 +58,9 @@ char *LP_zeroconf_deposit(struct iguana_info *coin,int32_t weeks,double amount,i amount64 = (amount64 / 10000) * 10000 + weeki; jaddnum(item,BOTS_BONDADDRESS,dstr(amount64)); jaddi(array,item); + item = cJSON_CreateObject(); + jaddnum(item,coin->smartaddr,0.0001); + jaddi(array,item); jadd(argjson,"outputs",array); printf("deposit.(%s)\n",jprint(argjson,0)); if ( (retstr= LP_withdraw(coin,argjson)) != 0 ) From 56239ad966ccd4a647eeef73ce961b42c0e5e72c Mon Sep 17 00:00:00 2001 From: jl777 Date: Wed, 22 Nov 2017 19:50:25 +0400 Subject: [PATCH 1077/1664] Test --- iguana/exchanges/LP_transaction.c | 2 +- iguana/exchanges/LP_zeroconf.c | 1 + 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/iguana/exchanges/LP_transaction.c b/iguana/exchanges/LP_transaction.c index a739bf5dc..15d14bb18 100644 --- a/iguana/exchanges/LP_transaction.c +++ b/iguana/exchanges/LP_transaction.c @@ -1231,7 +1231,7 @@ char *LP_createrawtransaction(cJSON **txobjp,int32_t *numvinsp,struct iguana_inf ignore_cltverr = 0; suppress_pubkeys = 1; - scriptlen = bitcoin_pubkeyspend(script,0,G.LP_pubsecp); + 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,utxotxid,utxovout,dustcombine); if ( numvins <= 0 || total < amount ) { diff --git a/iguana/exchanges/LP_zeroconf.c b/iguana/exchanges/LP_zeroconf.c index 8ef280b1d..c84279924 100644 --- a/iguana/exchanges/LP_zeroconf.c +++ b/iguana/exchanges/LP_zeroconf.c @@ -202,6 +202,7 @@ void LP_zeroconf_deposits(struct iguana_info *coin) { if ( (vouts= jarray(&numvouts,txjson,"vout")) > 0 ) { + // get pubkey from vout.2 v = jitem(vouts,0); satoshis = LP_value_extract(v,0); if ( (sobj= jobj(v,"scriptPubKey")) != 0 ) From 2d283af45c67095dad5473f3c7fda91a34ed783d Mon Sep 17 00:00:00 2001 From: jl777 Date: Wed, 22 Nov 2017 20:07:07 +0400 Subject: [PATCH 1078/1664] Test --- iguana/exchanges/LP_nativeDEX.c | 1 + iguana/exchanges/LP_zeroconf.c | 24 +++++++++++++++--------- 2 files changed, 16 insertions(+), 9 deletions(-) diff --git a/iguana/exchanges/LP_nativeDEX.c b/iguana/exchanges/LP_nativeDEX.c index f3552ac85..719b699e2 100644 --- a/iguana/exchanges/LP_nativeDEX.c +++ b/iguana/exchanges/LP_nativeDEX.c @@ -28,6 +28,7 @@ // MNZ getcoin strangeness // portfolio value based on ask? // listunspent triplicate +// disable basilisk // verify encrypted destpubkey, broadcast:0 setprice // improve critical section detection when parallel trades diff --git a/iguana/exchanges/LP_zeroconf.c b/iguana/exchanges/LP_zeroconf.c index c84279924..19016682b 100644 --- a/iguana/exchanges/LP_zeroconf.c +++ b/iguana/exchanges/LP_zeroconf.c @@ -154,7 +154,7 @@ char *LP_zeroconf_claim(struct iguana_info *coin,char *depositaddr,uint32_t expi { item = jitem(array,i); satoshis = LP_listunspent_parseitem(coin,&utxotxid,&utxovout,&height,item); - if ( (signedtx= basilisk_swap_bobtxspend(&signedtxid,0,"zeroconfclaim",coin->symbol,coin->wiftaddr,coin->taddr,coin->pubtype,coin->p2shtype,coin->isPoS,coin->wiftype,ctx,G.LP_privkey,0,redeemscript,redeemlen,userdata,userdatalen,utxotxid,utxovout,coin->smartaddr,G.LP_pubsecp,0xffffffff,0,&destamount,satoshis-coin->txfee,coin->smartaddr,vinaddr,0,coin->zcash)) != 0 ) + if ( (signedtx= basilisk_swap_bobtxspend(&signedtxid,0,"zeroconfclaim",coin->symbol,coin->wiftaddr,coin->taddr,coin->pubtype,coin->p2shtype,coin->isPoS,coin->wiftype,ctx,G.LP_privkey,0,redeemscript,redeemlen,userdata,userdatalen,utxotxid,utxovout,coin->smartaddr,G.LP_pubsecp,0xffffffff,0,&destamount,satoshis-coin->txfee,coin->smartaddr,vinaddr,1,coin->zcash)) != 0 ) { sendtxid = LP_broadcast("claim","KMD",signedtx,signedtxid); if ( bits256_cmp(sendtxid,signedtxid) == 0 ) @@ -181,31 +181,37 @@ char *LP_zeroconf_claim(struct iguana_info *coin,char *depositaddr,uint32_t expi return(clonestr("{\"error\":\"no zeroconf deposits to claim\"}")); } +void LP_zeroconf_credit(char *coinaddr,uint64_t satoshis,int32_t weeki,char *p2shaddr) +{ + uint32_t timestamp; + timestamp = LP_FIRSTWEEKTIME + weeki*LP_WEEKMULT; + printf("ZEROCONF credit.(%s) %.8f weeki.%d (%s)\n",coinaddr,dstr(satoshis),weeki,p2shaddr); +} + void LP_zeroconf_deposits(struct iguana_info *coin) { - cJSON *array,*item,*txjson,*vouts,*v,*sobj; uint32_t timestamp; int32_t i,n,redeemlen,len,numvouts,height,vout,weeki; bits256 txid; char *scriptstr,coinaddr[64],p2shaddr[64]; int64_t satoshis,amount64; uint8_t redeemscript[512],spendscript[512],*pub33; + cJSON *array,*item,*txjson,*vouts,*v; int32_t i,n,numvouts,height,vout,weeki; bits256 txid; char destaddr[64],p2shaddr[64]; int64_t satoshis,amount64; if ( (array= LP_listunspent("KMD",BOTS_BONDADDRESS)) != 0 ) { - printf("ZEROCONF.(%s)\n",jprint(array,0)); + //printf("ZEROCONF.(%s)\n",jprint(array,0)); if ( (n= cJSON_GetArraySize(array)) > 0 ) { for (i=0; i= 0 && (txjson= LP_gettx(coin->symbol,txid)) != 0 ) { - if ( (vouts= jarray(&numvouts,txjson,"vout")) > 0 ) + if ( (vouts= jarray(&numvouts,txjson,"vout")) > 0 && numvouts >= 3 && LP_destaddr(destaddr,jitem(vouts,2)) == 0 ) { - // get pubkey from vout.2 v = jitem(vouts,0); satoshis = LP_value_extract(v,0); - if ( (sobj= jobj(v,"scriptPubKey")) != 0 ) + if ( LP_destaddr(p2shaddr,v) == 0 ) + LP_zeroconf_credit(destaddr,satoshis,weeki,p2shaddr); + /*if ( (sobj= jobj(v,"scriptPubKey")) != 0 ) { if ( (scriptstr= jstr(sobj,"hex")) != 0 ) { @@ -227,7 +233,7 @@ void LP_zeroconf_deposits(struct iguana_info *coin) } } } - } + }*/ } } } From 335e3ce8a6d8d7b224f6b34c90d8b631c548a83d Mon Sep 17 00:00:00 2001 From: jl777 Date: Wed, 22 Nov 2017 20:14:53 +0400 Subject: [PATCH 1079/1664] Test --- iguana/exchanges/LP_zeroconf.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/iguana/exchanges/LP_zeroconf.c b/iguana/exchanges/LP_zeroconf.c index 19016682b..c9ace18aa 100644 --- a/iguana/exchanges/LP_zeroconf.c +++ b/iguana/exchanges/LP_zeroconf.c @@ -154,8 +154,9 @@ char *LP_zeroconf_claim(struct iguana_info *coin,char *depositaddr,uint32_t expi { item = jitem(array,i); satoshis = LP_listunspent_parseitem(coin,&utxotxid,&utxovout,&height,item); - if ( (signedtx= basilisk_swap_bobtxspend(&signedtxid,0,"zeroconfclaim",coin->symbol,coin->wiftaddr,coin->taddr,coin->pubtype,coin->p2shtype,coin->isPoS,coin->wiftype,ctx,G.LP_privkey,0,redeemscript,redeemlen,userdata,userdatalen,utxotxid,utxovout,coin->smartaddr,G.LP_pubsecp,0xffffffff,0,&destamount,satoshis-coin->txfee,coin->smartaddr,vinaddr,1,coin->zcash)) != 0 ) + if ( (signedtx= basilisk_swap_bobtxspend(&signedtxid,0,"zeroconfclaim",coin->symbol,coin->wiftaddr,coin->taddr,coin->pubtype,coin->p2shtype,coin->isPoS,coin->wiftype,ctx,G.LP_privkey,0,redeemscript,redeemlen,userdata,userdatalen,utxotxid,utxovout,coin->smartaddr,G.LP_pubsecp,timestamp,0,&destamount,satoshis-coin->txfee,coin->smartaddr,vinaddr,1,coin->zcash)) != 0 ) { + printf("signedtx.(%s)\n",signedtx); sendtxid = LP_broadcast("claim","KMD",signedtx,signedtxid); if ( bits256_cmp(sendtxid,signedtxid) == 0 ) { From 06ce0353b03f4f0f3fbf466fd82a6b66b395c7a7 Mon Sep 17 00:00:00 2001 From: jl777 Date: Wed, 22 Nov 2017 20:32:25 +0400 Subject: [PATCH 1080/1664] Test --- iguana/exchanges/LP_nativeDEX.c | 2 +- iguana/exchanges/LP_ordermatch.c | 2 +- iguana/exchanges/LP_transaction.c | 4 ++-- iguana/exchanges/LP_zeroconf.c | 2 +- 4 files changed, 5 insertions(+), 5 deletions(-) diff --git a/iguana/exchanges/LP_nativeDEX.c b/iguana/exchanges/LP_nativeDEX.c index 719b699e2..dcaefe770 100644 --- a/iguana/exchanges/LP_nativeDEX.c +++ b/iguana/exchanges/LP_nativeDEX.c @@ -27,7 +27,7 @@ // waiting for alice and alice disconnects // MNZ getcoin strangeness // portfolio value based on ask? -// listunspent triplicate +// listunspent triplicate, tradebot timeslice? // disable basilisk // verify encrypted destpubkey, broadcast:0 setprice diff --git a/iguana/exchanges/LP_ordermatch.c b/iguana/exchanges/LP_ordermatch.c index 6266fb2bb..c9f7ed36a 100644 --- a/iguana/exchanges/LP_ordermatch.c +++ b/iguana/exchanges/LP_ordermatch.c @@ -1150,7 +1150,7 @@ char *LP_autobuy(void *ctx,char *myipaddr,int32_t mypubsock,char *base,char *rel memset(pubkeys,0,sizeof(pubkeys)); LP_txfees(&txfee,&desttxfee,base,rel); destsatoshis = SATOSHIDEN * relvolume; - LP_address_utxo_reset(relcoin); + //LP_address_utxo_reset(relcoin); 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->S.satoshis)); diff --git a/iguana/exchanges/LP_transaction.c b/iguana/exchanges/LP_transaction.c index 15d14bb18..3c39c6784 100644 --- a/iguana/exchanges/LP_transaction.c +++ b/iguana/exchanges/LP_transaction.c @@ -604,12 +604,12 @@ int32_t iguana_signrawtransaction(void *ctx,char *symbol,uint8_t wiftaddr,uint8_ sighash = LP_sighash(symbol,zcash); if ( (complete= bitcoin_verifyvins(ctx,symbol,taddr,pubtype,p2shtype,isPoS,height,signedtxidp,&signedtx,msgtx,serialized3,maxsize,V,sighash,1,V->suppress_pubkeys,zcash)) > 0 && signedtx != 0 ) { - /*int32_t tmp; //char str[65]; + int32_t tmp; //char str[65]; if ( (tmp= iguana_interpreter(ctx,cJSON_CreateArray(),iguana_lockval(finalized,jint(txobj,"locktime")),V,numinputs)) < 0 ) { printf("iguana_interpreter %d error.(%s)\n",tmp,signedtx); complete = 0; - } else printf("interpreter passed\n");*/ + } else printf("interpreter passed\n"); } else printf("complete.%d\n",complete); } else printf("rwmsgtx error\n"); } else printf("no inputs in vins.(%s)\n",vins!=0?jprint(vins,0):"null"); diff --git a/iguana/exchanges/LP_zeroconf.c b/iguana/exchanges/LP_zeroconf.c index c9ace18aa..0a68e3391 100644 --- a/iguana/exchanges/LP_zeroconf.c +++ b/iguana/exchanges/LP_zeroconf.c @@ -154,7 +154,7 @@ char *LP_zeroconf_claim(struct iguana_info *coin,char *depositaddr,uint32_t expi { item = jitem(array,i); satoshis = LP_listunspent_parseitem(coin,&utxotxid,&utxovout,&height,item); - if ( (signedtx= basilisk_swap_bobtxspend(&signedtxid,0,"zeroconfclaim",coin->symbol,coin->wiftaddr,coin->taddr,coin->pubtype,coin->p2shtype,coin->isPoS,coin->wiftype,ctx,G.LP_privkey,0,redeemscript,redeemlen,userdata,userdatalen,utxotxid,utxovout,coin->smartaddr,G.LP_pubsecp,timestamp,0,&destamount,satoshis-coin->txfee,coin->smartaddr,vinaddr,1,coin->zcash)) != 0 ) + if ( (signedtx= basilisk_swap_bobtxspend(&signedtxid,0,"zeroconfclaim",coin->symbol,coin->wiftaddr,coin->taddr,coin->pubtype,coin->p2shtype,coin->isPoS,coin->wiftype,ctx,G.LP_privkey,0,redeemscript,redeemlen,userdata,userdatalen,utxotxid,utxovout,coin->smartaddr,G.LP_pubsecp,timestamp,0,&destamount,satoshis-10000,coin->smartaddr,vinaddr,1,coin->zcash)) != 0 ) { printf("signedtx.(%s)\n",signedtx); sendtxid = LP_broadcast("claim","KMD",signedtx,signedtxid); From e94b511f3156ee4076218b2145b787352a06c613 Mon Sep 17 00:00:00 2001 From: jl777 Date: Wed, 22 Nov 2017 20:40:28 +0400 Subject: [PATCH 1081/1664] Test --- iguana/exchanges/LP_nativeDEX.c | 2 +- iguana/exchanges/LP_transaction.c | 4 ++-- iguana/exchanges/LP_zeroconf.c | 2 +- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/iguana/exchanges/LP_nativeDEX.c b/iguana/exchanges/LP_nativeDEX.c index dcaefe770..3b75576d8 100644 --- a/iguana/exchanges/LP_nativeDEX.c +++ b/iguana/exchanges/LP_nativeDEX.c @@ -27,7 +27,7 @@ // waiting for alice and alice disconnects // MNZ getcoin strangeness // portfolio value based on ask? -// listunspent triplicate, tradebot timeslice? +// listunspent triplicate, tradebot timeslice? the tradebot timeslice is just getting too much timeslices // disable basilisk // verify encrypted destpubkey, broadcast:0 setprice diff --git a/iguana/exchanges/LP_transaction.c b/iguana/exchanges/LP_transaction.c index 3c39c6784..15d14bb18 100644 --- a/iguana/exchanges/LP_transaction.c +++ b/iguana/exchanges/LP_transaction.c @@ -604,12 +604,12 @@ int32_t iguana_signrawtransaction(void *ctx,char *symbol,uint8_t wiftaddr,uint8_ sighash = LP_sighash(symbol,zcash); if ( (complete= bitcoin_verifyvins(ctx,symbol,taddr,pubtype,p2shtype,isPoS,height,signedtxidp,&signedtx,msgtx,serialized3,maxsize,V,sighash,1,V->suppress_pubkeys,zcash)) > 0 && signedtx != 0 ) { - int32_t tmp; //char str[65]; + /*int32_t tmp; //char str[65]; if ( (tmp= iguana_interpreter(ctx,cJSON_CreateArray(),iguana_lockval(finalized,jint(txobj,"locktime")),V,numinputs)) < 0 ) { printf("iguana_interpreter %d error.(%s)\n",tmp,signedtx); complete = 0; - } else printf("interpreter passed\n"); + } else printf("interpreter passed\n");*/ } else printf("complete.%d\n",complete); } else printf("rwmsgtx error\n"); } else printf("no inputs in vins.(%s)\n",vins!=0?jprint(vins,0):"null"); diff --git a/iguana/exchanges/LP_zeroconf.c b/iguana/exchanges/LP_zeroconf.c index 0a68e3391..7c27a3d6b 100644 --- a/iguana/exchanges/LP_zeroconf.c +++ b/iguana/exchanges/LP_zeroconf.c @@ -154,7 +154,7 @@ char *LP_zeroconf_claim(struct iguana_info *coin,char *depositaddr,uint32_t expi { item = jitem(array,i); satoshis = LP_listunspent_parseitem(coin,&utxotxid,&utxovout,&height,item); - if ( (signedtx= basilisk_swap_bobtxspend(&signedtxid,0,"zeroconfclaim",coin->symbol,coin->wiftaddr,coin->taddr,coin->pubtype,coin->p2shtype,coin->isPoS,coin->wiftype,ctx,G.LP_privkey,0,redeemscript,redeemlen,userdata,userdatalen,utxotxid,utxovout,coin->smartaddr,G.LP_pubsecp,timestamp,0,&destamount,satoshis-10000,coin->smartaddr,vinaddr,1,coin->zcash)) != 0 ) + if ( (signedtx= basilisk_swap_bobtxspend(&signedtxid,0,"zeroconfclaim",coin->symbol,coin->wiftaddr,coin->taddr,coin->pubtype,coin->p2shtype,coin->isPoS,coin->wiftype,ctx,G.LP_privkey,0,redeemscript,redeemlen,userdata,userdatalen,utxotxid,utxovout,coin->smartaddr,G.LP_pubsecp,timestamp,1,&destamount,satoshis-10000,coin->smartaddr,vinaddr,1,coin->zcash)) != 0 ) { printf("signedtx.(%s)\n",signedtx); sendtxid = LP_broadcast("claim","KMD",signedtx,signedtxid); From 861d922935712fa2783f165adfe1d5e9c7ed45f4 Mon Sep 17 00:00:00 2001 From: jl777 Date: Wed, 22 Nov 2017 20:42:30 +0400 Subject: [PATCH 1082/1664] Test --- iguana/exchanges/LP_zeroconf.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/iguana/exchanges/LP_zeroconf.c b/iguana/exchanges/LP_zeroconf.c index 7c27a3d6b..6d7b18d77 100644 --- a/iguana/exchanges/LP_zeroconf.c +++ b/iguana/exchanges/LP_zeroconf.c @@ -154,7 +154,7 @@ char *LP_zeroconf_claim(struct iguana_info *coin,char *depositaddr,uint32_t expi { item = jitem(array,i); satoshis = LP_listunspent_parseitem(coin,&utxotxid,&utxovout,&height,item); - if ( (signedtx= basilisk_swap_bobtxspend(&signedtxid,0,"zeroconfclaim",coin->symbol,coin->wiftaddr,coin->taddr,coin->pubtype,coin->p2shtype,coin->isPoS,coin->wiftype,ctx,G.LP_privkey,0,redeemscript,redeemlen,userdata,userdatalen,utxotxid,utxovout,coin->smartaddr,G.LP_pubsecp,timestamp,1,&destamount,satoshis-10000,coin->smartaddr,vinaddr,1,coin->zcash)) != 0 ) + if ( (signedtx= basilisk_swap_bobtxspend(&signedtxid,0,"zeroconfclaim",coin->symbol,coin->wiftaddr,coin->taddr,coin->pubtype,coin->p2shtype,coin->isPoS,coin->wiftype,ctx,G.LP_privkey,0,redeemscript,redeemlen,userdata,userdatalen,utxotxid,utxovout,coin->smartaddr,G.LP_pubsecp,0,1,&destamount,satoshis-10000,coin->smartaddr,vinaddr,1,coin->zcash)) != 0 ) { printf("signedtx.(%s)\n",signedtx); sendtxid = LP_broadcast("claim","KMD",signedtx,signedtxid); From bcc78fa36d6318e96efac731dc4cc37731698205 Mon Sep 17 00:00:00 2001 From: jl777 Date: Wed, 22 Nov 2017 20:47:32 +0400 Subject: [PATCH 1083/1664] Test --- iguana/exchanges/LP_zeroconf.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/iguana/exchanges/LP_zeroconf.c b/iguana/exchanges/LP_zeroconf.c index 6d7b18d77..8ade1ebdc 100644 --- a/iguana/exchanges/LP_zeroconf.c +++ b/iguana/exchanges/LP_zeroconf.c @@ -154,7 +154,7 @@ char *LP_zeroconf_claim(struct iguana_info *coin,char *depositaddr,uint32_t expi { item = jitem(array,i); satoshis = LP_listunspent_parseitem(coin,&utxotxid,&utxovout,&height,item); - if ( (signedtx= basilisk_swap_bobtxspend(&signedtxid,0,"zeroconfclaim",coin->symbol,coin->wiftaddr,coin->taddr,coin->pubtype,coin->p2shtype,coin->isPoS,coin->wiftype,ctx,G.LP_privkey,0,redeemscript,redeemlen,userdata,userdatalen,utxotxid,utxovout,coin->smartaddr,G.LP_pubsecp,0,1,&destamount,satoshis-10000,coin->smartaddr,vinaddr,1,coin->zcash)) != 0 ) + if ( (signedtx= basilisk_swap_bobtxspend(&signedtxid,0,"zeroconfclaim",coin->symbol,coin->wiftaddr,coin->taddr,coin->pubtype,coin->p2shtype,coin->isPoS,coin->wiftype,ctx,G.LP_privkey,0,redeemscript,redeemlen,userdata,userdatalen,utxotxid,utxovout,coin->smartaddr,G.LP_pubsecp,1,0,&destamount,satoshis-10000,coin->smartaddr,vinaddr,1,coin->zcash)) != 0 ) { printf("signedtx.(%s)\n",signedtx); sendtxid = LP_broadcast("claim","KMD",signedtx,signedtxid); From 4a44b07b9585cd37d8faf3fd18babe0b2c462058 Mon Sep 17 00:00:00 2001 From: jl777 Date: Wed, 22 Nov 2017 20:55:07 +0400 Subject: [PATCH 1084/1664] Test --- iguana/exchanges/LP_zeroconf.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/iguana/exchanges/LP_zeroconf.c b/iguana/exchanges/LP_zeroconf.c index 8ade1ebdc..a38353142 100644 --- a/iguana/exchanges/LP_zeroconf.c +++ b/iguana/exchanges/LP_zeroconf.c @@ -154,7 +154,8 @@ char *LP_zeroconf_claim(struct iguana_info *coin,char *depositaddr,uint32_t expi { item = jitem(array,i); satoshis = LP_listunspent_parseitem(coin,&utxotxid,&utxovout,&height,item); - if ( (signedtx= basilisk_swap_bobtxspend(&signedtxid,0,"zeroconfclaim",coin->symbol,coin->wiftaddr,coin->taddr,coin->pubtype,coin->p2shtype,coin->isPoS,coin->wiftype,ctx,G.LP_privkey,0,redeemscript,redeemlen,userdata,userdatalen,utxotxid,utxovout,coin->smartaddr,G.LP_pubsecp,1,0,&destamount,satoshis-10000,coin->smartaddr,vinaddr,1,coin->zcash)) != 0 ) + //if ( (rswap.txbytes[BASILISK_BOBRECLAIM]= basilisk_swap_bobtxspend(&signedtxid,rswap.Btxfee,"bobrefund",rswap.bobcoin,bob->wiftaddr,bob->taddr,bob->pubtype,bob->p2shtype,bob->isPoS,bob->wiftype,ctx,rswap.myprivs[1],0,redeemscript,redeemlen,userdata,len,rswap.txids[BASILISK_BOBPAYMENT],0,0,rswap.pubkey33,0,rswap.expiration,&rswap.values[BASILISK_BOBRECLAIM],0,0,rswap.bobpaymentaddr,1,bob->zcash)) != 0 ) + if ( (signedtx= basilisk_swap_bobtxspend(&signedtxid,10000,"zeroconfclaim",coin->symbol,coin->wiftaddr,coin->taddr,coin->pubtype,coin->p2shtype,coin->isPoS,coin->wiftype,ctx,G.LP_privkey,0,redeemscript,redeemlen,userdata,userdatalen,utxotxid,utxovout,coin->smartaddr,G.LP_pubsecp,0,timestamp,&destamount,0,0,vinaddr,1,coin->zcash)) != 0 ) { printf("signedtx.(%s)\n",signedtx); sendtxid = LP_broadcast("claim","KMD",signedtx,signedtxid); From 264a1d0935f57e2f316ad7f741a71f646dfd8d5c Mon Sep 17 00:00:00 2001 From: jl777 Date: Wed, 22 Nov 2017 21:10:48 +0400 Subject: [PATCH 1085/1664] Test --- iguana/exchanges/LP_zeroconf.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/iguana/exchanges/LP_zeroconf.c b/iguana/exchanges/LP_zeroconf.c index a38353142..0bf848972 100644 --- a/iguana/exchanges/LP_zeroconf.c +++ b/iguana/exchanges/LP_zeroconf.c @@ -154,8 +154,7 @@ char *LP_zeroconf_claim(struct iguana_info *coin,char *depositaddr,uint32_t expi { item = jitem(array,i); satoshis = LP_listunspent_parseitem(coin,&utxotxid,&utxovout,&height,item); - //if ( (rswap.txbytes[BASILISK_BOBRECLAIM]= basilisk_swap_bobtxspend(&signedtxid,rswap.Btxfee,"bobrefund",rswap.bobcoin,bob->wiftaddr,bob->taddr,bob->pubtype,bob->p2shtype,bob->isPoS,bob->wiftype,ctx,rswap.myprivs[1],0,redeemscript,redeemlen,userdata,len,rswap.txids[BASILISK_BOBPAYMENT],0,0,rswap.pubkey33,0,rswap.expiration,&rswap.values[BASILISK_BOBRECLAIM],0,0,rswap.bobpaymentaddr,1,bob->zcash)) != 0 ) - if ( (signedtx= basilisk_swap_bobtxspend(&signedtxid,10000,"zeroconfclaim",coin->symbol,coin->wiftaddr,coin->taddr,coin->pubtype,coin->p2shtype,coin->isPoS,coin->wiftype,ctx,G.LP_privkey,0,redeemscript,redeemlen,userdata,userdatalen,utxotxid,utxovout,coin->smartaddr,G.LP_pubsecp,0,timestamp,&destamount,0,0,vinaddr,1,coin->zcash)) != 0 ) + if ( (signedtx= basilisk_swap_bobtxspend(&signedtxid,10000,"zeroconfclaim",coin->symbol,coin->wiftaddr,coin->taddr,coin->pubtype,coin->p2shtype,coin->isPoS,coin->wiftype,ctx,G.LP_privkey,0,redeemscript,redeemlen,userdata,userdatalen,utxotxid,utxovout,coin->smartaddr,G.LP_pubsecp,0,(uint32_t)time(NULL)-60,&destamount,0,0,vinaddr,1,coin->zcash)) != 0 ) { printf("signedtx.(%s)\n",signedtx); sendtxid = LP_broadcast("claim","KMD",signedtx,signedtxid); From c0f4220f38d220b4a0b3bdd87a2e801150e32779 Mon Sep 17 00:00:00 2001 From: jl777 Date: Wed, 22 Nov 2017 21:12:26 +0400 Subject: [PATCH 1086/1664] Test --- iguana/exchanges/LP_zeroconf.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/iguana/exchanges/LP_zeroconf.c b/iguana/exchanges/LP_zeroconf.c index 0bf848972..52171e5f9 100644 --- a/iguana/exchanges/LP_zeroconf.c +++ b/iguana/exchanges/LP_zeroconf.c @@ -154,7 +154,7 @@ char *LP_zeroconf_claim(struct iguana_info *coin,char *depositaddr,uint32_t expi { item = jitem(array,i); satoshis = LP_listunspent_parseitem(coin,&utxotxid,&utxovout,&height,item); - if ( (signedtx= basilisk_swap_bobtxspend(&signedtxid,10000,"zeroconfclaim",coin->symbol,coin->wiftaddr,coin->taddr,coin->pubtype,coin->p2shtype,coin->isPoS,coin->wiftype,ctx,G.LP_privkey,0,redeemscript,redeemlen,userdata,userdatalen,utxotxid,utxovout,coin->smartaddr,G.LP_pubsecp,0,(uint32_t)time(NULL)-60,&destamount,0,0,vinaddr,1,coin->zcash)) != 0 ) + if ( (signedtx= basilisk_swap_bobtxspend(&signedtxid,10000,"zeroconfclaim",coin->symbol,coin->wiftaddr,coin->taddr,coin->pubtype,coin->p2shtype,coin->isPoS,coin->wiftype,ctx,G.LP_privkey,0,redeemscript,redeemlen,userdata,userdatalen,utxotxid,utxovout,coin->smartaddr,G.LP_pubsecp,1,(uint32_t)time(NULL)-60,&destamount,0,0,vinaddr,1,coin->zcash)) != 0 ) { printf("signedtx.(%s)\n",signedtx); sendtxid = LP_broadcast("claim","KMD",signedtx,signedtxid); From c0a8e3e40643c87ac859325a90dd357949069d9e Mon Sep 17 00:00:00 2001 From: jl777 Date: Wed, 22 Nov 2017 21:16:27 +0400 Subject: [PATCH 1087/1664] Test --- iguana/exchanges/LP_zeroconf.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/iguana/exchanges/LP_zeroconf.c b/iguana/exchanges/LP_zeroconf.c index 52171e5f9..263cfa3dd 100644 --- a/iguana/exchanges/LP_zeroconf.c +++ b/iguana/exchanges/LP_zeroconf.c @@ -154,7 +154,7 @@ char *LP_zeroconf_claim(struct iguana_info *coin,char *depositaddr,uint32_t expi { item = jitem(array,i); satoshis = LP_listunspent_parseitem(coin,&utxotxid,&utxovout,&height,item); - if ( (signedtx= basilisk_swap_bobtxspend(&signedtxid,10000,"zeroconfclaim",coin->symbol,coin->wiftaddr,coin->taddr,coin->pubtype,coin->p2shtype,coin->isPoS,coin->wiftype,ctx,G.LP_privkey,0,redeemscript,redeemlen,userdata,userdatalen,utxotxid,utxovout,coin->smartaddr,G.LP_pubsecp,1,(uint32_t)time(NULL)-60,&destamount,0,0,vinaddr,1,coin->zcash)) != 0 ) + if ( (signedtx= basilisk_swap_bobtxspend(&signedtxid,10000,"zeroconfclaim",coin->symbol,coin->wiftaddr,coin->taddr,coin->pubtype,coin->p2shtype,coin->isPoS,coin->wiftype,ctx,G.LP_privkey,0,redeemscript,redeemlen,userdata,userdatalen,utxotxid,utxovout,coin->smartaddr,G.LP_pubsecp,1,(uint32_t)time(NULL)-777,&destamount,0,0,vinaddr,1,coin->zcash)) != 0 ) { printf("signedtx.(%s)\n",signedtx); sendtxid = LP_broadcast("claim","KMD",signedtx,signedtxid); From b0933bbeef04858896034e95a21d6df69372f63c Mon Sep 17 00:00:00 2001 From: jl777 Date: Wed, 22 Nov 2017 21:17:38 +0400 Subject: [PATCH 1088/1664] Test --- iguana/exchanges/LP_zeroconf.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/iguana/exchanges/LP_zeroconf.c b/iguana/exchanges/LP_zeroconf.c index 263cfa3dd..5158a5337 100644 --- a/iguana/exchanges/LP_zeroconf.c +++ b/iguana/exchanges/LP_zeroconf.c @@ -154,7 +154,7 @@ char *LP_zeroconf_claim(struct iguana_info *coin,char *depositaddr,uint32_t expi { item = jitem(array,i); satoshis = LP_listunspent_parseitem(coin,&utxotxid,&utxovout,&height,item); - if ( (signedtx= basilisk_swap_bobtxspend(&signedtxid,10000,"zeroconfclaim",coin->symbol,coin->wiftaddr,coin->taddr,coin->pubtype,coin->p2shtype,coin->isPoS,coin->wiftype,ctx,G.LP_privkey,0,redeemscript,redeemlen,userdata,userdatalen,utxotxid,utxovout,coin->smartaddr,G.LP_pubsecp,1,(uint32_t)time(NULL)-777,&destamount,0,0,vinaddr,1,coin->zcash)) != 0 ) + if ( (signedtx= basilisk_swap_bobtxspend(&signedtxid,10000,"zeroconfclaim",coin->symbol,coin->wiftaddr,coin->taddr,coin->pubtype,coin->p2shtype,coin->isPoS,coin->wiftype,ctx,G.LP_privkey,0,redeemscript,redeemlen,userdata,userdatalen,utxotxid,utxovout,coin->smartaddr,G.LP_pubsecp,1,timestamp+777,&destamount,0,0,vinaddr,1,coin->zcash)) != 0 ) { printf("signedtx.(%s)\n",signedtx); sendtxid = LP_broadcast("claim","KMD",signedtx,signedtxid); From d16b595df69a624fe683a4860f2dfccc425b598a Mon Sep 17 00:00:00 2001 From: jl777 Date: Wed, 22 Nov 2017 21:36:08 +0400 Subject: [PATCH 1089/1664] Test --- iguana/exchanges/LP_zeroconf.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/iguana/exchanges/LP_zeroconf.c b/iguana/exchanges/LP_zeroconf.c index 5158a5337..52171e5f9 100644 --- a/iguana/exchanges/LP_zeroconf.c +++ b/iguana/exchanges/LP_zeroconf.c @@ -154,7 +154,7 @@ char *LP_zeroconf_claim(struct iguana_info *coin,char *depositaddr,uint32_t expi { item = jitem(array,i); satoshis = LP_listunspent_parseitem(coin,&utxotxid,&utxovout,&height,item); - if ( (signedtx= basilisk_swap_bobtxspend(&signedtxid,10000,"zeroconfclaim",coin->symbol,coin->wiftaddr,coin->taddr,coin->pubtype,coin->p2shtype,coin->isPoS,coin->wiftype,ctx,G.LP_privkey,0,redeemscript,redeemlen,userdata,userdatalen,utxotxid,utxovout,coin->smartaddr,G.LP_pubsecp,1,timestamp+777,&destamount,0,0,vinaddr,1,coin->zcash)) != 0 ) + if ( (signedtx= basilisk_swap_bobtxspend(&signedtxid,10000,"zeroconfclaim",coin->symbol,coin->wiftaddr,coin->taddr,coin->pubtype,coin->p2shtype,coin->isPoS,coin->wiftype,ctx,G.LP_privkey,0,redeemscript,redeemlen,userdata,userdatalen,utxotxid,utxovout,coin->smartaddr,G.LP_pubsecp,1,(uint32_t)time(NULL)-60,&destamount,0,0,vinaddr,1,coin->zcash)) != 0 ) { printf("signedtx.(%s)\n",signedtx); sendtxid = LP_broadcast("claim","KMD",signedtx,signedtxid); From 04219e616bcbb1e7dc19c92efdb9e8ac49ca708f Mon Sep 17 00:00:00 2001 From: jl777 Date: Wed, 22 Nov 2017 21:41:52 +0400 Subject: [PATCH 1090/1664] Test --- iguana/exchanges/LP_zeroconf.c | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/iguana/exchanges/LP_zeroconf.c b/iguana/exchanges/LP_zeroconf.c index 52171e5f9..4bff36e32 100644 --- a/iguana/exchanges/LP_zeroconf.c +++ b/iguana/exchanges/LP_zeroconf.c @@ -191,7 +191,7 @@ void LP_zeroconf_credit(char *coinaddr,uint64_t satoshis,int32_t weeki,char *p2s void LP_zeroconf_deposits(struct iguana_info *coin) { - cJSON *array,*item,*txjson,*vouts,*v; int32_t i,n,numvouts,height,vout,weeki; bits256 txid; char destaddr[64],p2shaddr[64]; int64_t satoshis,amount64; + cJSON *array,*item,*txjson,*vouts,*v,*txobj; int32_t i,n,numvouts,height,vout,weeki; bits256 txid; char destaddr[64],p2shaddr[64]; int64_t satoshis,amount64; if ( (array= LP_listunspent("KMD",BOTS_BONDADDRESS)) != 0 ) { //printf("ZEROCONF.(%s)\n",jprint(array,0)); @@ -211,7 +211,12 @@ void LP_zeroconf_deposits(struct iguana_info *coin) v = jitem(vouts,0); satoshis = LP_value_extract(v,0); if ( LP_destaddr(p2shaddr,v) == 0 ) + { + if ( (txobj= LP_gettxout(coin->symbol,p2shaddr,txid,0)) == 0 ) + continue; + else free_json(txobj); LP_zeroconf_credit(destaddr,satoshis,weeki,p2shaddr); + } /*if ( (sobj= jobj(v,"scriptPubKey")) != 0 ) { if ( (scriptstr= jstr(sobj,"hex")) != 0 ) From 31c37e225bbd1bf18c1087dc55230dea43bcbb21 Mon Sep 17 00:00:00 2001 From: jl777 Date: Wed, 22 Nov 2017 21:49:39 +0400 Subject: [PATCH 1091/1664] Test --- iguana/exchanges/LP_zeroconf.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/iguana/exchanges/LP_zeroconf.c b/iguana/exchanges/LP_zeroconf.c index 4bff36e32..17547c97e 100644 --- a/iguana/exchanges/LP_zeroconf.c +++ b/iguana/exchanges/LP_zeroconf.c @@ -154,7 +154,7 @@ char *LP_zeroconf_claim(struct iguana_info *coin,char *depositaddr,uint32_t expi { item = jitem(array,i); satoshis = LP_listunspent_parseitem(coin,&utxotxid,&utxovout,&height,item); - if ( (signedtx= basilisk_swap_bobtxspend(&signedtxid,10000,"zeroconfclaim",coin->symbol,coin->wiftaddr,coin->taddr,coin->pubtype,coin->p2shtype,coin->isPoS,coin->wiftype,ctx,G.LP_privkey,0,redeemscript,redeemlen,userdata,userdatalen,utxotxid,utxovout,coin->smartaddr,G.LP_pubsecp,1,(uint32_t)time(NULL)-60,&destamount,0,0,vinaddr,1,coin->zcash)) != 0 ) + if ( (signedtx= basilisk_swap_bobtxspend(&signedtxid,10000,"zeroconfclaim",coin->symbol,coin->wiftaddr,coin->taddr,coin->pubtype,coin->p2shtype,coin->isPoS,coin->wiftype,ctx,G.LP_privkey,0,redeemscript,redeemlen,userdata,userdatalen,utxotxid,utxovout,coin->smartaddr,G.LP_pubsecp,0,(uint32_t)time(NULL)-60,&destamount,0,0,vinaddr,1,coin->zcash)) != 0 ) { printf("signedtx.(%s)\n",signedtx); sendtxid = LP_broadcast("claim","KMD",signedtx,signedtxid); From 0c2f141ecd108263dcb3ad9f73ef43a583719f85 Mon Sep 17 00:00:00 2001 From: jl777 Date: Wed, 22 Nov 2017 21:58:06 +0400 Subject: [PATCH 1092/1664] Test --- iguana/exchanges/LP_zeroconf.c | 60 +++++++++++++++++++--------------- 1 file changed, 34 insertions(+), 26 deletions(-) diff --git a/iguana/exchanges/LP_zeroconf.c b/iguana/exchanges/LP_zeroconf.c index 17547c97e..e44934c79 100644 --- a/iguana/exchanges/LP_zeroconf.c +++ b/iguana/exchanges/LP_zeroconf.c @@ -125,7 +125,7 @@ char *LP_zeroconf_deposit(struct iguana_info *coin,int32_t weeks,double amount,i char *LP_zeroconf_claim(struct iguana_info *coin,char *depositaddr,uint32_t expiration) { static void *ctx; - uint8_t redeemscript[512],userdata[64]; char vinaddr[64],str[65],*signedtx=0; uint32_t timestamp,now,redeemlen; int32_t i,n,height,utxovout,userdatalen; bits256 signedtxid,utxotxid,sendtxid; int64_t sum,destamount,satoshis; cJSON *array,*item,*txids,*retjson; + uint8_t redeemscript[512],userdata[64]; char vinaddr[64],str[65],*signedtx=0; uint32_t timestamp,now,redeemlen,claimtime; int32_t i,n,height,utxovout,userdatalen; bits256 signedtxid,utxotxid,sendtxid; int64_t sum,destamount,satoshis; cJSON *array,*item,*txids,*retjson; if ( ctx == 0 ) ctx = bitcoin_ctx(); if ( strcmp(coin->symbol,"KMD") != 0 ) @@ -142,38 +142,46 @@ char *LP_zeroconf_claim(struct iguana_info *coin,char *depositaddr,uint32_t expi redeemlen = LP_deposit_addr(vinaddr,redeemscript,coin->taddr,coin->p2shtype,timestamp,G.LP_pubsecp); if ( strcmp(depositaddr,vinaddr) == 0 ) { - printf("found %s at timestamp.%u\n",vinaddr,timestamp); - if ( (array= LP_listunspent(coin->symbol,vinaddr)) != 0 ) + claimtime = (uint32_t)time(NULL)-777/2; + if ( claimtime <= timestamp ) { - userdata[0] = 0x51; - userdatalen = 1; - utxovout = 0; - if ( (n= cJSON_GetArraySize(array)) > 0 ) + printf("claimtime.%u vs locktime.%u, need to wait %d seconds\n",claimtime,timestamp,(int32_t)timestamp-claimtime); + } + else + { + printf("found %s at timestamp.%u\n",vinaddr,timestamp); + if ( (array= LP_listunspent(coin->symbol,vinaddr)) != 0 ) { - for (i=0; i 0 ) { - item = jitem(array,i); - satoshis = LP_listunspent_parseitem(coin,&utxotxid,&utxovout,&height,item); - if ( (signedtx= basilisk_swap_bobtxspend(&signedtxid,10000,"zeroconfclaim",coin->symbol,coin->wiftaddr,coin->taddr,coin->pubtype,coin->p2shtype,coin->isPoS,coin->wiftype,ctx,G.LP_privkey,0,redeemscript,redeemlen,userdata,userdatalen,utxotxid,utxovout,coin->smartaddr,G.LP_pubsecp,0,(uint32_t)time(NULL)-60,&destamount,0,0,vinaddr,1,coin->zcash)) != 0 ) + for (i=0; isymbol,coin->wiftaddr,coin->taddr,coin->pubtype,coin->p2shtype,coin->isPoS,coin->wiftype,ctx,G.LP_privkey,0,redeemscript,redeemlen,userdata,userdatalen,utxotxid,utxovout,coin->smartaddr,G.LP_pubsecp,0,claimtime,&destamount,0,0,vinaddr,1,coin->zcash)) != 0 ) { - jaddibits256(txids,sendtxid); - sum += (satoshis-coin->txfee); - } - else printf("error sending %s\n",bits256_str(str,signedtxid)); - free(signedtx); - } else printf("error claiming zeroconf deposit %s/v%d %.8f\n",bits256_str(str,utxotxid),utxovout,dstr(satoshis)); + printf("signedtx.(%s)\n",signedtx); + sendtxid = LP_broadcast("claim","KMD",signedtx,signedtxid); + if ( bits256_cmp(sendtxid,signedtxid) == 0 ) + { + jaddibits256(txids,sendtxid); + sum += (satoshis-coin->txfee); + } + else printf("error sending %s\n",bits256_str(str,signedtxid)); + free(signedtx); + } else printf("error claiming zeroconf deposit %s/v%d %.8f\n",bits256_str(str,utxotxid),utxovout,dstr(satoshis)); + } } + free_json(array); + retjson = cJSON_CreateObject(); + jaddstr(retjson,"result","success"); + jaddnum(retjson,"claimed",dstr(sum)); + jadd(retjson,"txids",txids); + return(jprint(retjson,1)); } - free_json(array); - retjson = cJSON_CreateObject(); - jaddstr(retjson,"result","success"); - jaddnum(retjson,"claimed",dstr(sum)); - jadd(retjson,"txids",txids); - return(jprint(retjson,1)); } } if ( expiration != 0 ) From fb26682b21958f903d636db072e5fc720804f128 Mon Sep 17 00:00:00 2001 From: jl777 Date: Wed, 22 Nov 2017 22:25:12 +0400 Subject: [PATCH 1093/1664] Test --- iguana/exchanges/LP_include.h | 3 +-- iguana/exchanges/LP_zeroconf.c | 13 ++++++++++--- 2 files changed, 11 insertions(+), 5 deletions(-) diff --git a/iguana/exchanges/LP_include.h b/iguana/exchanges/LP_include.h index 8eb56d467..04261a769 100644 --- a/iguana/exchanges/LP_include.h +++ b/iguana/exchanges/LP_include.h @@ -322,7 +322,7 @@ struct LP_address UT_hash_handle hh; struct LP_address_utxo *utxos; bits256 pubkey; - int64_t balance,total; + int64_t balance,total,zeroconf_credits; uint32_t timestamp,n,unspenttime; int32_t unspentheight; char coinaddr[40]; @@ -398,7 +398,6 @@ struct LP_pubkey_info bits256 pubkey; struct LP_pubkey_quote *quotes; struct LP_pubswap *bobswaps,*aliceswaps; - uint64_t bondvalue,swaps_kmdvalue; uint32_t timestamp,numerrors,lasttime; int32_t istrusted; uint8_t rmd160[20],sig[65],pubsecp[33],siglen; diff --git a/iguana/exchanges/LP_zeroconf.c b/iguana/exchanges/LP_zeroconf.c index e44934c79..f47e67633 100644 --- a/iguana/exchanges/LP_zeroconf.c +++ b/iguana/exchanges/LP_zeroconf.c @@ -192,9 +192,16 @@ char *LP_zeroconf_claim(struct iguana_info *coin,char *depositaddr,uint32_t expi void LP_zeroconf_credit(char *coinaddr,uint64_t satoshis,int32_t weeki,char *p2shaddr) { - uint32_t timestamp; - timestamp = LP_FIRSTWEEKTIME + weeki*LP_WEEKMULT; - printf("ZEROCONF credit.(%s) %.8f weeki.%d (%s)\n",coinaddr,dstr(satoshis),weeki,p2shaddr); + uint32_t timestamp; struct LP_address *ap; struct iguana_info *coin = LP_coinfind("KMD"); + if ( coin != 0 ) + { + timestamp = LP_FIRSTWEEKTIME + weeki*LP_WEEKMULT; + if ( (ap= LP_address(coin,coinaddr)) != 0 ) + { + ap->zeroconf_credits += satoshis; + printf("ZEROCONF credit.(%s) %.8f weeki.%d (%s) -> sum %.8f\n",coinaddr,dstr(satoshis),weeki,p2shaddr,dstr(ap->zeroconf_credits)); + } + } } void LP_zeroconf_deposits(struct iguana_info *coin) From a285d58f73f9e728a26b36fcc3baef528c477083 Mon Sep 17 00:00:00 2001 From: jl777 Date: Wed, 22 Nov 2017 22:35:28 +0400 Subject: [PATCH 1094/1664] test --- iguana/exchanges/LP_zeroconf.c | 22 ++++++++++++++++++---- 1 file changed, 18 insertions(+), 4 deletions(-) diff --git a/iguana/exchanges/LP_zeroconf.c b/iguana/exchanges/LP_zeroconf.c index f47e67633..996a5d4c4 100644 --- a/iguana/exchanges/LP_zeroconf.c +++ b/iguana/exchanges/LP_zeroconf.c @@ -266,11 +266,25 @@ void LP_zeroconf_deposits(struct iguana_info *coin) int32_t LP_dynamictrust(bits256 pubkey,int64_t kmdvalue) { - struct LP_pubkey_info *pubp; - if ( (pubp= LP_pubkeyfind(pubkey)) != 0 ) + struct LP_pubswap *ptr,*tmp; struct LP_swapstats *sp; struct LP_pubkey_info *pubp; struct LP_address *ap; char coinaddr[64]; struct iguana_info *coin; int64_t swaps_kmdvalue = 0; + if ( (coin= LP_coinfind("KMD")) != 0 && (pubp= LP_pubkeyfind(pubkey)) != 0 ) { - if ( pubp->bondvalue > pubp->swaps_kmdvalue+kmdvalue ) - return(1); + if ((ap= LP_address(coin,coinaddr)) != 0 && ap->zeroconf_credits >= kmdvalue ) + { + DL_FOREACH_SAFE(pubp->bobswaps,ptr,tmp) + { + if ( (sp= ptr->swap) != 0 && sp->finished == 0 && sp->expired == 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 ) + swaps_kmdvalue += LP_kmdvalue(sp->Q.destcoin,sp->Q.destsatoshis); + } + printf("credits %.8f vs (%.8f + current %.8f)\n",dstr(ap->zeroconf_credits),dstr(swaps_kmdvalue),dstr(kmdvalue)); + if ( ap->zeroconf_credits > swaps_kmdvalue+kmdvalue ) + return(1); + } } return(0); } From ae7776d707d0736135626dab8018a480f9291b08 Mon Sep 17 00:00:00 2001 From: jl777 Date: Wed, 22 Nov 2017 22:42:11 +0400 Subject: [PATCH 1095/1664] Test --- iguana/exchanges/LP_include.h | 1 + iguana/exchanges/LP_ordermatch.c | 4 ++-- iguana/exchanges/LP_prices.c | 1 + iguana/exchanges/LP_statemachine.c | 23 ++++++++++++++++++++++ iguana/exchanges/LP_zeroconf.c | 31 ++++-------------------------- 5 files changed, 31 insertions(+), 29 deletions(-) diff --git a/iguana/exchanges/LP_include.h b/iguana/exchanges/LP_include.h index 04261a769..386778c8b 100644 --- a/iguana/exchanges/LP_include.h +++ b/iguana/exchanges/LP_include.h @@ -502,6 +502,7 @@ int32_t LP_gettx_presence(char *symbol,bits256 expectedtxid); double LP_getestimatedrate(struct iguana_info *coin); 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); +int64_t LP_dynamictrust(bits256 pubkey,int64_t kmdvalue); void LP_listunspent_query(char *symbol,char *coinaddr); int32_t bitcoin_priv2wif(uint8_t wiftaddr,char *wifstr,bits256 privkey,uint8_t addrtype); diff --git a/iguana/exchanges/LP_ordermatch.c b/iguana/exchanges/LP_ordermatch.c index c9f7ed36a..39ede0a76 100644 --- a/iguana/exchanges/LP_ordermatch.c +++ b/iguana/exchanges/LP_ordermatch.c @@ -454,7 +454,7 @@ int32_t LP_connectstartbob(void *ctx,int32_t pubsock,cJSON *argjson,char *base,c printf("requestid.%u quoteid.%u is already in progres\n",qp->R.requestid,qp->R.quoteid); return(-1); } - if ( (swap= LP_swapinit(1,0,privkey,&qp->R,qp,LP_dynamictrust(qp->desthash,LP_kmdvalue(qp->destcoin,qp->destsatoshis)))) == 0 ) + if ( (swap= LP_swapinit(1,0,privkey,&qp->R,qp,LP_dynamictrust(qp->desthash,LP_kmdvalue(qp->destcoin,qp->destsatoshis) > 0))) == 0 ) { printf("cant initialize swap\n"); return(-1); @@ -626,7 +626,7 @@ char *LP_connectedalice(cJSON *argjson) // alice if ( bits256_nonz(Q.privkey) != 0 )//&& Q.quotetime >= Q.timestamp-3 ) { retjson = cJSON_CreateObject(); - if ( (swap= LP_swapinit(0,0,Q.privkey,&Q.R,&Q,LP_dynamictrust(Q.srchash,LP_kmdvalue(Q.srccoin,Q.satoshis)))) == 0 ) + if ( (swap= LP_swapinit(0,0,Q.privkey,&Q.R,&Q,LP_dynamictrust(Q.srchash,LP_kmdvalue(Q.srccoin,Q.satoshis) > 0))) == 0 ) { jaddstr(retjson,"error","couldnt swapinit"); LP_availableset(Q.desttxid,Q.vout); diff --git a/iguana/exchanges/LP_prices.c b/iguana/exchanges/LP_prices.c index adb1e7e45..a01956929 100644 --- a/iguana/exchanges/LP_prices.c +++ b/iguana/exchanges/LP_prices.c @@ -750,6 +750,7 @@ cJSON *LP_orderbookjson(char *symbol,struct LP_orderbookentry *op) jaddnum(item,"depth",dstr(op->depth)*0.8); jaddbits256(item,"pubkey",op->pubkey); jaddnum(item,"age",time(NULL)-op->timestamp); + jaddnum(item,"netcredits",dstr(LP_dynamictrust(op->pubkey,0)); } return(item); } diff --git a/iguana/exchanges/LP_statemachine.c b/iguana/exchanges/LP_statemachine.c index 54d9ddc95..01d966310 100644 --- a/iguana/exchanges/LP_statemachine.c +++ b/iguana/exchanges/LP_statemachine.c @@ -3039,6 +3039,29 @@ if ( (0) ) #undef aptr #undef bptr }*/ +/*if ( (sobj= jobj(v,"scriptPubKey")) != 0 ) + { + if ( (scriptstr= jstr(sobj,"hex")) != 0 ) + { + printf("amount64 %.8f vout.%d (%s) weeki.%d %.8f (%s)\n",dstr(amount64),vout,jprint(v,0),weeki,dstr(satoshis),scriptstr); + len = (int32_t)strlen(scriptstr) >> 1; + if ( len <= sizeof(spendscript)/sizeof(*spendscript) ) + { + decode_hex(spendscript,len,scriptstr); + if ( spendscript[11] == 33 ) + { + pub33 = &spendscript[12]; + redeemlen = LP_deposit_addr(p2shaddr,redeemscript,coin->taddr,coin->p2shtype,timestamp,pub33); + if ( len == redeemlen && (timestamp % LP_WEEKMULT) == 0 ) + { + bitcoin_address(coinaddr,coin->taddr,coin->pubtype,pub33,33); + printf("%s -> matched %s script t.%u weeki.%d deposit %.8f\n",coinaddr,p2shaddr,timestamp,(timestamp-LP_FIRSTWEEKTIME)/LP_WEEKMULT,dstr(satoshis)); + // add to pubp->credits; + } + } + } + } + }*/ /*portable_mutex_lock(&ep->pendingQ.mutex); if ( ep->pendingQ.list != 0 ) diff --git a/iguana/exchanges/LP_zeroconf.c b/iguana/exchanges/LP_zeroconf.c index 996a5d4c4..b9b7a0d68 100644 --- a/iguana/exchanges/LP_zeroconf.c +++ b/iguana/exchanges/LP_zeroconf.c @@ -62,7 +62,7 @@ char *LP_zeroconf_deposit(struct iguana_info *coin,int32_t weeks,double amount,i jaddnum(item,coin->smartaddr,0.0001); jaddi(array,item); jadd(argjson,"outputs",array); - printf("deposit.(%s)\n",jprint(argjson,0)); + //printf("deposit.(%s)\n",jprint(argjson,0)); if ( (retstr= LP_withdraw(coin,argjson)) != 0 ) { if ( (retjson= cJSON_Parse(retstr)) != 0 ) @@ -196,7 +196,7 @@ void LP_zeroconf_credit(char *coinaddr,uint64_t satoshis,int32_t weeki,char *p2s if ( coin != 0 ) { timestamp = LP_FIRSTWEEKTIME + weeki*LP_WEEKMULT; - if ( (ap= LP_address(coin,coinaddr)) != 0 ) + if ( time(NULL) < timestamp-24*3600 && (ap= LP_address(coin,coinaddr)) != 0 ) { ap->zeroconf_credits += satoshis; printf("ZEROCONF credit.(%s) %.8f weeki.%d (%s) -> sum %.8f\n",coinaddr,dstr(satoshis),weeki,p2shaddr,dstr(ap->zeroconf_credits)); @@ -232,29 +232,6 @@ void LP_zeroconf_deposits(struct iguana_info *coin) else free_json(txobj); LP_zeroconf_credit(destaddr,satoshis,weeki,p2shaddr); } - /*if ( (sobj= jobj(v,"scriptPubKey")) != 0 ) - { - if ( (scriptstr= jstr(sobj,"hex")) != 0 ) - { - printf("amount64 %.8f vout.%d (%s) weeki.%d %.8f (%s)\n",dstr(amount64),vout,jprint(v,0),weeki,dstr(satoshis),scriptstr); - len = (int32_t)strlen(scriptstr) >> 1; - if ( len <= sizeof(spendscript)/sizeof(*spendscript) ) - { - decode_hex(spendscript,len,scriptstr); - if ( spendscript[11] == 33 ) - { - pub33 = &spendscript[12]; - redeemlen = LP_deposit_addr(p2shaddr,redeemscript,coin->taddr,coin->p2shtype,timestamp,pub33); - if ( len == redeemlen && (timestamp % LP_WEEKMULT) == 0 ) - { - bitcoin_address(coinaddr,coin->taddr,coin->pubtype,pub33,33); - printf("%s -> matched %s script t.%u weeki.%d deposit %.8f\n",coinaddr,p2shaddr,timestamp,(timestamp-LP_FIRSTWEEKTIME)/LP_WEEKMULT,dstr(satoshis)); - // add to pubp->credits; - } - } - } - } - }*/ } } } @@ -264,7 +241,7 @@ void LP_zeroconf_deposits(struct iguana_info *coin) } } -int32_t LP_dynamictrust(bits256 pubkey,int64_t kmdvalue) +int64_t LP_dynamictrust(bits256 pubkey,int64_t kmdvalue) { struct LP_pubswap *ptr,*tmp; struct LP_swapstats *sp; struct LP_pubkey_info *pubp; struct LP_address *ap; char coinaddr[64]; struct iguana_info *coin; int64_t swaps_kmdvalue = 0; if ( (coin= LP_coinfind("KMD")) != 0 && (pubp= LP_pubkeyfind(pubkey)) != 0 ) @@ -283,7 +260,7 @@ int32_t LP_dynamictrust(bits256 pubkey,int64_t kmdvalue) } printf("credits %.8f vs (%.8f + current %.8f)\n",dstr(ap->zeroconf_credits),dstr(swaps_kmdvalue),dstr(kmdvalue)); if ( ap->zeroconf_credits > swaps_kmdvalue+kmdvalue ) - return(1); + return(ap->zeroconf_credits - (swaps_kmdvalue+kmdvalue)); } } return(0); From f34c880a646986d957c6e3dd4f27dc7a4455e02d Mon Sep 17 00:00:00 2001 From: jl777 Date: Wed, 22 Nov 2017 22:43:03 +0400 Subject: [PATCH 1096/1664] Test --- iguana/exchanges/LP_ordermatch.c | 4 ++-- iguana/exchanges/LP_prices.c | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/iguana/exchanges/LP_ordermatch.c b/iguana/exchanges/LP_ordermatch.c index 39ede0a76..c78fd2a2f 100644 --- a/iguana/exchanges/LP_ordermatch.c +++ b/iguana/exchanges/LP_ordermatch.c @@ -454,7 +454,7 @@ int32_t LP_connectstartbob(void *ctx,int32_t pubsock,cJSON *argjson,char *base,c printf("requestid.%u quoteid.%u is already in progres\n",qp->R.requestid,qp->R.quoteid); return(-1); } - if ( (swap= LP_swapinit(1,0,privkey,&qp->R,qp,LP_dynamictrust(qp->desthash,LP_kmdvalue(qp->destcoin,qp->destsatoshis) > 0))) == 0 ) + if ( (swap= LP_swapinit(1,0,privkey,&qp->R,qp,LP_dynamictrust(qp->desthash,LP_kmdvalue(qp->destcoin,qp->destsatoshis)) > 0)) == 0 ) { printf("cant initialize swap\n"); return(-1); @@ -626,7 +626,7 @@ char *LP_connectedalice(cJSON *argjson) // alice if ( bits256_nonz(Q.privkey) != 0 )//&& Q.quotetime >= Q.timestamp-3 ) { retjson = cJSON_CreateObject(); - if ( (swap= LP_swapinit(0,0,Q.privkey,&Q.R,&Q,LP_dynamictrust(Q.srchash,LP_kmdvalue(Q.srccoin,Q.satoshis) > 0))) == 0 ) + if ( (swap= LP_swapinit(0,0,Q.privkey,&Q.R,&Q,LP_dynamictrust(Q.srchash,LP_kmdvalue(Q.srccoin,Q.satoshis)) > 0)) == 0 ) { jaddstr(retjson,"error","couldnt swapinit"); LP_availableset(Q.desttxid,Q.vout); diff --git a/iguana/exchanges/LP_prices.c b/iguana/exchanges/LP_prices.c index a01956929..96a8384bc 100644 --- a/iguana/exchanges/LP_prices.c +++ b/iguana/exchanges/LP_prices.c @@ -750,7 +750,7 @@ cJSON *LP_orderbookjson(char *symbol,struct LP_orderbookentry *op) jaddnum(item,"depth",dstr(op->depth)*0.8); jaddbits256(item,"pubkey",op->pubkey); jaddnum(item,"age",time(NULL)-op->timestamp); - jaddnum(item,"netcredits",dstr(LP_dynamictrust(op->pubkey,0)); + jaddnum(item,"zcredits",dstr(LP_dynamictrust(op->pubkey,0))); } return(item); } From c68105dbe28f30f9909f8c1873842533bd726e1d Mon Sep 17 00:00:00 2001 From: jl777 Date: Wed, 22 Nov 2017 22:56:56 +0400 Subject: [PATCH 1097/1664] Test --- iguana/exchanges/LP_include.h | 1 + iguana/exchanges/LP_prices.c | 17 +++++++++++++---- iguana/exchanges/LP_stats.c | 6 +++++- 3 files changed, 19 insertions(+), 5 deletions(-) diff --git a/iguana/exchanges/LP_include.h b/iguana/exchanges/LP_include.h index 386778c8b..0197bd72a 100644 --- a/iguana/exchanges/LP_include.h +++ b/iguana/exchanges/LP_include.h @@ -398,6 +398,7 @@ struct LP_pubkey_info bits256 pubkey; struct LP_pubkey_quote *quotes; struct LP_pubswap *bobswaps,*aliceswaps; + uint64_t dynamictrust; uint32_t timestamp,numerrors,lasttime; int32_t istrusted; uint8_t rmd160[20],sig[65],pubsecp[33],siglen; diff --git a/iguana/exchanges/LP_prices.c b/iguana/exchanges/LP_prices.c index 96a8384bc..4812891b0 100644 --- a/iguana/exchanges/LP_prices.c +++ b/iguana/exchanges/LP_prices.c @@ -18,7 +18,15 @@ // marketmaker // -struct LP_orderbookentry { bits256 pubkey; double price; uint64_t avesatoshis,maxsatoshis,depth; uint32_t timestamp; int32_t numutxos; char coinaddr[64]; }; +struct LP_orderbookentry +{ + bits256 pubkey; + double price; + uint64_t avesatoshis,maxsatoshis,depth,dynamictrust; + uint32_t timestamp; + int32_t numutxos; + char coinaddr[64]; +}; struct LP_priceinfo { @@ -750,12 +758,12 @@ cJSON *LP_orderbookjson(char *symbol,struct LP_orderbookentry *op) jaddnum(item,"depth",dstr(op->depth)*0.8); jaddbits256(item,"pubkey",op->pubkey); jaddnum(item,"age",time(NULL)-op->timestamp); - jaddnum(item,"zcredits",dstr(LP_dynamictrust(op->pubkey,0))); + jaddnum(item,"zcredits",dstr(op->dynamictrust)); } return(item); } -struct LP_orderbookentry *LP_orderbookentry(char *address,char *base,char *rel,double price,int32_t numutxos,uint64_t avesatoshis,uint64_t maxsatoshis,bits256 pubkey,uint32_t timestamp,uint64_t balance) +struct LP_orderbookentry *LP_orderbookentry(char *address,char *base,char *rel,double price,int32_t numutxos,uint64_t avesatoshis,uint64_t maxsatoshis,bits256 pubkey,uint32_t timestamp,uint64_t balance,uint64_t dynamictrust) { struct LP_orderbookentry *op; if ( (op= calloc(1,sizeof(*op))) != 0 ) @@ -768,6 +776,7 @@ struct LP_orderbookentry *LP_orderbookentry(char *address,char *base,char *rel,d op->pubkey = pubkey; op->timestamp = timestamp; op->depth = balance; + op->dynamictrust = dynamictrust; } return(op); } @@ -828,7 +837,7 @@ int32_t LP_orderbook_utxoentries(uint32_t now,int32_t polarity,char *base,char * } //printf("%s/%s %s n.%d ap->n.%d %.8f\n",base,rel,coinaddr,n,ap->n,dstr(ap->total)); } - if ( (op= LP_orderbookentry(coinaddr,base,rel,polarity > 0 ? price : 1./price,n,avesatoshis,maxsatoshis,pubp->pubkey,pubp->timestamp,balance)) != 0 ) + if ( (op= LP_orderbookentry(coinaddr,base,rel,polarity > 0 ? price : 1./price,n,avesatoshis,maxsatoshis,pubp->pubkey,pubp->timestamp,balance,pubp->dynamictrust)) != 0 ) { *arrayp = realloc(*arrayp,sizeof(*(*arrayp)) * (num+1)); (*arrayp)[num++] = op; diff --git a/iguana/exchanges/LP_stats.c b/iguana/exchanges/LP_stats.c index 19f528850..b7d9323ee 100644 --- a/iguana/exchanges/LP_stats.c +++ b/iguana/exchanges/LP_stats.c @@ -428,7 +428,7 @@ int32_t LP_stats_dispiter(cJSON *array,struct LP_swapstats *sp,uint32_t starttim cJSON *LP_statslog_disp(uint32_t starttime,uint32_t endtime,char *refgui,bits256 refpubkey,char *refbase,char *refrel) { static int32_t rval; - cJSON *retjson,*array,*item,*reqjson; bits256 zero; uint32_t now; struct LP_swapstats *sp,*tmp; int32_t i,n,numtrades[LP_MAXPRICEINFOS]; uint64_t basevols[LP_MAXPRICEINFOS],relvols[LP_MAXPRICEINFOS]; + cJSON *retjson,*array,*item,*reqjson; struct LP_pubkey_info *pubp,*ptmp; bits256 zero; uint32_t now; struct LP_swapstats *sp,*tmp; int32_t i,n,numtrades[LP_MAXPRICEINFOS]; uint64_t basevols[LP_MAXPRICEINFOS],relvols[LP_MAXPRICEINFOS]; if ( rval == 0 ) rval = (LP_rand() % 300) + 60; if ( starttime > endtime ) @@ -468,6 +468,10 @@ cJSON *LP_statslog_disp(uint32_t starttime,uint32_t endtime,char *refgui,bits256 LP_stats_dispiter(array,sp,starttime,endtime,refbase,refrel,refgui,refpubkey); LP_swapscount++; } + HASH_ITER(hh,LP_pubkeyinfos,pubp,ptmp) + { + pubp->dynamictrust = LP_dynamictrust(pubp->pubkey,0); + } //printf("RT.%d completed.%d\n",LP_RTcount,LP_swapscount); jadd(retjson,"swaps",array); jaddnum(retjson,"RTcount",LP_RTcount); From 6cb530d5094dd594754a36c0cc60ab29cd142f3e Mon Sep 17 00:00:00 2001 From: jl777 Date: Wed, 22 Nov 2017 23:02:46 +0400 Subject: [PATCH 1098/1664] Test --- iguana/exchanges/LP_zeroconf.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/iguana/exchanges/LP_zeroconf.c b/iguana/exchanges/LP_zeroconf.c index b9b7a0d68..8c18d9937 100644 --- a/iguana/exchanges/LP_zeroconf.c +++ b/iguana/exchanges/LP_zeroconf.c @@ -258,7 +258,7 @@ int64_t LP_dynamictrust(bits256 pubkey,int64_t kmdvalue) if ( (sp= ptr->swap) != 0 && sp->finished == 0 && sp->expired == 0 ) swaps_kmdvalue += LP_kmdvalue(sp->Q.destcoin,sp->Q.destsatoshis); } - printf("credits %.8f vs (%.8f + current %.8f)\n",dstr(ap->zeroconf_credits),dstr(swaps_kmdvalue),dstr(kmdvalue)); + //printf("credits %.8f vs (%.8f + current %.8f)\n",dstr(ap->zeroconf_credits),dstr(swaps_kmdvalue),dstr(kmdvalue)); if ( ap->zeroconf_credits > swaps_kmdvalue+kmdvalue ) return(ap->zeroconf_credits - (swaps_kmdvalue+kmdvalue)); } From ff779558bc306f696fed4d7fab4874d5453a6b30 Mon Sep 17 00:00:00 2001 From: jl777 Date: Thu, 23 Nov 2017 00:10:01 +0400 Subject: [PATCH 1099/1664] Test --- iguana/exchanges/LP_nativeDEX.c | 15 +++++++++++++++ iguana/exchanges/deposit | 2 +- iguana/exchanges/deposit1 | 3 +++ 3 files changed, 19 insertions(+), 1 deletion(-) create mode 100755 iguana/exchanges/deposit1 diff --git a/iguana/exchanges/LP_nativeDEX.c b/iguana/exchanges/LP_nativeDEX.c index 3b75576d8..cf2682003 100644 --- a/iguana/exchanges/LP_nativeDEX.c +++ b/iguana/exchanges/LP_nativeDEX.c @@ -24,6 +24,21 @@ // https://github.com/bitcoin/bips/blob/master/bip-0143.mediawiki for signing BCH/BTG // // bugs, validations: +/*Buyer Payment 08ccac7534dc6aad0139b7dd6a78344d309fbc6bff27f2fba7c8f178f5d309a0 + +Seller Payment f876412f3dc637998b099b05ae0fe3e769e5adafcb49ef156be9f7749f2e3071 + +Quote ID 2681103143 +Request ID 301413467 +Trade id 3567859514*/ +/*KMD.(electrum2.cipig.net:10001) already an electrum server +KMD.(electrum1.cipig.net:10001) already an electrum server +bindflag.0 iguana_socket mismatch (18.216.195.109) -> (electrum1.cipig.net) +RECONNECT ep.0x7f46950fbbd0 KMD numerrors.32 too big -> new electrum1.cipig.net:10001 sock.110 +KMD.(electrum2.cipig.net:10001) already an electrum server +KMD.(electrum1.cipig.net:10001) already an electrum server +KMD.(electrum2.cipig.net:10001) already an electrum server +KMD.(electrum1.cipig.net:10001) already an electrum serve*/ // waiting for alice and alice disconnects // MNZ getcoin strangeness // portfolio value based on ask? diff --git a/iguana/exchanges/deposit b/iguana/exchanges/deposit index dae61c47a..1fe7c6138 100755 --- a/iguana/exchanges/deposit +++ b/iguana/exchanges/deposit @@ -1,3 +1,3 @@ #!/bin/bash source userpass -curl --url "http://127.0.0.1:7783" --data "{\"userpass\":\"$userpass\",\"method\":\"zeroconf_deposit\",\"numweeks\":0,\"amount\":10.0,\"broadcast\":1}" +curl --url "http://127.0.0.1:7783" --data "{\"userpass\":\"$userpass\",\"method\":\"zeroconf_deposit\",\"weeks\":0,\"amount\":10.0,\"broadcast\":1}" diff --git a/iguana/exchanges/deposit1 b/iguana/exchanges/deposit1 new file mode 100755 index 000000000..c82178e79 --- /dev/null +++ b/iguana/exchanges/deposit1 @@ -0,0 +1,3 @@ +#!/bin/bash +source userpass +curl --url "http://127.0.0.1:7783" --data "{\"userpass\":\"$userpass\",\"method\":\"zeroconf_deposit\",\"weeks\":1,\"amount\":10.0,\"broadcast\":1}" From 3b3f2c3e69e417480523f0542ce31d4f78a57cce Mon Sep 17 00:00:00 2001 From: jl777 Date: Thu, 23 Nov 2017 00:13:09 +0400 Subject: [PATCH 1100/1664] Test --- iguana/exchanges/LP_nativeDEX.c | 1 + 1 file changed, 1 insertion(+) diff --git a/iguana/exchanges/LP_nativeDEX.c b/iguana/exchanges/LP_nativeDEX.c index cf2682003..36acf3ba2 100644 --- a/iguana/exchanges/LP_nativeDEX.c +++ b/iguana/exchanges/LP_nativeDEX.c @@ -571,6 +571,7 @@ void LP_coinsloop(void *_coins) } HASH_ITER(hh,coin->addresses,ap,atmp) { + break; //printf("call unspent %s\n",ap->coinaddr); if ( strcmp(coin->smartaddr,ap->coinaddr) != 0 && (retjson= electrum_address_listunspent(coin->symbol,ep,&retjson,ap->coinaddr,1)) != 0 ) free_json(retjson); From 6b22cdc9270d463e184ab32ba3c0ccea3dec590b Mon Sep 17 00:00:00 2001 From: jl777 Date: Thu, 23 Nov 2017 00:22:00 +0400 Subject: [PATCH 1101/1664] Test --- iguana/exchanges/LP_zeroconf.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/iguana/exchanges/LP_zeroconf.c b/iguana/exchanges/LP_zeroconf.c index 8c18d9937..a000fd239 100644 --- a/iguana/exchanges/LP_zeroconf.c +++ b/iguana/exchanges/LP_zeroconf.c @@ -209,7 +209,7 @@ void LP_zeroconf_deposits(struct iguana_info *coin) cJSON *array,*item,*txjson,*vouts,*v,*txobj; int32_t i,n,numvouts,height,vout,weeki; bits256 txid; char destaddr[64],p2shaddr[64]; int64_t satoshis,amount64; if ( (array= LP_listunspent("KMD",BOTS_BONDADDRESS)) != 0 ) { - //printf("ZEROCONF.(%s)\n",jprint(array,0)); + printf("ZEROCONF.(%s)\n",jprint(array,0)); if ( (n= cJSON_GetArraySize(array)) > 0 ) { for (i=0; i Date: Thu, 23 Nov 2017 00:27:49 +0400 Subject: [PATCH 1102/1664] Test --- iguana/exchanges/LP_zeroconf.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/iguana/exchanges/LP_zeroconf.c b/iguana/exchanges/LP_zeroconf.c index a000fd239..8423dc2d5 100644 --- a/iguana/exchanges/LP_zeroconf.c +++ b/iguana/exchanges/LP_zeroconf.c @@ -196,7 +196,7 @@ void LP_zeroconf_credit(char *coinaddr,uint64_t satoshis,int32_t weeki,char *p2s if ( coin != 0 ) { timestamp = LP_FIRSTWEEKTIME + weeki*LP_WEEKMULT; - if ( time(NULL) < timestamp-24*3600 && (ap= LP_address(coin,coinaddr)) != 0 ) + if ( (ap= LP_address(coin,coinaddr)) != 0 ) //time(NULL) < timestamp-24*3600 && { ap->zeroconf_credits += satoshis; printf("ZEROCONF credit.(%s) %.8f weeki.%d (%s) -> sum %.8f\n",coinaddr,dstr(satoshis),weeki,p2shaddr,dstr(ap->zeroconf_credits)); @@ -219,6 +219,7 @@ void LP_zeroconf_deposits(struct iguana_info *coin) if ( vout == 1 ) { weeki = (amount64 % 10000); + printf("weeki.%d %.8f %s\n",weeki,dstr(amount64),jprint(item,0)); if ( weeki >= 0 && (txjson= LP_gettx(coin->symbol,txid)) != 0 ) { if ( (vouts= jarray(&numvouts,txjson,"vout")) > 0 && numvouts >= 3 && LP_destaddr(destaddr,jitem(vouts,2)) == 0 ) From 35e6266673fc14a379ce5e2c463757ff1ec200cf Mon Sep 17 00:00:00 2001 From: jl777 Date: Thu, 23 Nov 2017 00:29:54 +0400 Subject: [PATCH 1103/1664] Test --- iguana/exchanges/LP_zeroconf.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/iguana/exchanges/LP_zeroconf.c b/iguana/exchanges/LP_zeroconf.c index 8423dc2d5..19ff644de 100644 --- a/iguana/exchanges/LP_zeroconf.c +++ b/iguana/exchanges/LP_zeroconf.c @@ -200,7 +200,7 @@ void LP_zeroconf_credit(char *coinaddr,uint64_t satoshis,int32_t weeki,char *p2s { ap->zeroconf_credits += satoshis; printf("ZEROCONF credit.(%s) %.8f weeki.%d (%s) -> sum %.8f\n",coinaddr,dstr(satoshis),weeki,p2shaddr,dstr(ap->zeroconf_credits)); - } + } else printf("couldnt create address.%s\n",coinaddr); } } @@ -226,6 +226,7 @@ void LP_zeroconf_deposits(struct iguana_info *coin) { v = jitem(vouts,0); satoshis = LP_value_extract(v,0); + printf("%s funded %.8f\n",destaddr,dstr(satoshis)); if ( LP_destaddr(p2shaddr,v) == 0 ) { if ( (txobj= LP_gettxout(coin->symbol,p2shaddr,txid,0)) == 0 ) From 4ea16f22cfa6ada34a7502cd6180bb65232ee4cb Mon Sep 17 00:00:00 2001 From: jl777 Date: Thu, 23 Nov 2017 11:32:21 +0400 Subject: [PATCH 1104/1664] Test --- iguana/exchanges/LP_nativeDEX.c | 1 + iguana/exchanges/stats.c | 2 +- 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/iguana/exchanges/LP_nativeDEX.c b/iguana/exchanges/LP_nativeDEX.c index 36acf3ba2..b58545fe1 100644 --- a/iguana/exchanges/LP_nativeDEX.c +++ b/iguana/exchanges/LP_nativeDEX.c @@ -18,6 +18,7 @@ // marketmaker // // feature requests: +// listtransactions for zeroconf credits in native // alice waiting for bestprice // USD paxprice based USDvalue in portfolio // cancel bid/ask diff --git a/iguana/exchanges/stats.c b/iguana/exchanges/stats.c index 681da52d2..8ad7c94e1 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", "tradestatus" + "orderbook", "help", "getcoins", "pricearray", "balance", "tradesarray" }; int32_t LP_valid_remotemethod(cJSON *argjson) From d7dccbdff74bbd696ca6f7ff05797e71efb459e9 Mon Sep 17 00:00:00 2001 From: jl777 Date: Thu, 23 Nov 2017 11:36:09 +0400 Subject: [PATCH 1105/1664] Test --- iguana/exchanges/LP_commands.c | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/iguana/exchanges/LP_commands.c b/iguana/exchanges/LP_commands.c index 67ace1054..8f8e11968 100644 --- a/iguana/exchanges/LP_commands.c +++ b/iguana/exchanges/LP_commands.c @@ -574,6 +574,10 @@ zeroconf_claim(address, expiration=0)\n\ { if ( strcmp(method,"gettradestatus") == 0 ) return(LP_gettradestatus(j64bits(argjson,"aliceid"))); + else if ( strcmp(method,"tradesarray") == 0 ) + { + return(jprint(LP_tradesarray(base,rel,juint(argjson,"starttime"),juint(argjson,"endtime"),jint(argjson,"timescale")),1)); + } } // received response if ( strcmp(method,"swapstatus") == 0 ) From fcb616b0b2a6a8700fed3ddb328c03f692f3a463 Mon Sep 17 00:00:00 2001 From: jl777 Date: Thu, 23 Nov 2017 11:40:03 +0400 Subject: [PATCH 1106/1664] Btc2kmd --- iguana/exchanges/mm.c | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/iguana/exchanges/mm.c b/iguana/exchanges/mm.c index a87481f15..6bc188982 100644 --- a/iguana/exchanges/mm.c +++ b/iguana/exchanges/mm.c @@ -881,6 +881,14 @@ int main(int argc, const char * argv[]) double profitmargin,maxexposure,incrratio,start_rel,start_base,minask,maxbid,incr; cJSON *retjson,*loginjson; int32_t i; OS_init(); + if ( argc == 2 && strncmp(argv[0],"btc2kmd",7) == 0 ) + { + uint8_t addrtype,rmd160[20]; char coinaddr[64]; + bitcoin_addr2rmd160(0,&addrtype,rmd160,(char *)argv[1]); + bitcoin_address(coinaddr,0,60,rmd160,20); + printf("%s\n",coinaddr); + exit(0); + } sprintf(dirname,"%s",GLOBAL_DBDIR), OS_ensure_directory(dirname); sprintf(dirname,"%s/SWAPS",GLOBAL_DBDIR), OS_ensure_directory(dirname); sprintf(dirname,"%s/PRICES",GLOBAL_DBDIR), OS_ensure_directory(dirname); From c672b8a8197e5ac8a7e4d8af413e62827f3500ee Mon Sep 17 00:00:00 2001 From: jl777 Date: Thu, 23 Nov 2017 11:42:21 +0400 Subject: [PATCH 1107/1664] Test --- iguana/exchanges/mm.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/iguana/exchanges/mm.c b/iguana/exchanges/mm.c index 6bc188982..5cc959751 100644 --- a/iguana/exchanges/mm.c +++ b/iguana/exchanges/mm.c @@ -881,7 +881,7 @@ int main(int argc, const char * argv[]) double profitmargin,maxexposure,incrratio,start_rel,start_base,minask,maxbid,incr; cJSON *retjson,*loginjson; int32_t i; OS_init(); - if ( argc == 2 && strncmp(argv[0],"btc2kmd",7) == 0 ) + if ( strncmp(argv[0],"btc2kmd",7) == 0 && argv[1] != 0 ) { uint8_t addrtype,rmd160[20]; char coinaddr[64]; bitcoin_addr2rmd160(0,&addrtype,rmd160,(char *)argv[1]); From ca6e96b07046ea97712b8cd04f2571b6c360a9a1 Mon Sep 17 00:00:00 2001 From: jl777 Date: Thu, 23 Nov 2017 11:43:16 +0400 Subject: [PATCH 1108/1664] Test --- iguana/exchanges/mm.c | 1 + 1 file changed, 1 insertion(+) diff --git a/iguana/exchanges/mm.c b/iguana/exchanges/mm.c index 5cc959751..275a3ad88 100644 --- a/iguana/exchanges/mm.c +++ b/iguana/exchanges/mm.c @@ -881,6 +881,7 @@ int main(int argc, const char * argv[]) double profitmargin,maxexposure,incrratio,start_rel,start_base,minask,maxbid,incr; cJSON *retjson,*loginjson; int32_t i; OS_init(); + printf("%s\n",(char *)argv[0]); if ( strncmp(argv[0],"btc2kmd",7) == 0 && argv[1] != 0 ) { uint8_t addrtype,rmd160[20]; char coinaddr[64]; From 1f7b0d879ca1f7c4e4e1487d4153fe825431673f Mon Sep 17 00:00:00 2001 From: jl777 Date: Thu, 23 Nov 2017 11:43:55 +0400 Subject: [PATCH 1109/1664] Test --- iguana/exchanges/mm.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/iguana/exchanges/mm.c b/iguana/exchanges/mm.c index 275a3ad88..5d392f002 100644 --- a/iguana/exchanges/mm.c +++ b/iguana/exchanges/mm.c @@ -882,7 +882,7 @@ int main(int argc, const char * argv[]) cJSON *retjson,*loginjson; int32_t i; OS_init(); printf("%s\n",(char *)argv[0]); - if ( strncmp(argv[0],"btc2kmd",7) == 0 && argv[1] != 0 ) + if ( strstr("btc2kmd",argv[0]) != 0 && argv[1] != 0 ) { uint8_t addrtype,rmd160[20]; char coinaddr[64]; bitcoin_addr2rmd160(0,&addrtype,rmd160,(char *)argv[1]); From e99951fd1fa0a3a93cad41cdaf39a5705b8a16fa Mon Sep 17 00:00:00 2001 From: jl777 Date: Thu, 23 Nov 2017 11:44:16 +0400 Subject: [PATCH 1110/1664] Test --- iguana/exchanges/mm.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/iguana/exchanges/mm.c b/iguana/exchanges/mm.c index 5d392f002..650aecaa3 100644 --- a/iguana/exchanges/mm.c +++ b/iguana/exchanges/mm.c @@ -882,7 +882,7 @@ int main(int argc, const char * argv[]) cJSON *retjson,*loginjson; int32_t i; OS_init(); printf("%s\n",(char *)argv[0]); - if ( strstr("btc2kmd",argv[0]) != 0 && argv[1] != 0 ) + if ( strstr(argv[0],"btc2kmd") != 0 && argv[1] != 0 ) { uint8_t addrtype,rmd160[20]; char coinaddr[64]; bitcoin_addr2rmd160(0,&addrtype,rmd160,(char *)argv[1]); From 3d047108c98e80f0bcbba5ae465b70e99fec5bdf Mon Sep 17 00:00:00 2001 From: jl777 Date: Thu, 23 Nov 2017 11:47:44 +0400 Subject: [PATCH 1111/1664] Test --- iguana/exchanges/mm.c | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/iguana/exchanges/mm.c b/iguana/exchanges/mm.c index 650aecaa3..46d64c15b 100644 --- a/iguana/exchanges/mm.c +++ b/iguana/exchanges/mm.c @@ -881,13 +881,15 @@ int main(int argc, const char * argv[]) double profitmargin,maxexposure,incrratio,start_rel,start_base,minask,maxbid,incr; cJSON *retjson,*loginjson; int32_t i; OS_init(); - printf("%s\n",(char *)argv[0]); if ( strstr(argv[0],"btc2kmd") != 0 && argv[1] != 0 ) { - uint8_t addrtype,rmd160[20]; char coinaddr[64]; + uint8_t addrtype,rmd160[20],rmd160b[20]; char coinaddr[64],coinaddr2[64],coinaddr3[64]; bitcoin_addr2rmd160(0,&addrtype,rmd160,(char *)argv[1]); bitcoin_address(coinaddr,0,60,rmd160,20); - printf("%s\n",coinaddr); + bitcoin_address(coinaddr2,0,0,rmd160,20); + bitcoin_addr2rmd160(0,&addrtype,rmd160b,coinaddr); + bitcoin_address(coinaddr3,0,0,rmd160b,20); + printf("%s %s %s\n",coinaddr,coinaddr2,coinaddr3); exit(0); } sprintf(dirname,"%s",GLOBAL_DBDIR), OS_ensure_directory(dirname); From 2223d2fcc49d173084e695bf83995e25b6852970 Mon Sep 17 00:00:00 2001 From: jl777 Date: Thu, 23 Nov 2017 11:50:10 +0400 Subject: [PATCH 1112/1664] Test --- iguana/exchanges/mm.c | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/iguana/exchanges/mm.c b/iguana/exchanges/mm.c index 46d64c15b..f4d147131 100644 --- a/iguana/exchanges/mm.c +++ b/iguana/exchanges/mm.c @@ -883,13 +883,14 @@ int main(int argc, const char * argv[]) OS_init(); if ( strstr(argv[0],"btc2kmd") != 0 && argv[1] != 0 ) { - uint8_t addrtype,rmd160[20],rmd160b[20]; char coinaddr[64],coinaddr2[64],coinaddr3[64]; + uint8_t addrtype,rmd160[20],rmd160b[20]; char coinaddr[64],coinaddr2[64]; bitcoin_addr2rmd160(0,&addrtype,rmd160,(char *)argv[1]); bitcoin_address(coinaddr,0,60,rmd160,20); - bitcoin_address(coinaddr2,0,0,rmd160,20); bitcoin_addr2rmd160(0,&addrtype,rmd160b,coinaddr); - bitcoin_address(coinaddr3,0,0,rmd160b,20); - printf("%s %s %s\n",coinaddr,coinaddr2,coinaddr3); + bitcoin_address(coinaddr2,0,0,rmd160b,20); + printf("(%s) -> %s -> %s\n",(char *)argv[1],coinaddr,coinaddr2); + if ( strcmp((char *)argv[1],coinaddr2) != 0 ) + printf("ERROR\n"); exit(0); } sprintf(dirname,"%s",GLOBAL_DBDIR), OS_ensure_directory(dirname); From ecf073fc533ced9868116aac10a3f0de18431590 Mon Sep 17 00:00:00 2001 From: jl777 Date: Thu, 23 Nov 2017 14:23:41 +0400 Subject: [PATCH 1113/1664] Test --- iguana/exchanges/LP_include.h | 1 + iguana/exchanges/LP_nativeDEX.c | 10 +--------- iguana/exchanges/LP_rpc.c | 30 ++++++++++++++++++++++++++++++ iguana/exchanges/LP_zeroconf.c | 33 ++++++++++++++++++--------------- 4 files changed, 50 insertions(+), 24 deletions(-) diff --git a/iguana/exchanges/LP_include.h b/iguana/exchanges/LP_include.h index 0197bd72a..c3c66761d 100644 --- a/iguana/exchanges/LP_include.h +++ b/iguana/exchanges/LP_include.h @@ -460,6 +460,7 @@ 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); 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); diff --git a/iguana/exchanges/LP_nativeDEX.c b/iguana/exchanges/LP_nativeDEX.c index b58545fe1..5655b7ca8 100644 --- a/iguana/exchanges/LP_nativeDEX.c +++ b/iguana/exchanges/LP_nativeDEX.c @@ -32,15 +32,7 @@ Seller Payment f876412f3dc637998b099b05ae0fe3e769e5adafcb49ef156be9f7749f2e30 Quote ID 2681103143 Request ID 301413467 Trade id 3567859514*/ -/*KMD.(electrum2.cipig.net:10001) already an electrum server -KMD.(electrum1.cipig.net:10001) already an electrum server -bindflag.0 iguana_socket mismatch (18.216.195.109) -> (electrum1.cipig.net) -RECONNECT ep.0x7f46950fbbd0 KMD numerrors.32 too big -> new electrum1.cipig.net:10001 sock.110 -KMD.(electrum2.cipig.net:10001) already an electrum server -KMD.(electrum1.cipig.net:10001) already an electrum server -KMD.(electrum2.cipig.net:10001) already an electrum server -KMD.(electrum1.cipig.net:10001) already an electrum serve*/ -// waiting for alice and alice disconnects +// waiting for alice and alice disconnects, can find bobpayment based on Q.txid // MNZ getcoin strangeness // portfolio value based on ask? // listunspent triplicate, tradebot timeslice? the tradebot timeslice is just getting too much timeslices diff --git a/iguana/exchanges/LP_rpc.c b/iguana/exchanges/LP_rpc.c index f728262aa..367fb502c 100644 --- a/iguana/exchanges/LP_rpc.c +++ b/iguana/exchanges/LP_rpc.c @@ -673,6 +673,36 @@ cJSON *LP_listunspent(char *symbol,char *coinaddr) } else return(electrum_address_listunspent(symbol,coin->electrum,&retjson,coinaddr,1)); } +cJSON *LP_listreceivedbyaddress(char *symbol,char *coinaddr) +{ + char buf[128],*addr; cJSON *retjson,*array,*item; int32_t i,n; struct iguana_info *coin; + if ( symbol == 0 || symbol[0] == 0 ) + return(cJSON_Parse("{\"error\":\"null symbol\"}")); + coin = LP_coinfind(symbol); + if ( coin == 0 || (IAMLP == 0 && coin->inactive != 0) ) + return(cJSON_Parse("{\"error\":\"no coin\"}")); + if ( coin->electrum == 0 ) + { + if ( (array= bitcoin_json(coin,"listreceivedbyaddress",buf)) != 0 ) + { + if ( (n= cJSON_GetArraySize(array)) > 0 ) + { + for (i=0; ielectrum,&retjson,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; diff --git a/iguana/exchanges/LP_zeroconf.c b/iguana/exchanges/LP_zeroconf.c index 19ff644de..9b639bae3 100644 --- a/iguana/exchanges/LP_zeroconf.c +++ b/iguana/exchanges/LP_zeroconf.c @@ -207,35 +207,38 @@ void LP_zeroconf_credit(char *coinaddr,uint64_t satoshis,int32_t weeki,char *p2s void LP_zeroconf_deposits(struct iguana_info *coin) { cJSON *array,*item,*txjson,*vouts,*v,*txobj; int32_t i,n,numvouts,height,vout,weeki; bits256 txid; char destaddr[64],p2shaddr[64]; int64_t satoshis,amount64; - if ( (array= LP_listunspent("KMD",BOTS_BONDADDRESS)) != 0 ) + if ( (array= LP_listreceivedbyaddress("KMD",BOTS_BONDADDRESS)) != 0 ) { printf("ZEROCONF.(%s)\n",jprint(array,0)); if ( (n= cJSON_GetArraySize(array)) > 0 ) { for (i=0; ielectrum != 0 ) { - weeki = (amount64 % 10000); - printf("weeki.%d %.8f %s\n",weeki,dstr(amount64),jprint(item,0)); - if ( weeki >= 0 && (txjson= LP_gettx(coin->symbol,txid)) != 0 ) + item = jitem(array,i); + LP_listunspent_parseitem(coin,&txid,&vout,&height,item); + } else txid = jbits256i(array,i); + if ( (txjson= LP_gettx(coin->symbol,txid)) != 0 ) + { + // vout0 deposit, vout1 botsfee, vout2 smartaddress + if ( (vouts= jarray(&numvouts,txjson,"vout")) > 0 && numvouts >= 3 && LP_destaddr(destaddr,jitem(vouts,2)) == 0 ) { - if ( (vouts= jarray(&numvouts,txjson,"vout")) > 0 && numvouts >= 3 && LP_destaddr(destaddr,jitem(vouts,2)) == 0 ) + amount64 = LP_value_extract(jitem(vouts,1),0); + weeki = (amount64 % 10000); + v = jitem(vouts,0); + satoshis = LP_value_extract(v,0); + printf("%s funded %.8f weeki.%d\n",destaddr,dstr(satoshis),weeki); + if ( LP_destaddr(p2shaddr,v) == 0 ) { - v = jitem(vouts,0); - satoshis = LP_value_extract(v,0); - printf("%s funded %.8f\n",destaddr,dstr(satoshis)); - if ( LP_destaddr(p2shaddr,v) == 0 ) + if ( (txobj= LP_gettxout(coin->symbol,p2shaddr,txid,0)) != 0 ) { - if ( (txobj= LP_gettxout(coin->symbol,p2shaddr,txid,0)) == 0 ) - continue; - else free_json(txobj); + free_json(txobj); LP_zeroconf_credit(destaddr,satoshis,weeki,p2shaddr); } } } + free_json(txjson); } } } From 129ff364f13e74758cf71455f2c0b45233755046 Mon Sep 17 00:00:00 2001 From: jl777 Date: Thu, 23 Nov 2017 14:25:22 +0400 Subject: [PATCH 1114/1664] Test --- iguana/exchanges/LP_rpc.c | 1 + 1 file changed, 1 insertion(+) diff --git a/iguana/exchanges/LP_rpc.c b/iguana/exchanges/LP_rpc.c index 367fb502c..5dfa79c0f 100644 --- a/iguana/exchanges/LP_rpc.c +++ b/iguana/exchanges/LP_rpc.c @@ -683,6 +683,7 @@ cJSON *LP_listreceivedbyaddress(char *symbol,char *coinaddr) return(cJSON_Parse("{\"error\":\"no coin\"}")); if ( coin->electrum == 0 ) { + sprintf(buf,"[1, false, true]"); if ( (array= bitcoin_json(coin,"listreceivedbyaddress",buf)) != 0 ) { if ( (n= cJSON_GetArraySize(array)) > 0 ) From f1a4e490c54fafabdbe2c240c004473b11aa7a38 Mon Sep 17 00:00:00 2001 From: jl777 Date: Thu, 23 Nov 2017 14:47:30 +0400 Subject: [PATCH 1115/1664] Test --- iguana/exchanges/LP_include.h | 2 +- iguana/exchanges/LP_nativeDEX.c | 5 +++++ iguana/exchanges/LP_zeroconf.c | 6 +++--- iguana/exchanges/stats.c | 3 +++ 4 files changed, 12 insertions(+), 4 deletions(-) diff --git a/iguana/exchanges/LP_include.h b/iguana/exchanges/LP_include.h index c3c66761d..e8ba59f54 100644 --- a/iguana/exchanges/LP_include.h +++ b/iguana/exchanges/LP_include.h @@ -273,7 +273,7 @@ struct iguana_info 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; + uint32_t loadedcache,electrumlist,lastunspent,importedprivkey,lastpushtime,lastutxosync,addr_listunspent_requested,lastutxos,updaterate,counter,inactive,lastmempool,lastgetinfo,ratetime,heighttime,lastmonitor,obooktime,electrumzeroconf; uint8_t pubtype,p2shtype,isPoS,wiftype,wiftaddr,taddr,noimportprivkey_flag,userconfirms,isassetchain,maxconfirms; char symbol[128],smartaddr[64],userpass[1024],serverport[128]; // portfolio diff --git a/iguana/exchanges/LP_nativeDEX.c b/iguana/exchanges/LP_nativeDEX.c index 5655b7ca8..518e9248b 100644 --- a/iguana/exchanges/LP_nativeDEX.c +++ b/iguana/exchanges/LP_nativeDEX.c @@ -555,6 +555,11 @@ void LP_coinsloop(void *_coins) coin->longestchain = LP_getheight(coin); if ( (ep= coin->electrum) != 0 ) { + if ( strcmp("KMD",coin->symbol) == 0 && coin->electrumzeroconf == 0 ) + { + LP_zeroconf_deposits(coin); + coin->electrumzeroconf = (uint32_t)time(NULL); + } if ( (backupep= ep->prev) == 0 ) backupep = ep; if ( (ap= LP_addressfind(coin,coin->smartaddr)) != 0 ) diff --git a/iguana/exchanges/LP_zeroconf.c b/iguana/exchanges/LP_zeroconf.c index 9b639bae3..bd2d09a9f 100644 --- a/iguana/exchanges/LP_zeroconf.c +++ b/iguana/exchanges/LP_zeroconf.c @@ -196,7 +196,7 @@ void LP_zeroconf_credit(char *coinaddr,uint64_t satoshis,int32_t weeki,char *p2s if ( coin != 0 ) { timestamp = LP_FIRSTWEEKTIME + weeki*LP_WEEKMULT; - if ( (ap= LP_address(coin,coinaddr)) != 0 ) //time(NULL) < timestamp-24*3600 && + if ( time(NULL) < timestamp-24*3600 && (ap= LP_address(coin,coinaddr)) != 0 ) { ap->zeroconf_credits += satoshis; printf("ZEROCONF credit.(%s) %.8f weeki.%d (%s) -> sum %.8f\n",coinaddr,dstr(satoshis),weeki,p2shaddr,dstr(ap->zeroconf_credits)); @@ -209,7 +209,7 @@ void LP_zeroconf_deposits(struct iguana_info *coin) cJSON *array,*item,*txjson,*vouts,*v,*txobj; int32_t i,n,numvouts,height,vout,weeki; bits256 txid; char destaddr[64],p2shaddr[64]; int64_t satoshis,amount64; if ( (array= LP_listreceivedbyaddress("KMD",BOTS_BONDADDRESS)) != 0 ) { - printf("ZEROCONF.(%s)\n",jprint(array,0)); + //printf("ZEROCONF.(%s)\n",jprint(array,0)); if ( (n= cJSON_GetArraySize(array)) > 0 ) { for (i=0; isymbol,p2shaddr,txid,0)) != 0 ) diff --git a/iguana/exchanges/stats.c b/iguana/exchanges/stats.c index 8ad7c94e1..a8a1c23ac 100644 --- a/iguana/exchanges/stats.c +++ b/iguana/exchanges/stats.c @@ -624,10 +624,12 @@ void LP_rpc_processreq(void *_ptr) printf("EAGAIN for len %d, remains.%d\n",len,remains); usleep(10000); } + printf("errno.%d len.%d remains.%d\n",errno,len,remains); break; } else { + printf("received len.%d\n",len); if ( len > 0 ) { buf[len] = 0; @@ -787,6 +789,7 @@ void stats_rpcloop(void *args) memcpy(&ipbits,&cli_addr.sin_addr.s_addr,sizeof(ipbits)); if ( port == RPC_port && ipbits != localhostbits ) { + printf("port.%u RPC_port.%u ipbits %x != %x\n",port,RPC_port,ipbits,localhostbits); closesocket(sock); continue; } From af0342c10184dab4cb8f292e335cd19e3d1ed3b0 Mon Sep 17 00:00:00 2001 From: jl777 Date: Thu, 23 Nov 2017 14:49:54 +0400 Subject: [PATCH 1116/1664] Test --- iguana/exchanges/stats.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/iguana/exchanges/stats.c b/iguana/exchanges/stats.c index a8a1c23ac..b3811c906 100644 --- a/iguana/exchanges/stats.c +++ b/iguana/exchanges/stats.c @@ -629,7 +629,7 @@ void LP_rpc_processreq(void *_ptr) } else { - printf("received len.%d\n",len); + printf("received len.%d\n%s\n",len,buf); if ( len > 0 ) { buf[len] = 0; From ad64b5a4efdd3af4b781267e17fe061184994c60 Mon Sep 17 00:00:00 2001 From: jl777 Date: Thu, 23 Nov 2017 15:24:17 +0400 Subject: [PATCH 1117/1664] Test --- iguana/exchanges/LP_nativeDEX.c | 1 - iguana/exchanges/LP_zeroconf.c | 3 ++- iguana/exchanges/stats.c | 4 ++-- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/iguana/exchanges/LP_nativeDEX.c b/iguana/exchanges/LP_nativeDEX.c index 518e9248b..70deb5af1 100644 --- a/iguana/exchanges/LP_nativeDEX.c +++ b/iguana/exchanges/LP_nativeDEX.c @@ -18,7 +18,6 @@ // marketmaker // // feature requests: -// listtransactions for zeroconf credits in native // alice waiting for bestprice // USD paxprice based USDvalue in portfolio // cancel bid/ask diff --git a/iguana/exchanges/LP_zeroconf.c b/iguana/exchanges/LP_zeroconf.c index bd2d09a9f..f20d5e6df 100644 --- a/iguana/exchanges/LP_zeroconf.c +++ b/iguana/exchanges/LP_zeroconf.c @@ -251,6 +251,7 @@ int64_t LP_dynamictrust(bits256 pubkey,int64_t kmdvalue) struct LP_pubswap *ptr,*tmp; struct LP_swapstats *sp; struct LP_pubkey_info *pubp; struct LP_address *ap; char coinaddr[64]; struct iguana_info *coin; int64_t swaps_kmdvalue = 0; if ( (coin= LP_coinfind("KMD")) != 0 && (pubp= LP_pubkeyfind(pubkey)) != 0 ) { + bitcoin_address(coinaddr,coin->taddr,coin->pubtype,pubp->pubsecp,33); if ((ap= LP_address(coin,coinaddr)) != 0 && ap->zeroconf_credits >= kmdvalue ) { DL_FOREACH_SAFE(pubp->bobswaps,ptr,tmp) @@ -263,7 +264,7 @@ int64_t LP_dynamictrust(bits256 pubkey,int64_t kmdvalue) if ( (sp= ptr->swap) != 0 && sp->finished == 0 && sp->expired == 0 ) swaps_kmdvalue += LP_kmdvalue(sp->Q.destcoin,sp->Q.destsatoshis); } - //printf("credits %.8f vs (%.8f + current %.8f)\n",dstr(ap->zeroconf_credits),dstr(swaps_kmdvalue),dstr(kmdvalue)); + printf("%s zeroconf_credits %.8f vs (%.8f + current %.8f)\n",coinaddr,dstr(ap->zeroconf_credits),dstr(swaps_kmdvalue),dstr(kmdvalue)); if ( ap->zeroconf_credits > swaps_kmdvalue+kmdvalue ) return(ap->zeroconf_credits - (swaps_kmdvalue+kmdvalue)); } diff --git a/iguana/exchanges/stats.c b/iguana/exchanges/stats.c index b3811c906..f9a11c97a 100644 --- a/iguana/exchanges/stats.c +++ b/iguana/exchanges/stats.c @@ -624,7 +624,7 @@ void LP_rpc_processreq(void *_ptr) printf("EAGAIN for len %d, remains.%d\n",len,remains); usleep(10000); } - printf("errno.%d len.%d remains.%d\n",errno,len,remains); + //printf("errno.%d len.%d remains.%d\n",errno,len,remains); break; } else @@ -789,7 +789,7 @@ void stats_rpcloop(void *args) memcpy(&ipbits,&cli_addr.sin_addr.s_addr,sizeof(ipbits)); if ( port == RPC_port && ipbits != localhostbits ) { - printf("port.%u RPC_port.%u ipbits %x != %x\n",port,RPC_port,ipbits,localhostbits); + //printf("port.%u RPC_port.%u ipbits %x != %x\n",port,RPC_port,ipbits,localhostbits); closesocket(sock); continue; } From cbda9230f648e6a0d23ec2facb973234c600f794 Mon Sep 17 00:00:00 2001 From: jl777 Date: Thu, 23 Nov 2017 15:27:29 +0400 Subject: [PATCH 1118/1664] Test --- iguana/exchanges/LP_zeroconf.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/iguana/exchanges/LP_zeroconf.c b/iguana/exchanges/LP_zeroconf.c index f20d5e6df..e43e6f807 100644 --- a/iguana/exchanges/LP_zeroconf.c +++ b/iguana/exchanges/LP_zeroconf.c @@ -200,7 +200,7 @@ void LP_zeroconf_credit(char *coinaddr,uint64_t satoshis,int32_t weeki,char *p2s { ap->zeroconf_credits += satoshis; printf("ZEROCONF credit.(%s) %.8f weeki.%d (%s) -> sum %.8f\n",coinaddr,dstr(satoshis),weeki,p2shaddr,dstr(ap->zeroconf_credits)); - } else printf("couldnt create address.%s\n",coinaddr); + } } } @@ -264,7 +264,7 @@ int64_t LP_dynamictrust(bits256 pubkey,int64_t kmdvalue) if ( (sp= ptr->swap) != 0 && sp->finished == 0 && sp->expired == 0 ) swaps_kmdvalue += LP_kmdvalue(sp->Q.destcoin,sp->Q.destsatoshis); } - printf("%s zeroconf_credits %.8f vs (%.8f + current %.8f)\n",coinaddr,dstr(ap->zeroconf_credits),dstr(swaps_kmdvalue),dstr(kmdvalue)); + //printf("%s zeroconf_credits %.8f vs (%.8f + current %.8f)\n",coinaddr,dstr(ap->zeroconf_credits),dstr(swaps_kmdvalue),dstr(kmdvalue)); if ( ap->zeroconf_credits > swaps_kmdvalue+kmdvalue ) return(ap->zeroconf_credits - (swaps_kmdvalue+kmdvalue)); } From 184d8512bd376caa56e3daeffe4f8eb813277203 Mon Sep 17 00:00:00 2001 From: jl777 Date: Thu, 23 Nov 2017 15:32:00 +0400 Subject: [PATCH 1119/1664] Test --- iguana/exchanges/LP_stats.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/iguana/exchanges/LP_stats.c b/iguana/exchanges/LP_stats.c index b7d9323ee..9dcc9e113 100644 --- a/iguana/exchanges/LP_stats.c +++ b/iguana/exchanges/LP_stats.c @@ -368,10 +368,11 @@ char *LP_swapstatus_recv(cJSON *argjson) sp->lasttime = (uint32_t)time(NULL); if ( (methodind= jint(argjson,"ind")) > sp->methodind && methodind < sizeof(LP_stats_methods)/sizeof(*LP_stats_methods) ) { + if ( sp->finished == 0 && sp->expired == 0 ) + printf("SWAPSTATUS updated %llu %s %u %u\n",(long long)sp->aliceid,LP_stats_methods[sp->methodind],juint(argjson,"finished"),juint(argjson,"expired")); sp->methodind = methodind; sp->finished = juint(argjson,"finished"); sp->expired = juint(argjson,"expired"); - printf("SWAPSTATUS updated %llu %s %u %u\n",(long long)sp->aliceid,LP_stats_methods[sp->methodind],sp->finished,sp->expired); } } return(clonestr("{\"result\":\"success\"}")); From 210fac22ac4c7461404ab6f5b21b0318204af460 Mon Sep 17 00:00:00 2001 From: jl777 Date: Thu, 23 Nov 2017 15:35:07 +0400 Subject: [PATCH 1120/1664] Test --- iguana/exchanges/LP_stats.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/iguana/exchanges/LP_stats.c b/iguana/exchanges/LP_stats.c index 9dcc9e113..096c02d0a 100644 --- a/iguana/exchanges/LP_stats.c +++ b/iguana/exchanges/LP_stats.c @@ -251,7 +251,7 @@ int32_t LP_statslog_parsequote(char *method,cJSON *lineobj) } } if ( flag == 0 ) - printf("unexpected.%d tradestatus.(%s)\n",unexpected++,jprint(lineobj,0)); + printf("unexpected.%d tradestatus\n",unexpected++);//,jprint(lineobj,0)); return(0); } if ( LP_quoteparse(&Q,lineobj) < 0 ) From d7537498fca216b7fa093b11a33cbcf717dc76bc Mon Sep 17 00:00:00 2001 From: jl777 Date: Thu, 23 Nov 2017 15:35:43 +0400 Subject: [PATCH 1121/1664] Test --- iguana/exchanges/stats.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/iguana/exchanges/stats.c b/iguana/exchanges/stats.c index f9a11c97a..ddea6722e 100644 --- a/iguana/exchanges/stats.c +++ b/iguana/exchanges/stats.c @@ -629,7 +629,7 @@ void LP_rpc_processreq(void *_ptr) } else { - printf("received len.%d\n%s\n",len,buf); + //printf("received len.%d\n%s\n",len,buf); if ( len > 0 ) { buf[len] = 0; From 948d07abe0aef5d67b05d476998644373d6167aa Mon Sep 17 00:00:00 2001 From: jl777 Date: Thu, 23 Nov 2017 15:37:06 +0400 Subject: [PATCH 1122/1664] Test --- iguana/exchanges/LP_stats.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/iguana/exchanges/LP_stats.c b/iguana/exchanges/LP_stats.c index 096c02d0a..3f6c8ee4d 100644 --- a/iguana/exchanges/LP_stats.c +++ b/iguana/exchanges/LP_stats.c @@ -251,7 +251,7 @@ int32_t LP_statslog_parsequote(char *method,cJSON *lineobj) } } if ( flag == 0 ) - printf("unexpected.%d tradestatus\n",unexpected++);//,jprint(lineobj,0)); + printf("unexpected.%d tradestatus aliceid.%llu\n",unexpected++,(long long)j64bits(lineobj,"aliceid"));//,jprint(lineobj,0)); return(0); } if ( LP_quoteparse(&Q,lineobj) < 0 ) From be93499b2b72b5e64d8dcfad9f51c38cc3ae5fdd Mon Sep 17 00:00:00 2001 From: jl777 Date: Thu, 23 Nov 2017 15:41:49 +0400 Subject: [PATCH 1123/1664] Test --- iguana/exchanges/LP_stats.c | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/iguana/exchanges/LP_stats.c b/iguana/exchanges/LP_stats.c index 3f6c8ee4d..bfb6bb3f9 100644 --- a/iguana/exchanges/LP_stats.c +++ b/iguana/exchanges/LP_stats.c @@ -244,14 +244,16 @@ int32_t LP_statslog_parsequote(char *method,cJSON *lineobj) { sp->methodind = methodind; if ( LP_swapstats_update(sp,&Q,lineobj) == 0 ) + { flag = 1; - else printf("error after delayed match\n"); - break; + break; + } + printf("error after delayed match\n"); } } } if ( flag == 0 ) - printf("unexpected.%d tradestatus aliceid.%llu\n",unexpected++,(long long)j64bits(lineobj,"aliceid"));//,jprint(lineobj,0)); + printf("unexpected.%d tradestatus aliceid.%llu requestid.%u quoteid.%u\n",unexpected++,(long long)aliceid,requestid,quoteid);//,jprint(lineobj,0)); return(0); } if ( LP_quoteparse(&Q,lineobj) < 0 ) From f6766870cb758986d41668a9dcc4654d71a3c53d Mon Sep 17 00:00:00 2001 From: jl777 Date: Thu, 23 Nov 2017 15:45:34 +0400 Subject: [PATCH 1124/1664] test --- iguana/exchanges/LP_stats.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/iguana/exchanges/LP_stats.c b/iguana/exchanges/LP_stats.c index bfb6bb3f9..cdf51c025 100644 --- a/iguana/exchanges/LP_stats.c +++ b/iguana/exchanges/LP_stats.c @@ -235,6 +235,7 @@ int32_t LP_statslog_parsequote(char *method,cJSON *lineobj) sp->methodind = methodind; if ( LP_swapstats_update(sp,&Q,lineobj) == 0 ) flag = 1; + else printf("LP_swapstats_update error\n"); } if ( flag == 0 ) { @@ -301,6 +302,7 @@ int32_t LP_statslog_parsequote(char *method,cJSON *lineobj) } else { + printf("create aliceid.%llu\n",(long long)aliceid); if ( (sp= LP_swapstats_add(aliceid,RTflag)) != 0 ) { sp->Q = Q; From 00f5a101a0abe72809822ae4f2310b344ccc39c5 Mon Sep 17 00:00:00 2001 From: jl777 Date: Thu, 23 Nov 2017 15:49:29 +0400 Subject: [PATCH 1125/1664] Test --- iguana/exchanges/LP_stats.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/iguana/exchanges/LP_stats.c b/iguana/exchanges/LP_stats.c index cdf51c025..b3eb1d2cf 100644 --- a/iguana/exchanges/LP_stats.c +++ b/iguana/exchanges/LP_stats.c @@ -199,7 +199,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 ( 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); } @@ -302,7 +302,7 @@ int32_t LP_statslog_parsequote(char *method,cJSON *lineobj) } else { - printf("create aliceid.%llu\n",(long long)aliceid); + //printf("create aliceid.%llu\n",(long long)aliceid); if ( (sp= LP_swapstats_add(aliceid,RTflag)) != 0 ) { sp->Q = Q; From dd1407cffde6dc787a0f1c2da80ad53078f9cbf2 Mon Sep 17 00:00:00 2001 From: jl777 Date: Thu, 23 Nov 2017 15:51:09 +0400 Subject: [PATCH 1126/1664] Test --- iguana/exchanges/LP_stats.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/iguana/exchanges/LP_stats.c b/iguana/exchanges/LP_stats.c index b3eb1d2cf..2bfaca37f 100644 --- a/iguana/exchanges/LP_stats.c +++ b/iguana/exchanges/LP_stats.c @@ -233,6 +233,8 @@ int32_t LP_statslog_parsequote(char *method,cJSON *lineobj) if ( (sp= LP_swapstats_find(aliceid)) != 0 ) { sp->methodind = methodind; + sp->Q.R.requestid = requestid; + sp->Q.R.quoteid = quoteid; if ( LP_swapstats_update(sp,&Q,lineobj) == 0 ) flag = 1; else printf("LP_swapstats_update error\n"); From 32c0e12011ab61d5776635432c5107feab88a31b Mon Sep 17 00:00:00 2001 From: jl777 Date: Thu, 23 Nov 2017 16:05:28 +0400 Subject: [PATCH 1127/1664] Test --- iguana/exchanges/LP_stats.c | 2 +- iguana/exchanges/LP_zeroconf.c | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/iguana/exchanges/LP_stats.c b/iguana/exchanges/LP_stats.c index 2bfaca37f..9c3dd87cd 100644 --- a/iguana/exchanges/LP_stats.c +++ b/iguana/exchanges/LP_stats.c @@ -237,7 +237,7 @@ int32_t LP_statslog_parsequote(char *method,cJSON *lineobj) sp->Q.R.quoteid = quoteid; if ( LP_swapstats_update(sp,&Q,lineobj) == 0 ) flag = 1; - else printf("LP_swapstats_update error\n"); + //else printf("LP_swapstats_update error\n"); } if ( flag == 0 ) { diff --git a/iguana/exchanges/LP_zeroconf.c b/iguana/exchanges/LP_zeroconf.c index e43e6f807..f013c9965 100644 --- a/iguana/exchanges/LP_zeroconf.c +++ b/iguana/exchanges/LP_zeroconf.c @@ -265,7 +265,7 @@ int64_t LP_dynamictrust(bits256 pubkey,int64_t kmdvalue) swaps_kmdvalue += LP_kmdvalue(sp->Q.destcoin,sp->Q.destsatoshis); } //printf("%s zeroconf_credits %.8f vs (%.8f + current %.8f)\n",coinaddr,dstr(ap->zeroconf_credits),dstr(swaps_kmdvalue),dstr(kmdvalue)); - if ( ap->zeroconf_credits > swaps_kmdvalue+kmdvalue ) + //if ( ap->zeroconf_credits > swaps_kmdvalue+kmdvalue ) return(ap->zeroconf_credits - (swaps_kmdvalue+kmdvalue)); } } From 4adcaa9eee97f450094fc8d785c0567695a26edd Mon Sep 17 00:00:00 2001 From: jl777 Date: Thu, 23 Nov 2017 16:13:03 +0400 Subject: [PATCH 1128/1664] Test --- iguana/exchanges/LP_commands.c | 16 ++++++++++++++++ iguana/exchanges/LP_zeroconf.c | 8 ++++++-- 2 files changed, 22 insertions(+), 2 deletions(-) diff --git a/iguana/exchanges/LP_commands.c b/iguana/exchanges/LP_commands.c index 8f8e11968..2df539365 100644 --- a/iguana/exchanges/LP_commands.c +++ b/iguana/exchanges/LP_commands.c @@ -292,6 +292,22 @@ zeroconf_claim(address, expiration=0)\n\ return(basilisk_swapentries(base,rel,jint(argjson,"limit"))); else return(basilisk_swaplist(0,0)); } + else if ( strcmp(method,"dynamictrust") == 0 ) + { + struct LP_address *ap; char *coinaddr; + if ( (ptr= LP_coinsearch("KMD")) != 0 && (coinaddr= jstr(argjson,"address")) != 0 ) + { + if ( (ap= LP_addressfind(ptr,coinaddr)) != 0 ) + { + retjson = cJSON_CreateObject(); + jaddstr(retjson,"result","success"); + jaddstr(retjson,"address",coinaddr); + jaddnum(retjson,"zcredits",dstr(ap->zeroconf_credits)); + return(jprint(retjson,1)); + } + } + return(clonestr("{\"error\":\"cant find address\"}")); + } else if ( (retstr= LP_istradebots_command(ctx,pubsock,method,argjson)) != 0 ) return(retstr); if ( base[0] != 0 && rel[0] != 0 ) diff --git a/iguana/exchanges/LP_zeroconf.c b/iguana/exchanges/LP_zeroconf.c index f013c9965..876ac4128 100644 --- a/iguana/exchanges/LP_zeroconf.c +++ b/iguana/exchanges/LP_zeroconf.c @@ -206,7 +206,11 @@ void LP_zeroconf_credit(char *coinaddr,uint64_t satoshis,int32_t weeki,char *p2s void LP_zeroconf_deposits(struct iguana_info *coin) { - cJSON *array,*item,*txjson,*vouts,*v,*txobj; int32_t i,n,numvouts,height,vout,weeki; bits256 txid; char destaddr[64],p2shaddr[64]; int64_t satoshis,amount64; + cJSON *array,*item,*txjson,*vouts,*v,*txobj; int32_t i,n,numvouts,height,vout,weeki; bits256 txid; char destaddr[64],p2shaddr[64]; struct LP_address *ap,*tmp; int64_t satoshis,amount64; + HASH_ITER(hh,coin->addresses,ap,tmp) + { + ap->zeroconf_credits = 0; + } if ( (array= LP_listreceivedbyaddress("KMD",BOTS_BONDADDRESS)) != 0 ) { //printf("ZEROCONF.(%s)\n",jprint(array,0)); @@ -252,7 +256,7 @@ int64_t LP_dynamictrust(bits256 pubkey,int64_t kmdvalue) if ( (coin= LP_coinfind("KMD")) != 0 && (pubp= LP_pubkeyfind(pubkey)) != 0 ) { bitcoin_address(coinaddr,coin->taddr,coin->pubtype,pubp->pubsecp,33); - if ((ap= LP_address(coin,coinaddr)) != 0 && ap->zeroconf_credits >= kmdvalue ) + if ((ap= LP_address(coin,coinaddr)) != 0 )//&& ap->zeroconf_credits >= kmdvalue ) { DL_FOREACH_SAFE(pubp->bobswaps,ptr,tmp) { From 674be38211caf15fb37fbff78e201b46fdcf28fd Mon Sep 17 00:00:00 2001 From: jl777 Date: Thu, 23 Nov 2017 16:35:07 +0400 Subject: [PATCH 1129/1664] Test --- iguana/dpow/dpow_network.c | 2 ++ iguana/exchanges/LP_commands.c | 5 ----- iguana/exchanges/LP_nativeDEX.c | 10 +--------- iguana/main.c | 2 +- 4 files changed, 4 insertions(+), 15 deletions(-) diff --git a/iguana/dpow/dpow_network.c b/iguana/dpow/dpow_network.c index 9899b9cac..c7e5d311a 100755 --- a/iguana/dpow/dpow_network.c +++ b/iguana/dpow/dpow_network.c @@ -584,6 +584,8 @@ char *dex_response(int32_t *broadcastflagp,struct supernet_info *myinfo,struct d { char buf[65],*retstr = 0; int32_t i,datalen; bits256 hash2; cJSON *retjson=0; struct iguana_info *coin; struct dex_request dexreq; *broadcastflagp = 0; +return(clonestr("{\"error\":\"basilisk disabled\"}")); + if ( strcmp(dexp->handler,"request") == 0 ) { datalen = dex_rwrequest(0,dexp->packet,&dexreq); diff --git a/iguana/exchanges/LP_commands.c b/iguana/exchanges/LP_commands.c index 2df539365..75b642396 100644 --- a/iguana/exchanges/LP_commands.c +++ b/iguana/exchanges/LP_commands.c @@ -442,16 +442,11 @@ zeroconf_claim(address, expiration=0)\n\ if ( coinaddr[0] != 0 ) { LP_address(ptr,coinaddr); - //LP_listunspent_issue(coin,coinaddr,2); if ( strcmp(coinaddr,ptr->smartaddr) == 0 && bits256_nonz(G.LP_privkey) != 0 ) { LP_privkey_init(-1,ptr,G.LP_privkey,G.LP_mypub25519); - //LP_smartutxos_push(ptr); } return(jprint(LP_listunspent(coin,coinaddr),0)); - //if ( ptr->electrum != 0 ) - //return(LP_unspents_filestr(coin,coinaddr)); - //else return(jprint(LP_address_utxos(ptr,coinaddr,1),1)); } } return(clonestr("{\"error\":\"no address specified\"}")); diff --git a/iguana/exchanges/LP_nativeDEX.c b/iguana/exchanges/LP_nativeDEX.c index 70deb5af1..4e0f23bcf 100644 --- a/iguana/exchanges/LP_nativeDEX.c +++ b/iguana/exchanges/LP_nativeDEX.c @@ -18,23 +18,15 @@ // marketmaker // // feature requests: +// electrum memleak? // alice waiting for bestprice // USD paxprice based USDvalue in portfolio // cancel bid/ask // https://github.com/bitcoin/bips/blob/master/bip-0143.mediawiki for signing BCH/BTG // // bugs, validations: -/*Buyer Payment 08ccac7534dc6aad0139b7dd6a78344d309fbc6bff27f2fba7c8f178f5d309a0 - -Seller Payment f876412f3dc637998b099b05ae0fe3e769e5adafcb49ef156be9f7749f2e3071 - -Quote ID 2681103143 -Request ID 301413467 -Trade id 3567859514*/ // waiting for alice and alice disconnects, can find bobpayment based on Q.txid -// MNZ getcoin strangeness // portfolio value based on ask? -// listunspent triplicate, tradebot timeslice? the tradebot timeslice is just getting too much timeslices // disable basilisk // verify encrypted destpubkey, broadcast:0 setprice diff --git a/iguana/main.c b/iguana/main.c index 85510c3fb..b89521a04 100755 --- a/iguana/main.c +++ b/iguana/main.c @@ -793,7 +793,7 @@ void iguana_launchdaemons(struct supernet_info *myinfo) if ( COMMANDLINE_ARGFILE == 0 ) iguana_launch(0,"rpcloop",iguana_rpcloop,myinfo,IGUANA_PERMTHREAD); // limit to oneprocess printf("launch mainloop\n"); - OS_thread_create(malloc(sizeof(pthread_t)),NULL,(void *)DEX_explorerloop,(void *)myinfo); + // disable basilisk: OS_thread_create(malloc(sizeof(pthread_t)),NULL,(void *)DEX_explorerloop,(void *)myinfo); OS_thread_create(malloc(sizeof(pthread_t)),NULL,(void *)jumblr_loop,(void *)myinfo); OS_thread_create(malloc(sizeof(pthread_t)),NULL,(void *)dpow_psockloop,(void *)myinfo); mainloop(myinfo); From f87068f33dabd0e1675f685fbf6c2983c80872cd Mon Sep 17 00:00:00 2001 From: jl777 Date: Thu, 23 Nov 2017 16:39:37 +0400 Subject: [PATCH 1130/1664] Test --- iguana/exchanges/LP_commands.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/iguana/exchanges/LP_commands.c b/iguana/exchanges/LP_commands.c index 75b642396..c7417437b 100644 --- a/iguana/exchanges/LP_commands.c +++ b/iguana/exchanges/LP_commands.c @@ -444,7 +444,7 @@ zeroconf_claim(address, expiration=0)\n\ LP_address(ptr,coinaddr); if ( strcmp(coinaddr,ptr->smartaddr) == 0 && bits256_nonz(G.LP_privkey) != 0 ) { - LP_privkey_init(-1,ptr,G.LP_privkey,G.LP_mypub25519); + //LP_privkey_init(-1,ptr,G.LP_privkey,G.LP_mypub25519); } return(jprint(LP_listunspent(coin,coinaddr),0)); } From 37754dca8aeb278e9e8efd784ef4747e9b0c93a6 Mon Sep 17 00:00:00 2001 From: jl777 Date: Thu, 23 Nov 2017 16:40:07 +0400 Subject: [PATCH 1131/1664] Test --- iguana/exchanges/LP_commands.c | 1 + 1 file changed, 1 insertion(+) diff --git a/iguana/exchanges/LP_commands.c b/iguana/exchanges/LP_commands.c index c7417437b..41dfdaff9 100644 --- a/iguana/exchanges/LP_commands.c +++ b/iguana/exchanges/LP_commands.c @@ -442,6 +442,7 @@ zeroconf_claim(address, expiration=0)\n\ if ( coinaddr[0] != 0 ) { LP_address(ptr,coinaddr); + LP_listunspent_issue(coin,coinaddr,2); if ( strcmp(coinaddr,ptr->smartaddr) == 0 && bits256_nonz(G.LP_privkey) != 0 ) { //LP_privkey_init(-1,ptr,G.LP_privkey,G.LP_mypub25519); From 2be982d74b5f2ca4c28ae615676974df4339ea0c Mon Sep 17 00:00:00 2001 From: jl777 Date: Thu, 23 Nov 2017 16:44:51 +0400 Subject: [PATCH 1132/1664] Test --- iguana/exchanges/LP_include.h | 2 +- iguana/exchanges/LP_portfolio.c | 2 +- iguana/exchanges/LP_utxos.c | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/iguana/exchanges/LP_include.h b/iguana/exchanges/LP_include.h index e8ba59f54..7580c68ba 100644 --- a/iguana/exchanges/LP_include.h +++ b/iguana/exchanges/LP_include.h @@ -23,7 +23,7 @@ #define LP_MAJOR_VERSION "0" #define LP_MINOR_VERSION "1" -#define LP_BUILD_NUMBER "15324" +#define LP_BUILD_NUMBER "15377" #define LP_BARTERDEX_VERSION 1 #define LP_MAGICBITS 8 diff --git a/iguana/exchanges/LP_portfolio.c b/iguana/exchanges/LP_portfolio.c index 4004a8c41..e8d42ffd1 100644 --- a/iguana/exchanges/LP_portfolio.c +++ b/iguana/exchanges/LP_portfolio.c @@ -94,7 +94,7 @@ char *LP_portfolio() if ( iter == 0 ) { //printf("from portfolio\n"); - LP_privkey_init(-1,coin,G.LP_privkey,G.LP_mypub25519); + //LP_privkey_init(-1,coin,G.LP_privkey,G.LP_mypub25519); coin->balanceA = LP_balance(&coin->valuesumA,0,coin->symbol,coin->smartaddr); coin->balanceB = LP_balance(&coin->valuesumB,1,coin->symbol,coin->smartaddr); if ( strcmp(coin->symbol,"KMD") != 0 ) diff --git a/iguana/exchanges/LP_utxos.c b/iguana/exchanges/LP_utxos.c index f73bd42de..7d637e459 100644 --- a/iguana/exchanges/LP_utxos.c +++ b/iguana/exchanges/LP_utxos.c @@ -855,7 +855,7 @@ void LP_privkey_updates(void *ctx,int32_t pubsock,char *passphrase) else if ( IAMLP == 0 || coin->inactive == 0 ) { //printf("from updates %s\n",coin->symbol); - if ( LP_privkey_init(pubsock,coin,G.LP_privkey,G.LP_mypub25519) == 0 && (LP_rand() % 10) == 0 ) + if ( 0 && LP_privkey_init(pubsock,coin,G.LP_privkey,G.LP_mypub25519) == 0 && (LP_rand() % 10) == 0 ) { //LP_postutxos(coin->symbol,coin->smartaddr); } From 345845e7da002d22b307327e165cbf163c5c6cda Mon Sep 17 00:00:00 2001 From: jl777 Date: Thu, 23 Nov 2017 17:05:14 +0400 Subject: [PATCH 1133/1664] Test --- crypto777/bitcoind_RPC.c | 13 +++++-------- iguana/exchanges/LP_transaction.c | 5 +++-- iguana/exchanges/LP_utxo.c | 3 ++- 3 files changed, 10 insertions(+), 11 deletions(-) diff --git a/crypto777/bitcoind_RPC.c b/crypto777/bitcoind_RPC.c index f624cd342..8bdd89e1f 100755 --- a/crypto777/bitcoind_RPC.c +++ b/crypto777/bitcoind_RPC.c @@ -231,30 +231,30 @@ try_again: free(databuf); databuf = 0; } + retstr = chunk.memory; // retstr = s.ptr; if ( res != CURLE_OK ) { numretries++; if ( specialcase != 0 || timeout != 0 ) { - //printf("<<<<<<<<<<< bitcoind_RPC.(%s): BTCD.%s timeout params.(%s) s.ptr.(%s) err.%d\n",url,command,params,s.ptr,res); - free(chunk.memory); //free(s.ptr); + //printf("<<<<<<<<<<< bitcoind_RPC.(%s): BTCD.%s timeout params.(%s) s.ptr.(%s) err.%d\n",url,command,params,retstr,res); + free(retstr); return(0); } else if ( numretries >= 4 ) { printf( "curl_easy_perform() failed: %s %s.(%s %s), retries: %d\n",curl_easy_strerror(res),debugstr,url,command,numretries); //printf("Maximum number of retries exceeded!\n"); - free(chunk.memory);//free(s.ptr); + free(retstr); return(0); } - free(chunk.memory);//free(s.ptr); + free(retstr); sleep((1<symbol,coin->smartaddr,up->U.txid,up->U.vout) < 0 ) continue; } - + if ( LP_allocated(up->U.txid,up->U.vout) != 0 ) + continue; up->spendheight = 1; total += up->U.value; remains -= up->U.value; @@ -1139,7 +1140,7 @@ int32_t LP_vins_select(void *ctx,struct iguana_info *coin,int64_t *totalp,int64_ char str[65]; printf("%s/%d %.8f interest %.8f -> sum %.8f\n",bits256_str(str,up->U.txid),up->U.vout,dstr(up->U.value),dstr(interest),dstr(interestsum)); } } - //printf("numunspents.%d vini.%d value %.8f, total %.8f remains %.8f interest %.8f sum %.8f %s/v%d\n",numunspents,n,dstr(up->U.value),dstr(total),dstr(remains),dstr(interest),dstr(interestsum),bits256_str(str,up->U.txid),up->U.vout); + printf("numunspents.%d vini.%d value %.8f, total %.8f remains %.8f interest %.8f sum %.8f %s/v%d\n",numunspents,n,dstr(up->U.value),dstr(total),dstr(remains),dstr(interest),dstr(interestsum),bits256_str(str,up->U.txid),up->U.vout); vp = &V[n++]; vp->N = vp->M = 1; vp->signers[0].privkey = privkey; diff --git a/iguana/exchanges/LP_utxo.c b/iguana/exchanges/LP_utxo.c index 7e677c69b..d0c26c788 100644 --- a/iguana/exchanges/LP_utxo.c +++ b/iguana/exchanges/LP_utxo.c @@ -99,9 +99,10 @@ struct LP_inuse_info *_LP_inuse_add(uint32_t expiration,bits256 otherpub,bits256 { if ( bits256_nonz(otherpub) != 0 ) lp->otherpub = otherpub; - if ( expiration > lp->expiration || expiration == 0 ) + //if ( expiration > lp->expiration || expiration == 0 ) lp->expiration = expiration; } + char str[65]; printf("set inuse until %u lag.%d for %s/v%d\n",expiration,(int32_t)(expiration-(uint32_t)time(NULL)),bits256_str(str,txid),vout); return(lp); } else printf("_LP_inuse_add [%d] overflow\n",LP_numinuse); return(0); From 7063ae7cba211a2b12578a07a5998a3dca1fa66a Mon Sep 17 00:00:00 2001 From: jl777 Date: Thu, 23 Nov 2017 17:07:42 +0400 Subject: [PATCH 1134/1664] Test --- iguana/exchanges/stats.c | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/iguana/exchanges/stats.c b/iguana/exchanges/stats.c index ddea6722e..aa1a26ac6 100644 --- a/iguana/exchanges/stats.c +++ b/iguana/exchanges/stats.c @@ -735,10 +735,13 @@ void LP_rpc_processreq(void *_ptr) free(space); free(jsonbuf); closesocket(sock); - portable_mutex_lock(&LP_gcmutex); - DL_APPEND(LP_garbage_collector,req); + if ( 0 ) + { + portable_mutex_lock(&LP_gcmutex); + DL_APPEND(LP_garbage_collector,req); + portable_mutex_unlock(&LP_gcmutex); + } free(req); spawned--; - portable_mutex_unlock(&LP_gcmutex); } extern int32_t IAMLP; From 0bb41ba9f2bf3a397568a4caf0592db473e1c93b Mon Sep 17 00:00:00 2001 From: jl777 Date: Thu, 23 Nov 2017 17:20:33 +0400 Subject: [PATCH 1135/1664] Test --- iguana/exchanges/stats.c | 24 +++++++++++++++++------- 1 file changed, 17 insertions(+), 7 deletions(-) diff --git a/iguana/exchanges/stats.c b/iguana/exchanges/stats.c index aa1a26ac6..c04d01cde 100644 --- a/iguana/exchanges/stats.c +++ b/iguana/exchanges/stats.c @@ -562,7 +562,9 @@ char *stats_rpcparse(char *retbuf,int32_t bufsize,int32_t *jsonflagp,int32_t *po } free_json(argjson); if ( tmpjson != 0 ) - free(tmpjson); + free_json(tmpjson); + if ( tokens != 0 ) + free_json(tokens); *jsonflagp = 1; return(clonestr("{\"error\":\"couldnt process packet\"}")); } @@ -597,15 +599,16 @@ void LP_rpc_processreq(void *_ptr) static uint32_t spawned,maxspawned; char filetype[128],content_type[128]; int32_t recvlen,flag,postflag=0,contentlen,remains,sock,numsent,jsonflag=0,hdrsize,len; - char helpname[512],remoteaddr[64],*buf,*retstr,*space,*jsonbuf; struct rpcrequest_info *req = _ptr; + char helpname[512],remoteaddr[64],*buf,*retstr,space[4096],*jsonbuf; struct rpcrequest_info *req = _ptr; uint32_t ipbits,i,size = IGUANA_MAXPACKETSIZE + 512; ipbits = req->ipbits;; expand_ipbits(remoteaddr,ipbits); sock = req->sock; recvlen = flag = 0; retstr = 0; - space = calloc(1,size); + //space = calloc(1,size); jsonbuf = calloc(1,size); + printf("alloc jsonbuf.%p\n",jsonbuf); remains = size-1; buf = jsonbuf; spawned++; @@ -696,16 +699,18 @@ void LP_rpc_processreq(void *_ptr) //printf("RETURN.(%s) jsonflag.%d postflag.%d\n",retstr,jsonflag,postflag); if ( jsonflag != 0 || postflag != 0 ) { - if ( retstr == 0 ) - retstr = clonestr("{}"); response = malloc(strlen(retstr)+1024+1+1); + printf("alloc response.%p\n",response); sprintf(hdrs,"HTTP/1.1 200 OK\r\nAccess-Control-Allow-Origin: *\r\nAccess-Control-Allow-Credentials: true\r\nAccess-Control-Allow-Methods: GET, POST\r\nCache-Control : no-cache, no-store, must-revalidate\r\n%sContent-Length : %8d\r\n\r\n",content_type,(int32_t)strlen(retstr)); response[0] = '\0'; strcat(response,hdrs); strcat(response,retstr); strcat(response,"\n"); if ( retstr != space ) + { + printf("free retstr0.%p\n",retstr); free(retstr); + } retstr = response; //printf("RET.(%s)\n",retstr); } @@ -729,10 +734,14 @@ void LP_rpc_processreq(void *_ptr) printf("iguana sent.%d remains.%d of recvlen.%d (%s)\n",numsent,remains,recvlen,jsonbuf); } } - if ( retstr != space) + if ( retstr != space ) + { + printf("free retstr.%p\n",retstr); free(retstr); + } } - free(space); + //free(space); + printf("free jsonbuf.%p\n",jsonbuf); free(jsonbuf); closesocket(sock); if ( 0 ) @@ -797,6 +806,7 @@ void stats_rpcloop(void *args) continue; } req = calloc(1,sizeof(*req)); + printf("alloc req.%p\n",req); req->sock = sock; req->ipbits = ipbits; req->port = port; From c9bcdcacc6e09231fbd803fb45963c65cf4d4649 Mon Sep 17 00:00:00 2001 From: jl777 Date: Thu, 23 Nov 2017 17:29:07 +0400 Subject: [PATCH 1136/1664] Test --- iguana/exchanges/LP_signatures.c | 4 ++-- iguana/exchanges/LP_transaction.c | 2 +- iguana/exchanges/stats.c | 7 ++++++- 3 files changed, 9 insertions(+), 4 deletions(-) diff --git a/iguana/exchanges/LP_signatures.c b/iguana/exchanges/LP_signatures.c index 3fc10d7aa..4fab2feca 100644 --- a/iguana/exchanges/LP_signatures.c +++ b/iguana/exchanges/LP_signatures.c @@ -700,8 +700,8 @@ void LP_query(void *ctx,char *myipaddr,int32_t mypubsock,char *method,struct LP_ { if ( LP_allocated(qp->desttxid,qp->destvout) == 0 && LP_allocated(qp->feetxid,qp->feevout) == 0 ) { - LP_unavailableset(qp->desttxid,qp->destvout,qp->timestamp+LP_AUTOTRADE_TIMEOUT,qp->srchash); - LP_unavailableset(qp->feetxid,qp->feevout,qp->timestamp+LP_AUTOTRADE_TIMEOUT,qp->srchash); + LP_unavailableset(qp->desttxid,qp->destvout,qp->timestamp+LP_AUTOTRADE_TIMEOUT*4,qp->srchash); + LP_unavailableset(qp->feetxid,qp->feevout,qp->timestamp+LP_AUTOTRADE_TIMEOUT*4,qp->srchash); } else { diff --git a/iguana/exchanges/LP_transaction.c b/iguana/exchanges/LP_transaction.c index 665732df6..96ed9976a 100644 --- a/iguana/exchanges/LP_transaction.c +++ b/iguana/exchanges/LP_transaction.c @@ -1149,7 +1149,7 @@ int32_t LP_vins_select(void *ctx,struct iguana_info *coin,int64_t *totalp,int64_ vp->suppress_pubkeys = suppress_pubkeys; vp->ignore_cltverr = ignore_cltverr; jaddi(vins,LP_inputjson(up->U.txid,up->U.vout,spendscriptstr)); - LP_unavailableset(up->U.txid,up->U.vout,(uint32_t)time(NULL)+600,G.LP_mypub25519); + LP_unavailableset(up->U.txid,up->U.vout,(uint32_t)time(NULL)+LP_RESERVETIME,G.LP_mypub25519); if ( remains <= 0 && i >= numpre-1 ) break; if ( numunspents < 0 ) diff --git a/iguana/exchanges/stats.c b/iguana/exchanges/stats.c index c04d01cde..269aff52e 100644 --- a/iguana/exchanges/stats.c +++ b/iguana/exchanges/stats.c @@ -749,7 +749,12 @@ void LP_rpc_processreq(void *_ptr) portable_mutex_lock(&LP_gcmutex); DL_APPEND(LP_garbage_collector,req); portable_mutex_unlock(&LP_gcmutex); - } free(req); + } + else + { + printf("free req.%p\n",req); + free(req); + } spawned--; } From 628e55b627925e28b864173293ba7372b1f21d4d Mon Sep 17 00:00:00 2001 From: jl777 Date: Thu, 23 Nov 2017 17:41:48 +0400 Subject: [PATCH 1137/1664] Test --- iguana/exchanges/stats.c | 106 +++++++++++++++++++++------------------ 1 file changed, 58 insertions(+), 48 deletions(-) diff --git a/iguana/exchanges/stats.c b/iguana/exchanges/stats.c index 269aff52e..02cea490e 100644 --- a/iguana/exchanges/stats.c +++ b/iguana/exchanges/stats.c @@ -412,7 +412,12 @@ char *stats_rpcparse(char *retbuf,int32_t bufsize,int32_t *jsonflagp,int32_t *po { jadd(json,"tokens",tokens); jaddstr(json,"urlmethod",urlmethod); - if ( (data= jstr(json,"POST")) == 0 || (argjson= cJSON_Parse(data)) == 0 ) + if ( (data= jstr(json,"POST")) != 0 ) + { + free_json(argjson); + argjson = cJSON_Parse(data); + } + if ( argjson != 0 ) { userpass = jstr(argjson,"userpass"); //printf("userpass.(%s)\n",userpass); @@ -499,62 +504,62 @@ char *stats_rpcparse(char *retbuf,int32_t bufsize,int32_t *jsonflagp,int32_t *po } } } - } - if ( is_cJSON_Array(argjson) != 0 && (n= cJSON_GetArraySize(argjson)) > 0 ) - { - cJSON *retitem,*retarray = cJSON_CreateArray(); - origargjson = argjson; - symbol[0] = 0; - for (i=0; i 0 ) { - argjson = jitem(origargjson,i); - if ( userpass != 0 && jstr(argjson,"userpass") == 0 ) - jaddstr(argjson,"userpass",userpass); - //printf("after urlconv.(%s) argjson.(%s)\n",jprint(json,0),jprint(argjson,0)); -#ifdef FROM_MARKETMAKER - if ( strcmp(remoteaddr,"127.0.0.1") == 0 || LP_valid_remotemethod(argjson) > 0 ) + cJSON *retitem,*retarray = cJSON_CreateArray(); + origargjson = argjson; + symbol[0] = 0; + for (i=0; i 0 ) + { + if ( (retstr= stats_JSON(ctx,myipaddr,-1,argjson,remoteaddr,port)) != 0 ) + { + if ( (retitem= cJSON_Parse(retstr)) != 0 ) + jaddi(retarray,retitem); + free(retstr); + } + } else retstr = clonestr("{\"error\":\"invalid remote method\"}"); +#else if ( (retstr= stats_JSON(ctx,myipaddr,-1,argjson,remoteaddr,port)) != 0 ) { if ( (retitem= cJSON_Parse(retstr)) != 0 ) jaddi(retarray,retitem); free(retstr); } - } else retstr = clonestr("{\"error\":\"invalid remote method\"}"); -#else - if ( (retstr= stats_JSON(ctx,myipaddr,-1,argjson,remoteaddr,port)) != 0 ) - { - if ( (retitem= cJSON_Parse(retstr)) != 0 ) - jaddi(retarray,retitem); - free(retstr); - } #endif - //printf("(%s) {%s} -> (%s) postflag.%d (%s)\n",urlstr,jprint(argjson,0),jprint(json,0),*postflagp,retstr); + //printf("(%s) {%s} -> (%s) postflag.%d (%s)\n",urlstr,jprint(argjson,0),jprint(json,0),*postflagp,retstr); + } + free_json(origargjson); + retstr = jprint(retarray,1); } - free_json(origargjson); - retstr = jprint(retarray,1); - } - else - { - cJSON *arg; - if ( jstr(argjson,"agent") != 0 && strcmp(jstr(argjson,"agent"),"bitcoinrpc") != 0 && jobj(argjson,"params") != 0 ) + else { - arg = jobj(argjson,"params"); - if ( is_cJSON_Array(arg) != 0 && cJSON_GetArraySize(arg) == 1 ) - arg = jitem(arg,0); - } else arg = argjson; - //printf("ARGJSON.(%s)\n",jprint(arg,0)); - if ( userpass != 0 && jstr(arg,"userpass") == 0 ) - jaddstr(arg,"userpass",userpass); + cJSON *arg; + if ( jstr(argjson,"agent") != 0 && strcmp(jstr(argjson,"agent"),"bitcoinrpc") != 0 && jobj(argjson,"params") != 0 ) + { + arg = jobj(argjson,"params"); + if ( is_cJSON_Array(arg) != 0 && cJSON_GetArraySize(arg) == 1 ) + arg = jitem(arg,0); + } else arg = argjson; + //printf("ARGJSON.(%s)\n",jprint(arg,0)); + if ( userpass != 0 && jstr(arg,"userpass") == 0 ) + jaddstr(arg,"userpass",userpass); #ifdef FROM_MARKETMAKER - if ( strcmp(remoteaddr,"127.0.0.1") == 0 || LP_valid_remotemethod(arg) > 0 ) - retstr = stats_JSON(ctx,myipaddr,-1,arg,remoteaddr,port); - else retstr = clonestr("{\"error\":\"invalid remote method\"}"); + if ( strcmp(remoteaddr,"127.0.0.1") == 0 || LP_valid_remotemethod(arg) > 0 ) + retstr = stats_JSON(ctx,myipaddr,-1,arg,remoteaddr,port); + else retstr = clonestr("{\"error\":\"invalid remote method\"}"); #else - retstr = stats_JSON(ctx,myipaddr,-1,arg,remoteaddr,port); + retstr = stats_JSON(ctx,myipaddr,-1,arg,remoteaddr,port); #endif + } + free_json(argjson); } - free_json(argjson); free_json(json); if ( tmpjson != 0 ) free(tmpjson); @@ -599,7 +604,7 @@ void LP_rpc_processreq(void *_ptr) static uint32_t spawned,maxspawned; char filetype[128],content_type[128]; int32_t recvlen,flag,postflag=0,contentlen,remains,sock,numsent,jsonflag=0,hdrsize,len; - char helpname[512],remoteaddr[64],*buf,*retstr,space[4096],*jsonbuf; struct rpcrequest_info *req = _ptr; + char helpname[512],remoteaddr[64],*buf,*retstr,space[4096],space2[8192],*jsonbuf; struct rpcrequest_info *req = _ptr; uint32_t ipbits,i,size = IGUANA_MAXPACKETSIZE + 512; ipbits = req->ipbits;; expand_ipbits(remoteaddr,ipbits); @@ -699,8 +704,13 @@ void LP_rpc_processreq(void *_ptr) //printf("RETURN.(%s) jsonflag.%d postflag.%d\n",retstr,jsonflag,postflag); if ( jsonflag != 0 || postflag != 0 ) { - response = malloc(strlen(retstr)+1024+1+1); - printf("alloc response.%p\n",response); + if ( strlen(retstr)+1024+1+1 < sizeof(space2) ) + response = space2; + else + { + response = malloc(strlen(retstr)+1024+1+1); + printf("alloc response.%p\n",response); + } sprintf(hdrs,"HTTP/1.1 200 OK\r\nAccess-Control-Allow-Origin: *\r\nAccess-Control-Allow-Credentials: true\r\nAccess-Control-Allow-Methods: GET, POST\r\nCache-Control : no-cache, no-store, must-revalidate\r\n%sContent-Length : %8d\r\n\r\n",content_type,(int32_t)strlen(retstr)); response[0] = '\0'; strcat(response,hdrs); @@ -734,7 +744,7 @@ void LP_rpc_processreq(void *_ptr) printf("iguana sent.%d remains.%d of recvlen.%d (%s)\n",numsent,remains,recvlen,jsonbuf); } } - if ( retstr != space ) + if ( retstr != space && retstr != space2 ) { printf("free retstr.%p\n",retstr); free(retstr); @@ -752,7 +762,7 @@ void LP_rpc_processreq(void *_ptr) } else { - printf("free req.%p\n",req); + //printf("free req.%p\n",req); free(req); } spawned--; @@ -811,7 +821,7 @@ void stats_rpcloop(void *args) continue; } req = calloc(1,sizeof(*req)); - printf("alloc req.%p\n",req); + //printf("alloc req.%p\n",req); req->sock = sock; req->ipbits = ipbits; req->port = port; From 84d9e5f53b74d827d305b321b1e58b2ac7e9097b Mon Sep 17 00:00:00 2001 From: jl777 Date: Thu, 23 Nov 2017 17:46:06 +0400 Subject: [PATCH 1138/1664] Test --- iguana/exchanges/stats.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/iguana/exchanges/stats.c b/iguana/exchanges/stats.c index 02cea490e..54a4df18a 100644 --- a/iguana/exchanges/stats.c +++ b/iguana/exchanges/stats.c @@ -604,7 +604,7 @@ void LP_rpc_processreq(void *_ptr) static uint32_t spawned,maxspawned; char filetype[128],content_type[128]; int32_t recvlen,flag,postflag=0,contentlen,remains,sock,numsent,jsonflag=0,hdrsize,len; - char helpname[512],remoteaddr[64],*buf,*retstr,space[4096],space2[8192],*jsonbuf; struct rpcrequest_info *req = _ptr; + char helpname[512],remoteaddr[64],*buf,*retstr,space[8192],space2[32786],*jsonbuf; struct rpcrequest_info *req = _ptr; uint32_t ipbits,i,size = IGUANA_MAXPACKETSIZE + 512; ipbits = req->ipbits;; expand_ipbits(remoteaddr,ipbits); From ad22daaddf7795e53de042ff4c9615366a70a7eb Mon Sep 17 00:00:00 2001 From: jl777 Date: Thu, 23 Nov 2017 17:51:10 +0400 Subject: [PATCH 1139/1664] Test --- iguana/exchanges/stats.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/iguana/exchanges/stats.c b/iguana/exchanges/stats.c index 54a4df18a..11afc2d4d 100644 --- a/iguana/exchanges/stats.c +++ b/iguana/exchanges/stats.c @@ -613,7 +613,7 @@ void LP_rpc_processreq(void *_ptr) retstr = 0; //space = calloc(1,size); jsonbuf = calloc(1,size); - printf("alloc jsonbuf.%p\n",jsonbuf); + //printf("alloc jsonbuf.%p\n",jsonbuf); remains = size-1; buf = jsonbuf; spawned++; @@ -718,7 +718,7 @@ void LP_rpc_processreq(void *_ptr) strcat(response,"\n"); if ( retstr != space ) { - printf("free retstr0.%p\n",retstr); + //printf("free retstr0.%p\n",retstr); free(retstr); } retstr = response; @@ -746,12 +746,12 @@ void LP_rpc_processreq(void *_ptr) } if ( retstr != space && retstr != space2 ) { - printf("free retstr.%p\n",retstr); + //printf("free retstr.%p\n",retstr); free(retstr); } } //free(space); - printf("free jsonbuf.%p\n",jsonbuf); + //printf("free jsonbuf.%p\n",jsonbuf); free(jsonbuf); closesocket(sock); if ( 0 ) From a1871c3b777ce9fe099a6a575aa48a644f1924cb Mon Sep 17 00:00:00 2001 From: jl777 Date: Thu, 23 Nov 2017 17:55:30 +0400 Subject: [PATCH 1140/1664] Test --- iguana/exchanges/LP_nativeDEX.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/iguana/exchanges/LP_nativeDEX.c b/iguana/exchanges/LP_nativeDEX.c index 4e0f23bcf..d320b2e67 100644 --- a/iguana/exchanges/LP_nativeDEX.c +++ b/iguana/exchanges/LP_nativeDEX.c @@ -835,7 +835,7 @@ void LP_privkeysloop(void *ctx) void LP_swapsloop(void *ignore) { - char *retstr; + char *retstr; struct iguana_info *coin; strcpy(LP_swapsloop_stats.name,"LP_swapsloop"); LP_swapsloop_stats.threshold = 605000.; sleep(50); @@ -847,6 +847,8 @@ void LP_swapsloop(void *ignore) if ( (retstr= basilisk_swapentry(0,0)) != 0 ) free(retstr); sleep(600); + if ( (coin= LP_coinfind("KMD")) != 0 ) + LP_zeroconf_deposits(coin); } } From 3c0825d4c6db5b677c650f8d9accfbbf66f961a8 Mon Sep 17 00:00:00 2001 From: jl777 Date: Thu, 23 Nov 2017 18:04:26 +0400 Subject: [PATCH 1141/1664] Test --- crypto777/bitcoind_RPC.c | 1 + iguana/exchanges/stats.c | 2 +- 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/crypto777/bitcoind_RPC.c b/crypto777/bitcoind_RPC.c index 8bdd89e1f..408e09479 100755 --- a/crypto777/bitcoind_RPC.c +++ b/crypto777/bitcoind_RPC.c @@ -334,6 +334,7 @@ static size_t WriteMemoryCallback(void *ptr,size_t size,size_t nmemb,void *data) { //printf("curl needs %d more\n",(int32_t)realsize); mem->memory = (ptr != 0) ? realloc(mem->memory,needed) : malloc(needed); + printf("mem->memory.%p len.%d\n",mem->memory,(int32_t)needed); mem->allocsize = needed; } //mem->memory = (ptr != 0) ? realloc(mem->memory,mem->size + realsize + 1) : malloc(mem->size + realsize + 1); diff --git a/iguana/exchanges/stats.c b/iguana/exchanges/stats.c index 11afc2d4d..cc73844f6 100644 --- a/iguana/exchanges/stats.c +++ b/iguana/exchanges/stats.c @@ -718,7 +718,7 @@ void LP_rpc_processreq(void *_ptr) strcat(response,"\n"); if ( retstr != space ) { - //printf("free retstr0.%p\n",retstr); + printf("free retstr0.%p\n",retstr); free(retstr); } retstr = response; From 10bad59429519ea0de69680885348221fb7576f5 Mon Sep 17 00:00:00 2001 From: jl777 Date: Thu, 23 Nov 2017 18:09:04 +0400 Subject: [PATCH 1142/1664] Test --- crypto777/bitcoind_RPC.c | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/crypto777/bitcoind_RPC.c b/crypto777/bitcoind_RPC.c index 408e09479..d4eeac739 100755 --- a/crypto777/bitcoind_RPC.c +++ b/crypto777/bitcoind_RPC.c @@ -96,6 +96,7 @@ char *post_process_bitcoind_RPC(char *debugstr,char *command,char *rpcstr,char * if ( (error->type&0xff) == cJSON_NULL && (result->type&0xff) != cJSON_NULL ) { retstr = jprint(result,0); + printf("rpc retstr.%p\n",retstr); len = strlen(retstr); if ( retstr[0] == '"' && retstr[len-1] == '"' ) { @@ -112,7 +113,10 @@ char *post_process_bitcoind_RPC(char *debugstr,char *command,char *rpcstr,char * rpcstr = 0; } if ( rpcstr != 0 ) + { + printf("free rpcstr.%p\n",rpcstr); free(rpcstr); + } } else retstr = rpcstr; free_json(json); //fprintf(stderr,"<<<<<<<<<<< bitcoind_RPC: postprocess returns.(%s)\n",retstr); From fed50853c6cec8685755a72c04bf7b047f25a935 Mon Sep 17 00:00:00 2001 From: jl777 Date: Thu, 23 Nov 2017 18:11:48 +0400 Subject: [PATCH 1143/1664] Test --- crypto777/bitcoind_RPC.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/crypto777/bitcoind_RPC.c b/crypto777/bitcoind_RPC.c index d4eeac739..99cc62bf7 100755 --- a/crypto777/bitcoind_RPC.c +++ b/crypto777/bitcoind_RPC.c @@ -96,7 +96,7 @@ char *post_process_bitcoind_RPC(char *debugstr,char *command,char *rpcstr,char * if ( (error->type&0xff) == cJSON_NULL && (result->type&0xff) != cJSON_NULL ) { retstr = jprint(result,0); - printf("rpc retstr.%p\n",retstr); + printf("%s %s rpc retstr.%p\n",command,params,retstr); len = strlen(retstr); if ( retstr[0] == '"' && retstr[len-1] == '"' ) { From 4cc9e2cc397f9a4eba2caf7006525f67ea145aa5 Mon Sep 17 00:00:00 2001 From: jl777 Date: Thu, 23 Nov 2017 18:19:20 +0400 Subject: [PATCH 1144/1664] Test --- iguana/exchanges/LP_commands.c | 2 +- iguana/exchanges/LP_rpc.c | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/iguana/exchanges/LP_commands.c b/iguana/exchanges/LP_commands.c index 41dfdaff9..d7a2fd73b 100644 --- a/iguana/exchanges/LP_commands.c +++ b/iguana/exchanges/LP_commands.c @@ -442,9 +442,9 @@ zeroconf_claim(address, expiration=0)\n\ if ( coinaddr[0] != 0 ) { LP_address(ptr,coinaddr); - LP_listunspent_issue(coin,coinaddr,2); if ( strcmp(coinaddr,ptr->smartaddr) == 0 && bits256_nonz(G.LP_privkey) != 0 ) { + //LP_listunspent_issue(coin,coinaddr,2); //LP_privkey_init(-1,ptr,G.LP_privkey,G.LP_mypub25519); } return(jprint(LP_listunspent(coin,coinaddr),0)); diff --git a/iguana/exchanges/LP_rpc.c b/iguana/exchanges/LP_rpc.c index 5dfa79c0f..6359d5132 100644 --- a/iguana/exchanges/LP_rpc.c +++ b/iguana/exchanges/LP_rpc.c @@ -657,7 +657,6 @@ cJSON *LP_listunspent(char *symbol,char *coinaddr) if ( symbol == 0 || symbol[0] == 0 ) return(cJSON_Parse("{\"error\":\"null symbol\"}")); coin = LP_coinfind(symbol); - //printf("LP_listunspent.(%s %s)\n",symbol,coinaddr); if ( coin == 0 || (IAMLP == 0 && coin->inactive != 0) ) return(cJSON_Parse("{\"error\":\"no coin\"}")); if ( coin->electrum == 0 ) @@ -668,6 +667,7 @@ cJSON *LP_listunspent(char *symbol,char *coinaddr) numconfs = 0; else numconfs = 1; sprintf(buf,"[%d, 99999999, [\"%s\"]]",numconfs,coinaddr); + printf("LP_listunspent.(%s %s)\n",symbol,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,1)); From 8d3e95fb643a2d758e9a9d7236782fcd8b816abc Mon Sep 17 00:00:00 2001 From: jl777 Date: Thu, 23 Nov 2017 18:29:17 +0400 Subject: [PATCH 1145/1664] Test --- iguana/exchanges/LP_rpc.c | 14 ++++++++------ 1 file changed, 8 insertions(+), 6 deletions(-) diff --git a/iguana/exchanges/LP_rpc.c b/iguana/exchanges/LP_rpc.c index 6359d5132..b5f27da8c 100644 --- a/iguana/exchanges/LP_rpc.c +++ b/iguana/exchanges/LP_rpc.c @@ -1038,17 +1038,19 @@ bits256 LP_getbestblockhash(struct iguana_info *coin) char *LP_blockhashstr(char *symbol,int32_t height) { - cJSON *array; char *paramstr,*retstr; struct iguana_info *coin; + char params[64],*retstr; struct iguana_info *coin; //cJSON *array; if ( symbol == 0 || symbol[0] == 0 ) return(0); coin = LP_coinfind(symbol); if ( coin == 0 || coin->electrum != 0 ) return(0); - array = cJSON_CreateArray(); - jaddinum(array,height); - paramstr = jprint(array,1); - retstr = bitcoind_passthru(symbol,coin->serverport,coin->userpass,"getblockhash",paramstr); - free(paramstr); + //array = cJSON_CreateArray(); + //jaddinum(array,height); + //paramstr = jprint(array,1); + sprintf(params,"[%d]",height); + retstr = bitcoind_passthru(symbol,coin->serverport,coin->userpass,"getblockhash",params); + //free(paramstr); + printf("blockhashstr.(%s)\n",retstr); return(retstr); } From 2a1ae387320d796eae811106854138068d4b3fca Mon Sep 17 00:00:00 2001 From: jl777 Date: Thu, 23 Nov 2017 18:34:03 +0400 Subject: [PATCH 1146/1664] Test --- crypto777/bitcoind_RPC.c | 6 +++--- iguana/exchanges/LP_rpc.c | 4 ++-- iguana/exchanges/stats.c | 2 +- 3 files changed, 6 insertions(+), 6 deletions(-) diff --git a/crypto777/bitcoind_RPC.c b/crypto777/bitcoind_RPC.c index 99cc62bf7..6bb5d3a12 100755 --- a/crypto777/bitcoind_RPC.c +++ b/crypto777/bitcoind_RPC.c @@ -96,7 +96,7 @@ char *post_process_bitcoind_RPC(char *debugstr,char *command,char *rpcstr,char * if ( (error->type&0xff) == cJSON_NULL && (result->type&0xff) != cJSON_NULL ) { retstr = jprint(result,0); - printf("%s %s rpc retstr.%p\n",command,params,retstr); + //printf("%s %s rpc retstr.%p\n",command,params,retstr); len = strlen(retstr); if ( retstr[0] == '"' && retstr[len-1] == '"' ) { @@ -114,7 +114,7 @@ char *post_process_bitcoind_RPC(char *debugstr,char *command,char *rpcstr,char * } if ( rpcstr != 0 ) { - printf("free rpcstr.%p\n",rpcstr); + //printf("free rpcstr.%p\n",rpcstr); free(rpcstr); } } else retstr = rpcstr; @@ -338,7 +338,7 @@ static size_t WriteMemoryCallback(void *ptr,size_t size,size_t nmemb,void *data) { //printf("curl needs %d more\n",(int32_t)realsize); mem->memory = (ptr != 0) ? realloc(mem->memory,needed) : malloc(needed); - printf("mem->memory.%p len.%d\n",mem->memory,(int32_t)needed); + //printf("mem->memory.%p len.%d\n",mem->memory,(int32_t)needed); mem->allocsize = needed; } //mem->memory = (ptr != 0) ? realloc(mem->memory,mem->size + realsize + 1) : malloc(mem->size + realsize + 1); diff --git a/iguana/exchanges/LP_rpc.c b/iguana/exchanges/LP_rpc.c index b5f27da8c..836f6a123 100644 --- a/iguana/exchanges/LP_rpc.c +++ b/iguana/exchanges/LP_rpc.c @@ -1038,7 +1038,7 @@ bits256 LP_getbestblockhash(struct iguana_info *coin) char *LP_blockhashstr(char *symbol,int32_t height) { - char params[64],*retstr; struct iguana_info *coin; //cJSON *array; + char params[64],*retstr; struct iguana_info *coin; //cJSON *array; if ( symbol == 0 || symbol[0] == 0 ) return(0); coin = LP_coinfind(symbol); @@ -1050,7 +1050,7 @@ char *LP_blockhashstr(char *symbol,int32_t height) sprintf(params,"[%d]",height); retstr = bitcoind_passthru(symbol,coin->serverport,coin->userpass,"getblockhash",params); //free(paramstr); - printf("blockhashstr.(%s)\n",retstr); + //printf("blockhashstr.(%s)\n",retstr); return(retstr); } diff --git a/iguana/exchanges/stats.c b/iguana/exchanges/stats.c index cc73844f6..0aabfa65b 100644 --- a/iguana/exchanges/stats.c +++ b/iguana/exchanges/stats.c @@ -329,7 +329,7 @@ extern void *bitcoin_ctx(); char *stats_rpcparse(char *retbuf,int32_t bufsize,int32_t *jsonflagp,int32_t *postflagp,char *urlstr,char *remoteaddr,char *filetype,uint16_t port) { static void *ctx; - cJSON *tokens,*argjson,*origargjson,*tmpjson=0,*json = 0; long filesize; char *myipaddr="127.0.0.1",symbol[64],buf[4096],*userpass=0,urlmethod[16],*data,url[8192],furl[8192],*retstr,*filestr,*token = 0; int32_t i,j,n,num=0; + cJSON *tokens,*argjson,*origargjson,*tmpjson=0,*json = 0; long filesize; char *myipaddr="127.0.0.1",symbol[64],buf[4096],*userpass=0,urlmethod[16],*data,url[8192],furl[8192],*retstr=0,*filestr,*token = 0; int32_t i,j,n,num=0; //printf("rpcparse.(%s)\n",urlstr); if ( ctx == 0 ) ctx = bitcoin_ctx(); From 4885b497ba1f17beaf2659676b3608fa9f1774d5 Mon Sep 17 00:00:00 2001 From: jl777 Date: Thu, 23 Nov 2017 18:42:10 +0400 Subject: [PATCH 1147/1664] Test --- iguana/exchanges/LP_include.h | 1 + iguana/exchanges/LP_rpc.c | 25 ++++++++++++++++++++++--- 2 files changed, 23 insertions(+), 3 deletions(-) diff --git a/iguana/exchanges/LP_include.h b/iguana/exchanges/LP_include.h index 7580c68ba..1ba94ebfb 100644 --- a/iguana/exchanges/LP_include.h +++ b/iguana/exchanges/LP_include.h @@ -505,6 +505,7 @@ double LP_getestimatedrate(struct iguana_info *coin); 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); int64_t LP_dynamictrust(bits256 pubkey,int64_t kmdvalue); +struct LP_address *LP_addressfind(struct iguana_info *coin,char *coinaddr); void LP_listunspent_query(char *symbol,char *coinaddr); int32_t bitcoin_priv2wif(uint8_t wiftaddr,char *wifstr,bits256 privkey,uint8_t addrtype); diff --git a/iguana/exchanges/LP_rpc.c b/iguana/exchanges/LP_rpc.c index 836f6a123..d2f3702c6 100644 --- a/iguana/exchanges/LP_rpc.c +++ b/iguana/exchanges/LP_rpc.c @@ -653,7 +653,7 @@ int32_t LP_address_isvalid(char *symbol,char *address) cJSON *LP_listunspent(char *symbol,char *coinaddr) { - char buf[128]; cJSON *retjson; int32_t numconfs; struct iguana_info *coin; + char buf[128],*retstr; struct LP_address *ap; cJSON *retjson; int32_t numconfs,usecache=1; struct iguana_info *coin; if ( symbol == 0 || symbol[0] == 0 ) return(cJSON_Parse("{\"error\":\"null symbol\"}")); coin = LP_coinfind(symbol); @@ -661,14 +661,33 @@ cJSON *LP_listunspent(char *symbol,char *coinaddr) return(cJSON_Parse("{\"error\":\"no coin\"}")); if ( coin->electrum == 0 ) { + if ( (ap= LP_addressfind(coin,symbol)) != 0 ) + { + if ( ap->unspenttime == 0 ) + usecache = 0; + else if ( G.LP_pendingswaps != 0 && time(NULL) > ap->unspenttime+30 ) + usecache = 0; + if ( usecache != 0 && (retstr= LP_unspents_filestr(symbol,coinaddr)) != 0 ) + { + retjson = cJSON_Parse(retstr); + free(retstr); + return(retjson); + } + } if ( LP_address_ismine(symbol,coinaddr) > 0 || LP_address_iswatched(symbol,coinaddr) > 0 ) { if ( strcmp(symbol,"BTC") == 0 ) numconfs = 0; else numconfs = 1; sprintf(buf,"[%d, 99999999, [\"%s\"]]",numconfs,coinaddr); - printf("LP_listunspent.(%s %s)\n",symbol,coinaddr); - return(bitcoin_json(coin,"listunspent",buf)); + //printf("LP_listunspent.(%s %s)\n",symbol,coinaddr); + retjson = bitcoin_json(coin,"listunspent",buf); + retstr = jprint(retjson,0); + LP_unspents_cache(coin->symbol,coinaddr,retstr,1); + free(retstr); + if ( ap != 0 ) + ap->unspenttime = (uint32_t)time(NULL); + return(retjson); } else return(LP_address_utxos(coin,coinaddr,0)); } else return(electrum_address_listunspent(symbol,coin->electrum,&retjson,coinaddr,1)); } From af07d4934e1505db8e1517612fc91e9b7d414d0e Mon Sep 17 00:00:00 2001 From: jl777 Date: Thu, 23 Nov 2017 18:45:50 +0400 Subject: [PATCH 1148/1664] Test --- iguana/exchanges/stats.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/iguana/exchanges/stats.c b/iguana/exchanges/stats.c index 0aabfa65b..3b690f1f6 100644 --- a/iguana/exchanges/stats.c +++ b/iguana/exchanges/stats.c @@ -718,7 +718,7 @@ void LP_rpc_processreq(void *_ptr) strcat(response,"\n"); if ( retstr != space ) { - printf("free retstr0.%p\n",retstr); + //printf("free retstr0.%p\n",retstr); free(retstr); } retstr = response; @@ -754,7 +754,7 @@ void LP_rpc_processreq(void *_ptr) //printf("free jsonbuf.%p\n",jsonbuf); free(jsonbuf); closesocket(sock); - if ( 0 ) + if ( 1 ) { portable_mutex_lock(&LP_gcmutex); DL_APPEND(LP_garbage_collector,req); From ecd1601a99ea772cece641253b54e7c3848f94aa Mon Sep 17 00:00:00 2001 From: jl777 Date: Thu, 23 Nov 2017 18:54:14 +0400 Subject: [PATCH 1149/1664] Test --- iguana/exchanges/LP_commands.c | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/iguana/exchanges/LP_commands.c b/iguana/exchanges/LP_commands.c index d7a2fd73b..de915b9e8 100644 --- a/iguana/exchanges/LP_commands.c +++ b/iguana/exchanges/LP_commands.c @@ -68,6 +68,10 @@ char *stats_JSON(void *ctx,char *myipaddr,int32_t pubsock,cJSON *argjson,char *r } if ( strcmp(method,"hello") == 0 ) { + retjson = cJSON_CreateObject(); + jaddstr(retjson,"result","success"); + jaddstr(retjson,"status","got hello"); + return(jprint(retjson,1)); //printf("got hello from %s:%u\n",ipaddr!=0?ipaddr:"",argport); return(clonestr("{\"result\":\"success\",\"status\":\"got hello\"}")); } From 5c494f1ac5a4ef45803643fdd961c7df19640a60 Mon Sep 17 00:00:00 2001 From: jl777 Date: Thu, 23 Nov 2017 18:58:20 +0400 Subject: [PATCH 1150/1664] Test --- iguana/exchanges/LP_commands.c | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/iguana/exchanges/LP_commands.c b/iguana/exchanges/LP_commands.c index de915b9e8..cec08f8ab 100644 --- a/iguana/exchanges/LP_commands.c +++ b/iguana/exchanges/LP_commands.c @@ -68,9 +68,13 @@ char *stats_JSON(void *ctx,char *myipaddr,int32_t pubsock,cJSON *argjson,char *r } if ( strcmp(method,"hello") == 0 ) { + int32_t i; cJSON *array = cJSON_CreateArray(); retjson = cJSON_CreateObject(); jaddstr(retjson,"result","success"); jaddstr(retjson,"status","got hello"); + for (i=0; i<10000; i++) + jaddinum(array,i); + jadd(retjson,"array",array); return(jprint(retjson,1)); //printf("got hello from %s:%u\n",ipaddr!=0?ipaddr:"",argport); return(clonestr("{\"result\":\"success\",\"status\":\"got hello\"}")); From f2282bb1b2a8ba74f05a927d980dba0303d022e3 Mon Sep 17 00:00:00 2001 From: jl777 Date: Thu, 23 Nov 2017 19:03:25 +0400 Subject: [PATCH 1151/1664] Test --- iguana/exchanges/LP_commands.c | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/iguana/exchanges/LP_commands.c b/iguana/exchanges/LP_commands.c index cec08f8ab..54c4f45d0 100644 --- a/iguana/exchanges/LP_commands.c +++ b/iguana/exchanges/LP_commands.c @@ -68,16 +68,16 @@ char *stats_JSON(void *ctx,char *myipaddr,int32_t pubsock,cJSON *argjson,char *r } if ( strcmp(method,"hello") == 0 ) { - int32_t i; cJSON *array = cJSON_CreateArray(); + //int32_t i; cJSON *array = cJSON_CreateArray(); retjson = cJSON_CreateObject(); jaddstr(retjson,"result","success"); jaddstr(retjson,"status","got hello"); - for (i=0; i<10000; i++) - jaddinum(array,i); - jadd(retjson,"array",array); + //for (i=0; i<10000; i++) + // jaddinum(array,i); + //jadd(retjson,"array",array); return(jprint(retjson,1)); //printf("got hello from %s:%u\n",ipaddr!=0?ipaddr:"",argport); - return(clonestr("{\"result\":\"success\",\"status\":\"got hello\"}")); + //return(clonestr("{\"result\":\"success\",\"status\":\"got hello\"}")); } /*else if ( strcmp(method,"sendmessage") == 0 && jobj(argjson,"userpass") == 0 ) { @@ -455,7 +455,7 @@ zeroconf_claim(address, expiration=0)\n\ //LP_listunspent_issue(coin,coinaddr,2); //LP_privkey_init(-1,ptr,G.LP_privkey,G.LP_mypub25519); } - return(jprint(LP_listunspent(coin,coinaddr),0)); + return(jprint(LP_listunspent(coin,coinaddr),1)); } } return(clonestr("{\"error\":\"no address specified\"}")); @@ -631,7 +631,7 @@ zeroconf_claim(address, expiration=0)\n\ { bits256 zero; cJSON *tmpjson; LP_tradecommand_log(argjson); - printf("GOT TRADESTATUS! %s\n",jprint(argjson,0)); + //printf("GOT TRADESTATUS! %s\n",jprint(argjson,0)); if ( LP_statslog_parse() > 0 ) { memset(zero.bytes,0,sizeof(zero)); From 5fab41a8066693abc0cdeb9e76fa28bea81d02f6 Mon Sep 17 00:00:00 2001 From: jl777 Date: Thu, 23 Nov 2017 19:28:47 +0400 Subject: [PATCH 1152/1664] Test --- iguana/exchanges/stats.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/iguana/exchanges/stats.c b/iguana/exchanges/stats.c index 3b690f1f6..45f3541cb 100644 --- a/iguana/exchanges/stats.c +++ b/iguana/exchanges/stats.c @@ -637,7 +637,7 @@ void LP_rpc_processreq(void *_ptr) } else { - //printf("received len.%d\n%s\n",len,buf); + printf("received len.%d\n%s\n",len,buf); if ( len > 0 ) { buf[len] = 0; From 7656c893739904ffaaa848c8bd6dc5a9918e1ea6 Mon Sep 17 00:00:00 2001 From: jl777 Date: Thu, 23 Nov 2017 19:32:01 +0400 Subject: [PATCH 1153/1664] Test --- iguana/exchanges/LP_commands.c | 2 +- iguana/exchanges/stats.c | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/iguana/exchanges/LP_commands.c b/iguana/exchanges/LP_commands.c index 54c4f45d0..9d1f24462 100644 --- a/iguana/exchanges/LP_commands.c +++ b/iguana/exchanges/LP_commands.c @@ -38,7 +38,7 @@ char *stats_JSON(void *ctx,char *myipaddr,int32_t pubsock,cJSON *argjson,char *r method = jstr(argjson,"method"); if ( method != 0 && (strcmp(method,"addr_unspents") == 0 || strcmp(method,"uitem") == 0 || strcmp(method,"postutxos") == 0) ) return(0); -//printf("stats_JSON %s\n",method); +printf("stats_JSON.(%s)\n",jprint(argjson,0)); /*if ( (ipaddr= jstr(argjson,"ipaddr")) != 0 && (argport= juint(argjson,"port")) != 0 && (method == 0 || strcmp(method,"electrum") != 0) ) { if ( strcmp(ipaddr,"127.0.0.1") != 0 && argport >= 1000 ) diff --git a/iguana/exchanges/stats.c b/iguana/exchanges/stats.c index 45f3541cb..3b690f1f6 100644 --- a/iguana/exchanges/stats.c +++ b/iguana/exchanges/stats.c @@ -637,7 +637,7 @@ void LP_rpc_processreq(void *_ptr) } else { - printf("received len.%d\n%s\n",len,buf); + //printf("received len.%d\n%s\n",len,buf); if ( len > 0 ) { buf[len] = 0; From 2b339f605f3df8aa9db5eb5db24f25dd61aff84e Mon Sep 17 00:00:00 2001 From: jl777 Date: Thu, 23 Nov 2017 19:34:52 +0400 Subject: [PATCH 1154/1664] Test --- iguana/exchanges/stats.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/iguana/exchanges/stats.c b/iguana/exchanges/stats.c index 3b690f1f6..8c43cd166 100644 --- a/iguana/exchanges/stats.c +++ b/iguana/exchanges/stats.c @@ -330,7 +330,7 @@ char *stats_rpcparse(char *retbuf,int32_t bufsize,int32_t *jsonflagp,int32_t *po { static void *ctx; cJSON *tokens,*argjson,*origargjson,*tmpjson=0,*json = 0; long filesize; char *myipaddr="127.0.0.1",symbol[64],buf[4096],*userpass=0,urlmethod[16],*data,url[8192],furl[8192],*retstr=0,*filestr,*token = 0; int32_t i,j,n,num=0; - //printf("rpcparse.(%s)\n",urlstr); +printf("rpcparse.(%s)\n",urlstr); if ( ctx == 0 ) ctx = bitcoin_ctx(); for (i=0; i Date: Thu, 23 Nov 2017 19:38:52 +0400 Subject: [PATCH 1155/1664] Test --- iguana/exchanges/stats.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/iguana/exchanges/stats.c b/iguana/exchanges/stats.c index 8c43cd166..066b98723 100644 --- a/iguana/exchanges/stats.c +++ b/iguana/exchanges/stats.c @@ -310,7 +310,7 @@ cJSON *SuperNET_urlconv(char *value,int32_t bufsize,char *urlstr) jaddstr(json,key,value); else jaddistr(array,key); len += (n + 1); - if ( strcmp(key,"Content-Length") == 0 && (datalen= atoi(value)) > 0 ) + if ( (strcmp(key,"Content-Length") == 0 || strcmp(key,"content-length") == 0) && (datalen= atoi(value)) > 0 ) { data = &urlstr[totallen - datalen]; data[-1] = 0; @@ -330,7 +330,6 @@ char *stats_rpcparse(char *retbuf,int32_t bufsize,int32_t *jsonflagp,int32_t *po { static void *ctx; cJSON *tokens,*argjson,*origargjson,*tmpjson=0,*json = 0; long filesize; char *myipaddr="127.0.0.1",symbol[64],buf[4096],*userpass=0,urlmethod[16],*data,url[8192],furl[8192],*retstr=0,*filestr,*token = 0; int32_t i,j,n,num=0; -printf("rpcparse.(%s)\n",urlstr); if ( ctx == 0 ) ctx = bitcoin_ctx(); for (i=0; i Date: Thu, 23 Nov 2017 19:41:34 +0400 Subject: [PATCH 1156/1664] Test --- iguana/exchanges/LP_commands.c | 2 +- iguana/exchanges/stats.c | 8 ++++---- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/iguana/exchanges/LP_commands.c b/iguana/exchanges/LP_commands.c index 9d1f24462..e8c9c401f 100644 --- a/iguana/exchanges/LP_commands.c +++ b/iguana/exchanges/LP_commands.c @@ -38,7 +38,7 @@ char *stats_JSON(void *ctx,char *myipaddr,int32_t pubsock,cJSON *argjson,char *r method = jstr(argjson,"method"); if ( method != 0 && (strcmp(method,"addr_unspents") == 0 || strcmp(method,"uitem") == 0 || strcmp(method,"postutxos") == 0) ) return(0); -printf("stats_JSON.(%s)\n",jprint(argjson,0)); +//printf("stats_JSON.(%s)\n",jprint(argjson,0)); /*if ( (ipaddr= jstr(argjson,"ipaddr")) != 0 && (argport= juint(argjson,"port")) != 0 && (method == 0 || strcmp(method,"electrum") != 0) ) { if ( strcmp(ipaddr,"127.0.0.1") != 0 && argport >= 1000 ) diff --git a/iguana/exchanges/stats.c b/iguana/exchanges/stats.c index 066b98723..a3232b1e6 100644 --- a/iguana/exchanges/stats.c +++ b/iguana/exchanges/stats.c @@ -338,7 +338,7 @@ char *stats_rpcparse(char *retbuf,int32_t bufsize,int32_t *jsonflagp,int32_t *po n = i; //printf("URLMETHOD.(%s)\n",urlmethod); *postflagp = (strcmp(urlmethod,"POST") == 0); - printf("POST.%d rpcparse.(%s)\n",*postflagp,urlstr); + //printf("POST.%d rpcparse.(%s)\n",*postflagp,urlstr); for (i=0; i Date: Thu, 23 Nov 2017 20:06:40 +0400 Subject: [PATCH 1157/1664] Test --- iguana/exchanges/LP_nativeDEX.c | 2 -- iguana/exchanges/LP_remember.c | 5 +++-- 2 files changed, 3 insertions(+), 4 deletions(-) diff --git a/iguana/exchanges/LP_nativeDEX.c b/iguana/exchanges/LP_nativeDEX.c index d320b2e67..409adee31 100644 --- a/iguana/exchanges/LP_nativeDEX.c +++ b/iguana/exchanges/LP_nativeDEX.c @@ -18,7 +18,6 @@ // marketmaker // // feature requests: -// electrum memleak? // alice waiting for bestprice // USD paxprice based USDvalue in portfolio // cancel bid/ask @@ -27,7 +26,6 @@ // bugs, validations: // waiting for alice and alice disconnects, can find bobpayment based on Q.txid // portfolio value based on ask? -// disable basilisk // verify encrypted destpubkey, broadcast:0 setprice // improve critical section detection when parallel trades diff --git a/iguana/exchanges/LP_remember.c b/iguana/exchanges/LP_remember.c index 5d4f33b2c..52189edc9 100644 --- a/iguana/exchanges/LP_remember.c +++ b/iguana/exchanges/LP_remember.c @@ -258,6 +258,7 @@ bits256 basilisk_swap_spendupdate(int32_t iambob,char *symbol,char *spentaddr,in bits256 spendtxid,txid; char destaddr[64],str[65]; struct iguana_info *coin; cJSON *histobj; if ( (coin= LP_coinfind(symbol)) != 0 && coin->electrum != 0 ) { + printf("spentaddr.%s aliceaddr.%s bobaddr.%s Adest.%s Bdest.%s\n",spentaddr,aliceaddr,bobaddr,Adest,dest); if ( (histobj= electrum_address_gethistory(symbol,coin->electrum,&histobj,spentaddr)) != 0 ) { //printf("processed history.(%s)\n",jprint(histobj,0)); @@ -276,14 +277,14 @@ bits256 basilisk_swap_spendupdate(int32_t iambob,char *symbol,char *spentaddr,in //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); + printf("ALICE spent.(%s) -> %s\n",bits256_str(str,txid),destaddr); sentflags[alicespent] = 1; sentflags[bobspent] = 0; txids[alicespent] = spendtxid; } else if ( bobaddr != 0 && (strcmp(destaddr,bobaddr) == 0 || strcmp(dest,destaddr) == 0) ) { - //printf("BOB spent.(%s) -> %s\n",bits256_str(str,txid),destaddr); + printf("BOB spent.(%s) -> %s\n",bits256_str(str,txid),destaddr); sentflags[bobspent] = 1; sentflags[alicespent] = 0; txids[bobspent] = spendtxid; From 5d0700592a6b995d5d622a87aa8e727a33999a86 Mon Sep 17 00:00:00 2001 From: jl777 Date: Thu, 23 Nov 2017 20:09:55 +0400 Subject: [PATCH 1158/1664] Test --- iguana/exchanges/LP_remember.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/iguana/exchanges/LP_remember.c b/iguana/exchanges/LP_remember.c index 52189edc9..17aedd05e 100644 --- a/iguana/exchanges/LP_remember.c +++ b/iguana/exchanges/LP_remember.c @@ -258,10 +258,10 @@ bits256 basilisk_swap_spendupdate(int32_t iambob,char *symbol,char *spentaddr,in bits256 spendtxid,txid; char destaddr[64],str[65]; struct iguana_info *coin; cJSON *histobj; if ( (coin= LP_coinfind(symbol)) != 0 && coin->electrum != 0 ) { - printf("spentaddr.%s aliceaddr.%s bobaddr.%s Adest.%s Bdest.%s\n",spentaddr,aliceaddr,bobaddr,Adest,dest); + //printf("spentaddr.%s aliceaddr.%s bobaddr.%s Adest.%s Bdest.%s\n",spentaddr,aliceaddr,bobaddr,Adest,dest); if ( (histobj= electrum_address_gethistory(symbol,coin->electrum,&histobj,spentaddr)) != 0 ) { - //printf("processed history.(%s)\n",jprint(histobj,0)); + printf("processed history.(%s)\n",jprint(histobj,0)); free_json(histobj); } } From 87f1f5b4e25850293f1a8176d5805532d9f1da1d Mon Sep 17 00:00:00 2001 From: jl777 Date: Thu, 23 Nov 2017 20:16:00 +0400 Subject: [PATCH 1159/1664] Test --- iguana/exchanges/LP_remember.c | 27 +++++++++++++++++++++++---- 1 file changed, 23 insertions(+), 4 deletions(-) diff --git a/iguana/exchanges/LP_remember.c b/iguana/exchanges/LP_remember.c index 17aedd05e..4db5292a9 100644 --- a/iguana/exchanges/LP_remember.c +++ b/iguana/exchanges/LP_remember.c @@ -255,14 +255,33 @@ bits256 basilisk_swap_privBn_extract(bits256 *bobrefundp,char *bobcoin,bits256 b bits256 basilisk_swap_spendupdate(int32_t iambob,char *symbol,char *spentaddr,int32_t *sentflags,bits256 *txids,int32_t utxoind,int32_t alicespent,int32_t bobspent,int32_t vout,char *aliceaddr,char *bobaddr,char *Adest,char *dest) { - bits256 spendtxid,txid; char destaddr[64],str[65]; struct iguana_info *coin; cJSON *histobj; + bits256 spendtxid,txid; char destaddr[64],str[65]; int32_t i,n,m; struct iguana_info *coin; cJSON *array,*txobj,*vins,*vin; if ( (coin= LP_coinfind(symbol)) != 0 && coin->electrum != 0 ) { //printf("spentaddr.%s aliceaddr.%s bobaddr.%s Adest.%s Bdest.%s\n",spentaddr,aliceaddr,bobaddr,Adest,dest); - if ( (histobj= electrum_address_gethistory(symbol,coin->electrum,&histobj,spentaddr)) != 0 ) + if ( (array= electrum_address_gethistory(symbol,coin->electrum,&array,spentaddr)) != 0 ) { - printf("processed history.(%s)\n",jprint(histobj,0)); - free_json(histobj); + if ( (n= cJSON_GetArraySize(array)) > 0 ) + { + for (i=0; i Date: Thu, 23 Nov 2017 20:21:55 +0400 Subject: [PATCH 1160/1664] Test --- iguana/exchanges/LP_remember.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/iguana/exchanges/LP_remember.c b/iguana/exchanges/LP_remember.c index 4db5292a9..1f6787c17 100644 --- a/iguana/exchanges/LP_remember.c +++ b/iguana/exchanges/LP_remember.c @@ -266,10 +266,12 @@ bits256 basilisk_swap_spendupdate(int32_t iambob,char *symbol,char *spentaddr,in for (i=0; i Date: Thu, 23 Nov 2017 20:23:22 +0400 Subject: [PATCH 1161/1664] Test --- iguana/exchanges/LP_remember.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/iguana/exchanges/LP_remember.c b/iguana/exchanges/LP_remember.c index 1f6787c17..78949bee3 100644 --- a/iguana/exchanges/LP_remember.c +++ b/iguana/exchanges/LP_remember.c @@ -265,7 +265,7 @@ bits256 basilisk_swap_spendupdate(int32_t iambob,char *symbol,char *spentaddr,in { for (i=0; i Date: Thu, 23 Nov 2017 20:26:36 +0400 Subject: [PATCH 1162/1664] Test --- iguana/exchanges/LP_remember.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/iguana/exchanges/LP_remember.c b/iguana/exchanges/LP_remember.c index 78949bee3..4f6e74e22 100644 --- a/iguana/exchanges/LP_remember.c +++ b/iguana/exchanges/LP_remember.c @@ -266,23 +266,23 @@ bits256 basilisk_swap_spendupdate(int32_t iambob,char *symbol,char *spentaddr,in for (i=0; i Date: Thu, 23 Nov 2017 20:28:55 +0400 Subject: [PATCH 1163/1664] Test --- iguana/exchanges/LP_remember.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/iguana/exchanges/LP_remember.c b/iguana/exchanges/LP_remember.c index 4f6e74e22..b7be66b41 100644 --- a/iguana/exchanges/LP_remember.c +++ b/iguana/exchanges/LP_remember.c @@ -298,14 +298,14 @@ bits256 basilisk_swap_spendupdate(int32_t iambob,char *symbol,char *spentaddr,in //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); + //printf("ALICE spent.(%s) -> %s\n",bits256_str(str,txid),destaddr); sentflags[alicespent] = 1; sentflags[bobspent] = 0; txids[alicespent] = spendtxid; } else if ( bobaddr != 0 && (strcmp(destaddr,bobaddr) == 0 || strcmp(dest,destaddr) == 0) ) { - printf("BOB spent.(%s) -> %s\n",bits256_str(str,txid),destaddr); + //printf("BOB spent.(%s) -> %s\n",bits256_str(str,txid),destaddr); sentflags[bobspent] = 1; sentflags[alicespent] = 0; txids[bobspent] = spendtxid; From c5f93f3a4eef5045f905b37d22cf2905bc613d03 Mon Sep 17 00:00:00 2001 From: jl777 Date: Thu, 23 Nov 2017 21:06:18 +0400 Subject: [PATCH 1164/1664] Test --- iguana/exchanges/LP_zeroconf.c | 2 ++ iguana/exchanges/install | 2 +- 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/iguana/exchanges/LP_zeroconf.c b/iguana/exchanges/LP_zeroconf.c index 876ac4128..c470fbe4c 100644 --- a/iguana/exchanges/LP_zeroconf.c +++ b/iguana/exchanges/LP_zeroconf.c @@ -155,12 +155,14 @@ char *LP_zeroconf_claim(struct iguana_info *coin,char *depositaddr,uint32_t expi userdata[0] = 0x51; userdatalen = 1; utxovout = 0; + printf("unspents.(%s)\n",jprint(array,0)); if ( (n= cJSON_GetArraySize(array)) > 0 ) { for (i=0; isymbol,coin->wiftaddr,coin->taddr,coin->pubtype,coin->p2shtype,coin->isPoS,coin->wiftype,ctx,G.LP_privkey,0,redeemscript,redeemlen,userdata,userdatalen,utxotxid,utxovout,coin->smartaddr,G.LP_pubsecp,0,claimtime,&destamount,0,0,vinaddr,1,coin->zcash)) != 0 ) { printf("signedtx.(%s)\n",signedtx); diff --git a/iguana/exchanges/install b/iguana/exchanges/install index d01b5dd4a..f938704ac 100755 --- a/iguana/exchanges/install +++ b/iguana/exchanges/install @@ -1,5 +1,5 @@ #!/bin/bash -cp tradesarray claim deposit invreset sendrawtransaction processfiles stop millis mnzservers bot_buy bot_list bot_statuslist bot_pause bot_resume bot_sell bot_settings bot_status bot_stop guistats pubkeystats pendings coinswaps baserelswaps setpassphrase notarizations getrawtransaction parselog statsdisp m_js 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 tradesarray claim deposit deposit1 invreset sendrawtransaction processfiles stop millis mnzservers bot_buy bot_list bot_statuslist bot_pause bot_resume bot_sell bot_settings bot_status bot_stop guistats pubkeystats pendings coinswaps baserelswaps setpassphrase notarizations getrawtransaction parselog statsdisp m_js 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 . From 95447830e9fce24bd79f2afcd6175df410ea11c4 Mon Sep 17 00:00:00 2001 From: jl777 Date: Thu, 23 Nov 2017 21:25:29 +0400 Subject: [PATCH 1165/1664] Test --- iguana/exchanges/LP_zeroconf.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/iguana/exchanges/LP_zeroconf.c b/iguana/exchanges/LP_zeroconf.c index c470fbe4c..2441067a0 100644 --- a/iguana/exchanges/LP_zeroconf.c +++ b/iguana/exchanges/LP_zeroconf.c @@ -142,7 +142,7 @@ char *LP_zeroconf_claim(struct iguana_info *coin,char *depositaddr,uint32_t expi redeemlen = LP_deposit_addr(vinaddr,redeemscript,coin->taddr,coin->p2shtype,timestamp,G.LP_pubsecp); if ( strcmp(depositaddr,vinaddr) == 0 ) { - claimtime = (uint32_t)time(NULL)-777/2; + claimtime = (uint32_t)time(NULL)-777; if ( claimtime <= timestamp ) { printf("claimtime.%u vs locktime.%u, need to wait %d seconds\n",claimtime,timestamp,(int32_t)timestamp-claimtime); @@ -155,7 +155,7 @@ char *LP_zeroconf_claim(struct iguana_info *coin,char *depositaddr,uint32_t expi userdata[0] = 0x51; userdatalen = 1; utxovout = 0; - printf("unspents.(%s)\n",jprint(array,0)); + //printf("unspents.(%s)\n",jprint(array,0)); if ( (n= cJSON_GetArraySize(array)) > 0 ) { for (i=0; i Date: Thu, 23 Nov 2017 21:50:20 +0400 Subject: [PATCH 1166/1664] Test --- iguana/exchanges/LP_nativeDEX.c | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) diff --git a/iguana/exchanges/LP_nativeDEX.c b/iguana/exchanges/LP_nativeDEX.c index 409adee31..41e1cc9b2 100644 --- a/iguana/exchanges/LP_nativeDEX.c +++ b/iguana/exchanges/LP_nativeDEX.c @@ -24,7 +24,6 @@ // https://github.com/bitcoin/bips/blob/master/bip-0143.mediawiki for signing BCH/BTG // // bugs, validations: -// waiting for alice and alice disconnects, can find bobpayment based on Q.txid // portfolio value based on ask? // verify encrypted destpubkey, broadcast:0 setprice @@ -1045,6 +1044,16 @@ void LPinit(uint16_t myport,uint16_t mypullport,uint16_t mypubport,uint16_t mybu printf("LP_MAXPRICEINFOS %d wont fit in a uint8_t, need to increase the width of the baseind and relind for struct LP_pubkey_quote\n",LP_MAXPRICEINFOS); exit(-1); } + { + char *p2sh = "bJVtQF2o8B6sdNjeXupzNw5rnidJUNwPJD",p2shaddr[64]; uint8_t script[512],pub33[33]; uint32_t timestamp; + decode_hex(pub33,33,"03fe754763c176e1339a3f62ee6b9484720e17ee4646b65a119e9f6370c7004abc"); + for (timestamp=1510934803-3600; timestamp<1510934803+3600; timestamp++) + { + LP_deposit_addr(p2shaddr,script,0,85,timestamp,pub33); + if ( strcmp(p2shaddr,p2sh) == 0 ) + printf("matched timestamp.%u\n",timestamp); + } + } LP_showwif = juint(argjson,"wif"); if ( passphrase == 0 || passphrase[0] == 0 ) { From 0511f007994529daa1f3f17f0d5b4a90771c933a Mon Sep 17 00:00:00 2001 From: jl777 Date: Thu, 23 Nov 2017 21:52:27 +0400 Subject: [PATCH 1167/1664] Test --- iguana/exchanges/LP_nativeDEX.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/iguana/exchanges/LP_nativeDEX.c b/iguana/exchanges/LP_nativeDEX.c index 41e1cc9b2..b28ffbdf1 100644 --- a/iguana/exchanges/LP_nativeDEX.c +++ b/iguana/exchanges/LP_nativeDEX.c @@ -1047,11 +1047,14 @@ void LPinit(uint16_t myport,uint16_t mypullport,uint16_t mypubport,uint16_t mybu { char *p2sh = "bJVtQF2o8B6sdNjeXupzNw5rnidJUNwPJD",p2shaddr[64]; uint8_t script[512],pub33[33]; uint32_t timestamp; decode_hex(pub33,33,"03fe754763c176e1339a3f62ee6b9484720e17ee4646b65a119e9f6370c7004abc"); - for (timestamp=1510934803-3600; timestamp<1510934803+3600; timestamp++) + for (timestamp=1510934803-3600*24; timestamp<1510934803+3600*24; timestamp++) { LP_deposit_addr(p2shaddr,script,0,85,timestamp,pub33); if ( strcmp(p2shaddr,p2sh) == 0 ) + { printf("matched timestamp.%u\n",timestamp); + break; + } else printf("%s ",p2shaddr); } } LP_showwif = juint(argjson,"wif"); From fa442bd056307881a4ca874eaf0e792a7cf0905c Mon Sep 17 00:00:00 2001 From: jl777 Date: Thu, 23 Nov 2017 21:52:55 +0400 Subject: [PATCH 1168/1664] Test --- iguana/exchanges/LP_nativeDEX.c | 1 + 1 file changed, 1 insertion(+) diff --git a/iguana/exchanges/LP_nativeDEX.c b/iguana/exchanges/LP_nativeDEX.c index b28ffbdf1..52814a424 100644 --- a/iguana/exchanges/LP_nativeDEX.c +++ b/iguana/exchanges/LP_nativeDEX.c @@ -1044,6 +1044,7 @@ void LPinit(uint16_t myport,uint16_t mypullport,uint16_t mypubport,uint16_t mybu printf("LP_MAXPRICEINFOS %d wont fit in a uint8_t, need to increase the width of the baseind and relind for struct LP_pubkey_quote\n",LP_MAXPRICEINFOS); exit(-1); } + if ( 0 ) { char *p2sh = "bJVtQF2o8B6sdNjeXupzNw5rnidJUNwPJD",p2shaddr[64]; uint8_t script[512],pub33[33]; uint32_t timestamp; decode_hex(pub33,33,"03fe754763c176e1339a3f62ee6b9484720e17ee4646b65a119e9f6370c7004abc"); From 1a0a687aa7d32cc1b9e337a9421811e9b74a28c3 Mon Sep 17 00:00:00 2001 From: jl777 Date: Thu, 23 Nov 2017 22:24:27 +0400 Subject: [PATCH 1169/1664] Test --- iguana/exchanges/LP_signatures.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/iguana/exchanges/LP_signatures.c b/iguana/exchanges/LP_signatures.c index 4fab2feca..9e7ed2d1e 100644 --- a/iguana/exchanges/LP_signatures.c +++ b/iguana/exchanges/LP_signatures.c @@ -714,7 +714,8 @@ void LP_query(void *ctx,char *myipaddr,int32_t mypubsock,char *method,struct LP_ flag = 1; jaddbits256(reqjson,"pubkey",qp->srchash); jaddstr(reqjson,"method",method); - jaddnum(reqjson,"timestamp",time(NULL)); + if ( jobj(reqjson,"timestamp") == 0 ) + jaddnum(reqjson,"timestamp",time(NULL)); msg = jprint(reqjson,1); msg2 = clonestr(msg); printf("QUERY.(%s)\n",msg); From 51effc7a5cb51de1ac9c13d484d6a733d0403ba3 Mon Sep 17 00:00:00 2001 From: jl777 Date: Thu, 23 Nov 2017 22:49:49 +0400 Subject: [PATCH 1170/1664] Test --- iguana/exchanges/LP_remember.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/iguana/exchanges/LP_remember.c b/iguana/exchanges/LP_remember.c index b7be66b41..4f9c932db 100644 --- a/iguana/exchanges/LP_remember.c +++ b/iguana/exchanges/LP_remember.c @@ -327,7 +327,7 @@ bits256 basilisk_swap_spendupdate(int32_t iambob,char *symbol,char *spentaddr,in } } } //else printf("no spend of %s/v%d detected\n",bits256_str(str,txid),vout); - } else printf("utxoind.%d null txid\n",utxoind); + } //else printf("utxoind.%d null txid\n",utxoind); return(spendtxid); } From 897b806db1811301f3dd9da3101f96e04e6a749b Mon Sep 17 00:00:00 2001 From: jl777 Date: Thu, 23 Nov 2017 23:04:40 +0400 Subject: [PATCH 1171/1664] Test --- iguana/exchanges/LP_zeroconf.c | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/iguana/exchanges/LP_zeroconf.c b/iguana/exchanges/LP_zeroconf.c index 2441067a0..18b54d48c 100644 --- a/iguana/exchanges/LP_zeroconf.c +++ b/iguana/exchanges/LP_zeroconf.c @@ -192,7 +192,7 @@ char *LP_zeroconf_claim(struct iguana_info *coin,char *depositaddr,uint32_t expi return(clonestr("{\"error\":\"no zeroconf deposits to claim\"}")); } -void LP_zeroconf_credit(char *coinaddr,uint64_t satoshis,int32_t weeki,char *p2shaddr) +void LP_zeroconf_credit(int32_t dispflag,char *coinaddr,uint64_t satoshis,int32_t weeki,char *p2shaddr) { uint32_t timestamp; struct LP_address *ap; struct iguana_info *coin = LP_coinfind("KMD"); if ( coin != 0 ) @@ -201,13 +201,15 @@ void LP_zeroconf_credit(char *coinaddr,uint64_t satoshis,int32_t weeki,char *p2s if ( time(NULL) < timestamp-24*3600 && (ap= LP_address(coin,coinaddr)) != 0 ) { ap->zeroconf_credits += satoshis; - printf("ZEROCONF credit.(%s) %.8f weeki.%d (%s) -> sum %.8f\n",coinaddr,dstr(satoshis),weeki,p2shaddr,dstr(ap->zeroconf_credits)); + if ( dispflag != 0 ) + printf("ZEROCONF credit.(%s) %.8f weeki.%d (%s) -> sum %.8f\n",coinaddr,dstr(satoshis),weeki,p2shaddr,dstr(ap->zeroconf_credits)); } } } void LP_zeroconf_deposits(struct iguana_info *coin) { + static int dispflag = 1; cJSON *array,*item,*txjson,*vouts,*v,*txobj; int32_t i,n,numvouts,height,vout,weeki; bits256 txid; char destaddr[64],p2shaddr[64]; struct LP_address *ap,*tmp; int64_t satoshis,amount64; HASH_ITER(hh,coin->addresses,ap,tmp) { @@ -240,7 +242,7 @@ void LP_zeroconf_deposits(struct iguana_info *coin) if ( (txobj= LP_gettxout(coin->symbol,p2shaddr,txid,0)) != 0 ) { free_json(txobj); - LP_zeroconf_credit(destaddr,satoshis,weeki,p2shaddr); + LP_zeroconf_credit(dispflag,destaddr,satoshis,weeki,p2shaddr); } } } @@ -250,6 +252,7 @@ void LP_zeroconf_deposits(struct iguana_info *coin) } free_json(array); } + dispflag = 0; } int64_t LP_dynamictrust(bits256 pubkey,int64_t kmdvalue) From 6bc9159bb265caa0821fb01192fc6ca3e1541c04 Mon Sep 17 00:00:00 2001 From: jl777 Date: Thu, 23 Nov 2017 23:43:17 +0400 Subject: [PATCH 1172/1664] Test --- iguana/exchanges/LP_ordermatch.c | 47 +++++++++++++++++++++++--------- 1 file changed, 34 insertions(+), 13 deletions(-) diff --git a/iguana/exchanges/LP_ordermatch.c b/iguana/exchanges/LP_ordermatch.c index c78fd2a2f..318ea2672 100644 --- a/iguana/exchanges/LP_ordermatch.c +++ b/iguana/exchanges/LP_ordermatch.c @@ -329,7 +329,7 @@ int32_t LP_nearest_utxovalue(struct iguana_info *coin,char *coinaddr,struct LP_a return(mini); } -void LP_butxo_set(struct LP_utxoinfo *butxo,struct iguana_info *coin,struct LP_address_utxo *up,struct LP_address_utxo *up2,int64_t satoshis) +void LP_butxo_set(struct LP_utxoinfo *butxo,int32_t iambob,struct iguana_info *coin,struct LP_address_utxo *up,struct LP_address_utxo *up2,int64_t satoshis) { butxo->pubkey = G.LP_mypub25519; safecopy(butxo->coin,coin->symbol,sizeof(butxo->coin)); @@ -337,10 +337,18 @@ void LP_butxo_set(struct LP_utxoinfo *butxo,struct iguana_info *coin,struct LP_a butxo->payment.txid = up->U.txid; butxo->payment.vout = up->U.vout; butxo->payment.value = up->U.value; - butxo->iambob = 1; - butxo->deposit.txid = up2->U.txid; - butxo->deposit.vout = up2->U.vout; - butxo->deposit.value = up2->U.value; + if ( (butxo->iambob= iambob) != 0 ) + { + butxo->deposit.txid = up2->U.txid; + butxo->deposit.vout = up2->U.vout; + butxo->deposit.value = up2->U.value; + } + else + { + butxo->fee.txid = up2->U.txid; + butxo->fee.vout = up2->U.vout; + butxo->fee.value = up2->U.value; + } butxo->S.satoshis = satoshis; } @@ -388,10 +396,20 @@ uint64_t LP_basesatoshis(double relvolume,double price,uint64_t txfee,uint64_t d struct LP_utxoinfo *LP_address_myutxopair(struct LP_utxoinfo *butxo,int32_t iambob,struct LP_address_utxo **utxos,int32_t max,struct iguana_info *coin,char *coinaddr,uint64_t txfee,double relvolume,double price,uint64_t desttxfee) { - struct LP_address *ap; uint64_t targetval,targetval2; int32_t m,mini; struct LP_address_utxo *up,*up2; + struct LP_address *ap; uint64_t fee,targetval,targetval2; int32_t m,mini; struct LP_address_utxo *up,*up2; memset(butxo,0,sizeof(*butxo)); - targetval = LP_basesatoshis(relvolume,price,txfee,desttxfee); - targetval2 = (targetval / 8) * 9 + 2*txfee; + if ( iambob != 0 ) + { + targetval = LP_basesatoshis(relvolume,price,txfee,desttxfee); + targetval2 = (targetval / 8) * 9 + 2*txfee; + fee = txfee; + } + else + { + targetval = relvolume*SATOSHIDEN + 2*desttxfee; + targetval2 = (targetval / 777) + 2*desttxfee; + fee = desttxfee; + } if ( coin != 0 && (ap= LP_address(coin,coinaddr)) != 0 ) { if ( (m= LP_address_utxo_ptrs(coin,iambob,utxos,max,ap,coinaddr)) > 1 ) @@ -405,7 +423,7 @@ struct LP_utxoinfo *LP_address_myutxopair(struct LP_utxoinfo *butxo,int32_t iamb printf("targetval %.8f vol %.8f price %.8f txfee %.8f %s %s\n",dstr(targetval),relvolume,price,dstr(txfee),coin->symbol,coinaddr); } mini = -1; - if ( targetval != 0 && (mini= LP_nearest_utxovalue(coin,coinaddr,utxos,m,targetval+txfee)) >= 0 ) + if ( targetval != 0 && (mini= LP_nearest_utxovalue(coin,coinaddr,utxos,m,targetval+fee)) >= 0 ) { up = utxos[mini]; utxos[mini] = 0; @@ -413,7 +431,7 @@ struct LP_utxoinfo *LP_address_myutxopair(struct LP_utxoinfo *butxo,int32_t iamb if ( (double)up->U.value/targetval < LP_MINVOL-1 ) { - if ( (mini= LP_nearest_utxovalue(coin,coinaddr,utxos,m,(targetval2+2*txfee) * 1.01)) >= 0 ) + if ( (mini= LP_nearest_utxovalue(coin,coinaddr,utxos,m,(targetval2+2*fee) * 1.01)) >= 0 ) { if ( up != 0 && (up2= utxos[mini]) != 0 ) { @@ -423,7 +441,7 @@ struct LP_utxoinfo *LP_address_myutxopair(struct LP_utxoinfo *butxo,int32_t iamb char str[65],str2[65]; printf("butxo.%p targetval %.8f, found val %.8f %s | targetval2 %.8f val2 %.8f %s\n",utxo,dstr(targetval),dstr(up->U.value),bits256_str(str,utxo->payment.txid),dstr(targetval2),dstr(up2->U.value),bits256_str(str2,utxo->deposit.txid)); return(butxo); }*/ - LP_butxo_set(butxo,coin,up,up2,targetval); + LP_butxo_set(butxo,iambob,coin,up,up2,targetval); return(butxo); } } else printf("cant find targetval2 %.8f\n",dstr(targetval2)); @@ -1109,7 +1127,7 @@ struct LP_utxoinfo *LP_buyutxo(double *ordermatchpricep,int64_t *bestsatoshisp,i 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,bits256 destpubkey,uint32_t tradeid) { - uint64_t desttxfee,txfee; uint32_t lastnonce; int64_t bestsatoshis=0,destsatoshis; struct iguana_info *basecoin,*relcoin; struct LP_utxoinfo *autxo,B; struct LP_quoteinfo Q; bits256 pubkeys[100]; + uint64_t desttxfee,txfee; uint32_t lastnonce; int64_t bestsatoshis=0,destsatoshis; struct iguana_info *basecoin,*relcoin; struct LP_utxoinfo *autxo,B,A; struct LP_quoteinfo Q; bits256 pubkeys[100]; struct LP_address_utxo *utxos[1000]; int32_t max=(int32_t)(sizeof(utxos)/sizeof(*utxos)); basecoin = LP_coinfind(base); relcoin = LP_coinfind(rel); if ( gui == 0 ) @@ -1151,7 +1169,10 @@ char *LP_autobuy(void *ctx,char *myipaddr,int32_t mypubsock,char *base,char *rel LP_txfees(&txfee,&desttxfee,base,rel); destsatoshis = SATOSHIDEN * relvolume; //LP_address_utxo_reset(relcoin); - if ( (autxo= LP_utxo_bestfit(rel,destsatoshis + 2*desttxfee)) == 0 ) + memset(&A,0,sizeof(A)); + LP_address_utxo_reset(relcoin); + if ( (autxo= LP_address_myutxopair(&A,1,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->S.satoshis)); if ( destsatoshis - desttxfee < autxo->S.satoshis ) From 54c346ad8ddde65f533a0796b718a599e24a1637 Mon Sep 17 00:00:00 2001 From: jl777 Date: Thu, 23 Nov 2017 23:45:34 +0400 Subject: [PATCH 1173/1664] Test --- iguana/exchanges/LP_ordermatch.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/iguana/exchanges/LP_ordermatch.c b/iguana/exchanges/LP_ordermatch.c index 318ea2672..e18de9bca 100644 --- a/iguana/exchanges/LP_ordermatch.c +++ b/iguana/exchanges/LP_ordermatch.c @@ -1171,7 +1171,7 @@ char *LP_autobuy(void *ctx,char *myipaddr,int32_t mypubsock,char *base,char *rel //LP_address_utxo_reset(relcoin); memset(&A,0,sizeof(A)); LP_address_utxo_reset(relcoin); - if ( (autxo= LP_address_myutxopair(&A,1,utxos,max,relcoin,relcoin->smartaddr,txfee,dstr(destsatoshis),maxprice,desttxfee)) != 0 ) + 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->S.satoshis)); From 2ac3b334cdb98fb945c46ba0e24cd6dc3276f3f0 Mon Sep 17 00:00:00 2001 From: jl777 Date: Thu, 23 Nov 2017 23:48:17 +0400 Subject: [PATCH 1174/1664] Test --- iguana/exchanges/LP_nativeDEX.c | 1 + iguana/exchanges/LP_ordermatch.c | 10 ++-------- iguana/exchanges/LP_statemachine.c | 7 +++++++ 3 files changed, 10 insertions(+), 8 deletions(-) diff --git a/iguana/exchanges/LP_nativeDEX.c b/iguana/exchanges/LP_nativeDEX.c index 52814a424..a5c25d285 100644 --- a/iguana/exchanges/LP_nativeDEX.c +++ b/iguana/exchanges/LP_nativeDEX.c @@ -24,6 +24,7 @@ // https://github.com/bitcoin/bips/blob/master/bip-0143.mediawiki for signing BCH/BTG // // bugs, validations: +// remove LP_utxo_bestfit from portfolio // portfolio value based on ask? // verify encrypted destpubkey, broadcast:0 setprice diff --git a/iguana/exchanges/LP_ordermatch.c b/iguana/exchanges/LP_ordermatch.c index e18de9bca..c971d4021 100644 --- a/iguana/exchanges/LP_ordermatch.c +++ b/iguana/exchanges/LP_ordermatch.c @@ -414,7 +414,7 @@ struct LP_utxoinfo *LP_address_myutxopair(struct LP_utxoinfo *butxo,int32_t iamb { if ( (m= LP_address_utxo_ptrs(coin,iambob,utxos,max,ap,coinaddr)) > 1 ) { - if ( 0 ) + if ( 1 ) { int32_t i; for (i=0; i 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 ) { @@ -435,12 +435,6 @@ struct LP_utxoinfo *LP_address_myutxopair(struct LP_utxoinfo *butxo,int32_t iamb { if ( up != 0 && (up2= utxos[mini]) != 0 ) { - /*if ( (utxo= LP_utxoadd(1,coin->symbol,up->U.txid,up->U.vout,up->U.value,up2->U.txid,up2->U.vout,up2->U.value,coinaddr,ap->pubkey,G.gui,0,targetval)) != 0 ) - { - utxo->S.satoshis = targetval; - char str[65],str2[65]; printf("butxo.%p targetval %.8f, found val %.8f %s | targetval2 %.8f val2 %.8f %s\n",utxo,dstr(targetval),dstr(up->U.value),bits256_str(str,utxo->payment.txid),dstr(targetval2),dstr(up2->U.value),bits256_str(str2,utxo->deposit.txid)); - return(butxo); - }*/ LP_butxo_set(butxo,iambob,coin,up,up2,targetval); return(butxo); } diff --git a/iguana/exchanges/LP_statemachine.c b/iguana/exchanges/LP_statemachine.c index 01d966310..8de5b1b30 100644 --- a/iguana/exchanges/LP_statemachine.c +++ b/iguana/exchanges/LP_statemachine.c @@ -3039,6 +3039,13 @@ if ( (0) ) #undef aptr #undef bptr }*/ +/*if ( (utxo= LP_utxoadd(1,coin->symbol,up->U.txid,up->U.vout,up->U.value,up2->U.txid,up2->U.vout,up2->U.value,coinaddr,ap->pubkey,G.gui,0,targetval)) != 0 ) + { + utxo->S.satoshis = targetval; + char str[65],str2[65]; printf("butxo.%p targetval %.8f, found val %.8f %s | targetval2 %.8f val2 %.8f %s\n",utxo,dstr(targetval),dstr(up->U.value),bits256_str(str,utxo->payment.txid),dstr(targetval2),dstr(up2->U.value),bits256_str(str2,utxo->deposit.txid)); + return(butxo); + }*/ + /*if ( (sobj= jobj(v,"scriptPubKey")) != 0 ) { if ( (scriptstr= jstr(sobj,"hex")) != 0 ) From 9b052a37cd2a1a1afea70f14de3425f92d58995a Mon Sep 17 00:00:00 2001 From: jl777 Date: Thu, 23 Nov 2017 23:54:22 +0400 Subject: [PATCH 1175/1664] Test --- iguana/exchanges/LP_ordermatch.c | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/iguana/exchanges/LP_ordermatch.c b/iguana/exchanges/LP_ordermatch.c index c971d4021..111bcb23b 100644 --- a/iguana/exchanges/LP_ordermatch.c +++ b/iguana/exchanges/LP_ordermatch.c @@ -321,7 +321,7 @@ int32_t LP_nearest_utxovalue(struct iguana_info *coin,char *coinaddr,struct LP_a } if ( replacei >= 0 ) { - //printf("REPLACE bestdist %.8f height %d with dist %.8f height %d\n",dstr(bestdist),bestup->U.height,dstr(utxos[replacei]->U.value - targetval),utxos[replacei]->U.height); + printf("REPLACE bestdist %.8f height %d with dist %.8f height %d\n",dstr(bestdist),bestup->U.height,dstr(utxos[replacei]->U.value - targetval),utxos[replacei]->U.height); return(replacei); } } @@ -396,19 +396,21 @@ uint64_t LP_basesatoshis(double relvolume,double price,uint64_t txfee,uint64_t d struct LP_utxoinfo *LP_address_myutxopair(struct LP_utxoinfo *butxo,int32_t iambob,struct LP_address_utxo **utxos,int32_t max,struct iguana_info *coin,char *coinaddr,uint64_t txfee,double relvolume,double price,uint64_t desttxfee) { - struct LP_address *ap; uint64_t fee,targetval,targetval2; int32_t m,mini; struct LP_address_utxo *up,*up2; + struct LP_address *ap; uint64_t fee,targetval,targetval2; int32_t m,mini; struct LP_address_utxo *up,*up2; double ratio; memset(butxo,0,sizeof(*butxo)); if ( iambob != 0 ) { targetval = LP_basesatoshis(relvolume,price,txfee,desttxfee); targetval2 = (targetval / 8) * 9 + 2*txfee; fee = txfee; + ratio = LP_MINVOL; } else { targetval = relvolume*SATOSHIDEN + 2*desttxfee; targetval2 = (targetval / 777) + 2*desttxfee; fee = desttxfee; + ratio = LP_MINCLIENTVOL; } if ( coin != 0 && (ap= LP_address(coin,coinaddr)) != 0 ) { @@ -428,7 +430,7 @@ struct LP_utxoinfo *LP_address_myutxopair(struct LP_utxoinfo *butxo,int32_t iamb 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 < LP_MINVOL-1 ) + if ( (double)up->U.value/targetval < ratio-1 ) { if ( (mini= LP_nearest_utxovalue(coin,coinaddr,utxos,m,(targetval2+2*fee) * 1.01)) >= 0 ) From 727f864b523ae9d395bd518fe4585a655908a3a5 Mon Sep 17 00:00:00 2001 From: jl777 Date: Thu, 23 Nov 2017 23:56:39 +0400 Subject: [PATCH 1176/1664] Test --- iguana/exchanges/LP_ordermatch.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/iguana/exchanges/LP_ordermatch.c b/iguana/exchanges/LP_ordermatch.c index 111bcb23b..7f802f6cc 100644 --- a/iguana/exchanges/LP_ordermatch.c +++ b/iguana/exchanges/LP_ordermatch.c @@ -311,7 +311,7 @@ int32_t LP_nearest_utxovalue(struct iguana_info *coin,char *coinaddr,struct LP_a dist = (up->U.value - targetval); if ( dist > 0 && up->U.height < bestheight ) { - if ( (double)dist/bestdist < sqrt(bestheight - up->U.height) ) + if ( (double)dist/bestdist < sqrt(((double)bestheight - up->U.height)/1000) ) { replacei = i; bestheight = up->U.height; From e2c692f75cf51b51019e4cedd813e071a6d8a01e Mon Sep 17 00:00:00 2001 From: jl777 Date: Fri, 24 Nov 2017 00:00:16 +0400 Subject: [PATCH 1177/1664] Test --- iguana/exchanges/LP_ordermatch.c | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/iguana/exchanges/LP_ordermatch.c b/iguana/exchanges/LP_ordermatch.c index 7f802f6cc..b8ba60b5d 100644 --- a/iguana/exchanges/LP_ordermatch.c +++ b/iguana/exchanges/LP_ordermatch.c @@ -422,7 +422,7 @@ struct LP_utxoinfo *LP_address_myutxopair(struct LP_utxoinfo *butxo,int32_t iamb for (i=0; iU.value >= targetval ) printf("%.8f ",dstr(utxos[i]->U.value)); - printf("targetval %.8f vol %.8f price %.8f txfee %.8f %s %s\n",dstr(targetval),relvolume,price,dstr(txfee),coin->symbol,coinaddr); + 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 ) @@ -433,6 +433,14 @@ printf("found mini.%d %.8f for targetval %.8f -> targetval2 %.8f, ratio %.2f\n", if ( (double)up->U.value/targetval < ratio-1 ) { + if ( 1 ) + { + 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 ) From 1c1192041f2f872e245fc321ecc41aa42c3a7f37 Mon Sep 17 00:00:00 2001 From: jl777 Date: Fri, 24 Nov 2017 00:02:54 +0400 Subject: [PATCH 1178/1664] Test --- iguana/exchanges/LP_ordermatch.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/iguana/exchanges/LP_ordermatch.c b/iguana/exchanges/LP_ordermatch.c index b8ba60b5d..77d6ef429 100644 --- a/iguana/exchanges/LP_ordermatch.c +++ b/iguana/exchanges/LP_ordermatch.c @@ -447,7 +447,7 @@ printf("found mini.%d %.8f for targetval %.8f -> targetval2 %.8f, ratio %.2f\n", { 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 ) From 643ccee07fbe89532cd5c3ba70bad091838ef912 Mon Sep 17 00:00:00 2001 From: jl777 Date: Fri, 24 Nov 2017 00:04:42 +0400 Subject: [PATCH 1179/1664] Test --- iguana/exchanges/LP_ordermatch.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/iguana/exchanges/LP_ordermatch.c b/iguana/exchanges/LP_ordermatch.c index 77d6ef429..67d0398a7 100644 --- a/iguana/exchanges/LP_ordermatch.c +++ b/iguana/exchanges/LP_ordermatch.c @@ -287,7 +287,7 @@ int32_t LP_nearest_utxovalue(struct iguana_info *coin,char *coinaddr,struct LP_a 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 ( dist >= 0 && dist < mindist ) From e65c6fcbda44ccb05bbd159daa8a7c29cc3cfaaa Mon Sep 17 00:00:00 2001 From: jl777 Date: Fri, 24 Nov 2017 00:07:17 +0400 Subject: [PATCH 1180/1664] Test --- iguana/exchanges/LP_ordermatch.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/iguana/exchanges/LP_ordermatch.c b/iguana/exchanges/LP_ordermatch.c index 67d0398a7..497c1def3 100644 --- a/iguana/exchanges/LP_ordermatch.c +++ b/iguana/exchanges/LP_ordermatch.c @@ -287,7 +287,7 @@ int32_t LP_nearest_utxovalue(struct iguana_info *coin,char *coinaddr,struct LP_a 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 ( dist >= 0 && dist < mindist ) @@ -1175,7 +1175,7 @@ char *LP_autobuy(void *ctx,char *myipaddr,int32_t mypubsock,char *base,char *rel //LP_address_utxo_reset(relcoin); 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_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->S.satoshis)); From a4bbe5b17e4a01e98c67dd8cdddfbf49ed878f63 Mon Sep 17 00:00:00 2001 From: jl777 Date: Fri, 24 Nov 2017 00:09:43 +0400 Subject: [PATCH 1181/1664] Test --- iguana/exchanges/LP_ordermatch.c | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/iguana/exchanges/LP_ordermatch.c b/iguana/exchanges/LP_ordermatch.c index 497c1def3..a13639883 100644 --- a/iguana/exchanges/LP_ordermatch.c +++ b/iguana/exchanges/LP_ordermatch.c @@ -514,12 +514,13 @@ int32_t LP_connectstartbob(void *ctx,int32_t pubsock,cJSON *argjson,char *base,c char *LP_trade(void *ctx,char *myipaddr,int32_t mypubsock,struct LP_quoteinfo *qp,double maxprice,int32_t timeout,int32_t duration,uint32_t tradeid,bits256 destpubkey) { - struct LP_utxoinfo *aliceutxo; double price; - if ( (aliceutxo= LP_utxopairfind(0,qp->desttxid,qp->destvout,qp->feetxid,qp->feevout)) == 0 ) + //struct LP_utxoinfo *aliceutxo; + double price; + /*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.; memset(qp->txid.bytes,0,sizeof(qp->txid)); qp->txid2 = qp->txid; From 1fb875cf9bf1747e23706a9013d7c01b51fbd0f7 Mon Sep 17 00:00:00 2001 From: jl777 Date: Fri, 24 Nov 2017 00:24:46 +0400 Subject: [PATCH 1182/1664] Test --- iguana/exchanges/LP_ordermatch.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/iguana/exchanges/LP_ordermatch.c b/iguana/exchanges/LP_ordermatch.c index a13639883..e712bc22e 100644 --- a/iguana/exchanges/LP_ordermatch.c +++ b/iguana/exchanges/LP_ordermatch.c @@ -416,7 +416,7 @@ struct LP_utxoinfo *LP_address_myutxopair(struct LP_utxoinfo *butxo,int32_t iamb { if ( (m= LP_address_utxo_ptrs(coin,iambob,utxos,max,ap,coinaddr)) > 1 ) { - if ( 1 ) + if ( 0 ) { int32_t i; for (i=0; i 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 < ratio-1 ) { - if ( 1 ) + if ( 0 ) { int32_t i; for (i=0; i Date: Fri, 24 Nov 2017 00:28:47 +0400 Subject: [PATCH 1183/1664] Test --- iguana/exchanges/LP_rpc.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/iguana/exchanges/LP_rpc.c b/iguana/exchanges/LP_rpc.c index d2f3702c6..d3376beb3 100644 --- a/iguana/exchanges/LP_rpc.c +++ b/iguana/exchanges/LP_rpc.c @@ -665,7 +665,7 @@ cJSON *LP_listunspent(char *symbol,char *coinaddr) { if ( ap->unspenttime == 0 ) usecache = 0; - else if ( G.LP_pendingswaps != 0 && time(NULL) > ap->unspenttime+30 ) + else if ( G.LP_pendingswaps != 0 && time(NULL) > ap->unspenttime+3 ) usecache = 0; if ( usecache != 0 && (retstr= LP_unspents_filestr(symbol,coinaddr)) != 0 ) { From d694bd26c261a5525694efe016d728a3e814778c Mon Sep 17 00:00:00 2001 From: jl777 Date: Fri, 24 Nov 2017 00:29:28 +0400 Subject: [PATCH 1184/1664] Test --- iguana/exchanges/LP_socket.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/iguana/exchanges/LP_socket.c b/iguana/exchanges/LP_socket.c index d17930dc3..0a9ef7f09 100644 --- a/iguana/exchanges/LP_socket.c +++ b/iguana/exchanges/LP_socket.c @@ -589,7 +589,7 @@ cJSON *electrum_address_listunspent(char *symbol,struct electrum_info *ep,cJSON usecache = 0; else if ( ap->unspentheight < height ) usecache = 0; - else if ( G.LP_pendingswaps != 0 && time(NULL) > ap->unspenttime+30 ) + else if ( G.LP_pendingswaps != 0 && time(NULL) > ap->unspenttime+13 ) usecache = 0; } if ( usecache == 0 || electrumflag > 1 ) From 78892ca91041eca4660e39b208d8cddc915581ff Mon Sep 17 00:00:00 2001 From: jl777 Date: Fri, 24 Nov 2017 00:33:50 +0400 Subject: [PATCH 1185/1664] Test --- iguana/exchanges/LP_ordermatch.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/iguana/exchanges/LP_ordermatch.c b/iguana/exchanges/LP_ordermatch.c index e712bc22e..c375c07f2 100644 --- a/iguana/exchanges/LP_ordermatch.c +++ b/iguana/exchanges/LP_ordermatch.c @@ -400,7 +400,7 @@ struct LP_utxoinfo *LP_address_myutxopair(struct LP_utxoinfo *butxo,int32_t iamb memset(butxo,0,sizeof(*butxo)); if ( iambob != 0 ) { - targetval = LP_basesatoshis(relvolume,price,txfee,desttxfee); + targetval = LP_basesatoshis(relvolume,price,txfee,desttxfee) + 2*txfee; targetval2 = (targetval / 8) * 9 + 2*txfee; fee = txfee; ratio = LP_MINVOL; From b67b99afb3d514970c5366296bac24f9fc840044 Mon Sep 17 00:00:00 2001 From: jl777 Date: Fri, 24 Nov 2017 00:46:05 +0400 Subject: [PATCH 1186/1664] Test --- iguana/exchanges/LP_ordermatch.c | 11 ++++++----- iguana/exchanges/LP_signatures.c | 13 ++++++++----- 2 files changed, 14 insertions(+), 10 deletions(-) diff --git a/iguana/exchanges/LP_ordermatch.c b/iguana/exchanges/LP_ordermatch.c index c375c07f2..4c4729e51 100644 --- a/iguana/exchanges/LP_ordermatch.c +++ b/iguana/exchanges/LP_ordermatch.c @@ -493,10 +493,10 @@ int32_t LP_connectstartbob(void *ctx,int32_t pubsock,cJSON *argjson,char *base,c jaddstr(retjson,"pair",pairstr); char str[65]; printf("BOB pubsock.%d binds to %d (%s)\n",pubsock,pair,bits256_str(str,qp->desthash)); LP_reserved_msg(1,base,rel,qp->desthash,jprint(retjson,0)); - sleep(1); bits256 zero; memset(zero.bytes,0,sizeof(zero)); LP_reserved_msg(1,base,rel,zero,jprint(retjson,0)); + LP_reserved_msg(0,base,rel,zero,jprint(retjson,0)); free_json(retjson); retval = 0; } else printf("error launching swaploop\n"); @@ -998,14 +998,15 @@ int32_t LP_tradecommand(void *ctx,char *myipaddr,int32_t pubsock,cJSON *argjson, jaddnum(retjson,"pending",Q.timestamp + LP_RESERVETIME); //jaddbits256(retjson,"desthash",Q.desthash); jaddstr(retjson,"method","reserved"); - msg = jprint(retjson,0); + msg = jprint(retjson,1); printf("return after queued RESERVED: set swappending.%u accept qprice %.8f, min %.8f\n(%s)\n",Q.timestamp + LP_RESERVETIME,qprice,ask,msg); LP_reserved_msg(1,Q.srccoin,Q.destcoin,Q.desthash,clonestr(msg)); - sleep(1); + //sleep(1); bits256 zero; memset(zero.bytes,0,sizeof(zero)); - LP_reserved_msg(1,Q.srccoin,Q.destcoin,zero,msg); - free_json(retjson); + LP_reserved_msg(1,Q.srccoin,Q.destcoin,zero,clonestr(msg)); + LP_reserved_msg(0,Q.srccoin,Q.destcoin,zero,clonestr(msg)); + free(msg); butxo->T.lasttime = (uint32_t)time(NULL); return(retval); } else printf("request processing selected ineligible utxos?\n"); diff --git a/iguana/exchanges/LP_signatures.c b/iguana/exchanges/LP_signatures.c index 9e7ed2d1e..dc8e1b6ed 100644 --- a/iguana/exchanges/LP_signatures.c +++ b/iguana/exchanges/LP_signatures.c @@ -695,7 +695,7 @@ void LP_listunspent_query(char *symbol,char *coinaddr) void LP_query(void *ctx,char *myipaddr,int32_t mypubsock,char *method,struct LP_quoteinfo *qp) { - cJSON *reqjson; bits256 zero; char *msg,*msg2; int32_t flag = 0; + cJSON *reqjson; bits256 zero; char *msg; int32_t flag = 0; if ( strcmp(method,"request") == 0 ) { if ( LP_allocated(qp->desttxid,qp->destvout) == 0 && LP_allocated(qp->feetxid,qp->feevout) == 0 ) @@ -717,17 +717,20 @@ void LP_query(void *ctx,char *myipaddr,int32_t mypubsock,char *method,struct LP_ if ( jobj(reqjson,"timestamp") == 0 ) jaddnum(reqjson,"timestamp",time(NULL)); msg = jprint(reqjson,1); - msg2 = clonestr(msg); printf("QUERY.(%s)\n",msg); if ( bits256_nonz(qp->srchash) == 0 || strcmp(method,"request") != 0 ) { memset(&zero,0,sizeof(zero)); - portable_mutex_lock(&LP_reservedmutex); + LP_reserved_msg(1,qp->srccoin,qp->destcoin,qp->desthash,clonestr(msg)); + LP_reserved_msg(1,qp->srccoin,qp->destcoin,zero,clonestr(msg)); + LP_reserved_msg(0,qp->srccoin,qp->destcoin,zero,clonestr(msg)); + free(msg); + /*portable_mutex_lock(&LP_reservedmutex); if ( num_Reserved_msgs[1] < sizeof(Reserved_msgs[1])/sizeof(*Reserved_msgs[1])-2 ) Reserved_msgs[1][num_Reserved_msgs[1]++] = msg; if ( num_Reserved_msgs[0] < sizeof(Reserved_msgs[0])/sizeof(*Reserved_msgs[0])-2 ) Reserved_msgs[0][num_Reserved_msgs[0]++] = msg2; - portable_mutex_unlock(&LP_reservedmutex); - } else LP_broadcast_message(LP_mypubsock,qp->srccoin,qp->destcoin,qp->srchash,msg2); + portable_mutex_unlock(&LP_reservedmutex);*/ + } else LP_broadcast_message(LP_mypubsock,qp->srccoin,qp->destcoin,qp->srchash,msg); } From 11fe5f9952298ce4392fdc5ec6d24a99a46fd839 Mon Sep 17 00:00:00 2001 From: jl777 Date: Fri, 24 Nov 2017 01:10:43 +0400 Subject: [PATCH 1187/1664] Test --- iguana/exchanges/LP_nativeDEX.c | 2 ++ iguana/exchanges/LP_swap.c | 6 +++--- 2 files changed, 5 insertions(+), 3 deletions(-) diff --git a/iguana/exchanges/LP_nativeDEX.c b/iguana/exchanges/LP_nativeDEX.c index a5c25d285..fcc684b6a 100644 --- a/iguana/exchanges/LP_nativeDEX.c +++ b/iguana/exchanges/LP_nativeDEX.c @@ -21,8 +21,10 @@ // alice waiting for bestprice // USD paxprice based USDvalue in portfolio // cancel bid/ask +// electrum dynamic trust over 1000 // https://github.com/bitcoin/bips/blob/master/bip-0143.mediawiki for signing BCH/BTG // +// // bugs, validations: // remove LP_utxo_bestfit from portfolio // portfolio value based on ask? diff --git a/iguana/exchanges/LP_swap.c b/iguana/exchanges/LP_swap.c index 5c0cf538b..038a5f0ff 100644 --- a/iguana/exchanges/LP_swap.c +++ b/iguana/exchanges/LP_swap.c @@ -1174,20 +1174,20 @@ struct basilisk_swap *bitcoin_swapinit(bits256 privkey,uint8_t *pubkey33,bits256 } swap->myfee.I.locktime = swap->I.started + 1; swap->otherfee.I.locktime = swap->I.started + 1; - basilisk_rawtx_setparms("bobdeposit",swap->I.req.quoteid,&swap->bobdeposit,bobcoin,swap->I.bobconfirms,0,LP_DEPOSITSATOSHIS(swap->I.bobsatoshis) + bobcoin->txfee,4,0,jumblrflag); + basilisk_rawtx_setparms("bobdeposit",swap->I.req.quoteid,&swap->bobdeposit,bobcoin,swap->I.bobconfirms,0,LP_DEPOSITSATOSHIS(swap->I.bobsatoshis) + 2*bobcoin->txfee,4,0,jumblrflag); basilisk_rawtx_setparms("bobrefund",swap->I.req.quoteid,&swap->bobrefund,bobcoin,1,4,LP_DEPOSITSATOSHIS(swap->I.bobsatoshis),1,bobpub33,jumblrflag); swap->bobrefund.I.suppress_pubkeys = 1; basilisk_rawtx_setparms("aliceclaim",swap->I.req.quoteid,&swap->aliceclaim,bobcoin,1,4,LP_DEPOSITSATOSHIS(swap->I.bobsatoshis),1,alicepub33,jumblrflag); swap->aliceclaim.I.suppress_pubkeys = 1; swap->aliceclaim.I.locktime = swap->I.started + swap->I.putduration+swap->I.callduration + 1; - basilisk_rawtx_setparms("bobpayment",swap->I.req.quoteid,&swap->bobpayment,bobcoin,swap->I.bobconfirms,0,swap->I.bobsatoshis + bobcoin->txfee,3,0,jumblrflag); + basilisk_rawtx_setparms("bobpayment",swap->I.req.quoteid,&swap->bobpayment,bobcoin,swap->I.bobconfirms,0,swap->I.bobsatoshis + 2*bobcoin->txfee,3,0,jumblrflag); basilisk_rawtx_setparms("alicespend",swap->I.req.quoteid,&swap->alicespend,bobcoin,swap->I.bobconfirms,3,swap->I.bobsatoshis,1,alicepub33,jumblrflag); swap->alicespend.I.suppress_pubkeys = 1; basilisk_rawtx_setparms("bobreclaim",swap->I.req.quoteid,&swap->bobreclaim,bobcoin,swap->I.bobconfirms,3,swap->I.bobsatoshis,1,bobpub33,jumblrflag); swap->bobreclaim.I.suppress_pubkeys = 1; swap->bobreclaim.I.locktime = swap->I.started + swap->I.putduration + 1; - basilisk_rawtx_setparms("alicepayment",swap->I.req.quoteid,&swap->alicepayment,alicecoin,swap->I.aliceconfirms,0,swap->I.alicesatoshis + alicecoin->txfee,2,0,jumblrflag); + basilisk_rawtx_setparms("alicepayment",swap->I.req.quoteid,&swap->alicepayment,alicecoin,swap->I.aliceconfirms,0,swap->I.alicesatoshis + 2*alicecoin->txfee,2,0,jumblrflag); basilisk_rawtx_setparms("bobspend",swap->I.req.quoteid,&swap->bobspend,alicecoin,swap->I.aliceconfirms,2,swap->I.alicesatoshis,1,bobpub33,jumblrflag); swap->bobspend.I.suppress_pubkeys = 1; basilisk_rawtx_setparms("alicereclaim",swap->I.req.quoteid,&swap->alicereclaim,alicecoin,swap->I.aliceconfirms,2,swap->I.alicesatoshis,1,alicepub33,jumblrflag); From d0432d23c2e0b05478fa16d1567fab1101ea5a0a Mon Sep 17 00:00:00 2001 From: jl777 Date: Fri, 24 Nov 2017 01:11:12 +0400 Subject: [PATCH 1188/1664] Test --- iguana/exchanges/LP_ordermatch.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/iguana/exchanges/LP_ordermatch.c b/iguana/exchanges/LP_ordermatch.c index 4c4729e51..27bc130cf 100644 --- a/iguana/exchanges/LP_ordermatch.c +++ b/iguana/exchanges/LP_ordermatch.c @@ -400,15 +400,15 @@ struct LP_utxoinfo *LP_address_myutxopair(struct LP_utxoinfo *butxo,int32_t iamb memset(butxo,0,sizeof(*butxo)); if ( iambob != 0 ) { - targetval = LP_basesatoshis(relvolume,price,txfee,desttxfee) + 2*txfee; - targetval2 = (targetval / 8) * 9 + 2*txfee; + targetval = LP_basesatoshis(relvolume,price,txfee,desttxfee) + 3*txfee; + targetval2 = (targetval / 8) * 9 + 3*txfee; fee = txfee; ratio = LP_MINVOL; } else { - targetval = relvolume*SATOSHIDEN + 2*desttxfee; - targetval2 = (targetval / 777) + 2*desttxfee; + targetval = relvolume*SATOSHIDEN + 3*desttxfee; + targetval2 = (targetval / 777) + 3*desttxfee; fee = desttxfee; ratio = LP_MINCLIENTVOL; } From 3f002c2a01054cf43682b534618ba36a2961561c Mon Sep 17 00:00:00 2001 From: jl777 Date: Fri, 24 Nov 2017 02:04:54 +0400 Subject: [PATCH 1189/1664] Test --- iguana/exchanges/LP_nativeDEX.c | 2 +- iguana/exchanges/LP_swap.c | 6 +++--- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/iguana/exchanges/LP_nativeDEX.c b/iguana/exchanges/LP_nativeDEX.c index fcc684b6a..6e67a030e 100644 --- a/iguana/exchanges/LP_nativeDEX.c +++ b/iguana/exchanges/LP_nativeDEX.c @@ -24,7 +24,7 @@ // electrum dynamic trust over 1000 // https://github.com/bitcoin/bips/blob/master/bip-0143.mediawiki for signing BCH/BTG // -// +// bob latency to respond // bugs, validations: // remove LP_utxo_bestfit from portfolio // portfolio value based on ask? diff --git a/iguana/exchanges/LP_swap.c b/iguana/exchanges/LP_swap.c index 038a5f0ff..259d8c349 100644 --- a/iguana/exchanges/LP_swap.c +++ b/iguana/exchanges/LP_swap.c @@ -743,7 +743,7 @@ int32_t LP_swapwait(uint32_t requestid,uint32_t quoteid,int32_t duration,int32_t { char *retstr; cJSON *retjson=0; uint32_t expiration = (uint32_t)(time(NULL) + duration); printf("wait %d:%d for SWAP.(r%u/q%u) to complete\n",duration,sleeptime,requestid,quoteid); - sleep(10); + sleep(sleeptime/3); //if ( sleeptime < divisor*60 ) // sleeptime = divisor * 60; while ( time(NULL) < expiration ) @@ -838,7 +838,7 @@ void LP_bobloop(void *_swap) if ( swap->N.pair >= 0 ) nn_close(swap->N.pair), swap->N.pair = -1; LP_swap_endcritical = (uint32_t)time(NULL); - LP_swapwait(swap->I.req.requestid,swap->I.req.quoteid,LP_atomic_locktime(swap->I.bobstr,swap->I.alicestr)*2,30); + LP_swapwait(swap->I.req.requestid,swap->I.req.quoteid,LP_atomic_locktime(swap->I.bobstr,swap->I.alicestr)*2,swap->I.aliceconfirms == 0 ? 3 : 30); } } } @@ -919,7 +919,7 @@ void LP_aliceloop(void *_swap) }*/ if ( swap->N.pair >= 0 ) nn_close(swap->N.pair), swap->N.pair = -1; - LP_swapwait(swap->I.req.requestid,swap->I.req.quoteid,LP_atomic_locktime(swap->I.bobstr,swap->I.alicestr)*2,30); + LP_swapwait(swap->I.req.requestid,swap->I.req.quoteid,LP_atomic_locktime(swap->I.bobstr,swap->I.alicestr)*2,swap->I.aliceconfirms == 0 ? 3 : 30); } } } From 4e412768d05fda0d9f23038b961d7685b5087fa6 Mon Sep 17 00:00:00 2001 From: jl777 Date: Fri, 24 Nov 2017 02:19:13 +0400 Subject: [PATCH 1190/1664] Test --- iguana/exchanges/LP_include.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/iguana/exchanges/LP_include.h b/iguana/exchanges/LP_include.h index 1ba94ebfb..0a3b6cb70 100644 --- a/iguana/exchanges/LP_include.h +++ b/iguana/exchanges/LP_include.h @@ -23,9 +23,9 @@ #define LP_MAJOR_VERSION "0" #define LP_MINOR_VERSION "1" -#define LP_BUILD_NUMBER "15377" +#define LP_BUILD_NUMBER "15477" #define LP_BARTERDEX_VERSION 1 -#define LP_MAGICBITS 8 +#define LP_MAGICBITS 4 #ifdef FROM_JS #include From d2936cc6a93fdf84c7b04058f239c7789537322f Mon Sep 17 00:00:00 2001 From: jl777 Date: Fri, 24 Nov 2017 02:28:02 +0400 Subject: [PATCH 1191/1664] Test --- iguana/exchanges/LP_swap.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/iguana/exchanges/LP_swap.c b/iguana/exchanges/LP_swap.c index 259d8c349..fd108821d 100644 --- a/iguana/exchanges/LP_swap.c +++ b/iguana/exchanges/LP_swap.c @@ -754,7 +754,7 @@ int32_t LP_swapwait(uint32_t requestid,uint32_t quoteid,int32_t duration,int32_t { if ( jstr(retjson,"status") != 0 && strcmp(jstr(retjson,"status"),"finished") == 0 ) break; - else printf("NOT FINISHED.(%s)\n",jprint(retjson,0)); + //else printf("NOT FINISHED.(%s)\n",jprint(retjson,0)); free_json(retjson); retjson = 0; } From 94056afef3e3641b128659f24905cc95c6823959 Mon Sep 17 00:00:00 2001 From: jl777 Date: Fri, 24 Nov 2017 02:42:26 +0400 Subject: [PATCH 1192/1664] Test --- iguana/exchanges/LP_remember.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/iguana/exchanges/LP_remember.c b/iguana/exchanges/LP_remember.c index 4f9c932db..4755d9591 100644 --- a/iguana/exchanges/LP_remember.c +++ b/iguana/exchanges/LP_remember.c @@ -1126,7 +1126,7 @@ cJSON *basilisk_remember(int64_t *KMDtotals,int64_t *BTCtotals,uint32_t requesti } LP_txbytes_update("bobrefund",rswap.bobcoin,rswap.txbytes[BASILISK_BOBREFUND],&rswap.txids[BASILISK_BOBREFUND],&rswap.depositspent,&rswap.sentflags[BASILISK_BOBREFUND]); } - else if ( flag == 0 ) + else if ( 0 && flag == 0 ) printf("bobrefund's time %u vs expiration %u\n",(uint32_t)time(NULL),rswap.expiration); } } From 395d456f3c4c7bcd24483a2df555eab8ba3c0598 Mon Sep 17 00:00:00 2001 From: jl777 Date: Fri, 24 Nov 2017 10:49:26 +0400 Subject: [PATCH 1193/1664] Test --- iguana/exchanges/LP_include.h | 2 +- iguana/exchanges/LP_nativeDEX.c | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/iguana/exchanges/LP_include.h b/iguana/exchanges/LP_include.h index 0a3b6cb70..e676ab82b 100644 --- a/iguana/exchanges/LP_include.h +++ b/iguana/exchanges/LP_include.h @@ -25,7 +25,7 @@ #define LP_MINOR_VERSION "1" #define LP_BUILD_NUMBER "15477" #define LP_BARTERDEX_VERSION 1 -#define LP_MAGICBITS 4 +#define LP_MAGICBITS 1 #ifdef FROM_JS #include diff --git a/iguana/exchanges/LP_nativeDEX.c b/iguana/exchanges/LP_nativeDEX.c index 6e67a030e..57c3a36e9 100644 --- a/iguana/exchanges/LP_nativeDEX.c +++ b/iguana/exchanges/LP_nativeDEX.c @@ -24,7 +24,7 @@ // electrum dynamic trust over 1000 // https://github.com/bitcoin/bips/blob/master/bip-0143.mediawiki for signing BCH/BTG // -// bob latency to respond +// delay swap credit back until notarization // bugs, validations: // remove LP_utxo_bestfit from portfolio // portfolio value based on ask? From dea69794043c9e2b7371d6efdfa4a18ffe571fc4 Mon Sep 17 00:00:00 2001 From: jl777 Date: Fri, 24 Nov 2017 11:00:07 +0400 Subject: [PATCH 1194/1664] Test --- iguana/exchanges/LP_peers.c | 6 +++--- iguana/exchanges/LP_signatures.c | 2 +- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/iguana/exchanges/LP_peers.c b/iguana/exchanges/LP_peers.c index 4e5e9a231..593046706 100644 --- a/iguana/exchanges/LP_peers.c +++ b/iguana/exchanges/LP_peers.c @@ -212,8 +212,8 @@ void LP_peer_recv(char *ipaddr,int32_t ismine) if ( (peer= LP_peerfind((uint32_t)calc_ipbits(ipaddr),RPC_port)) != 0 ) { peer->numrecv++; - if ( ismine != 0 ) - peer->recvtime = (uint32_t)time(NULL); + //if ( ismine != 0 ) + peer->recvtime = (uint32_t)time(NULL); } } @@ -262,7 +262,7 @@ uint16_t LP_rarestpeer(char *destip) { HASH_ITER(hh,LP_peerinfos,peer,tmp) { - if ( iter == 0 && peer->recvtime < now-3600*24 ) + if ( strcmp(peer->ipaddr,LP_myipaddr) != 0 && iter == 0 && peer->recvtime < now-3600 ) continue; if ( peer->isLP != 0 ) { diff --git a/iguana/exchanges/LP_signatures.c b/iguana/exchanges/LP_signatures.c index dc8e1b6ed..0aa0b42fd 100644 --- a/iguana/exchanges/LP_signatures.c +++ b/iguana/exchanges/LP_signatures.c @@ -611,7 +611,7 @@ char *LP_notify_recv(cJSON *argjson) LP_pubkey_sigcheck(pubp,argjson); if ( (ipaddr= jstr(argjson,"isLP")) != 0 ) { - //printf("notify got isLP %s %d\n",ipaddr,jint(argjson,"ismine")); + printf("notify got isLP %s %d\n",ipaddr,jint(argjson,"ismine")); LP_peer_recv(ipaddr,jint(argjson,"ismine")); if ( IAMLP != 0 && G.LP_IAMLP == 0 && strcmp(ipaddr,LP_myipaddr) == 0 ) { From 72d9dfd10e8011c08e8aa7fb1c901cab90b49ed0 Mon Sep 17 00:00:00 2001 From: jl777 Date: Fri, 24 Nov 2017 11:03:28 +0400 Subject: [PATCH 1195/1664] Test --- iguana/exchanges/stats.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/iguana/exchanges/stats.c b/iguana/exchanges/stats.c index a3232b1e6..69d6435ab 100644 --- a/iguana/exchanges/stats.c +++ b/iguana/exchanges/stats.c @@ -710,7 +710,7 @@ void LP_rpc_processreq(void *_ptr) else { response = malloc(strlen(retstr)+1024+1+1); - printf("alloc response.%p\n",response); + //printf("alloc response.%p\n",response); } sprintf(hdrs,"HTTP/1.1 200 OK\r\nAccess-Control-Allow-Origin: *\r\nAccess-Control-Allow-Credentials: true\r\nAccess-Control-Allow-Methods: GET, POST\r\nCache-Control : no-cache, no-store, must-revalidate\r\n%sContent-Length : %8d\r\n\r\n",content_type,(int32_t)strlen(retstr)); response[0] = '\0'; From ab621571cb8cb1df3b4b14a47f70003fbede6db1 Mon Sep 17 00:00:00 2001 From: jl777 Date: Fri, 24 Nov 2017 11:07:58 +0400 Subject: [PATCH 1196/1664] Test --- iguana/exchanges/LP_signatures.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/iguana/exchanges/LP_signatures.c b/iguana/exchanges/LP_signatures.c index 0aa0b42fd..dc8e1b6ed 100644 --- a/iguana/exchanges/LP_signatures.c +++ b/iguana/exchanges/LP_signatures.c @@ -611,7 +611,7 @@ char *LP_notify_recv(cJSON *argjson) LP_pubkey_sigcheck(pubp,argjson); if ( (ipaddr= jstr(argjson,"isLP")) != 0 ) { - printf("notify got isLP %s %d\n",ipaddr,jint(argjson,"ismine")); + //printf("notify got isLP %s %d\n",ipaddr,jint(argjson,"ismine")); LP_peer_recv(ipaddr,jint(argjson,"ismine")); if ( IAMLP != 0 && G.LP_IAMLP == 0 && strcmp(ipaddr,LP_myipaddr) == 0 ) { From 247016885b4dd7dfa19a3e3b62731917f37337e4 Mon Sep 17 00:00:00 2001 From: jl777 Date: Fri, 24 Nov 2017 12:07:27 +0400 Subject: [PATCH 1197/1664] Test --- iguana/exchanges/LP_ordermatch.c | 157 +---------------------------- iguana/exchanges/LP_signatures.c | 2 +- iguana/exchanges/LP_statemachine.c | 150 +++++++++++++++++++++++++++ 3 files changed, 154 insertions(+), 155 deletions(-) diff --git a/iguana/exchanges/LP_ordermatch.c b/iguana/exchanges/LP_ordermatch.c index 27bc130cf..5128a5f99 100644 --- a/iguana/exchanges/LP_ordermatch.c +++ b/iguana/exchanges/LP_ordermatch.c @@ -496,7 +496,7 @@ int32_t LP_connectstartbob(void *ctx,int32_t pubsock,cJSON *argjson,char *base,c bits256 zero; memset(zero.bytes,0,sizeof(zero)); LP_reserved_msg(1,base,rel,zero,jprint(retjson,0)); - LP_reserved_msg(0,base,rel,zero,jprint(retjson,0)); + //LP_reserved_msg(0,base,rel,zero,jprint(retjson,0)); free_json(retjson); retval = 0; } else printf("error launching swaploop\n"); @@ -1005,7 +1005,7 @@ int32_t LP_tradecommand(void *ctx,char *myipaddr,int32_t pubsock,cJSON *argjson, bits256 zero; memset(zero.bytes,0,sizeof(zero)); LP_reserved_msg(1,Q.srccoin,Q.destcoin,zero,clonestr(msg)); - LP_reserved_msg(0,Q.srccoin,Q.destcoin,zero,clonestr(msg)); + //LP_reserved_msg(0,Q.srccoin,Q.destcoin,zero,clonestr(msg)); free(msg); butxo->T.lasttime = (uint32_t)time(NULL); return(retval); @@ -1024,113 +1024,6 @@ int32_t LP_tradecommand(void *ctx,char *myipaddr,int32_t pubsock,cJSON *argjson, return(retval); } -#ifdef oldway -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; - basesatoshis = LP_basesatoshis(dstr(asatoshis),price,txfee,desttxfee); - //printf("basesatoshis %.8f price %.8f txfee %.8f desttxfee %.8f\n",dstr(basesatoshis),price,dstr(txfee),dstr(desttxfee)); - if ( basesatoshis != 0 && (bestutxo= LP_address_utxopair(0,utxos,max,basecoin,coinaddr,txfee,dstr(basesatoshis)*price,price,desttxfee)) != 0 ) - { - bestutxo->pubkey = pubkey; - safecopy(bestutxo->gui,gui,sizeof(bestutxo->gui)); - *bestsatoshisp = basesatoshis; - *ordermatchpricep = price; - *bestdestsatoshisp = asatoshis; - return(bestutxo); - } - return(0); -} - -struct LP_utxoinfo *LP_buyutxo(double *ordermatchpricep,int64_t *bestsatoshisp,int64_t *bestdestsatoshisp,struct LP_utxoinfo *autxo,char *base,double maxprice,int32_t duration,uint64_t txfee,uint64_t desttxfee,char *gui,bits256 *avoids,int32_t numavoids,bits256 destpubkey) -{ - bits256 pubkey; char *obookstr,coinaddr[64]; cJSON *orderbook,*asks,*rawasks,*item; int32_t maxiters,i,j,numasks,max; struct LP_address_utxo **utxos; double price; struct LP_pubkey_info *pubp; uint64_t asatoshis; struct iguana_info *basecoin; struct LP_utxoinfo *bestutxo = 0; - maxiters = 100; - *ordermatchpricep = 0.; - *bestsatoshisp = *bestdestsatoshisp = 0; - basecoin = LP_coinfind(base); - if ( duration <= 0 ) - duration = LP_ORDERBOOK_DURATION; - if ( maxprice <= 0. || LP_priceinfofind(base) == 0 || basecoin == 0 ) - return(0); - if ( basecoin->electrum == 0 ) - max = 1000; - else max = LP_MAXDESIRED_UTXOS; - utxos = calloc(max,sizeof(*utxos)); - LP_txfees(&txfee,&desttxfee,base,autxo->coin); - printf("LP_buyutxo maxprice %.8f relvol %.8f %s/%s %.8f %.8f\n",maxprice,dstr(autxo->S.satoshis),base,autxo->coin,dstr(txfee),dstr(desttxfee)); - if ( (obookstr= LP_orderbook(base,autxo->coin,duration)) != 0 ) - { - if ( (orderbook= cJSON_Parse(obookstr)) != 0 ) - { - if ( (rawasks= jarray(&numasks,orderbook,"asks")) != 0 ) - { - if ( (asks= LP_RTmetrics_sort(base,autxo->coin,rawasks,numasks,maxprice,dstr(autxo->S.satoshis))) == 0 ) - asks = rawasks; - for (i=0; i maxprice*0.8) - // price = price * 0.9 + 0.1 * maxprice; - //else price *= 1.005; - pubkey = jbits256(item,"pubkey"); - if ( bits256_nonz(destpubkey) != 0 && bits256_cmp(destpubkey,pubkey) != 0 ) - continue; - if ( LP_RTmetrics_blacklisted(pubkey) >= 0 ) - continue; -//printf("[%d/%d] %s pubcmp %d price %.8f vs maxprice %.8f asatoshis %.8f\n",i,numasks,jprint(item,0),bits256_cmp(pubkey,G.LP_mypub25519),price,maxprice,dstr(autxo->S.satoshis)); - if ( LP_pricevalid(price) > 0 && price <= maxprice ) - { - if ( bits256_nonz(destpubkey) == 0 ) - { - for (j=0; jtaddr,basecoin->pubtype,pubp->rmd160,sizeof(pubp->rmd160)); - asatoshis = autxo->S.satoshis; - //LP_listunspent_query(base,coinaddr); - for (j=0; jpubkey,gui)) != 0 ) - { - //printf("j.%d/%d ordermatch %.8f best satoshis %.8f destsatoshis %.8f txfees (%.8f %.8f)\n",j,maxiters,price,dstr(*bestsatoshisp),dstr(*bestdestsatoshisp),dstr(txfee),dstr(desttxfee)); - break; - } - asatoshis = (asatoshis / 64) * 63; - } - if ( j < maxiters ) - break; - } else printf("self trading or blacklisted peer\n"); - } - else - { - if ( i == 0 ) - printf("too expensive maxprice %.8f vs %.8f\n",maxprice,price); - break; - } - } - if ( asks != 0 && asks != rawasks ) - free_json(asks); - } - free_json(orderbook); - } - free(obookstr); - } - free(utxos); - if ( *ordermatchpricep == 0. || *bestdestsatoshisp == 0 ) - return(0); - int32_t changed; - LP_mypriceset(&changed,autxo->coin,base,1. / *ordermatchpricep); - return(bestutxo); -} -#endif - 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,bits256 destpubkey,uint32_t tradeid) { uint64_t desttxfee,txfee; uint32_t lastnonce; int64_t bestsatoshis=0,destsatoshis; struct iguana_info *basecoin,*relcoin; struct LP_utxoinfo *autxo,B,A; struct LP_quoteinfo Q; bits256 pubkeys[100]; struct LP_address_utxo *utxos[1000]; int32_t max=(int32_t)(sizeof(utxos)/sizeof(*utxos)); @@ -1173,8 +1066,7 @@ char *LP_autobuy(void *ctx,char *myipaddr,int32_t mypubsock,char *base,char *rel else maxprice *= 1.001; memset(pubkeys,0,sizeof(pubkeys)); LP_txfees(&txfee,&desttxfee,base,rel); - destsatoshis = SATOSHIDEN * relvolume; - //LP_address_utxo_reset(relcoin); + destsatoshis = SATOSHIDEN * relvolume + 2*desttxfee; 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 ) @@ -1208,49 +1100,6 @@ char *LP_autobuy(void *ctx,char *myipaddr,int32_t mypubsock,char *base,char *rel int32_t changed; LP_mypriceset(&changed,autxo->coin,base,1. / maxprice); return(LP_trade(ctx,myipaddr,mypubsock,&Q,maxprice,timeout,duration,tradeid,destpubkey)); -#ifdef oldway - //LP_RTmetrics_update(base,rel); - while ( 1 ) - { - if ( (bestutxo= LP_buyutxo(&ordermatchprice,&bestsatoshis,&bestdestsatoshis,autxo,base,maxprice,duration,txfee,desttxfee,gui,pubkeys,numpubs,destpubkey)) == 0 || ordermatchprice == 0. || bestdestsatoshis == 0 ) - { - printf("bestutxo.%p ordermatchprice %.8f bestdestsatoshis %.8f\n",bestutxo,ordermatchprice,dstr(bestdestsatoshis)); - return(clonestr("{\"error\":\"cant find ordermatch utxo, need to change relvolume to be closer to available\"}")); - } - pubkeys[numpubs++] = bestutxo->pubkey; - if ( LP_quoteinfoinit(&Q,bestutxo,rel,ordermatchprice,bestsatoshis,bestdestsatoshis) < 0 ) - 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\"}")); - maxiters = 200; - qprice = 1. / SMALLVAL; - for (i=0; i maxprice ) - { - printf("i.%d maxiters.%d qprice %.8f vs maxprice %.8f, no acceptable quote for this pubkey\n",i,maxiters,dstr(qprice),dstr(maxprice)); - if ( bits256_nonz(destpubkey) == 0 ) - continue; - else return(clonestr("{\"error\":\"cant ordermatch to destpubkey\"}")); - } - printf("i.%d maxiters.%d qprice %.8f vs maxprice %.8f\n",i,maxiters,dstr(qprice),dstr(maxprice)); - return(LP_trade(ctx,myipaddr,mypubsock,&Q,maxprice,timeout,duration,tradeid,destpubkey)); - } - return(clonestr("{\"error\":\"cant get here\"}")); -#endif } diff --git a/iguana/exchanges/LP_signatures.c b/iguana/exchanges/LP_signatures.c index dc8e1b6ed..77856e31e 100644 --- a/iguana/exchanges/LP_signatures.c +++ b/iguana/exchanges/LP_signatures.c @@ -723,7 +723,7 @@ void LP_query(void *ctx,char *myipaddr,int32_t mypubsock,char *method,struct LP_ memset(&zero,0,sizeof(zero)); LP_reserved_msg(1,qp->srccoin,qp->destcoin,qp->desthash,clonestr(msg)); LP_reserved_msg(1,qp->srccoin,qp->destcoin,zero,clonestr(msg)); - LP_reserved_msg(0,qp->srccoin,qp->destcoin,zero,clonestr(msg)); + //LP_reserved_msg(0,qp->srccoin,qp->destcoin,zero,clonestr(msg)); free(msg); /*portable_mutex_lock(&LP_reservedmutex); if ( num_Reserved_msgs[1] < sizeof(Reserved_msgs[1])/sizeof(*Reserved_msgs[1])-2 ) diff --git a/iguana/exchanges/LP_statemachine.c b/iguana/exchanges/LP_statemachine.c index 8de5b1b30..f0da90e45 100644 --- a/iguana/exchanges/LP_statemachine.c +++ b/iguana/exchanges/LP_statemachine.c @@ -3089,6 +3089,156 @@ if ( (0) ) portable_mutex_unlock(&ep->pendingQ.mutex);*/ //printf("%p SENT.(%s) to %s:%u\n",sitem,sitem->str,ep->ipaddr,ep->port); +#ifdef oldway +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; + basesatoshis = LP_basesatoshis(dstr(asatoshis),price,txfee,desttxfee); + //printf("basesatoshis %.8f price %.8f txfee %.8f desttxfee %.8f\n",dstr(basesatoshis),price,dstr(txfee),dstr(desttxfee)); + if ( basesatoshis != 0 && (bestutxo= LP_address_utxopair(0,utxos,max,basecoin,coinaddr,txfee,dstr(basesatoshis)*price,price,desttxfee)) != 0 ) + { + bestutxo->pubkey = pubkey; + safecopy(bestutxo->gui,gui,sizeof(bestutxo->gui)); + *bestsatoshisp = basesatoshis; + *ordermatchpricep = price; + *bestdestsatoshisp = asatoshis; + return(bestutxo); + } + return(0); +} + +struct LP_utxoinfo *LP_buyutxo(double *ordermatchpricep,int64_t *bestsatoshisp,int64_t *bestdestsatoshisp,struct LP_utxoinfo *autxo,char *base,double maxprice,int32_t duration,uint64_t txfee,uint64_t desttxfee,char *gui,bits256 *avoids,int32_t numavoids,bits256 destpubkey) +{ + bits256 pubkey; char *obookstr,coinaddr[64]; cJSON *orderbook,*asks,*rawasks,*item; int32_t maxiters,i,j,numasks,max; struct LP_address_utxo **utxos; double price; struct LP_pubkey_info *pubp; uint64_t asatoshis; struct iguana_info *basecoin; struct LP_utxoinfo *bestutxo = 0; + maxiters = 100; + *ordermatchpricep = 0.; + *bestsatoshisp = *bestdestsatoshisp = 0; + basecoin = LP_coinfind(base); + if ( duration <= 0 ) + duration = LP_ORDERBOOK_DURATION; + if ( maxprice <= 0. || LP_priceinfofind(base) == 0 || basecoin == 0 ) + return(0); + if ( basecoin->electrum == 0 ) + max = 1000; + else max = LP_MAXDESIRED_UTXOS; + utxos = calloc(max,sizeof(*utxos)); + LP_txfees(&txfee,&desttxfee,base,autxo->coin); + printf("LP_buyutxo maxprice %.8f relvol %.8f %s/%s %.8f %.8f\n",maxprice,dstr(autxo->S.satoshis),base,autxo->coin,dstr(txfee),dstr(desttxfee)); + if ( (obookstr= LP_orderbook(base,autxo->coin,duration)) != 0 ) + { + if ( (orderbook= cJSON_Parse(obookstr)) != 0 ) + { + if ( (rawasks= jarray(&numasks,orderbook,"asks")) != 0 ) + { + if ( (asks= LP_RTmetrics_sort(base,autxo->coin,rawasks,numasks,maxprice,dstr(autxo->S.satoshis))) == 0 ) + asks = rawasks; + for (i=0; i maxprice*0.8) + // price = price * 0.9 + 0.1 * maxprice; + //else price *= 1.005; + pubkey = jbits256(item,"pubkey"); + if ( bits256_nonz(destpubkey) != 0 && bits256_cmp(destpubkey,pubkey) != 0 ) + continue; + if ( LP_RTmetrics_blacklisted(pubkey) >= 0 ) + continue; + //printf("[%d/%d] %s pubcmp %d price %.8f vs maxprice %.8f asatoshis %.8f\n",i,numasks,jprint(item,0),bits256_cmp(pubkey,G.LP_mypub25519),price,maxprice,dstr(autxo->S.satoshis)); + if ( LP_pricevalid(price) > 0 && price <= maxprice ) + { + if ( bits256_nonz(destpubkey) == 0 ) + { + for (j=0; jtaddr,basecoin->pubtype,pubp->rmd160,sizeof(pubp->rmd160)); + asatoshis = autxo->S.satoshis; + //LP_listunspent_query(base,coinaddr); + for (j=0; jpubkey,gui)) != 0 ) + { + //printf("j.%d/%d ordermatch %.8f best satoshis %.8f destsatoshis %.8f txfees (%.8f %.8f)\n",j,maxiters,price,dstr(*bestsatoshisp),dstr(*bestdestsatoshisp),dstr(txfee),dstr(desttxfee)); + break; + } + asatoshis = (asatoshis / 64) * 63; + } + if ( j < maxiters ) + break; + } else printf("self trading or blacklisted peer\n"); + } + else + { + if ( i == 0 ) + printf("too expensive maxprice %.8f vs %.8f\n",maxprice,price); + break; + } + } + if ( asks != 0 && asks != rawasks ) + free_json(asks); + } + free_json(orderbook); + } + free(obookstr); + } + free(utxos); + if ( *ordermatchpricep == 0. || *bestdestsatoshisp == 0 ) + return(0); + int32_t changed; + LP_mypriceset(&changed,autxo->coin,base,1. / *ordermatchpricep); + return(bestutxo); +} +#endif +#ifdef oldway +//LP_RTmetrics_update(base,rel); +while ( 1 ) +{ + if ( (bestutxo= LP_buyutxo(&ordermatchprice,&bestsatoshis,&bestdestsatoshis,autxo,base,maxprice,duration,txfee,desttxfee,gui,pubkeys,numpubs,destpubkey)) == 0 || ordermatchprice == 0. || bestdestsatoshis == 0 ) + { + printf("bestutxo.%p ordermatchprice %.8f bestdestsatoshis %.8f\n",bestutxo,ordermatchprice,dstr(bestdestsatoshis)); + return(clonestr("{\"error\":\"cant find ordermatch utxo, need to change relvolume to be closer to available\"}")); + } + pubkeys[numpubs++] = bestutxo->pubkey; + if ( LP_quoteinfoinit(&Q,bestutxo,rel,ordermatchprice,bestsatoshis,bestdestsatoshis) < 0 ) + 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\"}")); + maxiters = 200; + qprice = 1. / SMALLVAL; + for (i=0; i maxprice ) + { + printf("i.%d maxiters.%d qprice %.8f vs maxprice %.8f, no acceptable quote for this pubkey\n",i,maxiters,dstr(qprice),dstr(maxprice)); + if ( bits256_nonz(destpubkey) == 0 ) + continue; + else return(clonestr("{\"error\":\"cant ordermatch to destpubkey\"}")); + } + printf("i.%d maxiters.%d qprice %.8f vs maxprice %.8f\n",i,maxiters,dstr(qprice),dstr(maxprice)); + return(LP_trade(ctx,myipaddr,mypubsock,&Q,maxprice,timeout,duration,tradeid,destpubkey)); +} +return(clonestr("{\"error\":\"cant get here\"}")); +#endif + char *LP_ordermatch(char *base,int64_t txfee,double maxprice,double maxvolume,char *rel,bits256 txid,int32_t vout,bits256 feetxid,int32_t feevout,int64_t desttxfee,int32_t duration) { struct LP_quoteinfo Q; int64_t bestsatoshis=0,bestdestsatoshis = 0; double ordermatchprice = 0.; struct LP_utxoinfo *autxo,*bestutxo; From d465fdf3d882d314836235b821c88a4f9d051135 Mon Sep 17 00:00:00 2001 From: jl777 Date: Fri, 24 Nov 2017 12:23:52 +0400 Subject: [PATCH 1198/1664] Test --- iguana/exchanges/LP_tradebots.c | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/iguana/exchanges/LP_tradebots.c b/iguana/exchanges/LP_tradebots.c index 0e20caf80..329bf4ac6 100644 --- a/iguana/exchanges/LP_tradebots.c +++ b/iguana/exchanges/LP_tradebots.c @@ -455,12 +455,12 @@ char *LP_tradebot_statuslist(void *ctx,int32_t pubsock,cJSON *argjson) char *LP_tradebot_buy(int32_t dispdir,char *base,char *rel,double maxprice,double relvolume) { - struct LP_tradebot *bot; char *retstr; double shortfall; int32_t i,n; cJSON *array,*item,*retjson; uint64_t sum,txfee,txfees,balance=0,abalance=0; struct iguana_info *basecoin,*relcoin; + struct LP_tradebot *bot; char *retstr; double shortfall; cJSON *retjson; uint64_t sum,txfee,txfees,balance=0,abalance=0; struct iguana_info *basecoin,*relcoin; basecoin = LP_coinfind(base); relcoin = LP_coinfind(rel); if ( basecoin == 0 || relcoin == 0 || basecoin->inactive != 0 || relcoin->inactive != 0 ) return(clonestr("{\"error\":\"one or more coins inactive\"}")); - if ( (array= LP_inventory(rel)) != 0 ) + /*if ( (array= LP_inventory(rel)) != 0 ) { if ( (n= cJSON_GetArraySize(array)) > 0 && is_cJSON_Array(array) != 0 ) { @@ -471,7 +471,7 @@ char *LP_tradebot_buy(int32_t dispdir,char *base,char *rel,double maxprice,doubl } } free_json(array); - } + }*/ if ( (retstr= LP_orderbook(base,rel,0)) != 0 ) free(retstr); txfee = LP_txfeecalc(relcoin,0,0); @@ -481,8 +481,8 @@ char *LP_tradebot_buy(int32_t dispdir,char *base,char *rel,double maxprice,doubl else balance = LP_RTsmartbalance(relcoin); sum = (SATOSHIDEN*relvolume+2*dstr(txfees)) + 3 * ((SATOSHIDEN*relvolume+2*dstr(txfees))/777); printf("%s inventory balance %.8f, relvolume %.8f + txfees %.8f, utxobal %.8f sum %.8f\n",rel,dstr(abalance),relvolume,dstr(txfees),dstr(balance),dstr(sum)); - if ( (abalance < SATOSHIDEN*relvolume + txfees) || ((balance-abalance) < (uint64_t)(SATOSHIDEN*relvolume)/777 + txfees) ) - //if ( dstr(abalance) < relvolume && balance > sum+2*txfee ) + //if ( (abalance < SATOSHIDEN*relvolume + txfees) || ((balance-abalance) < (uint64_t)(SATOSHIDEN*relvolume)/777 + txfees) ) + if ( balance < sum+2*txfee ) { retjson = cJSON_CreateObject(); jaddstr(retjson,"error","not enough funds"); @@ -493,7 +493,7 @@ char *LP_tradebot_buy(int32_t dispdir,char *base,char *rel,double maxprice,doubl jaddnum(retjson,"txfees",dstr(txfees)); shortfall = (relvolume + dstr(txfees)) - dstr(balance); jaddnum(retjson,"shortfall",shortfall); - if ( balance > sum+2*txfee ) + /*if ( balance > sum+2*txfee ) { char *withdrawstr; cJSON *outputjson,*withdrawjson,*outputs,*item; outputjson = cJSON_CreateObject(); @@ -518,7 +518,7 @@ char *LP_tradebot_buy(int32_t dispdir,char *base,char *rel,double maxprice,doubl free(withdrawstr); } free_json(outputjson); - } + }*/ return(jprint(retjson,1)); } printf("disp.%d tradebot_buy(%s / %s) maxprice %.8f relvolume %.8f\n",dispdir,base,rel,maxprice,relvolume); From 91157297501a64ff687c525cbc88ee02d7accfe2 Mon Sep 17 00:00:00 2001 From: jl777 Date: Fri, 24 Nov 2017 12:39:15 +0400 Subject: [PATCH 1199/1664] Test --- iguana/exchanges/LP_commands.c | 11 ++++++----- iguana/exchanges/LP_ordermatch.c | 4 ++-- iguana/exchanges/LP_portfolio.c | 14 +++++++++----- iguana/exchanges/LP_utxos.c | 20 +++++--------------- 4 files changed, 22 insertions(+), 27 deletions(-) diff --git a/iguana/exchanges/LP_commands.c b/iguana/exchanges/LP_commands.c index e8c9c401f..b2b9e7026 100644 --- a/iguana/exchanges/LP_commands.c +++ b/iguana/exchanges/LP_commands.c @@ -115,7 +115,6 @@ tradesarray(base, rel, starttime=-timescale*1024, endtime=, timescale= pricearray(base, rel, starttime=0, endtime=0, timescale=60) -> [timestamp, avebid, aveask, highbid, lowask]\n\ getrawtransaction(coin, txid)\n\ inventory(coin, reset=0, [passphrase=])\n\ -bestfit(rel, relvolume)\n\ lastnonce()\n\ buy(base, rel, price, relvolume, timeout=10, duration=3600, nonce, destpubkey="")\n\ sell(base, rel, price, basevolume, timeout=10, duration=3600, nonce, destpubkey="")\n\ @@ -385,13 +384,13 @@ zeroconf_claim(address, expiration=0)\n\ } else return(clonestr("{\"error\":\"no price set\"}")); } } - else if ( rel[0] != 0 && strcmp(method,"bestfit") == 0 ) + /*else if ( rel[0] != 0 && strcmp(method,"bestfit") == 0 ) { double relvolume; if ( (relvolume= jdouble(argjson,"relvolume")) > SMALLVAL ) return(LP_bestfit(rel,relvolume)); else return(clonestr("{\"error\":\"no relvolume set\"}")); - } + }*/ else if ( coin[0] != 0 ) { if ( strcmp(method,"enable") == 0 ) @@ -548,9 +547,11 @@ zeroconf_claim(address, expiration=0)\n\ jaddstr(retjson,"result","success"); jaddstr(retjson,"coin",coin); jaddnum(retjson,"timestamp",time(NULL)); - jadd(retjson,"alice",LP_inventory(coin)); + jadd(retjson,"alice",cJSON_Parse("[]")); + //jadd(retjson,"alice",LP_inventory(coin)); //jadd(retjson,"bob",LP_inventory(coin,1)); - LP_smartutxos_push(ptr); + //LP_smartutxos_push(ptr); + LP_address_utxo_reset(ptr); return(jprint(retjson,1)); } } diff --git a/iguana/exchanges/LP_ordermatch.c b/iguana/exchanges/LP_ordermatch.c index 5128a5f99..4070ce290 100644 --- a/iguana/exchanges/LP_ordermatch.c +++ b/iguana/exchanges/LP_ordermatch.c @@ -751,7 +751,7 @@ int32_t LP_listunspent_both(char *symbol,char *coinaddr,int32_t fullflag) return(n); } -char *LP_bestfit(char *rel,double relvolume) +/*char *LP_bestfit(char *rel,double relvolume) { struct LP_utxoinfo *autxo; if ( relvolume <= 0. || LP_priceinfofind(rel) == 0 ) @@ -759,7 +759,7 @@ char *LP_bestfit(char *rel,double relvolume) if ( (autxo= LP_utxo_bestfit(rel,SATOSHIDEN * relvolume)) == 0 ) return(clonestr("{\"error\":\"cant find utxo that is close enough in size\"}")); return(jprint(LP_utxojson(autxo),1)); -} +}*/ int32_t LP_aliceonly(char *symbol) { diff --git a/iguana/exchanges/LP_portfolio.c b/iguana/exchanges/LP_portfolio.c index e8d42ffd1..fea00ca21 100644 --- a/iguana/exchanges/LP_portfolio.c +++ b/iguana/exchanges/LP_portfolio.c @@ -63,7 +63,7 @@ uint64_t LP_balance(uint64_t *valuep,int32_t iambob,char *symbol,char *coinaddr) } free_json(array); } - if ( (array= LP_inventory(symbol)) != 0 ) + /*if ( (array= LP_inventory(symbol)) != 0 ) { if ( (n= cJSON_GetArraySize(array)) > 0 && is_cJSON_Array(array) != 0 ) { @@ -75,8 +75,9 @@ uint64_t LP_balance(uint64_t *valuep,int32_t iambob,char *symbol,char *coinaddr) } } free_json(array); - } + }*/ *valuep = valuesum; + satoshisum = valuesum; return(satoshisum); } @@ -489,7 +490,8 @@ void LP_autoprice_iter(void *ctx,struct LP_priceinfo *btcpp) int32_t LP_portfolio_trade(void *ctx,uint32_t *requestidp,uint32_t *quoteidp,struct iguana_info *buy,struct iguana_info *sell,double relvolume,int32_t setbaserel,char *gui) { - char *retstr2; double bid,ask,maxprice; bits256 zero; uint32_t requestid,quoteid,iter,i; cJSON *retjson2; + char *retstr2; uint64_t txfee,desttxfee; double bid,ask,maxprice; bits256 zero; uint32_t requestid,quoteid,iter,i; cJSON *retjson2; struct LP_utxoinfo A; struct LP_address_utxo *utxos[1000]; int32_t max=(int32_t)(sizeof(utxos)/sizeof(*utxos)); + LP_txfees(&txfee,&desttxfee,buy->symbol,sell->symbol); requestid = quoteid = 0; LP_myprice(&bid,&ask,buy->symbol,sell->symbol); maxprice = ask; @@ -507,7 +509,8 @@ int32_t LP_portfolio_trade(void *ctx,uint32_t *requestidp,uint32_t *quoteidp,str { if ( relvolume < dstr(LP_MIN_TXFEE) ) break; - if ( LP_utxo_bestfit(sell->symbol,SATOSHIDEN * relvolume) != 0 ) + if ( LP_address_myutxopair(&A,0,utxos,max,sell,sell->symbol,txfee,relvolume,maxprice,desttxfee) == 0 ) + //if ( LP_utxo_bestfit(sell->symbol,SATOSHIDEN * relvolume) != 0 ) { memset(zero.bytes,0,sizeof(zero)); if ( (retstr2= LP_autobuy(ctx,"127.0.0.1",-1,buy->symbol,sell->symbol,maxprice,relvolume,60,24*3600,gui,LP_lastnonce+1,zero,1)) != 0 ) @@ -531,7 +534,8 @@ int32_t LP_portfolio_trade(void *ctx,uint32_t *requestidp,uint32_t *quoteidp,str for (i=0; i<100; i++) { relvolume *= .99; - if ( LP_utxo_bestfit(sell->symbol,SATOSHIDEN * relvolume) != 0 ) + if ( LP_address_myutxopair(&A,0,utxos,max,sell,sell->symbol,txfee,relvolume,maxprice,desttxfee) == 0 ) + //if ( LP_utxo_bestfit(sell->symbol,SATOSHIDEN * relvolume) != 0 ) { printf("i.%d relvolume %.8f from %.8f\n",i,relvolume,sell->relvolume); break; diff --git a/iguana/exchanges/LP_utxos.c b/iguana/exchanges/LP_utxos.c index 7d637e459..f333e9c48 100644 --- a/iguana/exchanges/LP_utxos.c +++ b/iguana/exchanges/LP_utxos.c @@ -194,7 +194,7 @@ void LP_availableset(struct LP_utxoinfo *utxo) } } } -*/ + cJSON *LP_inventoryjson(cJSON *item,struct LP_utxoinfo *utxo) { @@ -327,16 +327,6 @@ struct LP_utxoinfo *LP_utxoadd(int32_t iambob,char *symbol,bits256 txid,int32_t return(0); } txfee = LP_txfeecalc(coin,0,0); - /*if ( iambob != 0 && value2 < 9 * (satoshis >> 3) + 2*txfee ) // big txfee padding - { - if ( value2 > 2*txfee ) - tmpsatoshis = (((value2 - 2*txfee) / 9) << 3); - else - { - printf("value2 %.8f <= 2 * %.8f\n",dstr(value2),dstr(txfee)); - return(0); - } - } else tmpsatoshis = (satoshis - txfee);*/ char str[65],str2[65],dispflag = 0;//(iambob == 0); if ( iambob == 0 && bits256_cmp(pubkey,G.LP_mypub25519) != 0 ) { @@ -527,7 +517,7 @@ cJSON *LP_inventory(char *symbol) printf("skip %s %s %d %d %d %d\n",utxo->coin,bits256_str(str,utxo->payment.txid),LP_isunspent(utxo) != 0,strcmp(symbol,utxo->coin) == 0,utxo->iambob == iambob,LP_ismine(utxo) > 0); } return(array); -} +}*/ int32_t LP_maxvalue(uint64_t *values,int32_t n) { @@ -582,7 +572,7 @@ int64_t LP_listunspent_parseitem(struct iguana_info *coin,bits256 *txidp,int32_t int32_t LP_privkey_init(int32_t mypubsock,struct iguana_info *coin,bits256 myprivkey,bits256 mypub) { int32_t enable_utxos = 0; - char *script,destaddr[64]; struct LP_utxoinfo *utxo; cJSON *array,*item; bits256 txid,deposittxid; int32_t used,i,flag=0,height,n,cmpflag,iambob,vout,depositvout; uint64_t *values=0,satoshis,txfee,biggerval,value,total = 0; int64_t targetval; + char *script,destaddr[64]; cJSON *array,*item; bits256 txid,deposittxid; int32_t used,i,flag=0,height,n,cmpflag,iambob,vout,depositvout; uint64_t *values=0,satoshis,txfee,biggerval,value,total = 0; int64_t targetval; //struct LP_utxoinfo *utxo; if ( coin == 0 || (IAMLP == 0 && coin->inactive != 0) ) { //printf("coin not active\n"); @@ -682,7 +672,7 @@ int32_t LP_privkey_init(int32_t mypubsock,struct iguana_info *coin,bits256 mypri { value = values[i]; values[i] = 0, used++; - portable_mutex_lock(&LP_UTXOmutex); + /*portable_mutex_lock(&LP_UTXOmutex); if ( iambob != 0 ) { if ( (utxo= LP_utxoadd(1,coin->symbol,txid,vout,value,deposittxid,depositvout,biggerval,coin->smartaddr,mypub,LP_gui,G.LP_sessionid,value)) != 0 ) @@ -696,7 +686,7 @@ int32_t LP_privkey_init(int32_t mypubsock,struct iguana_info *coin,bits256 mypri { } } - portable_mutex_unlock(&LP_UTXOmutex); + portable_mutex_unlock(&LP_UTXOmutex);*/ total += value; } // else printf("scriptmismatch.(%s) vs %s\n",script,jprint(item,0)); } //else printf("nothing near i.%d\n",i); From 027b90707c198f008cc19f41acaffc2c6b710e12 Mon Sep 17 00:00:00 2001 From: jl777 Date: Fri, 24 Nov 2017 12:44:36 +0400 Subject: [PATCH 1200/1664] Test --- iguana/exchanges/LP_transaction.c | 19 +++++++------------ 1 file changed, 7 insertions(+), 12 deletions(-) diff --git a/iguana/exchanges/LP_transaction.c b/iguana/exchanges/LP_transaction.c index 96ed9976a..99e84135e 100644 --- a/iguana/exchanges/LP_transaction.c +++ b/iguana/exchanges/LP_transaction.c @@ -1210,13 +1210,8 @@ char *LP_createrawtransaction(cJSON **txobjp,int32_t *numvinsp,struct iguana_inf return(0); } } - //if ( bits256_nonz(utxotxid) == 0 ) - { - if ( (ap= LP_address_utxo_reset(coin)) == 0 ) - return(0); - } - //else if ( (ap= LP_address(coin,coin->smartaddr)) == 0 ) - // return(0); + if ( (ap= LP_address_utxo_reset(coin)) == 0 ) + return(0); memset(utxos,0,sizeof(utxos)); if ( (numutxos= LP_address_utxo_ptrs(coin,0,utxos,max,ap,coin->smartaddr)) <= 0 ) { @@ -1247,11 +1242,6 @@ char *LP_createrawtransaction(cJSON **txobjp,int32_t *numvinsp,struct iguana_inf 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; - } printf("change %.8f = total %.8f - amount %.8f, adjust %.8f numvouts.%d\n",dstr(change),dstr(total),dstr(amount),dstr(adjust),numvouts); for (i=0; iisPoS,&txid,txobj,V)) != 0 ) From 3d9b4f517cadb9930af8338872de45eb9a55a0e8 Mon Sep 17 00:00:00 2001 From: jl777 Date: Fri, 24 Nov 2017 12:51:01 +0400 Subject: [PATCH 1201/1664] Test --- iguana/exchanges/LP_ordermatch.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/iguana/exchanges/LP_ordermatch.c b/iguana/exchanges/LP_ordermatch.c index 4070ce290..9dae6dec8 100644 --- a/iguana/exchanges/LP_ordermatch.c +++ b/iguana/exchanges/LP_ordermatch.c @@ -810,7 +810,7 @@ int32_t LP_tradecommand(void *ctx,char *myipaddr,int32_t pubsock,cJSON *argjson, LP_quoteparse(&Q,argjson); LP_requestinit(&Q.R,Q.srchash,Q.desthash,Q.srccoin,Q.satoshis-Q.txfee,Q.destcoin,Q.destsatoshis-Q.desttxfee,Q.timestamp,Q.quotetime,DEXselector); LP_tradecommand_log(argjson); - printf("(%-10u %10u) %12s aliceid.%22llu %5s/%-5s %12.8f -> %12.8f price %12.8f | RT.%d %d\n",Q.R.requestid,Q.R.quoteid,method,(long long)Q.aliceid,Q.srccoin,Q.destcoin,dstr(Q.satoshis),dstr(Q.destsatoshis),(double)Q.destsatoshis/Q.satoshis,LP_RTcount,LP_swapscount); + printf("%-4d (%-10u %10u) %12s id.%22llu %5s/%-5s %12.8f -> %11.8f price %11.8f | RT.%d %d\n",(uint32_t)time(NULL) % 3600,Q.R.requestid,Q.R.quoteid,method,(long long)Q.aliceid,Q.srccoin,Q.destcoin,dstr(Q.satoshis),dstr(Q.destsatoshis),(double)Q.destsatoshis/Q.satoshis,LP_RTcount,LP_swapscount); retval = 1; autxo = &A; butxo = &B; From 467563abc4d10b21f781a3b747c39628d87d2c59 Mon Sep 17 00:00:00 2001 From: jl777 Date: Fri, 24 Nov 2017 12:58:11 +0400 Subject: [PATCH 1202/1664] Test --- iguana/exchanges/LP_nativeDEX.c | 18 ++++++++++-------- 1 file changed, 10 insertions(+), 8 deletions(-) diff --git a/iguana/exchanges/LP_nativeDEX.c b/iguana/exchanges/LP_nativeDEX.c index 57c3a36e9..85187706e 100644 --- a/iguana/exchanges/LP_nativeDEX.c +++ b/iguana/exchanges/LP_nativeDEX.c @@ -553,11 +553,8 @@ void LP_coinsloop(void *_coins) } if ( (backupep= ep->prev) == 0 ) backupep = ep; - if ( (ap= LP_addressfind(coin,coin->smartaddr)) != 0 ) - { - if ( (retjson= electrum_address_listunspent(coin->symbol,ep,&retjson,ap->coinaddr,1)) != 0 ) - free_json(retjson); - } + if ( (retjson= electrum_address_listunspent(coin->symbol,ep,&retjson,coin->smartaddr,1)) != 0 ) + free_json(retjson); HASH_ITER(hh,coin->addresses,ap,atmp) { break; @@ -791,14 +788,15 @@ void LP_initpeers(int32_t pubsock,struct LP_peerinfo *mypeer,char *myipaddr,uint void LP_pubkeysloop(void *ctx) { - static uint32_t lasttime; cJSON *retjson; struct iguana_info *coin,*tmp; + static uint32_t lasttime; + struct LP_pubkey_info *pubp,*ptmp; //cJSON *retjson; struct iguana_info *coin,*tmp; strcpy(LP_pubkeysloop_stats.name,"LP_pubkeysloop"); LP_pubkeysloop_stats.threshold = 15000.; sleep(10); while ( 1 ) { LP_millistats_update(&LP_pubkeysloop_stats); - HASH_ITER(hh,LP_coins,coin,tmp) // firstrefht,firstscanht,lastscanht + /*HASH_ITER(hh,LP_coins,coin,tmp) // firstrefht,firstscanht,lastscanht { if ( coin->electrum != 0 && time(NULL) > coin->lastunspent+30 ) { @@ -807,6 +805,10 @@ void LP_pubkeysloop(void *ctx) free_json(retjson); coin->lastunspent = (uint32_t)time(NULL); } + }*/ + HASH_ITER(hh,LP_pubkeyinfos,pubp,ptmp) + { + pubp->dynamictrust = LP_dynamictrust(pubp->pubkey,0); } if ( time(NULL) > lasttime+LP_ORDERBOOK_DURATION*0.5 ) { @@ -1271,7 +1273,7 @@ void LPinit(uint16_t myport,uint16_t mypullport,uint16_t mypubport,uint16_t mybu printf("error launching LP_pubkeysloop for ctx.%p\n",ctx); exit(-1); } - if ( OS_thread_create(malloc(sizeof(pthread_t)),NULL,(void *)LP_privkeysloop,(void *)myipaddr) != 0 ) + if ( 0 && OS_thread_create(malloc(sizeof(pthread_t)),NULL,(void *)LP_privkeysloop,(void *)myipaddr) != 0 ) { printf("error launching LP_privkeysloop for ctx.%p\n",ctx); exit(-1); From b6032610f62ab92f723c5005a3d9497a06728a7c Mon Sep 17 00:00:00 2001 From: jl777 Date: Fri, 24 Nov 2017 13:01:12 +0400 Subject: [PATCH 1203/1664] Test --- iguana/exchanges/LP_include.h | 2 +- iguana/exchanges/LP_prices.c | 4 ++-- iguana/exchanges/LP_zeroconf.c | 2 +- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/iguana/exchanges/LP_include.h b/iguana/exchanges/LP_include.h index e676ab82b..e6b83e7c9 100644 --- a/iguana/exchanges/LP_include.h +++ b/iguana/exchanges/LP_include.h @@ -484,7 +484,7 @@ 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); -uint64_t LP_KMDvalue(struct iguana_info *coin,uint64_t balance); +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); void LP_cacheptrs_init(struct iguana_info *coin); diff --git a/iguana/exchanges/LP_prices.c b/iguana/exchanges/LP_prices.c index 4812891b0..97c2a9ce9 100644 --- a/iguana/exchanges/LP_prices.c +++ b/iguana/exchanges/LP_prices.c @@ -952,9 +952,9 @@ char *LP_orderbook(char *base,char *rel,int32_t duration) return(jprint(retjson,1)); } -uint64_t LP_KMDvalue(struct iguana_info *coin,uint64_t balance) +int64_t LP_KMDvalue(struct iguana_info *coin,int64_t balance) { - cJSON *bids,*asks,*orderbook,*item; double bid=0,ask=0,price = 0.; int32_t numasks,numbids; char *retstr; uint64_t KMDvalue=0; + cJSON *bids,*asks,*orderbook,*item; double bid=0,ask=0,price = 0.; int32_t numasks,numbids; char *retstr; int64_t KMDvalue=0; if ( balance != 0 ) { if ( strcmp(coin->symbol,"KMD") == 0 ) diff --git a/iguana/exchanges/LP_zeroconf.c b/iguana/exchanges/LP_zeroconf.c index 18b54d48c..11aedbbc4 100644 --- a/iguana/exchanges/LP_zeroconf.c +++ b/iguana/exchanges/LP_zeroconf.c @@ -192,7 +192,7 @@ char *LP_zeroconf_claim(struct iguana_info *coin,char *depositaddr,uint32_t expi return(clonestr("{\"error\":\"no zeroconf deposits to claim\"}")); } -void LP_zeroconf_credit(int32_t dispflag,char *coinaddr,uint64_t satoshis,int32_t weeki,char *p2shaddr) +void LP_zeroconf_credit(int32_t dispflag,char *coinaddr,int64_t satoshis,int32_t weeki,char *p2shaddr) { uint32_t timestamp; struct LP_address *ap; struct iguana_info *coin = LP_coinfind("KMD"); if ( coin != 0 ) From 7d08a5e7ba9edc2a3ffb0c8403264904cdb84ec3 Mon Sep 17 00:00:00 2001 From: jl777 Date: Fri, 24 Nov 2017 13:03:30 +0400 Subject: [PATCH 1204/1664] Test --- iguana/exchanges/LP_prices.c | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/iguana/exchanges/LP_prices.c b/iguana/exchanges/LP_prices.c index 97c2a9ce9..516b455cf 100644 --- a/iguana/exchanges/LP_prices.c +++ b/iguana/exchanges/LP_prices.c @@ -22,7 +22,7 @@ struct LP_orderbookentry { bits256 pubkey; double price; - uint64_t avesatoshis,maxsatoshis,depth,dynamictrust; + int64_t avesatoshis,maxsatoshis,depth,dynamictrust; uint32_t timestamp; int32_t numutxos; char coinaddr[64]; @@ -330,9 +330,9 @@ char *LP_pubkey_trusted() return(jprint(array,1)); } -uint64_t LP_unspents_metric(struct iguana_info *coin,char *coinaddr) +int64_t LP_unspents_metric(struct iguana_info *coin,char *coinaddr) { - cJSON *array,*item; int32_t i,n; uint64_t metric=0,total; + cJSON *array,*item; int32_t i,n; int64_t metric=0,total; LP_listunspent_both(coin->symbol,coinaddr,0); if ( (array= LP_address_utxos(coin,coinaddr,1)) != 0 ) { @@ -763,7 +763,7 @@ cJSON *LP_orderbookjson(char *symbol,struct LP_orderbookentry *op) return(item); } -struct LP_orderbookentry *LP_orderbookentry(char *address,char *base,char *rel,double price,int32_t numutxos,uint64_t avesatoshis,uint64_t maxsatoshis,bits256 pubkey,uint32_t timestamp,uint64_t balance,uint64_t dynamictrust) +struct LP_orderbookentry *LP_orderbookentry(char *address,char *base,char *rel,double price,int32_t numutxos,int64_t avesatoshis,int64_t maxsatoshis,bits256 pubkey,uint32_t timestamp,int64_t balance,int64_t dynamictrust) { struct LP_orderbookentry *op; if ( (op= calloc(1,sizeof(*op))) != 0 ) @@ -850,7 +850,7 @@ int32_t LP_orderbook_utxoentries(uint32_t now,int32_t polarity,char *base,char * char *LP_orderbook(char *base,char *rel,int32_t duration) { - uint32_t now,i; uint64_t depth; struct LP_priceinfo *basepp=0,*relpp=0; struct LP_orderbookentry **bids = 0,**asks = 0; cJSON *retjson,*array; struct iguana_info *basecoin,*relcoin; int32_t n,numbids=0,numasks=0,cachenumbids,cachenumasks,baseid,relid,suppress_prefetch=0; + uint32_t now,i; int64_t depth; struct LP_priceinfo *basepp=0,*relpp=0; struct LP_orderbookentry **bids = 0,**asks = 0; cJSON *retjson,*array; struct iguana_info *basecoin,*relcoin; int32_t n,numbids=0,numasks=0,cachenumbids,cachenumasks,baseid,relid,suppress_prefetch=0; basecoin = LP_coinfind(base); relcoin = LP_coinfind(rel); if ( basecoin == 0 || relcoin == 0 ) @@ -1021,7 +1021,7 @@ void LP_priceitemadd(cJSON *retarray,uint32_t timestamp,double avebid,double ave cJSON *LP_pricearray(char *base,char *rel,uint32_t firsttime,uint32_t lasttime,int32_t timescale) { - cJSON *retarray; char askfname[1024],bidfname[1024]; uint64_t bidprice64,askprice64; uint32_t bidnow,asknow,bidi,aski,lastbidi,lastaski; int32_t numbids,numasks; double bidemit,askemit,bidsum,asksum,bid,ask,highbid,lowbid,highask,lowask,bidemit2,askemit2; FILE *askfp=0,*bidfp=0; + cJSON *retarray; char askfname[1024],bidfname[1024]; int64_t bidprice64,askprice64; uint32_t bidnow,asknow,bidi,aski,lastbidi,lastaski; int32_t numbids,numasks; double bidemit,askemit,bidsum,asksum,bid,ask,highbid,lowbid,highask,lowask,bidemit2,askemit2; FILE *askfp=0,*bidfp=0; if ( timescale <= 0 ) timescale = 60; if ( lasttime == 0 ) @@ -1132,7 +1132,7 @@ cJSON *LP_pricearray(char *base,char *rel,uint32_t firsttime,uint32_t lasttime,i void LP_pricefeedupdate(bits256 pubkey,char *base,char *rel,double price,char *utxocoin,int32_t numrelutxos,int64_t balance,int64_t minutxo,int64_t maxutxo) { - struct LP_priceinfo *basepp,*relpp; uint32_t now; uint64_t price64; struct LP_pubkey_info *pubp; char str[65],fname[512]; FILE *fp; + struct LP_priceinfo *basepp,*relpp; uint32_t now; int64_t price64; struct LP_pubkey_info *pubp; char str[65],fname[512]; FILE *fp; //printf("check PRICEFEED UPDATE.(%s/%s) %.8f %s\n",base,rel,price,bits256_str(str,pubkey)); if ( LP_pricevalid(price) > 0 && (basepp= LP_priceinfofind(base)) != 0 && (relpp= LP_priceinfofind(rel)) != 0 ) { From 5d10bb2692ef8b2faf9d7779b6833b8520df97bb Mon Sep 17 00:00:00 2001 From: jl777 Date: Fri, 24 Nov 2017 13:14:16 +0400 Subject: [PATCH 1205/1664] Test --- iguana/exchanges/LP_ordermatch.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/iguana/exchanges/LP_ordermatch.c b/iguana/exchanges/LP_ordermatch.c index 9dae6dec8..78ba7552f 100644 --- a/iguana/exchanges/LP_ordermatch.c +++ b/iguana/exchanges/LP_ordermatch.c @@ -416,7 +416,7 @@ struct LP_utxoinfo *LP_address_myutxopair(struct LP_utxoinfo *butxo,int32_t iamb { if ( (m= LP_address_utxo_ptrs(coin,iambob,utxos,max,ap,coinaddr)) > 1 ) { - if ( 0 ) + if ( 1 ) { int32_t i; for (i=0; i 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 < ratio-1 ) { - if ( 0 ) + if ( 1 ) { int32_t i; for (i=0; i Date: Fri, 24 Nov 2017 13:20:05 +0400 Subject: [PATCH 1206/1664] Test --- iguana/exchanges/LP_include.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/iguana/exchanges/LP_include.h b/iguana/exchanges/LP_include.h index e6b83e7c9..314e4f7fd 100644 --- a/iguana/exchanges/LP_include.h +++ b/iguana/exchanges/LP_include.h @@ -23,7 +23,7 @@ #define LP_MAJOR_VERSION "0" #define LP_MINOR_VERSION "1" -#define LP_BUILD_NUMBER "15477" +#define LP_BUILD_NUMBER "15577" #define LP_BARTERDEX_VERSION 1 #define LP_MAGICBITS 1 @@ -83,7 +83,7 @@ void emscripten_usleep(int32_t x); // returns immediate, no sense for sleeping #define LP_SWAPSTEP_TIMEOUT 30 #define LP_MIN_TXFEE 10000 #define LP_MINVOL 20 -#define LP_MINCLIENTVOL 20 +#define LP_MINCLIENTVOL 200 #define LP_MINSIZE_TXFEEMULT 10 #define LP_REQUIRED_TXFEE 0.8 From 0c8d72d8c79f0432c1a263d58d497b377f599ec9 Mon Sep 17 00:00:00 2001 From: jl777 Date: Fri, 24 Nov 2017 13:30:59 +0400 Subject: [PATCH 1207/1664] Test --- iguana/exchanges/LP_nativeDEX.c | 3 +-- iguana/exchanges/LP_zeroconf.c | 2 +- 2 files changed, 2 insertions(+), 3 deletions(-) diff --git a/iguana/exchanges/LP_nativeDEX.c b/iguana/exchanges/LP_nativeDEX.c index 85187706e..aced90d80 100644 --- a/iguana/exchanges/LP_nativeDEX.c +++ b/iguana/exchanges/LP_nativeDEX.c @@ -21,12 +21,11 @@ // alice waiting for bestprice // USD paxprice based USDvalue in portfolio // cancel bid/ask +// delay swap credit back until notarization // electrum dynamic trust over 1000 // https://github.com/bitcoin/bips/blob/master/bip-0143.mediawiki for signing BCH/BTG // -// delay swap credit back until notarization // bugs, validations: -// remove LP_utxo_bestfit from portfolio // portfolio value based on ask? // verify encrypted destpubkey, broadcast:0 setprice diff --git a/iguana/exchanges/LP_zeroconf.c b/iguana/exchanges/LP_zeroconf.c index 11aedbbc4..c9b07fb9d 100644 --- a/iguana/exchanges/LP_zeroconf.c +++ b/iguana/exchanges/LP_zeroconf.c @@ -198,7 +198,7 @@ void LP_zeroconf_credit(int32_t dispflag,char *coinaddr,int64_t satoshis,int32_t if ( coin != 0 ) { timestamp = LP_FIRSTWEEKTIME + weeki*LP_WEEKMULT; - if ( time(NULL) < timestamp-24*3600 && (ap= LP_address(coin,coinaddr)) != 0 ) + if ( time(NULL) < timestamp-60*3600 && (ap= LP_address(coin,coinaddr)) != 0 ) { ap->zeroconf_credits += satoshis; if ( dispflag != 0 ) From feeaab54643fbb8f0baa13f12ec23cdcd2960986 Mon Sep 17 00:00:00 2001 From: jl777 Date: Fri, 24 Nov 2017 13:41:54 +0400 Subject: [PATCH 1208/1664] Test --- iguana/exchanges/LP_commands.c | 1 + iguana/exchanges/LP_nativeDEX.c | 5 +---- 2 files changed, 2 insertions(+), 4 deletions(-) diff --git a/iguana/exchanges/LP_commands.c b/iguana/exchanges/LP_commands.c index b2b9e7026..310de97ae 100644 --- a/iguana/exchanges/LP_commands.c +++ b/iguana/exchanges/LP_commands.c @@ -304,6 +304,7 @@ zeroconf_claim(address, expiration=0)\n\ struct LP_address *ap; char *coinaddr; if ( (ptr= LP_coinsearch("KMD")) != 0 && (coinaddr= jstr(argjson,"address")) != 0 ) { + LP_zeroconf_deposits(ptr); if ( (ap= LP_addressfind(ptr,coinaddr)) != 0 ) { retjson = cJSON_CreateObject(); diff --git a/iguana/exchanges/LP_nativeDEX.c b/iguana/exchanges/LP_nativeDEX.c index aced90d80..abbc777a5 100644 --- a/iguana/exchanges/LP_nativeDEX.c +++ b/iguana/exchanges/LP_nativeDEX.c @@ -17,20 +17,17 @@ // LP_nativeDEX.c // marketmaker // -// feature requests: // alice waiting for bestprice -// USD paxprice based USDvalue in portfolio // cancel bid/ask // delay swap credit back until notarization // electrum dynamic trust over 1000 // https://github.com/bitcoin/bips/blob/master/bip-0143.mediawiki for signing BCH/BTG // -// bugs, validations: // portfolio value based on ask? // verify encrypted destpubkey, broadcast:0 setprice +// USD paxprice based USDvalue in portfolio // improve critical section detection when parallel trades -// previously, it used to show amount, kmd equiv, perc // dPoW security -> 4: KMD notarized, 5: BTC notarized, after next notary elections // bigendian architectures need to use little endian for sighash calcs From 53f20fe033ddacc213a3cebc463a9e2272320d9d Mon Sep 17 00:00:00 2001 From: jl777 Date: Fri, 24 Nov 2017 13:50:24 +0400 Subject: [PATCH 1209/1664] Test --- iguana/exchanges/LP_commands.c | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/iguana/exchanges/LP_commands.c b/iguana/exchanges/LP_commands.c index 310de97ae..618aec6b0 100644 --- a/iguana/exchanges/LP_commands.c +++ b/iguana/exchanges/LP_commands.c @@ -631,15 +631,18 @@ zeroconf_claim(address, expiration=0)\n\ else if ( strcmp(method,"tradestatus") == 0 ) { - bits256 zero; cJSON *tmpjson; + bits256 zero; cJSON *tmpjson; struct LP_quoteinfo Q; + LP_tradecommand_log(argjson); + LP_quoteparse(&Q,argjson); + LP_requestinit(&Q.R,Q.srchash,Q.desthash,Q.srccoin,Q.satoshis-Q.txfee,Q.destcoin,Q.destsatoshis-Q.desttxfee,Q.timestamp,Q.quotetime,0); LP_tradecommand_log(argjson); - //printf("GOT TRADESTATUS! %s\n",jprint(argjson,0)); if ( LP_statslog_parse() > 0 ) { memset(zero.bytes,0,sizeof(zero)); if ( (tmpjson= LP_statslog_disp(2000000000,2000000000,"",zero,0,0))) // pending swaps free_json(tmpjson); } + printf("%-4d (%-10u %10u) %12s id.%22llu %5s/%-5s %12.8f -> %11.8f price %11.8f | RT.%d %d\n",(uint32_t)time(NULL) % 3600,Q.R.requestid,Q.R.quoteid,method,(long long)Q.aliceid,Q.srccoin,Q.destcoin,dstr(Q.satoshis),dstr(Q.destsatoshis),(double)Q.destsatoshis/Q.satoshis,LP_RTcount,LP_swapscount); retstr = clonestr("{\"result\":\"success\"}"); } else if ( strcmp(method,"wantnotify") == 0 ) From a7616b2e7224ef4ab0fd38f3ca6a18d091053af4 Mon Sep 17 00:00:00 2001 From: jl777 Date: Fri, 24 Nov 2017 13:59:55 +0400 Subject: [PATCH 1210/1664] Test --- iguana/exchanges/LP_transaction.c | 2 +- iguana/exchanges/dynamictrust | 3 +++ iguana/exchanges/install | 2 +- 3 files changed, 5 insertions(+), 2 deletions(-) create mode 100755 iguana/exchanges/dynamictrust diff --git a/iguana/exchanges/LP_transaction.c b/iguana/exchanges/LP_transaction.c index 99e84135e..a7e70ab5f 100644 --- a/iguana/exchanges/LP_transaction.c +++ b/iguana/exchanges/LP_transaction.c @@ -1126,7 +1126,7 @@ int32_t LP_vins_select(void *ctx,struct iguana_info *coin,int64_t *totalp,int64_ if ( LP_validSPV(coin->symbol,coin->smartaddr,up->U.txid,up->U.vout) < 0 ) continue; } - if ( LP_allocated(up->U.txid,up->U.vout) != 0 ) + if ( bits256_cmp(utxotxid,up->U.txid) != 0 && LP_allocated(up->U.txid,up->U.vout) != 0 ) continue; up->spendheight = 1; total += up->U.value; diff --git a/iguana/exchanges/dynamictrust b/iguana/exchanges/dynamictrust new file mode 100755 index 000000000..0a22e9fd9 --- /dev/null +++ b/iguana/exchanges/dynamictrust @@ -0,0 +1,3 @@ +#!/bin/bash +source userpass +curl --url "http://127.0.0.1:7783" --data "{\"userpass\":\"$userpass\",\"method\":\"dynamictrust\",\"address\":\"RMfQwu5ey23eWJ4as2ckd8dqsQJwo836ny\"}" diff --git a/iguana/exchanges/install b/iguana/exchanges/install index f938704ac..d7810e3c5 100755 --- a/iguana/exchanges/install +++ b/iguana/exchanges/install @@ -1,5 +1,5 @@ #!/bin/bash -cp tradesarray claim deposit deposit1 invreset sendrawtransaction processfiles stop millis mnzservers bot_buy bot_list bot_statuslist bot_pause bot_resume bot_sell bot_settings bot_status bot_stop guistats pubkeystats pendings coinswaps baserelswaps setpassphrase notarizations getrawtransaction parselog statsdisp m_js 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 dynamictrust tradesarray claim deposit deposit1 invreset sendrawtransaction processfiles stop millis mnzservers bot_buy bot_list bot_statuslist bot_pause bot_resume bot_sell bot_settings bot_status bot_stop guistats pubkeystats pendings coinswaps baserelswaps setpassphrase notarizations getrawtransaction parselog statsdisp m_js 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 . From e7f86ecb39da9e07e1570653e2d29958e272c8ca Mon Sep 17 00:00:00 2001 From: jl777 Date: Fri, 24 Nov 2017 14:08:54 +0400 Subject: [PATCH 1211/1664] Test --- iguana/exchanges/LP_commands.c | 1 + iguana/exchanges/LP_stats.c | 2 ++ 2 files changed, 3 insertions(+) diff --git a/iguana/exchanges/LP_commands.c b/iguana/exchanges/LP_commands.c index 618aec6b0..978fb05b9 100644 --- a/iguana/exchanges/LP_commands.c +++ b/iguana/exchanges/LP_commands.c @@ -304,6 +304,7 @@ zeroconf_claim(address, expiration=0)\n\ struct LP_address *ap; char *coinaddr; if ( (ptr= LP_coinsearch("KMD")) != 0 && (coinaddr= jstr(argjson,"address")) != 0 ) { + LP_statslog_parse(); LP_zeroconf_deposits(ptr); if ( (ap= LP_addressfind(ptr,coinaddr)) != 0 ) { diff --git a/iguana/exchanges/LP_stats.c b/iguana/exchanges/LP_stats.c index 9c3dd87cd..ffb8d0c8f 100644 --- a/iguana/exchanges/LP_stats.c +++ b/iguana/exchanges/LP_stats.c @@ -84,6 +84,7 @@ 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; + portable_mutex_lock(&LP_logmutex); if ( (fp= fopen(LP_STATSLOG_FNAME,"rb")) != 0 ) { if ( lastpos > 0 ) @@ -110,6 +111,7 @@ int32_t LP_statslog_parse() } fclose(fp); } + portable_mutex_unlock(&LP_logmutex); return(n); } From db520a5911905c97b53f4cf3dd062f052eab9956 Mon Sep 17 00:00:00 2001 From: jl777 Date: Fri, 24 Nov 2017 14:11:28 +0400 Subject: [PATCH 1212/1664] Test --- iguana/exchanges/LP_nativeDEX.c | 3 ++- iguana/exchanges/LP_stats.c | 4 ++-- 2 files changed, 4 insertions(+), 3 deletions(-) diff --git a/iguana/exchanges/LP_nativeDEX.c b/iguana/exchanges/LP_nativeDEX.c index abbc777a5..03e143e0b 100644 --- a/iguana/exchanges/LP_nativeDEX.c +++ b/iguana/exchanges/LP_nativeDEX.c @@ -86,7 +86,7 @@ void LP_millistats_update(struct LP_millistats *mp) } #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,LP_reservedmutex,LP_nanorecvsmutex,LP_tradebotsmutex,LP_gcmutex,LP_inusemutex,LP_cJSONmutex,LP_logmutex; +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,LP_tradebotsmutex,LP_gcmutex,LP_inusemutex,LP_cJSONmutex,LP_logmutex,LP_statslogmutex; int32_t LP_canbind; char *Broadcaststr,*Reserved_msgs[2][1000]; int32_t num_Reserved_msgs[2],max_Reserved_msgs[2]; @@ -1124,6 +1124,7 @@ void LPinit(uint16_t myport,uint16_t mypullport,uint16_t mypubport,uint16_t mybu portable_mutex_init(&LP_tradebotsmutex); portable_mutex_init(&LP_cJSONmutex); portable_mutex_init(&LP_logmutex); + portable_mutex_init(&LP_statslogmutex); myipaddr = clonestr("127.0.0.1"); #ifndef _WIN32 #ifndef FROM_JS diff --git a/iguana/exchanges/LP_stats.c b/iguana/exchanges/LP_stats.c index ffb8d0c8f..855a87ff4 100644 --- a/iguana/exchanges/LP_stats.c +++ b/iguana/exchanges/LP_stats.c @@ -30,7 +30,7 @@ static uint32_t LP_requests,LP_reserveds,LP_connects,LP_connecteds,LP_tradestatu void LP_tradecommand_log(cJSON *argjson) { static FILE *logfp; char *jsonstr; - portable_mutex_lock(&LP_logmutex); + portable_mutex_lock(&LP_statslogmutex); if ( logfp == 0 ) { if ( (logfp= fopen(LP_STATSLOG_FNAME,"rb+")) != 0 ) @@ -44,7 +44,7 @@ void LP_tradecommand_log(cJSON *argjson) free(jsonstr); fflush(logfp); } - portable_mutex_unlock(&LP_logmutex); + portable_mutex_unlock(&LP_statslogmutex); } void LP_statslog_parseline(cJSON *lineobj) From eca316822d9938fbc42e79a1b3842e9088ef07ec Mon Sep 17 00:00:00 2001 From: jl777 Date: Fri, 24 Nov 2017 14:13:40 +0400 Subject: [PATCH 1213/1664] Test --- iguana/exchanges/LP_commands.c | 1 - 1 file changed, 1 deletion(-) diff --git a/iguana/exchanges/LP_commands.c b/iguana/exchanges/LP_commands.c index 978fb05b9..618aec6b0 100644 --- a/iguana/exchanges/LP_commands.c +++ b/iguana/exchanges/LP_commands.c @@ -304,7 +304,6 @@ zeroconf_claim(address, expiration=0)\n\ struct LP_address *ap; char *coinaddr; if ( (ptr= LP_coinsearch("KMD")) != 0 && (coinaddr= jstr(argjson,"address")) != 0 ) { - LP_statslog_parse(); LP_zeroconf_deposits(ptr); if ( (ap= LP_addressfind(ptr,coinaddr)) != 0 ) { From 5b031772fa2af7b3e9a6781dce0b2d53fbfe3bef Mon Sep 17 00:00:00 2001 From: jl777 Date: Fri, 24 Nov 2017 14:19:09 +0400 Subject: [PATCH 1214/1664] Test --- iguana/exchanges/LP_ordermatch.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/iguana/exchanges/LP_ordermatch.c b/iguana/exchanges/LP_ordermatch.c index 78ba7552f..ee64b03de 100644 --- a/iguana/exchanges/LP_ordermatch.c +++ b/iguana/exchanges/LP_ordermatch.c @@ -495,8 +495,11 @@ int32_t LP_connectstartbob(void *ctx,int32_t pubsock,cJSON *argjson,char *base,c LP_reserved_msg(1,base,rel,qp->desthash,jprint(retjson,0)); bits256 zero; memset(zero.bytes,0,sizeof(zero)); + sleep(1); LP_reserved_msg(1,base,rel,zero,jprint(retjson,0)); - //LP_reserved_msg(0,base,rel,zero,jprint(retjson,0)); + LP_reserved_msg(0,base,rel,zero,jprint(retjson,0)); + sleep(1); + LP_reserved_msg(0,base,rel,zero,jprint(retjson,0)); free_json(retjson); retval = 0; } else printf("error launching swaploop\n"); From f1cbd668fdbea386f8616430a265a70baae24bad Mon Sep 17 00:00:00 2001 From: jl777 Date: Fri, 24 Nov 2017 14:21:37 +0400 Subject: [PATCH 1215/1664] Test --- iguana/exchanges/LP_commands.c | 13 ------------- iguana/exchanges/LP_ordermatch.c | 3 --- 2 files changed, 16 deletions(-) diff --git a/iguana/exchanges/LP_commands.c b/iguana/exchanges/LP_commands.c index 618aec6b0..d09217f51 100644 --- a/iguana/exchanges/LP_commands.c +++ b/iguana/exchanges/LP_commands.c @@ -109,7 +109,6 @@ myprice(base, rel)\n\ enable(coin)\n\ disable(coin)\n\ notarizations(coin)\n\ -parselog()\n\ statsdisp(starttime=0, endtime=0, gui="", pubkey="", base="", rel="")\n\ tradesarray(base, rel, starttime=-timescale*1024, endtime=, timescale=60) -> [timestamp, high, low, open, close, relvolume, basevolume, aveprice, numtrades]\n\ pricearray(base, rel, starttime=0, endtime=0, timescale=60) -> [timestamp, avebid, aveask, highbid, lowask]\n\ @@ -269,12 +268,6 @@ zeroconf_claim(address, expiration=0)\n\ { return(LP_portfolio()); } - else if ( strcmp(method,"parselog") == 0 ) - { - bits256 zero; - memset(zero.bytes,0,sizeof(zero)); - return(jprint(LP_statslog_disp(2000000000,2000000000,"",zero,0,0),1)); - } else if ( strcmp(method,"statsdisp") == 0 ) { return(jprint(LP_statslog_disp(juint(argjson,"starttime"),juint(argjson,"endtime"),jstr(argjson,"gui"),jbits256(argjson,"pubkey"),jstr(argjson,"base"),jstr(argjson,"rel")),1)); @@ -636,12 +629,6 @@ zeroconf_claim(address, expiration=0)\n\ LP_quoteparse(&Q,argjson); LP_requestinit(&Q.R,Q.srchash,Q.desthash,Q.srccoin,Q.satoshis-Q.txfee,Q.destcoin,Q.destsatoshis-Q.desttxfee,Q.timestamp,Q.quotetime,0); LP_tradecommand_log(argjson); - if ( LP_statslog_parse() > 0 ) - { - memset(zero.bytes,0,sizeof(zero)); - if ( (tmpjson= LP_statslog_disp(2000000000,2000000000,"",zero,0,0))) // pending swaps - free_json(tmpjson); - } printf("%-4d (%-10u %10u) %12s id.%22llu %5s/%-5s %12.8f -> %11.8f price %11.8f | RT.%d %d\n",(uint32_t)time(NULL) % 3600,Q.R.requestid,Q.R.quoteid,method,(long long)Q.aliceid,Q.srccoin,Q.destcoin,dstr(Q.satoshis),dstr(Q.destsatoshis),(double)Q.destsatoshis/Q.satoshis,LP_RTcount,LP_swapscount); retstr = clonestr("{\"result\":\"success\"}"); } diff --git a/iguana/exchanges/LP_ordermatch.c b/iguana/exchanges/LP_ordermatch.c index ee64b03de..4a5617469 100644 --- a/iguana/exchanges/LP_ordermatch.c +++ b/iguana/exchanges/LP_ordermatch.c @@ -495,11 +495,8 @@ int32_t LP_connectstartbob(void *ctx,int32_t pubsock,cJSON *argjson,char *base,c LP_reserved_msg(1,base,rel,qp->desthash,jprint(retjson,0)); bits256 zero; memset(zero.bytes,0,sizeof(zero)); - sleep(1); LP_reserved_msg(1,base,rel,zero,jprint(retjson,0)); LP_reserved_msg(0,base,rel,zero,jprint(retjson,0)); - sleep(1); - LP_reserved_msg(0,base,rel,zero,jprint(retjson,0)); free_json(retjson); retval = 0; } else printf("error launching swaploop\n"); From d060c7ce2934159a851b78112c6948d3bf279f30 Mon Sep 17 00:00:00 2001 From: jl777 Date: Fri, 24 Nov 2017 14:33:00 +0400 Subject: [PATCH 1216/1664] Test --- iguana/exchanges/LP_commands.c | 4 ++-- iguana/exchanges/LP_nativeDEX.c | 7 ++++++- iguana/exchanges/dynamictrust | 3 --- iguana/exchanges/install | 2 +- 4 files changed, 9 insertions(+), 7 deletions(-) delete mode 100755 iguana/exchanges/dynamictrust diff --git a/iguana/exchanges/LP_commands.c b/iguana/exchanges/LP_commands.c index d09217f51..c122ff233 100644 --- a/iguana/exchanges/LP_commands.c +++ b/iguana/exchanges/LP_commands.c @@ -292,7 +292,7 @@ zeroconf_claim(address, expiration=0)\n\ return(basilisk_swapentries(base,rel,jint(argjson,"limit"))); else return(basilisk_swaplist(0,0)); } - else if ( strcmp(method,"dynamictrust") == 0 ) + /*else if ( strcmp(method,"dynamictrust") == 0 ) { struct LP_address *ap; char *coinaddr; if ( (ptr= LP_coinsearch("KMD")) != 0 && (coinaddr= jstr(argjson,"address")) != 0 ) @@ -308,7 +308,7 @@ zeroconf_claim(address, expiration=0)\n\ } } return(clonestr("{\"error\":\"cant find address\"}")); - } + }*/ else if ( (retstr= LP_istradebots_command(ctx,pubsock,method,argjson)) != 0 ) return(retstr); if ( base[0] != 0 && rel[0] != 0 ) diff --git a/iguana/exchanges/LP_nativeDEX.c b/iguana/exchanges/LP_nativeDEX.c index 03e143e0b..9533d7199 100644 --- a/iguana/exchanges/LP_nativeDEX.c +++ b/iguana/exchanges/LP_nativeDEX.c @@ -30,7 +30,12 @@ // improve critical section detection when parallel trades // dPoW security -> 4: KMD notarized, 5: BTC notarized, after next notary elections // bigendian architectures need to use little endian for sighash calcs - +// dont change error messages: +// if (enable_electrum_coin_output_data.error == 'couldnt find coin locally installed') { //{error: "couldnt find coin locally installed", coin: "BTC"} +//if (enable_native_coin_output_data.error == 'couldnt find coin locally installed') { //{error: "couldnt find coin locally installed", coin: "BTC"} +// if (!data.error === true && data.error !== 'coin is disabled') { +// if (bot_output_data.error == 'not enough funds') { + #include long LP_cjson_allocated,LP_cjson_total,LP_cjson_count; diff --git a/iguana/exchanges/dynamictrust b/iguana/exchanges/dynamictrust deleted file mode 100755 index 0a22e9fd9..000000000 --- a/iguana/exchanges/dynamictrust +++ /dev/null @@ -1,3 +0,0 @@ -#!/bin/bash -source userpass -curl --url "http://127.0.0.1:7783" --data "{\"userpass\":\"$userpass\",\"method\":\"dynamictrust\",\"address\":\"RMfQwu5ey23eWJ4as2ckd8dqsQJwo836ny\"}" diff --git a/iguana/exchanges/install b/iguana/exchanges/install index d7810e3c5..f938704ac 100755 --- a/iguana/exchanges/install +++ b/iguana/exchanges/install @@ -1,5 +1,5 @@ #!/bin/bash -cp dynamictrust tradesarray claim deposit deposit1 invreset sendrawtransaction processfiles stop millis mnzservers bot_buy bot_list bot_statuslist bot_pause bot_resume bot_sell bot_settings bot_status bot_stop guistats pubkeystats pendings coinswaps baserelswaps setpassphrase notarizations getrawtransaction parselog statsdisp m_js 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 tradesarray claim deposit deposit1 invreset sendrawtransaction processfiles stop millis mnzservers bot_buy bot_list bot_statuslist bot_pause bot_resume bot_sell bot_settings bot_status bot_stop guistats pubkeystats pendings coinswaps baserelswaps setpassphrase notarizations getrawtransaction parselog statsdisp m_js 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 . From 2cfb57877addfaa028b27c14b055a07629c35bf7 Mon Sep 17 00:00:00 2001 From: jl777 Date: Fri, 24 Nov 2017 14:35:06 +0400 Subject: [PATCH 1217/1664] Test --- iguana/exchanges/LP_utxo.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/iguana/exchanges/LP_utxo.c b/iguana/exchanges/LP_utxo.c index d0c26c788..6669963be 100644 --- a/iguana/exchanges/LP_utxo.c +++ b/iguana/exchanges/LP_utxo.c @@ -419,7 +419,7 @@ int32_t LP_address_utxoadd(uint32_t timestamp,char *debug,struct iguana_info *co struct LP_address *LP_address_utxo_reset(struct iguana_info *coin) { - struct LP_address *ap; struct LP_address_utxo *up,*tmp; int32_t i,n,vout,height; cJSON *array,*item; int64_t value; bits256 txid; uint32_t now; + struct LP_address *ap; struct LP_address_utxo *up,*tmp; int32_t i,n,vout,height; cJSON *array,*item,*txobj; int64_t value; bits256 txid; uint32_t now; LP_address(coin,coin->smartaddr); LP_listunspent_issue(coin->symbol,coin->smartaddr,2); if ( (ap= LP_addressfind(coin,coin->smartaddr)) == 0 ) @@ -448,6 +448,9 @@ struct LP_address *LP_address_utxo_reset(struct iguana_info *coin) //{"tx_hash":"38d1b7c73015e1b1d6cb7fc314cae402a635b7d7ea294970ab857df8777a66f4","tx_pos":0,"height":577975,"value":238700} item = jitem(array,i); value = LP_listunspent_parseitem(coin,&txid,&vout,&height,item); + if ( (txobj= LP_gettxout(coin->symbol,coin->symbol,txid,vout)) == 0 ) + continue; + else free_json(txobj); LP_address_utxoadd(now,"withdraw",coin,coin->smartaddr,txid,vout,value,height,-1); if ( (up= LP_address_utxofind(coin,coin->smartaddr,txid,vout)) == 0 ) printf("couldnt find just added %s/%d ht.%d %.8f\n",bits256_str(str,txid),vout,height,dstr(value)); From 3cf18b518be575946a6453a88353a8d4a1fc7525 Mon Sep 17 00:00:00 2001 From: jl777 Date: Fri, 24 Nov 2017 14:39:35 +0400 Subject: [PATCH 1218/1664] Test --- iguana/exchanges/LP_stats.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/iguana/exchanges/LP_stats.c b/iguana/exchanges/LP_stats.c index 855a87ff4..8c8534153 100644 --- a/iguana/exchanges/LP_stats.c +++ b/iguana/exchanges/LP_stats.c @@ -30,7 +30,7 @@ static uint32_t LP_requests,LP_reserveds,LP_connects,LP_connecteds,LP_tradestatu void LP_tradecommand_log(cJSON *argjson) { static FILE *logfp; char *jsonstr; - portable_mutex_lock(&LP_statslogmutex); + //portable_mutex_lock(&LP_statslogmutex); if ( logfp == 0 ) { if ( (logfp= fopen(LP_STATSLOG_FNAME,"rb+")) != 0 ) @@ -44,7 +44,7 @@ void LP_tradecommand_log(cJSON *argjson) free(jsonstr); fflush(logfp); } - portable_mutex_unlock(&LP_statslogmutex); + //portable_mutex_unlock(&LP_statslogmutex); } void LP_statslog_parseline(cJSON *lineobj) From 4cdd33ccd8a4bf91db2ff89ec1df1d466edb9059 Mon Sep 17 00:00:00 2001 From: jl777 Date: Fri, 24 Nov 2017 14:44:28 +0400 Subject: [PATCH 1219/1664] Test --- iguana/exchanges/LP_stats.c | 4 ---- 1 file changed, 4 deletions(-) diff --git a/iguana/exchanges/LP_stats.c b/iguana/exchanges/LP_stats.c index 8c8534153..f2f9cf13b 100644 --- a/iguana/exchanges/LP_stats.c +++ b/iguana/exchanges/LP_stats.c @@ -30,7 +30,6 @@ static uint32_t LP_requests,LP_reserveds,LP_connects,LP_connecteds,LP_tradestatu void LP_tradecommand_log(cJSON *argjson) { static FILE *logfp; char *jsonstr; - //portable_mutex_lock(&LP_statslogmutex); if ( logfp == 0 ) { if ( (logfp= fopen(LP_STATSLOG_FNAME,"rb+")) != 0 ) @@ -44,7 +43,6 @@ void LP_tradecommand_log(cJSON *argjson) free(jsonstr); fflush(logfp); } - //portable_mutex_unlock(&LP_statslogmutex); } void LP_statslog_parseline(cJSON *lineobj) @@ -84,7 +82,6 @@ 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; - portable_mutex_lock(&LP_logmutex); if ( (fp= fopen(LP_STATSLOG_FNAME,"rb")) != 0 ) { if ( lastpos > 0 ) @@ -111,7 +108,6 @@ int32_t LP_statslog_parse() } fclose(fp); } - portable_mutex_unlock(&LP_logmutex); return(n); } From 1a6ea390f03289e59b89a6b72f517ba272504dce Mon Sep 17 00:00:00 2001 From: jl777 Date: Fri, 24 Nov 2017 14:55:00 +0400 Subject: [PATCH 1220/1664] Test --- iguana/exchanges/LP_ordermatch.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/iguana/exchanges/LP_ordermatch.c b/iguana/exchanges/LP_ordermatch.c index 4a5617469..78ba7552f 100644 --- a/iguana/exchanges/LP_ordermatch.c +++ b/iguana/exchanges/LP_ordermatch.c @@ -496,7 +496,7 @@ int32_t LP_connectstartbob(void *ctx,int32_t pubsock,cJSON *argjson,char *base,c bits256 zero; memset(zero.bytes,0,sizeof(zero)); LP_reserved_msg(1,base,rel,zero,jprint(retjson,0)); - LP_reserved_msg(0,base,rel,zero,jprint(retjson,0)); + //LP_reserved_msg(0,base,rel,zero,jprint(retjson,0)); free_json(retjson); retval = 0; } else printf("error launching swaploop\n"); From 637c5a268121bab76d93b7a974fead19f78b62f2 Mon Sep 17 00:00:00 2001 From: jl777 Date: Fri, 24 Nov 2017 14:59:09 +0400 Subject: [PATCH 1221/1664] Test --- iguana/exchanges/LP_ordermatch.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/iguana/exchanges/LP_ordermatch.c b/iguana/exchanges/LP_ordermatch.c index 78ba7552f..8213146f5 100644 --- a/iguana/exchanges/LP_ordermatch.c +++ b/iguana/exchanges/LP_ordermatch.c @@ -928,7 +928,7 @@ int32_t LP_tradecommand(void *ctx,char *myipaddr,int32_t pubsock,cJSON *argjson, price += (r * range) / 100.; bestprice = LP_bob_competition(&counter,aliceid,price,0); printf(">>>>>>>>>>>>> price %.8f qprice %.8f r.%d range %.8f -> %.8f, bestprice %.8f counter.%d\n",ask,qprice,r,range,price,bestprice,counter); - if ( counter > 3 || price > bestprice ) // skip if late or bad price + if ( counter > 2 || price > bestprice*.99 ) // skip if late or bad price return(retval); } else return(retval); //LP_RTmetrics_update(Q.srccoin,Q.destcoin); From 294d70b214a119f9ca4dee42472cefd90a34a172 Mon Sep 17 00:00:00 2001 From: jl777 Date: Fri, 24 Nov 2017 15:14:08 +0400 Subject: [PATCH 1222/1664] Test --- iguana/exchanges/LP_ordermatch.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/iguana/exchanges/LP_ordermatch.c b/iguana/exchanges/LP_ordermatch.c index 8213146f5..728125455 100644 --- a/iguana/exchanges/LP_ordermatch.c +++ b/iguana/exchanges/LP_ordermatch.c @@ -927,7 +927,7 @@ int32_t LP_tradecommand(void *ctx,char *myipaddr,int32_t pubsock,cJSON *argjson, range = (qprice - price); price += (r * range) / 100.; bestprice = LP_bob_competition(&counter,aliceid,price,0); - printf(">>>>>>>>>>>>> price %.8f qprice %.8f r.%d range %.8f -> %.8f, bestprice %.8f counter.%d\n",ask,qprice,r,range,price,bestprice,counter); + printf("%llu >>>>>>> price %.8f qprice %.8f r.%d range %.8f -> %.8f, bestprice %.8f counter.%d\n",(long long)aliceid,ask,qprice,r,range,price,bestprice,counter); if ( counter > 2 || price > bestprice*.99 ) // skip if late or bad price return(retval); } else return(retval); From c8620d5a3b9017eb773e4017649f2a03c793bd42 Mon Sep 17 00:00:00 2001 From: jl777 Date: Fri, 24 Nov 2017 15:17:50 +0400 Subject: [PATCH 1223/1664] Test --- iguana/exchanges/LP_commands.c | 6 +----- iguana/exchanges/LP_ordermatch.c | 4 ++-- iguana/exchanges/LP_signatures.c | 2 +- 3 files changed, 4 insertions(+), 8 deletions(-) diff --git a/iguana/exchanges/LP_commands.c b/iguana/exchanges/LP_commands.c index c122ff233..1c587d461 100644 --- a/iguana/exchanges/LP_commands.c +++ b/iguana/exchanges/LP_commands.c @@ -624,12 +624,8 @@ zeroconf_claim(address, expiration=0)\n\ else if ( strcmp(method,"tradestatus") == 0 ) { - bits256 zero; cJSON *tmpjson; struct LP_quoteinfo Q; LP_tradecommand_log(argjson); - LP_quoteparse(&Q,argjson); - LP_requestinit(&Q.R,Q.srchash,Q.desthash,Q.srccoin,Q.satoshis-Q.txfee,Q.destcoin,Q.destsatoshis-Q.desttxfee,Q.timestamp,Q.quotetime,0); - LP_tradecommand_log(argjson); - printf("%-4d (%-10u %10u) %12s id.%22llu %5s/%-5s %12.8f -> %11.8f price %11.8f | RT.%d %d\n",(uint32_t)time(NULL) % 3600,Q.R.requestid,Q.R.quoteid,method,(long long)Q.aliceid,Q.srccoin,Q.destcoin,dstr(Q.satoshis),dstr(Q.destsatoshis),(double)Q.destsatoshis/Q.satoshis,LP_RTcount,LP_swapscount); + printf("%-4d tradestatus | RT.%d %d\n",(uint32_t)time(NULL) % 3600,LP_RTcount,LP_swapscount); retstr = clonestr("{\"result\":\"success\"}"); } else if ( strcmp(method,"wantnotify") == 0 ) diff --git a/iguana/exchanges/LP_ordermatch.c b/iguana/exchanges/LP_ordermatch.c index 728125455..435f43599 100644 --- a/iguana/exchanges/LP_ordermatch.c +++ b/iguana/exchanges/LP_ordermatch.c @@ -496,7 +496,7 @@ int32_t LP_connectstartbob(void *ctx,int32_t pubsock,cJSON *argjson,char *base,c bits256 zero; memset(zero.bytes,0,sizeof(zero)); LP_reserved_msg(1,base,rel,zero,jprint(retjson,0)); - //LP_reserved_msg(0,base,rel,zero,jprint(retjson,0)); + LP_reserved_msg(0,base,rel,zero,jprint(retjson,0)); free_json(retjson); retval = 0; } else printf("error launching swaploop\n"); @@ -1005,7 +1005,7 @@ int32_t LP_tradecommand(void *ctx,char *myipaddr,int32_t pubsock,cJSON *argjson, bits256 zero; memset(zero.bytes,0,sizeof(zero)); LP_reserved_msg(1,Q.srccoin,Q.destcoin,zero,clonestr(msg)); - //LP_reserved_msg(0,Q.srccoin,Q.destcoin,zero,clonestr(msg)); + LP_reserved_msg(0,Q.srccoin,Q.destcoin,zero,clonestr(msg)); free(msg); butxo->T.lasttime = (uint32_t)time(NULL); return(retval); diff --git a/iguana/exchanges/LP_signatures.c b/iguana/exchanges/LP_signatures.c index 77856e31e..dc8e1b6ed 100644 --- a/iguana/exchanges/LP_signatures.c +++ b/iguana/exchanges/LP_signatures.c @@ -723,7 +723,7 @@ void LP_query(void *ctx,char *myipaddr,int32_t mypubsock,char *method,struct LP_ memset(&zero,0,sizeof(zero)); LP_reserved_msg(1,qp->srccoin,qp->destcoin,qp->desthash,clonestr(msg)); LP_reserved_msg(1,qp->srccoin,qp->destcoin,zero,clonestr(msg)); - //LP_reserved_msg(0,qp->srccoin,qp->destcoin,zero,clonestr(msg)); + LP_reserved_msg(0,qp->srccoin,qp->destcoin,zero,clonestr(msg)); free(msg); /*portable_mutex_lock(&LP_reservedmutex); if ( num_Reserved_msgs[1] < sizeof(Reserved_msgs[1])/sizeof(*Reserved_msgs[1])-2 ) From 9735e93a4dba51eada853cdb84baca600544056f Mon Sep 17 00:00:00 2001 From: jl777 Date: Fri, 24 Nov 2017 15:23:21 +0400 Subject: [PATCH 1224/1664] Test --- iguana/exchanges/LP_prices.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/iguana/exchanges/LP_prices.c b/iguana/exchanges/LP_prices.c index 516b455cf..67b8ca816 100644 --- a/iguana/exchanges/LP_prices.c +++ b/iguana/exchanges/LP_prices.c @@ -902,7 +902,7 @@ char *LP_orderbook(char *base,char *rel,int32_t duration) { //printf("bid ping %s %s\n",rel,bids[i]->coinaddr); LP_address(relcoin,bids[i]->coinaddr); - if ( 0 && relcoin->electrum == 0 ) + if ( 1 && relcoin->electrum == 0 ) { LP_listunspent_issue(rel,bids[i]->coinaddr,0); //else if ( (tmpjson= LP_listunspent(rel,bids[i]->coinaddr)) != 0 ) @@ -926,7 +926,7 @@ char *LP_orderbook(char *base,char *rel,int32_t duration) { //printf("ask ping %s %s\n",base,asks[i]->coinaddr); LP_address(basecoin,asks[i]->coinaddr); - if ( 0 && basecoin->electrum == 0 ) + if ( 1 && basecoin->electrum == 0 ) { LP_listunspent_issue(base,asks[i]->coinaddr,0); //else if ( (tmpjson= LP_listunspent(base,asks[i]->coinaddr)) != 0 ) From cb74be7fdf77cb0934914cbb3098856bc160404a Mon Sep 17 00:00:00 2001 From: jl777 Date: Fri, 24 Nov 2017 15:30:03 +0400 Subject: [PATCH 1225/1664] Test --- iguana/exchanges/LP_prices.c | 6 +++--- iguana/exchanges/LP_signatures.c | 2 +- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/iguana/exchanges/LP_prices.c b/iguana/exchanges/LP_prices.c index 67b8ca816..310550be1 100644 --- a/iguana/exchanges/LP_prices.c +++ b/iguana/exchanges/LP_prices.c @@ -122,7 +122,7 @@ void LP_pubkey_update(struct LP_pubkey_info *pubp,uint32_t baseind,uint32_t reli max64 = (1LL << 32) - 1; pq->aveutxo = (uint32_t)ave64; pq->maxutxo = (uint32_t)max64; - //printf("price %.8f base.%s rel.%s utxocoin.%s balance %.8f numutxos.%u %u scale64 = %llu, ave %llu, ave32 %u (%llu) max32 %u (%llu)\n",price,LP_priceinfos[baseind].symbol,LP_priceinfos[relind].symbol,utxocoin,dstr(balance),numutxos,pq->numutxos,(long long)scale64,(long long)aveutxo,pq->aveutxo,(long long)pq->aveutxo * scale64,pq->maxutxo,(long long)pq->maxutxo * scale64); + printf("price %.8f base.%s rel.%s utxocoin.%s balance %.8f numutxos.%u %u scale64 = %llu, ave %llu, ave32 %u (%llu) max32 %u (%llu)\n",price,LP_priceinfos[baseind].symbol,LP_priceinfos[relind].symbol,utxocoin,dstr(balance),numutxos,pq->numutxos,(long long)scale64,(long long)aveutxo,pq->aveutxo,(long long)pq->aveutxo * scale64,pq->maxutxo,(long long)pq->maxutxo * scale64); //int64_t avesatoshis,maxsatoshis; //price = LP_pubkey_price(&numutxos,&avesatoshis,&maxsatoshis,pubp,baseind,relind); //printf("checkprice %.8f numutxos.%d ave %.8f max %.8f\n",price,numutxos,dstr(avesatoshis),dstr(maxsatoshis)); @@ -902,7 +902,7 @@ char *LP_orderbook(char *base,char *rel,int32_t duration) { //printf("bid ping %s %s\n",rel,bids[i]->coinaddr); LP_address(relcoin,bids[i]->coinaddr); - if ( 1 && relcoin->electrum == 0 ) + if ( 0 && relcoin->electrum == 0 ) { LP_listunspent_issue(rel,bids[i]->coinaddr,0); //else if ( (tmpjson= LP_listunspent(rel,bids[i]->coinaddr)) != 0 ) @@ -926,7 +926,7 @@ char *LP_orderbook(char *base,char *rel,int32_t duration) { //printf("ask ping %s %s\n",base,asks[i]->coinaddr); LP_address(basecoin,asks[i]->coinaddr); - if ( 1 && basecoin->electrum == 0 ) + if ( 0 && basecoin->electrum == 0 ) { LP_listunspent_issue(base,asks[i]->coinaddr,0); //else if ( (tmpjson= LP_listunspent(base,asks[i]->coinaddr)) != 0 ) diff --git a/iguana/exchanges/LP_signatures.c b/iguana/exchanges/LP_signatures.c index dc8e1b6ed..0903afe47 100644 --- a/iguana/exchanges/LP_signatures.c +++ b/iguana/exchanges/LP_signatures.c @@ -472,7 +472,7 @@ char *LP_pricepings(void *ctx,char *myipaddr,int32_t pubsock,char *base,char *re { if ( (numutxos= LP_address_minmax(&balance,&minsize,&maxsize,ap)) != 0 ) { - //printf("%s numutxos.%d balance %.8f min %.8f max %.8f\n",base,numutxos,dstr(balance),dstr(minsize),dstr(maxsize)); + printf("send %s numutxos.%d balance %.8f min %.8f max %.8f\n",base,numutxos,dstr(balance),dstr(minsize),dstr(maxsize)); jaddstr(reqjson,"utxocoin",base); jaddnum(reqjson,"n",numutxos); jaddnum(reqjson,"bal",dstr(balance)); From 7cd8d49a3aa238180c34f9d3e26644c2b626c805 Mon Sep 17 00:00:00 2001 From: jl777 Date: Fri, 24 Nov 2017 15:34:33 +0400 Subject: [PATCH 1226/1664] Test --- iguana/exchanges/LP_signatures.c | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/iguana/exchanges/LP_signatures.c b/iguana/exchanges/LP_signatures.c index 0903afe47..4b93bd0ed 100644 --- a/iguana/exchanges/LP_signatures.c +++ b/iguana/exchanges/LP_signatures.c @@ -489,7 +489,7 @@ char *LP_pricepings(void *ctx,char *myipaddr,int32_t pubsock,char *base,char *re char *LP_postprice_recv(cJSON *argjson) { bits256 pubkey; double price; char *base,*rel; - //printf("PRICE POSTED.(%s)\n",jprint(argjson,0)); + printf("PRICE POSTED.(%s)\n",jprint(argjson,0)); if ( (base= jstr(argjson,"base")) != 0 && (rel= jstr(argjson,"rel")) != 0 && (price= jdouble(argjson,"price")) > SMALLVAL ) { pubkey = jbits256(argjson,"pubkey"); @@ -499,7 +499,12 @@ char *LP_postprice_recv(cJSON *argjson) { LP_pricefeedupdate(pubkey,base,rel,price,jstr(argjson,"utxocoin"),jint(argjson,"n"),jdouble(argjson,"bal")*SATOSHIDEN,jdouble(argjson,"min")*SATOSHIDEN,jdouble(argjson,"max")*SATOSHIDEN); return(clonestr("{\"result\":\"success\"}")); - } else return(clonestr("{\"error\":\"sig failure\"}")); + } + else + { + printf("sig failure\n"); + return(clonestr("{\"error\":\"sig failure\"}")); + } } } return(clonestr("{\"error\":\"missing fields in posted price\"}")); From 7525b70d2c385596196465ba1dbc015ba23fb670 Mon Sep 17 00:00:00 2001 From: jl777 Date: Fri, 24 Nov 2017 15:36:00 +0400 Subject: [PATCH 1227/1664] Test --- iguana/exchanges/LP_signatures.c | 1 + 1 file changed, 1 insertion(+) diff --git a/iguana/exchanges/LP_signatures.c b/iguana/exchanges/LP_signatures.c index 4b93bd0ed..a50879727 100644 --- a/iguana/exchanges/LP_signatures.c +++ b/iguana/exchanges/LP_signatures.c @@ -497,6 +497,7 @@ char *LP_postprice_recv(cJSON *argjson) { if ( LP_price_sigcheck(juint(argjson,"timestamp"),jstr(argjson,"sig"),jstr(argjson,"pubsecp"),pubkey,base,rel,j64bits(argjson,"price64")) == 0 ) { + printf("call pricefeed update\n"); LP_pricefeedupdate(pubkey,base,rel,price,jstr(argjson,"utxocoin"),jint(argjson,"n"),jdouble(argjson,"bal")*SATOSHIDEN,jdouble(argjson,"min")*SATOSHIDEN,jdouble(argjson,"max")*SATOSHIDEN); return(clonestr("{\"result\":\"success\"}")); } From 8b4cc47bdf73f03fdf19e268d4381da8de8271ec Mon Sep 17 00:00:00 2001 From: jl777 Date: Fri, 24 Nov 2017 15:37:35 +0400 Subject: [PATCH 1228/1664] Test --- iguana/exchanges/LP_prices.c | 2 +- iguana/exchanges/LP_signatures.c | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/iguana/exchanges/LP_prices.c b/iguana/exchanges/LP_prices.c index 310550be1..26ff1800c 100644 --- a/iguana/exchanges/LP_prices.c +++ b/iguana/exchanges/LP_prices.c @@ -1164,7 +1164,7 @@ void LP_pricefeedupdate(bits256 pubkey,char *base,char *rel,double price,char *u } if ( (pubp= LP_pubkeyadd(pubkey)) != 0 ) { - if ( (LP_rand() % 1000) == 0 ) + //if ( (LP_rand() % 1000) == 0 ) printf("PRICEFEED UPDATE.(%-6s/%6s) %12.8f %s %12.8f\n",base,rel,price,bits256_str(str,pubkey),1./price); pubp->timestamp = (uint32_t)time(NULL); LP_pubkey_update(pubp,basepp->ind,relpp->ind,price,balance,utxocoin,numrelutxos,minutxo,maxutxo); diff --git a/iguana/exchanges/LP_signatures.c b/iguana/exchanges/LP_signatures.c index a50879727..7e77fe987 100644 --- a/iguana/exchanges/LP_signatures.c +++ b/iguana/exchanges/LP_signatures.c @@ -489,7 +489,7 @@ char *LP_pricepings(void *ctx,char *myipaddr,int32_t pubsock,char *base,char *re char *LP_postprice_recv(cJSON *argjson) { bits256 pubkey; double price; char *base,*rel; - printf("PRICE POSTED.(%s)\n",jprint(argjson,0)); + //printf("PRICE POSTED.(%s)\n",jprint(argjson,0)); if ( (base= jstr(argjson,"base")) != 0 && (rel= jstr(argjson,"rel")) != 0 && (price= jdouble(argjson,"price")) > SMALLVAL ) { pubkey = jbits256(argjson,"pubkey"); @@ -497,7 +497,7 @@ char *LP_postprice_recv(cJSON *argjson) { if ( LP_price_sigcheck(juint(argjson,"timestamp"),jstr(argjson,"sig"),jstr(argjson,"pubsecp"),pubkey,base,rel,j64bits(argjson,"price64")) == 0 ) { - printf("call pricefeed update\n"); + //printf("call pricefeed update\n"); LP_pricefeedupdate(pubkey,base,rel,price,jstr(argjson,"utxocoin"),jint(argjson,"n"),jdouble(argjson,"bal")*SATOSHIDEN,jdouble(argjson,"min")*SATOSHIDEN,jdouble(argjson,"max")*SATOSHIDEN); return(clonestr("{\"result\":\"success\"}")); } From 880a858bb44f51f76ac00264afc7542001f6a3b1 Mon Sep 17 00:00:00 2001 From: jl777 Date: Fri, 24 Nov 2017 15:41:37 +0400 Subject: [PATCH 1229/1664] Test --- iguana/exchanges/LP_prices.c | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/iguana/exchanges/LP_prices.c b/iguana/exchanges/LP_prices.c index 26ff1800c..b2dd726f2 100644 --- a/iguana/exchanges/LP_prices.c +++ b/iguana/exchanges/LP_prices.c @@ -99,7 +99,9 @@ void LP_pubkey_update(struct LP_pubkey_info *pubp,uint32_t baseind,uint32_t reli pq->relind = relind; pq->scale = 6; // millions of SATOSHIS, ie. 0.01 DL_APPEND(pubp->quotes,pq); // already serialized as only path is via stats_JSON() + printf("create pubp quotes %d/%d\n",baseind,relind); } + printf("%d/%d price %.8f balance %d %s num.%d %.8f %.8f\n",baseind,relind,price,dstr(balance),utxocoin,numutxos,dstr(minutxo),dstr(maxutxo)); pq->price = price; if ( utxocoin != 0 && utxocoin[0] != 0 ) { @@ -123,9 +125,9 @@ void LP_pubkey_update(struct LP_pubkey_info *pubp,uint32_t baseind,uint32_t reli pq->aveutxo = (uint32_t)ave64; pq->maxutxo = (uint32_t)max64; printf("price %.8f base.%s rel.%s utxocoin.%s balance %.8f numutxos.%u %u scale64 = %llu, ave %llu, ave32 %u (%llu) max32 %u (%llu)\n",price,LP_priceinfos[baseind].symbol,LP_priceinfos[relind].symbol,utxocoin,dstr(balance),numutxos,pq->numutxos,(long long)scale64,(long long)aveutxo,pq->aveutxo,(long long)pq->aveutxo * scale64,pq->maxutxo,(long long)pq->maxutxo * scale64); - //int64_t avesatoshis,maxsatoshis; - //price = LP_pubkey_price(&numutxos,&avesatoshis,&maxsatoshis,pubp,baseind,relind); - //printf("checkprice %.8f numutxos.%d ave %.8f max %.8f\n",price,numutxos,dstr(avesatoshis),dstr(maxsatoshis)); + int64_t avesatoshis,maxsatoshis; + price = LP_pubkey_price(&numutxos,&avesatoshis,&maxsatoshis,pubp,baseind,relind); + printf("checkprice %.8f numutxos.%d ave %.8f max %.8f\n",price,numutxos,dstr(avesatoshis),dstr(maxsatoshis)); } } From a32fc3480e248648589d1b2b790ae8d6113261f3 Mon Sep 17 00:00:00 2001 From: jl777 Date: Fri, 24 Nov 2017 15:42:46 +0400 Subject: [PATCH 1230/1664] Test --- iguana/exchanges/LP_prices.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/iguana/exchanges/LP_prices.c b/iguana/exchanges/LP_prices.c index b2dd726f2..b3078c8fd 100644 --- a/iguana/exchanges/LP_prices.c +++ b/iguana/exchanges/LP_prices.c @@ -101,7 +101,7 @@ void LP_pubkey_update(struct LP_pubkey_info *pubp,uint32_t baseind,uint32_t reli DL_APPEND(pubp->quotes,pq); // already serialized as only path is via stats_JSON() printf("create pubp quotes %d/%d\n",baseind,relind); } - printf("%d/%d price %.8f balance %d %s num.%d %.8f %.8f\n",baseind,relind,price,dstr(balance),utxocoin,numutxos,dstr(minutxo),dstr(maxutxo)); + printf("%d/%d price %.8f balance %.8f %s num.%d %.8f %.8f\n",baseind,relind,price,dstr(balance),utxocoin,numutxos,dstr(minutxo),dstr(maxutxo)); pq->price = price; if ( utxocoin != 0 && utxocoin[0] != 0 ) { From d593f9e467611e6d6a04e7538bb200a734b11c6a Mon Sep 17 00:00:00 2001 From: jl777 Date: Fri, 24 Nov 2017 15:49:00 +0400 Subject: [PATCH 1231/1664] Test --- iguana/exchanges/LP_prices.c | 4 ++-- iguana/exchanges/LP_signatures.c | 6 +++--- iguana/exchanges/LP_statemachine.c | 12 ++++++++++++ iguana/exchanges/LP_utxo.c | 27 +++++++++++++++------------ 4 files changed, 32 insertions(+), 17 deletions(-) diff --git a/iguana/exchanges/LP_prices.c b/iguana/exchanges/LP_prices.c index b3078c8fd..fb333c69f 100644 --- a/iguana/exchanges/LP_prices.c +++ b/iguana/exchanges/LP_prices.c @@ -99,9 +99,9 @@ void LP_pubkey_update(struct LP_pubkey_info *pubp,uint32_t baseind,uint32_t reli pq->relind = relind; pq->scale = 6; // millions of SATOSHIS, ie. 0.01 DL_APPEND(pubp->quotes,pq); // already serialized as only path is via stats_JSON() - printf("create pubp quotes %d/%d\n",baseind,relind); + //printf("create pubp quotes %d/%d\n",baseind,relind); } - printf("%d/%d price %.8f balance %.8f %s num.%d %.8f %.8f\n",baseind,relind,price,dstr(balance),utxocoin,numutxos,dstr(minutxo),dstr(maxutxo)); + //printf("%d/%d price %.8f balance %.8f %s num.%d %.8f %.8f\n",baseind,relind,price,dstr(balance),utxocoin,numutxos,dstr(minutxo),dstr(maxutxo)); pq->price = price; if ( utxocoin != 0 && utxocoin[0] != 0 ) { diff --git a/iguana/exchanges/LP_signatures.c b/iguana/exchanges/LP_signatures.c index 7e77fe987..72189c764 100644 --- a/iguana/exchanges/LP_signatures.c +++ b/iguana/exchanges/LP_signatures.c @@ -451,7 +451,7 @@ int32_t LP_price_sigadd(cJSON *item,uint32_t timestamp,bits256 priv,uint8_t *pub char *LP_pricepings(void *ctx,char *myipaddr,int32_t pubsock,char *base,char *rel,double price) { - struct iguana_info *basecoin,*relcoin; struct LP_address *ap; char pubsecpstr[67]; uint32_t numutxos,timestamp; uint64_t price64,balance,minsize,maxsize; bits256 zero; cJSON *reqjson; + struct iguana_info *basecoin,*relcoin; char pubsecpstr[67]; uint32_t numutxos,timestamp; uint64_t price64,balance,minsize,maxsize; bits256 zero; cJSON *reqjson; reqjson = cJSON_CreateObject(); // LP_addsig if ( (basecoin= LP_coinfind(base)) != 0 && (relcoin= LP_coinfind(rel)) != 0 )//&& basecoin->electrum == 0 )//&& relcoin->electrum == 0 ) @@ -468,9 +468,9 @@ char *LP_pricepings(void *ctx,char *myipaddr,int32_t pubsock,char *base,char *re jaddnum(reqjson,"timestamp",timestamp); init_hexbytes_noT(pubsecpstr,G.LP_pubsecp,33); jaddstr(reqjson,"pubsecp",pubsecpstr); - if ( (ap= LP_address(basecoin,basecoin->smartaddr)) != 0 ) + //if ( (ap= LP_address(basecoin,basecoin->smartaddr)) != 0 ) { - if ( (numutxos= LP_address_minmax(&balance,&minsize,&maxsize,ap)) != 0 ) + if ( (numutxos= LP_address_minmax(&balance,&minsize,&maxsize,basecoin,basecoin->smartaddr)) != 0 ) { printf("send %s numutxos.%d balance %.8f min %.8f max %.8f\n",base,numutxos,dstr(balance),dstr(minsize),dstr(maxsize)); jaddstr(reqjson,"utxocoin",base); diff --git a/iguana/exchanges/LP_statemachine.c b/iguana/exchanges/LP_statemachine.c index f0da90e45..4c8bb5301 100644 --- a/iguana/exchanges/LP_statemachine.c +++ b/iguana/exchanges/LP_statemachine.c @@ -3238,6 +3238,18 @@ while ( 1 ) } return(clonestr("{\"error\":\"cant get here\"}")); #endif +/*DL_FOREACH_SAFE(ap->utxos,up,tmp) + { + if ( up->spendheight <= 0 ) + { + if ( up->U.value > *maxp ) + *maxp = up->U.value; + if ( *minp == 0 || up->U.value < *minp ) + *minp = up->U.value; + *balancep += up->U.value; + n++; + } + }*/ char *LP_ordermatch(char *base,int64_t txfee,double maxprice,double maxvolume,char *rel,bits256 txid,int32_t vout,bits256 feetxid,int32_t feevout,int64_t desttxfee,int32_t duration) { diff --git a/iguana/exchanges/LP_utxo.c b/iguana/exchanges/LP_utxo.c index 6669963be..2ed442355 100644 --- a/iguana/exchanges/LP_utxo.c +++ b/iguana/exchanges/LP_utxo.c @@ -238,24 +238,27 @@ struct LP_address *LP_address(struct iguana_info *coin,char *coinaddr) return(ap); } -int32_t LP_address_minmax(uint64_t *balancep,uint64_t *minp,uint64_t *maxp,struct LP_address *ap) +int32_t LP_address_minmax(uint64_t *balancep,uint64_t *minp,uint64_t *maxp,struct iguana_info *coin,char *coinaddr) { - struct LP_address_utxo *up,*tmp; int32_t n = 0; + cJSON *array,*item; bits256 txid; int64_t value; int32_t i,vout,height,n = 0; *minp = *maxp = *balancep = 0; - DL_FOREACH_SAFE(ap->utxos,up,tmp) + if ( (array= LP_listunspent(coin->symbol,coinaddr)) != 0 ) { - if ( up->spendheight <= 0 ) + if ( (n= cJSON_GetArraySize(array)) > 0 ) { - if ( up->U.value > *maxp ) - *maxp = up->U.value; - if ( *minp == 0 || up->U.value < *minp ) - *minp = up->U.value; - *balancep += up->U.value; - n++; + for (i=0; i *maxp ) + *maxp = value; + if ( *minp == 0 || value < *minp ) + *minp = value; + *balancep += value; + n++; + } } } - if ( 0 && n > 0 ) - printf("n.%d %s min %.8f max %.8f\n",n,ap->coinaddr,dstr(*minp),dstr(*maxp)); return(n); } From 18c34139e690fd623ac71730bec8ecb9b7b32489 Mon Sep 17 00:00:00 2001 From: jl777 Date: Fri, 24 Nov 2017 15:51:03 +0400 Subject: [PATCH 1232/1664] Test --- iguana/exchanges/LP_prices.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/iguana/exchanges/LP_prices.c b/iguana/exchanges/LP_prices.c index fb333c69f..55f87fa29 100644 --- a/iguana/exchanges/LP_prices.c +++ b/iguana/exchanges/LP_prices.c @@ -1166,7 +1166,7 @@ void LP_pricefeedupdate(bits256 pubkey,char *base,char *rel,double price,char *u } if ( (pubp= LP_pubkeyadd(pubkey)) != 0 ) { - //if ( (LP_rand() % 1000) == 0 ) + if ( (LP_rand() % 1000) == 0 ) printf("PRICEFEED UPDATE.(%-6s/%6s) %12.8f %s %12.8f\n",base,rel,price,bits256_str(str,pubkey),1./price); pubp->timestamp = (uint32_t)time(NULL); LP_pubkey_update(pubp,basepp->ind,relpp->ind,price,balance,utxocoin,numrelutxos,minutxo,maxutxo); From d051f5f8bae6fbde4a8020c5ebbffe6dacfbaf8f Mon Sep 17 00:00:00 2001 From: jl777 Date: Fri, 24 Nov 2017 16:04:19 +0400 Subject: [PATCH 1233/1664] Test --- iguana/exchanges/LP_nativeDEX.c | 22 ++++------------------ iguana/exchanges/LP_statemachine.c | 16 ++++++++++++++++ 2 files changed, 20 insertions(+), 18 deletions(-) diff --git a/iguana/exchanges/LP_nativeDEX.c b/iguana/exchanges/LP_nativeDEX.c index 9533d7199..54140d3bf 100644 --- a/iguana/exchanges/LP_nativeDEX.c +++ b/iguana/exchanges/LP_nativeDEX.c @@ -807,10 +807,10 @@ void LP_pubkeysloop(void *ctx) coin->lastunspent = (uint32_t)time(NULL); } }*/ - HASH_ITER(hh,LP_pubkeyinfos,pubp,ptmp) + /*HASH_ITER(hh,LP_pubkeyinfos,pubp,ptmp) { pubp->dynamictrust = LP_dynamictrust(pubp->pubkey,0); - } + }*/ if ( time(NULL) > lasttime+LP_ORDERBOOK_DURATION*0.5 ) { //printf("LP_pubkeysloop %u\n",(uint32_t)time(NULL)); @@ -821,7 +821,7 @@ void LP_pubkeysloop(void *ctx) } } -void LP_privkeysloop(void *ctx) +/*void LP_privkeysloop(void *ctx) { strcpy(LP_privkeysloop_stats.name,"LP_privkeysloop"); LP_privkeysloop_stats.threshold = (LP_ORDERBOOK_DURATION * .8 * 1000) + 10000; @@ -834,7 +834,7 @@ void LP_privkeysloop(void *ctx) LP_privkey_updates(ctx,LP_mypubsock,0); sleep(LP_ORDERBOOK_DURATION * .777); } -} +}*/ void LP_swapsloop(void *ignore) { @@ -1050,20 +1050,6 @@ void LPinit(uint16_t myport,uint16_t mypullport,uint16_t mypubport,uint16_t mybu printf("LP_MAXPRICEINFOS %d wont fit in a uint8_t, need to increase the width of the baseind and relind for struct LP_pubkey_quote\n",LP_MAXPRICEINFOS); exit(-1); } - if ( 0 ) - { - char *p2sh = "bJVtQF2o8B6sdNjeXupzNw5rnidJUNwPJD",p2shaddr[64]; uint8_t script[512],pub33[33]; uint32_t timestamp; - decode_hex(pub33,33,"03fe754763c176e1339a3f62ee6b9484720e17ee4646b65a119e9f6370c7004abc"); - for (timestamp=1510934803-3600*24; timestamp<1510934803+3600*24; timestamp++) - { - LP_deposit_addr(p2shaddr,script,0,85,timestamp,pub33); - if ( strcmp(p2shaddr,p2sh) == 0 ) - { - printf("matched timestamp.%u\n",timestamp); - break; - } else printf("%s ",p2shaddr); - } - } LP_showwif = juint(argjson,"wif"); if ( passphrase == 0 || passphrase[0] == 0 ) { diff --git a/iguana/exchanges/LP_statemachine.c b/iguana/exchanges/LP_statemachine.c index 4c8bb5301..92330e83a 100644 --- a/iguana/exchanges/LP_statemachine.c +++ b/iguana/exchanges/LP_statemachine.c @@ -3238,6 +3238,22 @@ while ( 1 ) } return(clonestr("{\"error\":\"cant get here\"}")); #endif + +if ( 0 ) +{ + char *p2sh = "bJVtQF2o8B6sdNjeXupzNw5rnidJUNwPJD",p2shaddr[64]; uint8_t script[512],pub33[33]; uint32_t timestamp; + decode_hex(pub33,33,"03fe754763c176e1339a3f62ee6b9484720e17ee4646b65a119e9f6370c7004abc"); + for (timestamp=1510934803-3600*24; timestamp<1510934803+3600*24; timestamp++) + { + LP_deposit_addr(p2shaddr,script,0,85,timestamp,pub33); + if ( strcmp(p2shaddr,p2sh) == 0 ) + { + printf("matched timestamp.%u\n",timestamp); + break; + } else printf("%s ",p2shaddr); + } +} + /*DL_FOREACH_SAFE(ap->utxos,up,tmp) { if ( up->spendheight <= 0 ) From a82382013c026a916a6c90da96bccf6379183901 Mon Sep 17 00:00:00 2001 From: jl777 Date: Fri, 24 Nov 2017 16:08:36 +0400 Subject: [PATCH 1234/1664] Test --- iguana/exchanges/LP_nativeDEX.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/iguana/exchanges/LP_nativeDEX.c b/iguana/exchanges/LP_nativeDEX.c index 54140d3bf..cfb101aad 100644 --- a/iguana/exchanges/LP_nativeDEX.c +++ b/iguana/exchanges/LP_nativeDEX.c @@ -1261,11 +1261,11 @@ void LPinit(uint16_t myport,uint16_t mypullport,uint16_t mypubport,uint16_t mybu printf("error launching LP_pubkeysloop for ctx.%p\n",ctx); exit(-1); } - if ( 0 && OS_thread_create(malloc(sizeof(pthread_t)),NULL,(void *)LP_privkeysloop,(void *)myipaddr) != 0 ) + /*if ( 0 && OS_thread_create(malloc(sizeof(pthread_t)),NULL,(void *)LP_privkeysloop,(void *)myipaddr) != 0 ) { printf("error launching LP_privkeysloop for ctx.%p\n",ctx); exit(-1); - } + }*/ if ( OS_thread_create(malloc(sizeof(pthread_t)),NULL,(void *)LP_swapsloop,(void *)myipaddr) != 0 ) { printf("error launching LP_swapsloop for port.%u\n",myport); From 9e3180daeab488b38b83483840b6c74aa759c69b Mon Sep 17 00:00:00 2001 From: jl777 Date: Fri, 24 Nov 2017 16:16:09 +0400 Subject: [PATCH 1235/1664] Test --- iguana/exchanges/LP_commands.c | 2 +- iguana/exchanges/LP_utxo.c | 3 ++- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/iguana/exchanges/LP_commands.c b/iguana/exchanges/LP_commands.c index 1c587d461..fe9647be8 100644 --- a/iguana/exchanges/LP_commands.c +++ b/iguana/exchanges/LP_commands.c @@ -343,7 +343,7 @@ zeroconf_claim(address, expiration=0)\n\ return(clonestr("{\"error\":\"couldnt set price\"}")); //else if ( LP_mypriceset(&changed,rel,base,1./price) < 0 ) // return(clonestr("{\"error\":\"couldnt set price\"}")); - else if ( jint(argjson,"broadcast") != 0 || jobj(argjson,"broadcast") == 0 ) + else if ( jobj(argjson,"broadcast") == 0 || jint(argjson,"broadcast") != 0 ) return(LP_pricepings(ctx,myipaddr,LP_mypubsock,base,rel,price * LP_profitratio)); else return(clonestr("{\"result\":\"success\"}")); } diff --git a/iguana/exchanges/LP_utxo.c b/iguana/exchanges/LP_utxo.c index 2ed442355..ca8016bab 100644 --- a/iguana/exchanges/LP_utxo.c +++ b/iguana/exchanges/LP_utxo.c @@ -244,6 +244,7 @@ int32_t LP_address_minmax(uint64_t *balancep,uint64_t *minp,uint64_t *maxp,struc *minp = *maxp = *balancep = 0; if ( (array= LP_listunspent(coin->symbol,coinaddr)) != 0 ) { + //printf("address minmax.(%s)\n",jprint(array,0)); if ( (n= cJSON_GetArraySize(array)) > 0 ) { for (i=0; i Date: Fri, 24 Nov 2017 16:18:33 +0400 Subject: [PATCH 1236/1664] Test --- iguana/exchanges/LP_prices.c | 11 +++++++---- iguana/exchanges/LP_signatures.c | 2 +- 2 files changed, 8 insertions(+), 5 deletions(-) diff --git a/iguana/exchanges/LP_prices.c b/iguana/exchanges/LP_prices.c index 55f87fa29..a41a7ac7e 100644 --- a/iguana/exchanges/LP_prices.c +++ b/iguana/exchanges/LP_prices.c @@ -124,10 +124,13 @@ void LP_pubkey_update(struct LP_pubkey_info *pubp,uint32_t baseind,uint32_t reli max64 = (1LL << 32) - 1; pq->aveutxo = (uint32_t)ave64; pq->maxutxo = (uint32_t)max64; - printf("price %.8f base.%s rel.%s utxocoin.%s balance %.8f numutxos.%u %u scale64 = %llu, ave %llu, ave32 %u (%llu) max32 %u (%llu)\n",price,LP_priceinfos[baseind].symbol,LP_priceinfos[relind].symbol,utxocoin,dstr(balance),numutxos,pq->numutxos,(long long)scale64,(long long)aveutxo,pq->aveutxo,(long long)pq->aveutxo * scale64,pq->maxutxo,(long long)pq->maxutxo * scale64); - int64_t avesatoshis,maxsatoshis; - price = LP_pubkey_price(&numutxos,&avesatoshis,&maxsatoshis,pubp,baseind,relind); - printf("checkprice %.8f numutxos.%d ave %.8f max %.8f\n",price,numutxos,dstr(avesatoshis),dstr(maxsatoshis)); + if ( 0 ) + { + printf("price %.8f base.%s rel.%s utxocoin.%s balance %.8f numutxos.%u %u scale64 = %llu, ave %llu, ave32 %u (%llu) max32 %u (%llu)\n",price,LP_priceinfos[baseind].symbol,LP_priceinfos[relind].symbol,utxocoin,dstr(balance),numutxos,pq->numutxos,(long long)scale64,(long long)aveutxo,pq->aveutxo,(long long)pq->aveutxo * scale64,pq->maxutxo,(long long)pq->maxutxo * scale64); + int64_t avesatoshis,maxsatoshis; + price = LP_pubkey_price(&numutxos,&avesatoshis,&maxsatoshis,pubp,baseind,relind); + printf("checkprice %.8f numutxos.%d ave %.8f max %.8f\n",price,numutxos,dstr(avesatoshis),dstr(maxsatoshis)); + } } } diff --git a/iguana/exchanges/LP_signatures.c b/iguana/exchanges/LP_signatures.c index 72189c764..e9e44e6ed 100644 --- a/iguana/exchanges/LP_signatures.c +++ b/iguana/exchanges/LP_signatures.c @@ -472,7 +472,7 @@ char *LP_pricepings(void *ctx,char *myipaddr,int32_t pubsock,char *base,char *re { if ( (numutxos= LP_address_minmax(&balance,&minsize,&maxsize,basecoin,basecoin->smartaddr)) != 0 ) { - printf("send %s numutxos.%d balance %.8f min %.8f max %.8f\n",base,numutxos,dstr(balance),dstr(minsize),dstr(maxsize)); + //printf("send %s numutxos.%d balance %.8f min %.8f max %.8f\n",base,numutxos,dstr(balance),dstr(minsize),dstr(maxsize)); jaddstr(reqjson,"utxocoin",base); jaddnum(reqjson,"n",numutxos); jaddnum(reqjson,"bal",dstr(balance)); From 6da04d4d865205cb278bfcc94df04af25aa704f8 Mon Sep 17 00:00:00 2001 From: jl777 Date: Fri, 24 Nov 2017 16:21:52 +0400 Subject: [PATCH 1237/1664] Test --- iguana/exchanges/LP_commands.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/iguana/exchanges/LP_commands.c b/iguana/exchanges/LP_commands.c index fe9647be8..226901d50 100644 --- a/iguana/exchanges/LP_commands.c +++ b/iguana/exchanges/LP_commands.c @@ -625,7 +625,7 @@ zeroconf_claim(address, expiration=0)\n\ else if ( strcmp(method,"tradestatus") == 0 ) { LP_tradecommand_log(argjson); - printf("%-4d tradestatus | RT.%d %d\n",(uint32_t)time(NULL) % 3600,LP_RTcount,LP_swapscount); + printf("%-4d tradestatus | aliceid.%llu RT.%d %d\n",(uint32_t)time(NULL) % 3600,(long long)j64bits(argjson,"aliceid"),LP_RTcount,LP_swapscount); retstr = clonestr("{\"result\":\"success\"}"); } else if ( strcmp(method,"wantnotify") == 0 ) From 06d3b4d8fe8f351c985894495512dbe1ac59fd2b Mon Sep 17 00:00:00 2001 From: jl777 Date: Fri, 24 Nov 2017 16:38:19 +0400 Subject: [PATCH 1238/1664] Test --- iguana/exchanges/LP_signatures.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/iguana/exchanges/LP_signatures.c b/iguana/exchanges/LP_signatures.c index e9e44e6ed..06053ac54 100644 --- a/iguana/exchanges/LP_signatures.c +++ b/iguana/exchanges/LP_signatures.c @@ -724,12 +724,12 @@ void LP_query(void *ctx,char *myipaddr,int32_t mypubsock,char *method,struct LP_ jaddnum(reqjson,"timestamp",time(NULL)); msg = jprint(reqjson,1); printf("QUERY.(%s)\n",msg); - if ( bits256_nonz(qp->srchash) == 0 || strcmp(method,"request") != 0 ) + //if ( bits256_nonz(qp->srchash) == 0 || strcmp(method,"request") != 0 ) { memset(&zero,0,sizeof(zero)); LP_reserved_msg(1,qp->srccoin,qp->destcoin,qp->desthash,clonestr(msg)); LP_reserved_msg(1,qp->srccoin,qp->destcoin,zero,clonestr(msg)); - LP_reserved_msg(0,qp->srccoin,qp->destcoin,zero,clonestr(msg)); + //LP_reserved_msg(0,qp->srccoin,qp->destcoin,zero,clonestr(msg)); free(msg); /*portable_mutex_lock(&LP_reservedmutex); if ( num_Reserved_msgs[1] < sizeof(Reserved_msgs[1])/sizeof(*Reserved_msgs[1])-2 ) @@ -737,6 +737,6 @@ void LP_query(void *ctx,char *myipaddr,int32_t mypubsock,char *method,struct LP_ if ( num_Reserved_msgs[0] < sizeof(Reserved_msgs[0])/sizeof(*Reserved_msgs[0])-2 ) Reserved_msgs[0][num_Reserved_msgs[0]++] = msg2; portable_mutex_unlock(&LP_reservedmutex);*/ - } else LP_broadcast_message(LP_mypubsock,qp->srccoin,qp->destcoin,qp->srchash,msg); + } //else LP_broadcast_message(LP_mypubsock,qp->srccoin,qp->destcoin,qp->srchash,msg); } From 477a483e7f77a51eaa9f4e0b9fd7229e4b10a8b7 Mon Sep 17 00:00:00 2001 From: jl777 Date: Fri, 24 Nov 2017 16:48:13 +0400 Subject: [PATCH 1239/1664] Test --- iguana/exchanges/LP_nativeDEX.c | 2 +- iguana/exchanges/LP_ordermatch.c | 9 +++++---- iguana/exchanges/LP_signatures.c | 1 + 3 files changed, 7 insertions(+), 5 deletions(-) diff --git a/iguana/exchanges/LP_nativeDEX.c b/iguana/exchanges/LP_nativeDEX.c index cfb101aad..9dcd04f35 100644 --- a/iguana/exchanges/LP_nativeDEX.c +++ b/iguana/exchanges/LP_nativeDEX.c @@ -1029,7 +1029,7 @@ int32_t LP_reserved_msg(int32_t priority,char *base,char *rel,bits256 pubkey,cha { Reserved_msgs[priority][num_Reserved_msgs[priority]++] = msg; n = num_Reserved_msgs[priority]; - } else LP_broadcast_message(LP_mypubsock,base,rel,pubkey,msg); + } //else LP_broadcast_message(LP_mypubsock,base,rel,pubkey,msg); if ( num_Reserved_msgs[priority] > max_Reserved_msgs[priority] ) { max_Reserved_msgs[priority] = num_Reserved_msgs[priority]; diff --git a/iguana/exchanges/LP_ordermatch.c b/iguana/exchanges/LP_ordermatch.c index 435f43599..aceaf0a4a 100644 --- a/iguana/exchanges/LP_ordermatch.c +++ b/iguana/exchanges/LP_ordermatch.c @@ -492,11 +492,12 @@ int32_t LP_connectstartbob(void *ctx,int32_t pubsock,cJSON *argjson,char *base,c jaddstr(retjson,"method","connected"); jaddstr(retjson,"pair",pairstr); char str[65]; printf("BOB pubsock.%d binds to %d (%s)\n",pubsock,pair,bits256_str(str,qp->desthash)); - LP_reserved_msg(1,base,rel,qp->desthash,jprint(retjson,0)); bits256 zero; memset(zero.bytes,0,sizeof(zero)); LP_reserved_msg(1,base,rel,zero,jprint(retjson,0)); - LP_reserved_msg(0,base,rel,zero,jprint(retjson,0)); + //sleep(1); + //LP_reserved_msg(1,base,rel,qp->desthash,jprint(retjson,0)); + //LP_reserved_msg(0,base,rel,zero,jprint(retjson,0)); free_json(retjson); retval = 0; } else printf("error launching swaploop\n"); @@ -1001,11 +1002,11 @@ int32_t LP_tradecommand(void *ctx,char *myipaddr,int32_t pubsock,cJSON *argjson, msg = jprint(retjson,1); printf("return after queued RESERVED: set swappending.%u accept qprice %.8f, min %.8f\n(%s)\n",Q.timestamp + LP_RESERVETIME,qprice,ask,msg); LP_reserved_msg(1,Q.srccoin,Q.destcoin,Q.desthash,clonestr(msg)); - //sleep(1); + sleep(1); bits256 zero; memset(zero.bytes,0,sizeof(zero)); LP_reserved_msg(1,Q.srccoin,Q.destcoin,zero,clonestr(msg)); - LP_reserved_msg(0,Q.srccoin,Q.destcoin,zero,clonestr(msg)); + //LP_reserved_msg(0,Q.srccoin,Q.destcoin,zero,clonestr(msg)); free(msg); butxo->T.lasttime = (uint32_t)time(NULL); return(retval); diff --git a/iguana/exchanges/LP_signatures.c b/iguana/exchanges/LP_signatures.c index 06053ac54..fe309f6e5 100644 --- a/iguana/exchanges/LP_signatures.c +++ b/iguana/exchanges/LP_signatures.c @@ -728,6 +728,7 @@ void LP_query(void *ctx,char *myipaddr,int32_t mypubsock,char *method,struct LP_ { memset(&zero,0,sizeof(zero)); LP_reserved_msg(1,qp->srccoin,qp->destcoin,qp->desthash,clonestr(msg)); + sleep(1); LP_reserved_msg(1,qp->srccoin,qp->destcoin,zero,clonestr(msg)); //LP_reserved_msg(0,qp->srccoin,qp->destcoin,zero,clonestr(msg)); free(msg); From 91857b435ae3638f92272e99cd2882f999c4e84d Mon Sep 17 00:00:00 2001 From: jl777 Date: Fri, 24 Nov 2017 16:52:37 +0400 Subject: [PATCH 1240/1664] Test --- iguana/exchanges/LP_ordermatch.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/iguana/exchanges/LP_ordermatch.c b/iguana/exchanges/LP_ordermatch.c index aceaf0a4a..8ef7fbb33 100644 --- a/iguana/exchanges/LP_ordermatch.c +++ b/iguana/exchanges/LP_ordermatch.c @@ -929,7 +929,7 @@ int32_t LP_tradecommand(void *ctx,char *myipaddr,int32_t pubsock,cJSON *argjson, price += (r * range) / 100.; bestprice = LP_bob_competition(&counter,aliceid,price,0); printf("%llu >>>>>>> price %.8f qprice %.8f r.%d range %.8f -> %.8f, bestprice %.8f counter.%d\n",(long long)aliceid,ask,qprice,r,range,price,bestprice,counter); - if ( counter > 2 || price > bestprice*.99 ) // skip if late or bad price + if ( counter > 3 || price > bestprice*1.1 ) // skip if late or bad price return(retval); } else return(retval); //LP_RTmetrics_update(Q.srccoin,Q.destcoin); @@ -1001,12 +1001,12 @@ int32_t LP_tradecommand(void *ctx,char *myipaddr,int32_t pubsock,cJSON *argjson, jaddstr(retjson,"method","reserved"); msg = jprint(retjson,1); printf("return after queued RESERVED: set swappending.%u accept qprice %.8f, min %.8f\n(%s)\n",Q.timestamp + LP_RESERVETIME,qprice,ask,msg); - LP_reserved_msg(1,Q.srccoin,Q.destcoin,Q.desthash,clonestr(msg)); - sleep(1); bits256 zero; memset(zero.bytes,0,sizeof(zero)); LP_reserved_msg(1,Q.srccoin,Q.destcoin,zero,clonestr(msg)); //LP_reserved_msg(0,Q.srccoin,Q.destcoin,zero,clonestr(msg)); + sleep(1); + LP_reserved_msg(1,Q.srccoin,Q.destcoin,Q.desthash,clonestr(msg)); free(msg); butxo->T.lasttime = (uint32_t)time(NULL); return(retval); From ce1db896b2897ff193f64b5544282e463302bd41 Mon Sep 17 00:00:00 2001 From: jl777 Date: Fri, 24 Nov 2017 16:59:13 +0400 Subject: [PATCH 1241/1664] Test --- iguana/exchanges/LP_stats.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/iguana/exchanges/LP_stats.c b/iguana/exchanges/LP_stats.c index f2f9cf13b..d6ce19cdb 100644 --- a/iguana/exchanges/LP_stats.c +++ b/iguana/exchanges/LP_stats.c @@ -372,7 +372,7 @@ char *LP_swapstatus_recv(cJSON *argjson) sp->lasttime = (uint32_t)time(NULL); if ( (methodind= jint(argjson,"ind")) > sp->methodind && methodind < sizeof(LP_stats_methods)/sizeof(*LP_stats_methods) ) { - if ( sp->finished == 0 && sp->expired == 0 ) + if ( 0 && sp->finished == 0 && sp->expired == 0 ) printf("SWAPSTATUS updated %llu %s %u %u\n",(long long)sp->aliceid,LP_stats_methods[sp->methodind],juint(argjson,"finished"),juint(argjson,"expired")); sp->methodind = methodind; sp->finished = juint(argjson,"finished"); From 864285803c6fac883185ab8c2f4b3fcb3893f583 Mon Sep 17 00:00:00 2001 From: jl777 Date: Fri, 24 Nov 2017 17:07:32 +0400 Subject: [PATCH 1242/1664] Test --- iguana/exchanges/LP_ordermatch.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/iguana/exchanges/LP_ordermatch.c b/iguana/exchanges/LP_ordermatch.c index 8ef7fbb33..b4e79db07 100644 --- a/iguana/exchanges/LP_ordermatch.c +++ b/iguana/exchanges/LP_ordermatch.c @@ -929,7 +929,7 @@ int32_t LP_tradecommand(void *ctx,char *myipaddr,int32_t pubsock,cJSON *argjson, price += (r * range) / 100.; bestprice = LP_bob_competition(&counter,aliceid,price,0); printf("%llu >>>>>>> price %.8f qprice %.8f r.%d range %.8f -> %.8f, bestprice %.8f counter.%d\n",(long long)aliceid,ask,qprice,r,range,price,bestprice,counter); - if ( counter > 3 || price > bestprice*1.1 ) // skip if late or bad price + if ( counter > 3 || price >= bestprice-SMALLVAL ) // skip if late or bad price return(retval); } else return(retval); //LP_RTmetrics_update(Q.srccoin,Q.destcoin); From 666d74ffa3f1613f7354902c6345434f74be5687 Mon Sep 17 00:00:00 2001 From: jl777 Date: Fri, 24 Nov 2017 17:12:52 +0400 Subject: [PATCH 1243/1664] Test --- iguana/exchanges/LP_ordermatch.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/iguana/exchanges/LP_ordermatch.c b/iguana/exchanges/LP_ordermatch.c index b4e79db07..88e0f831a 100644 --- a/iguana/exchanges/LP_ordermatch.c +++ b/iguana/exchanges/LP_ordermatch.c @@ -929,7 +929,7 @@ int32_t LP_tradecommand(void *ctx,char *myipaddr,int32_t pubsock,cJSON *argjson, price += (r * range) / 100.; bestprice = LP_bob_competition(&counter,aliceid,price,0); printf("%llu >>>>>>> price %.8f qprice %.8f r.%d range %.8f -> %.8f, bestprice %.8f counter.%d\n",(long long)aliceid,ask,qprice,r,range,price,bestprice,counter); - if ( counter > 3 || price >= bestprice-SMALLVAL ) // skip if late or bad price + if ( counter > 3 && price >= bestprice-SMALLVAL ) // skip if late or bad price return(retval); } else return(retval); //LP_RTmetrics_update(Q.srccoin,Q.destcoin); From 4fcdad97c8dabe1cc44d71f3fdba4decfd9529fb Mon Sep 17 00:00:00 2001 From: jl777 Date: Fri, 24 Nov 2017 17:24:21 +0400 Subject: [PATCH 1244/1664] Test --- iguana/exchanges/LP_nativeDEX.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/iguana/exchanges/LP_nativeDEX.c b/iguana/exchanges/LP_nativeDEX.c index 9dcd04f35..5b53a63e9 100644 --- a/iguana/exchanges/LP_nativeDEX.c +++ b/iguana/exchanges/LP_nativeDEX.c @@ -790,7 +790,7 @@ void LP_initpeers(int32_t pubsock,struct LP_peerinfo *mypeer,char *myipaddr,uint void LP_pubkeysloop(void *ctx) { static uint32_t lasttime; - struct LP_pubkey_info *pubp,*ptmp; //cJSON *retjson; struct iguana_info *coin,*tmp; + //struct LP_pubkey_info *pubp,*ptmp; //cJSON *retjson; struct iguana_info *coin,*tmp; strcpy(LP_pubkeysloop_stats.name,"LP_pubkeysloop"); LP_pubkeysloop_stats.threshold = 15000.; sleep(10); From 30422c2593cc638854607d366f4d5bc664d0d320 Mon Sep 17 00:00:00 2001 From: jl777 Date: Fri, 24 Nov 2017 17:37:23 +0400 Subject: [PATCH 1245/1664] Test --- iguana/exchanges/LP_rpc.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/iguana/exchanges/LP_rpc.c b/iguana/exchanges/LP_rpc.c index d3376beb3..b47319391 100644 --- a/iguana/exchanges/LP_rpc.c +++ b/iguana/exchanges/LP_rpc.c @@ -665,7 +665,7 @@ cJSON *LP_listunspent(char *symbol,char *coinaddr) { if ( ap->unspenttime == 0 ) usecache = 0; - else if ( G.LP_pendingswaps != 0 && time(NULL) > ap->unspenttime+3 ) + else if ( G.LP_pendingswaps != 0 && time(NULL) > ap->unspenttime+1 ) usecache = 0; if ( usecache != 0 && (retstr= LP_unspents_filestr(symbol,coinaddr)) != 0 ) { From c58aeb278b2b186cfd194e01a637c986107a3985 Mon Sep 17 00:00:00 2001 From: jl777 Date: Fri, 24 Nov 2017 17:42:30 +0400 Subject: [PATCH 1246/1664] Test --- iguana/exchanges/LP_ordermatch.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/iguana/exchanges/LP_ordermatch.c b/iguana/exchanges/LP_ordermatch.c index 88e0f831a..2b32ac8ac 100644 --- a/iguana/exchanges/LP_ordermatch.c +++ b/iguana/exchanges/LP_ordermatch.c @@ -416,7 +416,7 @@ struct LP_utxoinfo *LP_address_myutxopair(struct LP_utxoinfo *butxo,int32_t iamb { if ( (m= LP_address_utxo_ptrs(coin,iambob,utxos,max,ap,coinaddr)) > 1 ) { - if ( 1 ) + if ( 0 ) { int32_t i; for (i=0; i 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 < ratio-1 ) { - if ( 1 ) + if ( 0 ) { int32_t i; for (i=0; i Date: Fri, 24 Nov 2017 19:53:39 +0400 Subject: [PATCH 1247/1664] Test --- iguana/exchanges/LP_stats.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/iguana/exchanges/LP_stats.c b/iguana/exchanges/LP_stats.c index d6ce19cdb..02ef164f0 100644 --- a/iguana/exchanges/LP_stats.c +++ b/iguana/exchanges/LP_stats.c @@ -519,7 +519,7 @@ struct LP_ohlc cJSON *LP_ohlc_json(struct LP_ohlc *bar) { cJSON *item; - if ( bar->numtrades != 0 && bar->relsum > SMALLVAL && bar->basesum > SMALLVAL ) + //if ( bar->numtrades != 0 && bar->relsum > SMALLVAL && bar->basesum > SMALLVAL ) { item = cJSON_CreateArray(); jaddinum(item,bar->timestamp); @@ -529,7 +529,9 @@ cJSON *LP_ohlc_json(struct LP_ohlc *bar) jaddinum(item,bar->close); jaddinum(item,bar->relsum); jaddinum(item,bar->basesum); - jaddinum(item,bar->relsum / bar->basesum); + if ( bar->basesum != 0 ) + jaddinum(item,bar->relsum / bar->basesum); + else jaddinum(item,0); jaddinum(item,bar->numtrades); return(item); } From f142c0357435c1358ea52406ff3e515ab9f70c23 Mon Sep 17 00:00:00 2001 From: jl777 Date: Fri, 24 Nov 2017 19:56:49 +0400 Subject: [PATCH 1248/1664] Test --- iguana/exchanges/LP_transaction.c | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/iguana/exchanges/LP_transaction.c b/iguana/exchanges/LP_transaction.c index a7e70ab5f..f8f0f2c5c 100644 --- a/iguana/exchanges/LP_transaction.c +++ b/iguana/exchanges/LP_transaction.c @@ -1288,7 +1288,7 @@ char *LP_createrawtransaction(cJSON **txobjp,int32_t *numvinsp,struct iguana_inf char *LP_withdraw(struct iguana_info *coin,cJSON *argjson) { static void *ctx; - int32_t iter,utxovout,autofee,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; uint32_t locktime; cJSON *retjson,*outputs,*vins=0,*txobj=0,*privkeys=0; struct iguana_msgtx msgtx; bits256 utxotxid,signedtxid; uint64_t txfee,newtxfee=10000; + int32_t iter,i,utxovout,autofee,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; uint32_t locktime; cJSON *retjson,*item,*outputs,*vins=0,*txobj=0,*privkeys=0; struct iguana_msgtx msgtx; bits256 utxotxid,signedtxid; uint64_t txfee,newtxfee=10000; if ( ctx == 0 ) ctx = bitcoin_ctx(); if ( (outputs= jarray(&numvouts,argjson,"outputs")) == 0 ) @@ -1342,6 +1342,11 @@ char *LP_withdraw(struct iguana_info *coin,cJSON *argjson) printf("txfee %.8f -> newtxfee %.8f\n",dstr(txfee),dstr(newtxfee)); } else break; } else break; + for (i=0; i Date: Fri, 24 Nov 2017 20:02:34 +0400 Subject: [PATCH 1249/1664] Test --- iguana/exchanges/LP_utxo.c | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/iguana/exchanges/LP_utxo.c b/iguana/exchanges/LP_utxo.c index ca8016bab..983dd1637 100644 --- a/iguana/exchanges/LP_utxo.c +++ b/iguana/exchanges/LP_utxo.c @@ -45,6 +45,7 @@ int32_t _LP_inuse_delete(bits256 txid,int32_t vout) if ( (lp= _LP_inuse_find(txid,vout)) != 0 ) { ind = lp->ind; + char str[65]; printf("_LP_inuse_delete removing %s/v%d\n",bits256_str(str,txid),vout); *lp = LP_inuse[--LP_numinuse]; lp->ind = ind; memset(&LP_inuse[LP_numinuse],0,sizeof(struct LP_inuse_info)); @@ -52,7 +53,6 @@ int32_t _LP_inuse_delete(bits256 txid,int32_t vout) if ( LP_inuse[ind].ind != ind ) printf("ind.%d of %d: mismatched ind.%d\n",ind,LP_numinuse,LP_inuse[ind].ind); } - //char str[65]; printf("_LP_inuse_delete cant find %s/v%d\n",bits256_str(str,txid),vout); return(-1); } @@ -423,7 +423,7 @@ int32_t LP_address_utxoadd(uint32_t timestamp,char *debug,struct iguana_info *co struct LP_address *LP_address_utxo_reset(struct iguana_info *coin) { - struct LP_address *ap; struct LP_address_utxo *up,*tmp; int32_t i,n,vout,height; cJSON *array,*item,*txobj; int64_t value; bits256 txid; uint32_t now; + struct LP_address *ap; struct LP_address_utxo *up,*tmp; int32_t i,n,m,vout,height; cJSON *array,*item,*txobj; int64_t value; bits256 txid; uint32_t now; LP_address(coin,coin->smartaddr); LP_listunspent_issue(coin->symbol,coin->smartaddr,2); if ( (ap= LP_addressfind(coin,coin->smartaddr)) == 0 ) @@ -447,7 +447,7 @@ struct LP_address *LP_address_utxo_reset(struct iguana_info *coin) if ( (n= cJSON_GetArraySize(array)) > 0 ) { char str[65]; - for (i=0; ismartaddr,txid,vout,value,height,-1); if ( (up= LP_address_utxofind(coin,coin->smartaddr,txid,vout)) == 0 ) printf("couldnt find just added %s/%d ht.%d %.8f\n",bits256_str(str,txid),vout,height,dstr(value)); + else m++; } - printf("added %d from listunspents\n",n); + printf("added %d from listunspents\n",m); } free_json(array); } From 90643fec8f93f97da660f16e91bc29aea8e525e3 Mon Sep 17 00:00:00 2001 From: jl777 Date: Fri, 24 Nov 2017 20:09:08 +0400 Subject: [PATCH 1250/1664] Test --- iguana/exchanges/LP_transaction.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/iguana/exchanges/LP_transaction.c b/iguana/exchanges/LP_transaction.c index f8f0f2c5c..66c61b2cb 100644 --- a/iguana/exchanges/LP_transaction.c +++ b/iguana/exchanges/LP_transaction.c @@ -1210,7 +1210,7 @@ char *LP_createrawtransaction(cJSON **txobjp,int32_t *numvinsp,struct iguana_inf return(0); } } - if ( (ap= LP_address_utxo_reset(coin)) == 0 ) + if ( (ap= LP_address(coin,coin->smartaddr)) == 0 ) return(0); memset(utxos,0,sizeof(utxos)); if ( (numutxos= LP_address_utxo_ptrs(coin,0,utxos,max,ap,coin->smartaddr)) <= 0 ) @@ -1288,7 +1288,7 @@ char *LP_createrawtransaction(cJSON **txobjp,int32_t *numvinsp,struct iguana_inf char *LP_withdraw(struct iguana_info *coin,cJSON *argjson) { static void *ctx; - int32_t iter,i,utxovout,autofee,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; uint32_t locktime; cJSON *retjson,*item,*outputs,*vins=0,*txobj=0,*privkeys=0; struct iguana_msgtx msgtx; bits256 utxotxid,signedtxid; uint64_t txfee,newtxfee=10000; + int32_t iter,i,utxovout,autofee,completed=0,maxV,numvins,numvouts,datalen,suppress_pubkeys; bits256 privkey; struct LP_address *ap; char changeaddr[64],vinaddr[64],str[65],*signedtx=0,*rawtx=0; struct vin_info *V; uint32_t locktime; cJSON *retjson,*item,*outputs,*vins=0,*txobj=0,*privkeys=0; struct iguana_msgtx msgtx; bits256 utxotxid,signedtxid; uint64_t txfee,newtxfee=10000; if ( ctx == 0 ) ctx = bitcoin_ctx(); if ( (outputs= jarray(&numvouts,argjson,"outputs")) == 0 ) @@ -1317,6 +1317,8 @@ char *LP_withdraw(struct iguana_info *coin,cJSON *argjson) V = malloc(maxV * sizeof(*V)); for (iter=0; iter<2; iter++) { + if ( (ap= LP_address_utxo_reset(coin)) == 0 ) + return(0); privkeys = cJSON_CreateArray(); vins = cJSON_CreateArray(); memset(V,0,sizeof(*V) * maxV); From 843fd4dee3426d1f3137e62d8ccf338dfa5ea153 Mon Sep 17 00:00:00 2001 From: jl777 Date: Fri, 24 Nov 2017 20:14:31 +0400 Subject: [PATCH 1251/1664] Test --- iguana/exchanges/LP_utxo.c | 13 +++++++------ 1 file changed, 7 insertions(+), 6 deletions(-) diff --git a/iguana/exchanges/LP_utxo.c b/iguana/exchanges/LP_utxo.c index 983dd1637..2e8f65e01 100644 --- a/iguana/exchanges/LP_utxo.c +++ b/iguana/exchanges/LP_utxo.c @@ -268,11 +268,12 @@ int32_t LP_address_utxo_ptrs(struct iguana_info *coin,int32_t iambob,struct LP_a struct LP_address_utxo *up,*tmp; struct LP_transaction *tx; cJSON *txout; int32_t n = 0; if ( strcmp(ap->coinaddr,coinaddr) != 0 ) printf("UNEXPECTED coinaddr mismatch (%s) != (%s)\n",ap->coinaddr,coinaddr); - //LP_listunspent_issue(coin->symbol,coin->smartaddr,2); + if ( coin->electrum != 0 ) + LP_listunspent_issue(coin->symbol,coin->smartaddr,2); //portable_mutex_lock(&LP_utxomutex); DL_FOREACH_SAFE(ap->utxos,up,tmp) { - //char str[65]; printf("LP_address_utxo_ptrs %s n.%d %.8f %s v%d spendheight.%d allocated.%d\n",ap->coinaddr,n,dstr(up->U.value),bits256_str(str,up->U.txid),up->U.vout,up->spendheight,LP_allocated(up->U.txid,up->U.vout)); + char str[65]; printf("LP_address_utxo_ptrs %s n.%d %.8f %s v%d spendheight.%d allocated.%d\n",ap->coinaddr,n,dstr(up->U.value),bits256_str(str,up->U.txid),up->U.vout,up->spendheight,LP_allocated(up->U.txid,up->U.vout)); if ( up->spendheight <= 0 && LP_RTmetrics_avoidtxid(up->U.txid) < 0 ) { if ( coin->electrum == 0 ) @@ -281,7 +282,7 @@ int32_t LP_address_utxo_ptrs(struct iguana_info *coin,int32_t iambob,struct LP_a { if ( LP_value_extract(txout,0) == 0 ) { - //printf("LP_address_utxo_ptrs skip zero value %s/v%d\n",bits256_str(str,up->U.txid),up->U.vout); + printf("LP_address_utxo_ptrs skip zero value %s/v%d\n",bits256_str(str,up->U.txid),up->U.vout); free_json(txout); up->spendheight = 1; if ( (tx= LP_transactionfind(coin,up->U.txid)) != 0 && up->U.vout < tx->numvouts ) @@ -292,7 +293,7 @@ int32_t LP_address_utxo_ptrs(struct iguana_info *coin,int32_t iambob,struct LP_a } else { - //printf("LP_address_utxo_ptrs skips %s %s payment %s/v%d is spent\n",coin->symbol,coinaddr,bits256_str(str,up->U.txid),up->U.vout); + printf("LP_address_utxo_ptrs skips %s %s payment %s/v%d is spent\n",coin->symbol,coinaddr,bits256_str(str,up->U.txid),up->U.vout); up->spendheight = 1; if ( (tx= LP_transactionfind(coin,up->U.txid)) != 0 && up->U.vout < tx->numvouts ) tx->outpoints[up->U.vout].spendheight = 1; @@ -303,7 +304,7 @@ int32_t LP_address_utxo_ptrs(struct iguana_info *coin,int32_t iambob,struct LP_a { if ( up->SPV < 0 || up->U.height == 0 ) { -//printf("LP_address_utxo_ptrs skips %s/v%u due to SPV.%d ht.%d\n",bits256_str(str,up->U.txid),up->U.vout,up->SPV,up->U.height); +printf("LP_address_utxo_ptrs skips %s/v%u due to SPV.%d ht.%d\n",bits256_str(str,up->U.txid),up->U.vout,up->SPV,up->U.height); if ( (tx= LP_transactionfind(coin,up->U.txid)) != 0 && up->U.vout < tx->numvouts ) tx->outpoints[up->U.vout].spendheight = 1; continue; @@ -314,7 +315,7 @@ int32_t LP_address_utxo_ptrs(struct iguana_info *coin,int32_t iambob,struct LP_a utxos[n++] = up; if ( n >= max ) break; - } //else printf("LP_allocated skip\n"); + } else printf("LP_allocated skip\n"); } else { From e8d46c4acb26d9cd49f22b475ba4d3b56c476e6b Mon Sep 17 00:00:00 2001 From: jl777 Date: Fri, 24 Nov 2017 20:20:29 +0400 Subject: [PATCH 1252/1664] Test --- iguana/exchanges/LP_transaction.c | 5 +++-- iguana/exchanges/LP_utxo.c | 18 +++++++++--------- 2 files changed, 12 insertions(+), 11 deletions(-) diff --git a/iguana/exchanges/LP_transaction.c b/iguana/exchanges/LP_transaction.c index 66c61b2cb..2c9fa38cc 100644 --- a/iguana/exchanges/LP_transaction.c +++ b/iguana/exchanges/LP_transaction.c @@ -1315,10 +1315,10 @@ char *LP_withdraw(struct iguana_info *coin,cJSON *argjson) privkey = LP_privkey(vinaddr,coin->taddr); maxV = LP_MAXVINS; V = malloc(maxV * sizeof(*V)); + if ( (ap= LP_address_utxo_reset(coin)) == 0 ) + return(0); for (iter=0; iter<2; iter++) { - if ( (ap= LP_address_utxo_reset(coin)) == 0 ) - return(0); privkeys = cJSON_CreateArray(); vins = cJSON_CreateArray(); memset(V,0,sizeof(*V) * maxV); @@ -1347,6 +1347,7 @@ char *LP_withdraw(struct iguana_info *coin,cJSON *argjson) for (i=0; iind; - char str[65]; printf("_LP_inuse_delete removing %s/v%d\n",bits256_str(str,txid),vout); + printf("_LP_inuse_delete removing %s/v%d\n",bits256_str(str,txid),vout); *lp = LP_inuse[--LP_numinuse]; lp->ind = ind; memset(&LP_inuse[LP_numinuse],0,sizeof(struct LP_inuse_info)); for (ind=0; indcoinaddr,coinaddr) != 0 ) printf("UNEXPECTED coinaddr mismatch (%s) != (%s)\n",ap->coinaddr,coinaddr); - if ( coin->electrum != 0 ) + if ( 0 && coin->electrum != 0 ) LP_listunspent_issue(coin->symbol,coin->smartaddr,2); //portable_mutex_lock(&LP_utxomutex); DL_FOREACH_SAFE(ap->utxos,up,tmp) { - char str[65]; printf("LP_address_utxo_ptrs %s n.%d %.8f %s v%d spendheight.%d allocated.%d\n",ap->coinaddr,n,dstr(up->U.value),bits256_str(str,up->U.txid),up->U.vout,up->spendheight,LP_allocated(up->U.txid,up->U.vout)); + //char str[65]; printf("LP_address_utxo_ptrs %s n.%d %.8f %s v%d spendheight.%d allocated.%d\n",ap->coinaddr,n,dstr(up->U.value),bits256_str(str,up->U.txid),up->U.vout,up->spendheight,LP_allocated(up->U.txid,up->U.vout)); if ( up->spendheight <= 0 && LP_RTmetrics_avoidtxid(up->U.txid) < 0 ) { if ( coin->electrum == 0 ) @@ -282,7 +282,7 @@ int32_t LP_address_utxo_ptrs(struct iguana_info *coin,int32_t iambob,struct LP_a { if ( LP_value_extract(txout,0) == 0 ) { - printf("LP_address_utxo_ptrs skip zero value %s/v%d\n",bits256_str(str,up->U.txid),up->U.vout); + //printf("LP_address_utxo_ptrs skip zero value %s/v%d\n",bits256_str(str,up->U.txid),up->U.vout); free_json(txout); up->spendheight = 1; if ( (tx= LP_transactionfind(coin,up->U.txid)) != 0 && up->U.vout < tx->numvouts ) @@ -293,7 +293,7 @@ int32_t LP_address_utxo_ptrs(struct iguana_info *coin,int32_t iambob,struct LP_a } else { - printf("LP_address_utxo_ptrs skips %s %s payment %s/v%d is spent\n",coin->symbol,coinaddr,bits256_str(str,up->U.txid),up->U.vout); + //printf("LP_address_utxo_ptrs skips %s %s payment %s/v%d is spent\n",coin->symbol,coinaddr,bits256_str(str,up->U.txid),up->U.vout); up->spendheight = 1; if ( (tx= LP_transactionfind(coin,up->U.txid)) != 0 && up->U.vout < tx->numvouts ) tx->outpoints[up->U.vout].spendheight = 1; @@ -304,7 +304,7 @@ int32_t LP_address_utxo_ptrs(struct iguana_info *coin,int32_t iambob,struct LP_a { if ( up->SPV < 0 || up->U.height == 0 ) { -printf("LP_address_utxo_ptrs skips %s/v%u due to SPV.%d ht.%d\n",bits256_str(str,up->U.txid),up->U.vout,up->SPV,up->U.height); +//printf("LP_address_utxo_ptrs skips %s/v%u due to SPV.%d ht.%d\n",bits256_str(str,up->U.txid),up->U.vout,up->SPV,up->U.height); if ( (tx= LP_transactionfind(coin,up->U.txid)) != 0 && up->U.vout < tx->numvouts ) tx->outpoints[up->U.vout].spendheight = 1; continue; @@ -315,7 +315,7 @@ printf("LP_address_utxo_ptrs skips %s/v%u due to SPV.%d ht.%d\n",bits256_str(str utxos[n++] = up; if ( n >= max ) break; - } else printf("LP_allocated skip\n"); + } //else printf("LP_allocated skip\n"); } else { From a4a3a46aa7239e6e5d156c0fc64fcfb9686363b4 Mon Sep 17 00:00:00 2001 From: jl777 Date: Fri, 24 Nov 2017 20:24:08 +0400 Subject: [PATCH 1253/1664] Test --- iguana/exchanges/LP_transaction.c | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/iguana/exchanges/LP_transaction.c b/iguana/exchanges/LP_transaction.c index 2c9fa38cc..3edd206b1 100644 --- a/iguana/exchanges/LP_transaction.c +++ b/iguana/exchanges/LP_transaction.c @@ -1341,15 +1341,15 @@ char *LP_withdraw(struct iguana_info *coin,cJSON *argjson) if ( strcmp(coin->symbol,"BTC") == 0 ) { newtxfee = LP_txfeecalc(coin,0,datalen); - printf("txfee %.8f -> newtxfee %.8f\n",dstr(txfee),dstr(newtxfee)); + printf("txfee %.8f -> newtxfee %.8f, numvins.%d\n",dstr(txfee),dstr(newtxfee),numvins); + for (i=0; i Date: Fri, 24 Nov 2017 20:25:43 +0400 Subject: [PATCH 1254/1664] Test --- iguana/exchanges/LP_transaction.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/iguana/exchanges/LP_transaction.c b/iguana/exchanges/LP_transaction.c index 3edd206b1..d4b769d15 100644 --- a/iguana/exchanges/LP_transaction.c +++ b/iguana/exchanges/LP_transaction.c @@ -1282,6 +1282,7 @@ char *LP_createrawtransaction(cJSON **txobjp,int32_t *numvinsp,struct iguana_inf { } else printf("error making rawtx suppress.%d\n",suppress_pubkeys); *txobjp = txobj; + *numvinsp = numvins; return(rawtxbytes); } @@ -1350,6 +1351,7 @@ char *LP_withdraw(struct iguana_info *coin,cJSON *argjson) } } else break; } else break; + printf("free vars for second iter\n"); free_json(vins), vins = 0; free_json(txobj), txobj = 0; free_json(privkeys), privkeys = 0; From a6e5535774e08c054466d29afbf8c6a8c5c796f1 Mon Sep 17 00:00:00 2001 From: jl777 Date: Fri, 24 Nov 2017 20:29:45 +0400 Subject: [PATCH 1255/1664] Test --- iguana/exchanges/LP_transaction.c | 3 +-- iguana/exchanges/LP_utxo.c | 7 ++++--- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/iguana/exchanges/LP_transaction.c b/iguana/exchanges/LP_transaction.c index d4b769d15..387d156e8 100644 --- a/iguana/exchanges/LP_transaction.c +++ b/iguana/exchanges/LP_transaction.c @@ -1346,12 +1346,11 @@ char *LP_withdraw(struct iguana_info *coin,cJSON *argjson) for (i=0; iind; - printf("_LP_inuse_delete removing %s/v%d\n",bits256_str(str,txid),vout); - *lp = LP_inuse[--LP_numinuse]; + if ( LP_numinuse > 0 ) + *lp = LP_inuse[--LP_numinuse]; lp->ind = ind; memset(&LP_inuse[LP_numinuse],0,sizeof(struct LP_inuse_info)); + printf("_LP_inuse_delete deleted %s/v%d find.%p\n",bits256_str(str,txid),vout,_LP_inuse_find(txid,vout)); for (ind=0; ind Date: Fri, 24 Nov 2017 20:32:14 +0400 Subject: [PATCH 1256/1664] Test --- iguana/exchanges/LP_utxo.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/iguana/exchanges/LP_utxo.c b/iguana/exchanges/LP_utxo.c index bb0f294c6..abd62173f 100644 --- a/iguana/exchanges/LP_utxo.c +++ b/iguana/exchanges/LP_utxo.c @@ -274,7 +274,7 @@ int32_t LP_address_utxo_ptrs(struct iguana_info *coin,int32_t iambob,struct LP_a //portable_mutex_lock(&LP_utxomutex); DL_FOREACH_SAFE(ap->utxos,up,tmp) { - //char str[65]; printf("LP_address_utxo_ptrs %s n.%d %.8f %s v%d spendheight.%d allocated.%d\n",ap->coinaddr,n,dstr(up->U.value),bits256_str(str,up->U.txid),up->U.vout,up->spendheight,LP_allocated(up->U.txid,up->U.vout)); + char str[65]; printf("LP_address_utxo_ptrs %s n.%d %.8f %s v%d spendheight.%d allocated.%d\n",ap->coinaddr,n,dstr(up->U.value),bits256_str(str,up->U.txid),up->U.vout,up->spendheight,LP_allocated(up->U.txid,up->U.vout)); if ( up->spendheight <= 0 && LP_RTmetrics_avoidtxid(up->U.txid) < 0 ) { if ( coin->electrum == 0 ) @@ -316,7 +316,7 @@ int32_t LP_address_utxo_ptrs(struct iguana_info *coin,int32_t iambob,struct LP_a utxos[n++] = up; if ( n >= max ) break; - } //else printf("LP_allocated skip\n"); + } else printf("LP_allocated skip %u\n",LP_allocated(up->U.txid,up->U.vout)); } else { From 9089bd83d9556c46dd4c4d845799928b8175040e Mon Sep 17 00:00:00 2001 From: jl777 Date: Fri, 24 Nov 2017 20:35:35 +0400 Subject: [PATCH 1257/1664] Test --- iguana/exchanges/LP_transaction.c | 4 ++-- iguana/exchanges/LP_utxo.c | 6 +++--- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/iguana/exchanges/LP_transaction.c b/iguana/exchanges/LP_transaction.c index 387d156e8..752964c5d 100644 --- a/iguana/exchanges/LP_transaction.c +++ b/iguana/exchanges/LP_transaction.c @@ -1316,10 +1316,10 @@ char *LP_withdraw(struct iguana_info *coin,cJSON *argjson) privkey = LP_privkey(vinaddr,coin->taddr); maxV = LP_MAXVINS; V = malloc(maxV * sizeof(*V)); - if ( (ap= LP_address_utxo_reset(coin)) == 0 ) - return(0); for (iter=0; iter<2; iter++) { + if ( (ap= LP_address_utxo_reset(coin)) == 0 ) + return(0); privkeys = cJSON_CreateArray(); vins = cJSON_CreateArray(); memset(V,0,sizeof(*V) * maxV); diff --git a/iguana/exchanges/LP_utxo.c b/iguana/exchanges/LP_utxo.c index abd62173f..44d0162dd 100644 --- a/iguana/exchanges/LP_utxo.c +++ b/iguana/exchanges/LP_utxo.c @@ -49,7 +49,7 @@ int32_t _LP_inuse_delete(bits256 txid,int32_t vout) *lp = LP_inuse[--LP_numinuse]; lp->ind = ind; memset(&LP_inuse[LP_numinuse],0,sizeof(struct LP_inuse_info)); - printf("_LP_inuse_delete deleted %s/v%d find.%p\n",bits256_str(str,txid),vout,_LP_inuse_find(txid,vout)); + //printf("_LP_inuse_delete deleted %s/v%d find.%p\n",bits256_str(str,txid),vout,_LP_inuse_find(txid,vout)); for (ind=0; indutxos,up,tmp) { - char str[65]; printf("LP_address_utxo_ptrs %s n.%d %.8f %s v%d spendheight.%d allocated.%d\n",ap->coinaddr,n,dstr(up->U.value),bits256_str(str,up->U.txid),up->U.vout,up->spendheight,LP_allocated(up->U.txid,up->U.vout)); + //char str[65]; printf("LP_address_utxo_ptrs %s n.%d %.8f %s v%d spendheight.%d allocated.%d\n",ap->coinaddr,n,dstr(up->U.value),bits256_str(str,up->U.txid),up->U.vout,up->spendheight,LP_allocated(up->U.txid,up->U.vout)); if ( up->spendheight <= 0 && LP_RTmetrics_avoidtxid(up->U.txid) < 0 ) { if ( coin->electrum == 0 ) @@ -316,7 +316,7 @@ int32_t LP_address_utxo_ptrs(struct iguana_info *coin,int32_t iambob,struct LP_a utxos[n++] = up; if ( n >= max ) break; - } else printf("LP_allocated skip %u\n",LP_allocated(up->U.txid,up->U.vout)); + } //else printf("LP_allocated skip %u\n",LP_allocated(up->U.txid,up->U.vout)); } else { From 6489816e83284618e11f1d837ec61a74acdfef3d Mon Sep 17 00:00:00 2001 From: jl777 Date: Fri, 24 Nov 2017 20:39:26 +0400 Subject: [PATCH 1258/1664] Test --- iguana/exchanges/LP_utxo.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/iguana/exchanges/LP_utxo.c b/iguana/exchanges/LP_utxo.c index 44d0162dd..93eca3034 100644 --- a/iguana/exchanges/LP_utxo.c +++ b/iguana/exchanges/LP_utxo.c @@ -49,7 +49,7 @@ int32_t _LP_inuse_delete(bits256 txid,int32_t vout) *lp = LP_inuse[--LP_numinuse]; lp->ind = ind; memset(&LP_inuse[LP_numinuse],0,sizeof(struct LP_inuse_info)); - //printf("_LP_inuse_delete deleted %s/v%d find.%p\n",bits256_str(str,txid),vout,_LP_inuse_find(txid,vout)); + printf("_LP_inuse_delete mark as free %s/v%d find.%p\n",bits256_str(str,txid),vout,_LP_inuse_find(txid,vout)); for (ind=0; ind Date: Fri, 24 Nov 2017 22:41:33 +0400 Subject: [PATCH 1259/1664] Test --- iguana/exchanges/LP_nativeDEX.c | 5 +++-- iguana/exchanges/LP_socket.c | 2 +- 2 files changed, 4 insertions(+), 3 deletions(-) diff --git a/iguana/exchanges/LP_nativeDEX.c b/iguana/exchanges/LP_nativeDEX.c index 5b53a63e9..270193c63 100644 --- a/iguana/exchanges/LP_nativeDEX.c +++ b/iguana/exchanges/LP_nativeDEX.c @@ -18,11 +18,12 @@ // marketmaker // // alice waiting for bestprice -// cancel bid/ask +// big BTC swaps // delay swap credit back until notarization -// electrum dynamic trust over 1000 +// electrum dynamic trust over 1000 tx // https://github.com/bitcoin/bips/blob/master/bip-0143.mediawiki for signing BCH/BTG // +// cancel bid/ask // portfolio value based on ask? // verify encrypted destpubkey, broadcast:0 setprice // USD paxprice based USDvalue in portfolio diff --git a/iguana/exchanges/LP_socket.c b/iguana/exchanges/LP_socket.c index 0a9ef7f09..7d1762e96 100644 --- a/iguana/exchanges/LP_socket.c +++ b/iguana/exchanges/LP_socket.c @@ -417,7 +417,7 @@ cJSON *electrum_submit(char *symbol,struct electrum_info *ep,cJSON **retjsonp,ch { *retjsonp = 0; sprintf(stratumreq,"{ \"jsonrpc\":\"2.0\", \"id\": %u, \"method\":\"%s\", \"params\": %s }\n",ep->stratumid,method,params); -//printf("%s %s",symbol,stratumreq); +printf("%s %s",symbol,stratumreq); memset(ep->buf,0,ep->bufsize); sitem = electrum_sitem(ep,stratumreq,timeout,retjsonp); portable_mutex_lock(&ep->mutex); // this helps performance! From 87dddf4f8ff3334355a93c2840971163809eaae1 Mon Sep 17 00:00:00 2001 From: jl777 Date: Fri, 24 Nov 2017 22:49:49 +0400 Subject: [PATCH 1260/1664] Test --- iguana/exchanges/LP_socket.c | 2 +- iguana/exchanges/LP_swap.c | 30 ++++++++++++++++++------------ 2 files changed, 19 insertions(+), 13 deletions(-) diff --git a/iguana/exchanges/LP_socket.c b/iguana/exchanges/LP_socket.c index 7d1762e96..0a9ef7f09 100644 --- a/iguana/exchanges/LP_socket.c +++ b/iguana/exchanges/LP_socket.c @@ -417,7 +417,7 @@ cJSON *electrum_submit(char *symbol,struct electrum_info *ep,cJSON **retjsonp,ch { *retjsonp = 0; sprintf(stratumreq,"{ \"jsonrpc\":\"2.0\", \"id\": %u, \"method\":\"%s\", \"params\": %s }\n",ep->stratumid,method,params); -printf("%s %s",symbol,stratumreq); +//printf("%s %s",symbol,stratumreq); memset(ep->buf,0,ep->bufsize); sitem = electrum_sitem(ep,stratumreq,timeout,retjsonp); portable_mutex_lock(&ep->mutex); // this helps performance! diff --git a/iguana/exchanges/LP_swap.c b/iguana/exchanges/LP_swap.c index fd108821d..c19c10df2 100644 --- a/iguana/exchanges/LP_swap.c +++ b/iguana/exchanges/LP_swap.c @@ -132,18 +132,21 @@ void basilisk_swap_finished(struct basilisk_swap *swap) LP_availableset(swap->utxo); swap->utxo = 0; //LP_butxo_swapfields_set(swap->utxo); - }*/ - if ( swap->I.iambob != 0 ) - { - LP_availableset(swap->bobdeposit.utxotxid,swap->bobdeposit.utxovout); - LP_availableset(swap->bobpayment.utxotxid,swap->bobpayment.utxovout); } - else + swap->I.finished = (uint32_t)time(NULL);*/ + if ( swap->I.finished == 0 ) { - LP_availableset(swap->alicepayment.utxotxid,swap->alicepayment.utxovout); - LP_availableset(swap->myfee.utxotxid,swap->myfee.utxovout); + if ( swap->I.iambob != 0 ) + { + LP_availableset(swap->bobdeposit.utxotxid,swap->bobdeposit.utxovout); + LP_availableset(swap->bobpayment.utxotxid,swap->bobpayment.utxovout); + } + else + { + LP_availableset(swap->alicepayment.utxotxid,swap->alicepayment.utxovout); + LP_availableset(swap->myfee.utxotxid,swap->myfee.utxovout); + } } - swap->I.finished = (uint32_t)time(NULL); // save to permanent storage basilisk_rawtx_purge(&swap->bobdeposit); basilisk_rawtx_purge(&swap->bobpayment); @@ -739,7 +742,7 @@ uint32_t LP_swapdata_rawtxsend(int32_t pairsock,struct basilisk_swap *swap,uint3 return(0); } -int32_t LP_swapwait(uint32_t requestid,uint32_t quoteid,int32_t duration,int32_t sleeptime) +int32_t LP_swapwait(struct basilisk_swap *swap,uint32_t requestid,uint32_t quoteid,int32_t duration,int32_t sleeptime) { char *retstr; cJSON *retjson=0; uint32_t expiration = (uint32_t)(time(NULL) + duration); printf("wait %d:%d for SWAP.(r%u/q%u) to complete\n",duration,sleeptime,requestid,quoteid); @@ -753,7 +756,10 @@ int32_t LP_swapwait(uint32_t requestid,uint32_t quoteid,int32_t duration,int32_t if ( (retjson= cJSON_Parse(retstr)) != 0 ) { if ( jstr(retjson,"status") != 0 && strcmp(jstr(retjson,"status"),"finished") == 0 ) + { + swap->I.finished = (uint32_t)time(NULL); break; + } //else printf("NOT FINISHED.(%s)\n",jprint(retjson,0)); free_json(retjson); retjson = 0; @@ -838,7 +844,7 @@ void LP_bobloop(void *_swap) if ( swap->N.pair >= 0 ) nn_close(swap->N.pair), swap->N.pair = -1; LP_swap_endcritical = (uint32_t)time(NULL); - LP_swapwait(swap->I.req.requestid,swap->I.req.quoteid,LP_atomic_locktime(swap->I.bobstr,swap->I.alicestr)*2,swap->I.aliceconfirms == 0 ? 3 : 30); + LP_swapwait(swap,swap->I.req.requestid,swap->I.req.quoteid,LP_atomic_locktime(swap->I.bobstr,swap->I.alicestr)*2,swap->I.aliceconfirms == 0 ? 3 : 30); } } } @@ -919,7 +925,7 @@ void LP_aliceloop(void *_swap) }*/ if ( swap->N.pair >= 0 ) nn_close(swap->N.pair), swap->N.pair = -1; - LP_swapwait(swap->I.req.requestid,swap->I.req.quoteid,LP_atomic_locktime(swap->I.bobstr,swap->I.alicestr)*2,swap->I.aliceconfirms == 0 ? 3 : 30); + LP_swapwait(swap,swap->I.req.requestid,swap->I.req.quoteid,LP_atomic_locktime(swap->I.bobstr,swap->I.alicestr)*2,swap->I.aliceconfirms == 0 ? 3 : 30); } } } From 83339e5b37eefba8d29052fc08fb6888375c519c Mon Sep 17 00:00:00 2001 From: jl777 Date: Fri, 24 Nov 2017 22:58:05 +0400 Subject: [PATCH 1261/1664] Test --- iguana/exchanges/LP_socket.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/iguana/exchanges/LP_socket.c b/iguana/exchanges/LP_socket.c index 0a9ef7f09..7d1762e96 100644 --- a/iguana/exchanges/LP_socket.c +++ b/iguana/exchanges/LP_socket.c @@ -417,7 +417,7 @@ cJSON *electrum_submit(char *symbol,struct electrum_info *ep,cJSON **retjsonp,ch { *retjsonp = 0; sprintf(stratumreq,"{ \"jsonrpc\":\"2.0\", \"id\": %u, \"method\":\"%s\", \"params\": %s }\n",ep->stratumid,method,params); -//printf("%s %s",symbol,stratumreq); +printf("%s %s",symbol,stratumreq); memset(ep->buf,0,ep->bufsize); sitem = electrum_sitem(ep,stratumreq,timeout,retjsonp); portable_mutex_lock(&ep->mutex); // this helps performance! From 4e9d722fee7aeea4792a267e486f111e4afdd612 Mon Sep 17 00:00:00 2001 From: jl777 Date: Fri, 24 Nov 2017 23:48:35 +0400 Subject: [PATCH 1262/1664] Test --- iguana/exchanges/LP_ordermatch.c | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/iguana/exchanges/LP_ordermatch.c b/iguana/exchanges/LP_ordermatch.c index 2b32ac8ac..04cde52ad 100644 --- a/iguana/exchanges/LP_ordermatch.c +++ b/iguana/exchanges/LP_ordermatch.c @@ -281,13 +281,13 @@ int32_t LP_nearest_utxovalue(struct iguana_info *coin,char *coinaddr,struct LP_a 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 %s utxos[%d] target %.8f\n",coin->symbol,coinaddr,n,dstr(targetval)); for (i=0; iU.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 ( dist >= 0 && dist < mindist ) @@ -325,7 +325,7 @@ int32_t LP_nearest_utxovalue(struct iguana_info *coin,char *coinaddr,struct LP_a return(replacei); } } - //printf("return mini.%d\n",mini); + printf("return mini.%d\n",mini); return(mini); } @@ -416,7 +416,7 @@ struct LP_utxoinfo *LP_address_myutxopair(struct LP_utxoinfo *butxo,int32_t iamb { if ( (m= LP_address_utxo_ptrs(coin,iambob,utxos,max,ap,coinaddr)) > 1 ) { - if ( 0 ) + if ( 1 ) { int32_t i; for (i=0; i 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 < ratio-1 ) { - if ( 0 ) + if ( 1 ) { int32_t i; for (i=0; i Date: Fri, 24 Nov 2017 23:55:10 +0400 Subject: [PATCH 1263/1664] Test --- iguana/exchanges/LP_socket.c | 4 ++++ iguana/exchanges/LP_utxo.c | 1 + 2 files changed, 5 insertions(+) diff --git a/iguana/exchanges/LP_socket.c b/iguana/exchanges/LP_socket.c index 7d1762e96..3009ff206 100644 --- a/iguana/exchanges/LP_socket.c +++ b/iguana/exchanges/LP_socket.c @@ -401,6 +401,8 @@ int32_t electrum_kickstart(struct electrum_info *ep) return(0); } +int32_t zeroval(); + cJSON *electrum_submit(char *symbol,struct electrum_info *ep,cJSON **retjsonp,char *method,char *params,int32_t timeout) { // queue id and string and callback @@ -418,6 +420,8 @@ cJSON *electrum_submit(char *symbol,struct electrum_info *ep,cJSON **retjsonp,ch *retjsonp = 0; sprintf(stratumreq,"{ \"jsonrpc\":\"2.0\", \"id\": %u, \"method\":\"%s\", \"params\": %s }\n",ep->stratumid,method,params); printf("%s %s",symbol,stratumreq); + if ( strcmp(params,"[\"KMD\"]") == 0 ) + printf("div0 %d\n",1/zeroval()); memset(ep->buf,0,ep->bufsize); sitem = electrum_sitem(ep,stratumreq,timeout,retjsonp); portable_mutex_lock(&ep->mutex); // this helps performance! diff --git a/iguana/exchanges/LP_utxo.c b/iguana/exchanges/LP_utxo.c index 93eca3034..bd271ffde 100644 --- a/iguana/exchanges/LP_utxo.c +++ b/iguana/exchanges/LP_utxo.c @@ -427,6 +427,7 @@ struct LP_address *LP_address_utxo_reset(struct iguana_info *coin) { struct LP_address *ap; struct LP_address_utxo *up,*tmp; int32_t i,n,m,vout,height; cJSON *array,*item,*txobj; int64_t value; bits256 txid; uint32_t now; LP_address(coin,coin->smartaddr); + printf("call listunspent issue %s (%s)\n",coin->symbol,coin->smartaddr); LP_listunspent_issue(coin->symbol,coin->smartaddr,2); if ( (ap= LP_addressfind(coin,coin->smartaddr)) == 0 ) { From 83a05411e8bc3a883f0a5ecef9caaaf4c458deed Mon Sep 17 00:00:00 2001 From: jl777 Date: Sat, 25 Nov 2017 00:00:40 +0400 Subject: [PATCH 1264/1664] Test --- iguana/exchanges/LP_ordermatch.c | 6 +++--- iguana/exchanges/LP_socket.c | 4 +--- iguana/exchanges/LP_utxo.c | 2 +- 3 files changed, 5 insertions(+), 7 deletions(-) diff --git a/iguana/exchanges/LP_ordermatch.c b/iguana/exchanges/LP_ordermatch.c index 04cde52ad..b540a4f94 100644 --- a/iguana/exchanges/LP_ordermatch.c +++ b/iguana/exchanges/LP_ordermatch.c @@ -416,7 +416,7 @@ struct LP_utxoinfo *LP_address_myutxopair(struct LP_utxoinfo *butxo,int32_t iamb { if ( (m= LP_address_utxo_ptrs(coin,iambob,utxos,max,ap,coinaddr)) > 1 ) { - if ( 1 ) + if ( 0 ) { int32_t i; for (i=0; i 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 < ratio-1 ) { - if ( 1 ) + if ( 0 ) { int32_t i; for (i=0; istratumid,method,params); -printf("%s %s",symbol,stratumreq); - if ( strcmp(params,"[\"KMD\"]") == 0 ) - printf("div0 %d\n",1/zeroval()); +//printf("%s %s",symbol,stratumreq); memset(ep->buf,0,ep->bufsize); sitem = electrum_sitem(ep,stratumreq,timeout,retjsonp); portable_mutex_lock(&ep->mutex); // this helps performance! diff --git a/iguana/exchanges/LP_utxo.c b/iguana/exchanges/LP_utxo.c index bd271ffde..599794ddc 100644 --- a/iguana/exchanges/LP_utxo.c +++ b/iguana/exchanges/LP_utxo.c @@ -455,7 +455,7 @@ struct LP_address *LP_address_utxo_reset(struct iguana_info *coin) //{"tx_hash":"38d1b7c73015e1b1d6cb7fc314cae402a635b7d7ea294970ab857df8777a66f4","tx_pos":0,"height":577975,"value":238700} item = jitem(array,i); value = LP_listunspent_parseitem(coin,&txid,&vout,&height,item); - if ( (txobj= LP_gettxout(coin->symbol,coin->symbol,txid,vout)) == 0 ) + if ( (txobj= LP_gettxout(coin->symbol,coin->smartaddr,txid,vout)) == 0 ) continue; else free_json(txobj); LP_address_utxoadd(now,"withdraw",coin,coin->smartaddr,txid,vout,value,height,-1); From 0f287c276666243c9f870ce95c3975e2e5d44732 Mon Sep 17 00:00:00 2001 From: jl777 Date: Sat, 25 Nov 2017 00:30:07 +0400 Subject: [PATCH 1265/1664] Test --- iguana/exchanges/LP_ordermatch.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/iguana/exchanges/LP_ordermatch.c b/iguana/exchanges/LP_ordermatch.c index b540a4f94..426e62b3a 100644 --- a/iguana/exchanges/LP_ordermatch.c +++ b/iguana/exchanges/LP_ordermatch.c @@ -281,13 +281,13 @@ int32_t LP_nearest_utxovalue(struct iguana_info *coin,char *coinaddr,struct LP_a if ( (backupep= ep->prev) == 0 ) backupep = ep; } - printf("LP_nearest_utxovalue %s %s utxos[%d] target %.8f\n",coin->symbol,coinaddr,n,dstr(targetval)); + //printf("LP_nearest_utxovalue %s %s utxos[%d] target %.8f\n",coin->symbol,coinaddr,n,dstr(targetval)); for (i=0; iU.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 ( dist >= 0 && dist < mindist ) @@ -325,7 +325,7 @@ int32_t LP_nearest_utxovalue(struct iguana_info *coin,char *coinaddr,struct LP_a return(replacei); } } - printf("return mini.%d\n",mini); + //printf("return mini.%d\n",mini); return(mini); } From cd5e81a1a43e420793ea54cefb0f86b4ac91ec9b Mon Sep 17 00:00:00 2001 From: jl777 Date: Sat, 25 Nov 2017 19:40:51 +0400 Subject: [PATCH 1266/1664] Nonz bar --- iguana/exchanges/LP_stats.c | 51 ++++++++++++++++++++++--------------- iguana/exchanges/LP_utxo.c | 4 +-- 2 files changed, 33 insertions(+), 22 deletions(-) diff --git a/iguana/exchanges/LP_stats.c b/iguana/exchanges/LP_stats.c index 02ef164f0..4478b00ba 100644 --- a/iguana/exchanges/LP_stats.c +++ b/iguana/exchanges/LP_stats.c @@ -516,26 +516,30 @@ struct LP_ohlc double high,low,open,close,relsum,basesum; }; -cJSON *LP_ohlc_json(struct LP_ohlc *bar) +cJSON *LP_ohlc_json(struct LP_ohlc *bar,struct LP_ohlc *prevbar) { - cJSON *item; - //if ( bar->numtrades != 0 && bar->relsum > SMALLVAL && bar->basesum > SMALLVAL ) + cJSON *item; struct LP_ohlc tmp; + memset(&tmp,0,sizeof(tmp)); + if ( bar->numtrades == 0 ) { - item = cJSON_CreateArray(); - jaddinum(item,bar->timestamp); - jaddinum(item,bar->high); - jaddinum(item,bar->low); - jaddinum(item,bar->open); - jaddinum(item,bar->close); - jaddinum(item,bar->relsum); - jaddinum(item,bar->basesum); - if ( bar->basesum != 0 ) - jaddinum(item,bar->relsum / bar->basesum); - else jaddinum(item,0); - jaddinum(item,bar->numtrades); - return(item); - } - return(0); + tmp = *prevbar; + tmp.numtrades = 0; + tmp.relsum = tmp.basesum = 0.; + } else tmp = *bar; + bar = &tmp; + item = cJSON_CreateArray(); + jaddinum(item,bar->timestamp); + jaddinum(item,bar->high); + jaddinum(item,bar->low); + jaddinum(item,bar->open); + jaddinum(item,bar->close); + jaddinum(item,bar->relsum); + jaddinum(item,bar->basesum); + if ( bar->basesum != 0 ) + jaddinum(item,bar->relsum / bar->basesum); + else jaddinum(item,0); + jaddinum(item,bar->numtrades); + return(item); } void LP_ohlc_update(struct LP_ohlc *bar,uint32_t timestamp,double basevol,double relvol) @@ -567,7 +571,7 @@ void LP_ohlc_update(struct LP_ohlc *bar,uint32_t timestamp,double basevol,double cJSON *LP_tradesarray(char *base,char *rel,uint32_t starttime,uint32_t endtime,int32_t timescale) { - struct LP_ohlc *bars; cJSON *array,*item,*statsjson,*swaps; uint32_t timestamp; bits256 zero; int32_t i,n,numbars,bari; + struct LP_ohlc *bars,nonz; cJSON *array,*item,*statsjson,*swaps; uint32_t timestamp; bits256 zero; int32_t i,n,numbars,bari; if ( timescale < 60 ) return(cJSON_Parse("{\"error\":\"one minute is shortest timescale\"}")); memset(zero.bytes,0,sizeof(zero)); @@ -596,9 +600,16 @@ cJSON *LP_tradesarray(char *base,char *rel,uint32_t starttime,uint32_t endtime,i free_json(statsjson); } array = cJSON_CreateArray(); + memset(&nonz,0,sizeof(nonz)); for (bari=0; bari 0 ) + nonz = bars[bari]; + } + } free(bars); return(array); } diff --git a/iguana/exchanges/LP_utxo.c b/iguana/exchanges/LP_utxo.c index 599794ddc..9579c5474 100644 --- a/iguana/exchanges/LP_utxo.c +++ b/iguana/exchanges/LP_utxo.c @@ -427,7 +427,7 @@ struct LP_address *LP_address_utxo_reset(struct iguana_info *coin) { struct LP_address *ap; struct LP_address_utxo *up,*tmp; int32_t i,n,m,vout,height; cJSON *array,*item,*txobj; int64_t value; bits256 txid; uint32_t now; LP_address(coin,coin->smartaddr); - printf("call listunspent issue %s (%s)\n",coin->symbol,coin->smartaddr); + //printf("call listunspent issue %s (%s)\n",coin->symbol,coin->smartaddr); LP_listunspent_issue(coin->symbol,coin->smartaddr,2); if ( (ap= LP_addressfind(coin,coin->smartaddr)) == 0 ) { @@ -463,7 +463,7 @@ struct LP_address *LP_address_utxo_reset(struct iguana_info *coin) printf("couldnt find just added %s/%d ht.%d %.8f\n",bits256_str(str,txid),vout,height,dstr(value)); else m++; } - printf("added %d from listunspents\n",m); + //printf("added %d from listunspents\n",m); } free_json(array); } From d3f80aafd736179da70f387cc34a7a01884bc037 Mon Sep 17 00:00:00 2001 From: jl777 Date: Sat, 25 Nov 2017 23:42:21 +0400 Subject: [PATCH 1267/1664] Fix duplicated timestamp --- iguana/exchanges/LP_stats.c | 1 + 1 file changed, 1 insertion(+) diff --git a/iguana/exchanges/LP_stats.c b/iguana/exchanges/LP_stats.c index 4478b00ba..8ef41afb7 100644 --- a/iguana/exchanges/LP_stats.c +++ b/iguana/exchanges/LP_stats.c @@ -523,6 +523,7 @@ cJSON *LP_ohlc_json(struct LP_ohlc *bar,struct LP_ohlc *prevbar) if ( bar->numtrades == 0 ) { tmp = *prevbar; + tmp.timestamp = bar->timestamp; tmp.numtrades = 0; tmp.relsum = tmp.basesum = 0.; } else tmp = *bar; From eecc63c258f1d4cbf14df67346beff87aa56e961 Mon Sep 17 00:00:00 2001 From: jl777 Date: Sun, 26 Nov 2017 12:32:26 +0400 Subject: [PATCH 1268/1664] Cleanup --- iguana/exchanges/LP_commands.c | 2 - iguana/exchanges/LP_include.h | 8 +- iguana/exchanges/LP_nativeDEX.c | 36 +- iguana/exchanges/LP_ordermatch.c | 232 ++++---- iguana/exchanges/LP_privkey.c | 351 +++++++++++ iguana/exchanges/LP_remember.c | 2 + iguana/exchanges/LP_rpc.c | 20 + iguana/exchanges/LP_signatures.c | 57 -- iguana/exchanges/LP_statemachine.c | 659 +++++++++++++++++++++ iguana/exchanges/LP_utxo.c | 99 +--- iguana/exchanges/LP_utxos.c | 902 ----------------------------- 11 files changed, 1192 insertions(+), 1176 deletions(-) create mode 100644 iguana/exchanges/LP_privkey.c delete mode 100644 iguana/exchanges/LP_utxos.c diff --git a/iguana/exchanges/LP_commands.c b/iguana/exchanges/LP_commands.c index 226901d50..d06660352 100644 --- a/iguana/exchanges/LP_commands.c +++ b/iguana/exchanges/LP_commands.c @@ -599,8 +599,6 @@ zeroconf_claim(address, expiration=0)\n\ return(LP_swapstatus_recv(argjson)); else if ( strcmp(method,"postprice") == 0 ) return(LP_postprice_recv(argjson)); - else if ( strcmp(method,"postutxos") == 0 ) - return(LP_postutxos_recv(argjson)); else if ( strcmp(method,"uitem") == 0 ) return(LP_uitem_recv(argjson)); else if ( strcmp(method,"notify") == 0 ) diff --git a/iguana/exchanges/LP_include.h b/iguana/exchanges/LP_include.h index 314e4f7fd..7f0dfbd38 100644 --- a/iguana/exchanges/LP_include.h +++ b/iguana/exchanges/LP_include.h @@ -294,7 +294,7 @@ struct LP_utxobob { struct _LP_utxoinfo utxo,deposit; }; struct LP_utxoalice { struct _LP_utxoinfo utxo,fee; }; -struct LP_utxoswap { bits256 otherpubkey; uint64_t satoshis; }; +//struct LP_utxoswap { bits256 otherpubkey; uint64_t satoshis; }; struct LP_utxoinfo { @@ -302,7 +302,8 @@ struct LP_utxoinfo bits256 pubkey; struct _LP_utxoinfo payment,deposit,fee; struct LP_utxostats T; - struct LP_utxoswap S; + int64_t swap_satoshis; + //struct LP_utxoswap S; int32_t iambob,iamlp; uint8_t key[sizeof(bits256) + sizeof(int32_t)]; uint8_t key2[sizeof(bits256) + sizeof(int32_t)]; @@ -429,12 +430,9 @@ uint32_t basilisk_quoteid(struct basilisk_request *rp); struct basilisk_swap *LP_swapinit(int32_t iambob,int32_t optionduration,bits256 privkey,struct basilisk_request *rp,struct LP_quoteinfo *qp,int32_t dynamictrust); char *bitcoind_passthru(char *coinstr,char *serverport,char *userpass,char *method,char *params); uint32_t LP_swapdata_rawtxsend(int32_t pairsock,struct basilisk_swap *swap,uint32_t msgbits,uint8_t *data,int32_t maxlen,struct basilisk_rawtx *rawtx,uint32_t nextbits,int32_t suppress_swapsend); -//double LP_query(char *method,struct LP_quoteinfo *qp,char *base,char *rel,bits256 mypub); int32_t LP_rawtx_spendscript(struct basilisk_swap *swap,int32_t height,struct basilisk_rawtx *rawtx,int32_t v,uint8_t *recvbuf,int32_t recvlen,int32_t suppress_pubkeys); void LP_quotesinit(char *base,char *rel); int32_t LP_forward(void *ctx,char *myipaddr,int32_t pubsock,bits256 pubkey,char *jsonstr,int32_t freeflag); -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); diff --git a/iguana/exchanges/LP_nativeDEX.c b/iguana/exchanges/LP_nativeDEX.c index 270193c63..d003829b3 100644 --- a/iguana/exchanges/LP_nativeDEX.c +++ b/iguana/exchanges/LP_nativeDEX.c @@ -117,7 +117,7 @@ struct LP_privkey { bits256 privkey; uint8_t rmd160[20]; }; struct LP_globals { - struct LP_utxoinfo *LP_utxoinfos[2],*LP_utxoinfos2[2]; + //struct LP_utxoinfo *LP_utxoinfos[2],*LP_utxoinfos2[2]; bits256 LP_mypub25519,LP_privkey,LP_mypriv25519; uint64_t LP_skipstatus[10000]; uint8_t LP_myrmd160[20],LP_pubsecp[33]; @@ -187,7 +187,7 @@ char *blocktrail_listtransactions(char *symbol,char *coinaddr,int32_t num,int32_ #include "LP_zeroconf.c" #include "LP_swap.c" #include "LP_peers.c" -#include "LP_utxos.c" +#include "LP_privkey.c" #include "LP_forwarding.c" #include "LP_signatures.c" #include "LP_ordermatch.c" @@ -486,18 +486,6 @@ void command_rpcloop(void *myipaddr) } } -void utxosQ_loop(void *myipaddr) -{ - strcpy(utxosQ_loop_stats.name,"utxosQ_loop"); - utxosQ_loop_stats.threshold = 5000.; - while ( 1 ) - { - LP_millistats_update(&utxosQ_loop_stats); - if ( LP_utxosQ_process() == 0 ) - usleep(50000); - } -} - 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; @@ -791,27 +779,12 @@ void LP_initpeers(int32_t pubsock,struct LP_peerinfo *mypeer,char *myipaddr,uint void LP_pubkeysloop(void *ctx) { static uint32_t lasttime; - //struct LP_pubkey_info *pubp,*ptmp; //cJSON *retjson; struct iguana_info *coin,*tmp; strcpy(LP_pubkeysloop_stats.name,"LP_pubkeysloop"); LP_pubkeysloop_stats.threshold = 15000.; sleep(10); while ( 1 ) { LP_millistats_update(&LP_pubkeysloop_stats); - /*HASH_ITER(hh,LP_coins,coin,tmp) // firstrefht,firstscanht,lastscanht - { - if ( coin->electrum != 0 && time(NULL) > coin->lastunspent+30 ) - { - //printf("call electrum listunspent.%s\n",coin->symbol); - if ( (retjson= electrum_address_listunspent(coin->symbol,coin->electrum,&retjson,coin->smartaddr,2)) != 0 ) - free_json(retjson); - coin->lastunspent = (uint32_t)time(NULL); - } - }*/ - /*HASH_ITER(hh,LP_pubkeyinfos,pubp,ptmp) - { - pubp->dynamictrust = LP_dynamictrust(pubp->pubkey,0); - }*/ if ( time(NULL) > lasttime+LP_ORDERBOOK_DURATION*0.5 ) { //printf("LP_pubkeysloop %u\n",(uint32_t)time(NULL)); @@ -1206,11 +1179,6 @@ void LPinit(uint16_t myport,uint16_t mypullport,uint16_t mypubport,uint16_t mybu printf("error launching LP_reserved_msgs for (%s)\n",myipaddr); exit(-1); } - if ( OS_thread_create(malloc(sizeof(pthread_t)),NULL,(void *)utxosQ_loop,(void *)myipaddr) != 0 ) - { - printf("error launching utxosQ_loop for (%s)\n",myipaddr); - exit(-1); - } if ( OS_thread_create(malloc(sizeof(pthread_t)),NULL,(void *)stats_rpcloop,(void *)&myport) != 0 ) { printf("error launching stats rpcloop for port.%u\n",myport); diff --git a/iguana/exchanges/LP_ordermatch.c b/iguana/exchanges/LP_ordermatch.c index 426e62b3a..3f625ca72 100644 --- a/iguana/exchanges/LP_ordermatch.c +++ b/iguana/exchanges/LP_ordermatch.c @@ -349,7 +349,7 @@ void LP_butxo_set(struct LP_utxoinfo *butxo,int32_t iambob,struct iguana_info *c butxo->fee.vout = up2->U.vout; butxo->fee.value = up2->U.value; } - butxo->S.satoshis = satoshis; + butxo->swap_satoshis = satoshis; } void LP_abutxo_set(struct LP_utxoinfo *autxo,struct LP_utxoinfo *butxo,struct LP_quoteinfo *qp) @@ -367,7 +367,7 @@ void LP_abutxo_set(struct LP_utxoinfo *autxo,struct LP_utxoinfo *butxo,struct LP butxo->deposit.txid = qp->txid2; butxo->deposit.vout = qp->vout2; //butxo->deposit.value = up2->U.value; - butxo->S.satoshis = qp->satoshis; + butxo->swap_satoshis = qp->satoshis; } if ( autxo != 0 ) { @@ -382,7 +382,7 @@ void LP_abutxo_set(struct LP_utxoinfo *autxo,struct LP_utxoinfo *butxo,struct LP autxo->fee.txid = qp->feetxid; autxo->fee.vout = qp->feevout; //autxo->deposit.value = up2->U.value; - autxo->S.satoshis = qp->destsatoshis; + autxo->swap_satoshis = qp->destsatoshis; } } @@ -457,10 +457,9 @@ struct LP_utxoinfo *LP_address_myutxopair(struct LP_utxoinfo *butxo,int32_t iamb return(0); } -int32_t LP_connectstartbob(void *ctx,int32_t pubsock,cJSON *argjson,char *base,char *rel,double price,struct LP_quoteinfo *qp) +int32_t LP_connectstartbob(void *ctx,int32_t pubsock,char *base,char *rel,double price,struct LP_quoteinfo *qp) { 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(qp->srccoin)) == 0 ) { @@ -588,79 +587,79 @@ void LP_reserved(void *ctx,char *myipaddr,int32_t mypubsock,struct LP_quoteinfo } else printf("probably a timeout, reject reserved due to not eligible.%d or mismatched quote price %.8f vs maxprice %.8f\n",LP_alice_eligible(qp->quotetime),price,maxprice); } -char *LP_connectedalice(cJSON *argjson) // alice +char *LP_connectedalice(struct LP_quoteinfo *qp,char *pairstr) // alice { - cJSON *retjson; double bid,ask,price,qprice; int32_t pairsock = -1; char *pairstr; int32_t DEXselector = 0; struct LP_utxoinfo *autxo,A,B,*butxo; struct LP_quoteinfo Q; struct basilisk_swap *swap; struct iguana_info *coin; - if ( LP_quoteparse(&Q,argjson) < 0 ) + cJSON *retjson; double bid,ask,price,qprice; int32_t pairsock = -1; int32_t DEXselector = 0; struct LP_utxoinfo *autxo,A,B,*butxo; struct basilisk_swap *swap; struct iguana_info *coin; + /*if ( LP_quoteparse(&Q,argjson) < 0 ) { LP_aliceid(Q.tradeid,Q.aliceid,"error0",0,0); clonestr("{\"error\":\"cant parse quote\"}"); - } - if ( bits256_cmp(Q.desthash,G.LP_mypub25519) != 0 ) + }*/ + if ( bits256_cmp(qp->desthash,G.LP_mypub25519) != 0 ) { - LP_aliceid(Q.tradeid,Q.aliceid,"error1",0,0); + LP_aliceid(qp->tradeid,qp->aliceid,"error1",0,0); return(clonestr("{\"result\",\"update stats\"}")); } - printf("CONNECTED.(%s) numpending.%d tradeid.%u requestid.%u quoteid.%u\n",jprint(argjson,0),G.LP_pendingswaps,Q.tradeid,Q.R.requestid,Q.R.quoteid); - LP_requestinit(&Q.R,Q.srchash,Q.desthash,Q.srccoin,Q.satoshis-Q.txfee,Q.destcoin,Q.destsatoshis-Q.desttxfee,Q.timestamp,Q.quotetime,DEXselector); - printf("calculated requestid.%u quoteid.%u\n",Q.R.requestid,Q.R.quoteid); - if ( LP_pendingswap(Q.R.requestid,Q.R.quoteid) > 0 ) + printf("CONNECTED numpending.%d tradeid.%u requestid.%u quoteid.%u\n",G.LP_pendingswaps,qp->tradeid,qp->R.requestid,qp->R.quoteid); + LP_requestinit(&qp->R,qp->srchash,qp->desthash,qp->srccoin,qp->satoshis-qp->txfee,qp->destcoin,qp->destsatoshis-qp->desttxfee,qp->timestamp,qp->quotetime,DEXselector); + printf("calculated requestid.%u quoteid.%u\n",qp->R.requestid,qp->R.quoteid); + if ( LP_pendingswap(qp->R.requestid,qp->R.quoteid) > 0 ) { - printf("requestid.%u quoteid.%u is already in progres\n",Q.R.requestid,Q.R.quoteid); + printf("requestid.%u quoteid.%u is already in progres\n",qp->R.requestid,qp->R.quoteid); retjson = cJSON_CreateObject(); jaddstr(retjson,"error","swap already in progress"); return(jprint(retjson,1)); } - if ( LP_quotecmp(1,&Q,&LP_Alicereserved) == 0 ) + if ( LP_quotecmp(1,qp,&LP_Alicereserved) == 0 ) { printf("mismatched between reserved and connected\n"); } memset(&LP_Alicereserved,0,sizeof(LP_Alicereserved)); - LP_aliceid(Q.tradeid,Q.aliceid,"connected",Q.R.requestid,Q.R.quoteid); + LP_aliceid(qp->tradeid,qp->aliceid,"connected",qp->R.requestid,qp->R.quoteid); autxo = &A; butxo = &B; memset(autxo,0,sizeof(*autxo)); memset(butxo,0,sizeof(*butxo)); - LP_abutxo_set(autxo,butxo,&Q); - if ( (qprice= LP_quote_validate(autxo,butxo,&Q,0)) <= SMALLVAL ) + LP_abutxo_set(autxo,butxo,qp); + if ( (qprice= LP_quote_validate(autxo,butxo,qp,0)) <= SMALLVAL ) { - LP_availableset(Q.desttxid,Q.vout); - LP_availableset(Q.feetxid,Q.feevout); - LP_aliceid(Q.tradeid,Q.aliceid,"error4",0,0); + LP_availableset(qp->desttxid,qp->vout); + LP_availableset(qp->feetxid,qp->feevout); + LP_aliceid(qp->tradeid,qp->aliceid,"error4",0,0); printf("quote validate error %.0f\n",qprice); return(clonestr("{\"error\":\"quote validation error\"}")); } - if ( LP_myprice(&bid,&ask,Q.srccoin,Q.destcoin) <= SMALLVAL || bid <= SMALLVAL ) + if ( LP_myprice(&bid,&ask,qp->srccoin,qp->destcoin) <= SMALLVAL || bid <= SMALLVAL ) { - printf("this node has no price for %s/%s (%.8f %.8f)\n",Q.destcoin,Q.srccoin,bid,ask); - LP_availableset(Q.desttxid,Q.vout); - LP_availableset(Q.feetxid,Q.feevout); - LP_aliceid(Q.tradeid,Q.aliceid,"error5",0,0); + printf("this node has no price for %s/%s (%.8f %.8f)\n",qp->destcoin,qp->srccoin,bid,ask); + LP_availableset(qp->desttxid,qp->vout); + LP_availableset(qp->feetxid,qp->feevout); + LP_aliceid(qp->tradeid,qp->aliceid,"error5",0,0); return(clonestr("{\"error\":\"no price set\"}")); } - //LP_RTmetrics_update(Q.srccoin,Q.destcoin); - printf("%s/%s bid %.8f ask %.8f values %.8f %.8f\n",Q.srccoin,Q.destcoin,bid,ask,dstr(butxo->payment.value),dstr(butxo->deposit.value)); + //LP_RTmetrics_update(qp->srccoin,qp->destcoin); + printf("%s/%s bid %.8f ask %.8f values %.8f %.8f\n",qp->srccoin,qp->destcoin,bid,ask,dstr(butxo->payment.value),dstr(butxo->deposit.value)); price = bid; - if ( (coin= LP_coinfind(Q.destcoin)) == 0 ) + if ( (coin= LP_coinfind(qp->destcoin)) == 0 ) { - LP_aliceid(Q.tradeid,Q.aliceid,"error6",0,0); + LP_aliceid(qp->tradeid,qp->aliceid,"error6",0,0); 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 ) + qp->privkey = LP_privkey(qp->destaddr,coin->taddr); + if ( bits256_nonz(qp->privkey) != 0 )//&& qp->quotetime >= qp->timestamp-3 ) { retjson = cJSON_CreateObject(); - if ( (swap= LP_swapinit(0,0,Q.privkey,&Q.R,&Q,LP_dynamictrust(Q.srchash,LP_kmdvalue(Q.srccoin,Q.satoshis)) > 0)) == 0 ) + if ( (swap= LP_swapinit(0,0,qp->privkey,&qp->R,qp,LP_dynamictrust(qp->srchash,LP_kmdvalue(qp->srccoin,qp->satoshis)) > 0)) == 0 ) { jaddstr(retjson,"error","couldnt swapinit"); - LP_availableset(Q.desttxid,Q.vout); - LP_availableset(Q.feetxid,Q.feevout); - LP_aliceid(Q.tradeid,Q.aliceid,"error7",Q.R.requestid,Q.R.quoteid); + LP_availableset(qp->desttxid,qp->vout); + LP_availableset(qp->feetxid,qp->feevout); + LP_aliceid(qp->tradeid,qp->aliceid,"error7",qp->R.requestid,qp->R.quoteid); return(jprint(retjson,1)); } - if ( (pairstr= jstr(argjson,"pair")) == 0 || (pairsock= nn_socket(AF_SP,NN_PAIR)) < 0 ) + if ( pairstr == 0 || pairstr[0] == 0 || (pairsock= nn_socket(AF_SP,NN_PAIR)) < 0 ) { - LP_aliceid(Q.tradeid,Q.aliceid,"error8",Q.R.requestid,Q.R.quoteid); + LP_aliceid(qp->tradeid,qp->aliceid,"error8",qp->R.requestid,qp->R.quoteid); jaddstr(retjson,"error","couldnt create pairsock"); } else if ( nn_connect(pairsock,pairstr) >= 0 ) @@ -668,44 +667,44 @@ char *LP_connectedalice(cJSON *argjson) // alice //timeout = 1; //nn_setsockopt(pairsock,NN_SOL_SOCKET,NN_SNDTIMEO,&timeout,sizeof(timeout)); //nn_setsockopt(pairsock,NN_SOL_SOCKET,NN_RCVTIMEO,&timeout,sizeof(timeout)); - swap->tradeid = Q.tradeid; + swap->tradeid = qp->tradeid; swap->N.pair = pairsock; //autxo->S.swap = swap; //swap->utxo = autxo; - LP_aliceid(Q.tradeid,Q.aliceid,"started",Q.R.requestid,Q.R.quoteid); + LP_aliceid(qp->tradeid,qp->aliceid,"started",qp->R.requestid,qp->R.quoteid); printf("alice pairstr.(%s) pairsock.%d\n",pairstr,pairsock); if ( OS_thread_create(malloc(sizeof(pthread_t)),NULL,(void *)LP_aliceloop,(void *)swap) == 0 ) { - retjson = LP_quotejson(&Q); + retjson = LP_quotejson(qp); jaddstr(retjson,"result","success"); - //jaddnum(retjson,"requestid",Q.R.requestid); - //jaddnum(retjson,"quoteid",Q.R.quoteid); + //jaddnum(retjson,"requestid",qp->R.requestid); + //jaddnum(retjson,"quoteid",qp->R.quoteid); } else { - LP_aliceid(Q.tradeid,Q.aliceid,"error9",Q.R.requestid,Q.R.quoteid); + LP_aliceid(qp->tradeid,qp->aliceid,"error9",qp->R.requestid,qp->R.quoteid); jaddstr(retjson,"error","couldnt aliceloop"); } } else { - LP_aliceid(Q.tradeid,Q.aliceid,"error10",Q.R.requestid,Q.R.quoteid); + LP_aliceid(qp->tradeid,qp->aliceid,"error10",qp->R.requestid,qp->R.quoteid); printf("connect error %s\n",nn_strerror(nn_errno())); } printf("connected result.(%s)\n",jprint(retjson,0)); if ( jobj(retjson,"error") != 0 ) { - LP_availableset(Q.desttxid,Q.vout); - LP_availableset(Q.feetxid,Q.feevout); + LP_availableset(qp->desttxid,qp->vout); + LP_availableset(qp->feetxid,qp->feevout); } return(jprint(retjson,1)); } else { - LP_availableset(Q.desttxid,Q.vout); - LP_availableset(Q.feetxid,Q.feevout); - LP_aliceid(Q.tradeid,Q.aliceid,"error11",0,0); - printf("no privkey found coin.%s %s taddr.%u\n",Q.destcoin,Q.destaddr,coin->taddr); + LP_availableset(qp->desttxid,qp->vout); + LP_availableset(qp->feetxid,qp->feevout); + LP_aliceid(qp->tradeid,qp->aliceid,"error11",0,0); + printf("no privkey found coin.%s %s taddr.%u\n",qp->destcoin,qp->destaddr,coin->taddr); return(clonestr("{\"error\",\"no privkey\"}")); } } @@ -802,12 +801,17 @@ int32_t LP_validSPV(char *symbol,char *coinaddr,bits256 txid,int32_t vout) return(0); } +void LP_tradecommandQ(struct LP_quoteinfo *qp,char *pairstr) +{ + +} + int32_t LP_tradecommand(void *ctx,char *myipaddr,int32_t pubsock,cJSON *argjson,uint8_t *data,int32_t datalen) { + int32_t Qtrades = 0; char *method,*msg,*retstr,str[65]; int32_t DEXselector = 0; uint64_t aliceid; cJSON *retjson; double qprice,range,bestprice,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 r,counter,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) ) { - // LP_checksig LP_quoteparse(&Q,argjson); LP_requestinit(&Q.R,Q.srchash,Q.desthash,Q.srccoin,Q.satoshis-Q.txfee,Q.destcoin,Q.destsatoshis-Q.desttxfee,Q.timestamp,Q.quotetime,DEXselector); LP_tradecommand_log(argjson); @@ -824,38 +828,44 @@ int32_t LP_tradecommand(void *ctx,char *myipaddr,int32_t pubsock,cJSON *argjson, { bestprice = LP_bob_competition(&counter,aliceid,qprice,1); //printf("%s lag %ld: aliceid.%llu price %.8f -> bestprice %.8f Alice max %.8f\n",jprint(argjson,0),Q.quotetime - (time(NULL)-20),(long long)aliceid,qprice,bestprice,LP_Alicemaxprice); - if ( LP_Alicemaxprice == 0. ) - return(retval); - if ( bits256_nonz(LP_Alicedestpubkey) != 0 ) + if ( 0 ) { - if (bits256_cmp(LP_Alicedestpubkey,Q.srchash) != 0 ) - { - printf("got reserved response from different node %s\n",bits256_str(str,Q.srchash)); + if ( LP_Alicemaxprice == 0. ) return(retval); - } else printf("got reserved response from destpubkey %s\n",bits256_str(str,Q.srchash)); + if ( bits256_nonz(LP_Alicedestpubkey) != 0 ) + { + if (bits256_cmp(LP_Alicedestpubkey,Q.srchash) != 0 ) + { + printf("got reserved response from different node %s\n",bits256_str(str,Q.srchash)); + return(retval); + } else printf("got reserved response from destpubkey %s\n",bits256_str(str,Q.srchash)); + } } if ( bits256_cmp(G.LP_mypub25519,Q.desthash) == 0 && bits256_cmp(G.LP_mypub25519,Q.srchash) != 0 && Q.quotetime > time(NULL)-20 && LP_alice_eligible(Q.quotetime) > 0 ) { - printf("alice %s received RESERVED.(%s)\n",bits256_str(str,G.LP_mypub25519),jprint(argjson,0)); - if ( (qprice= LP_quote_validate(autxo,butxo,&Q,0)) <= SMALLVAL ) - { - printf("reserved quote validate error %.0f\n",qprice); - return(retval); - } - if ( LP_validSPV(Q.srccoin,Q.coinaddr,Q.txid,Q.vout) < 0 ) + if ( Qtrades == 0 ) { - printf("%s src %s failed SPV check\n",Q.srccoin,bits256_str(str,Q.txid)); - return(retval); - } - else if ( LP_validSPV(Q.srccoin,Q.coinaddr,Q.txid2,Q.vout2) < 0 ) - { - printf("%s src2 %s failed SPV check\n",Q.srccoin,bits256_str(str,Q.txid2)); - return(retval); - } - LP_aliceid(Q.tradeid,Q.aliceid,"reserved",0,0); - if ( (retstr= LP_quotereceived(argjson)) != 0 ) - free(retstr); - LP_reserved(ctx,myipaddr,pubsock,&Q); + printf("alice %s received RESERVED.(%s)\n",bits256_str(str,G.LP_mypub25519),jprint(argjson,0)); + if ( (qprice= LP_quote_validate(autxo,butxo,&Q,0)) <= SMALLVAL ) + { + printf("reserved quote validate error %.0f\n",qprice); + return(retval); + } + if ( LP_validSPV(Q.srccoin,Q.coinaddr,Q.txid,Q.vout) < 0 ) + { + printf("%s src %s failed SPV check\n",Q.srccoin,bits256_str(str,Q.txid)); + return(retval); + } + else if ( LP_validSPV(Q.srccoin,Q.coinaddr,Q.txid2,Q.vout2) < 0 ) + { + printf("%s src2 %s failed SPV check\n",Q.srccoin,bits256_str(str,Q.txid2)); + return(retval); + } + LP_aliceid(Q.tradeid,Q.aliceid,"reserved",0,0); + if ( (retstr= LP_quotereceived(argjson)) != 0 ) + free(retstr); + LP_reserved(ctx,myipaddr,pubsock,&Q); + } else LP_tradecommandQ(&Q,jstr(argjson,"pairstr")); } return(retval); } @@ -864,24 +874,27 @@ int32_t LP_tradecommand(void *ctx,char *myipaddr,int32_t pubsock,cJSON *argjson, bestprice = LP_bob_competition(&counter,aliceid,qprice,1000); if ( bits256_cmp(G.LP_mypub25519,Q.desthash) == 0 && bits256_cmp(G.LP_mypub25519,Q.srchash) != 0 ) { - if ( (qprice= LP_quote_validate(autxo,butxo,&Q,0)) <= SMALLVAL ) - { - printf("quote validate error %.0f\n",qprice); - return(retval); - } - if ( LP_validSPV(Q.srccoin,Q.coinaddr,Q.txid,Q.vout) < 0 ) - { - printf("%s src %s failed SPV check\n",Q.srccoin,bits256_str(str,Q.txid)); - return(retval); - } - else if (LP_validSPV(Q.srccoin,Q.coinaddr,Q.txid2,Q.vout2) < 0 ) + if ( Qtrades == 0 ) { - printf("%s src2 %s failed SPV check\n",Q.srccoin,bits256_str(str,Q.txid2)); - return(retval); - } - //printf("alice %s received CONNECTED.(%s)\n",bits256_str(str,G.LP_mypub25519),jprint(argjson,0)); - if ( (retstr= LP_connectedalice(argjson)) != 0 ) - free(retstr); + if ( (qprice= LP_quote_validate(autxo,butxo,&Q,0)) <= SMALLVAL ) + { + printf("quote validate error %.0f\n",qprice); + return(retval); + } + if ( LP_validSPV(Q.srccoin,Q.coinaddr,Q.txid,Q.vout) < 0 ) + { + printf("%s src %s failed SPV check\n",Q.srccoin,bits256_str(str,Q.txid)); + return(retval); + } + else if (LP_validSPV(Q.srccoin,Q.coinaddr,Q.txid2,Q.vout2) < 0 ) + { + printf("%s src2 %s failed SPV check\n",Q.srccoin,bits256_str(str,Q.txid2)); + return(retval); + } + //printf("alice %s received CONNECTED.(%s)\n",bits256_str(str,G.LP_mypub25519),jprint(argjson,0)); + if ( (retstr= LP_connectedalice(&Q,jstr(argjson,"pairstr"))) != 0 ) + free(retstr); + } else LP_tradecommandQ(&Q,jstr(argjson,"pairstr")); } return(retval); } @@ -891,6 +904,11 @@ int32_t LP_tradecommand(void *ctx,char *myipaddr,int32_t pubsock,cJSON *argjson, //printf("this node has no price for %s/%s\n",Q.srccoin,Q.destcoin); return(retval); } + if ( Qtrades != 0 ) + { + LP_tradecommandQ(&Q,jstr(argjson,"pairstr")); + return(retval); + } price = ask; //printf("MYPRICE %s/%s %.8f vs qprice %.8f\n",Q.srccoin,Q.destcoin,price,qprice); if ( LP_validSPV(Q.destcoin,Q.destaddr,Q.desttxid,Q.destvout) < 0 ) @@ -948,7 +966,7 @@ int32_t LP_tradecommand(void *ctx,char *myipaddr,int32_t pubsock,cJSON *argjson, Q.vout = butxo->payment.vout; Q.txid2 = butxo->deposit.txid; Q.vout2 = butxo->deposit.vout; - Q.satoshis = butxo->S.satoshis; + Q.satoshis = butxo->swap_satoshis; Q.quotetime = (uint32_t)time(NULL); printf("found %.8f -> %.8f newprice %.8f vs ask %.8f += %.8f qprice %.8f\n",dstr(Q.satoshis),dstr(Q.destsatoshis),(double)Q.destsatoshis/Q.satoshis,ask,price,qprice); } @@ -1017,7 +1035,7 @@ int32_t LP_tradecommand(void *ctx,char *myipaddr,int32_t pubsock,cJSON *argjson, retval = 4; if ( LP_reservation_check(Q.txid,Q.vout,Q.desthash) == 0 && LP_reservation_check(Q.txid2,Q.vout2,Q.desthash) == 0 ) { - LP_connectstartbob(ctx,pubsock,argjson,Q.srccoin,Q.destcoin,qprice,&Q); + LP_connectstartbob(ctx,pubsock,Q.srccoin,Q.destcoin,qprice,&Q); return(retval); } else printf("connect message from non-reserved (%s)\n",jprint(argjson,0)); } @@ -1073,18 +1091,18 @@ char *LP_autobuy(void *ctx,char *myipaddr,int32_t mypubsock,char *base,char *rel 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->S.satoshis)); - if ( destsatoshis - desttxfee < autxo->S.satoshis ) + //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 ) { destsatoshis -= desttxfee; - autxo->S.satoshis = destsatoshis; - //printf("first path dest %.8f from %.8f\n",dstr(destsatoshis),dstr(autxo->S.satoshis)); + autxo->swap_satoshis = destsatoshis; + //printf("first path dest %.8f from %.8f\n",dstr(destsatoshis),dstr(autxo->swap_satoshis)); } - else if ( autxo->S.satoshis - desttxfee < destsatoshis ) + else if ( autxo->swap_satoshis - desttxfee < destsatoshis ) { - autxo->S.satoshis -= desttxfee; - destsatoshis = autxo->S.satoshis; - printf("second path dest %.8f from %.8f\n",dstr(destsatoshis),dstr(autxo->S.satoshis)); + autxo->swap_satoshis -= desttxfee; + destsatoshis = autxo->swap_satoshis; + printf("second path dest %.8f from %.8f\n",dstr(destsatoshis),dstr(autxo->swap_satoshis)); } if ( destsatoshis < (autxo->payment.value / LP_MINCLIENTVOL) || autxo->payment.value < desttxfee*LP_MINSIZE_TXFEEMULT ) { diff --git a/iguana/exchanges/LP_privkey.c b/iguana/exchanges/LP_privkey.c new file mode 100644 index 000000000..ea98b8079 --- /dev/null +++ b/iguana/exchanges/LP_privkey.c @@ -0,0 +1,351 @@ + +/****************************************************************************** + * Copyright © 2014-2017 The SuperNET Developers. * + * * + * See the AUTHORS, DEVELOPER-AGREEMENT and LICENSE files at * + * the top-level directory of this distribution for the individual copyright * + * holder information and the developer policies on copyright and licensing. * + * * + * Unless otherwise agreed in a custom licensing agreement, no part of the * + * SuperNET software, including this file may be copied, modified, propagated * + * or distributed except according to the terms contained in the LICENSE file * + * * + * Removal or modification of this copyright notice is prohibited. * + * * + ******************************************************************************/ +// +// LP_utxos.c +// marketmaker +// + +int32_t LP_privkey_init(int32_t mypubsock,struct iguana_info *coin,bits256 myprivkey,bits256 mypub) +{ + int32_t enable_utxos = 0; + char *script,destaddr[64]; cJSON *array,*item; bits256 txid,deposittxid; int32_t used,i,flag=0,height,n,cmpflag,iambob,vout,depositvout; uint64_t *values=0,satoshis,txfee,biggerval,value,total = 0; int64_t targetval; //struct LP_utxoinfo *utxo; + if ( coin == 0 || (IAMLP == 0 && coin->inactive != 0) ) + { + //printf("coin not active\n"); + return(0); + } + if ( coin->privkeydepth > 0 ) + return(0); + coin->privkeydepth++; + LP_address(coin,coin->smartaddr); + //if ( coin->inactive == 0 ) + // LP_listunspent_issue(coin->symbol,coin->smartaddr,0); + array = LP_listunspent(coin->symbol,coin->smartaddr); + if ( array != 0 ) + { + txfee = LP_txfeecalc(coin,0,0); + if ( is_cJSON_Array(array) != 0 && (n= cJSON_GetArraySize(array)) > 0 ) + { + coin->numutxos = n; + //printf("LP_privkey_init %s %d\n",coin->symbol,n); + for (iambob=0; iambob<=1; iambob++) + { + if ( iambob == 0 ) + values = calloc(n,sizeof(*values)); + else memset(values,0,n * sizeof(*values)); + used = 0; + for (i=0; isymbol,txid,vout); + if ( satoshis != 0 && satoshis != value ) + printf("%s %s privkey_init value %.8f vs %.8f (%s) %.8f %.8f\n",coin->symbol,coin->smartaddr,dstr(satoshis),dstr(value),jprint(item,0),jdouble(item,"amount"),jdouble(item,"interest")); + if ( coin->electrum != 0 || LP_inventory_prevent(iambob,coin->symbol,txid,vout) == 0 )//&& height > 0 ) + { + values[i] = satoshis; + //flag += LP_address_utxoadd(coin,destaddr,txid,vout,satoshis,height,-1); + } else used++; + } + //printf("array.%d\n",n); + while ( used < n-1 ) + { + //for (i=0; i= 0 ) + { + item = jitem(array,i); + if ( coin->electrum == 0 ) + { + deposittxid = jbits256(item,"txid"); + depositvout = juint(item,"vout"); + script = jstr(item,"scriptPubKey"); + } + else + { + deposittxid = jbits256(item,"tx_hash"); + depositvout = juint(item,"tx_pos"); + script = coin->smartaddr; + } + biggerval = values[i]; + values[i] = 0, used++; + if ( iambob == 0 ) + targetval = (biggerval / 776) + txfee; + else targetval = (biggerval / 9) * 8 + 2*txfee; + if ( targetval < txfee*2 ) + targetval = txfee*2; + //printf("iambob.%d i.%d deposit %.8f min %.8f target %.8f\n",iambob,i,dstr(biggerval),dstr((1+LP_MINSIZE_TXFEEMULT)*txfee),dstr(targetval)); + if ( biggerval < (1+LP_MINSIZE_TXFEEMULT)*txfee ) + continue; + i = -1; + if ( iambob != 0 ) + { + if ( (i= LP_nearestvalue(iambob,values,n,targetval)) < 0 ) + targetval /= 4; + if ( targetval < txfee*(1+LP_MINSIZE_TXFEEMULT) ) + continue; + } + if ( i >= 0 || (i= LP_nearestvalue(iambob,values,n,targetval)) >= 0 ) + { + //printf("iambob.%d i.%d %.8f target %.8f\n",iambob,i,dstr(biggerval),dstr(targetval)); + item = jitem(array,i); + cmpflag = 0; + if ( coin->electrum == 0 ) + { + txid = jbits256(item,"txid"); + vout = juint(item,"vout"); + if ( jstr(item,"scriptPubKey") != 0 && strcmp(script,jstr(item,"scriptPubKey")) == 0 ) + cmpflag = 1; + } + else + { + txid = jbits256(item,"tx_hash"); + vout = juint(item,"tx_pos"); + cmpflag = 1; + } + if ( cmpflag != 0 ) + { + value = values[i]; + values[i] = 0, used++; + /*portable_mutex_lock(&LP_UTXOmutex); + if ( iambob != 0 ) + { + if ( (utxo= LP_utxoadd(1,coin->symbol,txid,vout,value,deposittxid,depositvout,biggerval,coin->smartaddr,mypub,LP_gui,G.LP_sessionid,value)) != 0 ) + { + } + } + else + { + //printf("call utxoadd\n"); + if ( (utxo= LP_utxoadd(0,coin->symbol,deposittxid,depositvout,biggerval,txid,vout,value,coin->smartaddr,mypub,LP_gui,G.LP_sessionid,biggerval)) != 0 ) + { + } + } + portable_mutex_unlock(&LP_UTXOmutex);*/ + total += value; + } // else printf("scriptmismatch.(%s) vs %s\n",script,jprint(item,0)); + } //else printf("nothing near i.%d\n",i); + } else break; + } + if ( enable_utxos == 0 ) + break; + } + } + free_json(array); + if ( 0 && flag != 0 ) + LP_postutxos(coin->symbol,coin->smartaddr); + } + if ( values != 0 ) + free(values); + if ( coin->privkeydepth > 0 ) + coin->privkeydepth--; + //printf("privkey.%s %.8f\n",symbol,dstr(total)); + return(flag); +} + +char *LP_secretaddresses(void *ctx,char *prefix,char *passphrase,int32_t n,uint8_t taddr,uint8_t pubtype) +{ + int32_t i; uint8_t tmptype,pubkey33[33],rmd160[20]; char output[777*45],str[65],str2[65],buf[8192],wifstr[128],coinaddr[64]; bits256 checkprivkey,privkey,pubkey; cJSON *retjson; + retjson = cJSON_CreateObject(); + if ( prefix == 0 || prefix[0] == 0 ) + prefix = "secretaddress"; + if ( passphrase == 0 || passphrase[0] == 0 ) + passphrase = "password"; + if ( n <= 0 ) + n = 16; + else if ( n > 777 ) + n = 777; + conv_NXTpassword(privkey.bytes,pubkey.bytes,(uint8_t *)passphrase,(int32_t)strlen(passphrase)); + bitcoin_priv2pub(ctx,pubkey33,coinaddr,privkey,taddr,pubtype); + printf("generator (%s) secrets.[%d] <%s> t.%u p.%u\n",coinaddr,n,passphrase,taddr,pubtype); + sprintf(output,"\"addresses\":["); + for (i=0; i %s vs %s?\n",wifstr,bits256_str(str,privkey),bits256_str(str2,checkprivkey)); + free_json(retjson); + return(clonestr("{\"error\":\"couldnt validate wifstr\"}")); + } + else if ( tmptype != pubtype ) + { + printf("checktype.%d != pubtype.%d\n",tmptype,pubtype); + free_json(retjson); + return(clonestr("{\"error\":\"couldnt validate pubtype\"}")); + } + jaddstr(retjson,coinaddr,wifstr); + sprintf(output+strlen(output),"\\\"%s\\\"%c ",coinaddr,ibytes,(uint8_t *)passphrase,(int32_t)strlen(passphrase)); + //vcalc_sha256(0,checkkey.bytes,(uint8_t *)passphrase,(int32_t)strlen(passphrase)); + //printf("SHA256.(%s) ",bits256_str(pstr,checkkey)); + //printf("privkey.(%s)\n",bits256_str(pstr,privkey)); + } + else + { + bitcoin_wif2priv(coin->wiftaddr,&tmptype,&privkey,wifstr); + if ( 0 ) + { + char str[65],str2[65]; + checkkey = iguana_wif2privkey(wifstr); + if ( bits256_cmp(checkkey,privkey) != 0 ) + printf("WIF.(%s) -> %s or %s?\n",wifstr,bits256_str(str,privkey),bits256_str(str2,checkkey)); + } + } + privkey.bytes[0] &= 248, privkey.bytes[31] &= 127, privkey.bytes[31] |= 64; + bitcoin_priv2pub(ctx,coin->pubkey33,coin->smartaddr,privkey,coin->taddr,coin->pubtype); + if ( coin->counter == 0 ) + { + coin->counter++; + memcpy(G.LP_pubsecp,coin->pubkey33,33); + bitcoin_priv2wif(coin->wiftaddr,tmpstr,privkey,coin->wiftype); + bitcoin_addr2rmd160(coin->taddr,&tmptype,G.LP_myrmd160,coin->smartaddr); + LP_privkeyadd(privkey,G.LP_myrmd160); + G.LP_privkey = privkey; + if ( 0 && (coin->pubtype != 60 || strcmp(coin->symbol,"KMD") == 0) ) + printf("%s (%s) %d wif.(%s) (%s)\n",coin->symbol,coin->smartaddr,coin->pubtype,tmpstr,passphrase); + if ( G.counter++ == 0 ) + { + bitcoin_priv2wif(coin->wiftaddr,G.USERPASS_WIFSTR,privkey,188); + bitcoin_wif2priv(coin->wiftaddr,&tmptype,&checkkey,G.USERPASS_WIFSTR); + if ( bits256_cmp(checkkey,privkey) != 0 ) + { + char str[65],str2[65]; + printf("FATAL ERROR converting USERPASS_WIFSTR %s -> %s != %s\n",G.USERPASS_WIFSTR,bits256_str(str,checkkey),bits256_str(str2,privkey)); + exit(-1); + } + conv_NXTpassword(userpass.bytes,pubkeyp->bytes,(uint8_t *)G.USERPASS_WIFSTR,(int32_t)strlen(G.USERPASS_WIFSTR)); + userpub = curve25519(userpass,curve25519_basepoint9()); + printf("userpass.(%s)\n",bits256_str(G.USERPASS,userpub)); + } + } + if ( coin->importedprivkey == 0 && coin->electrum == 0 && coin->userpass[0] != 0 && LP_getheight(coin) > 0 ) + { + LP_listunspent_issue(coin->symbol,coin->smartaddr,0); + if ( (retjson= LP_importprivkey(coin->symbol,tmpstr,coin->smartaddr,-1)) != 0 ) + { + if ( jobj(retjson,"error") != 0 ) + { + printf("cant importprivkey.%s -> (%s), abort session\n",coin->symbol,jprint(retjson,1)); + exit(-1); + } + free_json(retjson); + } + coin->importedprivkey = (uint32_t)time(NULL); + } + vcalc_sha256(0,checkkey.bytes,privkey.bytes,sizeof(privkey)); + checkkey.bytes[0] &= 248, checkkey.bytes[31] &= 127, checkkey.bytes[31] |= 64; + G.LP_mypub25519 = *pubkeyp = curve25519(checkkey,curve25519_basepoint9()); + G.LP_mypriv25519 = checkkey; + LP_pubkeyadd(G.LP_mypub25519); + return(privkey); +} + +void LP_privkey_updates(void *ctx,int32_t pubsock,char *passphrase) +{ + struct iguana_info *coin,*tmp; bits256 pubkey,privkey; uint8_t pubkey33[33]; int32_t initonly; + initonly = (passphrase != 0); + memset(privkey.bytes,0,sizeof(privkey)); + memset(pubkey.bytes,0,sizeof(pubkey)); + //printf("Total coins: %d\n", HASH_COUNT(LP_coins)); + //int num_iter = 0; + HASH_ITER(hh,LP_coins,coin,tmp) + { + //printf("LP_privkey_updates [%02d / %02d]\n", num_iter++, HASH_COUNT(LP_coins)); + if ( initonly != 0 ) + { + coin->counter = 0; + memset(coin->smartaddr,0,sizeof(coin->smartaddr)); + if ( bits256_nonz(privkey) == 0 || coin->smartaddr[0] == 0 ) + privkey = LP_privkeycalc(ctx,pubkey33,&pubkey,coin,passphrase,""); + } + //printf("i.%d of %d\n",i,LP_numcoins); + else if ( IAMLP == 0 || coin->inactive == 0 ) + { + //printf("from updates %s\n",coin->symbol); + if ( 0 && LP_privkey_init(pubsock,coin,G.LP_privkey,G.LP_mypub25519) == 0 && (LP_rand() % 10) == 0 ) + { + //LP_postutxos(coin->symbol,coin->smartaddr); + } + } + } +} + +int32_t LP_passphrase_init(char *passphrase,char *gui) +{ + static void *ctx; int32_t counter; //iambob,; struct LP_utxoinfo *utxo,*tmp; + if ( ctx == 0 ) + ctx = bitcoin_ctx(); + if ( G.LP_pendingswaps != 0 ) + return(-1); + G.initializing = 1; + if ( gui == 0 ) + gui = "cli"; + counter = G.USERPASS_COUNTER; + while ( G.waiting == 0 ) + { + printf("waiting for G.waiting\n"); + sleep(5); + } + /*for (iambob=0; iambob<2; iambob++) + { + if ( G.LP_utxoinfos[iambob] != 0 ) + { + HASH_ITER(hh,G.LP_utxoinfos[iambob],utxo,tmp) + { + HASH_DELETE(hh,G.LP_utxoinfos[iambob],utxo); + //free(utxo); + } + } + if ( G.LP_utxoinfos2[iambob] != 0 ) + { + G.LP_utxoinfos2[iambob] = 0; + //HASH_ITER(hh,G.LP_utxoinfos2[iambob],utxo,tmp) + //{ + // HASH_DELETE(hh,G.LP_utxoinfos2[iambob],utxo); + // free(utxo); + //} + } + }*/ + memset(&G,0,sizeof(G)); + LP_privkey_updates(ctx,LP_mypubsock,passphrase); + init_hexbytes_noT(G.LP_myrmd160str,G.LP_myrmd160,20); + G.LP_sessionid = (uint32_t)time(NULL); + safecopy(G.gui,gui,sizeof(G.gui)); + G.USERPASS_COUNTER = counter; + G.initializing = 0; + return(0); +} + + diff --git a/iguana/exchanges/LP_remember.c b/iguana/exchanges/LP_remember.c index 4755d9591..0aebcbcd1 100644 --- a/iguana/exchanges/LP_remember.c +++ b/iguana/exchanges/LP_remember.c @@ -1163,6 +1163,8 @@ cJSON *basilisk_remember(int64_t *KMDtotals,int64_t *BTCtotals,uint32_t requesti if ( (fp= fopen(fname,"wb")) != 0 ) { jaddstr(item,"method","tradestatus"); + if ( rswap.finishtime == 0 ) + rswap.finishtime = (uint32_t)time(NULL); jaddnum(item,"finishtime",rswap.finishtime); jaddstr(item,"gui",G.gui); //jaddbits256(item,"srchash",rswap.Q.srchash); diff --git a/iguana/exchanges/LP_rpc.c b/iguana/exchanges/LP_rpc.c index b47319391..cd5c89461 100644 --- a/iguana/exchanges/LP_rpc.c +++ b/iguana/exchanges/LP_rpc.c @@ -723,6 +723,26 @@ cJSON *LP_listreceivedbyaddress(char *symbol,char *coinaddr) } else return(electrum_address_gethistory(symbol,coin->electrum,&retjson,coinaddr)); } +int64_t LP_listunspent_parseitem(struct iguana_info *coin,bits256 *txidp,int32_t *voutp,int32_t *heightp,cJSON *item) +{ + int64_t satoshis = 0; + if ( coin->electrum == 0 ) + { + *txidp = jbits256(item,"txid"); + *voutp = juint(item,"vout"); + satoshis = LP_value_extract(item,0); + *heightp = LP_txheight(coin,*txidp); + } + else + { + *txidp = jbits256(item,"tx_hash"); + *voutp = juint(item,"tx_pos"); + satoshis = j64bits(item,"value"); + *heightp = jint(item,"height"); + } + return(satoshis); +} + 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; diff --git a/iguana/exchanges/LP_signatures.c b/iguana/exchanges/LP_signatures.c index fe309f6e5..5f6eab03c 100644 --- a/iguana/exchanges/LP_signatures.c +++ b/iguana/exchanges/LP_signatures.c @@ -357,63 +357,6 @@ return; } } -queue_t utxosQ; -struct LP_utxos_qitem { struct queueitem DL; cJSON *argjson; }; - -char *LP_postutxos_recv(cJSON *argjson) -{ - struct LP_utxos_qitem *uitem; struct iguana_info *coin; char *coinaddr,*symbol; bits256 utxoshash,pubkey; cJSON *obj; struct LP_pubkey_info *pubp; -printf("LP_postutxos_recv deprecated\n"); - pubkey = jbits256(argjson,"pubkey"); - pubp = LP_pubkeyfind(pubkey); - if ( pubp != 0 && pubp->numerrors > LP_MAXPUBKEY_ERRORS ) - return(clonestr("{\"error\":\"blacklisted\"}")); - if ( (coinaddr= jstr(argjson,"coinaddr")) != 0 && (symbol= jstr(argjson,"coin")) != 0 && (coin= LP_coinfind(symbol)) != 0 ) - { - if ( strcmp(coinaddr,coin->smartaddr) == 0 ) - { - //printf("ignore my utxo from external source %s %s\n",symbol,coinaddr); - return(clonestr("{\"result\":\"success\"}")); - } - } - if ( (obj= jobj(argjson,"utxos")) != 0 ) - { - utxoshash = LP_utxoshash_calc(obj); - //char str[65]; //printf("got utxoshash %s\n",bits256_str(str,utxoshash)); - if ( LP_utxos_sigcheck(juint(argjson,"timestamp"),jstr(argjson,"sig"),jstr(argjson,"pubsecp"),pubkey,utxoshash) == 0 ) - { - uitem = calloc(1,sizeof(*uitem)); - uitem->argjson = jduplicate(argjson); - queue_enqueue("utxosQ",&utxosQ,&uitem->DL); - return(clonestr("{\"result\":\"success\"}")); - } //else printf("valid utxos sig %s\n",bits256_str(str,pubp->pubkey)); - } - return(clonestr("{\"error\":\"sig failure\"}")); -} - -int32_t LP_utxosQ_process() -{ - struct LP_utxos_qitem *uitem; int32_t n; char *symbol,*coinaddr; struct LP_address *ap; struct iguana_info *coin; cJSON *array; - if ( (uitem= queue_dequeue(&utxosQ)) != 0 ) - { - //printf("LP_utxosQ_process.(%s)\n",jprint(uitem->argjson,0)); - if ( (coinaddr= jstr(uitem->argjson,"coinaddr")) != 0 && (symbol= jstr(uitem->argjson,"coin")) != 0 && (coin= LP_coinfind(symbol)) != 0 ) // addsig - { - if ( coin->electrum == 0 || (ap= LP_addressfind(coin,coinaddr)) != 0 ) - { - if ( (array= jarray(&n,uitem->argjson,"utxos")) != 0 ) - LP_unspents_array(coin,coinaddr,array); - } - else if ( (array= electrum_address_listunspent(symbol,coin->electrum,&array,coinaddr,1)) != 0 ) - free_json(array); - } - free_json(uitem->argjson); - free(uitem); - return(1); - } - return(0); -} - int32_t LP_price_sigcheck(uint32_t timestamp,char *sigstr,char *pubsecpstr,bits256 pubkey,char *base,char *rel,uint64_t price64) { static void *ctx; int32_t retval=-1; uint8_t pub33[33],pubsecp[33],sig[65]; bits256 sighash; struct LP_pubkey_info *pubp; diff --git a/iguana/exchanges/LP_statemachine.c b/iguana/exchanges/LP_statemachine.c index 92330e83a..61c1398ee 100644 --- a/iguana/exchanges/LP_statemachine.c +++ b/iguana/exchanges/LP_statemachine.c @@ -1797,6 +1797,77 @@ int32_t bitcoin_coinptrs(bits256 pubkey,struct iguana_info **bobcoinp,struct igu return(0); } +struct LP_utxoinfo *LP_utxopairfind(int32_t iambob,bits256 txid,int32_t vout,bits256 txid2,int32_t vout2) +{ + struct LP_utxoinfo *utxo=0; struct _LP_utxoinfo u; + if ( (utxo= LP_utxofind(iambob,txid,vout)) != 0 ) + { + u = (iambob != 0) ? utxo->deposit : utxo->fee; + if (vout2 == u.vout && bits256_cmp(u.txid,txid2) == 0 ) + return(utxo); + } + return(0); +} + +void LP_utxosetkey(uint8_t *key,bits256 txid,int32_t vout) +{ + memcpy(key,txid.bytes,sizeof(txid)); + memcpy(&key[sizeof(txid)],&vout,sizeof(vout)); +} + +struct LP_utxoinfo *_LP_utxofind(int32_t iambob,bits256 txid,int32_t vout) +{ + struct LP_utxoinfo *utxo=0; uint8_t key[sizeof(txid) + sizeof(vout)]; + LP_utxosetkey(key,txid,vout); + HASH_FIND(hh,G.LP_utxoinfos[iambob!=0],key,sizeof(key),utxo); + return(utxo); +} + +void _LP_utxo_delete(int32_t iambob,struct LP_utxoinfo *utxo) +{ + HASH_DELETE(hh,G.LP_utxoinfos[iambob],utxo); +} + +void _LP_utxo2_delete(int32_t iambob,struct LP_utxoinfo *utxo) +{ + HASH_DELETE(hh,G.LP_utxoinfos2[iambob],utxo); +} + +struct LP_utxoinfo *_LP_utxo2find(int32_t iambob,bits256 txid2,int32_t vout2) +{ + struct LP_utxoinfo *utxo=0; uint8_t key2[sizeof(txid2) + sizeof(vout2)]; + LP_utxosetkey(key2,txid2,vout2); + HASH_FIND(hh2,G.LP_utxoinfos2[iambob],key2,sizeof(key2),utxo); + return(utxo); +} + +struct LP_utxoinfo *LP_utxofind(int32_t iambob,bits256 txid,int32_t vout) +{ + struct LP_utxoinfo *utxo=0; + /*if ( iambob != 0 ) + { + printf("LP_utxofind deprecated iambob\n"); + return(0); + }*/ + portable_mutex_lock(&LP_utxomutex); + utxo = _LP_utxofind(iambob,txid,vout); + portable_mutex_unlock(&LP_utxomutex); + return(utxo); +} + +struct LP_utxoinfo *LP_utxo2find(int32_t iambob,bits256 txid2,int32_t vout2) +{ + struct LP_utxoinfo *utxo=0; + /*if ( iambob != 0 ) + { + printf("LP_utxo2find deprecated iambob\n"); + return(0); + }*/ + portable_mutex_lock(&LP_utxomutex); + utxo = _LP_utxo2find(iambob,txid2,vout2); + portable_mutex_unlock(&LP_utxomutex); + return(utxo); +} /*void basilisk_swap_purge(struct basilisk_swap *swap) { int32_t i,n; @@ -1850,6 +1921,14 @@ int32_t bitcoin_coinptrs(bits256 pubkey,struct iguana_info **bobcoinp,struct igu } } else return(retval);*/ +int32_t LP_isavailable(struct LP_utxoinfo *utxo) +{ + struct _LP_utxoinfo u; + u = (utxo->iambob != 0) ? utxo->deposit : utxo->fee; + if ( LP_allocated(utxo->payment.txid,utxo->payment.vout) == 0 && LP_allocated(u.txid,u.vout) == 0 ) + return(1); + else return(0); +} /*int32_t LP_priceping(int32_t pubsock,struct LP_utxoinfo *utxo,char *rel,double origprice) { double price,bid,ask; uint32_t now; cJSON *retjson; struct LP_quoteinfo Q; char *retstr; @@ -1911,6 +1990,90 @@ int32_t bitcoin_coinptrs(bits256 pubkey,struct iguana_info **bobcoinp,struct igu if ( LP_ismine(utxo) > 0 && strcmp(utxo->coin,base) == 0 ) LP_priceping(LP_mypubsock,utxo,rel,price * LP_profitratio); }*/ + +int32_t LP_ismine(struct LP_utxoinfo *utxo) +{ + if ( utxo != 0 && bits256_cmp(utxo->pubkey,G.LP_mypub25519) == 0 ) + return(1); + else return(0); +} + +queue_t utxosQ; +struct LP_utxos_qitem { struct queueitem DL; cJSON *argjson; }; + +char *LP_postutxos_recv(cJSON *argjson) +{ + struct LP_utxos_qitem *uitem; struct iguana_info *coin; char *coinaddr,*symbol; bits256 utxoshash,pubkey; cJSON *obj; struct LP_pubkey_info *pubp; + printf("LP_postutxos_recv deprecated\n"); + pubkey = jbits256(argjson,"pubkey"); + pubp = LP_pubkeyfind(pubkey); + if ( pubp != 0 && pubp->numerrors > LP_MAXPUBKEY_ERRORS ) + return(clonestr("{\"error\":\"blacklisted\"}")); + if ( (coinaddr= jstr(argjson,"coinaddr")) != 0 && (symbol= jstr(argjson,"coin")) != 0 && (coin= LP_coinfind(symbol)) != 0 ) + { + if ( strcmp(coinaddr,coin->smartaddr) == 0 ) + { + //printf("ignore my utxo from external source %s %s\n",symbol,coinaddr); + return(clonestr("{\"result\":\"success\"}")); + } + } + if ( (obj= jobj(argjson,"utxos")) != 0 ) + { + utxoshash = LP_utxoshash_calc(obj); + //char str[65]; //printf("got utxoshash %s\n",bits256_str(str,utxoshash)); + if ( LP_utxos_sigcheck(juint(argjson,"timestamp"),jstr(argjson,"sig"),jstr(argjson,"pubsecp"),pubkey,utxoshash) == 0 ) + { + uitem = calloc(1,sizeof(*uitem)); + uitem->argjson = jduplicate(argjson); + queue_enqueue("utxosQ",&utxosQ,&uitem->DL); + return(clonestr("{\"result\":\"success\"}")); + } //else printf("valid utxos sig %s\n",bits256_str(str,pubp->pubkey)); + } + return(clonestr("{\"error\":\"sig failure\"}")); +} + +int32_t LP_utxosQ_process() +{ + struct LP_utxos_qitem *uitem; int32_t n; char *symbol,*coinaddr; struct LP_address *ap; struct iguana_info *coin; cJSON *array; + if ( (uitem= queue_dequeue(&utxosQ)) != 0 ) + { + //printf("LP_utxosQ_process.(%s)\n",jprint(uitem->argjson,0)); + if ( (coinaddr= jstr(uitem->argjson,"coinaddr")) != 0 && (symbol= jstr(uitem->argjson,"coin")) != 0 && (coin= LP_coinfind(symbol)) != 0 ) // addsig + { + if ( coin->electrum == 0 || (ap= LP_addressfind(coin,coinaddr)) != 0 ) + { + if ( (array= jarray(&n,uitem->argjson,"utxos")) != 0 ) + LP_unspents_array(coin,coinaddr,array); + } + else if ( (array= electrum_address_listunspent(symbol,coin->electrum,&array,coinaddr,1)) != 0 ) + free_json(array); + } + free_json(uitem->argjson); + free(uitem); + return(1); + } + return(0); +} +else if ( strcmp(method,"postutxos") == 0 ) +return(LP_postutxos_recv(argjson)); + +void utxosQ_loop(void *myipaddr) +{ + strcpy(utxosQ_loop_stats.name,"utxosQ_loop"); + utxosQ_loop_stats.threshold = 5000.; + while ( 1 ) + { + LP_millistats_update(&utxosQ_loop_stats); + if ( LP_utxosQ_process() == 0 ) + usleep(50000); + } +} +if ( OS_thread_create(malloc(sizeof(pthread_t)),NULL,(void *)utxosQ_loop,(void *)myipaddr) != 0 ) +{ + printf("error launching utxosQ_loop for (%s)\n",myipaddr); + exit(-1); +} + /* bestprice = 0.; if ( (array= LP_tradecandidates(base)) != 0 ) @@ -2345,6 +2508,27 @@ char *LP_utxos(int32_t iambob,struct LP_peerinfo *mypeer,char *symbol,int32_t la } return(jprint(utxosjson,1)); } +int32_t LP_isunspent(struct LP_utxoinfo *utxo) +{ + struct LP_address_utxo *up; struct _LP_utxoinfo u; struct iguana_info *coin; + if ( (coin= LP_coinfind(utxo->coin)) == 0 ) + return(0); + if ( (up= LP_address_utxofind(coin,utxo->coinaddr,utxo->payment.txid,utxo->payment.vout)) != 0 && up->spendheight > 0 ) + { + utxo->T.spentflag = up->spendheight; + return(0); + } + u = (utxo->iambob != 0) ? utxo->deposit : utxo->fee; + if ( (up= LP_address_utxofind(coin,utxo->coinaddr,u.txid,u.vout)) != 0 && up->spendheight > 0 ) + { + utxo->T.spentflag = up->spendheight; + return(0); + } + if ( utxo != 0 && utxo->T.spentflag == 0 && LP_isavailable(utxo) > 0 ) + return(1); + else return(0); +} + void LP_utxo_clientpublish(struct LP_utxoinfo *utxo) { bits256 zero; char *msg; @@ -2494,6 +2678,466 @@ else jaddnum(bestitem,"maxprice",maxprice); jaddstr(bestitem,"status","no response to request"); } +uint32_t LP_allocated(bits256 txid,int32_t vout) +{ + struct LP_utxoinfo *utxo; + if ( (utxo= _LP_utxofind(0,txid,vout)) != 0 && LP_isavailable(utxo) == 0 ) + { + //char str[65]; printf("%s/v%d not available\n",bits256_str(str,txid),vout); + return(utxo); + } + if ( (utxo= _LP_utxo2find(0,txid,vout)) != 0 && LP_isavailable(utxo) == 0 ) + { + //char str[65]; printf("%s/v%d not available2\n",bits256_str(str,txid),vout); + return(utxo); + } + if ( (utxo= _LP_utxofind(1,txid,vout)) != 0 && LP_isavailable(utxo) == 0 ) + { + //char str[65]; printf("%s/v%d not available\n",bits256_str(str,txid),vout); + return(utxo); + } + if ( (utxo= _LP_utxo2find(1,txid,vout)) != 0 && LP_isavailable(utxo) == 0 ) + { + //char str[65]; printf("%s/v%d not available2\n",bits256_str(str,txid),vout); + return(utxo); + } + return(0); +} + +int32_t LP_isavailable(struct LP_utxoinfo *utxo) +{ + if ( time(NULL) > utxo->T.swappending ) + utxo->T.swappending = 0; + if ( utxo != 0 && utxo->T.swappending == 0 && utxo->S.swap == 0 ) + return(1); + else return(0); +} + +int32_t LP_utxoaddptrs(struct LP_utxoinfo *ptrs[],int32_t n,struct LP_utxoinfo *utxo) +{ + int32_t i; + for (i=0; ipayment.txid,refutxo->payment.vout)) != 0 && utxo != refutxo ) + n = LP_utxoaddptrs(ptrs,n,utxo); + if ( (utxo= _LP_utxo2find(iambob,refutxo->payment.txid,refutxo->payment.vout)) != 0 && utxo != refutxo ) + n = LP_utxoaddptrs(ptrs,n,utxo); + u = (refutxo->iambob != 0) ? refutxo->deposit : refutxo->fee; + if ( (utxo= _LP_utxofind(iambob,u.txid,u.vout)) != 0 && utxo != refutxo ) + n = LP_utxoaddptrs(ptrs,n,utxo); + if ( (utxo= _LP_utxo2find(iambob,u.txid,u.vout)) != 0 && utxo != refutxo ) + n = LP_utxoaddptrs(ptrs,n,utxo); + } + portable_mutex_unlock(&LP_utxomutex); + if ( 0 && n > 0 ) + printf("LP_utxocollisions n.%d\n",n); + return(n); +} + +int32_t _LP_availableset(struct LP_utxoinfo *utxo) +{ + int32_t flag = 0; + if ( utxo != 0 ) + { + if ( bits256_nonz(utxo->S.otherpubkey) != 0 ) + flag = 1, memset(&utxo->S.otherpubkey,0,sizeof(utxo->S.otherpubkey)); + if ( utxo->S.swap != 0 ) + flag = 1, utxo->S.swap = 0; + if ( utxo->T.swappending != 0 ) + flag = 1, utxo->T.swappending = 0; + return(flag); + } + return(0); +} + +void _LP_unavailableset(struct LP_utxoinfo *utxo,bits256 otherpubkey) +{ + if ( utxo != 0 ) + { + utxo->T.swappending = (uint32_t)(time(NULL) + LP_RESERVETIME); + utxo->S.otherpubkey = otherpubkey; + } +} + +void LP_unavailableset(struct LP_utxoinfo *utxo,bits256 otherpubkey) +{ + struct LP_utxoinfo *ptrs[8]; int32_t i,n; struct _LP_utxoinfo u; + memset(ptrs,0,sizeof(ptrs)); + if ( (n= LP_utxocollisions(ptrs,utxo)) > 0 ) + { + for (i=0; iiambob != 0) ? utxo->deposit : utxo->fee; + char str[65],str2[65]; printf("UTXO.[%d] RESERVED %s/v%d %s/v%d collisions.%d\n",utxo->iambob,bits256_str(str,utxo->payment.txid),utxo->payment.vout,bits256_str(str2,u.txid),u.vout,n); + _LP_unavailableset(utxo,otherpubkey); +} + +void LP_availableset(struct LP_utxoinfo *utxo) +{ + struct LP_utxoinfo *ptrs[8]; int32_t i,n,count = 0; struct _LP_utxoinfo u; + if ( utxo != 0 ) + { + memset(ptrs,0,sizeof(ptrs)); + if ( (n= LP_utxocollisions(ptrs,utxo)) > 0 ) + { + for (i=0; i 0 ) + { + u = (utxo->iambob != 0) ? utxo->deposit : utxo->fee; + char str[65],str2[65]; printf("UTXO.[%d] AVAIL %s/v%d %s/v%d collisions.%d\n",utxo->iambob,bits256_str(str,utxo->payment.txid),utxo->payment.vout,bits256_str(str2,u.txid),u.vout,n); + } + } +} + + +cJSON *LP_inventoryjson(cJSON *item,struct LP_utxoinfo *utxo) +{ + struct _LP_utxoinfo u; + //jaddstr(item,"method","oldutxo"); + if ( utxo == 0 ) + return(item); + if ( utxo->gui[0] != 0 ) + jaddstr(item,"gui",utxo->gui); + jaddstr(item,"coin",utxo->coin); + //jaddnum(item,"now",time(NULL)); + jaddnum(item,"iambob",utxo->iambob); + jaddstr(item,"address",utxo->coinaddr); + jaddbits256(item,"txid",utxo->payment.txid); + jaddnum(item,"vout",utxo->payment.vout); + jadd64bits(item,"value",utxo->payment.value); + jadd64bits(item,"satoshis",utxo->S.satoshis); + u = (utxo->iambob != 0) ? utxo->deposit : utxo->fee; + if ( bits256_nonz(u.txid) != 0 ) + { + jaddbits256(item,"txid2",u.txid); + jaddnum(item,"vout2",u.vout); + jadd64bits(item,"value2",u.value); + } + if ( utxo->T.swappending != 0 ) + jaddnum(item,"pending",utxo->T.swappending); + if ( utxo->iambob != 0 ) + { + jaddbits256(item,"srchash",utxo->pubkey);//LP_mypub25519); + if ( bits256_nonz(utxo->S.otherpubkey) != 0 ) + jaddbits256(item,"desthash",utxo->S.otherpubkey); + } + else + { + jaddbits256(item,"desthash",utxo->pubkey);//LP_mypub25519); + if ( bits256_nonz(utxo->S.otherpubkey) != 0 ) + jaddbits256(item,"srchash",utxo->S.otherpubkey); + } + //if ( utxo->S.swap != 0 ) + // jaddstr(item,"swap","in progress"); + if ( utxo->T.spentflag != 0 ) + jaddnum(item,"spent",utxo->T.spentflag); + jaddnum(item,"session",utxo->T.sessionid); + return(item); +} + +cJSON *LP_utxojson(struct LP_utxoinfo *utxo) +{ + cJSON *item = cJSON_CreateObject(); + item = LP_inventoryjson(item,utxo); + jaddbits256(item,"pubkey",utxo->pubkey); + //jaddnum(item,"profit",utxo->S.profitmargin); + jaddstr(item,"base",utxo->coin); + //jaddstr(item,"script",utxo->spendscript); + return(item); +} + +struct LP_utxoinfo *LP_utxo_bestfit(char *symbol,uint64_t destsatoshis) +{ + uint64_t srcvalue,srcvalue2; struct LP_utxoinfo *utxo,*tmp,*bestutxo = 0; int32_t bestsize,iambob = 0; + if ( symbol == 0 || destsatoshis == 0 ) + { + printf("LP_utxo_bestfit error symbol.%p %.8f\n",symbol,dstr(destsatoshis)); + return(0); + } + HASH_ITER(hh,G.LP_utxoinfos[iambob],utxo,tmp) + { + if ( strcmp(symbol,utxo->coin) != 0 ) + continue; + if ( LP_isavailable(utxo) > 0 && LP_ismine(utxo) > 0 ) + { + //printf("(%.8f %.8f %.8f)\n",dstr(utxo->payment.value),dstr(utxo->fee.value),dstr(utxo->S.satoshis)); + //char str[65]; printf("s%u %d [%.8f vs %.8f] check %s.%s avail.%d ismine.%d >= %d\n",utxo->T.spentflag,LP_iseligible(&srcvalue,&srcvalue2,utxo->iambob,symbol,utxo->payment.txid,utxo->payment.vout,utxo->S.satoshis,utxo->fee.txid,utxo->fee.vout),dstr(destsatoshis),dstr(utxo->S.satoshis),utxo->coin,bits256_str(str,utxo->payment.txid),LP_isavailable(utxo) > 0,LP_ismine(utxo) > 0,utxo->S.satoshis >= destsatoshis); + bestsize = 0; + if ( bestutxo == 0 ) + { + if ( utxo->S.satoshis > destsatoshis/LP_MINCLIENTVOL ) + bestsize = 1; + } + else + { + if ( bestutxo->S.satoshis < destsatoshis ) + { + if ( utxo->S.satoshis > destsatoshis ) + bestsize = 1; + else if ( utxo->S.satoshis > bestutxo->S.satoshis ) + bestsize = 1; + } + else + { + if ( utxo->S.satoshis > destsatoshis && utxo->S.satoshis < bestutxo->S.satoshis ) + bestsize = 1; + } + } + if ( bestsize > 0 ) + { + //printf("bestsize.%d %.8f %.8f -> %.8f\n",bestsize,dstr(utxo->payment.value),dstr(utxo->fee.value),dstr(utxo->S.satoshis)); + if ( LP_iseligible(&srcvalue,&srcvalue2,utxo->iambob,symbol,utxo->payment.txid,utxo->payment.vout,utxo->S.satoshis,utxo->fee.txid,utxo->fee.vout) == 0 ) + { + //if ( utxo->T.spentflag == 0 ) + // utxo->T.spentflag = (uint32_t)time(NULL); + continue; + } + bestutxo = utxo; + } //else printf("skip alice utxo %.8f vs dest %.8f, bestsize.%d %p\n",dstr(utxo->S.satoshis),dstr(destsatoshis),bestsize,bestutxo); + } + } + return(bestutxo); +} + +void LP_spentnotify(struct LP_utxoinfo *utxo,int32_t selector) +{ + if ( utxo == 0 ) + return; + utxo->T.spentflag = (uint32_t)time(NULL); +} + +struct LP_utxoinfo *LP_utxofinds(int32_t iambob,bits256 txid,int32_t vout,bits256 txid2,int32_t vout2) +{ + struct LP_utxoinfo *utxo; + if ( (utxo= LP_utxofind(iambob,txid,vout)) != 0 || (utxo= LP_utxofind(iambob,txid2,vout2)) != 0 || (utxo= LP_utxo2find(iambob,txid,vout)) != 0 || (utxo= LP_utxo2find(iambob,txid2,vout2)) != 0 ) + return(utxo); + else return(0); +} + +struct LP_utxoinfo *LP_utxoadd(int32_t iambob,char *symbol,bits256 txid,int32_t vout,int64_t value,bits256 txid2,int32_t vout2,int64_t value2,char *coinaddr,bits256 pubkey,char *gui,uint32_t sessionid,uint64_t satoshis) +{ + uint64_t val,val2=0,txfee; int32_t spendvini,numconfirms,selector; bits256 spendtxid; struct iguana_info *coin; struct _LP_utxoinfo u; struct LP_utxoinfo *utxo = 0; + if ( symbol == 0 || symbol[0] == 0 || coinaddr == 0 || coinaddr[0] == 0 || bits256_nonz(txid) == 0 || bits256_nonz(txid2) == 0 || vout < 0 || vout2 < 0 || value <= 0 || value2 <= 0 )//|| sessionid == 0 ) + { + char str[65],str2[65]; printf("REJECT (%s) iambob.%d %s utxoadd.(%.8f %.8f) %s/v%d %s/v%d\n",coinaddr,iambob,symbol,dstr(value),dstr(value2),bits256_str(str,txid),vout,bits256_str(str2,txid2),vout2); + printf("session.%u addutxo %d %d %d %d %d %d %d %d\n",sessionid,symbol == 0,coinaddr == 0,bits256_nonz(txid) == 0,bits256_nonz(txid2) == 0,vout < 0,vout2 < 0,value <= 0,value2 <= 0); + return(0); + } + if ( (coin= LP_coinfind(symbol)) == 0 || (IAMLP == 0 && coin->inactive != 0) ) + { + //printf("LP_utxoadd reject inactive %s\n",symbol); + return(0); + } + txfee = LP_txfeecalc(coin,0,0); + char str[65],str2[65],dispflag = 0;//(iambob == 0); + if ( iambob == 0 && bits256_cmp(pubkey,G.LP_mypub25519) != 0 ) + { + printf("trying to add Alice utxo when not mine? %s/v%d\n",bits256_str(str,txid),vout); + return(0); + } + if ( coin->inactive == 0 ) + { + if ( LP_iseligible(&val,&val2,iambob,symbol,txid,vout,satoshis,txid2,vout2) <= 0 ) + { + static uint32_t counter; + if ( counter++ < 3 ) + printf("iambob.%d utxoadd %s inactive.%u got ineligible txid value %.8f:%.8f, value2 %.8f:%.8f, tmpsatoshis %.8f\n",iambob,symbol,coin->inactive,dstr(value),dstr(val),dstr(value2),dstr(val2),dstr(satoshis)); + return(0); + } + if ( (numconfirms= LP_numconfirms(symbol,coinaddr,txid,vout,0)) <= 0 ) + { + printf("LP_utxoadd reject numconfirms.%d %s.%s\n",numconfirms,symbol,bits256_str(str,txid)); + return(0); + } + if ( (numconfirms= LP_numconfirms(symbol,coinaddr,txid2,vout2,0)) <= 0 ) + { + printf("LP_utxoadd reject2 numconfirms.%d %s %s/v%d\n",numconfirms,symbol,bits256_str(str,txid2),vout2); + return(0); + } + } + else + { + val = value; + val2 = value2; + } + dispflag = 0; + if ( dispflag != 0 ) + printf("%.8f %.8f %s iambob.%d %s utxoadd.(%.8f %.8f) %s %s\n",dstr(val),dstr(val2),coinaddr,iambob,symbol,dstr(value),dstr(value2),bits256_str(str,txid),bits256_str(str2,txid2)); + dispflag = 1; + if ( (utxo= LP_utxofinds(iambob,txid,vout,txid2,vout2)) != 0 ) + { + if ( 0 && LP_ismine(utxo) == 0 ) + { + char str2[65],str3[65]; printf("iambob.%d %s %s utxoadd.(%.8f %.8f) %s %s\n",iambob,bits256_str(str3,pubkey),symbol,dstr(value),dstr(value2),bits256_str(str,txid),bits256_str(str2,txid2)); + printf("duplicate %.8f %.8f %.8f vs utxo.(%.8f %.8f %.8f)\n",dstr(value),dstr(value2),dstr(satoshis),dstr(utxo->payment.value),dstr(utxo->deposit.value),dstr(utxo->S.satoshis)); + } + u = (utxo->iambob != 0) ? utxo->deposit : utxo->fee; + if ( bits256_cmp(txid,utxo->payment.txid) != 0 || bits256_cmp(txid2,u.txid) != 0 || vout != utxo->payment.vout || value != utxo->payment.value || satoshis != utxo->S.satoshis || vout2 != u.vout || value2 != u.value || strcmp(symbol,utxo->coin) != 0 || strcmp(coinaddr,utxo->coinaddr) != 0 || bits256_cmp(pubkey,utxo->pubkey) != 0 ) + { + utxo->T.errors++; + char str[65],str2[65],str3[65],str4[65],str5[65],str6[65]; + if ( utxo->T.spentflag != 0 || LP_txvalue(0,utxo->coin,utxo->payment.txid,utxo->payment.vout) < utxo->payment.value || LP_txvalue(0,utxo->coin,u.txid,u.vout) < u.value ) + { + //if ( utxo->T.spentflag == 0 ) + // utxo->T.spentflag = (uint32_t)time(NULL); + printf("original utxo pair not valid\n"); + if ( dispflag != 0 ) + printf("error on subsequent utxo iambob.%d %.8f %.8f add.(%s %s) when.(%s %s) %d %d %d %d %d %d %d %d %d %d pubkeys.(%s vs %s)\n",iambob,dstr(val),dstr(val2),bits256_str(str,txid),bits256_str(str2,txid2),bits256_str(str3,utxo->payment.txid),bits256_str(str4,utxo->deposit.txid),bits256_cmp(txid,utxo->payment.txid) != 0,bits256_cmp(txid2,u.txid) != 0,vout != utxo->payment.vout,satoshis != utxo->S.satoshis,vout2 != u.vout,value2 != u.value,strcmp(symbol,utxo->coin) != 0,strcmp(coinaddr,utxo->coinaddr) != 0,bits256_cmp(pubkey,utxo->pubkey) != 0,value != utxo->payment.value,bits256_str(str5,pubkey),bits256_str(str6,utxo->pubkey)); + utxo = 0; + } + } + if ( utxo != 0 ) + { + if ( utxo->T.sessionid == 0 ) + utxo->T.sessionid = sessionid; + //else if ( profitmargin > SMALLVAL ) + // utxo->S.profitmargin = profitmargin; + utxo->T.lasttime = (uint32_t)time(NULL); + //printf("return existing utxo[%d] %s %s\n",iambob,bits256_str(str,utxo->payment.txid),bits256_str(str2,iambob != 0 ? utxo->deposit.txid : utxo->fee.txid)); + return(utxo); + } + } + utxo = calloc(1,sizeof(*utxo)); + //utxo->S.profitmargin = profitmargin; + utxo->pubkey = pubkey; + safecopy(utxo->gui,gui,sizeof(utxo->gui)); + safecopy(utxo->coin,symbol,sizeof(utxo->coin)); + safecopy(utxo->coinaddr,coinaddr,sizeof(utxo->coinaddr)); + //safecopy(utxo->spendscript,spendscript,sizeof(utxo->spendscript)); + utxo->payment.txid = txid; + utxo->payment.vout = vout; + utxo->payment.value = value; + utxo->S.satoshis = satoshis; + if ( (utxo->iambob= iambob) != 0 ) + { + utxo->deposit.txid = txid2; + utxo->deposit.vout = vout2; + utxo->deposit.value = value2; + } + else + { + utxo->fee.txid = txid2; + utxo->fee.vout = vout2; + utxo->fee.value = value2; + } + LP_utxosetkey(utxo->key,txid,vout); + LP_utxosetkey(utxo->key2,txid2,vout2); + if ( LP_ismine(utxo) > 0 ) + utxo->T.sessionid = G.LP_sessionid; + else utxo->T.sessionid = sessionid; + if ( coin->inactive == 0 && (selector= LP_mempool_vinscan(&spendtxid,&spendvini,symbol,coinaddr,txid,vout,txid2,vout2)) >= 0 ) + { + printf("utxoadd selector.%d spent in mempool %s vini.%d",selector,bits256_str(str,spendtxid),spendvini); + utxo->T.spentflag = (uint32_t)time(NULL); + } + //printf(" %s %.8f %.8f %p addutxo.%d (%s %s) session.%u iambob.%d <<<<<<<<<<<<<<< %.8f\n",symbol,dstr(value),dstr(value2),utxo,LP_ismine(utxo) > 0,bits256_str(str,utxo->payment.txid),bits256_str(str2,iambob != 0 ? utxo->deposit.txid : utxo->fee.txid),utxo->T.sessionid,iambob,dstr(satoshis)); + portable_mutex_lock(&LP_utxomutex); + HASH_ADD_KEYPTR(hh,G.LP_utxoinfos[iambob],utxo->key,sizeof(utxo->key),utxo); + if ( _LP_utxo2find(iambob,txid2,vout2) == 0 ) + HASH_ADD_KEYPTR(hh2,G.LP_utxoinfos2[iambob],utxo->key2,sizeof(utxo->key2),utxo); + portable_mutex_unlock(&LP_utxomutex); + if ( iambob != 0 ) + { + if ( LP_ismine(utxo) > 0 ) + { + //LP_utxo_clientpublish(utxo); + if ( LP_mypeer != 0 ) + utxo->T.lasttime = (uint32_t)time(NULL); + } + } + return(utxo); +} + +int32_t _LP_utxos_remove(bits256 txid,int32_t vout) +{ + struct LP_utxoinfo *utxo,*utxo2; int32_t retval = 0,iambob = 1; + utxo = utxo2 = 0; + if ( (utxo= _LP_utxofind(iambob,txid,vout)) != 0 ) + { + if ( LP_isavailable(utxo) == 0 ) + retval = -1; + else + { + if ( (utxo2= _LP_utxo2find(iambob,txid,vout)) != 0 ) + { + if ( LP_isavailable(utxo) == 0 ) + retval = -1; + else + { + _LP_utxo_delete(iambob,utxo); + _LP_utxo2_delete(iambob,utxo2); + } + } + } + } + else if ( (utxo2= _LP_utxo2find(iambob,txid,vout)) != 0 ) + { + if ( LP_isavailable(utxo2) == 0 ) + retval = -1; + else _LP_utxo2_delete(iambob,utxo2); + } + return(retval); +} + +int32_t LP_utxos_remove(bits256 txid,int32_t vout) +{ + int32_t retval; + portable_mutex_lock(&LP_utxomutex); + retval = _LP_utxos_remove(txid,vout); + portable_mutex_unlock(&LP_utxomutex); + return(retval); +} + +cJSON *LP_inventory(char *symbol) +{ + struct LP_utxoinfo *utxo,*tmp; struct _LP_utxoinfo u; char *myipaddr; cJSON *array; uint64_t val,val2; int32_t iambob = 0; struct iguana_info *coin; + array = cJSON_CreateArray(); + if ( LP_mypeer != 0 ) + myipaddr = LP_mypeer->ipaddr; + else myipaddr = "127.0.0.1"; + if ( (coin= LP_coinfind(symbol)) != 0 ) + LP_listunspent_both(symbol,coin->smartaddr,0); + HASH_ITER(hh,G.LP_utxoinfos[iambob],utxo,tmp) + { + char str[65]; + //printf("iambob.%d iterate %s\n",iambob,bits256_str(str,LP_mypub25519)); + if ( LP_isunspent(utxo) != 0 && strcmp(symbol,utxo->coin) == 0 && utxo->iambob == iambob && LP_ismine(utxo) > 0 ) + { + u = (iambob != 0) ? utxo->deposit : utxo->fee; + if ( LP_iseligible(&val,&val2,iambob,utxo->coin,utxo->payment.txid,utxo->payment.vout,utxo->S.satoshis,u.txid,u.vout) == 0 ) + { + //if ( utxo->T.spentflag == 0 ) + // utxo->T.spentflag = (uint32_t)time(NULL); + //printf("%s %s ineligible %.8f %.8f\n",utxo->coin,bits256_str(str,u.txid),dstr(val),dstr(val2)); + continue; + } + //if ( iambob != 0 ) + // LP_utxo_clientpublish(utxo); + jaddi(array,LP_inventoryjson(cJSON_CreateObject(),utxo)); + } + else if ( 0 && LP_ismine(utxo) > 0 && strcmp(symbol,utxo->coin) == 0 ) + printf("skip %s %s %d %d %d %d\n",utxo->coin,bits256_str(str,utxo->payment.txid),LP_isunspent(utxo) != 0,strcmp(symbol,utxo->coin) == 0,utxo->iambob == iambob,LP_ismine(utxo) > 0); + } + return(array); +} + /*while ( time(NULL) < expiration ) { if ( (price= LP_pricecache(qp,qp->srccoin,qp->destcoin,qp->txid,qp->vout)) > SMALLVAL ) @@ -2503,6 +3147,21 @@ else } sleep(1); }*/ +//struct LP_pubkey_info *pubp,*ptmp; //cJSON *retjson; struct iguana_info *coin,*tmp; +/*HASH_ITER(hh,LP_coins,coin,tmp) // firstrefht,firstscanht,lastscanht + { + if ( coin->electrum != 0 && time(NULL) > coin->lastunspent+30 ) + { + //printf("call electrum listunspent.%s\n",coin->symbol); + if ( (retjson= electrum_address_listunspent(coin->symbol,coin->electrum,&retjson,coin->smartaddr,2)) != 0 ) + free_json(retjson); + coin->lastunspent = (uint32_t)time(NULL); + } + }*/ +/*HASH_ITER(hh,LP_pubkeyinfos,pubp,ptmp) + { + pubp->dynamictrust = LP_dynamictrust(pubp->pubkey,0); + }*/ if ( aliceutxo->S.swap == 0 ) LP_availableset(aliceutxo); diff --git a/iguana/exchanges/LP_utxo.c b/iguana/exchanges/LP_utxo.c index 9579c5474..a6af5330f 100644 --- a/iguana/exchanges/LP_utxo.c +++ b/iguana/exchanges/LP_utxo.c @@ -153,13 +153,34 @@ void LP_availableset(bits256 txid,int32_t vout) portable_mutex_unlock(&LP_inusemutex); } -int32_t LP_isavailable(struct LP_utxoinfo *utxo) +int32_t LP_maxvalue(uint64_t *values,int32_t n) { - struct _LP_utxoinfo u; - u = (utxo->iambob != 0) ? utxo->deposit : utxo->fee; - if ( LP_allocated(utxo->payment.txid,utxo->payment.vout) == 0 && LP_allocated(u.txid,u.vout) == 0 ) - return(1); - else return(0); + int32_t i,maxi = -1; uint64_t maxval = 0; + for (i=0; i maxval ) + { + maxi = i; + maxval = values[i]; + } + return(maxi); +} + +int32_t LP_nearestvalue(int32_t iambob,uint64_t *values,int32_t n,uint64_t targetval) +{ + int32_t i,mini = -1; int64_t dist; uint64_t mindist = (1 << 31); + for (i=0; i= 0 && dist < mindist ) + { + mini = i; + mindist = dist; + } + } + return(mini); } uint64_t LP_value_extract(cJSON *obj,int32_t addinterest) @@ -641,66 +662,6 @@ int32_t LP_unspents_array(struct iguana_info *coin,char *coinaddr,cJSON *array) return(count); } -void LP_utxosetkey(uint8_t *key,bits256 txid,int32_t vout) -{ - memcpy(key,txid.bytes,sizeof(txid)); - memcpy(&key[sizeof(txid)],&vout,sizeof(vout)); -} - -struct LP_utxoinfo *_LP_utxofind(int32_t iambob,bits256 txid,int32_t vout) -{ - struct LP_utxoinfo *utxo=0; uint8_t key[sizeof(txid) + sizeof(vout)]; - LP_utxosetkey(key,txid,vout); - HASH_FIND(hh,G.LP_utxoinfos[iambob!=0],key,sizeof(key),utxo); - return(utxo); -} - -void _LP_utxo_delete(int32_t iambob,struct LP_utxoinfo *utxo) -{ - HASH_DELETE(hh,G.LP_utxoinfos[iambob],utxo); -} - -void _LP_utxo2_delete(int32_t iambob,struct LP_utxoinfo *utxo) -{ - HASH_DELETE(hh,G.LP_utxoinfos2[iambob],utxo); -} - -struct LP_utxoinfo *_LP_utxo2find(int32_t iambob,bits256 txid2,int32_t vout2) -{ - struct LP_utxoinfo *utxo=0; uint8_t key2[sizeof(txid2) + sizeof(vout2)]; - LP_utxosetkey(key2,txid2,vout2); - HASH_FIND(hh2,G.LP_utxoinfos2[iambob],key2,sizeof(key2),utxo); - return(utxo); -} - -struct LP_utxoinfo *LP_utxofind(int32_t iambob,bits256 txid,int32_t vout) -{ - struct LP_utxoinfo *utxo=0; - /*if ( iambob != 0 ) - { - printf("LP_utxofind deprecated iambob\n"); - return(0); - }*/ - portable_mutex_lock(&LP_utxomutex); - utxo = _LP_utxofind(iambob,txid,vout); - portable_mutex_unlock(&LP_utxomutex); - return(utxo); -} - -struct LP_utxoinfo *LP_utxo2find(int32_t iambob,bits256 txid2,int32_t vout2) -{ - struct LP_utxoinfo *utxo=0; - /*if ( iambob != 0 ) - { - printf("LP_utxo2find deprecated iambob\n"); - return(0); - }*/ - portable_mutex_lock(&LP_utxomutex); - utxo = _LP_utxo2find(iambob,txid2,vout2); - portable_mutex_unlock(&LP_utxomutex); - return(utxo); -} - struct LP_transaction *LP_transactionfind(struct iguana_info *coin,bits256 txid) { struct LP_transaction *tx; @@ -1076,12 +1037,12 @@ int32_t LP_iseligible(uint64_t *valp,uint64_t *val2p,int32_t iambob,char *symbol int32_t LP_inventory_prevent(int32_t iambob,char *symbol,bits256 txid,int32_t vout) { - struct LP_address_utxo *up; struct LP_utxoinfo *utxo; struct LP_transaction *tx; struct iguana_info *coin; + struct LP_address_utxo *up; struct iguana_info *coin; //struct LP_utxoinfo *utxo; struct LP_transaction *tx; if ( (coin= LP_coinfind(symbol)) == 0 ) return(1); if ( LP_allocated(txid,vout) != 0 ) return(1); - if ( (utxo= LP_utxofind(iambob,txid,vout)) != 0 || (utxo= LP_utxo2find(iambob,txid,vout)) != 0 ) + /*if ( (utxo= LP_utxofind(iambob,txid,vout)) != 0 || (utxo= LP_utxo2find(iambob,txid,vout)) != 0 ) { if ( coin != 0 && (tx= LP_transactionfind(coin,txid)) != 0 ) { @@ -1094,7 +1055,7 @@ int32_t LP_inventory_prevent(int32_t iambob,char *symbol,bits256 txid,int32_t vo //char str[65]; printf("prevent adding iambob.%d %s/v%d to inventory\n",iambob,bits256_str(str,txid),vout); return(1); } - } + }*/ if ( (up= LP_address_utxofind(coin,coin->smartaddr,txid,vout)) != 0 && up->spendheight > 0 ) return(1); return(0); diff --git a/iguana/exchanges/LP_utxos.c b/iguana/exchanges/LP_utxos.c deleted file mode 100644 index f333e9c48..000000000 --- a/iguana/exchanges/LP_utxos.c +++ /dev/null @@ -1,902 +0,0 @@ - -/****************************************************************************** - * Copyright © 2014-2017 The SuperNET Developers. * - * * - * See the AUTHORS, DEVELOPER-AGREEMENT and LICENSE files at * - * the top-level directory of this distribution for the individual copyright * - * holder information and the developer policies on copyright and licensing. * - * * - * Unless otherwise agreed in a custom licensing agreement, no part of the * - * SuperNET software, including this file may be copied, modified, propagated * - * or distributed except according to the terms contained in the LICENSE file * - * * - * Removal or modification of this copyright notice is prohibited. * - * * - ******************************************************************************/ -// -// LP_utxos.c -// marketmaker -// - - -int32_t LP_ismine(struct LP_utxoinfo *utxo) -{ - if ( utxo != 0 && bits256_cmp(utxo->pubkey,G.LP_mypub25519) == 0 ) - return(1); - else return(0); -} - -int32_t LP_isunspent(struct LP_utxoinfo *utxo) -{ - struct LP_address_utxo *up; struct _LP_utxoinfo u; struct iguana_info *coin; - if ( (coin= LP_coinfind(utxo->coin)) == 0 ) - return(0); - if ( (up= LP_address_utxofind(coin,utxo->coinaddr,utxo->payment.txid,utxo->payment.vout)) != 0 && up->spendheight > 0 ) - { - utxo->T.spentflag = up->spendheight; - return(0); - } - u = (utxo->iambob != 0) ? utxo->deposit : utxo->fee; - if ( (up= LP_address_utxofind(coin,utxo->coinaddr,u.txid,u.vout)) != 0 && up->spendheight > 0 ) - { - utxo->T.spentflag = up->spendheight; - return(0); - } - if ( utxo != 0 && utxo->T.spentflag == 0 && LP_isavailable(utxo) > 0 ) - return(1); - else return(0); -} - -struct LP_utxoinfo *LP_utxopairfind(int32_t iambob,bits256 txid,int32_t vout,bits256 txid2,int32_t vout2) -{ - struct LP_utxoinfo *utxo=0; struct _LP_utxoinfo u; - if ( (utxo= LP_utxofind(iambob,txid,vout)) != 0 ) - { - u = (iambob != 0) ? utxo->deposit : utxo->fee; - if (vout2 == u.vout && bits256_cmp(u.txid,txid2) == 0 ) - return(utxo); - } - return(0); -} - -struct LP_utxoinfo *LP_utxofinds(int32_t iambob,bits256 txid,int32_t vout,bits256 txid2,int32_t vout2) -{ - struct LP_utxoinfo *utxo; - if ( (utxo= LP_utxofind(iambob,txid,vout)) != 0 || (utxo= LP_utxofind(iambob,txid2,vout2)) != 0 || (utxo= LP_utxo2find(iambob,txid,vout)) != 0 || (utxo= LP_utxo2find(iambob,txid2,vout2)) != 0 ) - return(utxo); - else return(0); -} - -int32_t LP_utxoaddptrs(struct LP_utxoinfo *ptrs[],int32_t n,struct LP_utxoinfo *utxo) -{ - int32_t i; - for (i=0; i utxo->T.swappending ) - utxo->T.swappending = 0; - if ( utxo != 0 && utxo->T.swappending == 0 && utxo->S.swap == 0 ) - return(1); - else return(0); -} - -int32_t LP_utxocollisions(struct LP_utxoinfo *ptrs[],struct LP_utxoinfo *refutxo) -{ - int32_t iambob,n = 0; struct LP_utxoinfo *utxo; struct _LP_utxoinfo u; - if ( refutxo == 0 ) - return(0); - portable_mutex_lock(&LP_utxomutex); - for (iambob=0; iambob<=1; iambob++) - { - if ( (utxo= _LP_utxofind(iambob,refutxo->payment.txid,refutxo->payment.vout)) != 0 && utxo != refutxo ) - n = LP_utxoaddptrs(ptrs,n,utxo); - if ( (utxo= _LP_utxo2find(iambob,refutxo->payment.txid,refutxo->payment.vout)) != 0 && utxo != refutxo ) - n = LP_utxoaddptrs(ptrs,n,utxo); - u = (refutxo->iambob != 0) ? refutxo->deposit : refutxo->fee; - if ( (utxo= _LP_utxofind(iambob,u.txid,u.vout)) != 0 && utxo != refutxo ) - n = LP_utxoaddptrs(ptrs,n,utxo); - if ( (utxo= _LP_utxo2find(iambob,u.txid,u.vout)) != 0 && utxo != refutxo ) - n = LP_utxoaddptrs(ptrs,n,utxo); - } - portable_mutex_unlock(&LP_utxomutex); - if ( 0 && n > 0 ) - printf("LP_utxocollisions n.%d\n",n); - return(n); -} - -int32_t _LP_availableset(struct LP_utxoinfo *utxo) -{ - int32_t flag = 0; - if ( utxo != 0 ) - { - if ( bits256_nonz(utxo->S.otherpubkey) != 0 ) - flag = 1, memset(&utxo->S.otherpubkey,0,sizeof(utxo->S.otherpubkey)); - if ( utxo->S.swap != 0 ) - flag = 1, utxo->S.swap = 0; - if ( utxo->T.swappending != 0 ) - flag = 1, utxo->T.swappending = 0; - return(flag); - } - return(0); -} - -void _LP_unavailableset(struct LP_utxoinfo *utxo,bits256 otherpubkey) -{ - if ( utxo != 0 ) - { - utxo->T.swappending = (uint32_t)(time(NULL) + LP_RESERVETIME); - utxo->S.otherpubkey = otherpubkey; - } -} - -void LP_unavailableset(struct LP_utxoinfo *utxo,bits256 otherpubkey) -{ - struct LP_utxoinfo *ptrs[8]; int32_t i,n; struct _LP_utxoinfo u; - memset(ptrs,0,sizeof(ptrs)); - if ( (n= LP_utxocollisions(ptrs,utxo)) > 0 ) - { - for (i=0; iiambob != 0) ? utxo->deposit : utxo->fee; - char str[65],str2[65]; printf("UTXO.[%d] RESERVED %s/v%d %s/v%d collisions.%d\n",utxo->iambob,bits256_str(str,utxo->payment.txid),utxo->payment.vout,bits256_str(str2,u.txid),u.vout,n); - _LP_unavailableset(utxo,otherpubkey); -} - -void LP_availableset(struct LP_utxoinfo *utxo) -{ - struct LP_utxoinfo *ptrs[8]; int32_t i,n,count = 0; struct _LP_utxoinfo u; - if ( utxo != 0 ) - { - memset(ptrs,0,sizeof(ptrs)); - if ( (n= LP_utxocollisions(ptrs,utxo)) > 0 ) - { - for (i=0; i 0 ) - { - u = (utxo->iambob != 0) ? utxo->deposit : utxo->fee; - char str[65],str2[65]; printf("UTXO.[%d] AVAIL %s/v%d %s/v%d collisions.%d\n",utxo->iambob,bits256_str(str,utxo->payment.txid),utxo->payment.vout,bits256_str(str2,u.txid),u.vout,n); - } - } -} - - -cJSON *LP_inventoryjson(cJSON *item,struct LP_utxoinfo *utxo) -{ - struct _LP_utxoinfo u; - //jaddstr(item,"method","oldutxo"); - if ( utxo == 0 ) - return(item); - if ( utxo->gui[0] != 0 ) - jaddstr(item,"gui",utxo->gui); - jaddstr(item,"coin",utxo->coin); - //jaddnum(item,"now",time(NULL)); - jaddnum(item,"iambob",utxo->iambob); - jaddstr(item,"address",utxo->coinaddr); - jaddbits256(item,"txid",utxo->payment.txid); - jaddnum(item,"vout",utxo->payment.vout); - jadd64bits(item,"value",utxo->payment.value); - jadd64bits(item,"satoshis",utxo->S.satoshis); - u = (utxo->iambob != 0) ? utxo->deposit : utxo->fee; - if ( bits256_nonz(u.txid) != 0 ) - { - jaddbits256(item,"txid2",u.txid); - jaddnum(item,"vout2",u.vout); - jadd64bits(item,"value2",u.value); - } - if ( utxo->T.swappending != 0 ) - jaddnum(item,"pending",utxo->T.swappending); - if ( utxo->iambob != 0 ) - { - jaddbits256(item,"srchash",utxo->pubkey);//LP_mypub25519); - if ( bits256_nonz(utxo->S.otherpubkey) != 0 ) - jaddbits256(item,"desthash",utxo->S.otherpubkey); - } - else - { - jaddbits256(item,"desthash",utxo->pubkey);//LP_mypub25519); - if ( bits256_nonz(utxo->S.otherpubkey) != 0 ) - jaddbits256(item,"srchash",utxo->S.otherpubkey); - } - //if ( utxo->S.swap != 0 ) - // jaddstr(item,"swap","in progress"); - if ( utxo->T.spentflag != 0 ) - jaddnum(item,"spent",utxo->T.spentflag); - jaddnum(item,"session",utxo->T.sessionid); - return(item); -} - -cJSON *LP_utxojson(struct LP_utxoinfo *utxo) -{ - cJSON *item = cJSON_CreateObject(); - item = LP_inventoryjson(item,utxo); - jaddbits256(item,"pubkey",utxo->pubkey); - //jaddnum(item,"profit",utxo->S.profitmargin); - jaddstr(item,"base",utxo->coin); - //jaddstr(item,"script",utxo->spendscript); - return(item); -} - -struct LP_utxoinfo *LP_utxo_bestfit(char *symbol,uint64_t destsatoshis) -{ - uint64_t srcvalue,srcvalue2; struct LP_utxoinfo *utxo,*tmp,*bestutxo = 0; int32_t bestsize,iambob = 0; - if ( symbol == 0 || destsatoshis == 0 ) - { - printf("LP_utxo_bestfit error symbol.%p %.8f\n",symbol,dstr(destsatoshis)); - return(0); - } - HASH_ITER(hh,G.LP_utxoinfos[iambob],utxo,tmp) - { - if ( strcmp(symbol,utxo->coin) != 0 ) - continue; - if ( LP_isavailable(utxo) > 0 && LP_ismine(utxo) > 0 ) - { - //printf("(%.8f %.8f %.8f)\n",dstr(utxo->payment.value),dstr(utxo->fee.value),dstr(utxo->S.satoshis)); - //char str[65]; printf("s%u %d [%.8f vs %.8f] check %s.%s avail.%d ismine.%d >= %d\n",utxo->T.spentflag,LP_iseligible(&srcvalue,&srcvalue2,utxo->iambob,symbol,utxo->payment.txid,utxo->payment.vout,utxo->S.satoshis,utxo->fee.txid,utxo->fee.vout),dstr(destsatoshis),dstr(utxo->S.satoshis),utxo->coin,bits256_str(str,utxo->payment.txid),LP_isavailable(utxo) > 0,LP_ismine(utxo) > 0,utxo->S.satoshis >= destsatoshis); - bestsize = 0; - if ( bestutxo == 0 ) - { - if ( utxo->S.satoshis > destsatoshis/LP_MINCLIENTVOL ) - bestsize = 1; - } - else - { - if ( bestutxo->S.satoshis < destsatoshis ) - { - if ( utxo->S.satoshis > destsatoshis ) - bestsize = 1; - else if ( utxo->S.satoshis > bestutxo->S.satoshis ) - bestsize = 1; - } - else - { - if ( utxo->S.satoshis > destsatoshis && utxo->S.satoshis < bestutxo->S.satoshis ) - bestsize = 1; - } - } - if ( bestsize > 0 ) - { - //printf("bestsize.%d %.8f %.8f -> %.8f\n",bestsize,dstr(utxo->payment.value),dstr(utxo->fee.value),dstr(utxo->S.satoshis)); - if ( LP_iseligible(&srcvalue,&srcvalue2,utxo->iambob,symbol,utxo->payment.txid,utxo->payment.vout,utxo->S.satoshis,utxo->fee.txid,utxo->fee.vout) == 0 ) - { - //if ( utxo->T.spentflag == 0 ) - // utxo->T.spentflag = (uint32_t)time(NULL); - continue; - } - bestutxo = utxo; - } //else printf("skip alice utxo %.8f vs dest %.8f, bestsize.%d %p\n",dstr(utxo->S.satoshis),dstr(destsatoshis),bestsize,bestutxo); - } - } - return(bestutxo); -} - -void LP_spentnotify(struct LP_utxoinfo *utxo,int32_t selector) -{ - if ( utxo == 0 ) - return; - utxo->T.spentflag = (uint32_t)time(NULL); -} - -struct LP_utxoinfo *LP_utxoadd(int32_t iambob,char *symbol,bits256 txid,int32_t vout,int64_t value,bits256 txid2,int32_t vout2,int64_t value2,char *coinaddr,bits256 pubkey,char *gui,uint32_t sessionid,uint64_t satoshis) -{ - uint64_t val,val2=0,txfee; int32_t spendvini,numconfirms,selector; bits256 spendtxid; struct iguana_info *coin; struct _LP_utxoinfo u; struct LP_utxoinfo *utxo = 0; - if ( symbol == 0 || symbol[0] == 0 || coinaddr == 0 || coinaddr[0] == 0 || bits256_nonz(txid) == 0 || bits256_nonz(txid2) == 0 || vout < 0 || vout2 < 0 || value <= 0 || value2 <= 0 )//|| sessionid == 0 ) - { - char str[65],str2[65]; printf("REJECT (%s) iambob.%d %s utxoadd.(%.8f %.8f) %s/v%d %s/v%d\n",coinaddr,iambob,symbol,dstr(value),dstr(value2),bits256_str(str,txid),vout,bits256_str(str2,txid2),vout2); - printf("session.%u addutxo %d %d %d %d %d %d %d %d\n",sessionid,symbol == 0,coinaddr == 0,bits256_nonz(txid) == 0,bits256_nonz(txid2) == 0,vout < 0,vout2 < 0,value <= 0,value2 <= 0); - return(0); - } - if ( (coin= LP_coinfind(symbol)) == 0 || (IAMLP == 0 && coin->inactive != 0) ) - { - //printf("LP_utxoadd reject inactive %s\n",symbol); - return(0); - } - txfee = LP_txfeecalc(coin,0,0); - char str[65],str2[65],dispflag = 0;//(iambob == 0); - if ( iambob == 0 && bits256_cmp(pubkey,G.LP_mypub25519) != 0 ) - { - printf("trying to add Alice utxo when not mine? %s/v%d\n",bits256_str(str,txid),vout); - return(0); - } - if ( coin->inactive == 0 ) - { - if ( LP_iseligible(&val,&val2,iambob,symbol,txid,vout,satoshis,txid2,vout2) <= 0 ) - { - static uint32_t counter; - if ( counter++ < 3 ) - printf("iambob.%d utxoadd %s inactive.%u got ineligible txid value %.8f:%.8f, value2 %.8f:%.8f, tmpsatoshis %.8f\n",iambob,symbol,coin->inactive,dstr(value),dstr(val),dstr(value2),dstr(val2),dstr(satoshis)); - return(0); - } - if ( (numconfirms= LP_numconfirms(symbol,coinaddr,txid,vout,0)) <= 0 ) - { - printf("LP_utxoadd reject numconfirms.%d %s.%s\n",numconfirms,symbol,bits256_str(str,txid)); - return(0); - } - if ( (numconfirms= LP_numconfirms(symbol,coinaddr,txid2,vout2,0)) <= 0 ) - { - printf("LP_utxoadd reject2 numconfirms.%d %s %s/v%d\n",numconfirms,symbol,bits256_str(str,txid2),vout2); - return(0); - } - } - else - { - val = value; - val2 = value2; - } - dispflag = 0; - if ( dispflag != 0 ) - printf("%.8f %.8f %s iambob.%d %s utxoadd.(%.8f %.8f) %s %s\n",dstr(val),dstr(val2),coinaddr,iambob,symbol,dstr(value),dstr(value2),bits256_str(str,txid),bits256_str(str2,txid2)); - dispflag = 1; - if ( (utxo= LP_utxofinds(iambob,txid,vout,txid2,vout2)) != 0 ) - { - if ( 0 && LP_ismine(utxo) == 0 ) - { - char str2[65],str3[65]; printf("iambob.%d %s %s utxoadd.(%.8f %.8f) %s %s\n",iambob,bits256_str(str3,pubkey),symbol,dstr(value),dstr(value2),bits256_str(str,txid),bits256_str(str2,txid2)); - printf("duplicate %.8f %.8f %.8f vs utxo.(%.8f %.8f %.8f)\n",dstr(value),dstr(value2),dstr(satoshis),dstr(utxo->payment.value),dstr(utxo->deposit.value),dstr(utxo->S.satoshis)); - } - u = (utxo->iambob != 0) ? utxo->deposit : utxo->fee; - if ( bits256_cmp(txid,utxo->payment.txid) != 0 || bits256_cmp(txid2,u.txid) != 0 || vout != utxo->payment.vout || value != utxo->payment.value || satoshis != utxo->S.satoshis || vout2 != u.vout || value2 != u.value || strcmp(symbol,utxo->coin) != 0 || strcmp(coinaddr,utxo->coinaddr) != 0 || bits256_cmp(pubkey,utxo->pubkey) != 0 ) - { - utxo->T.errors++; - char str[65],str2[65],str3[65],str4[65],str5[65],str6[65]; - if ( utxo->T.spentflag != 0 || LP_txvalue(0,utxo->coin,utxo->payment.txid,utxo->payment.vout) < utxo->payment.value || LP_txvalue(0,utxo->coin,u.txid,u.vout) < u.value ) - { - //if ( utxo->T.spentflag == 0 ) - // utxo->T.spentflag = (uint32_t)time(NULL); - printf("original utxo pair not valid\n"); - if ( dispflag != 0 ) - printf("error on subsequent utxo iambob.%d %.8f %.8f add.(%s %s) when.(%s %s) %d %d %d %d %d %d %d %d %d %d pubkeys.(%s vs %s)\n",iambob,dstr(val),dstr(val2),bits256_str(str,txid),bits256_str(str2,txid2),bits256_str(str3,utxo->payment.txid),bits256_str(str4,utxo->deposit.txid),bits256_cmp(txid,utxo->payment.txid) != 0,bits256_cmp(txid2,u.txid) != 0,vout != utxo->payment.vout,satoshis != utxo->S.satoshis,vout2 != u.vout,value2 != u.value,strcmp(symbol,utxo->coin) != 0,strcmp(coinaddr,utxo->coinaddr) != 0,bits256_cmp(pubkey,utxo->pubkey) != 0,value != utxo->payment.value,bits256_str(str5,pubkey),bits256_str(str6,utxo->pubkey)); - utxo = 0; - } - } - if ( utxo != 0 ) - { - if ( utxo->T.sessionid == 0 ) - utxo->T.sessionid = sessionid; - //else if ( profitmargin > SMALLVAL ) - // utxo->S.profitmargin = profitmargin; - utxo->T.lasttime = (uint32_t)time(NULL); - //printf("return existing utxo[%d] %s %s\n",iambob,bits256_str(str,utxo->payment.txid),bits256_str(str2,iambob != 0 ? utxo->deposit.txid : utxo->fee.txid)); - return(utxo); - } - } - utxo = calloc(1,sizeof(*utxo)); - //utxo->S.profitmargin = profitmargin; - utxo->pubkey = pubkey; - safecopy(utxo->gui,gui,sizeof(utxo->gui)); - safecopy(utxo->coin,symbol,sizeof(utxo->coin)); - safecopy(utxo->coinaddr,coinaddr,sizeof(utxo->coinaddr)); - //safecopy(utxo->spendscript,spendscript,sizeof(utxo->spendscript)); - utxo->payment.txid = txid; - utxo->payment.vout = vout; - utxo->payment.value = value; - utxo->S.satoshis = satoshis; - if ( (utxo->iambob= iambob) != 0 ) - { - utxo->deposit.txid = txid2; - utxo->deposit.vout = vout2; - utxo->deposit.value = value2; - } - else - { - utxo->fee.txid = txid2; - utxo->fee.vout = vout2; - utxo->fee.value = value2; - } - LP_utxosetkey(utxo->key,txid,vout); - LP_utxosetkey(utxo->key2,txid2,vout2); - if ( LP_ismine(utxo) > 0 ) - utxo->T.sessionid = G.LP_sessionid; - else utxo->T.sessionid = sessionid; - if ( coin->inactive == 0 && (selector= LP_mempool_vinscan(&spendtxid,&spendvini,symbol,coinaddr,txid,vout,txid2,vout2)) >= 0 ) - { - printf("utxoadd selector.%d spent in mempool %s vini.%d",selector,bits256_str(str,spendtxid),spendvini); - utxo->T.spentflag = (uint32_t)time(NULL); - } - //printf(" %s %.8f %.8f %p addutxo.%d (%s %s) session.%u iambob.%d <<<<<<<<<<<<<<< %.8f\n",symbol,dstr(value),dstr(value2),utxo,LP_ismine(utxo) > 0,bits256_str(str,utxo->payment.txid),bits256_str(str2,iambob != 0 ? utxo->deposit.txid : utxo->fee.txid),utxo->T.sessionid,iambob,dstr(satoshis)); - portable_mutex_lock(&LP_utxomutex); - HASH_ADD_KEYPTR(hh,G.LP_utxoinfos[iambob],utxo->key,sizeof(utxo->key),utxo); - if ( _LP_utxo2find(iambob,txid2,vout2) == 0 ) - HASH_ADD_KEYPTR(hh2,G.LP_utxoinfos2[iambob],utxo->key2,sizeof(utxo->key2),utxo); - portable_mutex_unlock(&LP_utxomutex); - if ( iambob != 0 ) - { - if ( LP_ismine(utxo) > 0 ) - { - //LP_utxo_clientpublish(utxo); - if ( LP_mypeer != 0 ) - utxo->T.lasttime = (uint32_t)time(NULL); - } - } - return(utxo); -} - -int32_t _LP_utxos_remove(bits256 txid,int32_t vout) -{ - struct LP_utxoinfo *utxo,*utxo2; int32_t retval = 0,iambob = 1; - utxo = utxo2 = 0; - if ( (utxo= _LP_utxofind(iambob,txid,vout)) != 0 ) - { - if ( LP_isavailable(utxo) == 0 ) - retval = -1; - else - { - if ( (utxo2= _LP_utxo2find(iambob,txid,vout)) != 0 ) - { - if ( LP_isavailable(utxo) == 0 ) - retval = -1; - else - { - _LP_utxo_delete(iambob,utxo); - _LP_utxo2_delete(iambob,utxo2); - } - } - } - } - else if ( (utxo2= _LP_utxo2find(iambob,txid,vout)) != 0 ) - { - if ( LP_isavailable(utxo2) == 0 ) - retval = -1; - else _LP_utxo2_delete(iambob,utxo2); - } - return(retval); -} - -int32_t LP_utxos_remove(bits256 txid,int32_t vout) -{ - int32_t retval; - portable_mutex_lock(&LP_utxomutex); - retval = _LP_utxos_remove(txid,vout); - portable_mutex_unlock(&LP_utxomutex); - return(retval); -} - -cJSON *LP_inventory(char *symbol) -{ - struct LP_utxoinfo *utxo,*tmp; struct _LP_utxoinfo u; char *myipaddr; cJSON *array; uint64_t val,val2; int32_t iambob = 0; struct iguana_info *coin; - array = cJSON_CreateArray(); - if ( LP_mypeer != 0 ) - myipaddr = LP_mypeer->ipaddr; - else myipaddr = "127.0.0.1"; - if ( (coin= LP_coinfind(symbol)) != 0 ) - LP_listunspent_both(symbol,coin->smartaddr,0); - HASH_ITER(hh,G.LP_utxoinfos[iambob],utxo,tmp) - { - char str[65]; - //printf("iambob.%d iterate %s\n",iambob,bits256_str(str,LP_mypub25519)); - if ( LP_isunspent(utxo) != 0 && strcmp(symbol,utxo->coin) == 0 && utxo->iambob == iambob && LP_ismine(utxo) > 0 ) - { - u = (iambob != 0) ? utxo->deposit : utxo->fee; - if ( LP_iseligible(&val,&val2,iambob,utxo->coin,utxo->payment.txid,utxo->payment.vout,utxo->S.satoshis,u.txid,u.vout) == 0 ) - { - //if ( utxo->T.spentflag == 0 ) - // utxo->T.spentflag = (uint32_t)time(NULL); - //printf("%s %s ineligible %.8f %.8f\n",utxo->coin,bits256_str(str,u.txid),dstr(val),dstr(val2)); - continue; - } - //if ( iambob != 0 ) - // LP_utxo_clientpublish(utxo); - jaddi(array,LP_inventoryjson(cJSON_CreateObject(),utxo)); - } - else if ( 0 && LP_ismine(utxo) > 0 && strcmp(symbol,utxo->coin) == 0 ) - printf("skip %s %s %d %d %d %d\n",utxo->coin,bits256_str(str,utxo->payment.txid),LP_isunspent(utxo) != 0,strcmp(symbol,utxo->coin) == 0,utxo->iambob == iambob,LP_ismine(utxo) > 0); - } - return(array); -}*/ - -int32_t LP_maxvalue(uint64_t *values,int32_t n) -{ - int32_t i,maxi = -1; uint64_t maxval = 0; - for (i=0; i maxval ) - { - maxi = i; - maxval = values[i]; - } - return(maxi); -} - -int32_t LP_nearestvalue(int32_t iambob,uint64_t *values,int32_t n,uint64_t targetval) -{ - int32_t i,mini = -1; int64_t dist; uint64_t mindist = (1 << 31); - for (i=0; i= 0 && dist < mindist ) - { - mini = i; - mindist = dist; - } - } - return(mini); -} - -int64_t LP_listunspent_parseitem(struct iguana_info *coin,bits256 *txidp,int32_t *voutp,int32_t *heightp,cJSON *item) -{ - int64_t satoshis = 0; - if ( coin->electrum == 0 ) - { - *txidp = jbits256(item,"txid"); - *voutp = juint(item,"vout"); - satoshis = LP_value_extract(item,0); - *heightp = LP_txheight(coin,*txidp); - } - else - { - *txidp = jbits256(item,"tx_hash"); - *voutp = juint(item,"tx_pos"); - satoshis = j64bits(item,"value"); - *heightp = jint(item,"height"); - } - return(satoshis); -} - -int32_t LP_privkey_init(int32_t mypubsock,struct iguana_info *coin,bits256 myprivkey,bits256 mypub) -{ - int32_t enable_utxos = 0; - char *script,destaddr[64]; cJSON *array,*item; bits256 txid,deposittxid; int32_t used,i,flag=0,height,n,cmpflag,iambob,vout,depositvout; uint64_t *values=0,satoshis,txfee,biggerval,value,total = 0; int64_t targetval; //struct LP_utxoinfo *utxo; - if ( coin == 0 || (IAMLP == 0 && coin->inactive != 0) ) - { - //printf("coin not active\n"); - return(0); - } - if ( coin->privkeydepth > 0 ) - return(0); - coin->privkeydepth++; - LP_address(coin,coin->smartaddr); - //if ( coin->inactive == 0 ) - // LP_listunspent_issue(coin->symbol,coin->smartaddr,0); - array = LP_listunspent(coin->symbol,coin->smartaddr); - if ( array != 0 ) - { - txfee = LP_txfeecalc(coin,0,0); - if ( is_cJSON_Array(array) != 0 && (n= cJSON_GetArraySize(array)) > 0 ) - { - coin->numutxos = n; - //printf("LP_privkey_init %s %d\n",coin->symbol,n); - for (iambob=0; iambob<=1; iambob++) - { - if ( iambob == 0 ) - values = calloc(n,sizeof(*values)); - else memset(values,0,n * sizeof(*values)); - used = 0; - for (i=0; isymbol,txid,vout); - if ( satoshis != 0 && satoshis != value ) - printf("%s %s privkey_init value %.8f vs %.8f (%s) %.8f %.8f\n",coin->symbol,coin->smartaddr,dstr(satoshis),dstr(value),jprint(item,0),jdouble(item,"amount"),jdouble(item,"interest")); - if ( coin->electrum != 0 || LP_inventory_prevent(iambob,coin->symbol,txid,vout) == 0 )//&& height > 0 ) - { - values[i] = satoshis; - //flag += LP_address_utxoadd(coin,destaddr,txid,vout,satoshis,height,-1); - } else used++; - } - //printf("array.%d\n",n); - while ( used < n-1 ) - { - //for (i=0; i= 0 ) - { - item = jitem(array,i); - if ( coin->electrum == 0 ) - { - deposittxid = jbits256(item,"txid"); - depositvout = juint(item,"vout"); - script = jstr(item,"scriptPubKey"); - } - else - { - deposittxid = jbits256(item,"tx_hash"); - depositvout = juint(item,"tx_pos"); - script = coin->smartaddr; - } - biggerval = values[i]; - values[i] = 0, used++; - if ( iambob == 0 ) - targetval = (biggerval / 776) + txfee; - else targetval = (biggerval / 9) * 8 + 2*txfee; - if ( targetval < txfee*2 ) - targetval = txfee*2; - //printf("iambob.%d i.%d deposit %.8f min %.8f target %.8f\n",iambob,i,dstr(biggerval),dstr((1+LP_MINSIZE_TXFEEMULT)*txfee),dstr(targetval)); - if ( biggerval < (1+LP_MINSIZE_TXFEEMULT)*txfee ) - continue; - i = -1; - if ( iambob != 0 ) - { - if ( (i= LP_nearestvalue(iambob,values,n,targetval)) < 0 ) - targetval /= 4; - if ( targetval < txfee*(1+LP_MINSIZE_TXFEEMULT) ) - continue; - } - if ( i >= 0 || (i= LP_nearestvalue(iambob,values,n,targetval)) >= 0 ) - { - //printf("iambob.%d i.%d %.8f target %.8f\n",iambob,i,dstr(biggerval),dstr(targetval)); - item = jitem(array,i); - cmpflag = 0; - if ( coin->electrum == 0 ) - { - txid = jbits256(item,"txid"); - vout = juint(item,"vout"); - if ( jstr(item,"scriptPubKey") != 0 && strcmp(script,jstr(item,"scriptPubKey")) == 0 ) - cmpflag = 1; - } - else - { - txid = jbits256(item,"tx_hash"); - vout = juint(item,"tx_pos"); - cmpflag = 1; - } - if ( cmpflag != 0 ) - { - value = values[i]; - values[i] = 0, used++; - /*portable_mutex_lock(&LP_UTXOmutex); - if ( iambob != 0 ) - { - if ( (utxo= LP_utxoadd(1,coin->symbol,txid,vout,value,deposittxid,depositvout,biggerval,coin->smartaddr,mypub,LP_gui,G.LP_sessionid,value)) != 0 ) - { - } - } - else - { - //printf("call utxoadd\n"); - if ( (utxo= LP_utxoadd(0,coin->symbol,deposittxid,depositvout,biggerval,txid,vout,value,coin->smartaddr,mypub,LP_gui,G.LP_sessionid,biggerval)) != 0 ) - { - } - } - portable_mutex_unlock(&LP_UTXOmutex);*/ - total += value; - } // else printf("scriptmismatch.(%s) vs %s\n",script,jprint(item,0)); - } //else printf("nothing near i.%d\n",i); - } else break; - } - if ( enable_utxos == 0 ) - break; - } - } - free_json(array); - if ( 0 && flag != 0 ) - LP_postutxos(coin->symbol,coin->smartaddr); - } - if ( values != 0 ) - free(values); - if ( coin->privkeydepth > 0 ) - coin->privkeydepth--; - //printf("privkey.%s %.8f\n",symbol,dstr(total)); - return(flag); -} - -char *LP_secretaddresses(void *ctx,char *prefix,char *passphrase,int32_t n,uint8_t taddr,uint8_t pubtype) -{ - int32_t i; uint8_t tmptype,pubkey33[33],rmd160[20]; char output[777*45],str[65],str2[65],buf[8192],wifstr[128],coinaddr[64]; bits256 checkprivkey,privkey,pubkey; cJSON *retjson; - retjson = cJSON_CreateObject(); - if ( prefix == 0 || prefix[0] == 0 ) - prefix = "secretaddress"; - if ( passphrase == 0 || passphrase[0] == 0 ) - passphrase = "password"; - if ( n <= 0 ) - n = 16; - else if ( n > 777 ) - n = 777; - conv_NXTpassword(privkey.bytes,pubkey.bytes,(uint8_t *)passphrase,(int32_t)strlen(passphrase)); - bitcoin_priv2pub(ctx,pubkey33,coinaddr,privkey,taddr,pubtype); - printf("generator (%s) secrets.[%d] <%s> t.%u p.%u\n",coinaddr,n,passphrase,taddr,pubtype); - sprintf(output,"\"addresses\":["); - for (i=0; i %s vs %s?\n",wifstr,bits256_str(str,privkey),bits256_str(str2,checkprivkey)); - free_json(retjson); - return(clonestr("{\"error\":\"couldnt validate wifstr\"}")); - } - else if ( tmptype != pubtype ) - { - printf("checktype.%d != pubtype.%d\n",tmptype,pubtype); - free_json(retjson); - return(clonestr("{\"error\":\"couldnt validate pubtype\"}")); - } - jaddstr(retjson,coinaddr,wifstr); - sprintf(output+strlen(output),"\\\"%s\\\"%c ",coinaddr,ibytes,(uint8_t *)passphrase,(int32_t)strlen(passphrase)); - //vcalc_sha256(0,checkkey.bytes,(uint8_t *)passphrase,(int32_t)strlen(passphrase)); - //printf("SHA256.(%s) ",bits256_str(pstr,checkkey)); - //printf("privkey.(%s)\n",bits256_str(pstr,privkey)); - } - else - { - bitcoin_wif2priv(coin->wiftaddr,&tmptype,&privkey,wifstr); - if ( 0 ) - { - char str[65],str2[65]; - checkkey = iguana_wif2privkey(wifstr); - if ( bits256_cmp(checkkey,privkey) != 0 ) - printf("WIF.(%s) -> %s or %s?\n",wifstr,bits256_str(str,privkey),bits256_str(str2,checkkey)); - } - } - privkey.bytes[0] &= 248, privkey.bytes[31] &= 127, privkey.bytes[31] |= 64; - bitcoin_priv2pub(ctx,coin->pubkey33,coin->smartaddr,privkey,coin->taddr,coin->pubtype); - if ( coin->counter == 0 ) - { - coin->counter++; - memcpy(G.LP_pubsecp,coin->pubkey33,33); - bitcoin_priv2wif(coin->wiftaddr,tmpstr,privkey,coin->wiftype); - bitcoin_addr2rmd160(coin->taddr,&tmptype,G.LP_myrmd160,coin->smartaddr); - LP_privkeyadd(privkey,G.LP_myrmd160); - G.LP_privkey = privkey; - if ( 0 && (coin->pubtype != 60 || strcmp(coin->symbol,"KMD") == 0) ) - printf("%s (%s) %d wif.(%s) (%s)\n",coin->symbol,coin->smartaddr,coin->pubtype,tmpstr,passphrase); - if ( G.counter++ == 0 ) - { - bitcoin_priv2wif(coin->wiftaddr,G.USERPASS_WIFSTR,privkey,188); - bitcoin_wif2priv(coin->wiftaddr,&tmptype,&checkkey,G.USERPASS_WIFSTR); - if ( bits256_cmp(checkkey,privkey) != 0 ) - { - char str[65],str2[65]; - printf("FATAL ERROR converting USERPASS_WIFSTR %s -> %s != %s\n",G.USERPASS_WIFSTR,bits256_str(str,checkkey),bits256_str(str2,privkey)); - exit(-1); - } - conv_NXTpassword(userpass.bytes,pubkeyp->bytes,(uint8_t *)G.USERPASS_WIFSTR,(int32_t)strlen(G.USERPASS_WIFSTR)); - userpub = curve25519(userpass,curve25519_basepoint9()); - printf("userpass.(%s)\n",bits256_str(G.USERPASS,userpub)); - } - } - if ( coin->importedprivkey == 0 && coin->electrum == 0 && coin->userpass[0] != 0 && LP_getheight(coin) > 0 ) - { - LP_listunspent_issue(coin->symbol,coin->smartaddr,0); - if ( (retjson= LP_importprivkey(coin->symbol,tmpstr,coin->smartaddr,-1)) != 0 ) - { - if ( jobj(retjson,"error") != 0 ) - { - printf("cant importprivkey.%s -> (%s), abort session\n",coin->symbol,jprint(retjson,1)); - exit(-1); - } - free_json(retjson); - } - coin->importedprivkey = (uint32_t)time(NULL); - } - vcalc_sha256(0,checkkey.bytes,privkey.bytes,sizeof(privkey)); - checkkey.bytes[0] &= 248, checkkey.bytes[31] &= 127, checkkey.bytes[31] |= 64; - G.LP_mypub25519 = *pubkeyp = curve25519(checkkey,curve25519_basepoint9()); - G.LP_mypriv25519 = checkkey; - LP_pubkeyadd(G.LP_mypub25519); - return(privkey); -} - -void LP_privkey_updates(void *ctx,int32_t pubsock,char *passphrase) -{ - struct iguana_info *coin,*tmp; bits256 pubkey,privkey; uint8_t pubkey33[33]; int32_t initonly; - initonly = (passphrase != 0); - memset(privkey.bytes,0,sizeof(privkey)); - memset(pubkey.bytes,0,sizeof(pubkey)); - //printf("Total coins: %d\n", HASH_COUNT(LP_coins)); - //int num_iter = 0; - HASH_ITER(hh,LP_coins,coin,tmp) - { - //printf("LP_privkey_updates [%02d / %02d]\n", num_iter++, HASH_COUNT(LP_coins)); - if ( initonly != 0 ) - { - coin->counter = 0; - memset(coin->smartaddr,0,sizeof(coin->smartaddr)); - if ( bits256_nonz(privkey) == 0 || coin->smartaddr[0] == 0 ) - privkey = LP_privkeycalc(ctx,pubkey33,&pubkey,coin,passphrase,""); - } - //printf("i.%d of %d\n",i,LP_numcoins); - else if ( IAMLP == 0 || coin->inactive == 0 ) - { - //printf("from updates %s\n",coin->symbol); - if ( 0 && LP_privkey_init(pubsock,coin,G.LP_privkey,G.LP_mypub25519) == 0 && (LP_rand() % 10) == 0 ) - { - //LP_postutxos(coin->symbol,coin->smartaddr); - } - } - } -} - -int32_t LP_passphrase_init(char *passphrase,char *gui) -{ - static void *ctx; int32_t iambob,counter; struct LP_utxoinfo *utxo,*tmp; - if ( ctx == 0 ) - ctx = bitcoin_ctx(); - if ( G.LP_pendingswaps != 0 ) - return(-1); - G.initializing = 1; - if ( gui == 0 ) - gui = "cli"; - counter = G.USERPASS_COUNTER; - while ( G.waiting == 0 ) - { - printf("waiting for G.waiting\n"); - sleep(5); - } - for (iambob=0; iambob<2; iambob++) - { - if ( G.LP_utxoinfos[iambob] != 0 ) - { - HASH_ITER(hh,G.LP_utxoinfos[iambob],utxo,tmp) - { - HASH_DELETE(hh,G.LP_utxoinfos[iambob],utxo); - //free(utxo); - } - } - if ( G.LP_utxoinfos2[iambob] != 0 ) - { - G.LP_utxoinfos2[iambob] = 0; - /*HASH_ITER(hh,G.LP_utxoinfos2[iambob],utxo,tmp) - { - HASH_DELETE(hh,G.LP_utxoinfos2[iambob],utxo); - free(utxo); - }*/ - } - } - memset(&G,0,sizeof(G)); - LP_privkey_updates(ctx,LP_mypubsock,passphrase); - init_hexbytes_noT(G.LP_myrmd160str,G.LP_myrmd160,20); - G.LP_sessionid = (uint32_t)time(NULL); - safecopy(G.gui,gui,sizeof(G.gui)); - G.USERPASS_COUNTER = counter; - G.initializing = 0; - return(0); -} - - From fdb14004ae80c385b80bc0bf14b5b1871074f7ff Mon Sep 17 00:00:00 2001 From: jl777 Date: Sun, 26 Nov 2017 12:36:12 +0400 Subject: [PATCH 1269/1664] Test --- iguana/exchanges/LP_ordermatch.c | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/iguana/exchanges/LP_ordermatch.c b/iguana/exchanges/LP_ordermatch.c index 3f625ca72..d172642d9 100644 --- a/iguana/exchanges/LP_ordermatch.c +++ b/iguana/exchanges/LP_ordermatch.c @@ -600,7 +600,7 @@ char *LP_connectedalice(struct LP_quoteinfo *qp,char *pairstr) // alice LP_aliceid(qp->tradeid,qp->aliceid,"error1",0,0); return(clonestr("{\"result\",\"update stats\"}")); } - printf("CONNECTED numpending.%d tradeid.%u requestid.%u quoteid.%u\n",G.LP_pendingswaps,qp->tradeid,qp->R.requestid,qp->R.quoteid); + printf("CONNECTED numpending.%d tradeid.%u requestid.%u quoteid.%u pairstr.%s\n",G.LP_pendingswaps,qp->tradeid,qp->R.requestid,qp->R.quoteid,pairstr!=0?pairstr:""); LP_requestinit(&qp->R,qp->srchash,qp->desthash,qp->srccoin,qp->satoshis-qp->txfee,qp->destcoin,qp->destsatoshis-qp->desttxfee,qp->timestamp,qp->quotetime,DEXselector); printf("calculated requestid.%u quoteid.%u\n",qp->R.requestid,qp->R.quoteid); if ( LP_pendingswap(qp->R.requestid,qp->R.quoteid) > 0 ) @@ -865,7 +865,7 @@ int32_t LP_tradecommand(void *ctx,char *myipaddr,int32_t pubsock,cJSON *argjson, if ( (retstr= LP_quotereceived(argjson)) != 0 ) free(retstr); LP_reserved(ctx,myipaddr,pubsock,&Q); - } else LP_tradecommandQ(&Q,jstr(argjson,"pairstr")); + } else LP_tradecommandQ(&Q,jstr(argjson,"pair")); } return(retval); } @@ -892,9 +892,9 @@ int32_t LP_tradecommand(void *ctx,char *myipaddr,int32_t pubsock,cJSON *argjson, return(retval); } //printf("alice %s received CONNECTED.(%s)\n",bits256_str(str,G.LP_mypub25519),jprint(argjson,0)); - if ( (retstr= LP_connectedalice(&Q,jstr(argjson,"pairstr"))) != 0 ) + if ( (retstr= LP_connectedalice(&Q,jstr(argjson,"pair"))) != 0 ) free(retstr); - } else LP_tradecommandQ(&Q,jstr(argjson,"pairstr")); + } else LP_tradecommandQ(&Q,jstr(argjson,"pair")); } return(retval); } @@ -906,7 +906,7 @@ int32_t LP_tradecommand(void *ctx,char *myipaddr,int32_t pubsock,cJSON *argjson, } if ( Qtrades != 0 ) { - LP_tradecommandQ(&Q,jstr(argjson,"pairstr")); + LP_tradecommandQ(&Q,jstr(argjson,"pair")); return(retval); } price = ask; From 27c99fb3fe0f000c4c3c5bc670011b5413c73fd3 Mon Sep 17 00:00:00 2001 From: jl777 Date: Sun, 26 Nov 2017 12:40:49 +0400 Subject: [PATCH 1270/1664] Test --- iguana/exchanges/LP_remember.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/iguana/exchanges/LP_remember.c b/iguana/exchanges/LP_remember.c index 0aebcbcd1..db55baff5 100644 --- a/iguana/exchanges/LP_remember.c +++ b/iguana/exchanges/LP_remember.c @@ -1151,20 +1151,20 @@ cJSON *basilisk_remember(int64_t *KMDtotals,int64_t *BTCtotals,uint32_t requesti 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); if ( rswap.origfinishedflag == 0 && rswap.finishedflag != 0 ) { char fname[1024],*itemstr; FILE *fp; LP_numfinished++; printf("SWAP %u-%u finished LP_numfinished.%d !\n",requestid,quoteid,LP_numfinished); + if ( rswap.finishtime == 0 ) + rswap.finishtime = (uint32_t)time(NULL); if ( rswap.tradeid != 0 ) LP_tradebot_finished(rswap.tradeid,rswap.requestid,rswap.quoteid); sprintf(fname,"%s/SWAPS/%u-%u.finished",GLOBAL_DBDIR,rswap.requestid,rswap.quoteid), OS_compatible_path(fname); + item = LP_swap_json(&rswap); if ( (fp= fopen(fname,"wb")) != 0 ) { jaddstr(item,"method","tradestatus"); - if ( rswap.finishtime == 0 ) - rswap.finishtime = (uint32_t)time(NULL); jaddnum(item,"finishtime",rswap.finishtime); jaddstr(item,"gui",G.gui); //jaddbits256(item,"srchash",rswap.Q.srchash); @@ -1178,7 +1178,7 @@ cJSON *basilisk_remember(int64_t *KMDtotals,int64_t *BTCtotals,uint32_t requesti //LP_broadcast_message(LP_mypubsock,rswap.src,rswap.dest,zero,itemstr); fclose(fp); } - } + } else item = LP_swap_json(&rswap); for (i=0; i Date: Sun, 26 Nov 2017 13:48:13 +0400 Subject: [PATCH 1271/1664] Test --- iguana/exchanges/LP_include.h | 14 ++++ iguana/exchanges/LP_nativeDEX.c | 5 +- iguana/exchanges/LP_ordermatch.c | 132 ++++++++++++++++++++----------- iguana/exchanges/LP_signatures.c | 14 ++-- 4 files changed, 110 insertions(+), 55 deletions(-) diff --git a/iguana/exchanges/LP_include.h b/iguana/exchanges/LP_include.h index 7f0dfbd38..2b6b74cff 100644 --- a/iguana/exchanges/LP_include.h +++ b/iguana/exchanges/LP_include.h @@ -124,6 +124,11 @@ void emscripten_usleep(int32_t x); // returns immediate, no sense for sleeping #define ZKSNARK_PROOF_SIZE 296 #define ZCASH_SOLUTION_ELEMENTS 1344 +#define LP_REQUEST 0 +#define LP_RESERVED 1 +#define LP_CONNECT 2 +#define LP_CONNECTED 3 + extern char GLOBAL_DBDIR[]; extern int32_t IAMLP; @@ -418,6 +423,15 @@ struct electrum_info uint8_t buf[]; }; +struct LP_trade +{ + UT_hash_handle hh; + uint64_t aliceid; + uint32_t firsttime,lasttime; + char pairstr[63],funcid,iambob; + struct LP_quoteinfo Q[4]; +}; + uint32_t LP_sighash(char *symbol,int32_t zcash); int32_t LP_pubkey_sigcheck(struct LP_pubkey_info *pubp,cJSON *item); int32_t LP_pubkey_sigadd(cJSON *item,uint32_t timestamp,bits256 priv,bits256 pub,uint8_t *rmd160,uint8_t *pubsecp); diff --git a/iguana/exchanges/LP_nativeDEX.c b/iguana/exchanges/LP_nativeDEX.c index d003829b3..fae05fcf1 100644 --- a/iguana/exchanges/LP_nativeDEX.c +++ b/iguana/exchanges/LP_nativeDEX.c @@ -92,7 +92,7 @@ void LP_millistats_update(struct LP_millistats *mp) } #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,LP_reservedmutex,LP_nanorecvsmutex,LP_tradebotsmutex,LP_gcmutex,LP_inusemutex,LP_cJSONmutex,LP_logmutex,LP_statslogmutex; +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,LP_tradebotsmutex,LP_gcmutex,LP_inusemutex,LP_cJSONmutex,LP_logmutex,LP_statslogmutex,LP_tradesmutex; int32_t LP_canbind; char *Broadcaststr,*Reserved_msgs[2][1000]; int32_t num_Reserved_msgs[2],max_Reserved_msgs[2]; @@ -102,7 +102,7 @@ struct iguana_info *LP_coins; struct LP_pubkey_info *LP_pubkeyinfos; struct rpcrequest_info *LP_garbage_collector; struct LP_address_utxo *LP_garbage_collector2; - +struct LP_trade *LP_trades; //uint32_t LP_deadman_switch; uint16_t LP_fixed_pairport,LP_publicport; @@ -1090,6 +1090,7 @@ void LPinit(uint16_t myport,uint16_t mypullport,uint16_t mypubport,uint16_t mybu portable_mutex_init(&LP_cJSONmutex); portable_mutex_init(&LP_logmutex); portable_mutex_init(&LP_statslogmutex); + portable_mutex_init(&LP_tradesmutex); myipaddr = clonestr("127.0.0.1"); #ifndef _WIN32 #ifndef FROM_JS diff --git a/iguana/exchanges/LP_ordermatch.c b/iguana/exchanges/LP_ordermatch.c index d172642d9..1297eda93 100644 --- a/iguana/exchanges/LP_ordermatch.c +++ b/iguana/exchanges/LP_ordermatch.c @@ -801,15 +801,93 @@ int32_t LP_validSPV(char *symbol,char *coinaddr,bits256 txid,int32_t vout) return(0); } -void LP_tradecommandQ(struct LP_quoteinfo *qp,char *pairstr) +int32_t LP_trades_alicevalidate(void *ctx,struct LP_quoteinfo *qp) { - + double qprice; struct LP_utxoinfo A,B,*autxo,*butxo; + char str[65]; printf("alice %s received RESERVED.(%llu)\n",bits256_str(str,G.LP_mypub25519),(long long)qp->aliceid); + autxo = &A; + butxo = &B; + memset(autxo,0,sizeof(*autxo)); + memset(butxo,0,sizeof(*butxo)); + LP_abutxo_set(autxo,butxo,qp); + if ( (qprice= LP_quote_validate(autxo,butxo,qp,0)) <= SMALLVAL ) + { + printf("reserved quote validate error %.0f\n",qprice); + return((int32_t)qprice); + } + if ( LP_validSPV(qp->srccoin,qp->coinaddr,qp->txid,qp->vout) < 0 ) + { + printf("%s src %s failed SPV check\n",qp->srccoin,bits256_str(str,qp->txid)); + return(-44); + } + else if ( LP_validSPV(qp->srccoin,qp->coinaddr,qp->txid2,qp->vout2) < 0 ) + { + printf("%s src2 %s failed SPV check\n",qp->srccoin,bits256_str(str,qp->txid2)); + return(-55); + } + return(0); +} + +void LP_trades_gotreserved(void *ctx,struct LP_quoteinfo *qp) +{ + char *retstr; + char str[65]; printf("alice %s received RESERVED.(%llu)\n",bits256_str(str,G.LP_mypub25519),(long long)qp->aliceid); + if ( LP_trades_alicevalidate(ctx,qp) == 0 ) + { + LP_aliceid(qp->tradeid,qp->aliceid,"reserved",0,0); + if ( (retstr= LP_quotereceived(qp)) != 0 ) + free(retstr); + LP_reserved(ctx,LP_myipaddr,LP_mypubsock,qp); + } +} + +void LP_trades_gotconnected(void *ctx,struct LP_quoteinfo *qp,char *pairstr) +{ + char *retstr; + char str[65]; printf("alice %s received CONNECTED.(%llu)\n",bits256_str(str,G.LP_mypub25519),(long long)qp->aliceid); + if ( LP_trades_alicevalidate(ctx,qp) == 0 ) + { + LP_aliceid(qp->tradeid,qp->aliceid,"connected",0,0); + if ( (retstr= LP_connectedalice(qp,pairstr)) != 0 ) + free(retstr); + } +} + +void LP_tradecommandQ(struct LP_quoteinfo *qp,char *pairstr,int32_t funcid) +{ + struct LP_trade *tp; uint64_t aliceid; int32_t iambob; + if ( funcid < 0 || funcid >= sizeof(tp->Q)/sizeof(*tp->Q) ) + return; + if ( funcid == LP_REQUEST || funcid == LP_CONNECT ) + iambob = 1; + else iambob = 0; + aliceid = qp->aliceid; + portable_mutex_lock(&LP_tradesmutex); + HASH_FIND(hh,LP_trades,&aliceid,sizeof(aliceid),tp); + if ( tp == 0 ) + { + tp = calloc(1,sizeof(*tp)); + tp->funcid = funcid; + tp->iambob = iambob; + tp->aliceid = aliceid; + tp->firsttime = tp->lasttime = (uint32_t)time(NULL); + tp->Q[funcid] = *qp; + if ( pairstr != 0 ) + safecopy(tp->pairstr,pairstr,sizeof(tp->pairstr)); + HASH_ADD(hh,LP_trades,aliceid,sizeof(aliceid),tp); + } + else if ( tp->Q[funcid].aliceid == 0 && tp->iambob == iambob ) + { + tp->Q[funcid] = *qp; + tp->lasttime = (uint32_t)time(NULL); + } + portable_mutex_unlock(&LP_tradesmutex); } int32_t LP_tradecommand(void *ctx,char *myipaddr,int32_t pubsock,cJSON *argjson,uint8_t *data,int32_t datalen) { int32_t Qtrades = 0; - char *method,*msg,*retstr,str[65]; int32_t DEXselector = 0; uint64_t aliceid; cJSON *retjson; double qprice,range,bestprice,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 r,counter,retval = -1,max=(int32_t)(sizeof(utxos)/sizeof(*utxos)); + char *method,*msg,str[65]; int32_t DEXselector = 0; uint64_t aliceid; cJSON *retjson; double qprice,range,bestprice,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 r,counter,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) ) { LP_quoteparse(&Q,argjson); @@ -844,28 +922,8 @@ int32_t LP_tradecommand(void *ctx,char *myipaddr,int32_t pubsock,cJSON *argjson, if ( bits256_cmp(G.LP_mypub25519,Q.desthash) == 0 && bits256_cmp(G.LP_mypub25519,Q.srchash) != 0 && Q.quotetime > time(NULL)-20 && LP_alice_eligible(Q.quotetime) > 0 ) { if ( Qtrades == 0 ) - { - printf("alice %s received RESERVED.(%s)\n",bits256_str(str,G.LP_mypub25519),jprint(argjson,0)); - if ( (qprice= LP_quote_validate(autxo,butxo,&Q,0)) <= SMALLVAL ) - { - printf("reserved quote validate error %.0f\n",qprice); - return(retval); - } - if ( LP_validSPV(Q.srccoin,Q.coinaddr,Q.txid,Q.vout) < 0 ) - { - printf("%s src %s failed SPV check\n",Q.srccoin,bits256_str(str,Q.txid)); - return(retval); - } - else if ( LP_validSPV(Q.srccoin,Q.coinaddr,Q.txid2,Q.vout2) < 0 ) - { - printf("%s src2 %s failed SPV check\n",Q.srccoin,bits256_str(str,Q.txid2)); - return(retval); - } - LP_aliceid(Q.tradeid,Q.aliceid,"reserved",0,0); - if ( (retstr= LP_quotereceived(argjson)) != 0 ) - free(retstr); - LP_reserved(ctx,myipaddr,pubsock,&Q); - } else LP_tradecommandQ(&Q,jstr(argjson,"pair")); + LP_trades_gotreserved(ctx,&Q); + else LP_tradecommandQ(&Q,jstr(argjson,"pair"),LP_RESERVED); } return(retval); } @@ -875,26 +933,8 @@ int32_t LP_tradecommand(void *ctx,char *myipaddr,int32_t pubsock,cJSON *argjson, if ( bits256_cmp(G.LP_mypub25519,Q.desthash) == 0 && bits256_cmp(G.LP_mypub25519,Q.srchash) != 0 ) { if ( Qtrades == 0 ) - { - if ( (qprice= LP_quote_validate(autxo,butxo,&Q,0)) <= SMALLVAL ) - { - printf("quote validate error %.0f\n",qprice); - return(retval); - } - if ( LP_validSPV(Q.srccoin,Q.coinaddr,Q.txid,Q.vout) < 0 ) - { - printf("%s src %s failed SPV check\n",Q.srccoin,bits256_str(str,Q.txid)); - return(retval); - } - else if (LP_validSPV(Q.srccoin,Q.coinaddr,Q.txid2,Q.vout2) < 0 ) - { - printf("%s src2 %s failed SPV check\n",Q.srccoin,bits256_str(str,Q.txid2)); - return(retval); - } - //printf("alice %s received CONNECTED.(%s)\n",bits256_str(str,G.LP_mypub25519),jprint(argjson,0)); - if ( (retstr= LP_connectedalice(&Q,jstr(argjson,"pair"))) != 0 ) - free(retstr); - } else LP_tradecommandQ(&Q,jstr(argjson,"pair")); + LP_trades_gotconnected(ctx,&Q,jstr(argjson,"pair")); + else LP_tradecommandQ(&Q,jstr(argjson,"pair"),LP_CONNECTED); } return(retval); } @@ -906,7 +946,7 @@ int32_t LP_tradecommand(void *ctx,char *myipaddr,int32_t pubsock,cJSON *argjson, } if ( Qtrades != 0 ) { - LP_tradecommandQ(&Q,jstr(argjson,"pair")); + LP_tradecommandQ(&Q,jstr(argjson,"pair"),strcmp(method,"request") == 0 ? LP_REQUEST : LP_CONNECT); return(retval); } price = ask; diff --git a/iguana/exchanges/LP_signatures.c b/iguana/exchanges/LP_signatures.c index 5f6eab03c..dac28c62e 100644 --- a/iguana/exchanges/LP_signatures.c +++ b/iguana/exchanges/LP_signatures.c @@ -194,15 +194,15 @@ int32_t LP_quotedestinfo(struct LP_quoteinfo *qp,bits256 desttxid,int32_t destvo return(0); } -char *LP_quotereceived(cJSON *argjson) +char *LP_quotereceived(struct LP_quoteinfo *qp) { - struct LP_cacheinfo *ptr; double price; struct LP_quoteinfo Q; - LP_quoteparse(&Q,argjson); - price = (double)Q.destsatoshis / (Q.satoshis - Q.txfee); - if ( (ptr= LP_cacheadd(Q.srccoin,Q.destcoin,Q.txid,Q.vout,price,&Q)) != 0 ) + struct LP_cacheinfo *ptr; double price; + //LP_quoteparse(&Q,argjson); + price = (double)qp->destsatoshis / (qp->satoshis - qp->txfee); + if ( (ptr= LP_cacheadd(qp->srccoin,qp->destcoin,qp->txid,qp->vout,price,qp)) != 0 ) { - ptr->Q = Q; - printf(">>>>>>>>>> received quote %s/%s %.8f\n",Q.srccoin,Q.destcoin,price); + ptr->Q = *qp; + printf(">>>>>>>>>> received quote %s/%s %.8f\n",qp->srccoin,qp->destcoin,price); return(clonestr("{\"result\":\"updated\"}")); } else return(clonestr("{\"error\":\"nullptr\"}")); } From 2d0f8e3ccbae495a2c17cd5bc34ce3ec1e02c5b9 Mon Sep 17 00:00:00 2001 From: jl777 Date: Sun, 26 Nov 2017 14:49:50 +0400 Subject: [PATCH 1272/1664] Test --- iguana/exchanges/LP_ordermatch.c | 326 +++++++++++++++++-------------- 1 file changed, 177 insertions(+), 149 deletions(-) diff --git a/iguana/exchanges/LP_ordermatch.c b/iguana/exchanges/LP_ordermatch.c index 1297eda93..51e022661 100644 --- a/iguana/exchanges/LP_ordermatch.c +++ b/iguana/exchanges/LP_ordermatch.c @@ -570,23 +570,6 @@ int32_t LP_alice_eligible(uint32_t quotetime) return(Alice_expiration == 0 || time(NULL) < Alice_expiration); } -void LP_reserved(void *ctx,char *myipaddr,int32_t mypubsock,struct LP_quoteinfo *qp) -{ - double price=0.,maxprice = LP_Alicemaxprice; - if ( LP_quotecmp(0,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 ) - { - qp->tradeid = LP_Alicequery.tradeid; - LP_Alicereserved = *qp; - LP_alicequery_clear(); - printf("send CONNECT\n"); - LP_query(ctx,myipaddr,mypubsock,"connect",qp); - } else printf("LP_reserved price %.8f vs maxprice %.8f\n",price,maxprice*1.005); - } else printf("probably a timeout, reject reserved due to not eligible.%d or mismatched quote price %.8f vs maxprice %.8f\n",LP_alice_eligible(qp->quotetime),price,maxprice); -} - char *LP_connectedalice(struct LP_quoteinfo *qp,char *pairstr) // alice { cJSON *retjson; double bid,ask,price,qprice; int32_t pairsock = -1; int32_t DEXselector = 0; struct LP_utxoinfo *autxo,A,B,*butxo; struct basilisk_swap *swap; struct iguana_info *coin; @@ -828,6 +811,157 @@ int32_t LP_trades_alicevalidate(void *ctx,struct LP_quoteinfo *qp) return(0); } +void LP_reserved(void *ctx,char *myipaddr,int32_t mypubsock,struct LP_quoteinfo *qp) +{ + double price=0.,maxprice = LP_Alicemaxprice; + if ( LP_quotecmp(0,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 ) + { + qp->tradeid = LP_Alicequery.tradeid; + LP_Alicereserved = *qp; + LP_alicequery_clear(); + printf("send CONNECT\n"); + LP_query(ctx,myipaddr,mypubsock,"connect",qp); + } else printf("LP_reserved price %.8f vs maxprice %.8f\n",price,maxprice*1.005); + } else printf("probably a timeout, reject reserved due to not eligible.%d or mismatched quote price %.8f vs maxprice %.8f\n",LP_alice_eligible(qp->quotetime),price,maxprice); +} + +double LP_trades_bobprice(double *bidp,double *askp,struct LP_quoteinfo *qp) +{ + double price; struct iguana_info *coin; char str[65]; + price = LP_myprice(bidp,askp,qp->srccoin,qp->destcoin); + if ( (coin= LP_coinfind(qp->srccoin)) == 0 || price <= SMALLVAL || *askp <= SMALLVAL ) + { + //printf("this node has no price for %s/%s\n",qp->srccoin,qp->destcoin); + return(0.); + } + price = *askp; + //printf("MYPRICE %s/%s %.8f vs qprice %.8f\n",qp->srccoin,qp->destcoin,price,qprice); + if ( LP_validSPV(qp->destcoin,qp->destaddr,qp->desttxid,qp->destvout) < 0 ) + { + printf("%s dest %s failed SPV check\n",qp->destcoin,bits256_str(str,qp->desttxid)); + return(0.); + } + else if (LP_validSPV(qp->destcoin,qp->destaddr,qp->feetxid,qp->feevout) < 0 ) + { + printf("%s dexfee %s failed SPV check\n",qp->destcoin,bits256_str(str,qp->feetxid)); + return(0.); + } + return(*askp); +} + +double LP_trades_pricevalidate(struct LP_quoteinfo *qp,struct iguana_info *coin,double price) +{ + double qprice; struct LP_utxoinfo A,B,*autxo,*butxo; + autxo = &A; + butxo = &B; + memset(autxo,0,sizeof(*autxo)); + memset(butxo,0,sizeof(*butxo)); + LP_abutxo_set(autxo,butxo,qp); + if ( strcmp(qp->coinaddr,coin->smartaddr) != 0 ) + { + printf("bob is patching qp->coinaddr %s mismatch != %s\n",qp->coinaddr,coin->smartaddr); + strcpy(qp->coinaddr,coin->smartaddr); + } + 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,qp->txid),qp->vout,bits256_str(str2,qp->txid2),qp->vout2,dstr(qp->satoshis),dstr(qp->destsatoshis)); + return(-66); + } + if ( (qprice= LP_quote_validate(autxo,butxo,qp,1)) <= SMALLVAL ) + { + printf("quote validate error %.0f\n",qprice); + return(-3); + } + if ( qprice < (price - 0.00000001) * 0.998 ) + { + printf(" quote price %.8f too low vs %.8f for %s/%s %.8f < %.8f\n",qprice,price,qp->srccoin,qp->destcoin,qprice,(price - 0.00000001) * 0.998); + return(-77); + } + return(qprice); +} + +void LP_trades_gotrequest(void *ctx,struct LP_quoteinfo *qp,char *pairstr) +{ + double price,qprice,bestprice,range,bid,ask; struct iguana_info *coin; struct LP_utxoinfo A,B,*autxo,*butxo; cJSON *reqjson; char str[65]; struct LP_address_utxo *utxos[1000]; int32_t r,counter,max = (int32_t)(sizeof(utxos)/sizeof(*utxos)); + if ( (coin= LP_coinfind(qp->srccoin)) == 0 ) + return; + if ( (price= LP_trades_bobprice(&bid,&ask,qp)) == 0. ) + return; + autxo = &A; + butxo = &B; + memset(autxo,0,sizeof(*autxo)); + memset(butxo,0,sizeof(*butxo)); + LP_abutxo_set(autxo,butxo,qp); + if ( bits256_nonz(qp->srchash) == 0 || bits256_cmp(qp->srchash,G.LP_mypub25519) == 0 ) + { + qprice = (double)qp->destsatoshis / qp->satoshis; + strcpy(qp->gui,G.gui); + strcpy(qp->coinaddr,coin->smartaddr); + strcpy(butxo->coinaddr,coin->smartaddr); + qp->srchash = G.LP_mypub25519; + memset(&qp->txid,0,sizeof(qp->txid)); + memset(&qp->txid2,0,sizeof(qp->txid2)); + qp->vout = qp->vout2 = -1; + } else return; + if ( qprice > price ) + { + r = (LP_rand() % 100); + range = (qprice - price); + price += (r * range) / 100.; + bestprice = LP_bob_competition(&counter,qp->aliceid,price,0); + printf("%llu >>>>>>> qprice %.8f r.%d range %.8f -> %.8f, bestprice %.8f counter.%d\n",(long long)qp->aliceid,qprice,r,range,price,bestprice,counter); + if ( counter > 3 && price >= bestprice-SMALLVAL ) // skip if late or bad price + return; + } else return; + //LP_RTmetrics_update(qp->srccoin,qp->destcoin); + if ( LP_RTmetrics_blacklisted(qp->desthash) >= 0 ) + { + printf("request from blacklisted %s, ignore\n",bits256_str(str,qp->desthash)); + return; + } + LP_address_utxo_reset(coin); + if ( (butxo= LP_address_myutxopair(butxo,1,utxos,max,LP_coinfind(qp->srccoin),qp->coinaddr,qp->txfee,dstr(qp->destsatoshis),price,qp->desttxfee)) != 0 ) + { + strcpy(qp->gui,G.gui); + strcpy(qp->coinaddr,coin->smartaddr); + qp->srchash = G.LP_mypub25519; + qp->txid = butxo->payment.txid; + qp->vout = butxo->payment.vout; + qp->txid2 = butxo->deposit.txid; + qp->vout2 = butxo->deposit.vout; + qp->satoshis = butxo->swap_satoshis; + qp->quotetime = (uint32_t)time(NULL); + } + else + { + printf("cant find utxopair aliceid.%llu %s/%s %.8f -> relvol %.8f\n",(long long)qp->aliceid,qp->srccoin,qp->destcoin,dstr(LP_basesatoshis(dstr(qp->destsatoshis),price,qp->txfee,qp->desttxfee)),dstr(qp->destsatoshis)); + return; + } + if ( (qprice= LP_trades_pricevalidate(qp,coin,price)) < 0. ) + return; + if ( LP_allocated(qp->txid,qp->vout) == 0 && LP_allocated(qp->txid2,qp->vout2) == 0 ) + { + reqjson = LP_quotejson(qp); + LP_unavailableset(qp->txid,qp->vout,qp->timestamp + LP_RESERVETIME,qp->desthash); + LP_unavailableset(qp->txid2,qp->vout2,qp->timestamp + LP_RESERVETIME,qp->desthash); + if ( qp->quotetime == 0 ) + qp->quotetime = (uint32_t)time(NULL); + jaddnum(reqjson,"quotetime",qp->quotetime); + jaddnum(reqjson,"pending",qp->timestamp + LP_RESERVETIME); + jaddstr(reqjson,"method","reserved"); + bits256 zero; + memset(zero.bytes,0,sizeof(zero)); + LP_reserved_msg(1,qp->srccoin,qp->destcoin,zero,jprint(reqjson,0)); + //LP_reserved_msg(0,qp->srccoin,qp->destcoin,zero,jprint(reqjson,0)); + //sleep(1); + //LP_reserved_msg(1,qp->srccoin,qp->destcoin,qp->desthash,jprint(reqjson,0)); + free_json(reqjson); + } else printf("request processing selected ineligible utxos?\n"); +} + void LP_trades_gotreserved(void *ctx,struct LP_quoteinfo *qp) { char *retstr; @@ -841,6 +975,24 @@ void LP_trades_gotreserved(void *ctx,struct LP_quoteinfo *qp) } } +void LP_trades_gotconnect(void *ctx,struct LP_quoteinfo *qp,char *pairstr) +{ + double price,qprice,bid,ask; struct iguana_info *coin; + if ( (coin= LP_coinfind(qp->srccoin)) == 0 ) + return; + if ( (price= LP_trades_bobprice(&bid,&ask,qp)) == 0. ) + return; + if ( bits256_cmp(G.LP_mypub25519,qp->srchash) != 0 || bits256_cmp(G.LP_mypub25519,qp->desthash) == 0 ) + return; + if ( (qprice= LP_trades_pricevalidate(qp,coin,price)) < 0. ) + return; + if ( LP_reservation_check(qp->txid,qp->vout,qp->desthash) == 0 && LP_reservation_check(qp->txid2,qp->vout2,qp->desthash) == 0 ) + { + LP_connectstartbob(ctx,LP_mypubsock,qp->srccoin,qp->destcoin,qprice,qp); + return; + } else printf("connect message from non-reserved (%llu)\n",(long long)qp->aliceid); +} + void LP_trades_gotconnected(void *ctx,struct LP_quoteinfo *qp,char *pairstr) { char *retstr; @@ -887,7 +1039,7 @@ void LP_tradecommandQ(struct LP_quoteinfo *qp,char *pairstr,int32_t funcid) int32_t LP_tradecommand(void *ctx,char *myipaddr,int32_t pubsock,cJSON *argjson,uint8_t *data,int32_t datalen) { int32_t Qtrades = 0; - char *method,*msg,str[65]; int32_t DEXselector = 0; uint64_t aliceid; cJSON *retjson; double qprice,range,bestprice,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 r,counter,retval = -1,max=(int32_t)(sizeof(utxos)/sizeof(*utxos)); + char *method,str[65]; int32_t DEXselector = 0; uint64_t aliceid; double qprice,bestprice,price,bid,ask; struct iguana_info *coin; struct LP_quoteinfo Q; int32_t counter,retval=-1; if ( (method= jstr(argjson,"method")) != 0 && (strcmp(method,"reserved") == 0 ||strcmp(method,"connected") == 0 || strcmp(method,"request") == 0 || strcmp(method,"connect") == 0) ) { LP_quoteparse(&Q,argjson); @@ -895,11 +1047,6 @@ int32_t LP_tradecommand(void *ctx,char *myipaddr,int32_t pubsock,cJSON *argjson, LP_tradecommand_log(argjson); printf("%-4d (%-10u %10u) %12s id.%22llu %5s/%-5s %12.8f -> %11.8f price %11.8f | RT.%d %d\n",(uint32_t)time(NULL) % 3600,Q.R.requestid,Q.R.quoteid,method,(long long)Q.aliceid,Q.srccoin,Q.destcoin,dstr(Q.satoshis),dstr(Q.destsatoshis),(double)Q.destsatoshis/Q.satoshis,LP_RTcount,LP_swapscount); retval = 1; - autxo = &A; - butxo = &B; - memset(autxo,0,sizeof(*autxo)); - memset(butxo,0,sizeof(*butxo)); - LP_abutxo_set(autxo,butxo,&Q); aliceid = j64bits(argjson,"aliceid"); qprice = jdouble(argjson,"price"); if ( strcmp(method,"reserved") == 0 ) @@ -925,7 +1072,6 @@ int32_t LP_tradecommand(void *ctx,char *myipaddr,int32_t pubsock,cJSON *argjson, LP_trades_gotreserved(ctx,&Q); else LP_tradecommandQ(&Q,jstr(argjson,"pair"),LP_RESERVED); } - return(retval); } else if ( strcmp(method,"connected") == 0 ) { @@ -936,7 +1082,6 @@ int32_t LP_tradecommand(void *ctx,char *myipaddr,int32_t pubsock,cJSON *argjson, LP_trades_gotconnected(ctx,&Q,jstr(argjson,"pair")); else LP_tradecommandQ(&Q,jstr(argjson,"pair"),LP_CONNECTED); } - return(retval); } price = LP_myprice(&bid,&ask,Q.srccoin,Q.destcoin); if ( (coin= LP_coinfind(Q.srccoin)) == 0 || price <= SMALLVAL || ask <= SMALLVAL ) @@ -944,23 +1089,6 @@ int32_t LP_tradecommand(void *ctx,char *myipaddr,int32_t pubsock,cJSON *argjson, //printf("this node has no price for %s/%s\n",Q.srccoin,Q.destcoin); return(retval); } - if ( Qtrades != 0 ) - { - LP_tradecommandQ(&Q,jstr(argjson,"pair"),strcmp(method,"request") == 0 ? LP_REQUEST : LP_CONNECT); - return(retval); - } - price = ask; - //printf("MYPRICE %s/%s %.8f vs qprice %.8f\n",Q.srccoin,Q.destcoin,price,qprice); - if ( LP_validSPV(Q.destcoin,Q.destaddr,Q.desttxid,Q.destvout) < 0 ) - { - printf("%s dest %s failed SPV check\n",Q.destcoin,bits256_str(str,Q.desttxid)); - return(retval); - } - else if (LP_validSPV(Q.destcoin,Q.destaddr,Q.feetxid,Q.feevout) < 0 ) - { - printf("%s dexfee %s failed SPV check\n",Q.destcoin,bits256_str(str,Q.feetxid)); - return(retval); - } if ( LP_aliceonly(Q.srccoin) > 0 ) { printf("{\"error\":\"GAME can only be alice coin\"}\n"); @@ -968,117 +1096,17 @@ int32_t LP_tradecommand(void *ctx,char *myipaddr,int32_t pubsock,cJSON *argjson, } if ( strcmp(method,"request") == 0 ) { - char str[65]; - if ( bits256_nonz(Q.srchash) == 0 || bits256_cmp(Q.srchash,G.LP_mypub25519) == 0 ) - { - qprice = (double)Q.destsatoshis / Q.satoshis; - strcpy(Q.gui,G.gui); - strcpy(Q.coinaddr,coin->smartaddr); - strcpy(butxo->coinaddr,coin->smartaddr); - Q.srchash = G.LP_mypub25519; - memset(&Q.txid,0,sizeof(Q.txid)); - memset(&Q.txid2,0,sizeof(Q.txid2)); - Q.vout = Q.vout2 = -1; - } else return(retval); - if ( qprice > price ) - { - r = (LP_rand() % 100); - range = (qprice - price); - price += (r * range) / 100.; - bestprice = LP_bob_competition(&counter,aliceid,price,0); - printf("%llu >>>>>>> price %.8f qprice %.8f r.%d range %.8f -> %.8f, bestprice %.8f counter.%d\n",(long long)aliceid,ask,qprice,r,range,price,bestprice,counter); - if ( counter > 3 && price >= bestprice-SMALLVAL ) // skip if late or bad price - return(retval); - } else return(retval); - //LP_RTmetrics_update(Q.srccoin,Q.destcoin); - if ( LP_RTmetrics_blacklisted(Q.desthash) >= 0 ) - { - printf("request from blacklisted %s, ignore\n",bits256_str(str,Q.desthash)); - return(retval); - } - LP_address_utxo_reset(coin); - if ( (butxo= LP_address_myutxopair(butxo,1,utxos,max,LP_coinfind(Q.srccoin),Q.coinaddr,Q.txfee,dstr(Q.destsatoshis),price,Q.desttxfee)) != 0 ) - { - strcpy(Q.gui,G.gui); - strcpy(Q.coinaddr,coin->smartaddr); - Q.srchash = G.LP_mypub25519; - Q.txid = butxo->payment.txid; - Q.vout = butxo->payment.vout; - Q.txid2 = butxo->deposit.txid; - Q.vout2 = butxo->deposit.vout; - Q.satoshis = butxo->swap_satoshis; - Q.quotetime = (uint32_t)time(NULL); - printf("found %.8f -> %.8f newprice %.8f vs ask %.8f += %.8f qprice %.8f\n",dstr(Q.satoshis),dstr(Q.destsatoshis),(double)Q.destsatoshis/Q.satoshis,ask,price,qprice); - } - else - { - printf("cant find utxopair aliceid.%llu %s/%s %.8f -> relvol %.8f\n",(long long)aliceid,Q.srccoin,Q.destcoin,dstr(LP_basesatoshis(dstr(Q.destsatoshis),price,Q.txfee,Q.desttxfee)),dstr(Q.destsatoshis)); - return(retval); - } + if ( Qtrades == 0 ) + LP_trades_gotrequest(ctx,&Q,jstr(argjson,"pair")); + else LP_tradecommandQ(&Q,jstr(argjson,"pair"),LP_REQUEST); } else if ( strcmp(method,"connect") == 0 ) { - if ( bits256_cmp(G.LP_mypub25519,Q.srchash) != 0 || bits256_cmp(G.LP_mypub25519,Q.desthash) == 0 ) - return(retval); - } - if ( strcmp(Q.coinaddr,coin->smartaddr) != 0 ) - { - printf("bob is patching Q.coinaddr %s mismatch != %s\n",Q.coinaddr,coin->smartaddr); - strcpy(Q.coinaddr,coin->smartaddr); - } - 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(retval); - } - if ( (qprice= LP_quote_validate(autxo,butxo,&Q,1)) <= SMALLVAL ) - { - printf("quote validate error %.0f\n",qprice); - return(-3); - } - if ( qprice < (ask - 0.00000001) * 0.998 ) - { - printf("(%.8f %.8f) quote price %.8f too low vs %.8f for %s/%s %.8f < %.8f\n",bid,ask,qprice,price,Q.srccoin,Q.destcoin,qprice,(ask - 0.00000001) * 0.998); - return(retval); - } - char *astr = jprint(argjson,0); - char str[65],str2[65]; printf("(%s/v%d %s/v%d) TRADECOMMAND.(%s)\n",bits256_str(str,Q.txid),Q.vout,bits256_str(str2,Q.txid2),Q.vout2,astr); - free(astr); - if ( strcmp(method,"request") == 0 ) // bob needs apayment + fee tx's - { - if ( LP_allocated(Q.txid,Q.vout) == 0 && LP_allocated(Q.txid2,Q.vout2) == 0 ) - { - retjson = LP_quotejson(&Q); - LP_unavailableset(Q.txid,Q.vout,Q.timestamp + LP_RESERVETIME,Q.desthash); - LP_unavailableset(Q.txid2,Q.vout2,Q.timestamp + LP_RESERVETIME,Q.desthash); - if ( Q.quotetime == 0 ) - Q.quotetime = (uint32_t)time(NULL); - jaddnum(retjson,"quotetime",Q.quotetime); - jaddnum(retjson,"pending",Q.timestamp + LP_RESERVETIME); - //jaddbits256(retjson,"desthash",Q.desthash); - jaddstr(retjson,"method","reserved"); - msg = jprint(retjson,1); - printf("return after queued RESERVED: set swappending.%u accept qprice %.8f, min %.8f\n(%s)\n",Q.timestamp + LP_RESERVETIME,qprice,ask,msg); - bits256 zero; - memset(zero.bytes,0,sizeof(zero)); - LP_reserved_msg(1,Q.srccoin,Q.destcoin,zero,clonestr(msg)); - //LP_reserved_msg(0,Q.srccoin,Q.destcoin,zero,clonestr(msg)); - sleep(1); - LP_reserved_msg(1,Q.srccoin,Q.destcoin,Q.desthash,clonestr(msg)); - free(msg); - butxo->T.lasttime = (uint32_t)time(NULL); - return(retval); - } else printf("request processing selected ineligible utxos?\n"); - } - else if ( strcmp(method,"connect") == 0 ) // bob - { - retval = 4; - if ( LP_reservation_check(Q.txid,Q.vout,Q.desthash) == 0 && LP_reservation_check(Q.txid2,Q.vout2,Q.desthash) == 0 ) - { - LP_connectstartbob(ctx,pubsock,Q.srccoin,Q.destcoin,qprice,&Q); - return(retval); - } else printf("connect message from non-reserved (%s)\n",jprint(argjson,0)); + if ( Qtrades == 0 ) + LP_trades_gotconnect(ctx,&Q,jstr(argjson,"pair")); + else LP_tradecommandQ(&Q,jstr(argjson,"pair"),LP_CONNECT); } + return(retval); } return(retval); } From e1cba16c3cf4c0be068fb2cac94342e5484b285d Mon Sep 17 00:00:00 2001 From: jl777 Date: Sun, 26 Nov 2017 16:20:33 +0400 Subject: [PATCH 1273/1664] Test --- iguana/exchanges/LP_include.h | 5 +- iguana/exchanges/LP_nativeDEX.c | 77 ++++------- iguana/exchanges/LP_ordermatch.c | 211 +++++++++++++++++++++++------ iguana/exchanges/LP_statemachine.c | 14 ++ 4 files changed, 218 insertions(+), 89 deletions(-) diff --git a/iguana/exchanges/LP_include.h b/iguana/exchanges/LP_include.h index 2b6b74cff..0ff04e7ff 100644 --- a/iguana/exchanges/LP_include.h +++ b/iguana/exchanges/LP_include.h @@ -427,8 +427,9 @@ struct LP_trade { UT_hash_handle hh; uint64_t aliceid; - uint32_t firsttime,lasttime; - char pairstr[63],funcid,iambob; + double bestprice; + uint32_t negotiationdone,connectsent,firsttime,lasttime,firstprocessed,lastprocessed,newtime; + char pairstr[63],firstfuncid,newfuncid,iambob; struct LP_quoteinfo Q[4]; }; diff --git a/iguana/exchanges/LP_nativeDEX.c b/iguana/exchanges/LP_nativeDEX.c index fae05fcf1..a38a99c97 100644 --- a/iguana/exchanges/LP_nativeDEX.c +++ b/iguana/exchanges/LP_nativeDEX.c @@ -17,7 +17,6 @@ // LP_nativeDEX.c // marketmaker // -// alice waiting for bestprice // big BTC swaps // delay swap credit back until notarization // electrum dynamic trust over 1000 tx @@ -46,7 +45,7 @@ struct LP_millistats double lastmilli,millisum,threshold; uint32_t count; char name[64]; -} LP_psockloop_stats,LP_reserved_msgs_stats,utxosQ_loop_stats,command_rpcloop_stats,queue_loop_stats,prices_loop_stats,LP_coinsloop_stats,LP_coinsloopBTC_stats,LP_coinsloopKMD_stats,LP_pubkeysloop_stats,LP_privkeysloop_stats,LP_swapsloop_stats,LP_gcloop_stats; +} LP_psockloop_stats,LP_reserved_msgs_stats,utxosQ_loop_stats,command_rpcloop_stats,queue_loop_stats,prices_loop_stats,LP_coinsloop_stats,LP_coinsloopBTC_stats,LP_coinsloopKMD_stats,LP_pubkeysloop_stats,LP_swapsloop_stats,LP_gcloop_stats,LP_tradesloop_stats; extern int32_t IAMLP; void LP_millistats_update(struct LP_millistats *mp) @@ -67,7 +66,7 @@ void LP_millistats_update(struct LP_millistats *mp) mp = &LP_coinsloopBTC_stats, printf("%32s lag %10.2f millis, threshold %10.2f, ave %10.2f millis, count.%u\n",mp->name,OS_milliseconds() - mp->lastmilli,mp->threshold,mp->millisum/(mp->count > 0 ? mp->count: 1),mp->count); mp = &LP_coinsloopKMD_stats, printf("%32s lag %10.2f millis, threshold %10.2f, ave %10.2f millis, count.%u\n",mp->name,OS_milliseconds() - mp->lastmilli,mp->threshold,mp->millisum/(mp->count > 0 ? mp->count: 1),mp->count); mp = &LP_pubkeysloop_stats, printf("%32s lag %10.2f millis, threshold %10.2f, ave %10.2f millis, count.%u\n",mp->name,OS_milliseconds() - mp->lastmilli,mp->threshold,mp->millisum/(mp->count > 0 ? mp->count: 1),mp->count); - mp = &LP_privkeysloop_stats, printf("%32s lag %10.2f millis, threshold %10.2f, ave %10.2f millis, count.%u\n",mp->name,OS_milliseconds() - mp->lastmilli,mp->threshold,mp->millisum/(mp->count > 0 ? mp->count: 1),mp->count); + mp = &LP_tradesloop_stats, printf("%32s lag %10.2f millis, threshold %10.2f, ave %10.2f millis, count.%u\n",mp->name,OS_milliseconds() - mp->lastmilli,mp->threshold,mp->millisum/(mp->count > 0 ? mp->count: 1),mp->count); mp = &LP_swapsloop_stats, printf("%32s lag %10.2f millis, threshold %10.2f, ave %10.2f millis, count.%u\n",mp->name,OS_milliseconds() - mp->lastmilli,mp->threshold,mp->millisum/(mp->count > 0 ? mp->count: 1),mp->count); mp = &LP_gcloop_stats, printf("%32s lag %10.2f millis, threshold %10.2f, ave %10.2f millis, count.%u\n",mp->name,OS_milliseconds() - mp->lastmilli,mp->threshold,mp->millisum/(mp->count > 0 ? mp->count: 1),mp->count); } @@ -106,7 +105,7 @@ struct LP_trade *LP_trades; //uint32_t LP_deadman_switch; uint16_t LP_fixed_pairport,LP_publicport; -uint32_t LP_lastnonce,LP_counter,LP_swap_endcritical,LP_swap_critical,LP_RTcount,LP_swapscount; +uint32_t LP_lastnonce,LP_swap_endcritical,LP_swap_critical,LP_RTcount,LP_swapscount; int32_t LP_mybussock = -1; int32_t LP_mypubsock = -1; int32_t LP_mypullsock = -1; @@ -463,10 +462,9 @@ int32_t LP_nanomsg_recvs(void *ctx) return(nonz); } -void command_rpcloop(void *myipaddr) +void command_rpcloop(void *ctx) { - int32_t nonz = 0; void *ctx; - ctx = bitcoin_ctx(); + int32_t nonz = 0; strcpy(command_rpcloop_stats.name,"command_rpcloop"); command_rpcloop_stats.threshold = 1000.; while ( 1 ) @@ -795,22 +793,7 @@ void LP_pubkeysloop(void *ctx) } } -/*void LP_privkeysloop(void *ctx) -{ - strcpy(LP_privkeysloop_stats.name,"LP_privkeysloop"); - LP_privkeysloop_stats.threshold = (LP_ORDERBOOK_DURATION * .8 * 1000) + 10000; - sleep(20); - while ( 1 ) - { - LP_millistats_update(&LP_privkeysloop_stats); - LP_counter += 1000; -//printf("LP_privkeysloop %u\n",LP_counter); - LP_privkey_updates(ctx,LP_mypubsock,0); - sleep(LP_ORDERBOOK_DURATION * .777); - } -}*/ - -void LP_swapsloop(void *ignore) +void LP_swapsloop(void *ctx) { char *retstr; struct iguana_info *coin; strcpy(LP_swapsloop_stats.name,"LP_swapsloop"); @@ -819,8 +802,6 @@ void LP_swapsloop(void *ignore) while ( 1 ) { LP_millistats_update(&LP_swapsloop_stats); - LP_counter += 10000; -//printf("LP_swapsloop %u\n",LP_counter); if ( (retstr= basilisk_swapentry(0,0)) != 0 ) free(retstr); sleep(600); @@ -829,7 +810,7 @@ void LP_swapsloop(void *ignore) } } -void gc_loop(void *arg) +void gc_loop(void *ctx) { uint32_t now; struct LP_address_utxo *up,*utmp; struct rpcrequest_info *req,*rtmp; int32_t flag = 0; strcpy(LP_gcloop_stats.name,"gc_loop"); @@ -864,7 +845,7 @@ void gc_loop(void *arg) } } -void queue_loop(void *arg) +void queue_loop(void *ctx) { struct LP_queue *ptr,*tmp; int32_t sentbytes,nonz,flag,duplicate,n=0; strcpy(queue_loop_stats.name,"queue_loop"); @@ -934,8 +915,6 @@ void queue_loop(void *arg) break; } } - if ( arg == 0 ) - break; if ( nonz == 0 ) { if ( IAMLP == 0 ) @@ -1191,54 +1170,59 @@ void LPinit(uint16_t myport,uint16_t mypullport,uint16_t mypubport,uint16_t mybu printf("error launching stats rpcloop for port.%u\n",myport); exit(-1); } - if ( OS_thread_create(malloc(sizeof(pthread_t)),NULL,(void *)command_rpcloop,(void *)myipaddr) != 0 ) + if ( OS_thread_create(malloc(sizeof(pthread_t)),NULL,(void *)command_rpcloop,ctx) != 0 ) { - printf("error launching command_rpcloop for port.%u\n",myport); + printf("error launching command_rpcloop for ctx.%p\n",ctx); exit(-1); } - if ( OS_thread_create(malloc(sizeof(pthread_t)),NULL,(void *)queue_loop,(void *)myipaddr) != 0 ) + if ( OS_thread_create(malloc(sizeof(pthread_t)),NULL,(void *)queue_loop,ctx) != 0 ) { - printf("error launching queue_loop for port.%u\n",myport); + printf("error launching queue_loop for ctx.%p\n",ctx); exit(-1); } - if ( OS_thread_create(malloc(sizeof(pthread_t)),NULL,(void *)gc_loop,(void *)myipaddr) != 0 ) + if ( OS_thread_create(malloc(sizeof(pthread_t)),NULL,(void *)gc_loop,ctx) != 0 ) { - printf("error launching gc_loop for port.%u\n",myport); + printf("error launching gc_loop for port.%p\n",ctx); exit(-1); } if ( OS_thread_create(malloc(sizeof(pthread_t)),NULL,(void *)prices_loop,ctx) != 0 ) { - printf("error launching prices_loop for port.%u\n",myport); + printf("error launching prices_loop for ctx.%p\n",ctx); exit(-1); } if ( OS_thread_create(malloc(sizeof(pthread_t)),NULL,(void *)LP_coinsloop,(void *)"") != 0 ) { - printf("error launching LP_coinsloop for port.%u\n",myport); + printf("error launching LP_coinsloop for (%s)\n",""); exit(-1); } if ( OS_thread_create(malloc(sizeof(pthread_t)),NULL,(void *)LP_coinsloop,(void *)"BTC") != 0 ) { - printf("error launching BTC LP_coinsloop for port.%u\n",myport); + printf("error launching LP_coinsloop for (%s)\n","BTC"); exit(-1); } if ( OS_thread_create(malloc(sizeof(pthread_t)),NULL,(void *)LP_coinsloop,(void *)"KMD") != 0 ) { - printf("error launching KMD LP_coinsloop for port.%u\n",myport); + printf("error launching LP_coinsloop for (%s)\n","KMD"); exit(-1); } - if ( OS_thread_create(malloc(sizeof(pthread_t)),NULL,(void *)LP_pubkeysloop,(void *)myipaddr) != 0 ) + if ( OS_thread_create(malloc(sizeof(pthread_t)),NULL,(void *)LP_pubkeysloop,ctx) != 0 ) { printf("error launching LP_pubkeysloop for ctx.%p\n",ctx); exit(-1); } - /*if ( 0 && OS_thread_create(malloc(sizeof(pthread_t)),NULL,(void *)LP_privkeysloop,(void *)myipaddr) != 0 ) + if ( OS_thread_create(malloc(sizeof(pthread_t)),NULL,(void *)LP_tradesloop,ctx) != 0 ) + { + printf("error launching LP_tradessloop for ctx.%p\n",ctx); + exit(-1); + } + /*if ( 0 && OS_thread_create(malloc(sizeof(pthread_t)),NULL,(void *)LP_privkeysloop,ctx) != 0 ) { printf("error launching LP_privkeysloop for ctx.%p\n",ctx); exit(-1); }*/ - if ( OS_thread_create(malloc(sizeof(pthread_t)),NULL,(void *)LP_swapsloop,(void *)myipaddr) != 0 ) + if ( OS_thread_create(malloc(sizeof(pthread_t)),NULL,(void *)LP_swapsloop,ctx) != 0 ) { - printf("error launching LP_swapsloop for port.%u\n",myport); + printf("error launching LP_swapsloop for ctx.%p\n",ctx); exit(-1); } int32_t nonz; @@ -1309,8 +1293,6 @@ void LP_fromjs_iter() } if ( ctx == 0 ) ctx = bitcoin_ctx(); - if ( 0 && (LP_counter % 100) == 0 ) - printf("LP_fromjs_iter got called LP_counter.%d userpass.(%s) ctx.%p\n",LP_counter,G.USERPASS,ctx); //if ( Nanomsg_threadarg != 0 ) // nn_thread_main_routine(Nanomsg_threadarg); //LP_pubkeys_query(); @@ -1318,10 +1300,10 @@ void LP_fromjs_iter() //LP_nanomsg_recvs(ctx); LP_mainloop_iter(ctx,LP_myipaddr,0,LP_mypubsock,LP_publicaddr,LP_RPCPORT); //queue_loop(0); - if ( 0 && (LP_counter % 10) == 0 ) // 10 seconds + if ( 0 ) // 10 seconds { LP_coinsloop(0); - if ( (LP_counter % 100) == 0 ) // 100 seconds + if ( 0 ) // 100 seconds { LP_notify_pubkeys(ctx,LP_mypubsock); LP_privkey_updates(ctx,LP_mypubsock,0); @@ -1329,7 +1311,6 @@ void LP_fromjs_iter() free(retstr); } } - LP_counter++; } #endif diff --git a/iguana/exchanges/LP_ordermatch.c b/iguana/exchanges/LP_ordermatch.c index 51e022661..507a3ab62 100644 --- a/iguana/exchanges/LP_ordermatch.c +++ b/iguana/exchanges/LP_ordermatch.c @@ -784,7 +784,7 @@ int32_t LP_validSPV(char *symbol,char *coinaddr,bits256 txid,int32_t vout) return(0); } -int32_t LP_trades_alicevalidate(void *ctx,struct LP_quoteinfo *qp) +double LP_trades_alicevalidate(void *ctx,struct LP_quoteinfo *qp) { double qprice; struct LP_utxoinfo A,B,*autxo,*butxo; char str[65]; printf("alice %s received RESERVED.(%llu)\n",bits256_str(str,G.LP_mypub25519),(long long)qp->aliceid); @@ -808,7 +808,7 @@ int32_t LP_trades_alicevalidate(void *ctx,struct LP_quoteinfo *qp) printf("%s src2 %s failed SPV check\n",qp->srccoin,bits256_str(str,qp->txid2)); return(-55); } - return(0); + return(qprice); } void LP_reserved(void *ctx,char *myipaddr,int32_t mypubsock,struct LP_quoteinfo *qp) @@ -883,13 +883,15 @@ double LP_trades_pricevalidate(struct LP_quoteinfo *qp,struct iguana_info *coin, return(qprice); } -void LP_trades_gotrequest(void *ctx,struct LP_quoteinfo *qp,char *pairstr) +struct LP_quoteinfo *LP_trades_gotrequest(void *ctx,struct LP_quoteinfo *qp,struct LP_quoteinfo *newqp,char *pairstr) { double price,qprice,bestprice,range,bid,ask; struct iguana_info *coin; struct LP_utxoinfo A,B,*autxo,*butxo; cJSON *reqjson; char str[65]; struct LP_address_utxo *utxos[1000]; int32_t r,counter,max = (int32_t)(sizeof(utxos)/sizeof(*utxos)); + *newqp = *qp; + qp = newqp; if ( (coin= LP_coinfind(qp->srccoin)) == 0 ) - return; + return(0); if ( (price= LP_trades_bobprice(&bid,&ask,qp)) == 0. ) - return; + return(0); autxo = &A; butxo = &B; memset(autxo,0,sizeof(*autxo)); @@ -905,7 +907,7 @@ void LP_trades_gotrequest(void *ctx,struct LP_quoteinfo *qp,char *pairstr) memset(&qp->txid,0,sizeof(qp->txid)); memset(&qp->txid2,0,sizeof(qp->txid2)); qp->vout = qp->vout2 = -1; - } else return; + } else return(0); if ( qprice > price ) { r = (LP_rand() % 100); @@ -914,13 +916,13 @@ void LP_trades_gotrequest(void *ctx,struct LP_quoteinfo *qp,char *pairstr) bestprice = LP_bob_competition(&counter,qp->aliceid,price,0); printf("%llu >>>>>>> qprice %.8f r.%d range %.8f -> %.8f, bestprice %.8f counter.%d\n",(long long)qp->aliceid,qprice,r,range,price,bestprice,counter); if ( counter > 3 && price >= bestprice-SMALLVAL ) // skip if late or bad price - return; - } else return; + return(0); + } else return(0); //LP_RTmetrics_update(qp->srccoin,qp->destcoin); if ( LP_RTmetrics_blacklisted(qp->desthash) >= 0 ) { printf("request from blacklisted %s, ignore\n",bits256_str(str,qp->desthash)); - return; + return(0); } LP_address_utxo_reset(coin); if ( (butxo= LP_address_myutxopair(butxo,1,utxos,max,LP_coinfind(qp->srccoin),qp->coinaddr,qp->txfee,dstr(qp->destsatoshis),price,qp->desttxfee)) != 0 ) @@ -938,10 +940,10 @@ void LP_trades_gotrequest(void *ctx,struct LP_quoteinfo *qp,char *pairstr) else { printf("cant find utxopair aliceid.%llu %s/%s %.8f -> relvol %.8f\n",(long long)qp->aliceid,qp->srccoin,qp->destcoin,dstr(LP_basesatoshis(dstr(qp->destsatoshis),price,qp->txfee,qp->desttxfee)),dstr(qp->destsatoshis)); - return; + return(0); } if ( (qprice= LP_trades_pricevalidate(qp,coin,price)) < 0. ) - return; + return(0); if ( LP_allocated(qp->txid,qp->vout) == 0 && LP_allocated(qp->txid2,qp->vout2) == 0 ) { reqjson = LP_quotejson(qp); @@ -959,49 +961,171 @@ void LP_trades_gotrequest(void *ctx,struct LP_quoteinfo *qp,char *pairstr) //sleep(1); //LP_reserved_msg(1,qp->srccoin,qp->destcoin,qp->desthash,jprint(reqjson,0)); free_json(reqjson); + return(qp); } else printf("request processing selected ineligible utxos?\n"); + return(0); } -void LP_trades_gotreserved(void *ctx,struct LP_quoteinfo *qp) +struct LP_quoteinfo *LP_trades_gotreserved(void *ctx,struct LP_quoteinfo *qp,struct LP_quoteinfo *newqp) { char *retstr; char str[65]; printf("alice %s received RESERVED.(%llu)\n",bits256_str(str,G.LP_mypub25519),(long long)qp->aliceid); - if ( LP_trades_alicevalidate(ctx,qp) == 0 ) + *newqp = *qp; + qp = newqp; + if ( LP_trades_alicevalidate(ctx,qp) > 0. ) { LP_aliceid(qp->tradeid,qp->aliceid,"reserved",0,0); if ( (retstr= LP_quotereceived(qp)) != 0 ) free(retstr); - LP_reserved(ctx,LP_myipaddr,LP_mypubsock,qp); + return(qp); } + return(0); } -void LP_trades_gotconnect(void *ctx,struct LP_quoteinfo *qp,char *pairstr) +struct LP_quoteinfo *LP_trades_gotconnect(void *ctx,struct LP_quoteinfo *qp,struct LP_quoteinfo *newqp,char *pairstr) { double price,qprice,bid,ask; struct iguana_info *coin; + *newqp = *qp; + qp = newqp; if ( (coin= LP_coinfind(qp->srccoin)) == 0 ) - return; + return(0); if ( (price= LP_trades_bobprice(&bid,&ask,qp)) == 0. ) - return; + return(0); if ( bits256_cmp(G.LP_mypub25519,qp->srchash) != 0 || bits256_cmp(G.LP_mypub25519,qp->desthash) == 0 ) - return; + return(0); if ( (qprice= LP_trades_pricevalidate(qp,coin,price)) < 0. ) - return; + return(0); if ( LP_reservation_check(qp->txid,qp->vout,qp->desthash) == 0 && LP_reservation_check(qp->txid2,qp->vout2,qp->desthash) == 0 ) { LP_connectstartbob(ctx,LP_mypubsock,qp->srccoin,qp->destcoin,qprice,qp); - return; + return(qp); } else printf("connect message from non-reserved (%llu)\n",(long long)qp->aliceid); + return(0); } -void LP_trades_gotconnected(void *ctx,struct LP_quoteinfo *qp,char *pairstr) +struct LP_quoteinfo *LP_trades_gotconnected(void *ctx,struct LP_quoteinfo *qp,struct LP_quoteinfo *newqp,char *pairstr) { char *retstr; char str[65]; printf("alice %s received CONNECTED.(%llu)\n",bits256_str(str,G.LP_mypub25519),(long long)qp->aliceid); - if ( LP_trades_alicevalidate(ctx,qp) == 0 ) + *newqp = *qp; + qp = newqp; + if ( LP_trades_alicevalidate(ctx,qp) > 0. ) { LP_aliceid(qp->tradeid,qp->aliceid,"connected",0,0); if ( (retstr= LP_connectedalice(qp,pairstr)) != 0 ) free(retstr); + return(qp); + } + return(0); +} + +void LP_tradesloop(void *ctx) +{ + struct LP_trade *tp,*tmp; double qprice; struct LP_quoteinfo *qp,Q; uint32_t now; int32_t flag,nonz = 0; + strcpy(LP_tradesloop_stats.name,"LP_tradesloop"); + LP_tradesloop_stats.threshold = 10000; + sleep(5); + while ( 1 ) + { + LP_millistats_update(&LP_tradesloop_stats); + now = (uint32_t)time(NULL); + HASH_ITER(hh,LP_trades,tp,tmp) + { + if ( tp->negotiationdone != 0 ) + continue; + flag = 0; + if ( tp->firstprocessed == 0 ) + { + if ( tp->iambob != 0 && tp->firstfuncid == LP_REQUEST ) // bob maybe sends LP_RESERVED + { + flag = 1; + if ( (qp= LP_trades_gotrequest(ctx,&tp->Q[LP_REQUEST],&Q,tp->pairstr)) != 0 ) + tp->Q[LP_RESERVED] = Q; + tp->firstprocessed = (uint32_t)time(NULL); + } + else if ( tp->iambob == 0 && tp->firstfuncid == LP_RESERVED ) // alice maybe sends LP_CONNECT + { + flag = 1; + if ( (qprice= LP_trades_alicevalidate(ctx,&tp->Q[LP_RESERVED])) > 0. ) + { + // update if best price + if ( qprice > tp->bestprice ) + { + tp->Q[LP_CONNECT] = tp->Q[LP_RESERVED]; + tp->bestprice = qprice; + printf("aliceid.%llu got price %.8f\n",(long long)tp->aliceid,tp->bestprice); + } + } + tp->firstprocessed = (uint32_t)time(NULL); + } + } + else if ( tp->newtime != 0 ) // alice: LP_RESERVED or LP_CONNECTED, bob: LP_CONNECT + { + if ( tp->iambob == 0 ) + { + if ( tp->newfuncid == LP_RESERVED ) // maybe sends LP_CONNECT + { + flag = 1; + if ( (qprice= LP_trades_alicevalidate(ctx,&tp->Q[LP_RESERVED])) > 0. ) + { + // update if best price + if ( qprice > tp->bestprice ) + { + tp->Q[LP_CONNECT] = tp->Q[LP_RESERVED]; + tp->bestprice = qprice; + printf("aliceid.%llu got better price %.8f\n",(long long)tp->aliceid,tp->bestprice); + } + } + } + else if ( tp->newfuncid == LP_CONNECTED ) // alice all done + { + flag = 1; + tp->negotiationdone = now; + LP_trades_gotconnected(ctx,&tp->Q[LP_CONNECTED],&Q,tp->pairstr); + } + } + else + { + if ( tp->newfuncid == LP_CONNECT ) // bob all cone + { + flag = 1; + tp->negotiationdone = now; + LP_trades_gotconnect(ctx,&tp->Q[LP_CONNECTED],&Q,tp->pairstr); + } + } + } + else if ( now > tp->lastprocessed+3 ) + { + if ( now < tp->lastprocessed+60 ) + { + flag = 1; + if ( tp->iambob == 0 ) + { + if ( tp->connectsent == 0 && tp->bestprice > 0. ) + { + LP_reserved(ctx,LP_myipaddr,LP_mypubsock,&tp->Q[LP_CONNECT]); // send LP_CONNECT + tp->connectsent = now; + } + } + } + else if ( now > tp->lastprocessed+600 ) + { + printf("purge swap aliceid.%llu\n",(long long)tp->aliceid); + portable_mutex_lock(&LP_tradesmutex); + HASH_DELETE(hh,LP_trades,tp); + portable_mutex_unlock(&LP_tradesmutex); + free(tp); + } + } + if ( flag != 0 ) + { + nonz++; + tp->lastprocessed = (uint32_t)time(NULL); + tp->newtime = 0; + } + } + if ( nonz == 0 ) + sleep(1); } } @@ -1018,20 +1142,24 @@ void LP_tradecommandQ(struct LP_quoteinfo *qp,char *pairstr,int32_t funcid) HASH_FIND(hh,LP_trades,&aliceid,sizeof(aliceid),tp); if ( tp == 0 ) { - tp = calloc(1,sizeof(*tp)); - tp->funcid = funcid; - tp->iambob = iambob; - tp->aliceid = aliceid; - tp->firsttime = tp->lasttime = (uint32_t)time(NULL); - tp->Q[funcid] = *qp; - if ( pairstr != 0 ) - safecopy(tp->pairstr,pairstr,sizeof(tp->pairstr)); - HASH_ADD(hh,LP_trades,aliceid,sizeof(aliceid),tp); + if ( funcid == LP_REQUEST || funcid == LP_RESERVED ) + { + tp = calloc(1,sizeof(*tp)); + tp->firstfuncid = funcid; + tp->iambob = iambob; + tp->aliceid = aliceid; + tp->firsttime = tp->lasttime = (uint32_t)time(NULL); + tp->Q[funcid] = *qp; + if ( pairstr != 0 ) + safecopy(tp->pairstr,pairstr,sizeof(tp->pairstr)); + HASH_ADD(hh,LP_trades,aliceid,sizeof(aliceid),tp); + } } else if ( tp->Q[funcid].aliceid == 0 && tp->iambob == iambob ) { tp->Q[funcid] = *qp; - tp->lasttime = (uint32_t)time(NULL); + tp->newfuncid = funcid; + tp->newtime = (uint32_t)time(NULL); } portable_mutex_unlock(&LP_tradesmutex); } @@ -1039,7 +1167,7 @@ void LP_tradecommandQ(struct LP_quoteinfo *qp,char *pairstr,int32_t funcid) int32_t LP_tradecommand(void *ctx,char *myipaddr,int32_t pubsock,cJSON *argjson,uint8_t *data,int32_t datalen) { int32_t Qtrades = 0; - char *method,str[65]; int32_t DEXselector = 0; uint64_t aliceid; double qprice,bestprice,price,bid,ask; struct iguana_info *coin; struct LP_quoteinfo Q; int32_t counter,retval=-1; + char *method,str[65]; int32_t DEXselector = 0; uint64_t aliceid; double qprice,bestprice,price,bid,ask; struct iguana_info *coin; struct LP_quoteinfo Q,Q2; int32_t counter,retval=-1; if ( (method= jstr(argjson,"method")) != 0 && (strcmp(method,"reserved") == 0 ||strcmp(method,"connected") == 0 || strcmp(method,"request") == 0 || strcmp(method,"connect") == 0) ) { LP_quoteparse(&Q,argjson); @@ -1066,11 +1194,16 @@ int32_t LP_tradecommand(void *ctx,char *myipaddr,int32_t pubsock,cJSON *argjson, } else printf("got reserved response from destpubkey %s\n",bits256_str(str,Q.srchash)); } } - if ( bits256_cmp(G.LP_mypub25519,Q.desthash) == 0 && bits256_cmp(G.LP_mypub25519,Q.srchash) != 0 && Q.quotetime > time(NULL)-20 && LP_alice_eligible(Q.quotetime) > 0 ) + if ( bits256_cmp(G.LP_mypub25519,Q.desthash) == 0 && bits256_cmp(G.LP_mypub25519,Q.srchash) != 0 ) { if ( Qtrades == 0 ) - LP_trades_gotreserved(ctx,&Q); - else LP_tradecommandQ(&Q,jstr(argjson,"pair"),LP_RESERVED); + { + if ( Q.quotetime > time(NULL)-20 && LP_alice_eligible(Q.quotetime) > 0 ) + { + LP_trades_gotreserved(ctx,&Q,&Q2); + LP_reserved(ctx,LP_myipaddr,LP_mypubsock,&Q); + } + } else LP_tradecommandQ(&Q,jstr(argjson,"pair"),LP_RESERVED); } } else if ( strcmp(method,"connected") == 0 ) @@ -1079,7 +1212,7 @@ int32_t LP_tradecommand(void *ctx,char *myipaddr,int32_t pubsock,cJSON *argjson, if ( bits256_cmp(G.LP_mypub25519,Q.desthash) == 0 && bits256_cmp(G.LP_mypub25519,Q.srchash) != 0 ) { if ( Qtrades == 0 ) - LP_trades_gotconnected(ctx,&Q,jstr(argjson,"pair")); + LP_trades_gotconnected(ctx,&Q,&Q2,jstr(argjson,"pair")); else LP_tradecommandQ(&Q,jstr(argjson,"pair"),LP_CONNECTED); } } @@ -1097,13 +1230,13 @@ int32_t LP_tradecommand(void *ctx,char *myipaddr,int32_t pubsock,cJSON *argjson, if ( strcmp(method,"request") == 0 ) { if ( Qtrades == 0 ) - LP_trades_gotrequest(ctx,&Q,jstr(argjson,"pair")); + LP_trades_gotrequest(ctx,&Q,&Q2,jstr(argjson,"pair")); else LP_tradecommandQ(&Q,jstr(argjson,"pair"),LP_REQUEST); } else if ( strcmp(method,"connect") == 0 ) { if ( Qtrades == 0 ) - LP_trades_gotconnect(ctx,&Q,jstr(argjson,"pair")); + LP_trades_gotconnect(ctx,&Q,&Q2,jstr(argjson,"pair")); else LP_tradecommandQ(&Q,jstr(argjson,"pair"),LP_CONNECT); } return(retval); diff --git a/iguana/exchanges/LP_statemachine.c b/iguana/exchanges/LP_statemachine.c index 61c1398ee..6960f0f62 100644 --- a/iguana/exchanges/LP_statemachine.c +++ b/iguana/exchanges/LP_statemachine.c @@ -1868,6 +1868,20 @@ struct LP_utxoinfo *LP_utxo2find(int32_t iambob,bits256 txid2,int32_t vout2) portable_mutex_unlock(&LP_utxomutex); return(utxo); } + +/*void LP_privkeysloop(void *ctx) + { + strcpy(LP_privkeysloop_stats.name,"LP_privkeysloop"); + LP_privkeysloop_stats.threshold = (LP_ORDERBOOK_DURATION * .8 * 1000) + 10000; + sleep(20); + while ( 1 ) + { + LP_millistats_update(&LP_privkeysloop_stats); + //printf("LP_privkeysloop %u\n",LP_counter); + LP_privkey_updates(ctx,LP_mypubsock,0); + sleep(LP_ORDERBOOK_DURATION * .777); + } + }*/ /*void basilisk_swap_purge(struct basilisk_swap *swap) { int32_t i,n; From 4225b0713e5db7ef6ced8f31f413b4f9765fa12e Mon Sep 17 00:00:00 2001 From: jl777 Date: Sun, 26 Nov 2017 16:20:52 +0400 Subject: [PATCH 1274/1664] Test --- iguana/exchanges/LP_ordermatch.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/iguana/exchanges/LP_ordermatch.c b/iguana/exchanges/LP_ordermatch.c index 507a3ab62..cb07f49de 100644 --- a/iguana/exchanges/LP_ordermatch.c +++ b/iguana/exchanges/LP_ordermatch.c @@ -1166,7 +1166,7 @@ void LP_tradecommandQ(struct LP_quoteinfo *qp,char *pairstr,int32_t funcid) int32_t LP_tradecommand(void *ctx,char *myipaddr,int32_t pubsock,cJSON *argjson,uint8_t *data,int32_t datalen) { - int32_t Qtrades = 0; + int32_t Qtrades = 1; char *method,str[65]; int32_t DEXselector = 0; uint64_t aliceid; double qprice,bestprice,price,bid,ask; struct iguana_info *coin; struct LP_quoteinfo Q,Q2; int32_t counter,retval=-1; if ( (method= jstr(argjson,"method")) != 0 && (strcmp(method,"reserved") == 0 ||strcmp(method,"connected") == 0 || strcmp(method,"request") == 0 || strcmp(method,"connect") == 0) ) { From 34e187bdcc41541ab26dbc45d7c6e974aff24541 Mon Sep 17 00:00:00 2001 From: jl777 Date: Sun, 26 Nov 2017 16:34:29 +0400 Subject: [PATCH 1275/1664] Test --- iguana/exchanges/LP_ordermatch.c | 65 ++++++++++++++++++-------------- 1 file changed, 37 insertions(+), 28 deletions(-) diff --git a/iguana/exchanges/LP_ordermatch.c b/iguana/exchanges/LP_ordermatch.c index cb07f49de..f29ada1c2 100644 --- a/iguana/exchanges/LP_ordermatch.c +++ b/iguana/exchanges/LP_ordermatch.c @@ -814,7 +814,7 @@ double LP_trades_alicevalidate(void *ctx,struct LP_quoteinfo *qp) void LP_reserved(void *ctx,char *myipaddr,int32_t mypubsock,struct LP_quoteinfo *qp) { double price=0.,maxprice = LP_Alicemaxprice; - if ( LP_quotecmp(0,qp,&LP_Alicequery) == 0 ) + //if ( LP_quotecmp(0,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 ) @@ -824,8 +824,8 @@ void LP_reserved(void *ctx,char *myipaddr,int32_t mypubsock,struct LP_quoteinfo LP_alicequery_clear(); printf("send CONNECT\n"); LP_query(ctx,myipaddr,mypubsock,"connect",qp); - } else printf("LP_reserved price %.8f vs maxprice %.8f\n",price,maxprice*1.005); - } else printf("probably a timeout, reject reserved due to not eligible.%d or mismatched quote price %.8f vs maxprice %.8f\n",LP_alice_eligible(qp->quotetime),price,maxprice); + } else printf("LP_reserved %llu price %.8f vs maxprice %.8f\n",(long long)qp->aliceid,price,maxprice*1.005); + } //else printf("probably a timeout, reject reserved due to not eligible.%d or mismatched quote price %.8f vs maxprice %.8f\n",LP_alice_eligible(qp->quotetime),price,maxprice); } double LP_trades_bobprice(double *bidp,double *askp,struct LP_quoteinfo *qp) @@ -1019,6 +1019,22 @@ struct LP_quoteinfo *LP_trades_gotconnected(void *ctx,struct LP_quoteinfo *qp,st return(0); } +void LP_trades_bestpricecheck(void *ctx,struct LP_trade *tp) +{ + double qprice; struct LP_quoteinfo Q; + if ( (qprice= LP_trades_alicevalidate(ctx,&tp->Q[LP_RESERVED])) > 0. ) + { + LP_trades_gotreserved(ctx,&tp->Q[LP_RESERVED],&Q); + // update if best price + if ( qprice > tp->bestprice ) + { + tp->Q[LP_CONNECT] = tp->Q[LP_RESERVED]; + tp->bestprice = qprice; + printf("aliceid.%llu got price %.8f\n",(long long)tp->aliceid,tp->bestprice); + } + } +} + void LP_tradesloop(void *ctx) { struct LP_trade *tp,*tmp; double qprice; struct LP_quoteinfo *qp,Q; uint32_t now; int32_t flag,nonz = 0; @@ -1046,16 +1062,7 @@ void LP_tradesloop(void *ctx) else if ( tp->iambob == 0 && tp->firstfuncid == LP_RESERVED ) // alice maybe sends LP_CONNECT { flag = 1; - if ( (qprice= LP_trades_alicevalidate(ctx,&tp->Q[LP_RESERVED])) > 0. ) - { - // update if best price - if ( qprice > tp->bestprice ) - { - tp->Q[LP_CONNECT] = tp->Q[LP_RESERVED]; - tp->bestprice = qprice; - printf("aliceid.%llu got price %.8f\n",(long long)tp->aliceid,tp->bestprice); - } - } + LP_trades_bestpricecheck(ctx,tp); tp->firstprocessed = (uint32_t)time(NULL); } } @@ -1066,16 +1073,8 @@ void LP_tradesloop(void *ctx) if ( tp->newfuncid == LP_RESERVED ) // maybe sends LP_CONNECT { flag = 1; - if ( (qprice= LP_trades_alicevalidate(ctx,&tp->Q[LP_RESERVED])) > 0. ) - { - // update if best price - if ( qprice > tp->bestprice ) - { - tp->Q[LP_CONNECT] = tp->Q[LP_RESERVED]; - tp->bestprice = qprice; - printf("aliceid.%llu got better price %.8f\n",(long long)tp->aliceid,tp->bestprice); - } - } + if ( tp->connectsent == 0 ) + LP_trades_bestpricecheck(ctx,tp); } else if ( tp->newfuncid == LP_CONNECTED ) // alice all done { @@ -1098,13 +1097,22 @@ void LP_tradesloop(void *ctx) { if ( now < tp->lastprocessed+60 ) { - flag = 1; if ( tp->iambob == 0 ) { - if ( tp->connectsent == 0 && tp->bestprice > 0. ) + if ( tp->bestprice > 0. ) { - LP_reserved(ctx,LP_myipaddr,LP_mypubsock,&tp->Q[LP_CONNECT]); // send LP_CONNECT - tp->connectsent = now; + if ( tp->connectsent == 0 ) + { + flag = 1; + LP_reserved(ctx,LP_myipaddr,LP_mypubsock,&tp->Q[LP_CONNECT]); // send LP_CONNECT + tp->connectsent = now; + printf("send LP_connect aliceid.%llu %.8f\n",(long long)tp->aliceid,tp->bestprice); + } + else if ( ((tp->lastprocessed - now) % 10) == 9 ) + { + LP_reserved(ctx,LP_myipaddr,LP_mypubsock,&tp->Q[LP_CONNECT]); // send LP_CONNECT + printf("repeat LP_connect aliceid.%llu %.8f\n",(long long)tp->aliceid,tp->bestprice); + } } } } @@ -1201,7 +1209,8 @@ int32_t LP_tradecommand(void *ctx,char *myipaddr,int32_t pubsock,cJSON *argjson, if ( Q.quotetime > time(NULL)-20 && LP_alice_eligible(Q.quotetime) > 0 ) { LP_trades_gotreserved(ctx,&Q,&Q2); - LP_reserved(ctx,LP_myipaddr,LP_mypubsock,&Q); + if ( LP_quotecmp(0,&Q,&LP_Alicequery) == 0 ) + LP_reserved(ctx,LP_myipaddr,LP_mypubsock,&Q); } } else LP_tradecommandQ(&Q,jstr(argjson,"pair"),LP_RESERVED); } From e49adec5c2647bb0cafe1f4acfef5750dc7944eb Mon Sep 17 00:00:00 2001 From: jl777 Date: Sun, 26 Nov 2017 16:43:46 +0400 Subject: [PATCH 1276/1664] Test --- iguana/exchanges/LP_ordermatch.c | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/iguana/exchanges/LP_ordermatch.c b/iguana/exchanges/LP_ordermatch.c index f29ada1c2..e0c235f92 100644 --- a/iguana/exchanges/LP_ordermatch.c +++ b/iguana/exchanges/LP_ordermatch.c @@ -786,8 +786,7 @@ int32_t LP_validSPV(char *symbol,char *coinaddr,bits256 txid,int32_t vout) double LP_trades_alicevalidate(void *ctx,struct LP_quoteinfo *qp) { - double qprice; struct LP_utxoinfo A,B,*autxo,*butxo; - char str[65]; printf("alice %s received RESERVED.(%llu)\n",bits256_str(str,G.LP_mypub25519),(long long)qp->aliceid); + double qprice; struct LP_utxoinfo A,B,*autxo,*butxo; char str[65]; autxo = &A; butxo = &B; memset(autxo,0,sizeof(*autxo)); @@ -969,7 +968,7 @@ struct LP_quoteinfo *LP_trades_gotrequest(void *ctx,struct LP_quoteinfo *qp,stru struct LP_quoteinfo *LP_trades_gotreserved(void *ctx,struct LP_quoteinfo *qp,struct LP_quoteinfo *newqp) { char *retstr; - char str[65]; printf("alice %s received RESERVED.(%llu)\n",bits256_str(str,G.LP_mypub25519),(long long)qp->aliceid); + char str[65]; printf("alice %s received RESERVED.(%llu) %.8f\n",bits256_str(str,G.LP_mypub25519),(long long)qp->aliceid,(double)qp->destsatoshis/(qp->satoshis+1)); *newqp = *qp; qp = newqp; if ( LP_trades_alicevalidate(ctx,qp) > 0. ) @@ -1012,6 +1011,7 @@ struct LP_quoteinfo *LP_trades_gotconnected(void *ctx,struct LP_quoteinfo *qp,st if ( LP_trades_alicevalidate(ctx,qp) > 0. ) { LP_aliceid(qp->tradeid,qp->aliceid,"connected",0,0); + LP_Alicereserved = *qp; if ( (retstr= LP_connectedalice(qp,pairstr)) != 0 ) free(retstr); return(qp); @@ -1037,7 +1037,7 @@ void LP_trades_bestpricecheck(void *ctx,struct LP_trade *tp) void LP_tradesloop(void *ctx) { - struct LP_trade *tp,*tmp; double qprice; struct LP_quoteinfo *qp,Q; uint32_t now; int32_t flag,nonz = 0; + struct LP_trade *tp,*tmp; struct LP_quoteinfo *qp,Q; uint32_t now; int32_t flag,nonz = 0; strcpy(LP_tradesloop_stats.name,"LP_tradesloop"); LP_tradesloop_stats.threshold = 10000; sleep(5); @@ -1168,6 +1168,8 @@ void LP_tradecommandQ(struct LP_quoteinfo *qp,char *pairstr,int32_t funcid) tp->Q[funcid] = *qp; tp->newfuncid = funcid; tp->newtime = (uint32_t)time(NULL); + if ( pairstr != 0 ) + safecopy(tp->pairstr,pairstr,sizeof(tp->pairstr)); } portable_mutex_unlock(&LP_tradesmutex); } From c2f185beef628a6e539b02ca44a95b5d9d583838 Mon Sep 17 00:00:00 2001 From: jl777 Date: Sun, 26 Nov 2017 16:58:18 +0400 Subject: [PATCH 1277/1664] Test --- iguana/exchanges/LP_include.h | 1 + iguana/exchanges/LP_ordermatch.c | 21 ++++++++++++--------- 2 files changed, 13 insertions(+), 9 deletions(-) diff --git a/iguana/exchanges/LP_include.h b/iguana/exchanges/LP_include.h index 0ff04e7ff..1bde3fe6b 100644 --- a/iguana/exchanges/LP_include.h +++ b/iguana/exchanges/LP_include.h @@ -427,6 +427,7 @@ struct LP_trade { UT_hash_handle hh; uint64_t aliceid; + int64_t besttrust; double bestprice; uint32_t negotiationdone,connectsent,firsttime,lasttime,firstprocessed,lastprocessed,newtime; char pairstr[63],firstfuncid,newfuncid,iambob; diff --git a/iguana/exchanges/LP_ordermatch.c b/iguana/exchanges/LP_ordermatch.c index e0c235f92..c55239f9b 100644 --- a/iguana/exchanges/LP_ordermatch.c +++ b/iguana/exchanges/LP_ordermatch.c @@ -593,10 +593,10 @@ char *LP_connectedalice(struct LP_quoteinfo *qp,char *pairstr) // alice jaddstr(retjson,"error","swap already in progress"); return(jprint(retjson,1)); } - if ( LP_quotecmp(1,qp,&LP_Alicereserved) == 0 ) + /*if ( LP_quotecmp(1,qp,&LP_Alicereserved) == 0 ) { printf("mismatched between reserved and connected\n"); - } + }*/ memset(&LP_Alicereserved,0,sizeof(LP_Alicereserved)); LP_aliceid(qp->tradeid,qp->aliceid,"connected",qp->R.requestid,qp->R.quoteid); autxo = &A; @@ -823,7 +823,7 @@ void LP_reserved(void *ctx,char *myipaddr,int32_t mypubsock,struct LP_quoteinfo LP_alicequery_clear(); printf("send CONNECT\n"); LP_query(ctx,myipaddr,mypubsock,"connect",qp); - } else printf("LP_reserved %llu price %.8f vs maxprice %.8f\n",(long long)qp->aliceid,price,maxprice*1.005); + } else printf("LP_reserved %llu price %.8f vs maxprice %.8f\n",(long long)qp->aliceid,price,maxprice); } //else printf("probably a timeout, reject reserved due to not eligible.%d or mismatched quote price %.8f vs maxprice %.8f\n",LP_alice_eligible(qp->quotetime),price,maxprice); } @@ -1011,7 +1011,6 @@ struct LP_quoteinfo *LP_trades_gotconnected(void *ctx,struct LP_quoteinfo *qp,st if ( LP_trades_alicevalidate(ctx,qp) > 0. ) { LP_aliceid(qp->tradeid,qp->aliceid,"connected",0,0); - LP_Alicereserved = *qp; if ( (retstr= LP_connectedalice(qp,pairstr)) != 0 ) free(retstr); return(qp); @@ -1021,16 +1020,18 @@ struct LP_quoteinfo *LP_trades_gotconnected(void *ctx,struct LP_quoteinfo *qp,st void LP_trades_bestpricecheck(void *ctx,struct LP_trade *tp) { - double qprice; struct LP_quoteinfo Q; - if ( (qprice= LP_trades_alicevalidate(ctx,&tp->Q[LP_RESERVED])) > 0. ) + double qprice; struct LP_quoteinfo Q; int64_t dynamictrust; + Q = tp->Q[LP_RESERVED]; + if ( (qprice= LP_trades_alicevalidate(ctx,&Q)) > 0. ) { LP_trades_gotreserved(ctx,&tp->Q[LP_RESERVED],&Q); - // update if best price - if ( qprice > tp->bestprice ) + dynamictrust = LP_dynamictrust(Q.srchash,LP_kmdvalue(Q.srccoin,Q.satoshis)); + if ( qprice > tp->bestprice || (qprice < tp->bestprice*.99 && dynamictrust > tp->besttrust) ) { tp->Q[LP_CONNECT] = tp->Q[LP_RESERVED]; tp->bestprice = qprice; - printf("aliceid.%llu got price %.8f\n",(long long)tp->aliceid,tp->bestprice); + tp->besttrust = dynamictrust; + printf("aliceid.%llu got price %.8f dynamictrust %.8f\n",(long long)tp->aliceid,tp->bestprice,dstr(dynamictrust)); } } } @@ -1104,12 +1105,14 @@ void LP_tradesloop(void *ctx) if ( tp->connectsent == 0 ) { flag = 1; + LP_Alicemaxprice = tp->bestprice; LP_reserved(ctx,LP_myipaddr,LP_mypubsock,&tp->Q[LP_CONNECT]); // send LP_CONNECT tp->connectsent = now; printf("send LP_connect aliceid.%llu %.8f\n",(long long)tp->aliceid,tp->bestprice); } else if ( ((tp->lastprocessed - now) % 10) == 9 ) { + LP_Alicemaxprice = tp->bestprice; LP_reserved(ctx,LP_myipaddr,LP_mypubsock,&tp->Q[LP_CONNECT]); // send LP_CONNECT printf("repeat LP_connect aliceid.%llu %.8f\n",(long long)tp->aliceid,tp->bestprice); } From ba0f79ed86687b4473270c0c6678b80d8aad4232 Mon Sep 17 00:00:00 2001 From: jl777 Date: Sun, 26 Nov 2017 17:07:27 +0400 Subject: [PATCH 1278/1664] Test --- iguana/exchanges/LP_ordermatch.c | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/iguana/exchanges/LP_ordermatch.c b/iguana/exchanges/LP_ordermatch.c index c55239f9b..129c81d06 100644 --- a/iguana/exchanges/LP_ordermatch.c +++ b/iguana/exchanges/LP_ordermatch.c @@ -1018,7 +1018,7 @@ struct LP_quoteinfo *LP_trades_gotconnected(void *ctx,struct LP_quoteinfo *qp,st return(0); } -void LP_trades_bestpricecheck(void *ctx,struct LP_trade *tp) +int32_t LP_trades_bestpricecheck(void *ctx,struct LP_trade *tp) { double qprice; struct LP_quoteinfo Q; int64_t dynamictrust; Q = tp->Q[LP_RESERVED]; @@ -1026,14 +1026,16 @@ void LP_trades_bestpricecheck(void *ctx,struct LP_trade *tp) { LP_trades_gotreserved(ctx,&tp->Q[LP_RESERVED],&Q); dynamictrust = LP_dynamictrust(Q.srchash,LP_kmdvalue(Q.srccoin,Q.satoshis)); - if ( qprice > tp->bestprice || (qprice < tp->bestprice*.99 && dynamictrust > tp->besttrust) ) + if ( qprice < tp->bestprice || (qprice < tp->bestprice*1.01 && dynamictrust > tp->besttrust) ) { tp->Q[LP_CONNECT] = tp->Q[LP_RESERVED]; tp->bestprice = qprice; tp->besttrust = dynamictrust; printf("aliceid.%llu got price %.8f dynamictrust %.8f\n",(long long)tp->aliceid,tp->bestprice,dstr(dynamictrust)); + return(qprice); } } + return(0); } void LP_tradesloop(void *ctx) @@ -1073,9 +1075,8 @@ void LP_tradesloop(void *ctx) { if ( tp->newfuncid == LP_RESERVED ) // maybe sends LP_CONNECT { - flag = 1; if ( tp->connectsent == 0 ) - LP_trades_bestpricecheck(ctx,tp); + flag = LP_trades_bestpricecheck(ctx,tp); } else if ( tp->newfuncid == LP_CONNECTED ) // alice all done { @@ -1094,7 +1095,7 @@ void LP_tradesloop(void *ctx) } } } - else if ( now > tp->lastprocessed+3 ) + else if ( now > tp->lastprocessed+1 ) { if ( now < tp->lastprocessed+60 ) { From 99653957cfda206d071273dedadf88c8dcd9ce14 Mon Sep 17 00:00:00 2001 From: jl777 Date: Sun, 26 Nov 2017 17:12:42 +0400 Subject: [PATCH 1279/1664] Test --- iguana/exchanges/LP_ordermatch.c | 14 +++++++++----- 1 file changed, 9 insertions(+), 5 deletions(-) diff --git a/iguana/exchanges/LP_ordermatch.c b/iguana/exchanges/LP_ordermatch.c index 129c81d06..1b23545ea 100644 --- a/iguana/exchanges/LP_ordermatch.c +++ b/iguana/exchanges/LP_ordermatch.c @@ -1022,6 +1022,7 @@ int32_t LP_trades_bestpricecheck(void *ctx,struct LP_trade *tp) { double qprice; struct LP_quoteinfo Q; int64_t dynamictrust; Q = tp->Q[LP_RESERVED]; + printf("check bestprice %.8f vs new price %.8f\n",tp->bestprice,(double)Q.destsatoshis/Q.satoshis); if ( (qprice= LP_trades_alicevalidate(ctx,&Q)) > 0. ) { LP_trades_gotreserved(ctx,&tp->Q[LP_RESERVED],&Q); @@ -1033,8 +1034,8 @@ int32_t LP_trades_bestpricecheck(void *ctx,struct LP_trade *tp) tp->besttrust = dynamictrust; printf("aliceid.%llu got price %.8f dynamictrust %.8f\n",(long long)tp->aliceid,tp->bestprice,dstr(dynamictrust)); return(qprice); - } - } + } else printf("qprice %.8f dynamictrust %.8f not good enough\n",qprice,dstr(dynamictrust)); + } else printf("alice didnt validate\n"); return(0); } @@ -1064,9 +1065,11 @@ void LP_tradesloop(void *ctx) } else if ( tp->iambob == 0 && tp->firstfuncid == LP_RESERVED ) // alice maybe sends LP_CONNECT { - flag = 1; - LP_trades_bestpricecheck(ctx,tp); - tp->firstprocessed = (uint32_t)time(NULL); + if ( LP_trades_bestpricecheck(ctx,tp) != 0 ) + { + flag = 1; + tp->firstprocessed = (uint32_t)time(NULL); + } } } else if ( tp->newtime != 0 ) // alice: LP_RESERVED or LP_CONNECTED, bob: LP_CONNECT @@ -1171,6 +1174,7 @@ void LP_tradecommandQ(struct LP_quoteinfo *qp,char *pairstr,int32_t funcid) { tp->Q[funcid] = *qp; tp->newfuncid = funcid; + printf("received newfuncid.%d\n",funcid); tp->newtime = (uint32_t)time(NULL); if ( pairstr != 0 ) safecopy(tp->pairstr,pairstr,sizeof(tp->pairstr)); From ea7666e5a8984fe2fcd1f0f63e838f361b755af1 Mon Sep 17 00:00:00 2001 From: jl777 Date: Sun, 26 Nov 2017 17:19:24 +0400 Subject: [PATCH 1280/1664] Test --- iguana/exchanges/LP_ordermatch.c | 1 + 1 file changed, 1 insertion(+) diff --git a/iguana/exchanges/LP_ordermatch.c b/iguana/exchanges/LP_ordermatch.c index 1b23545ea..e5bf628e5 100644 --- a/iguana/exchanges/LP_ordermatch.c +++ b/iguana/exchanges/LP_ordermatch.c @@ -1100,6 +1100,7 @@ void LP_tradesloop(void *ctx) } else if ( now > tp->lastprocessed+1 ) { + printf("lag.%d iambob.%d bestprice %.8f besttrust %.8f\n",now-tp->lastprocessed,tp->iambob,tp->bestprice,dstr(tp->besttrust)); if ( now < tp->lastprocessed+60 ) { if ( tp->iambob == 0 ) From a7c8606b1833df39087e276ef3207fdc622d66c6 Mon Sep 17 00:00:00 2001 From: jl777 Date: Sun, 26 Nov 2017 17:28:02 +0400 Subject: [PATCH 1281/1664] Test --- iguana/exchanges/LP_include.h | 2 +- iguana/exchanges/LP_ordermatch.c | 28 ++++++++++++++-------------- 2 files changed, 15 insertions(+), 15 deletions(-) diff --git a/iguana/exchanges/LP_include.h b/iguana/exchanges/LP_include.h index 1bde3fe6b..d41428006 100644 --- a/iguana/exchanges/LP_include.h +++ b/iguana/exchanges/LP_include.h @@ -431,7 +431,7 @@ struct LP_trade double bestprice; uint32_t negotiationdone,connectsent,firsttime,lasttime,firstprocessed,lastprocessed,newtime; char pairstr[63],firstfuncid,newfuncid,iambob; - struct LP_quoteinfo Q[4]; + struct LP_quoteinfo Qs[4],Q; }; uint32_t LP_sighash(char *symbol,int32_t zcash); diff --git a/iguana/exchanges/LP_ordermatch.c b/iguana/exchanges/LP_ordermatch.c index e5bf628e5..5e2e24f03 100644 --- a/iguana/exchanges/LP_ordermatch.c +++ b/iguana/exchanges/LP_ordermatch.c @@ -1021,15 +1021,15 @@ struct LP_quoteinfo *LP_trades_gotconnected(void *ctx,struct LP_quoteinfo *qp,st int32_t LP_trades_bestpricecheck(void *ctx,struct LP_trade *tp) { double qprice; struct LP_quoteinfo Q; int64_t dynamictrust; - Q = tp->Q[LP_RESERVED]; + Q = tp->Q; printf("check bestprice %.8f vs new price %.8f\n",tp->bestprice,(double)Q.destsatoshis/Q.satoshis); if ( (qprice= LP_trades_alicevalidate(ctx,&Q)) > 0. ) { - LP_trades_gotreserved(ctx,&tp->Q[LP_RESERVED],&Q); + LP_trades_gotreserved(ctx,&Q,&tp->Qs[LP_RESERVED]); dynamictrust = LP_dynamictrust(Q.srchash,LP_kmdvalue(Q.srccoin,Q.satoshis)); - if ( qprice < tp->bestprice || (qprice < tp->bestprice*1.01 && dynamictrust > tp->besttrust) ) + if ( tp->bestprice == 0. || (qprice < tp->bestprice || (qprice < tp->bestprice*1.01 && dynamictrust > tp->besttrust)) ) { - tp->Q[LP_CONNECT] = tp->Q[LP_RESERVED]; + tp->Qs[LP_CONNECT] = tp->Q; tp->bestprice = qprice; tp->besttrust = dynamictrust; printf("aliceid.%llu got price %.8f dynamictrust %.8f\n",(long long)tp->aliceid,tp->bestprice,dstr(dynamictrust)); @@ -1059,8 +1059,8 @@ void LP_tradesloop(void *ctx) if ( tp->iambob != 0 && tp->firstfuncid == LP_REQUEST ) // bob maybe sends LP_RESERVED { flag = 1; - if ( (qp= LP_trades_gotrequest(ctx,&tp->Q[LP_REQUEST],&Q,tp->pairstr)) != 0 ) - tp->Q[LP_RESERVED] = Q; + if ( (qp= LP_trades_gotrequest(ctx,&tp->Qs[LP_REQUEST],&Q,tp->pairstr)) != 0 ) + tp->Qs[LP_RESERVED] = Q; tp->firstprocessed = (uint32_t)time(NULL); } else if ( tp->iambob == 0 && tp->firstfuncid == LP_RESERVED ) // alice maybe sends LP_CONNECT @@ -1085,7 +1085,7 @@ void LP_tradesloop(void *ctx) { flag = 1; tp->negotiationdone = now; - LP_trades_gotconnected(ctx,&tp->Q[LP_CONNECTED],&Q,tp->pairstr); + LP_trades_gotconnected(ctx,&tp->Q,&tp->Qs[LP_CONNECTED],tp->pairstr); } } else @@ -1094,7 +1094,7 @@ void LP_tradesloop(void *ctx) { flag = 1; tp->negotiationdone = now; - LP_trades_gotconnect(ctx,&tp->Q[LP_CONNECTED],&Q,tp->pairstr); + LP_trades_gotconnect(ctx,&tp->Q,&tp->Qs[LP_CONNECT],tp->pairstr); } } } @@ -1111,14 +1111,14 @@ void LP_tradesloop(void *ctx) { flag = 1; LP_Alicemaxprice = tp->bestprice; - LP_reserved(ctx,LP_myipaddr,LP_mypubsock,&tp->Q[LP_CONNECT]); // send LP_CONNECT + LP_reserved(ctx,LP_myipaddr,LP_mypubsock,&tp->Qs[LP_CONNECT]); // send LP_CONNECT tp->connectsent = now; printf("send LP_connect aliceid.%llu %.8f\n",(long long)tp->aliceid,tp->bestprice); } else if ( ((tp->lastprocessed - now) % 10) == 9 ) { LP_Alicemaxprice = tp->bestprice; - LP_reserved(ctx,LP_myipaddr,LP_mypubsock,&tp->Q[LP_CONNECT]); // send LP_CONNECT + LP_reserved(ctx,LP_myipaddr,LP_mypubsock,&tp->Qs[LP_CONNECT]); // send LP_CONNECT printf("repeat LP_connect aliceid.%llu %.8f\n",(long long)tp->aliceid,tp->bestprice); } } @@ -1148,7 +1148,7 @@ void LP_tradesloop(void *ctx) void LP_tradecommandQ(struct LP_quoteinfo *qp,char *pairstr,int32_t funcid) { struct LP_trade *tp; uint64_t aliceid; int32_t iambob; - if ( funcid < 0 || funcid >= sizeof(tp->Q)/sizeof(*tp->Q) ) + if ( funcid < 0 || funcid >= sizeof(tp->Qs)/sizeof(*tp->Qs) ) return; if ( funcid == LP_REQUEST || funcid == LP_CONNECT ) iambob = 1; @@ -1165,15 +1165,15 @@ void LP_tradecommandQ(struct LP_quoteinfo *qp,char *pairstr,int32_t funcid) tp->iambob = iambob; tp->aliceid = aliceid; tp->firsttime = tp->lasttime = (uint32_t)time(NULL); - tp->Q[funcid] = *qp; + tp->Q = *qp; if ( pairstr != 0 ) safecopy(tp->pairstr,pairstr,sizeof(tp->pairstr)); HASH_ADD(hh,LP_trades,aliceid,sizeof(aliceid),tp); } } - else if ( tp->Q[funcid].aliceid == 0 && tp->iambob == iambob ) + else if ( tp->iambob == iambob ) { - tp->Q[funcid] = *qp; + tp->Q = *qp; tp->newfuncid = funcid; printf("received newfuncid.%d\n",funcid); tp->newtime = (uint32_t)time(NULL); From 1c00001b9de34d98158927e89334d32c54e32e58 Mon Sep 17 00:00:00 2001 From: jl777 Date: Sun, 26 Nov 2017 17:58:51 +0400 Subject: [PATCH 1282/1664] Test --- iguana/exchanges/LP_include.h | 3 +- iguana/exchanges/LP_nativeDEX.c | 2 +- iguana/exchanges/LP_ordermatch.c | 110 +++++++++++++++++-------------- 3 files changed, 63 insertions(+), 52 deletions(-) diff --git a/iguana/exchanges/LP_include.h b/iguana/exchanges/LP_include.h index d41428006..41e7a801e 100644 --- a/iguana/exchanges/LP_include.h +++ b/iguana/exchanges/LP_include.h @@ -425,12 +425,13 @@ struct electrum_info struct LP_trade { + struct LP_trade *next,*prev; UT_hash_handle hh; uint64_t aliceid; int64_t besttrust; double bestprice; uint32_t negotiationdone,connectsent,firsttime,lasttime,firstprocessed,lastprocessed,newtime; - char pairstr[63],firstfuncid,newfuncid,iambob; + char pairstr[64],funcid,iambob; struct LP_quoteinfo Qs[4],Q; }; diff --git a/iguana/exchanges/LP_nativeDEX.c b/iguana/exchanges/LP_nativeDEX.c index a38a99c97..cedd630ab 100644 --- a/iguana/exchanges/LP_nativeDEX.c +++ b/iguana/exchanges/LP_nativeDEX.c @@ -101,7 +101,7 @@ struct iguana_info *LP_coins; struct LP_pubkey_info *LP_pubkeyinfos; struct rpcrequest_info *LP_garbage_collector; struct LP_address_utxo *LP_garbage_collector2; -struct LP_trade *LP_trades; +struct LP_trade *LP_trades,*LP_tradesQ; //uint32_t LP_deadman_switch; uint16_t LP_fixed_pairport,LP_publicport; diff --git a/iguana/exchanges/LP_ordermatch.c b/iguana/exchanges/LP_ordermatch.c index 5e2e24f03..2b5796649 100644 --- a/iguana/exchanges/LP_ordermatch.c +++ b/iguana/exchanges/LP_ordermatch.c @@ -1041,47 +1041,56 @@ int32_t LP_trades_bestpricecheck(void *ctx,struct LP_trade *tp) void LP_tradesloop(void *ctx) { - struct LP_trade *tp,*tmp; struct LP_quoteinfo *qp,Q; uint32_t now; int32_t flag,nonz = 0; + struct LP_trade *qtp,*tp,*tmp; struct LP_quoteinfo *qp,Q; uint32_t now; int32_t funcid,flag,nonz = 0; strcpy(LP_tradesloop_stats.name,"LP_tradesloop"); LP_tradesloop_stats.threshold = 10000; sleep(5); while ( 1 ) { LP_millistats_update(&LP_tradesloop_stats); - now = (uint32_t)time(NULL); - HASH_ITER(hh,LP_trades,tp,tmp) + DL_FOREACH_SAFE(LP_tradesQ,qtp,tmp) { - if ( tp->negotiationdone != 0 ) - continue; - flag = 0; - if ( tp->firstprocessed == 0 ) + now = (uint32_t)time(NULL); + Q = qtp->Q; + funcid = qtp->funcid; + portable_mutex_lock(&LP_tradesmutex); + DL_DELETE(LP_tradesQ,qtp); + HASH_FIND(hh,LP_trades,&qtp->aliceid,sizeof(qtp->aliceid),tp); + if ( tp == 0 ) { - if ( tp->iambob != 0 && tp->firstfuncid == LP_REQUEST ) // bob maybe sends LP_RESERVED + tp = qtp; + HASH_ADD(hh,LP_trades,aliceid,sizeof(tp->aliceid),tp); + portable_mutex_unlock(&LP_tradesmutex); + if ( tp->iambob != 0 && funcid == LP_REQUEST ) // bob maybe sends LP_RESERVED { - flag = 1; if ( (qp= LP_trades_gotrequest(ctx,&tp->Qs[LP_REQUEST],&Q,tp->pairstr)) != 0 ) tp->Qs[LP_RESERVED] = Q; - tp->firstprocessed = (uint32_t)time(NULL); } - else if ( tp->iambob == 0 && tp->firstfuncid == LP_RESERVED ) // alice maybe sends LP_CONNECT + else if ( tp->iambob == 0 && funcid == LP_RESERVED ) // alice maybe sends LP_CONNECT { - if ( LP_trades_bestpricecheck(ctx,tp) != 0 ) - { - flag = 1; - tp->firstprocessed = (uint32_t)time(NULL); - } + LP_trades_bestpricecheck(ctx,tp); } + nonz++; + tp->firstprocessed = tp->lastprocessed = (uint32_t)time(NULL); + continue; } - else if ( tp->newtime != 0 ) // alice: LP_RESERVED or LP_CONNECTED, bob: LP_CONNECT + portable_mutex_unlock(&LP_tradesmutex); + if ( qtp->iambob == tp->iambob && qtp->pairstr[0] != 0 ) + safecopy(tp->pairstr,qtp->pairstr,sizeof(tp->pairstr)); + free(qtp); + if ( tp->negotiationdone != 0 ) + continue; + flag = 0; + if ( qtp->iambob == tp->iambob ) { if ( tp->iambob == 0 ) { - if ( tp->newfuncid == LP_RESERVED ) // maybe sends LP_CONNECT + if ( funcid == LP_RESERVED ) { if ( tp->connectsent == 0 ) flag = LP_trades_bestpricecheck(ctx,tp); } - else if ( tp->newfuncid == LP_CONNECTED ) // alice all done + else if ( funcid == LP_CONNECTED && tp->connectsent != 0 && tp->negotiationdone == 0 ) // alice all done { flag = 1; tp->negotiationdone = now; @@ -1090,18 +1099,29 @@ void LP_tradesloop(void *ctx) } else { - if ( tp->newfuncid == LP_CONNECT ) // bob all cone + if ( funcid == LP_CONNECT && tp->negotiationdone == 0 ) // bob all cone { flag = 1; tp->negotiationdone = now; LP_trades_gotconnect(ctx,&tp->Q,&tp->Qs[LP_CONNECT],tp->pairstr); } } + if ( flag != 0 ) + { + tp->lastprocessed = (uint32_t)time(NULL); + nonz++; + } } - else if ( now > tp->lastprocessed+1 ) + } + HASH_ITER(hh,LP_trades,tp,tmp) + { + if ( tp->negotiationdone != 0 ) + continue; + now = (uint32_t)time(NULL); + if ( now > tp->lastprocessed+1 ) { printf("lag.%d iambob.%d bestprice %.8f besttrust %.8f\n",now-tp->lastprocessed,tp->iambob,tp->bestprice,dstr(tp->besttrust)); - if ( now < tp->lastprocessed+60 ) + if ( now < tp->firstprocessed+60 ) { if ( tp->iambob == 0 ) { @@ -1109,7 +1129,6 @@ void LP_tradesloop(void *ctx) { if ( tp->connectsent == 0 ) { - flag = 1; LP_Alicemaxprice = tp->bestprice; LP_reserved(ctx,LP_myipaddr,LP_mypubsock,&tp->Qs[LP_CONNECT]); // send LP_CONNECT tp->connectsent = now; @@ -1124,7 +1143,7 @@ void LP_tradesloop(void *ctx) } } } - else if ( now > tp->lastprocessed+600 ) + else if ( now > tp->firstprocessed+600 ) { printf("purge swap aliceid.%llu\n",(long long)tp->aliceid); portable_mutex_lock(&LP_tradesmutex); @@ -1133,12 +1152,6 @@ void LP_tradesloop(void *ctx) free(tp); } } - if ( flag != 0 ) - { - nonz++; - tp->lastprocessed = (uint32_t)time(NULL); - tp->newtime = 0; - } } if ( nonz == 0 ) sleep(1); @@ -1147,30 +1160,28 @@ void LP_tradesloop(void *ctx) void LP_tradecommandQ(struct LP_quoteinfo *qp,char *pairstr,int32_t funcid) { - struct LP_trade *tp; uint64_t aliceid; int32_t iambob; - if ( funcid < 0 || funcid >= sizeof(tp->Qs)/sizeof(*tp->Qs) ) + struct LP_trade *qtp; uint64_t aliceid; int32_t iambob; + if ( funcid < 0 || funcid >= sizeof(qtp->Qs)/sizeof(*qtp->Qs) ) return; if ( funcid == LP_REQUEST || funcid == LP_CONNECT ) iambob = 1; else iambob = 0; aliceid = qp->aliceid; - portable_mutex_lock(&LP_tradesmutex); - HASH_FIND(hh,LP_trades,&aliceid,sizeof(aliceid),tp); - if ( tp == 0 ) - { - if ( funcid == LP_REQUEST || funcid == LP_RESERVED ) - { - tp = calloc(1,sizeof(*tp)); - tp->firstfuncid = funcid; - tp->iambob = iambob; - tp->aliceid = aliceid; - tp->firsttime = tp->lasttime = (uint32_t)time(NULL); - tp->Q = *qp; - if ( pairstr != 0 ) - safecopy(tp->pairstr,pairstr,sizeof(tp->pairstr)); - HASH_ADD(hh,LP_trades,aliceid,sizeof(aliceid),tp); - } + if ( funcid == LP_REQUEST || funcid == LP_RESERVED ) + { + portable_mutex_lock(&LP_tradesmutex); + qtp = calloc(1,sizeof(*qtp)); + qtp->funcid = funcid; + qtp->iambob = iambob; + qtp->aliceid = aliceid; + qtp->newtime = (uint32_t)time(NULL); + qtp->Q = *qp; + if ( pairstr != 0 ) + safecopy(qtp->pairstr,pairstr,sizeof(qtp->pairstr)); + DL_APPEND(LP_tradesQ,qtp); + portable_mutex_unlock(&LP_tradesmutex); } + /* } else if ( tp->iambob == iambob ) { tp->Q = *qp; @@ -1179,8 +1190,7 @@ void LP_tradecommandQ(struct LP_quoteinfo *qp,char *pairstr,int32_t funcid) tp->newtime = (uint32_t)time(NULL); if ( pairstr != 0 ) safecopy(tp->pairstr,pairstr,sizeof(tp->pairstr)); - } - portable_mutex_unlock(&LP_tradesmutex); + }*/ } int32_t LP_tradecommand(void *ctx,char *myipaddr,int32_t pubsock,cJSON *argjson,uint8_t *data,int32_t datalen) From 215551ac55165fb0712f606edc430feda873488d Mon Sep 17 00:00:00 2001 From: jl777 Date: Sun, 26 Nov 2017 18:07:12 +0400 Subject: [PATCH 1283/1664] Test --- iguana/exchanges/LP_ordermatch.c | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/iguana/exchanges/LP_ordermatch.c b/iguana/exchanges/LP_ordermatch.c index 2b5796649..333f6365a 100644 --- a/iguana/exchanges/LP_ordermatch.c +++ b/iguana/exchanges/LP_ordermatch.c @@ -1041,7 +1041,7 @@ int32_t LP_trades_bestpricecheck(void *ctx,struct LP_trade *tp) void LP_tradesloop(void *ctx) { - struct LP_trade *qtp,*tp,*tmp; struct LP_quoteinfo *qp,Q; uint32_t now; int32_t funcid,flag,nonz = 0; + struct LP_trade *qtp,*tp,*tmp; struct LP_quoteinfo *qp,Q; uint32_t now; int32_t funcid,flag,nonz; strcpy(LP_tradesloop_stats.name,"LP_tradesloop"); LP_tradesloop_stats.threshold = 10000; sleep(5); @@ -1050,6 +1050,8 @@ void LP_tradesloop(void *ctx) LP_millistats_update(&LP_tradesloop_stats); DL_FOREACH_SAFE(LP_tradesQ,qtp,tmp) { + nonz = 0; + printf("dequeued %p\n",qtp); now = (uint32_t)time(NULL); Q = qtp->Q; funcid = qtp->funcid; @@ -1075,6 +1077,7 @@ void LP_tradesloop(void *ctx) continue; } portable_mutex_unlock(&LP_tradesmutex); + tp->Q = qtp->Q; if ( qtp->iambob == tp->iambob && qtp->pairstr[0] != 0 ) safecopy(tp->pairstr,qtp->pairstr,sizeof(tp->pairstr)); free(qtp); @@ -1120,7 +1123,8 @@ void LP_tradesloop(void *ctx) now = (uint32_t)time(NULL); if ( now > tp->lastprocessed+1 ) { - printf("lag.%d iambob.%d bestprice %.8f besttrust %.8f\n",now-tp->lastprocessed,tp->iambob,tp->bestprice,dstr(tp->besttrust)); + if ( tp->connectsent == 0 ) + printf("lag.%d iambob.%d bestprice %.8f besttrust %.8f\n",now-tp->lastprocessed,tp->iambob,tp->bestprice,dstr(tp->besttrust)); if ( now < tp->firstprocessed+60 ) { if ( tp->iambob == 0 ) @@ -1180,6 +1184,7 @@ void LP_tradecommandQ(struct LP_quoteinfo *qp,char *pairstr,int32_t funcid) safecopy(qtp->pairstr,pairstr,sizeof(qtp->pairstr)); DL_APPEND(LP_tradesQ,qtp); portable_mutex_unlock(&LP_tradesmutex); + printf("queued %p\n",qtp); } /* } else if ( tp->iambob == iambob ) From 87f229486e4c924a17dbad7ec86541adc35b6800 Mon Sep 17 00:00:00 2001 From: jl777 Date: Sun, 26 Nov 2017 18:21:42 +0400 Subject: [PATCH 1284/1664] Test --- iguana/exchanges/LP_ordermatch.c | 39 ++++++++++---------------------- 1 file changed, 12 insertions(+), 27 deletions(-) diff --git a/iguana/exchanges/LP_ordermatch.c b/iguana/exchanges/LP_ordermatch.c index 333f6365a..68b1552a2 100644 --- a/iguana/exchanges/LP_ordermatch.c +++ b/iguana/exchanges/LP_ordermatch.c @@ -1048,10 +1048,9 @@ void LP_tradesloop(void *ctx) while ( 1 ) { LP_millistats_update(&LP_tradesloop_stats); + nonz = 0; DL_FOREACH_SAFE(LP_tradesQ,qtp,tmp) { - nonz = 0; - printf("dequeued %p\n",qtp); now = (uint32_t)time(NULL); Q = qtp->Q; funcid = qtp->funcid; @@ -1171,31 +1170,17 @@ void LP_tradecommandQ(struct LP_quoteinfo *qp,char *pairstr,int32_t funcid) iambob = 1; else iambob = 0; aliceid = qp->aliceid; - if ( funcid == LP_REQUEST || funcid == LP_RESERVED ) - { - portable_mutex_lock(&LP_tradesmutex); - qtp = calloc(1,sizeof(*qtp)); - qtp->funcid = funcid; - qtp->iambob = iambob; - qtp->aliceid = aliceid; - qtp->newtime = (uint32_t)time(NULL); - qtp->Q = *qp; - if ( pairstr != 0 ) - safecopy(qtp->pairstr,pairstr,sizeof(qtp->pairstr)); - DL_APPEND(LP_tradesQ,qtp); - portable_mutex_unlock(&LP_tradesmutex); - printf("queued %p\n",qtp); - } - /* } - else if ( tp->iambob == iambob ) - { - tp->Q = *qp; - tp->newfuncid = funcid; - printf("received newfuncid.%d\n",funcid); - tp->newtime = (uint32_t)time(NULL); - if ( pairstr != 0 ) - safecopy(tp->pairstr,pairstr,sizeof(tp->pairstr)); - }*/ + portable_mutex_lock(&LP_tradesmutex); + qtp = calloc(1,sizeof(*qtp)); + qtp->funcid = funcid; + qtp->iambob = iambob; + qtp->aliceid = aliceid; + qtp->newtime = (uint32_t)time(NULL); + qtp->Q = *qp; + if ( pairstr != 0 ) + safecopy(qtp->pairstr,pairstr,sizeof(qtp->pairstr)); + DL_APPEND(LP_tradesQ,qtp); + portable_mutex_unlock(&LP_tradesmutex); } int32_t LP_tradecommand(void *ctx,char *myipaddr,int32_t pubsock,cJSON *argjson,uint8_t *data,int32_t datalen) From dc63197601fd0719dca3f8145a236adad5233691 Mon Sep 17 00:00:00 2001 From: jl777 Date: Sun, 26 Nov 2017 18:33:47 +0400 Subject: [PATCH 1285/1664] Test --- iguana/exchanges/LP_ordermatch.c | 21 +++++++++++++-------- 1 file changed, 13 insertions(+), 8 deletions(-) diff --git a/iguana/exchanges/LP_ordermatch.c b/iguana/exchanges/LP_ordermatch.c index 68b1552a2..f345f6c2e 100644 --- a/iguana/exchanges/LP_ordermatch.c +++ b/iguana/exchanges/LP_ordermatch.c @@ -1022,7 +1022,7 @@ int32_t LP_trades_bestpricecheck(void *ctx,struct LP_trade *tp) { double qprice; struct LP_quoteinfo Q; int64_t dynamictrust; Q = tp->Q; - printf("check bestprice %.8f vs new price %.8f\n",tp->bestprice,(double)Q.destsatoshis/Q.satoshis); + //printf("check bestprice %.8f vs new price %.8f\n",tp->bestprice,(double)Q.destsatoshis/Q.satoshis); if ( (qprice= LP_trades_alicevalidate(ctx,&Q)) > 0. ) { LP_trades_gotreserved(ctx,&Q,&tp->Qs[LP_RESERVED]); @@ -1032,16 +1032,16 @@ int32_t LP_trades_bestpricecheck(void *ctx,struct LP_trade *tp) tp->Qs[LP_CONNECT] = tp->Q; tp->bestprice = qprice; tp->besttrust = dynamictrust; - printf("aliceid.%llu got price %.8f dynamictrust %.8f\n",(long long)tp->aliceid,tp->bestprice,dstr(dynamictrust)); + //printf("aliceid.%llu got price %.8f dynamictrust %.8f\n",(long long)tp->aliceid,tp->bestprice,dstr(dynamictrust)); return(qprice); - } else printf("qprice %.8f dynamictrust %.8f not good enough\n",qprice,dstr(dynamictrust)); + } //else printf("qprice %.8f dynamictrust %.8f not good enough\n",qprice,dstr(dynamictrust)); } else printf("alice didnt validate\n"); return(0); } void LP_tradesloop(void *ctx) { - struct LP_trade *qtp,*tp,*tmp; struct LP_quoteinfo *qp,Q; uint32_t now; int32_t funcid,flag,nonz; + struct LP_trade *qtp,*tp,*tmp; struct LP_quoteinfo *qp,Q; uint32_t now; int32_t timeout,funcid,flag,nonz; struct iguana_info *coin; strcpy(LP_tradesloop_stats.name,"LP_tradesloop"); LP_tradesloop_stats.threshold = 10000; sleep(5); @@ -1119,12 +1119,17 @@ void LP_tradesloop(void *ctx) { if ( tp->negotiationdone != 0 ) continue; + timeout = LP_AUTOTRADE_TIMEOUT; + if ( (coin= LP_coinfind(tp->Q.srccoin)) != 0 && coin->electrum != 0 ) + timeout += LP_AUTOTRADE_TIMEOUT * .5; + if ( (coin= LP_coinfind(tp->Q.destcoin)) != 0 && coin->electrum != 0 ) + timeout += LP_AUTOTRADE_TIMEOUT * .5; now = (uint32_t)time(NULL); - if ( now > tp->lastprocessed+1 ) + if ( now > tp->lastprocessed ) { if ( tp->connectsent == 0 ) printf("lag.%d iambob.%d bestprice %.8f besttrust %.8f\n",now-tp->lastprocessed,tp->iambob,tp->bestprice,dstr(tp->besttrust)); - if ( now < tp->firstprocessed+60 ) + if ( now < tp->firstprocessed+timeout ) { if ( tp->iambob == 0 ) { @@ -1135,9 +1140,9 @@ void LP_tradesloop(void *ctx) LP_Alicemaxprice = tp->bestprice; LP_reserved(ctx,LP_myipaddr,LP_mypubsock,&tp->Qs[LP_CONNECT]); // send LP_CONNECT tp->connectsent = now; - printf("send LP_connect aliceid.%llu %.8f\n",(long long)tp->aliceid,tp->bestprice); + //printf("send LP_connect aliceid.%llu %.8f\n",(long long)tp->aliceid,tp->bestprice); } - else if ( ((tp->lastprocessed - now) % 10) == 9 ) + else if ( ((tp->firstprocessed - now) % 5) == 4 ) { LP_Alicemaxprice = tp->bestprice; LP_reserved(ctx,LP_myipaddr,LP_mypubsock,&tp->Qs[LP_CONNECT]); // send LP_CONNECT From 4871cf4331fdc1967d45d70d5f560438a7474c98 Mon Sep 17 00:00:00 2001 From: jl777 Date: Sun, 26 Nov 2017 18:41:22 +0400 Subject: [PATCH 1286/1664] Test --- iguana/exchanges/LP_ordermatch.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/iguana/exchanges/LP_ordermatch.c b/iguana/exchanges/LP_ordermatch.c index f345f6c2e..228526f76 100644 --- a/iguana/exchanges/LP_ordermatch.c +++ b/iguana/exchanges/LP_ordermatch.c @@ -887,10 +887,12 @@ struct LP_quoteinfo *LP_trades_gotrequest(void *ctx,struct LP_quoteinfo *qp,stru double price,qprice,bestprice,range,bid,ask; struct iguana_info *coin; struct LP_utxoinfo A,B,*autxo,*butxo; cJSON *reqjson; char str[65]; struct LP_address_utxo *utxos[1000]; int32_t r,counter,max = (int32_t)(sizeof(utxos)/sizeof(*utxos)); *newqp = *qp; qp = newqp; + printf("LP_trades_gotrequest\n"); if ( (coin= LP_coinfind(qp->srccoin)) == 0 ) return(0); if ( (price= LP_trades_bobprice(&bid,&ask,qp)) == 0. ) return(0); + printf("LP_trades_gotrequest price %.8f\n",price); autxo = &A; butxo = &B; memset(autxo,0,sizeof(*autxo)); @@ -907,6 +909,7 @@ struct LP_quoteinfo *LP_trades_gotrequest(void *ctx,struct LP_quoteinfo *qp,stru memset(&qp->txid2,0,sizeof(qp->txid2)); qp->vout = qp->vout2 = -1; } else return(0); + printf("LP_trades_gotrequest qprice %.8f vs price %.8f\n",qprice,price); if ( qprice > price ) { r = (LP_rand() % 100); @@ -1127,8 +1130,6 @@ void LP_tradesloop(void *ctx) now = (uint32_t)time(NULL); if ( now > tp->lastprocessed ) { - if ( tp->connectsent == 0 ) - printf("lag.%d iambob.%d bestprice %.8f besttrust %.8f\n",now-tp->lastprocessed,tp->iambob,tp->bestprice,dstr(tp->besttrust)); if ( now < tp->firstprocessed+timeout ) { if ( tp->iambob == 0 ) From c0950090c9b42b86fa449be7618f235e6f3f7449 Mon Sep 17 00:00:00 2001 From: jl777 Date: Sun, 26 Nov 2017 18:49:37 +0400 Subject: [PATCH 1287/1664] Test --- iguana/exchanges/LP_ordermatch.c | 4 ++-- iguana/exchanges/LP_prices.c | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/iguana/exchanges/LP_ordermatch.c b/iguana/exchanges/LP_ordermatch.c index 228526f76..725b8b785 100644 --- a/iguana/exchanges/LP_ordermatch.c +++ b/iguana/exchanges/LP_ordermatch.c @@ -837,7 +837,7 @@ double LP_trades_bobprice(double *bidp,double *askp,struct LP_quoteinfo *qp) return(0.); } price = *askp; - //printf("MYPRICE %s/%s %.8f vs qprice %.8f\n",qp->srccoin,qp->destcoin,price,qprice); + printf("MYPRICE %s/%s %.8f vs qprice %.8f\n",qp->srccoin,qp->destcoin,price,(double)qp->destsatoshis/qp->satoshis); if ( LP_validSPV(qp->destcoin,qp->destaddr,qp->desttxid,qp->destvout) < 0 ) { printf("%s dest %s failed SPV check\n",qp->destcoin,bits256_str(str,qp->desttxid)); @@ -887,9 +887,9 @@ struct LP_quoteinfo *LP_trades_gotrequest(void *ctx,struct LP_quoteinfo *qp,stru double price,qprice,bestprice,range,bid,ask; struct iguana_info *coin; struct LP_utxoinfo A,B,*autxo,*butxo; cJSON *reqjson; char str[65]; struct LP_address_utxo *utxos[1000]; int32_t r,counter,max = (int32_t)(sizeof(utxos)/sizeof(*utxos)); *newqp = *qp; qp = newqp; - printf("LP_trades_gotrequest\n"); if ( (coin= LP_coinfind(qp->srccoin)) == 0 ) return(0); + printf("LP_trades_gotrequest %s/%s %.8f\n",qp->srccoin,qp->destcoin,LP_trades_bobprice(&bid,&ask,qp)); if ( (price= LP_trades_bobprice(&bid,&ask,qp)) == 0. ) return(0); printf("LP_trades_gotrequest price %.8f\n",price); diff --git a/iguana/exchanges/LP_prices.c b/iguana/exchanges/LP_prices.c index a41a7ac7e..43bb8c8d0 100644 --- a/iguana/exchanges/LP_prices.c +++ b/iguana/exchanges/LP_prices.c @@ -576,7 +576,7 @@ int32_t LP_mypriceset(int32_t *changedp,char *base,char *rel,double price) if ( fabs(basepp->myprices[relpp->ind] - price)/price > 0.001 ) *changedp = 1; basepp->myprices[relpp->ind] = price; // ask - //printf("LP_mypriceset base.%s rel.%s <- price %.8f\n",base,rel,price); + printf("LP_mypriceset base.%s rel.%s <- price %.8f\n",base,rel,price); //relpp->myprices[basepp->ind] = (1. / price); // bid if ( (pubp= LP_pubkeyadd(G.LP_mypub25519)) != 0 ) { From a5fe7cde793ba96b2d0ef8e53b0efc85862d8882 Mon Sep 17 00:00:00 2001 From: jl777 Date: Sun, 26 Nov 2017 19:12:47 +0400 Subject: [PATCH 1288/1664] Test --- iguana/exchanges/LP_ordermatch.c | 8 ++++++-- iguana/exchanges/LP_prices.c | 2 +- 2 files changed, 7 insertions(+), 3 deletions(-) diff --git a/iguana/exchanges/LP_ordermatch.c b/iguana/exchanges/LP_ordermatch.c index 725b8b785..aa3ada821 100644 --- a/iguana/exchanges/LP_ordermatch.c +++ b/iguana/exchanges/LP_ordermatch.c @@ -1057,6 +1057,7 @@ void LP_tradesloop(void *ctx) now = (uint32_t)time(NULL); Q = qtp->Q; funcid = qtp->funcid; + printf("dequeue %p funcid.%d aliceid.%llu iambob.%d\n",qtp,funcid,(long long)qtp->aliceid,qtp->iambob); portable_mutex_lock(&LP_tradesmutex); DL_DELETE(LP_tradesQ,qtp); HASH_FIND(hh,LP_trades,&qtp->aliceid,sizeof(qtp->aliceid),tp); @@ -1065,9 +1066,10 @@ void LP_tradesloop(void *ctx) tp = qtp; HASH_ADD(hh,LP_trades,aliceid,sizeof(tp->aliceid),tp); portable_mutex_unlock(&LP_tradesmutex); + printf("iambob.%d funcid.%d vs %d\n",tp->iambob,funcid,LP_REQUEST); if ( tp->iambob != 0 && funcid == LP_REQUEST ) // bob maybe sends LP_RESERVED { - if ( (qp= LP_trades_gotrequest(ctx,&tp->Qs[LP_REQUEST],&Q,tp->pairstr)) != 0 ) + if ( (qp= LP_trades_gotrequest(ctx,&Q,&tp->Qs[LP_REQUEST],tp->pairstr)) != 0 ) tp->Qs[LP_RESERVED] = Q; } else if ( tp->iambob == 0 && funcid == LP_RESERVED ) // alice maybe sends LP_CONNECT @@ -1187,6 +1189,7 @@ void LP_tradecommandQ(struct LP_quoteinfo *qp,char *pairstr,int32_t funcid) safecopy(qtp->pairstr,pairstr,sizeof(qtp->pairstr)); DL_APPEND(LP_tradesQ,qtp); portable_mutex_unlock(&LP_tradesmutex); + printf("queue.%d %p\n",funcid,qtp); } int32_t LP_tradecommand(void *ctx,char *myipaddr,int32_t pubsock,cJSON *argjson,uint8_t *data,int32_t datalen) @@ -1245,7 +1248,7 @@ int32_t LP_tradecommand(void *ctx,char *myipaddr,int32_t pubsock,cJSON *argjson, price = LP_myprice(&bid,&ask,Q.srccoin,Q.destcoin); if ( (coin= LP_coinfind(Q.srccoin)) == 0 || price <= SMALLVAL || ask <= SMALLVAL ) { - //printf("this node has no price for %s/%s\n",Q.srccoin,Q.destcoin); + printf("this node has no price for %s/%s\n",Q.srccoin,Q.destcoin); return(retval); } if ( LP_aliceonly(Q.srccoin) > 0 ) @@ -1261,6 +1264,7 @@ int32_t LP_tradecommand(void *ctx,char *myipaddr,int32_t pubsock,cJSON *argjson, } else if ( strcmp(method,"connect") == 0 ) { + LP_bob_competition(&counter,aliceid,qprice,1000); if ( Qtrades == 0 ) LP_trades_gotconnect(ctx,&Q,&Q2,jstr(argjson,"pair")); else LP_tradecommandQ(&Q,jstr(argjson,"pair"),LP_CONNECT); diff --git a/iguana/exchanges/LP_prices.c b/iguana/exchanges/LP_prices.c index 43bb8c8d0..a41a7ac7e 100644 --- a/iguana/exchanges/LP_prices.c +++ b/iguana/exchanges/LP_prices.c @@ -576,7 +576,7 @@ int32_t LP_mypriceset(int32_t *changedp,char *base,char *rel,double price) if ( fabs(basepp->myprices[relpp->ind] - price)/price > 0.001 ) *changedp = 1; basepp->myprices[relpp->ind] = price; // ask - printf("LP_mypriceset base.%s rel.%s <- price %.8f\n",base,rel,price); + //printf("LP_mypriceset base.%s rel.%s <- price %.8f\n",base,rel,price); //relpp->myprices[basepp->ind] = (1. / price); // bid if ( (pubp= LP_pubkeyadd(G.LP_mypub25519)) != 0 ) { From 1ae386551c46ddee3316b272d65769365f981fc1 Mon Sep 17 00:00:00 2001 From: jl777 Date: Sun, 26 Nov 2017 19:25:20 +0400 Subject: [PATCH 1289/1664] Test --- iguana/exchanges/LP_ordermatch.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/iguana/exchanges/LP_ordermatch.c b/iguana/exchanges/LP_ordermatch.c index aa3ada821..dcc75d13a 100644 --- a/iguana/exchanges/LP_ordermatch.c +++ b/iguana/exchanges/LP_ordermatch.c @@ -900,7 +900,7 @@ struct LP_quoteinfo *LP_trades_gotrequest(void *ctx,struct LP_quoteinfo *qp,stru LP_abutxo_set(autxo,butxo,qp); if ( bits256_nonz(qp->srchash) == 0 || bits256_cmp(qp->srchash,G.LP_mypub25519) == 0 ) { - qprice = (double)qp->destsatoshis / qp->satoshis; + qprice = (double)qp->destsatoshis / (qp->satoshis - qp->txfee); strcpy(qp->gui,G.gui); strcpy(qp->coinaddr,coin->smartaddr); strcpy(butxo->coinaddr,coin->smartaddr); @@ -936,7 +936,7 @@ struct LP_quoteinfo *LP_trades_gotrequest(void *ctx,struct LP_quoteinfo *qp,stru qp->vout = butxo->payment.vout; qp->txid2 = butxo->deposit.txid; qp->vout2 = butxo->deposit.vout; - qp->satoshis = butxo->swap_satoshis; + qp->satoshis = butxo->swap_satoshis + qp->txfee; qp->quotetime = (uint32_t)time(NULL); } else From 18e90cf4726966a1ccc8ce016fe19588e0251311 Mon Sep 17 00:00:00 2001 From: jl777 Date: Sun, 26 Nov 2017 19:34:16 +0400 Subject: [PATCH 1290/1664] Test --- iguana/exchanges/LP_ordermatch.c | 21 ++++++++++----------- 1 file changed, 10 insertions(+), 11 deletions(-) diff --git a/iguana/exchanges/LP_ordermatch.c b/iguana/exchanges/LP_ordermatch.c index dcc75d13a..c3814d306 100644 --- a/iguana/exchanges/LP_ordermatch.c +++ b/iguana/exchanges/LP_ordermatch.c @@ -884,15 +884,14 @@ double LP_trades_pricevalidate(struct LP_quoteinfo *qp,struct iguana_info *coin, struct LP_quoteinfo *LP_trades_gotrequest(void *ctx,struct LP_quoteinfo *qp,struct LP_quoteinfo *newqp,char *pairstr) { - double price,qprice,bestprice,range,bid,ask; struct iguana_info *coin; struct LP_utxoinfo A,B,*autxo,*butxo; cJSON *reqjson; char str[65]; struct LP_address_utxo *utxos[1000]; int32_t r,counter,max = (int32_t)(sizeof(utxos)/sizeof(*utxos)); + double price,qprice,myprice,bestprice,range,bid,ask; struct iguana_info *coin; struct LP_utxoinfo A,B,*autxo,*butxo; cJSON *reqjson; char str[65]; struct LP_address_utxo *utxos[1000]; int32_t r,counter,max = (int32_t)(sizeof(utxos)/sizeof(*utxos)); *newqp = *qp; qp = newqp; if ( (coin= LP_coinfind(qp->srccoin)) == 0 ) return(0); printf("LP_trades_gotrequest %s/%s %.8f\n",qp->srccoin,qp->destcoin,LP_trades_bobprice(&bid,&ask,qp)); - if ( (price= LP_trades_bobprice(&bid,&ask,qp)) == 0. ) + if ( (myprice= LP_trades_bobprice(&bid,&ask,qp)) == 0. ) return(0); - printf("LP_trades_gotrequest price %.8f\n",price); autxo = &A; butxo = &B; memset(autxo,0,sizeof(*autxo)); @@ -909,12 +908,12 @@ struct LP_quoteinfo *LP_trades_gotrequest(void *ctx,struct LP_quoteinfo *qp,stru memset(&qp->txid2,0,sizeof(qp->txid2)); qp->vout = qp->vout2 = -1; } else return(0); - printf("LP_trades_gotrequest qprice %.8f vs price %.8f\n",qprice,price); - if ( qprice > price ) + printf("LP_trades_gotrequest qprice %.8f vs myprice %.8f\n",qprice,myprice); + if ( qprice > myprice ) { r = (LP_rand() % 100); - range = (qprice - price); - price += (r * range) / 100.; + range = (qprice - myprice); + price = myprice + (r * range) / 100.; bestprice = LP_bob_competition(&counter,qp->aliceid,price,0); printf("%llu >>>>>>> qprice %.8f r.%d range %.8f -> %.8f, bestprice %.8f counter.%d\n",(long long)qp->aliceid,qprice,r,range,price,bestprice,counter); if ( counter > 3 && price >= bestprice-SMALLVAL ) // skip if late or bad price @@ -944,7 +943,7 @@ struct LP_quoteinfo *LP_trades_gotrequest(void *ctx,struct LP_quoteinfo *qp,stru printf("cant find utxopair aliceid.%llu %s/%s %.8f -> relvol %.8f\n",(long long)qp->aliceid,qp->srccoin,qp->destcoin,dstr(LP_basesatoshis(dstr(qp->destsatoshis),price,qp->txfee,qp->desttxfee)),dstr(qp->destsatoshis)); return(0); } - if ( (qprice= LP_trades_pricevalidate(qp,coin,price)) < 0. ) + if ( (qprice= LP_trades_pricevalidate(qp,coin,myprice)) < 0. ) return(0); if ( LP_allocated(qp->txid,qp->vout) == 0 && LP_allocated(qp->txid2,qp->vout2) == 0 ) { @@ -986,16 +985,16 @@ struct LP_quoteinfo *LP_trades_gotreserved(void *ctx,struct LP_quoteinfo *qp,str struct LP_quoteinfo *LP_trades_gotconnect(void *ctx,struct LP_quoteinfo *qp,struct LP_quoteinfo *newqp,char *pairstr) { - double price,qprice,bid,ask; struct iguana_info *coin; + double myprice,qprice,bid,ask; struct iguana_info *coin; *newqp = *qp; qp = newqp; if ( (coin= LP_coinfind(qp->srccoin)) == 0 ) return(0); - if ( (price= LP_trades_bobprice(&bid,&ask,qp)) == 0. ) + if ( (myprice= LP_trades_bobprice(&bid,&ask,qp)) == 0. ) return(0); if ( bits256_cmp(G.LP_mypub25519,qp->srchash) != 0 || bits256_cmp(G.LP_mypub25519,qp->desthash) == 0 ) return(0); - if ( (qprice= LP_trades_pricevalidate(qp,coin,price)) < 0. ) + if ( (qprice= LP_trades_pricevalidate(qp,coin,myprice)) < 0. ) return(0); if ( LP_reservation_check(qp->txid,qp->vout,qp->desthash) == 0 && LP_reservation_check(qp->txid2,qp->vout2,qp->desthash) == 0 ) { From 6c0d26f8c5f90f70bed92b648ab2e3c61434a00b Mon Sep 17 00:00:00 2001 From: jl777 Date: Sun, 26 Nov 2017 19:40:51 +0400 Subject: [PATCH 1291/1664] Test --- iguana/exchanges/LP_ordermatch.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/iguana/exchanges/LP_ordermatch.c b/iguana/exchanges/LP_ordermatch.c index c3814d306..071801a56 100644 --- a/iguana/exchanges/LP_ordermatch.c +++ b/iguana/exchanges/LP_ordermatch.c @@ -1056,7 +1056,7 @@ void LP_tradesloop(void *ctx) now = (uint32_t)time(NULL); Q = qtp->Q; funcid = qtp->funcid; - printf("dequeue %p funcid.%d aliceid.%llu iambob.%d\n",qtp,funcid,(long long)qtp->aliceid,qtp->iambob); + //printf("dequeue %p funcid.%d aliceid.%llu iambob.%d\n",qtp,funcid,(long long)qtp->aliceid,qtp->iambob); portable_mutex_lock(&LP_tradesmutex); DL_DELETE(LP_tradesQ,qtp); HASH_FIND(hh,LP_trades,&qtp->aliceid,sizeof(qtp->aliceid),tp); @@ -1065,7 +1065,7 @@ void LP_tradesloop(void *ctx) tp = qtp; HASH_ADD(hh,LP_trades,aliceid,sizeof(tp->aliceid),tp); portable_mutex_unlock(&LP_tradesmutex); - printf("iambob.%d funcid.%d vs %d\n",tp->iambob,funcid,LP_REQUEST); + //printf("iambob.%d funcid.%d vs %d\n",tp->iambob,funcid,LP_REQUEST); if ( tp->iambob != 0 && funcid == LP_REQUEST ) // bob maybe sends LP_RESERVED { if ( (qp= LP_trades_gotrequest(ctx,&Q,&tp->Qs[LP_REQUEST],tp->pairstr)) != 0 ) @@ -1155,7 +1155,7 @@ void LP_tradesloop(void *ctx) } else if ( now > tp->firstprocessed+600 ) { - printf("purge swap aliceid.%llu\n",(long long)tp->aliceid); + //printf("purge swap aliceid.%llu\n",(long long)tp->aliceid); portable_mutex_lock(&LP_tradesmutex); HASH_DELETE(hh,LP_trades,tp); portable_mutex_unlock(&LP_tradesmutex); @@ -1188,7 +1188,7 @@ void LP_tradecommandQ(struct LP_quoteinfo *qp,char *pairstr,int32_t funcid) safecopy(qtp->pairstr,pairstr,sizeof(qtp->pairstr)); DL_APPEND(LP_tradesQ,qtp); portable_mutex_unlock(&LP_tradesmutex); - printf("queue.%d %p\n",funcid,qtp); + //printf("queue.%d %p\n",funcid,qtp); } int32_t LP_tradecommand(void *ctx,char *myipaddr,int32_t pubsock,cJSON *argjson,uint8_t *data,int32_t datalen) From 939a6d86fc6ee7199bba738c57152e120310ffbc Mon Sep 17 00:00:00 2001 From: jl777 Date: Sun, 26 Nov 2017 19:56:42 +0400 Subject: [PATCH 1292/1664] Test --- iguana/exchanges/LP_ordermatch.c | 13 ++++--------- iguana/exchanges/LP_prices.c | 2 +- 2 files changed, 5 insertions(+), 10 deletions(-) diff --git a/iguana/exchanges/LP_ordermatch.c b/iguana/exchanges/LP_ordermatch.c index 071801a56..6f8ca81cf 100644 --- a/iguana/exchanges/LP_ordermatch.c +++ b/iguana/exchanges/LP_ordermatch.c @@ -514,13 +514,7 @@ int32_t LP_connectstartbob(void *ctx,int32_t pubsock,char *base,char *rel,double char *LP_trade(void *ctx,char *myipaddr,int32_t mypubsock,struct LP_quoteinfo *qp,double maxprice,int32_t timeout,int32_t duration,uint32_t tradeid,bits256 destpubkey) { - //struct LP_utxoinfo *aliceutxo; - double price; - /*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\"}")); - }*/ + double price; int32_t changed; price = 0.; memset(qp->txid.bytes,0,sizeof(qp->txid)); qp->txid2 = qp->txid; @@ -529,6 +523,7 @@ char *LP_trade(void *ctx,char *myipaddr,int32_t mypubsock,struct LP_quoteinfo *q qp->tradeid = LP_rand(); LP_query(ctx,myipaddr,mypubsock,"request",qp); LP_Alicequery = *qp, LP_Alicemaxprice = maxprice, Alice_expiration = qp->timestamp + timeout, LP_Alicedestpubkey = destpubkey; + LP_mypriceset(&changed,qp->destcoin,qp->srccoin,1. / maxprice); char str[65]; printf("LP_trade %s/%s %.8f vol %.8f dest.(%s) maxprice %.8f\n",qp->srccoin,qp->destcoin,dstr(qp->satoshis),dstr(qp->destsatoshis),bits256_str(str,LP_Alicedestpubkey),maxprice); return(LP_recent_swaps(0)); } @@ -837,7 +832,7 @@ double LP_trades_bobprice(double *bidp,double *askp,struct LP_quoteinfo *qp) return(0.); } price = *askp; - printf("MYPRICE %s/%s %.8f vs qprice %.8f\n",qp->srccoin,qp->destcoin,price,(double)qp->destsatoshis/qp->satoshis); + //printf("MYPRICE %s/%s %.8f vs qprice %.8f\n",qp->srccoin,qp->destcoin,price,(double)qp->destsatoshis/qp->satoshis); if ( LP_validSPV(qp->destcoin,qp->destaddr,qp->desttxid,qp->destvout) < 0 ) { printf("%s dest %s failed SPV check\n",qp->destcoin,bits256_str(str,qp->desttxid)); @@ -1056,7 +1051,7 @@ void LP_tradesloop(void *ctx) now = (uint32_t)time(NULL); Q = qtp->Q; funcid = qtp->funcid; - //printf("dequeue %p funcid.%d aliceid.%llu iambob.%d\n",qtp,funcid,(long long)qtp->aliceid,qtp->iambob); + printf("dequeue %p funcid.%d aliceid.%llu iambob.%d\n",qtp,funcid,(long long)qtp->aliceid,qtp->iambob); portable_mutex_lock(&LP_tradesmutex); DL_DELETE(LP_tradesQ,qtp); HASH_FIND(hh,LP_trades,&qtp->aliceid,sizeof(qtp->aliceid),tp); diff --git a/iguana/exchanges/LP_prices.c b/iguana/exchanges/LP_prices.c index a41a7ac7e..43bb8c8d0 100644 --- a/iguana/exchanges/LP_prices.c +++ b/iguana/exchanges/LP_prices.c @@ -576,7 +576,7 @@ int32_t LP_mypriceset(int32_t *changedp,char *base,char *rel,double price) if ( fabs(basepp->myprices[relpp->ind] - price)/price > 0.001 ) *changedp = 1; basepp->myprices[relpp->ind] = price; // ask - //printf("LP_mypriceset base.%s rel.%s <- price %.8f\n",base,rel,price); + printf("LP_mypriceset base.%s rel.%s <- price %.8f\n",base,rel,price); //relpp->myprices[basepp->ind] = (1. / price); // bid if ( (pubp= LP_pubkeyadd(G.LP_mypub25519)) != 0 ) { From b0e068144dcb1e3913fe3d2fa37b9031e02b4d6b Mon Sep 17 00:00:00 2001 From: jl777 Date: Sun, 26 Nov 2017 20:01:06 +0400 Subject: [PATCH 1293/1664] Test --- iguana/exchanges/LP_ordermatch.c | 9 +++++++-- iguana/exchanges/LP_prices.c | 2 +- 2 files changed, 8 insertions(+), 3 deletions(-) diff --git a/iguana/exchanges/LP_ordermatch.c b/iguana/exchanges/LP_ordermatch.c index 6f8ca81cf..60b317a1d 100644 --- a/iguana/exchanges/LP_ordermatch.c +++ b/iguana/exchanges/LP_ordermatch.c @@ -1240,9 +1240,14 @@ int32_t LP_tradecommand(void *ctx,char *myipaddr,int32_t pubsock,cJSON *argjson, } } price = LP_myprice(&bid,&ask,Q.srccoin,Q.destcoin); - if ( (coin= LP_coinfind(Q.srccoin)) == 0 || price <= SMALLVAL || ask <= SMALLVAL ) + if ( (coin= LP_coinfind(Q.srccoin)) == 0 || coin->inactive != 0 ) { - printf("this node has no price for %s/%s\n",Q.srccoin,Q.destcoin); + printf("%s is not active\n",Q.srccoin); + return(retval); + } + if ( price <= SMALLVAL || ask <= SMALLVAL ) + { + //printf("this node has no price for %s/%s\n",Q.srccoin,Q.destcoin); return(retval); } if ( LP_aliceonly(Q.srccoin) > 0 ) diff --git a/iguana/exchanges/LP_prices.c b/iguana/exchanges/LP_prices.c index 43bb8c8d0..a41a7ac7e 100644 --- a/iguana/exchanges/LP_prices.c +++ b/iguana/exchanges/LP_prices.c @@ -576,7 +576,7 @@ int32_t LP_mypriceset(int32_t *changedp,char *base,char *rel,double price) if ( fabs(basepp->myprices[relpp->ind] - price)/price > 0.001 ) *changedp = 1; basepp->myprices[relpp->ind] = price; // ask - printf("LP_mypriceset base.%s rel.%s <- price %.8f\n",base,rel,price); + //printf("LP_mypriceset base.%s rel.%s <- price %.8f\n",base,rel,price); //relpp->myprices[basepp->ind] = (1. / price); // bid if ( (pubp= LP_pubkeyadd(G.LP_mypub25519)) != 0 ) { From a0a94f2b60dbaae685b39f5899ad656e42e3d5af Mon Sep 17 00:00:00 2001 From: jl777 Date: Sun, 26 Nov 2017 20:04:13 +0400 Subject: [PATCH 1294/1664] Test --- iguana/exchanges/LP_ordermatch.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/iguana/exchanges/LP_ordermatch.c b/iguana/exchanges/LP_ordermatch.c index 60b317a1d..e01c7f003 100644 --- a/iguana/exchanges/LP_ordermatch.c +++ b/iguana/exchanges/LP_ordermatch.c @@ -930,7 +930,7 @@ struct LP_quoteinfo *LP_trades_gotrequest(void *ctx,struct LP_quoteinfo *qp,stru qp->vout = butxo->payment.vout; qp->txid2 = butxo->deposit.txid; qp->vout2 = butxo->deposit.vout; - qp->satoshis = butxo->swap_satoshis + qp->txfee; + qp->satoshis = butxo->swap_satoshis;// + qp->txfee; qp->quotetime = (uint32_t)time(NULL); } else @@ -1051,7 +1051,7 @@ void LP_tradesloop(void *ctx) now = (uint32_t)time(NULL); Q = qtp->Q; funcid = qtp->funcid; - printf("dequeue %p funcid.%d aliceid.%llu iambob.%d\n",qtp,funcid,(long long)qtp->aliceid,qtp->iambob); + //printf("dequeue %p funcid.%d aliceid.%llu iambob.%d\n",qtp,funcid,(long long)qtp->aliceid,qtp->iambob); portable_mutex_lock(&LP_tradesmutex); DL_DELETE(LP_tradesQ,qtp); HASH_FIND(hh,LP_trades,&qtp->aliceid,sizeof(qtp->aliceid),tp); From 95933724c5f263ddeb160eb8f869ca1ddd90975b Mon Sep 17 00:00:00 2001 From: jl777 Date: Sun, 26 Nov 2017 20:07:43 +0400 Subject: [PATCH 1295/1664] Test --- iguana/exchanges/LP_ordermatch.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/iguana/exchanges/LP_ordermatch.c b/iguana/exchanges/LP_ordermatch.c index e01c7f003..efaab00cf 100644 --- a/iguana/exchanges/LP_ordermatch.c +++ b/iguana/exchanges/LP_ordermatch.c @@ -903,7 +903,7 @@ struct LP_quoteinfo *LP_trades_gotrequest(void *ctx,struct LP_quoteinfo *qp,stru memset(&qp->txid2,0,sizeof(qp->txid2)); qp->vout = qp->vout2 = -1; } else return(0); - printf("LP_trades_gotrequest qprice %.8f vs myprice %.8f\n",qprice,myprice); + //printf("LP_trades_gotrequest qprice %.8f vs myprice %.8f\n",qprice,myprice); if ( qprice > myprice ) { r = (LP_rand() % 100); @@ -1242,7 +1242,7 @@ int32_t LP_tradecommand(void *ctx,char *myipaddr,int32_t pubsock,cJSON *argjson, price = LP_myprice(&bid,&ask,Q.srccoin,Q.destcoin); if ( (coin= LP_coinfind(Q.srccoin)) == 0 || coin->inactive != 0 ) { - printf("%s is not active\n",Q.srccoin); + //printf("%s is not active\n",Q.srccoin); return(retval); } if ( price <= SMALLVAL || ask <= SMALLVAL ) From 3d35db04c70c44144299c219dd0eab9322edea6c Mon Sep 17 00:00:00 2001 From: jl777 Date: Sun, 26 Nov 2017 20:10:03 +0400 Subject: [PATCH 1296/1664] Test --- iguana/exchanges/LP_signatures.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/iguana/exchanges/LP_signatures.c b/iguana/exchanges/LP_signatures.c index dac28c62e..f48a3d725 100644 --- a/iguana/exchanges/LP_signatures.c +++ b/iguana/exchanges/LP_signatures.c @@ -670,9 +670,9 @@ void LP_query(void *ctx,char *myipaddr,int32_t mypubsock,char *method,struct LP_ //if ( bits256_nonz(qp->srchash) == 0 || strcmp(method,"request") != 0 ) { memset(&zero,0,sizeof(zero)); - LP_reserved_msg(1,qp->srccoin,qp->destcoin,qp->desthash,clonestr(msg)); - sleep(1); LP_reserved_msg(1,qp->srccoin,qp->destcoin,zero,clonestr(msg)); + sleep(1); + //LP_reserved_msg(1,qp->srccoin,qp->destcoin,qp->desthash,clonestr(msg)); //LP_reserved_msg(0,qp->srccoin,qp->destcoin,zero,clonestr(msg)); free(msg); /*portable_mutex_lock(&LP_reservedmutex); From e8c29797c0b79248ee65488fd5ad96a98fa3c5e8 Mon Sep 17 00:00:00 2001 From: jl777 Date: Sun, 26 Nov 2017 20:19:42 +0400 Subject: [PATCH 1297/1664] Test --- iguana/exchanges/LP_ordermatch.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/iguana/exchanges/LP_ordermatch.c b/iguana/exchanges/LP_ordermatch.c index efaab00cf..342f0b72e 100644 --- a/iguana/exchanges/LP_ordermatch.c +++ b/iguana/exchanges/LP_ordermatch.c @@ -1020,8 +1020,9 @@ int32_t LP_trades_bestpricecheck(void *ctx,struct LP_trade *tp) double qprice; struct LP_quoteinfo Q; int64_t dynamictrust; Q = tp->Q; //printf("check bestprice %.8f vs new price %.8f\n",tp->bestprice,(double)Q.destsatoshis/Q.satoshis); - if ( (qprice= LP_trades_alicevalidate(ctx,&Q)) > 0. ) + if ( Q.satoshis != 0 )//(qprice= LP_trades_alicevalidate(ctx,&Q)) > 0. ) { + qprice = (double)Q.destsatoshis / (Q.satoshis - Q.txfee); LP_trades_gotreserved(ctx,&Q,&tp->Qs[LP_RESERVED]); dynamictrust = LP_dynamictrust(Q.srchash,LP_kmdvalue(Q.srccoin,Q.satoshis)); if ( tp->bestprice == 0. || (qprice < tp->bestprice || (qprice < tp->bestprice*1.01 && dynamictrust > tp->besttrust)) ) From 116123b7dc167a5b45d7c4f2e3ff89de5d662be7 Mon Sep 17 00:00:00 2001 From: jl777 Date: Sun, 26 Nov 2017 20:33:19 +0400 Subject: [PATCH 1298/1664] Test --- iguana/exchanges/LP_include.h | 2 +- iguana/exchanges/LP_ordermatch.c | 35 +++++++++++++++----------------- 2 files changed, 17 insertions(+), 20 deletions(-) diff --git a/iguana/exchanges/LP_include.h b/iguana/exchanges/LP_include.h index 41e7a801e..02b069427 100644 --- a/iguana/exchanges/LP_include.h +++ b/iguana/exchanges/LP_include.h @@ -43,7 +43,7 @@ void emscripten_usleep(int32_t x); // returns immediate, no sense for sleeping #define LP_MAXVINS 64 #define LP_HTTP_TIMEOUT 3 // 1 is too small due to edge cases of time(NULL) -#define LP_AUTOTRADE_TIMEOUT 30 +#define LP_AUTOTRADE_TIMEOUT 40 #define LP_RESERVETIME 600 //(LP_AUTOTRADE_TIMEOUT * 2) #define ELECTRUM_TIMEOUT 7 #define LP_ELECTRUM_KEEPALIVE 60 diff --git a/iguana/exchanges/LP_ordermatch.c b/iguana/exchanges/LP_ordermatch.c index 342f0b72e..b1a309bcd 100644 --- a/iguana/exchanges/LP_ordermatch.c +++ b/iguana/exchanges/LP_ordermatch.c @@ -1030,7 +1030,7 @@ int32_t LP_trades_bestpricecheck(void *ctx,struct LP_trade *tp) tp->Qs[LP_CONNECT] = tp->Q; tp->bestprice = qprice; tp->besttrust = dynamictrust; - //printf("aliceid.%llu got price %.8f dynamictrust %.8f\n",(long long)tp->aliceid,tp->bestprice,dstr(dynamictrust)); + printf("aliceid.%llu got new bestprice %.8f dynamictrust %.8f\n",(long long)tp->aliceid,tp->bestprice,dstr(dynamictrust)); return(qprice); } //else printf("qprice %.8f dynamictrust %.8f not good enough\n",qprice,dstr(dynamictrust)); } else printf("alice didnt validate\n"); @@ -1052,7 +1052,7 @@ void LP_tradesloop(void *ctx) now = (uint32_t)time(NULL); Q = qtp->Q; funcid = qtp->funcid; - //printf("dequeue %p funcid.%d aliceid.%llu iambob.%d\n",qtp,funcid,(long long)qtp->aliceid,qtp->iambob); + printf("dequeue %p funcid.%d aliceid.%llu iambob.%d\n",qtp,funcid,(long long)qtp->aliceid,qtp->iambob); portable_mutex_lock(&LP_tradesmutex); DL_DELETE(LP_tradesQ,qtp); HASH_FIND(hh,LP_trades,&qtp->aliceid,sizeof(qtp->aliceid),tp); @@ -1127,29 +1127,26 @@ void LP_tradesloop(void *ctx) now = (uint32_t)time(NULL); if ( now > tp->lastprocessed ) { - if ( now < tp->firstprocessed+timeout ) + if ( tp->iambob == 0 ) { - if ( tp->iambob == 0 ) + if ( tp->bestprice > 0. ) { - if ( tp->bestprice > 0. ) + if ( tp->connectsent == 0 ) + { + LP_Alicemaxprice = tp->bestprice; + LP_reserved(ctx,LP_myipaddr,LP_mypubsock,&tp->Qs[LP_CONNECT]); // send LP_CONNECT + tp->connectsent = now; + //printf("send LP_connect aliceid.%llu %.8f\n",(long long)tp->aliceid,tp->bestprice); + } + else if ( now < tp->firstprocessed+timeout && ((tp->firstprocessed - now) % 5) == 4 ) { - if ( tp->connectsent == 0 ) - { - LP_Alicemaxprice = tp->bestprice; - LP_reserved(ctx,LP_myipaddr,LP_mypubsock,&tp->Qs[LP_CONNECT]); // send LP_CONNECT - tp->connectsent = now; - //printf("send LP_connect aliceid.%llu %.8f\n",(long long)tp->aliceid,tp->bestprice); - } - else if ( ((tp->firstprocessed - now) % 5) == 4 ) - { - LP_Alicemaxprice = tp->bestprice; - LP_reserved(ctx,LP_myipaddr,LP_mypubsock,&tp->Qs[LP_CONNECT]); // send LP_CONNECT - printf("repeat LP_connect aliceid.%llu %.8f\n",(long long)tp->aliceid,tp->bestprice); - } + LP_Alicemaxprice = tp->bestprice; + LP_reserved(ctx,LP_myipaddr,LP_mypubsock,&tp->Qs[LP_CONNECT]); // send LP_CONNECT + printf("repeat LP_connect aliceid.%llu %.8f\n",(long long)tp->aliceid,tp->bestprice); } } } - else if ( now > tp->firstprocessed+600 ) + else if ( now > tp->firstprocessed+timeout*10 ) { //printf("purge swap aliceid.%llu\n",(long long)tp->aliceid); portable_mutex_lock(&LP_tradesmutex); From 622adffecd1ec6f10b76b4e246f3a8134e384c09 Mon Sep 17 00:00:00 2001 From: jl777 Date: Sun, 26 Nov 2017 20:40:05 +0400 Subject: [PATCH 1299/1664] Test --- iguana/exchanges/LP_ordermatch.c | 2 +- iguana/exchanges/LP_signatures.c | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/iguana/exchanges/LP_ordermatch.c b/iguana/exchanges/LP_ordermatch.c index b1a309bcd..a58847c74 100644 --- a/iguana/exchanges/LP_ordermatch.c +++ b/iguana/exchanges/LP_ordermatch.c @@ -1052,7 +1052,7 @@ void LP_tradesloop(void *ctx) now = (uint32_t)time(NULL); Q = qtp->Q; funcid = qtp->funcid; - printf("dequeue %p funcid.%d aliceid.%llu iambob.%d\n",qtp,funcid,(long long)qtp->aliceid,qtp->iambob); + //printf("dequeue %p funcid.%d aliceid.%llu iambob.%d\n",qtp,funcid,(long long)qtp->aliceid,qtp->iambob); portable_mutex_lock(&LP_tradesmutex); DL_DELETE(LP_tradesQ,qtp); HASH_FIND(hh,LP_trades,&qtp->aliceid,sizeof(qtp->aliceid),tp); diff --git a/iguana/exchanges/LP_signatures.c b/iguana/exchanges/LP_signatures.c index f48a3d725..f5293ff75 100644 --- a/iguana/exchanges/LP_signatures.c +++ b/iguana/exchanges/LP_signatures.c @@ -672,8 +672,8 @@ void LP_query(void *ctx,char *myipaddr,int32_t mypubsock,char *method,struct LP_ memset(&zero,0,sizeof(zero)); LP_reserved_msg(1,qp->srccoin,qp->destcoin,zero,clonestr(msg)); sleep(1); - //LP_reserved_msg(1,qp->srccoin,qp->destcoin,qp->desthash,clonestr(msg)); - //LP_reserved_msg(0,qp->srccoin,qp->destcoin,zero,clonestr(msg)); + LP_reserved_msg(1,qp->srccoin,qp->destcoin,qp->desthash,clonestr(msg)); + LP_reserved_msg(0,qp->srccoin,qp->destcoin,zero,clonestr(msg)); free(msg); /*portable_mutex_lock(&LP_reservedmutex); if ( num_Reserved_msgs[1] < sizeof(Reserved_msgs[1])/sizeof(*Reserved_msgs[1])-2 ) From 1e38e20c7f8321d18243ce5c74109b00ac805c4e Mon Sep 17 00:00:00 2001 From: jl777 Date: Sun, 26 Nov 2017 20:54:16 +0400 Subject: [PATCH 1300/1664] Test --- iguana/exchanges/LP_socket.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/iguana/exchanges/LP_socket.c b/iguana/exchanges/LP_socket.c index 68d02b3bd..3041b6cbc 100644 --- a/iguana/exchanges/LP_socket.c +++ b/iguana/exchanges/LP_socket.c @@ -419,7 +419,7 @@ cJSON *electrum_submit(char *symbol,struct electrum_info *ep,cJSON **retjsonp,ch { *retjsonp = 0; sprintf(stratumreq,"{ \"jsonrpc\":\"2.0\", \"id\": %u, \"method\":\"%s\", \"params\": %s }\n",ep->stratumid,method,params); -//printf("%s %s",symbol,stratumreq); +printf("%s %s",symbol,stratumreq); memset(ep->buf,0,ep->bufsize); sitem = electrum_sitem(ep,stratumreq,timeout,retjsonp); portable_mutex_lock(&ep->mutex); // this helps performance! From 81062b1ba9a419ac9b2345cb99e399a1359140ad Mon Sep 17 00:00:00 2001 From: jl777 Date: Sun, 26 Nov 2017 21:17:11 +0400 Subject: [PATCH 1301/1664] Test --- iguana/exchanges/LP_network.c | 2 +- iguana/exchanges/LP_ordermatch.c | 17 ++++++++++------- 2 files changed, 11 insertions(+), 8 deletions(-) diff --git a/iguana/exchanges/LP_network.c b/iguana/exchanges/LP_network.c index 0f680ad0b..673db2940 100644 --- a/iguana/exchanges/LP_network.c +++ b/iguana/exchanges/LP_network.c @@ -457,7 +457,7 @@ void LP_psockloop(void *_ptr) // printouts seem to be needed for forwarding to w } else if ( (pfds[n].revents & POLLIN) != 0 ) { - printf("publicsock.%d %s has pollin\n",ptr->publicsock,ptr->publicaddr); + //printf("publicsock.%d %s has pollin\n",ptr->publicsock,ptr->publicaddr); buf = 0; if ( (size= nn_recv(ptr->publicsock,&buf,NN_MSG,0)) > 0 ) { diff --git a/iguana/exchanges/LP_ordermatch.c b/iguana/exchanges/LP_ordermatch.c index a58847c74..f2dd80090 100644 --- a/iguana/exchanges/LP_ordermatch.c +++ b/iguana/exchanges/LP_ordermatch.c @@ -514,7 +514,7 @@ int32_t LP_connectstartbob(void *ctx,int32_t pubsock,char *base,char *rel,double char *LP_trade(void *ctx,char *myipaddr,int32_t mypubsock,struct LP_quoteinfo *qp,double maxprice,int32_t timeout,int32_t duration,uint32_t tradeid,bits256 destpubkey) { - double price; int32_t changed; + double price; price = 0.; memset(qp->txid.bytes,0,sizeof(qp->txid)); qp->txid2 = qp->txid; @@ -523,7 +523,6 @@ char *LP_trade(void *ctx,char *myipaddr,int32_t mypubsock,struct LP_quoteinfo *q qp->tradeid = LP_rand(); LP_query(ctx,myipaddr,mypubsock,"request",qp); LP_Alicequery = *qp, LP_Alicemaxprice = maxprice, Alice_expiration = qp->timestamp + timeout, LP_Alicedestpubkey = destpubkey; - LP_mypriceset(&changed,qp->destcoin,qp->srccoin,1. / maxprice); char str[65]; printf("LP_trade %s/%s %.8f vol %.8f dest.(%s) maxprice %.8f\n",qp->srccoin,qp->destcoin,dstr(qp->satoshis),dstr(qp->destsatoshis),bits256_str(str,LP_Alicedestpubkey),maxprice); return(LP_recent_swaps(0)); } @@ -1017,13 +1016,16 @@ struct LP_quoteinfo *LP_trades_gotconnected(void *ctx,struct LP_quoteinfo *qp,st int32_t LP_trades_bestpricecheck(void *ctx,struct LP_trade *tp) { - double qprice; struct LP_quoteinfo Q; int64_t dynamictrust; + double qprice; struct LP_quoteinfo Q; int64_t dynamictrust; char *retstr; Q = tp->Q; //printf("check bestprice %.8f vs new price %.8f\n",tp->bestprice,(double)Q.destsatoshis/Q.satoshis); if ( Q.satoshis != 0 )//(qprice= LP_trades_alicevalidate(ctx,&Q)) > 0. ) { qprice = (double)Q.destsatoshis / (Q.satoshis - Q.txfee); - LP_trades_gotreserved(ctx,&Q,&tp->Qs[LP_RESERVED]); + LP_aliceid(Q.tradeid,tp->aliceid,"reserved",0,0); + if ( (retstr= LP_quotereceived(&Q)) != 0 ) + free(retstr); + //LP_trades_gotreserved(ctx,&Q,&tp->Qs[LP_RESERVED]); dynamictrust = LP_dynamictrust(Q.srchash,LP_kmdvalue(Q.srccoin,Q.satoshis)); if ( tp->bestprice == 0. || (qprice < tp->bestprice || (qprice < tp->bestprice*1.01 && dynamictrust > tp->besttrust)) ) { @@ -1032,7 +1034,7 @@ int32_t LP_trades_bestpricecheck(void *ctx,struct LP_trade *tp) tp->besttrust = dynamictrust; printf("aliceid.%llu got new bestprice %.8f dynamictrust %.8f\n",(long long)tp->aliceid,tp->bestprice,dstr(dynamictrust)); return(qprice); - } //else printf("qprice %.8f dynamictrust %.8f not good enough\n",qprice,dstr(dynamictrust)); + } else printf("qprice %.8f dynamictrust %.8f not good enough\n",qprice,dstr(dynamictrust)); } else printf("alice didnt validate\n"); return(0); } @@ -1052,7 +1054,7 @@ void LP_tradesloop(void *ctx) now = (uint32_t)time(NULL); Q = qtp->Q; funcid = qtp->funcid; - //printf("dequeue %p funcid.%d aliceid.%llu iambob.%d\n",qtp,funcid,(long long)qtp->aliceid,qtp->iambob); +printf("dequeue %p funcid.%d aliceid.%llu iambob.%d\n",qtp,funcid,(long long)qtp->aliceid,qtp->iambob); portable_mutex_lock(&LP_tradesmutex); DL_DELETE(LP_tradesQ,qtp); HASH_FIND(hh,LP_trades,&qtp->aliceid,sizeof(qtp->aliceid),tp); @@ -1061,7 +1063,6 @@ void LP_tradesloop(void *ctx) tp = qtp; HASH_ADD(hh,LP_trades,aliceid,sizeof(tp->aliceid),tp); portable_mutex_unlock(&LP_tradesmutex); - //printf("iambob.%d funcid.%d vs %d\n",tp->iambob,funcid,LP_REQUEST); if ( tp->iambob != 0 && funcid == LP_REQUEST ) // bob maybe sends LP_RESERVED { if ( (qp= LP_trades_gotrequest(ctx,&Q,&tp->Qs[LP_REQUEST],tp->pairstr)) != 0 ) @@ -1073,12 +1074,14 @@ void LP_tradesloop(void *ctx) } nonz++; tp->firstprocessed = tp->lastprocessed = (uint32_t)time(NULL); +printf("iambob.%d funcid.%d vs %d\n",tp->iambob,funcid,LP_REQUEST); continue; } portable_mutex_unlock(&LP_tradesmutex); tp->Q = qtp->Q; if ( qtp->iambob == tp->iambob && qtp->pairstr[0] != 0 ) safecopy(tp->pairstr,qtp->pairstr,sizeof(tp->pairstr)); +printf("finished dequeue %p funcid.%d aliceid.%llu iambob.%d\n",qtp,funcid,(long long)qtp->aliceid,qtp->iambob); free(qtp); if ( tp->negotiationdone != 0 ) continue; From bf7260e4843508da07e927580bc8f358acf78b78 Mon Sep 17 00:00:00 2001 From: jl777 Date: Sun, 26 Nov 2017 21:26:53 +0400 Subject: [PATCH 1302/1664] Test --- iguana/exchanges/LP_cache.c | 7 +++---- iguana/exchanges/LP_ordermatch.c | 9 ++++----- 2 files changed, 7 insertions(+), 9 deletions(-) diff --git a/iguana/exchanges/LP_cache.c b/iguana/exchanges/LP_cache.c index d51e44922..226df276f 100644 --- a/iguana/exchanges/LP_cache.c +++ b/iguana/exchanges/LP_cache.c @@ -45,10 +45,9 @@ struct LP_transaction *LP_create_transaction(struct iguana_info *coin,bits256 tx vins = jarray(&numvins,txobj,"vin"); vouts = jarray(&numvouts,txobj,"vout"); tx = LP_transactionadd(coin,txid,height,numvouts,numvins); - tx->serialized = 0;//serialized; - free(serialized); + tx->serialized = serialized, tx->len = 0; + //free(serialized), tx->len = 0; tx->fpos = fpos; - tx->len = 0;//tx->len; tx->SPV = tx->height = height; //printf("tx.%s numvins.%d numvouts.%d\n",bits256_str(str,txid),numvins,numvouts); for (i=0; iSPV = height; - if ( tx->serialized != 0 ) + if ( 0 && tx->serialized != 0 ) { free(tx->serialized); tx->serialized = 0; diff --git a/iguana/exchanges/LP_ordermatch.c b/iguana/exchanges/LP_ordermatch.c index f2dd80090..a19feda6c 100644 --- a/iguana/exchanges/LP_ordermatch.c +++ b/iguana/exchanges/LP_ordermatch.c @@ -121,7 +121,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.; char str[65]; cJSON *txout; uint64_t txfee,desttxfee,srcvalue=0,srcvalue2=0,destvalue=0,destvalue2=0; - //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)); + 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 ) @@ -177,14 +177,11 @@ double LP_quote_validate(struct LP_utxoinfo *autxo,struct LP_utxoinfo *butxo,str return(-24); } } + printf("checked autxo and butxo\n"); if ( LP_quote_checkmempool(qp,autxo,butxo) < 0 ) return(-4); - //if ( iambob != 0 && (*butxop= LP_utxofind(1,qp->txid,qp->vout)) == 0 ) - // return(-5); if ( iambob == 0 && autxo != 0 ) { - //if ( (*autxop= LP_utxofind(0,qp->desttxid,qp->destvout)) == 0 ) - // return(-8); if ( bits256_cmp(autxo->fee.txid,qp->feetxid) != 0 || autxo->fee.vout != qp->feevout ) return(-9); if ( strcmp(autxo->coinaddr,qp->destaddr) != 0 ) @@ -1006,11 +1003,13 @@ struct LP_quoteinfo *LP_trades_gotconnected(void *ctx,struct LP_quoteinfo *qp,st qp = newqp; if ( LP_trades_alicevalidate(ctx,qp) > 0. ) { + printf("LP_trades_alicevalidate fine\n"); LP_aliceid(qp->tradeid,qp->aliceid,"connected",0,0); if ( (retstr= LP_connectedalice(qp,pairstr)) != 0 ) free(retstr); return(qp); } + printf("LP_trades_alicevalidate error\n"); return(0); } From cd00d7086115d5e36ebf6ce9c69ab2cd5ea61d75 Mon Sep 17 00:00:00 2001 From: jl777 Date: Sun, 26 Nov 2017 21:37:50 +0400 Subject: [PATCH 1303/1664] Test --- iguana/exchanges/LP_include.h | 2 +- iguana/exchanges/LP_ordermatch.c | 16 ++++++++-------- iguana/exchanges/LP_socket.c | 2 +- 3 files changed, 10 insertions(+), 10 deletions(-) diff --git a/iguana/exchanges/LP_include.h b/iguana/exchanges/LP_include.h index 02b069427..fe002e281 100644 --- a/iguana/exchanges/LP_include.h +++ b/iguana/exchanges/LP_include.h @@ -43,7 +43,7 @@ void emscripten_usleep(int32_t x); // returns immediate, no sense for sleeping #define LP_MAXVINS 64 #define LP_HTTP_TIMEOUT 3 // 1 is too small due to edge cases of time(NULL) -#define LP_AUTOTRADE_TIMEOUT 40 +#define LP_AUTOTRADE_TIMEOUT 60 #define LP_RESERVETIME 600 //(LP_AUTOTRADE_TIMEOUT * 2) #define ELECTRUM_TIMEOUT 7 #define LP_ELECTRUM_KEEPALIVE 60 diff --git a/iguana/exchanges/LP_ordermatch.c b/iguana/exchanges/LP_ordermatch.c index a19feda6c..54619b202 100644 --- a/iguana/exchanges/LP_ordermatch.c +++ b/iguana/exchanges/LP_ordermatch.c @@ -121,7 +121,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.; char str[65]; cJSON *txout; uint64_t txfee,desttxfee,srcvalue=0,srcvalue2=0,destvalue=0,destvalue2=0; - 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)); + //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 ) @@ -177,7 +177,7 @@ double LP_quote_validate(struct LP_utxoinfo *autxo,struct LP_utxoinfo *butxo,str return(-24); } } - printf("checked autxo and butxo\n"); + //printf("checked autxo and butxo\n"); if ( LP_quote_checkmempool(qp,autxo,butxo) < 0 ) return(-4); if ( iambob == 0 && autxo != 0 ) @@ -576,7 +576,7 @@ char *LP_connectedalice(struct LP_quoteinfo *qp,char *pairstr) // alice } printf("CONNECTED numpending.%d tradeid.%u requestid.%u quoteid.%u pairstr.%s\n",G.LP_pendingswaps,qp->tradeid,qp->R.requestid,qp->R.quoteid,pairstr!=0?pairstr:""); LP_requestinit(&qp->R,qp->srchash,qp->desthash,qp->srccoin,qp->satoshis-qp->txfee,qp->destcoin,qp->destsatoshis-qp->desttxfee,qp->timestamp,qp->quotetime,DEXselector); - printf("calculated requestid.%u quoteid.%u\n",qp->R.requestid,qp->R.quoteid); + //printf("calculated requestid.%u quoteid.%u\n",qp->R.requestid,qp->R.quoteid); if ( LP_pendingswap(qp->R.requestid,qp->R.quoteid) > 0 ) { printf("requestid.%u quoteid.%u is already in progres\n",qp->R.requestid,qp->R.quoteid); @@ -1003,13 +1003,13 @@ struct LP_quoteinfo *LP_trades_gotconnected(void *ctx,struct LP_quoteinfo *qp,st qp = newqp; if ( LP_trades_alicevalidate(ctx,qp) > 0. ) { - printf("LP_trades_alicevalidate fine\n"); + //printf("LP_trades_alicevalidate fine\n"); LP_aliceid(qp->tradeid,qp->aliceid,"connected",0,0); if ( (retstr= LP_connectedalice(qp,pairstr)) != 0 ) free(retstr); return(qp); } - printf("LP_trades_alicevalidate error\n"); + //printf("LP_trades_alicevalidate error\n"); return(0); } @@ -1053,7 +1053,7 @@ void LP_tradesloop(void *ctx) now = (uint32_t)time(NULL); Q = qtp->Q; funcid = qtp->funcid; -printf("dequeue %p funcid.%d aliceid.%llu iambob.%d\n",qtp,funcid,(long long)qtp->aliceid,qtp->iambob); +//printf("dequeue %p funcid.%d aliceid.%llu iambob.%d\n",qtp,funcid,(long long)qtp->aliceid,qtp->iambob); portable_mutex_lock(&LP_tradesmutex); DL_DELETE(LP_tradesQ,qtp); HASH_FIND(hh,LP_trades,&qtp->aliceid,sizeof(qtp->aliceid),tp); @@ -1073,14 +1073,14 @@ printf("dequeue %p funcid.%d aliceid.%llu iambob.%d\n",qtp,funcid,(long long)qtp } nonz++; tp->firstprocessed = tp->lastprocessed = (uint32_t)time(NULL); -printf("iambob.%d funcid.%d vs %d\n",tp->iambob,funcid,LP_REQUEST); +//printf("iambob.%d funcid.%d vs %d\n",tp->iambob,funcid,LP_REQUEST); continue; } portable_mutex_unlock(&LP_tradesmutex); tp->Q = qtp->Q; if ( qtp->iambob == tp->iambob && qtp->pairstr[0] != 0 ) safecopy(tp->pairstr,qtp->pairstr,sizeof(tp->pairstr)); -printf("finished dequeue %p funcid.%d aliceid.%llu iambob.%d\n",qtp,funcid,(long long)qtp->aliceid,qtp->iambob); +//printf("finished dequeue %p funcid.%d aliceid.%llu iambob.%d\n",qtp,funcid,(long long)qtp->aliceid,qtp->iambob); free(qtp); if ( tp->negotiationdone != 0 ) continue; diff --git a/iguana/exchanges/LP_socket.c b/iguana/exchanges/LP_socket.c index 3041b6cbc..68d02b3bd 100644 --- a/iguana/exchanges/LP_socket.c +++ b/iguana/exchanges/LP_socket.c @@ -419,7 +419,7 @@ cJSON *electrum_submit(char *symbol,struct electrum_info *ep,cJSON **retjsonp,ch { *retjsonp = 0; sprintf(stratumreq,"{ \"jsonrpc\":\"2.0\", \"id\": %u, \"method\":\"%s\", \"params\": %s }\n",ep->stratumid,method,params); -printf("%s %s",symbol,stratumreq); +//printf("%s %s",symbol,stratumreq); memset(ep->buf,0,ep->bufsize); sitem = electrum_sitem(ep,stratumreq,timeout,retjsonp); portable_mutex_lock(&ep->mutex); // this helps performance! From ccbad7bade5f8fbab30b1946df171f259f1516ab Mon Sep 17 00:00:00 2001 From: jl777 Date: Sun, 26 Nov 2017 21:53:55 +0400 Subject: [PATCH 1304/1664] Test --- iguana/exchanges/LP_ordermatch.c | 4 ++-- iguana/exchanges/LP_prices.c | 2 +- iguana/exchanges/LP_swap.c | 4 ++-- 3 files changed, 5 insertions(+), 5 deletions(-) diff --git a/iguana/exchanges/LP_ordermatch.c b/iguana/exchanges/LP_ordermatch.c index 54619b202..dd3920dfc 100644 --- a/iguana/exchanges/LP_ordermatch.c +++ b/iguana/exchanges/LP_ordermatch.c @@ -1033,7 +1033,7 @@ int32_t LP_trades_bestpricecheck(void *ctx,struct LP_trade *tp) tp->besttrust = dynamictrust; printf("aliceid.%llu got new bestprice %.8f dynamictrust %.8f\n",(long long)tp->aliceid,tp->bestprice,dstr(dynamictrust)); return(qprice); - } else printf("qprice %.8f dynamictrust %.8f not good enough\n",qprice,dstr(dynamictrust)); + } //else printf("qprice %.8f dynamictrust %.8f not good enough\n",qprice,dstr(dynamictrust)); } else printf("alice didnt validate\n"); return(0); } @@ -1140,7 +1140,7 @@ void LP_tradesloop(void *ctx) tp->connectsent = now; //printf("send LP_connect aliceid.%llu %.8f\n",(long long)tp->aliceid,tp->bestprice); } - else if ( now < tp->firstprocessed+timeout && ((tp->firstprocessed - now) % 5) == 4 ) + else if ( now < tp->firstprocessed+timeout && ((tp->firstprocessed - now) % 10) == 9 ) { LP_Alicemaxprice = tp->bestprice; LP_reserved(ctx,LP_myipaddr,LP_mypubsock,&tp->Qs[LP_CONNECT]); // send LP_CONNECT diff --git a/iguana/exchanges/LP_prices.c b/iguana/exchanges/LP_prices.c index a41a7ac7e..101440955 100644 --- a/iguana/exchanges/LP_prices.c +++ b/iguana/exchanges/LP_prices.c @@ -485,7 +485,7 @@ double LP_pricecache(struct LP_quoteinfo *qp,char *base,char *rel,bits256 txid,i ptr->price = 0.; printf("LP_pricecache: set %s/%s ptr->price %.8f\n",base,rel,ptr->price); } - printf(">>>>>>>>>> found %s/%s %.8f\n",base,rel,ptr->price); + //printf(">>>>>>>>>> found %s/%s %.8f\n",base,rel,ptr->price); return(ptr->price); } //char str[65]; printf("cachemiss %s/%s %s/v%d\n",base,rel,bits256_str(str,txid),vout); diff --git a/iguana/exchanges/LP_swap.c b/iguana/exchanges/LP_swap.c index c19c10df2..4a7f07f7f 100644 --- a/iguana/exchanges/LP_swap.c +++ b/iguana/exchanges/LP_swap.c @@ -794,7 +794,7 @@ void LP_bobloop(void *_swap) expiration = (uint32_t)time(NULL) + LP_SWAPSTEP_TIMEOUT; if ( swap != 0 ) { - if ( LP_waitsend("pubkeys",60,swap->N.pair,swap,data,maxlen,LP_pubkeys_verify,LP_pubkeys_data) < 0 ) + if ( LP_waitsend("pubkeys",120,swap->N.pair,swap,data,maxlen,LP_pubkeys_verify,LP_pubkeys_data) < 0 ) printf("error waitsend pubkeys\n"); else if ( LP_waitsend("choosei",LP_SWAPSTEP_TIMEOUT,swap->N.pair,swap,data,maxlen,LP_choosei_verify,LP_choosei_data) < 0 ) printf("error waitsend choosei\n"); @@ -864,7 +864,7 @@ void LP_aliceloop(void *_swap) if ( swap != 0 ) { printf("start swap iamalice pair.%d\n",swap->N.pair); - if ( LP_sendwait("pubkeys",60,swap->N.pair,swap,data,maxlen,LP_pubkeys_verify,LP_pubkeys_data) < 0 ) + if ( LP_sendwait("pubkeys",120,swap->N.pair,swap,data,maxlen,LP_pubkeys_verify,LP_pubkeys_data) < 0 ) printf("error LP_sendwait pubkeys\n"); else if ( LP_sendwait("choosei",LP_SWAPSTEP_TIMEOUT,swap->N.pair,swap,data,maxlen,LP_choosei_verify,LP_choosei_data) < 0 ) printf("error LP_sendwait choosei\n"); From 085fe53ba1f943f38a4b35736c063704b60a2278 Mon Sep 17 00:00:00 2001 From: jl777 Date: Sun, 26 Nov 2017 22:13:57 +0400 Subject: [PATCH 1305/1664] Test --- iguana/exchanges/LP_prices.c | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/iguana/exchanges/LP_prices.c b/iguana/exchanges/LP_prices.c index 101440955..facf672e6 100644 --- a/iguana/exchanges/LP_prices.c +++ b/iguana/exchanges/LP_prices.c @@ -855,7 +855,7 @@ int32_t LP_orderbook_utxoentries(uint32_t now,int32_t polarity,char *base,char * char *LP_orderbook(char *base,char *rel,int32_t duration) { - uint32_t now,i; int64_t depth; struct LP_priceinfo *basepp=0,*relpp=0; struct LP_orderbookentry **bids = 0,**asks = 0; cJSON *retjson,*array; struct iguana_info *basecoin,*relcoin; int32_t n,numbids=0,numasks=0,cachenumbids,cachenumasks,baseid,relid,suppress_prefetch=0; + uint32_t now,i; int64_t depth,askdepth=0,biddepth=0; struct LP_priceinfo *basepp=0,*relpp=0; struct LP_orderbookentry **bids = 0,**asks = 0; cJSON *retjson,*array; struct iguana_info *basecoin,*relcoin; int32_t n,numbids=0,numasks=0,cachenumbids,cachenumasks,baseid,relid,suppress_prefetch=0; basecoin = LP_coinfind(base); relcoin = LP_coinfind(rel); if ( basecoin == 0 || relcoin == 0 ) @@ -902,6 +902,7 @@ char *LP_orderbook(char *base,char *rel,int32_t duration) } for (i=n=0; idepth; jaddi(array,LP_orderbookjson(rel,bids[i])); if ( suppress_prefetch == 0 && n < 3 && bids[i]->numutxos == 0 ) { @@ -923,9 +924,11 @@ char *LP_orderbook(char *base,char *rel,int32_t duration) relcoin->lastmonitor -= 3600; jadd(retjson,"bids",array); jaddnum(retjson,"numbids",numbids); + jaddnum(retjson,"biddepth",dstr(biddepth)); array = cJSON_CreateArray(); for (i=n=0; idepth; jaddi(array,LP_orderbookjson(base,asks[i])); if ( suppress_prefetch == 0 && n < 3 && asks[i]->numutxos == 0 ) { @@ -947,6 +950,7 @@ char *LP_orderbook(char *base,char *rel,int32_t duration) basecoin->lastmonitor -= 3600; jadd(retjson,"asks",array); jaddnum(retjson,"numasks",numasks); + jaddnum(retjson,"askdepth",dstr(askdepth)); jaddstr(retjson,"base",base); jaddstr(retjson,"rel",rel); jaddnum(retjson,"timestamp",now); From 308d4743ce233b9c3bb95068361db966b981d6f6 Mon Sep 17 00:00:00 2001 From: jl777 Date: Sun, 26 Nov 2017 22:26:40 +0400 Subject: [PATCH 1306/1664] Test --- iguana/exchanges/LP_commands.c | 2 +- iguana/exchanges/LP_ordermatch.c | 2 +- iguana/exchanges/LP_remember.c | 4 ++-- iguana/exchanges/LP_rpc.c | 11 ++++++----- iguana/exchanges/LP_socket.c | 2 +- iguana/exchanges/LP_transaction.c | 8 ++++---- iguana/exchanges/LP_utxo.c | 6 +++--- iguana/exchanges/LP_zeroconf.c | 2 +- 8 files changed, 19 insertions(+), 18 deletions(-) diff --git a/iguana/exchanges/LP_commands.c b/iguana/exchanges/LP_commands.c index d06660352..392de5386 100644 --- a/iguana/exchanges/LP_commands.c +++ b/iguana/exchanges/LP_commands.c @@ -474,7 +474,7 @@ zeroconf_claim(address, expiration=0)\n\ } else if ( strcmp(method,"getrawtransaction") == 0 ) { - return(jprint(LP_gettx(coin,jbits256(argjson,"txid")),1)); + return(jprint(LP_gettx(coin,jbits256(argjson,"txid"),0),1)); } else if ( strcmp(method,"withdraw") == 0 ) { diff --git a/iguana/exchanges/LP_ordermatch.c b/iguana/exchanges/LP_ordermatch.c index dd3920dfc..905065d05 100644 --- a/iguana/exchanges/LP_ordermatch.c +++ b/iguana/exchanges/LP_ordermatch.c @@ -880,7 +880,7 @@ struct LP_quoteinfo *LP_trades_gotrequest(void *ctx,struct LP_quoteinfo *qp,stru qp = newqp; if ( (coin= LP_coinfind(qp->srccoin)) == 0 ) return(0); - printf("LP_trades_gotrequest %s/%s %.8f\n",qp->srccoin,qp->destcoin,LP_trades_bobprice(&bid,&ask,qp)); + //printf("LP_trades_gotrequest %s/%s %.8f\n",qp->srccoin,qp->destcoin,LP_trades_bobprice(&bid,&ask,qp)); if ( (myprice= LP_trades_bobprice(&bid,&ask,qp)) == 0. ) return(0); autxo = &A; diff --git a/iguana/exchanges/LP_remember.c b/iguana/exchanges/LP_remember.c index db55baff5..71f7b6ab8 100644 --- a/iguana/exchanges/LP_remember.c +++ b/iguana/exchanges/LP_remember.c @@ -269,7 +269,7 @@ bits256 basilisk_swap_spendupdate(int32_t iambob,char *symbol,char *spentaddr,in //printf("i.%d of %d: %s\n",i,n,bits256_str(str,txid)); if ( bits256_cmp(txid,txids[utxoind]) != 0 ) { - if ( (txobj= LP_gettx(symbol,txid)) != 0 ) + if ( (txobj= LP_gettx(symbol,txid,1)) != 0 ) { //printf("txobj.(%s)\n",jprint(txobj,0)); if ( (vins= jarray(&m,txobj,"vin")) != 0 ) @@ -777,7 +777,7 @@ int32_t LP_swap_load(struct LP_swap_remember *rswap) safecopy(rswap->alicecoin,symbol,sizeof(rswap->alicecoin)); if ( rswap->finishedflag == 0 ) { - if ( (sentobj= LP_gettx(symbol,txid)) == 0 ) + if ( (sentobj= LP_gettx(symbol,txid,1)) == 0 ) { char str2[65]; printf("%s %s ready to broadcast\n",symbol,bits256_str(str2,txid)); } diff --git a/iguana/exchanges/LP_rpc.c b/iguana/exchanges/LP_rpc.c index cd5c89461..0f6d42d8a 100644 --- a/iguana/exchanges/LP_rpc.c +++ b/iguana/exchanges/LP_rpc.c @@ -410,7 +410,7 @@ cJSON *LP_paxprice(char *fiat) return(bitcoin_json(coin,"paxprice",buf)); } -cJSON *LP_gettx(char *symbol,bits256 txid) +cJSON *LP_gettx(char *symbol,bits256 txid,int32_t suppress_errors) { struct iguana_info *coin; char buf[512],str[65]; cJSON *retjson; //printf("LP_gettx %s %s\n",symbol,bits256_str(str,txid)); @@ -431,7 +431,8 @@ cJSON *LP_gettx(char *symbol,bits256 txid) { if ( (retjson= electrum_transaction(symbol,coin->electrum,&retjson,txid,0)) != 0 ) return(retjson); - else printf("failed blockchain.transaction.get %s %s\n",coin->symbol,bits256_str(str,txid)); + else if ( suppress_errors == 0 ) + printf("failed blockchain.transaction.get %s %s\n",coin->symbol,bits256_str(str,txid)); return(cJSON_Parse("{\"error\":\"no transaction bytes\"}")); } } @@ -439,7 +440,7 @@ cJSON *LP_gettx(char *symbol,bits256 txid) uint32_t LP_locktime(char *symbol,bits256 txid) { cJSON *txobj; uint32_t locktime = 0; - if ( (txobj= LP_gettx(symbol,txid)) != 0 ) + if ( (txobj= LP_gettx(symbol,txid,0)) != 0 ) { locktime = juint(txobj,"locktime"); free_json(txobj); @@ -1242,7 +1243,7 @@ const char *Notaries_elected[][2] = int32_t LP_txhasnotarization(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; - if ( (txobj= LP_gettx(coin->symbol,txid)) != 0 ) + if ( (txobj= LP_gettx(coin->symbol,txid,0)) != 0 ) { if ( (vins= jarray(&numvins,txobj,"vin")) != 0 ) { @@ -1254,7 +1255,7 @@ int32_t LP_txhasnotarization(struct iguana_info *coin,bits256 txid) vin = jitem(vins,i); spenttxid = jbits256(vin,"txid"); spentvout = jint(vin,"vout"); - if ( (spentobj= LP_gettx(coin->symbol,spenttxid)) != 0 ) + if ( (spentobj= LP_gettx(coin->symbol,spenttxid,0)) != 0 ) { if ( (vouts= jarray(&numvouts,spentobj,"vout")) != 0 ) { diff --git a/iguana/exchanges/LP_socket.c b/iguana/exchanges/LP_socket.c index 68d02b3bd..63f6af131 100644 --- a/iguana/exchanges/LP_socket.c +++ b/iguana/exchanges/LP_socket.c @@ -733,7 +733,7 @@ cJSON *_electrum_transaction(char *symbol,struct electrum_info *ep,cJSON **retjs free_json(hexjson); //printf("return from electrum_transaction\n"); return(*retjsonp); - } else printf("%s %s non-hex tx.(%s)\n",coin->symbol,bits256_str(str,txid),jprint(hexjson,0)); + } //else printf("%s %s non-hex tx.(%s)\n",coin->symbol,bits256_str(str,txid),jprint(hexjson,0)); free(hexstr); free_json(hexjson); } diff --git a/iguana/exchanges/LP_transaction.c b/iguana/exchanges/LP_transaction.c index 752964c5d..ac7b6a563 100644 --- a/iguana/exchanges/LP_transaction.c +++ b/iguana/exchanges/LP_transaction.c @@ -63,7 +63,7 @@ bits256 LP_pubkey(bits256 privkey) int32_t LP_gettx_presence(char *symbol,bits256 expectedtxid) { cJSON *txobj; bits256 txid; int32_t flag = 0; - if ( (txobj= LP_gettx(symbol,expectedtxid)) != 0 ) + if ( (txobj= LP_gettx(symbol,expectedtxid,0)) != 0 ) { txid = jbits256(txobj,"txid"); if ( jobj(txobj,"error") == 0 && bits256_cmp(txid,expectedtxid) == 0 ) @@ -772,7 +772,7 @@ char *basilisk_swap_bobtxspend(bits256 *signedtxidp,uint64_t txfee,char *name,ch if ( (coin= LP_coinfind(symbol)) != 0 ) { #ifndef BASILISK_DISABLESENDTX - if ( (txobj= LP_gettx(symbol,utxotxid)) != 0 ) + if ( (txobj= LP_gettx(symbol,utxotxid,0)) != 0 ) { if ( (vouts= jarray(&n,txobj,"vout")) != 0 && utxovout < n ) { @@ -1530,7 +1530,7 @@ int32_t LP_swap_getcoinaddr(char *symbol,char *coinaddr,bits256 txid,int32_t vou { cJSON *retjson; coinaddr[0] = 0; - if ( (retjson= LP_gettx(symbol,txid)) != 0 ) + if ( (retjson= LP_gettx(symbol,txid,0)) != 0 ) { LP_txdestaddr(coinaddr,txid,vout,retjson); free_json(retjson); @@ -1541,7 +1541,7 @@ int32_t LP_swap_getcoinaddr(char *symbol,char *coinaddr,bits256 txid,int32_t vou int32_t basilisk_swap_getsigscript(char *symbol,uint8_t *script,int32_t maxlen,bits256 txid,int32_t vini) { cJSON *retjson,*vins,*item,*skey; int32_t n,scriptlen = 0; char *hexstr; - if ( (retjson= LP_gettx(symbol,txid)) != 0 ) + if ( (retjson= LP_gettx(symbol,txid,0)) != 0 ) { if ( (vins= jarray(&n,retjson,"vin")) != 0 && vini < n ) { diff --git a/iguana/exchanges/LP_utxo.c b/iguana/exchanges/LP_utxo.c index a6af5330f..99b0df584 100644 --- a/iguana/exchanges/LP_utxo.c +++ b/iguana/exchanges/LP_utxo.c @@ -701,7 +701,7 @@ cJSON *LP_transactioninit(struct iguana_info *coin,bits256 txid,int32_t iter,cJS struct LP_transaction *tx; int32_t i,height,numvouts,numvins,spentvout; cJSON *vins,*vouts,*vout,*vin; bits256 spenttxid; char str[65]; if ( coin->inactive != 0 ) return(0); - if ( txobj != 0 || (txobj= LP_gettx(coin->symbol,txid)) != 0 ) + if ( txobj != 0 || (txobj= LP_gettx(coin->symbol,txid,0)) != 0 ) { if ( coin->electrum == 0 ) height = LP_txheight(coin,txid); @@ -763,7 +763,7 @@ int32_t LP_txheight(struct iguana_info *coin,bits256 txid) return(-1); if ( coin->electrum == 0 ) { - if ( (txobj= LP_gettx(coin->symbol,txid)) != 0 ) + if ( (txobj= LP_gettx(coin->symbol,txid,0)) != 0 ) { //*timestampp = juint(txobj,"locktime"); //*blocktimep = juint(txobj,"blocktime"); @@ -803,7 +803,7 @@ int32_t LP_numconfirms(char *symbol,char *coinaddr,bits256 txid,int32_t vout,int } else if ( mempool != 0 && LP_mempoolscan(symbol,txid) >= 0 ) numconfirms = 0; - else if ( (txobj= LP_gettx(symbol,txid)) != 0 ) + else if ( (txobj= LP_gettx(symbol,txid,0)) != 0 ) { numconfirms = jint(txobj,"confirmations"); free_json(txobj); diff --git a/iguana/exchanges/LP_zeroconf.c b/iguana/exchanges/LP_zeroconf.c index c9b07fb9d..248ac6074 100644 --- a/iguana/exchanges/LP_zeroconf.c +++ b/iguana/exchanges/LP_zeroconf.c @@ -227,7 +227,7 @@ void LP_zeroconf_deposits(struct iguana_info *coin) item = jitem(array,i); LP_listunspent_parseitem(coin,&txid,&vout,&height,item); } else txid = jbits256i(array,i); - if ( (txjson= LP_gettx(coin->symbol,txid)) != 0 ) + if ( (txjson= LP_gettx(coin->symbol,txid,0)) != 0 ) { // vout0 deposit, vout1 botsfee, vout2 smartaddress if ( (vouts= jarray(&numvouts,txjson,"vout")) > 0 && numvouts >= 3 && LP_destaddr(destaddr,jitem(vouts,2)) == 0 ) From f7a58dde315982f226e7202b7ac8113c7d18f819 Mon Sep 17 00:00:00 2001 From: jl777 Date: Mon, 27 Nov 2017 00:08:01 +0400 Subject: [PATCH 1307/1664] Test --- iguana/exchanges/LP_commands.c | 4 ++-- iguana/exchanges/LP_include.h | 4 ++-- iguana/exchanges/LP_nativeDEX.c | 8 ++++++-- iguana/exchanges/LP_ordermatch.c | 13 ++++++++----- 4 files changed, 18 insertions(+), 11 deletions(-) diff --git a/iguana/exchanges/LP_commands.c b/iguana/exchanges/LP_commands.c index 392de5386..3345c0ca3 100644 --- a/iguana/exchanges/LP_commands.c +++ b/iguana/exchanges/LP_commands.c @@ -115,8 +115,8 @@ pricearray(base, rel, starttime=0, endtime=0, timescale=60) -> [timestamp, avebi getrawtransaction(coin, txid)\n\ inventory(coin, reset=0, [passphrase=])\n\ lastnonce()\n\ -buy(base, rel, price, relvolume, timeout=10, duration=3600, nonce, destpubkey="")\n\ -sell(base, rel, price, basevolume, timeout=10, duration=3600, nonce, destpubkey="")\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\ diff --git a/iguana/exchanges/LP_include.h b/iguana/exchanges/LP_include.h index fe002e281..7c7db22ed 100644 --- a/iguana/exchanges/LP_include.h +++ b/iguana/exchanges/LP_include.h @@ -405,7 +405,7 @@ struct LP_pubkey_info struct LP_pubkey_quote *quotes; struct LP_pubswap *bobswaps,*aliceswaps; uint64_t dynamictrust; - uint32_t timestamp,numerrors,lasttime; + uint32_t timestamp,numerrors,lasttime,slowresponse; int32_t istrusted; uint8_t rmd160[20],sig[65],pubsecp[33],siglen; }; @@ -430,7 +430,7 @@ struct LP_trade uint64_t aliceid; int64_t besttrust; double bestprice; - uint32_t negotiationdone,connectsent,firsttime,lasttime,firstprocessed,lastprocessed,newtime; + uint32_t negotiationdone,bestresponse,connectsent,firsttime,lasttime,firstprocessed,lastprocessed,newtime; char pairstr[64],funcid,iambob; struct LP_quoteinfo Qs[4],Q; }; diff --git a/iguana/exchanges/LP_nativeDEX.c b/iguana/exchanges/LP_nativeDEX.c index cedd630ab..274aae86f 100644 --- a/iguana/exchanges/LP_nativeDEX.c +++ b/iguana/exchanges/LP_nativeDEX.c @@ -17,19 +17,23 @@ // LP_nativeDEX.c // marketmaker // +// optimize electrum swap +// penalize unresponsive pubkeys more! // big BTC swaps -// delay swap credit back until notarization // electrum dynamic trust over 1000 tx // https://github.com/bitcoin/bips/blob/master/bip-0143.mediawiki for signing BCH/BTG // // cancel bid/ask +// portfolio: +// portfolio to set prices from historical // portfolio value based on ask? -// verify encrypted destpubkey, broadcast:0 setprice // USD paxprice based USDvalue in portfolio // improve critical section detection when parallel trades +// delay swap credit back until notarization // dPoW security -> 4: KMD notarized, 5: BTC notarized, after next notary elections // bigendian architectures need to use little endian for sighash calcs +// // dont change error messages: // if (enable_electrum_coin_output_data.error == 'couldnt find coin locally installed') { //{error: "couldnt find coin locally installed", coin: "BTC"} //if (enable_native_coin_output_data.error == 'couldnt find coin locally installed') { //{error: "couldnt find coin locally installed", coin: "BTC"} diff --git a/iguana/exchanges/LP_ordermatch.c b/iguana/exchanges/LP_ordermatch.c index 905065d05..819c207ac 100644 --- a/iguana/exchanges/LP_ordermatch.c +++ b/iguana/exchanges/LP_ordermatch.c @@ -1015,10 +1015,10 @@ struct LP_quoteinfo *LP_trades_gotconnected(void *ctx,struct LP_quoteinfo *qp,st int32_t LP_trades_bestpricecheck(void *ctx,struct LP_trade *tp) { - double qprice; struct LP_quoteinfo Q; int64_t dynamictrust; char *retstr; + double qprice; struct LP_quoteinfo Q; int64_t dynamictrust; char *retstr; struct LP_pubkey_info *pubp; Q = tp->Q; //printf("check bestprice %.8f vs new price %.8f\n",tp->bestprice,(double)Q.destsatoshis/Q.satoshis); - if ( Q.satoshis != 0 )//(qprice= LP_trades_alicevalidate(ctx,&Q)) > 0. ) + if ( Q.satoshis != 0 && (pubp= LP_pubkeyfind(Q.srchash)) != 0 )//(qprice= LP_trades_alicevalidate(ctx,&Q)) > 0. ) { qprice = (double)Q.destsatoshis / (Q.satoshis - Q.txfee); LP_aliceid(Q.tradeid,tp->aliceid,"reserved",0,0); @@ -1026,12 +1026,13 @@ int32_t LP_trades_bestpricecheck(void *ctx,struct LP_trade *tp) free(retstr); //LP_trades_gotreserved(ctx,&Q,&tp->Qs[LP_RESERVED]); dynamictrust = LP_dynamictrust(Q.srchash,LP_kmdvalue(Q.srccoin,Q.satoshis)); - if ( tp->bestprice == 0. || (qprice < tp->bestprice || (qprice < tp->bestprice*1.01 && dynamictrust > tp->besttrust)) ) + if ( tp->bestprice == 0. || (qprice < tp->bestprice && pubp->slowresponse <= tp->bestresponse*1.05) || (qprice < tp->bestprice*1.01 && dynamictrust > tp->besttrust && pubp->slowresponse <= tp->bestresponse*1.1) ) { tp->Qs[LP_CONNECT] = tp->Q; tp->bestprice = qprice; tp->besttrust = dynamictrust; - printf("aliceid.%llu got new bestprice %.8f dynamictrust %.8f\n",(long long)tp->aliceid,tp->bestprice,dstr(dynamictrust)); + tp->bestresponse = pubp->slowresponse; + printf("aliceid.%llu got new bestprice %.8f dynamictrust %.8f slowresponse.%d\n",(long long)tp->aliceid,tp->bestprice,dstr(dynamictrust),tp->bestresponse); return(qprice); } //else printf("qprice %.8f dynamictrust %.8f not good enough\n",qprice,dstr(dynamictrust)); } else printf("alice didnt validate\n"); @@ -1040,7 +1041,7 @@ int32_t LP_trades_bestpricecheck(void *ctx,struct LP_trade *tp) void LP_tradesloop(void *ctx) { - struct LP_trade *qtp,*tp,*tmp; struct LP_quoteinfo *qp,Q; uint32_t now; int32_t timeout,funcid,flag,nonz; struct iguana_info *coin; + struct LP_trade *qtp,*tp,*tmp; struct LP_quoteinfo *qp,Q; uint32_t now; int32_t timeout,funcid,flag,nonz; struct iguana_info *coin; struct LP_pubkey_info *pubp; strcpy(LP_tradesloop_stats.name,"LP_tradesloop"); LP_tradesloop_stats.threshold = 10000; sleep(5); @@ -1145,6 +1146,8 @@ void LP_tradesloop(void *ctx) LP_Alicemaxprice = tp->bestprice; LP_reserved(ctx,LP_myipaddr,LP_mypubsock,&tp->Qs[LP_CONNECT]); // send LP_CONNECT printf("repeat LP_connect aliceid.%llu %.8f\n",(long long)tp->aliceid,tp->bestprice); + if ( (pubp= LP_pubkeyfind(tp->Qs[LP_CONNECT].srchash)) != 0 ) + pubp->slowresponse++; } } } From 8943d707a450a6e8323adb8c4a3cb98ed9fc5b40 Mon Sep 17 00:00:00 2001 From: jl777 Date: Mon, 27 Nov 2017 00:26:24 +0400 Subject: [PATCH 1308/1664] Test --- iguana/exchanges/LP_signatures.c | 12 +++++++++--- 1 file changed, 9 insertions(+), 3 deletions(-) diff --git a/iguana/exchanges/LP_signatures.c b/iguana/exchanges/LP_signatures.c index f5293ff75..3393842c7 100644 --- a/iguana/exchanges/LP_signatures.c +++ b/iguana/exchanges/LP_signatures.c @@ -671,9 +671,15 @@ void LP_query(void *ctx,char *myipaddr,int32_t mypubsock,char *method,struct LP_ { memset(&zero,0,sizeof(zero)); LP_reserved_msg(1,qp->srccoin,qp->destcoin,zero,clonestr(msg)); - sleep(1); - LP_reserved_msg(1,qp->srccoin,qp->destcoin,qp->desthash,clonestr(msg)); - LP_reserved_msg(0,qp->srccoin,qp->destcoin,zero,clonestr(msg)); + if ( strcmp(method,"request") == 0 ) + { + sleep(1); + LP_reserved_msg(1,qp->srccoin,qp->destcoin,qp->desthash,clonestr(msg)); + sleep(1); + LP_reserved_msg(0,qp->srccoin,qp->destcoin,zero,clonestr(msg)); + sleep(1); + LP_reserved_msg(0,qp->srccoin,qp->destcoin,qp->desthash,clonestr(msg)); + } free(msg); /*portable_mutex_lock(&LP_reservedmutex); if ( num_Reserved_msgs[1] < sizeof(Reserved_msgs[1])/sizeof(*Reserved_msgs[1])-2 ) From d848423b5e511b5c539410eb6a620e604593f6c6 Mon Sep 17 00:00:00 2001 From: jl777 Date: Mon, 27 Nov 2017 00:29:33 +0400 Subject: [PATCH 1309/1664] Test --- iguana/exchanges/LP_signatures.c | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/iguana/exchanges/LP_signatures.c b/iguana/exchanges/LP_signatures.c index 3393842c7..80b1fb651 100644 --- a/iguana/exchanges/LP_signatures.c +++ b/iguana/exchanges/LP_signatures.c @@ -674,11 +674,9 @@ void LP_query(void *ctx,char *myipaddr,int32_t mypubsock,char *method,struct LP_ if ( strcmp(method,"request") == 0 ) { sleep(1); - LP_reserved_msg(1,qp->srccoin,qp->destcoin,qp->desthash,clonestr(msg)); + LP_reserved_msg(1,qp->srccoin,qp->destcoin,zero,clonestr(msg)); sleep(1); - LP_reserved_msg(0,qp->srccoin,qp->destcoin,zero,clonestr(msg)); - sleep(1); - LP_reserved_msg(0,qp->srccoin,qp->destcoin,qp->desthash,clonestr(msg)); + LP_reserved_msg(1,qp->srccoin,qp->destcoin,zero,clonestr(msg)); } free(msg); /*portable_mutex_lock(&LP_reservedmutex); From 1d3cce7fa070e4a4fe0171c93e597266ee2cf1a7 Mon Sep 17 00:00:00 2001 From: jl777 Date: Mon, 27 Nov 2017 01:09:09 +0400 Subject: [PATCH 1310/1664] Test --- iguana/exchanges/LP_include.h | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/iguana/exchanges/LP_include.h b/iguana/exchanges/LP_include.h index 7c7db22ed..3dbe4f95f 100644 --- a/iguana/exchanges/LP_include.h +++ b/iguana/exchanges/LP_include.h @@ -23,7 +23,7 @@ #define LP_MAJOR_VERSION "0" #define LP_MINOR_VERSION "1" -#define LP_BUILD_NUMBER "15577" +#define LP_BUILD_NUMBER "16577" #define LP_BARTERDEX_VERSION 1 #define LP_MAGICBITS 1 @@ -54,8 +54,8 @@ void emscripten_usleep(int32_t x); // returns immediate, no sense for sleeping #define LP_MIN_PEERS 8 #define LP_MAX_PEERS 32 -#define LP_MAXDESIRED_UTXOS (IAMLP != 0 ? 128 : 64) -#define LP_MINDESIRED_UTXOS (IAMLP != 0 ? 32 : 16) +#define LP_MAXDESIRED_UTXOS (IAMLP != 0 ? 256 : 64) +#define LP_MINDESIRED_UTXOS (IAMLP != 0 ? 64 : 16) #define LP_DUSTCOMBINE_THRESHOLD 1000000 // RTmetrics From d7190cfb651d9bfeda896ee124f33ab3ad76aa89 Mon Sep 17 00:00:00 2001 From: jl777 Date: Mon, 27 Nov 2017 11:17:51 +0400 Subject: [PATCH 1311/1664] Set LP_price --- iguana/exchanges/LP_nativeDEX.c | 2 +- iguana/exchanges/LP_prices.c | 97 +++++++----------------------- iguana/exchanges/LP_statemachine.c | 69 +++++++++++++++++++++ 3 files changed, 91 insertions(+), 77 deletions(-) diff --git a/iguana/exchanges/LP_nativeDEX.c b/iguana/exchanges/LP_nativeDEX.c index 274aae86f..5040800f4 100644 --- a/iguana/exchanges/LP_nativeDEX.c +++ b/iguana/exchanges/LP_nativeDEX.c @@ -18,9 +18,9 @@ // marketmaker // // optimize electrum swap -// penalize unresponsive pubkeys more! // big BTC swaps // electrum dynamic trust over 1000 tx +// compress packets // https://github.com/bitcoin/bips/blob/master/bip-0143.mediawiki for signing BCH/BTG // // cancel bid/ask diff --git a/iguana/exchanges/LP_prices.c b/iguana/exchanges/LP_prices.c index facf672e6..a239e0c9f 100644 --- a/iguana/exchanges/LP_prices.c +++ b/iguana/exchanges/LP_prices.c @@ -401,76 +401,6 @@ char *LP_prices() return(jprint(array,1)); } -/*void LP_prices_parse(struct LP_peerinfo *peer,cJSON *obj) -{ - struct LP_pubkey_info *pubp; struct LP_priceinfo *basepp,*relpp; uint32_t timestamp; bits256 pubkey; cJSON *asks,*item; uint8_t rmd160[20]; int32_t i,n,relid,mismatch; char *base,*rel,*hexstr; double askprice; uint32_t now; - now = (uint32_t)time(NULL); - pubkey = jbits256(obj,"pubkey"); - if ( bits256_nonz(pubkey) != 0 && (pubp= LP_pubkeyadd(pubkey)) != 0 ) - { - if ( (hexstr= jstr(obj,"rmd160")) != 0 && strlen(hexstr) == 2*sizeof(rmd160) ) - decode_hex(rmd160,sizeof(rmd160),hexstr); - if ( memcmp(pubp->rmd160,rmd160,sizeof(rmd160)) != 0 ) - mismatch = 1; - else mismatch = 0; - if ( bits256_cmp(pubkey,G.LP_mypub25519) == 0 && mismatch == 0 ) - peer->needping = 0; - LP_pubkey_sigcheck(pubp,obj); - timestamp = juint(obj,"timestamp"); - if ( timestamp > now ) - timestamp = now; - if ( timestamp >= pubp->timestamp && (asks= jarray(&n,obj,"asks")) != 0 ) - { - for (i=0; i 0 ) - { - if ( (basepp= LP_priceinfoptr(&relid,base,rel)) != 0 ) - { - //char str[65]; printf("gotprice %s %s/%s (%d/%d) %.8f\n",bits256_str(str,pubkey),base,rel,basepp->ind,relid,askprice); - pubp->matrix[basepp->ind][relid] = askprice; - //pubp->timestamps[basepp->ind][relid] = timestamp; - if ( (relpp= LP_priceinfofind(rel)) != 0 ) - { - dxblend(&basepp->relvals[relpp->ind],askprice,0.9); - dxblend(&relpp->relvals[basepp->ind],1. / askprice,0.9); - } - } - } - } - } - } -} - -void LP_peer_pricesquery(struct LP_peerinfo *peer) -{ - char *retstr; cJSON *array; int32_t i,n; - if ( strcmp(peer->ipaddr,LP_myipaddr) == 0 ) - return; - peer->needping = (uint32_t)time(NULL); - if ( (retstr= issue_LP_getprices(peer->ipaddr,peer->port)) != 0 ) - { - if ( (array= cJSON_Parse(retstr)) != 0 ) - { - if ( is_cJSON_Array(array) && (n= cJSON_GetArraySize(array)) > 0 ) - { - for (i=0; ineedping != 0 ) - { - //printf("%s needs ping\n",peer->ipaddr); - } -}*/ - double LP_pricecache(struct LP_quoteinfo *qp,char *base,char *rel,bits256 txid,int32_t vout) { struct LP_cacheinfo *ptr; @@ -499,10 +429,10 @@ void LP_priceinfoupdate(char *base,char *rel,double price) { if ( (basepp= LP_priceinfofind(base)) != 0 && (relpp= LP_priceinfofind(rel)) != 0 ) { - //dxblend(&basepp->relvals[relpp->ind],price,0.9); - //dxblend(&relpp->relvals[basepp->ind],1. / price,0.9); - basepp->relvals[relpp->ind] = price; - relpp->relvals[basepp->ind] = 1. / price; + dxblend(&basepp->relvals[relpp->ind],price,0.9); + dxblend(&relpp->relvals[basepp->ind],1. / price,0.9); + //basepp->relvals[relpp->ind] = price; + //relpp->relvals[basepp->ind] = 1. / price; } } } @@ -917,6 +847,11 @@ char *LP_orderbook(char *base,char *rel,int32_t duration) } n++; } + if ( i == 0 ) + { + LP_priceinfoupdate(rel,base,1. / bids[i]->price); + printf("update %s/%s %.8f [%.8f]\n",rel,base,1./bids[i]->price,bids[i]->price); + } free(bids[i]); bids[i] = 0; } @@ -943,6 +878,11 @@ char *LP_orderbook(char *base,char *rel,int32_t duration) } n++; } + if ( i == 0 ) + { + LP_priceinfoupdate(base,rel,asks[i]->price); + printf("update %s/%s %.8f [%.8f]\n",base,rel,asks[i]->price,1./asks[i]->price); + } free(asks[i]); asks[i] = 0; } @@ -963,12 +903,12 @@ char *LP_orderbook(char *base,char *rel,int32_t duration) int64_t LP_KMDvalue(struct iguana_info *coin,int64_t balance) { - cJSON *bids,*asks,*orderbook,*item; double bid=0,ask=0,price = 0.; int32_t numasks,numbids; char *retstr; int64_t KMDvalue=0; + double price = 0.; int64_t KMDvalue=0; if ( balance != 0 ) { if ( strcmp(coin->symbol,"KMD") == 0 ) KMDvalue = balance; - else if ( (retstr= LP_orderbook(coin->symbol,"KMD",-1)) != 0 ) + /*else if ( (retstr= LP_orderbook(coin->symbol,"KMD",-1)) != 0 ) { if ( (orderbook= cJSON_Parse(retstr)) != 0 ) { @@ -991,6 +931,11 @@ int64_t LP_KMDvalue(struct iguana_info *coin,int64_t balance) free_json(orderbook); } free(retstr); + }*/ + else + { + price = LP_price(coin->symbol,"KMD"); + KMDvalue = price * balance; } } return(KMDvalue); diff --git a/iguana/exchanges/LP_statemachine.c b/iguana/exchanges/LP_statemachine.c index 6960f0f62..a1c61d32b 100644 --- a/iguana/exchanges/LP_statemachine.c +++ b/iguana/exchanges/LP_statemachine.c @@ -3176,6 +3176,75 @@ cJSON *LP_inventory(char *symbol) { pubp->dynamictrust = LP_dynamictrust(pubp->pubkey,0); }*/ +/*void LP_prices_parse(struct LP_peerinfo *peer,cJSON *obj) + { + struct LP_pubkey_info *pubp; struct LP_priceinfo *basepp,*relpp; uint32_t timestamp; bits256 pubkey; cJSON *asks,*item; uint8_t rmd160[20]; int32_t i,n,relid,mismatch; char *base,*rel,*hexstr; double askprice; uint32_t now; + now = (uint32_t)time(NULL); + pubkey = jbits256(obj,"pubkey"); + if ( bits256_nonz(pubkey) != 0 && (pubp= LP_pubkeyadd(pubkey)) != 0 ) + { + if ( (hexstr= jstr(obj,"rmd160")) != 0 && strlen(hexstr) == 2*sizeof(rmd160) ) + decode_hex(rmd160,sizeof(rmd160),hexstr); + if ( memcmp(pubp->rmd160,rmd160,sizeof(rmd160)) != 0 ) + mismatch = 1; + else mismatch = 0; + if ( bits256_cmp(pubkey,G.LP_mypub25519) == 0 && mismatch == 0 ) + peer->needping = 0; + LP_pubkey_sigcheck(pubp,obj); + timestamp = juint(obj,"timestamp"); + if ( timestamp > now ) + timestamp = now; + if ( timestamp >= pubp->timestamp && (asks= jarray(&n,obj,"asks")) != 0 ) + { + for (i=0; i 0 ) + { + if ( (basepp= LP_priceinfoptr(&relid,base,rel)) != 0 ) + { + //char str[65]; printf("gotprice %s %s/%s (%d/%d) %.8f\n",bits256_str(str,pubkey),base,rel,basepp->ind,relid,askprice); + pubp->matrix[basepp->ind][relid] = askprice; + //pubp->timestamps[basepp->ind][relid] = timestamp; + if ( (relpp= LP_priceinfofind(rel)) != 0 ) + { + dxblend(&basepp->relvals[relpp->ind],askprice,0.9); + dxblend(&relpp->relvals[basepp->ind],1. / askprice,0.9); + } + } + } + } + } + } + } + + void LP_peer_pricesquery(struct LP_peerinfo *peer) + { + char *retstr; cJSON *array; int32_t i,n; + if ( strcmp(peer->ipaddr,LP_myipaddr) == 0 ) + return; + peer->needping = (uint32_t)time(NULL); + if ( (retstr= issue_LP_getprices(peer->ipaddr,peer->port)) != 0 ) + { + if ( (array= cJSON_Parse(retstr)) != 0 ) + { + if ( is_cJSON_Array(array) && (n= cJSON_GetArraySize(array)) > 0 ) + { + for (i=0; ineedping != 0 ) + { + //printf("%s needs ping\n",peer->ipaddr); + } + }*/ if ( aliceutxo->S.swap == 0 ) LP_availableset(aliceutxo); From 1d27e0cdc2ff310d301921d589628671cd7cbd8b Mon Sep 17 00:00:00 2001 From: jl777 Date: Mon, 27 Nov 2017 11:24:07 +0400 Subject: [PATCH 1312/1664] Test --- iguana/exchanges/LP_commands.c | 15 ++++++++++++++- 1 file changed, 14 insertions(+), 1 deletion(-) diff --git a/iguana/exchanges/LP_commands.c b/iguana/exchanges/LP_commands.c index 3345c0ca3..c01b1f70f 100644 --- a/iguana/exchanges/LP_commands.c +++ b/iguana/exchanges/LP_commands.c @@ -135,7 +135,8 @@ setconfirms(coin, numconfirms, maxconfirms=6)\n\ trust(pubkey, trust) # positive to trust, 0 for normal, negative to blacklist\n\ balance(coin, address)\n\ orderbook(base, rel, duration=3600)\n\ -getprices(base, rel)\n\ +getprices()\n\ +getprice(base, rel)\n\ //sendmessage(base=coin, rel="", pubkey=zero, )\n\ //getmessages(firsti=0, num=100)\n\ //deletemessages(firsti=0, num=100)\n\ @@ -320,6 +321,18 @@ zeroconf_claim(address, expiration=0)\n\ return(clonestr("{\"error\":\"couldnt set autoprice\"}")); else return(clonestr("{\"result\":\"success\"}")); } + else if ( strcmp(method,"getprice") == 0 ) + { + double price; + price = LP_price(base,rel); + retjson = cJSON_CreateObject(); + jaddstr(retjson,"result","success"); + jaddstr(retjson,"base",base); + jaddstr(retjson,"rel",rel); + jaddnum(retjson,"timestamp",time(NULL)); + jaddnum(retjson,"price",price); + return(jprint(retjson,1)); + } else if ( strcmp(method,"pricearray") == 0 ) { uint32_t firsttime; From b813141109e0bd4c74893eaaa1ab2a0bbfd24b41 Mon Sep 17 00:00:00 2001 From: jl777 Date: Tue, 28 Nov 2017 09:56:39 +0400 Subject: [PATCH 1313/1664] Test --- iguana/exchanges/LP_nativeDEX.c | 5 +++-- iguana/exchanges/LP_prices.c | 4 ++-- iguana/exchanges/LP_socket.c | 9 +++++---- 3 files changed, 10 insertions(+), 8 deletions(-) diff --git a/iguana/exchanges/LP_nativeDEX.c b/iguana/exchanges/LP_nativeDEX.c index 5040800f4..e0e1a0719 100644 --- a/iguana/exchanges/LP_nativeDEX.c +++ b/iguana/exchanges/LP_nativeDEX.c @@ -20,7 +20,6 @@ // optimize electrum swap // big BTC swaps // electrum dynamic trust over 1000 tx -// compress packets // https://github.com/bitcoin/bips/blob/master/bip-0143.mediawiki for signing BCH/BTG // // cancel bid/ask @@ -28,7 +27,9 @@ // portfolio to set prices from historical // portfolio value based on ask? // USD paxprice based USDvalue in portfolio - +// +// compress packets +// // improve critical section detection when parallel trades // delay swap credit back until notarization // dPoW security -> 4: KMD notarized, 5: BTC notarized, after next notary elections diff --git a/iguana/exchanges/LP_prices.c b/iguana/exchanges/LP_prices.c index a239e0c9f..4bd2432e7 100644 --- a/iguana/exchanges/LP_prices.c +++ b/iguana/exchanges/LP_prices.c @@ -850,7 +850,7 @@ char *LP_orderbook(char *base,char *rel,int32_t duration) if ( i == 0 ) { LP_priceinfoupdate(rel,base,1. / bids[i]->price); - printf("update %s/%s %.8f [%.8f]\n",rel,base,1./bids[i]->price,bids[i]->price); + //printf("update %s/%s %.8f [%.8f]\n",rel,base,1./bids[i]->price,bids[i]->price); } free(bids[i]); bids[i] = 0; @@ -881,7 +881,7 @@ char *LP_orderbook(char *base,char *rel,int32_t duration) if ( i == 0 ) { LP_priceinfoupdate(base,rel,asks[i]->price); - printf("update %s/%s %.8f [%.8f]\n",base,rel,asks[i]->price,1./asks[i]->price); + //printf("update %s/%s %.8f [%.8f]\n",base,rel,asks[i]->price,1./asks[i]->price); } free(asks[i]); asks[i] = 0; diff --git a/iguana/exchanges/LP_socket.c b/iguana/exchanges/LP_socket.c index 63f6af131..1f7e73e14 100644 --- a/iguana/exchanges/LP_socket.c +++ b/iguana/exchanges/LP_socket.c @@ -419,7 +419,7 @@ cJSON *electrum_submit(char *symbol,struct electrum_info *ep,cJSON **retjsonp,ch { *retjsonp = 0; sprintf(stratumreq,"{ \"jsonrpc\":\"2.0\", \"id\": %u, \"method\":\"%s\", \"params\": %s }\n",ep->stratumid,method,params); -//printf("%s %s",symbol,stratumreq); +printf("%s %s",symbol,stratumreq); memset(ep->buf,0,ep->bufsize); sitem = electrum_sitem(ep,stratumreq,timeout,retjsonp); portable_mutex_lock(&ep->mutex); // this helps performance! @@ -683,7 +683,7 @@ cJSON *LP_cache_transaction(struct iguana_info *coin,bits256 txid,uint8_t *seria cJSON *_electrum_transaction(char *symbol,struct electrum_info *ep,cJSON **retjsonp,bits256 txid) { char *hexstr,str[65]; int32_t len; cJSON *hexjson,*txobj=0; struct iguana_info *coin; uint8_t *serialized; struct LP_transaction *tx; - //printf("electrum_transaction %s %s\n",symbol,bits256_str(str,txid)); +printf("_electrum_transaction %s %s\n",symbol,bits256_str(str,txid)); if ( bits256_nonz(txid) != 0 && (coin= LP_coinfind(symbol)) != 0 ) { if ( (tx= LP_transactionfind(coin,txid)) != 0 && tx->serialized != 0 ) @@ -731,7 +731,7 @@ cJSON *_electrum_transaction(char *symbol,struct electrum_info *ep,cJSON **retjs //printf("DATA.(%s) from (%s)\n",hexstr+1,jprint(hexjson,0)); *retjsonp = LP_cache_transaction(coin,txid,serialized,len); // eats serialized free_json(hexjson); - //printf("return from electrum_transaction\n"); +printf("return from LP_cache_transaction\n"); return(*retjsonp); } //else printf("%s %s non-hex tx.(%s)\n",coin->symbol,bits256_str(str,txid),jprint(hexjson,0)); free(hexstr); @@ -744,6 +744,7 @@ cJSON *_electrum_transaction(char *symbol,struct electrum_info *ep,cJSON **retjs cJSON *electrum_transaction(char *symbol,struct electrum_info *ep,cJSON **retjsonp,bits256 txid,char *SPVcheck) { cJSON *retjson,*array; struct LP_transaction *tx; struct iguana_info *coin; + char str[65]; printf("electrum_transaction %s\n",bits256_str(str,txid)); coin = LP_coinfind(symbol); if ( ep != 0 ) portable_mutex_lock(&ep->txmutex); @@ -897,7 +898,7 @@ int32_t LP_recvfunc(struct electrum_info *ep,char *str,int32_t len) ep->lasttime = (uint32_t)time(NULL); if ( (strjson= cJSON_Parse(str)) != 0 ) { - //printf("%s RECV.(%ld) id.%d\n",ep->symbol,strlen(str),jint(strjson,"id")); +printf("%s RECV.(%ld) id.%d\n",ep->symbol,strlen(str),jint(strjson,"id")); resultjson = jobj(strjson,"result"); //printf("strjson.(%s)\n",jprint(strjson,0)); if ( (method= jstr(strjson,"method")) != 0 ) From 5dcc52ca008cc5fcc7f6b55d97150769cd57fc0e Mon Sep 17 00:00:00 2001 From: jl777 Date: Tue, 28 Nov 2017 10:08:48 +0400 Subject: [PATCH 1314/1664] Test --- iguana/exchanges/LP_socket.c | 7 +++---- iguana/exchanges/LP_zeroconf.c | 2 ++ 2 files changed, 5 insertions(+), 4 deletions(-) diff --git a/iguana/exchanges/LP_socket.c b/iguana/exchanges/LP_socket.c index 1f7e73e14..6ac754a50 100644 --- a/iguana/exchanges/LP_socket.c +++ b/iguana/exchanges/LP_socket.c @@ -683,7 +683,7 @@ cJSON *LP_cache_transaction(struct iguana_info *coin,bits256 txid,uint8_t *seria cJSON *_electrum_transaction(char *symbol,struct electrum_info *ep,cJSON **retjsonp,bits256 txid) { char *hexstr,str[65]; int32_t len; cJSON *hexjson,*txobj=0; struct iguana_info *coin; uint8_t *serialized; struct LP_transaction *tx; -printf("_electrum_transaction %s %s\n",symbol,bits256_str(str,txid)); + //printf("electrum_transaction %s %s\n",symbol,bits256_str(str,txid)); if ( bits256_nonz(txid) != 0 && (coin= LP_coinfind(symbol)) != 0 ) { if ( (tx= LP_transactionfind(coin,txid)) != 0 && tx->serialized != 0 ) @@ -731,7 +731,7 @@ printf("_electrum_transaction %s %s\n",symbol,bits256_str(str,txid)); //printf("DATA.(%s) from (%s)\n",hexstr+1,jprint(hexjson,0)); *retjsonp = LP_cache_transaction(coin,txid,serialized,len); // eats serialized free_json(hexjson); -printf("return from LP_cache_transaction\n"); + //printf("return from electrum_transaction\n"); return(*retjsonp); } //else printf("%s %s non-hex tx.(%s)\n",coin->symbol,bits256_str(str,txid),jprint(hexjson,0)); free(hexstr); @@ -744,7 +744,6 @@ printf("return from LP_cache_transaction\n"); cJSON *electrum_transaction(char *symbol,struct electrum_info *ep,cJSON **retjsonp,bits256 txid,char *SPVcheck) { cJSON *retjson,*array; struct LP_transaction *tx; struct iguana_info *coin; - char str[65]; printf("electrum_transaction %s\n",bits256_str(str,txid)); coin = LP_coinfind(symbol); if ( ep != 0 ) portable_mutex_lock(&ep->txmutex); @@ -898,7 +897,7 @@ int32_t LP_recvfunc(struct electrum_info *ep,char *str,int32_t len) ep->lasttime = (uint32_t)time(NULL); if ( (strjson= cJSON_Parse(str)) != 0 ) { -printf("%s RECV.(%ld) id.%d\n",ep->symbol,strlen(str),jint(strjson,"id")); + //printf("%s RECV.(%ld) id.%d\n",ep->symbol,strlen(str),jint(strjson,"id")); resultjson = jobj(strjson,"result"); //printf("strjson.(%s)\n",jprint(strjson,0)); if ( (method= jstr(strjson,"method")) != 0 ) diff --git a/iguana/exchanges/LP_zeroconf.c b/iguana/exchanges/LP_zeroconf.c index 248ac6074..8c7261b74 100644 --- a/iguana/exchanges/LP_zeroconf.c +++ b/iguana/exchanges/LP_zeroconf.c @@ -211,6 +211,8 @@ void LP_zeroconf_deposits(struct iguana_info *coin) { static int dispflag = 1; cJSON *array,*item,*txjson,*vouts,*v,*txobj; int32_t i,n,numvouts,height,vout,weeki; bits256 txid; char destaddr[64],p2shaddr[64]; struct LP_address *ap,*tmp; int64_t satoshis,amount64; + if ( coin->electrum != 0 && coin->electrumzeroconf == 0 ) + return; HASH_ITER(hh,coin->addresses,ap,tmp) { ap->zeroconf_credits = 0; From ea267466e9ca9554549feb6b2f067e94c6c45b95 Mon Sep 17 00:00:00 2001 From: jl777 Date: Tue, 28 Nov 2017 12:04:28 +0400 Subject: [PATCH 1315/1664] Test --- iguana/exchanges/LP_ordermatch.c | 52 ------------------------------ iguana/exchanges/LP_prices.c | 2 +- iguana/exchanges/LP_statemachine.c | 51 ++++++++++++++++++++++++++++- 3 files changed, 51 insertions(+), 54 deletions(-) diff --git a/iguana/exchanges/LP_ordermatch.c b/iguana/exchanges/LP_ordermatch.c index 819c207ac..5ccb2ee8e 100644 --- a/iguana/exchanges/LP_ordermatch.c +++ b/iguana/exchanges/LP_ordermatch.c @@ -683,58 +683,6 @@ char *LP_connectedalice(struct LP_quoteinfo *qp,char *pairstr) // alice } } -int32_t LP_listunspent_both(char *symbol,char *coinaddr,int32_t fullflag) -{ - int32_t i,v,numconfs,height,n=0; uint64_t value; bits256 txid; char buf[512]; cJSON *array,*item; uint32_t now; struct iguana_info *coin = LP_coinfind(symbol); - if ( coin != 0 )//&& (IAMLP != 0 || coin->inactive == 0) ) - { - if ( coin->electrum != 0 || LP_address_ismine(symbol,coinaddr) <= 0 ) - { - //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,fullflag); - } - else - { - if ( strcmp(symbol,"BTC") == 0 ) - numconfs = 0; - else numconfs = 1; - //printf("my coin electrum.%p\n",coin->electrum); - sprintf(buf,"[%d, 99999999, [\"%s\"]]",numconfs,coinaddr); - if ( (array= bitcoin_json(coin,"listunspent",buf)) != 0 ) - { - if ( (n= cJSON_GetArraySize(array)) > 0 ) - { - now = (uint32_t)time(NULL); - for (i=0; iinactive:-1); - 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 close enough in size\"}")); - return(jprint(LP_utxojson(autxo),1)); -}*/ - int32_t LP_aliceonly(char *symbol) { if ( strcmp(symbol,"GAME") == 0 ) diff --git a/iguana/exchanges/LP_prices.c b/iguana/exchanges/LP_prices.c index 4bd2432e7..d3d79d76b 100644 --- a/iguana/exchanges/LP_prices.c +++ b/iguana/exchanges/LP_prices.c @@ -338,7 +338,7 @@ char *LP_pubkey_trusted() int64_t LP_unspents_metric(struct iguana_info *coin,char *coinaddr) { cJSON *array,*item; int32_t i,n; int64_t metric=0,total; - LP_listunspent_both(coin->symbol,coinaddr,0); + //LP_listunspent_both(coin->symbol,coinaddr,0); if ( (array= LP_address_utxos(coin,coinaddr,1)) != 0 ) { total = 0; diff --git a/iguana/exchanges/LP_statemachine.c b/iguana/exchanges/LP_statemachine.c index a1c61d32b..21b8eeaf7 100644 --- a/iguana/exchanges/LP_statemachine.c +++ b/iguana/exchanges/LP_statemachine.c @@ -479,7 +479,56 @@ void issue_LP_listunspent(char *destip,uint16_t destport,char *symbol,char *coin return(retstr);*/ } - +int32_t LP_listunspent_both(char *symbol,char *coinaddr,int32_t fullflag) +{ + int32_t i,v,numconfs,height,n=0; uint64_t value; bits256 txid; char buf[512]; cJSON *array,*item; uint32_t now; struct iguana_info *coin = LP_coinfind(symbol); + if ( coin != 0 )//&& (IAMLP != 0 || coin->inactive == 0) ) + { + if ( coin->electrum != 0 || LP_address_ismine(symbol,coinaddr) <= 0 ) + { + //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,fullflag); + } + else + { + if ( strcmp(symbol,"BTC") == 0 ) + numconfs = 0; + else numconfs = 1; + //printf("my coin electrum.%p\n",coin->electrum); + sprintf(buf,"[%d, 99999999, [\"%s\"]]",numconfs,coinaddr); + if ( (array= bitcoin_json(coin,"listunspent",buf)) != 0 ) + { + if ( (n= cJSON_GetArraySize(array)) > 0 ) + { + now = (uint32_t)time(NULL); + for (i=0; iinactive:-1); + 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 close enough in size\"}")); + return(jprint(LP_utxojson(autxo),1)); +} int32_t LP_utxos_sync(struct LP_peerinfo *peer) { int32_t i,j,n=0,m,v,posted=0; bits256 txid; cJSON *array,*item,*item2,*array2; uint64_t total,total2; struct iguana_info *coin,*ctmp; char *retstr,*retstr2; From 825b06d3d30fd6144b039d91ae4a712cb9761f6b Mon Sep 17 00:00:00 2001 From: jl777 Date: Tue, 28 Nov 2017 12:35:42 +0400 Subject: [PATCH 1316/1664] Test --- iguana/exchanges/LP_cache.c | 11 +++++---- iguana/exchanges/LP_commands.c | 5 ++-- iguana/exchanges/LP_include.h | 4 ++-- iguana/exchanges/LP_nativeDEX.c | 6 ++--- iguana/exchanges/LP_portfolio.c | 5 ++-- iguana/exchanges/LP_prices.c | 8 +++---- iguana/exchanges/LP_privkey.c | 10 ++++---- iguana/exchanges/LP_remember.c | 2 +- iguana/exchanges/LP_rpc.c | 26 +++++++++++---------- iguana/exchanges/LP_scan.c | 16 +++++++------ iguana/exchanges/LP_socket.c | 41 ++++++++++++++++++--------------- iguana/exchanges/LP_tradebots.c | 5 ++-- iguana/exchanges/LP_utxo.c | 24 ++++++++++--------- iguana/exchanges/LP_zeroconf.c | 5 ++-- 14 files changed, 93 insertions(+), 75 deletions(-) diff --git a/iguana/exchanges/LP_cache.c b/iguana/exchanges/LP_cache.c index 226df276f..c27fb2ecd 100644 --- a/iguana/exchanges/LP_cache.c +++ b/iguana/exchanges/LP_cache.c @@ -45,8 +45,8 @@ struct LP_transaction *LP_create_transaction(struct iguana_info *coin,bits256 tx vins = jarray(&numvins,txobj,"vin"); vouts = jarray(&numvouts,txobj,"vout"); tx = LP_transactionadd(coin,txid,height,numvouts,numvins); - tx->serialized = serialized, tx->len = 0; - //free(serialized), tx->len = 0; + tx->serialized = serialized, tx->len = len; + // free(serialized), tx->len = 0; tx->fpos = fpos; tx->SPV = tx->height = height; //printf("tx.%s numvins.%d numvouts.%d\n",bits256_str(str,txid),numvins,numvouts); @@ -261,7 +261,7 @@ int32_t LP_merkleproof(struct iguana_info *coin,char *coinaddr,struct electrum_i if ( tx != 0 ) { tx->SPV = height; - if ( 0 && tx->serialized != 0 ) + if ( strcmp(coinaddr,coin->smartaddr) != 0 && tx->serialized != 0 ) { free(tx->serialized); tx->serialized = 0; @@ -313,7 +313,7 @@ void LP_unspents_cache(char *symbol,char *addr,char *arraystr,int32_t updatedfla uint64_t LP_unspents_load(char *symbol,char *addr) { - char *arraystr; uint64_t balance = 0; int32_t i,n; cJSON *retjson,*item; struct iguana_info *coin; + char *arraystr; uint64_t balance = 0; int32_t i,n; bits256 zero; cJSON *retjson,*item; struct iguana_info *coin; if ( (coin= LP_coinfind(symbol)) != 0 ) { if ( (arraystr= LP_unspents_filestr(symbol,addr)) != 0 ) @@ -329,7 +329,8 @@ uint64_t LP_unspents_load(char *symbol,char *addr) balance += j64bits(item,"value"); } } - electrum_process_array(coin,coin->electrum,addr,retjson,1); + memset(zero.bytes,0,sizeof(zero)); + electrum_process_array(coin,coin->electrum,addr,retjson,1,zero,zero); free_json(retjson); } free(arraystr); diff --git a/iguana/exchanges/LP_commands.c b/iguana/exchanges/LP_commands.c index c01b1f70f..1b483d0b7 100644 --- a/iguana/exchanges/LP_commands.c +++ b/iguana/exchanges/LP_commands.c @@ -450,7 +450,8 @@ zeroconf_claim(address, expiration=0)\n\ { if ( (ptr= LP_coinsearch(coin)) != 0 ) { - char *coinaddr; + char *coinaddr; bits256 zero; + memset(zero.bytes,0,sizeof(zero)); if ( (coinaddr= jstr(argjson,"address")) != 0 ) { if ( coinaddr[0] != 0 ) @@ -461,7 +462,7 @@ zeroconf_claim(address, expiration=0)\n\ //LP_listunspent_issue(coin,coinaddr,2); //LP_privkey_init(-1,ptr,G.LP_privkey,G.LP_mypub25519); } - return(jprint(LP_listunspent(coin,coinaddr),1)); + return(jprint(LP_listunspent(coin,coinaddr,zero,zero),1)); } } return(clonestr("{\"error\":\"no address specified\"}")); diff --git a/iguana/exchanges/LP_include.h b/iguana/exchanges/LP_include.h index 3dbe4f95f..3b07aa056 100644 --- a/iguana/exchanges/LP_include.h +++ b/iguana/exchanges/LP_include.h @@ -475,7 +475,7 @@ 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); +cJSON *electrum_address_gethistory(char *symbol,struct electrum_info *ep,cJSON **retjsonp,char *addr,bits256 reftxid); 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); @@ -514,7 +514,7 @@ char *issue_LP_psock(char *destip,uint16_t destport,int32_t ispaired); char *LP_unspents_filestr(char *symbol,char *addr); cJSON *bitcoin_data2json(char *symbol,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 zcash); //int32_t LP_butxo_findeither(bits256 txid,int32_t vout); -cJSON *LP_listunspent(char *symbol,char *coinaddr); +cJSON *LP_listunspent(char *symbol,char *coinaddr,bits256 reftxid,bits256 reftxid2); int32_t LP_gettx_presence(char *symbol,bits256 expectedtxid); double LP_getestimatedrate(struct iguana_info *coin); struct LP_utxoinfo *_LP_utxofind(int32_t iambob,bits256 txid,int32_t vout); diff --git a/iguana/exchanges/LP_nativeDEX.c b/iguana/exchanges/LP_nativeDEX.c index e0e1a0719..bd3ea3fde 100644 --- a/iguana/exchanges/LP_nativeDEX.c +++ b/iguana/exchanges/LP_nativeDEX.c @@ -546,13 +546,13 @@ void LP_coinsloop(void *_coins) } if ( (backupep= ep->prev) == 0 ) backupep = ep; - if ( (retjson= electrum_address_listunspent(coin->symbol,ep,&retjson,coin->smartaddr,1)) != 0 ) + if ( (retjson= electrum_address_listunspent(coin->symbol,ep,&retjson,coin->smartaddr,1,zero,zero)) != 0 ) free_json(retjson); HASH_ITER(hh,coin->addresses,ap,atmp) { break; //printf("call unspent %s\n",ap->coinaddr); - if ( strcmp(coin->smartaddr,ap->coinaddr) != 0 && (retjson= electrum_address_listunspent(coin->symbol,ep,&retjson,ap->coinaddr,1)) != 0 ) + if ( strcmp(coin->smartaddr,ap->coinaddr) != 0 && (retjson= electrum_address_listunspent(coin->symbol,ep,&retjson,ap->coinaddr,1,zero,zero)) != 0 ) free_json(retjson); } if ( (ap= LP_addressfind(coin,coin->smartaddr)) != 0 ) @@ -594,7 +594,7 @@ void LP_coinsloop(void *_coins) if ( time(NULL) > ep->keepalive+LP_ELECTRUM_KEEPALIVE ) { //printf("%s electrum.%p needs a keepalive: lag.%d\n",ep->symbol,ep,(int32_t)(time(NULL) - ep->keepalive)); - if ( (retjson= electrum_address_listunspent(coin->symbol,ep,&retjson,coin->smartaddr,1)) != 0 ) + if ( (retjson= electrum_banner(coin->symbol,ep,&retjson)) != 0 ) free_json(retjson); } ep = ep->prev; diff --git a/iguana/exchanges/LP_portfolio.c b/iguana/exchanges/LP_portfolio.c index fea00ca21..cf11dbe17 100644 --- a/iguana/exchanges/LP_portfolio.c +++ b/iguana/exchanges/LP_portfolio.c @@ -48,9 +48,10 @@ cJSON *LP_portfolio_entry(struct iguana_info *coin) uint64_t LP_balance(uint64_t *valuep,int32_t iambob,char *symbol,char *coinaddr) { - cJSON *array,*item; int32_t i,n; uint64_t valuesum,satoshisum,value; + cJSON *array,*item; bits256 zero; int32_t i,n; uint64_t valuesum,satoshisum,value; valuesum = satoshisum = 0; - if ( (array= LP_listunspent(symbol,coinaddr)) != 0 ) + memset(zero.bytes,0,sizeof(zero)); + if ( (array= LP_listunspent(symbol,coinaddr,zero,zero)) != 0 ) { if ( is_cJSON_Array(array) != 0 && (n= cJSON_GetArraySize(array)) > 0 ) { diff --git a/iguana/exchanges/LP_prices.c b/iguana/exchanges/LP_prices.c index d3d79d76b..b1f236fc3 100644 --- a/iguana/exchanges/LP_prices.c +++ b/iguana/exchanges/LP_prices.c @@ -838,13 +838,13 @@ char *LP_orderbook(char *base,char *rel,int32_t duration) { //printf("bid ping %s %s\n",rel,bids[i]->coinaddr); LP_address(relcoin,bids[i]->coinaddr); - if ( 0 && relcoin->electrum == 0 ) + /*if ( 0 && relcoin->electrum == 0 ) { LP_listunspent_issue(rel,bids[i]->coinaddr,0); //else if ( (tmpjson= LP_listunspent(rel,bids[i]->coinaddr)) != 0 ) // free_json(tmpjson); LP_listunspent_query(rel,bids[i]->coinaddr); - } + }*/ n++; } if ( i == 0 ) @@ -869,13 +869,13 @@ char *LP_orderbook(char *base,char *rel,int32_t duration) { //printf("ask ping %s %s\n",base,asks[i]->coinaddr); LP_address(basecoin,asks[i]->coinaddr); - if ( 0 && basecoin->electrum == 0 ) + /*if ( 0 && basecoin->electrum == 0 ) { LP_listunspent_issue(base,asks[i]->coinaddr,0); //else if ( (tmpjson= LP_listunspent(base,asks[i]->coinaddr)) != 0 ) // free_json(tmpjson); LP_listunspent_query(base,asks[i]->coinaddr); - } + }*/ n++; } if ( i == 0 ) diff --git a/iguana/exchanges/LP_privkey.c b/iguana/exchanges/LP_privkey.c index ea98b8079..3227c2331 100644 --- a/iguana/exchanges/LP_privkey.c +++ b/iguana/exchanges/LP_privkey.c @@ -21,7 +21,7 @@ int32_t LP_privkey_init(int32_t mypubsock,struct iguana_info *coin,bits256 myprivkey,bits256 mypub) { int32_t enable_utxos = 0; - char *script,destaddr[64]; cJSON *array,*item; bits256 txid,deposittxid; int32_t used,i,flag=0,height,n,cmpflag,iambob,vout,depositvout; uint64_t *values=0,satoshis,txfee,biggerval,value,total = 0; int64_t targetval; //struct LP_utxoinfo *utxo; + char *script,destaddr[64]; cJSON *array,*item; bits256 txid,deposittxid,zero; int32_t used,i,flag=0,height,n,cmpflag,iambob,vout,depositvout; uint64_t *values=0,satoshis,txfee,biggerval,value,total = 0; int64_t targetval; //struct LP_utxoinfo *utxo; if ( coin == 0 || (IAMLP == 0 && coin->inactive != 0) ) { //printf("coin not active\n"); @@ -33,7 +33,8 @@ int32_t LP_privkey_init(int32_t mypubsock,struct iguana_info *coin,bits256 mypri LP_address(coin,coin->smartaddr); //if ( coin->inactive == 0 ) // LP_listunspent_issue(coin->symbol,coin->smartaddr,0); - array = LP_listunspent(coin->symbol,coin->smartaddr); + memset(zero.bytes,0,sizeof(zero)); + array = LP_listunspent(coin->symbol,coin->smartaddr,zero,zero); if ( array != 0 ) { txfee = LP_txfeecalc(coin,0,0); @@ -204,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,userpass,checkkey; char tmpstr[128]; cJSON *retjson; uint8_t tmptype; + bits256 privkey,userpub,zero,userpass,checkkey; char tmpstr[128]; cJSON *retjson; uint8_t tmptype; if ( passphrase != 0 && passphrase[0] != 0 ) { conv_NXTpassword(privkey.bytes,pubkeyp->bytes,(uint8_t *)passphrase,(int32_t)strlen(passphrase)); @@ -252,7 +253,8 @@ bits256 LP_privkeycalc(void *ctx,uint8_t *pubkey33,bits256 *pubkeyp,struct iguan } if ( coin->importedprivkey == 0 && coin->electrum == 0 && coin->userpass[0] != 0 && LP_getheight(coin) > 0 ) { - LP_listunspent_issue(coin->symbol,coin->smartaddr,0); + memset(zero.bytes,0,sizeof(zero)); + LP_listunspent_issue(coin->symbol,coin->smartaddr,0,zero,zero); if ( (retjson= LP_importprivkey(coin->symbol,tmpstr,coin->smartaddr,-1)) != 0 ) { if ( jobj(retjson,"error") != 0 ) diff --git a/iguana/exchanges/LP_remember.c b/iguana/exchanges/LP_remember.c index 71f7b6ab8..0b8264214 100644 --- a/iguana/exchanges/LP_remember.c +++ b/iguana/exchanges/LP_remember.c @@ -259,7 +259,7 @@ bits256 basilisk_swap_spendupdate(int32_t iambob,char *symbol,char *spentaddr,in if ( (coin= LP_coinfind(symbol)) != 0 && coin->electrum != 0 ) { //printf("spentaddr.%s aliceaddr.%s bobaddr.%s Adest.%s Bdest.%s\n",spentaddr,aliceaddr,bobaddr,Adest,dest); - if ( (array= electrum_address_gethistory(symbol,coin->electrum,&array,spentaddr)) != 0 ) + if ( (array= electrum_address_gethistory(symbol,coin->electrum,&array,spentaddr,txids[utxoind])) != 0 ) { if ( (n= cJSON_GetArraySize(array)) > 0 ) { diff --git a/iguana/exchanges/LP_rpc.c b/iguana/exchanges/LP_rpc.c index 0f6d42d8a..31b168548 100644 --- a/iguana/exchanges/LP_rpc.c +++ b/iguana/exchanges/LP_rpc.c @@ -388,7 +388,7 @@ uint64_t LP_RTsmartbalance(struct iguana_info *coin) return(valuesum); } -cJSON *LP_getmempool(char *symbol,char *coinaddr) +cJSON *LP_getmempool(char *symbol,char *coinaddr,bits256 txid,bits256 txid2) { cJSON *array; struct iguana_info *coin; if ( symbol == 0 || symbol[0] == 0 ) @@ -398,7 +398,7 @@ cJSON *LP_getmempool(char *symbol,char *coinaddr) return(cJSON_Parse("{\"error\":\"no native coin\"}")); if ( coin->electrum == 0 ) return(bitcoin_json(coin,"getrawmempool","[]")); - else return(electrum_address_getmempool(symbol,coin->electrum,&array,coinaddr)); + else return(electrum_address_getmempool(symbol,coin->electrum,&array,coinaddr,txid,txid2)); } cJSON *LP_paxprice(char *fiat) @@ -486,7 +486,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; 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,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 ) @@ -523,7 +523,8 @@ 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,1)) != 0 ) + memset(zero.bytes,0,sizeof(zero)); + if ( (array= electrum_address_listunspent(coin->symbol,0,&array,coinaddr,1,txid,zero)) != 0 ) { //printf("array.(%s)\n",jprint(array,0)); if ( array != 0 && (n= cJSON_GetArraySize(array)) > 0 ) @@ -652,7 +653,7 @@ int32_t LP_address_isvalid(char *symbol,char *address) return(isvalid); } -cJSON *LP_listunspent(char *symbol,char *coinaddr) +cJSON *LP_listunspent(char *symbol,char *coinaddr,bits256 reftxid,bits256 reftxid2) { char buf[128],*retstr; struct LP_address *ap; cJSON *retjson; int32_t numconfs,usecache=1; struct iguana_info *coin; if ( symbol == 0 || symbol[0] == 0 ) @@ -690,17 +691,18 @@ cJSON *LP_listunspent(char *symbol,char *coinaddr) ap->unspenttime = (uint32_t)time(NULL); return(retjson); } else return(LP_address_utxos(coin,coinaddr,0)); - } else return(electrum_address_listunspent(symbol,coin->electrum,&retjson,coinaddr,1)); + } else return(electrum_address_listunspent(symbol,coin->electrum,&retjson,coinaddr,1,reftxid,reftxid2)); } cJSON *LP_listreceivedbyaddress(char *symbol,char *coinaddr) { - char buf[128],*addr; cJSON *retjson,*array,*item; int32_t i,n; struct iguana_info *coin; + char buf[128],*addr; bits256 zero; cJSON *retjson,*array,*item; int32_t i,n; struct iguana_info *coin; if ( symbol == 0 || symbol[0] == 0 ) return(cJSON_Parse("{\"error\":\"null symbol\"}")); coin = LP_coinfind(symbol); if ( coin == 0 || (IAMLP == 0 && coin->inactive != 0) ) return(cJSON_Parse("{\"error\":\"no coin\"}")); + memset(zero.bytes,0,sizeof(zero)); if ( coin->electrum == 0 ) { sprintf(buf,"[1, false, true]"); @@ -721,7 +723,7 @@ cJSON *LP_listreceivedbyaddress(char *symbol,char *coinaddr) } } return(cJSON_Parse("[]")); - } else return(electrum_address_gethistory(symbol,coin->electrum,&retjson,coinaddr)); + } else return(electrum_address_gethistory(symbol,coin->electrum,&retjson,coinaddr,zero)); } int64_t LP_listunspent_parseitem(struct iguana_info *coin,bits256 *txidp,int32_t *voutp,int32_t *heightp,cJSON *item) @@ -744,7 +746,7 @@ int64_t LP_listunspent_parseitem(struct iguana_info *coin,bits256 *txidp,int32_t return(satoshis); } -int32_t LP_listunspent_issue(char *symbol,char *coinaddr,int32_t fullflag) +int32_t LP_listunspent_issue(char *symbol,char *coinaddr,int32_t fullflag,bits256 reftxid,bits256 reftxid2) { struct iguana_info *coin; int32_t n = 0; cJSON *retjson=0; char *retstr=0; if ( symbol == 0 || symbol[0] == 0 ) @@ -753,7 +755,7 @@ int32_t LP_listunspent_issue(char *symbol,char *coinaddr,int32_t fullflag) { if ( coin->electrum != 0 ) { - if ( (retjson= electrum_address_listunspent(symbol,coin->electrum,&retjson,coinaddr,fullflag)) != 0 ) + if ( (retjson= electrum_address_listunspent(symbol,coin->electrum,&retjson,coinaddr,fullflag,reftxid,reftxid2)) != 0 ) { n = cJSON_GetArraySize(retjson); //printf("LP_listunspent_issue.%s %s.%d %s\n",symbol,coinaddr,n,jprint(retjson,0)); @@ -761,12 +763,12 @@ int32_t LP_listunspent_issue(char *symbol,char *coinaddr,int32_t fullflag) } else { - retjson = LP_listunspent(symbol,coinaddr); + retjson = LP_listunspent(symbol,coinaddr,reftxid,reftxid2); coin->numutxos = cJSON_GetArraySize(retjson); if ( retjson != 0 ) { n = cJSON_GetArraySize(retjson); - if ( electrum_process_array(coin,0,coinaddr,retjson,1) != 0 ) + if ( electrum_process_array(coin,0,coinaddr,retjson,1,reftxid,reftxid2) != 0 ) { //LP_postutxos(symbol,coinaddr); // might be good to not saturate } diff --git a/iguana/exchanges/LP_scan.c b/iguana/exchanges/LP_scan.c index f3b67476b..90e2f3899 100644 --- a/iguana/exchanges/LP_scan.c +++ b/iguana/exchanges/LP_scan.c @@ -413,10 +413,11 @@ int32_t LP_spendsearch(char *coinaddr,bits256 *spendtxidp,int32_t *indp,char *sy int32_t LP_mempoolscan(char *symbol,bits256 searchtxid) { - int32_t i,n; cJSON *array,*txobj; bits256 txid; struct iguana_info *coin; struct LP_transaction *tx; + int32_t i,n; cJSON *array,*txobj; bits256 txid,zero; struct iguana_info *coin; struct LP_transaction *tx; if ( (coin= LP_coinfind(symbol)) == 0 || coin->inactive != 0 || coin->electrum != 0 ) return(-1); - if ( (array= LP_getmempool(symbol,0)) != 0 ) + memset(zero.bytes,0,sizeof(zero)); + if ( (array= LP_getmempool(symbol,0,searchtxid,zero)) != 0 ) { if ( is_cJSON_Array(array) != 0 && (n= cJSON_GetArraySize(array)) > 0 ) { @@ -444,7 +445,7 @@ int32_t LP_mempoolscan(char *symbol,bits256 searchtxid) int32_t LP_waitmempool(char *symbol,char *coinaddr,bits256 txid,int32_t vout,int32_t duration) { - struct iguana_info *coin; cJSON *array,*item; uint32_t expiration,i,n; int32_t numconfirms = -1; + struct iguana_info *coin; bits256 zero; cJSON *array,*item; uint32_t expiration,i,n; int32_t numconfirms = -1; if ( (coin= LP_coinfind(symbol)) == 0 || coin->inactive != 0 ) { printf("LP_waitmempool missing coin.%p or inactive\n",coin); @@ -464,7 +465,8 @@ int32_t LP_waitmempool(char *symbol,char *coinaddr,bits256 txid,int32_t vout,int } else { - if ( (array= electrum_address_getmempool(symbol,coin->electrum,&array,coinaddr)) != 0 ) + memset(zero.bytes,0,sizeof(zero)); + if ( (array= electrum_address_getmempool(symbol,coin->electrum,&array,coinaddr,txid,zero)) != 0 ) { //char str[65]; printf("check %s mempool.(%s)\n",bits256_str(str,txid),jprint(array,0)); if ( (n= cJSON_GetArraySize(array)) > 0 ) @@ -482,12 +484,12 @@ int32_t LP_waitmempool(char *symbol,char *coinaddr,bits256 txid,int32_t vout,int } free(array); } - LP_listunspent_issue(coin->symbol,coinaddr,1); + LP_listunspent_issue(coin->symbol,coinaddr,1,txid,zero); struct LP_address_utxo *up; if ( (up= LP_address_utxofind(coin,coinaddr,txid,vout)) != 0 ) { char str[65]; printf("address_utxofind found confirmed %s %s %s ht.%d vs %d\n",symbol,coinaddr,bits256_str(str,txid),up->U.height,coin->height); - if ( coin->electrum != 0 && (array= electrum_address_gethistory(symbol,coin->electrum,&array,coinaddr)) != 0 ) + if ( coin->electrum != 0 && (array= electrum_address_gethistory(symbol,coin->electrum,&array,coinaddr,txid)) != 0 ) free_json(array); if ( coin->height >= up->U.height ) numconfirms = (coin->height - up->U.height + 1); @@ -512,7 +514,7 @@ int32_t LP_mempool_vinscan(bits256 *spendtxidp,int32_t *spendvinp,char *symbol,c return(-1); if ( time(NULL) > coin->lastmempool+LP_MEMPOOL_TIMEINCR ) { - if ( (array= LP_getmempool(symbol,coinaddr)) != 0 ) + if ( (array= LP_getmempool(symbol,coinaddr,searchtxid,searchtxid2)) != 0 ) { free_json(array); coin->lastmempool = (uint32_t)time(NULL); diff --git a/iguana/exchanges/LP_socket.c b/iguana/exchanges/LP_socket.c index 6ac754a50..37b3c4c0c 100644 --- a/iguana/exchanges/LP_socket.c +++ b/iguana/exchanges/LP_socket.c @@ -283,7 +283,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 electrumflag) +int32_t electrum_process_array(struct iguana_info *coin,struct electrum_info *ep,char *coinaddr,cJSON *array,int32_t electrumflag,bits256 reftxid,bits256 reftxid2) { 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 ) @@ -317,10 +317,13 @@ int32_t electrum_process_array(struct iguana_info *coin,struct electrum_info *ep continue; if ( (tx= LP_transactionfind(coin,txid)) == 0 ) { - txobj = LP_transactioninit(coin,txid,0,0); - LP_transactioninit(coin,txid,1,txobj); - free_json(txobj); - tx = LP_transactionfind(coin,txid); + if ( (bits256_nonz(reftxid) == 0 || bits256_cmp(reftxid,txid) == 0) && (bits256_nonz(reftxid2) == 0 || bits256_cmp(reftxid2,txid) == 0) ) + { + txobj = LP_transactioninit(coin,txid,0,0); + LP_transactioninit(coin,txid,1,txobj); + free_json(txobj); + tx = LP_transactionfind(coin,txid); + } } if ( tx != 0 ) { @@ -520,7 +523,7 @@ cJSON *electrum_address_subscribe(char *symbol,struct electrum_info *ep,cJSON ** return(retjson); } -cJSON *electrum_address_gethistory(char *symbol,struct electrum_info *ep,cJSON **retjsonp,char *addr) +cJSON *electrum_address_gethistory(char *symbol,struct electrum_info *ep,cJSON **retjsonp,char *addr,bits256 reftxid) { char str[65]; struct LP_transaction *tx; cJSON *retjson,*txobj,*item; int32_t i,n,height; bits256 txid; struct iguana_info *coin = LP_coinfind(symbol); retjson = electrum_strarg(symbol,ep,retjsonp,"blockchain.address.get_history",addr,ELECTRUM_TIMEOUT); @@ -532,7 +535,7 @@ cJSON *electrum_address_gethistory(char *symbol,struct electrum_info *ep,cJSON * item = jitem(retjson,i); txid = jbits256(item,"tx_hash"); height = jint(item,"height"); - if ( (tx= LP_transactionfind(coin,txid)) == 0 ) + if ( (tx= LP_transactionfind(coin,txid)) == 0 && (bits256_nonz(reftxid) == 0 || bits256_cmp(txid,reftxid) == 0) ) { //char str[65]; printf("history txinit %s ht.%d\n",bits256_str(str,txid),height); txobj = LP_transactioninit(coin,txid,0,0); @@ -560,22 +563,22 @@ int32_t LP_txheight_check(struct iguana_info *coin,char *coinaddr,struct LP_addr cJSON *retjson; if ( coin->electrum != 0 ) { - if ( (retjson= electrum_address_gethistory(coin->symbol,coin->electrum,&retjson,coinaddr)) != 0 ) + if ( (retjson= electrum_address_gethistory(coin->symbol,coin->electrum,&retjson,coinaddr,up->U.txid)) != 0 ) free_json(retjson); } return(0); } -cJSON *electrum_address_getmempool(char *symbol,struct electrum_info *ep,cJSON **retjsonp,char *addr) +cJSON *electrum_address_getmempool(char *symbol,struct electrum_info *ep,cJSON **retjsonp,char *addr,bits256 reftxid,bits256 reftxid2) { 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,1); + electrum_process_array(coin,ep,addr,retjson,1,reftxid,reftxid2); return(retjson); } -cJSON *electrum_address_listunspent(char *symbol,struct electrum_info *ep,cJSON **retjsonp,char *addr,int32_t electrumflag) +cJSON *electrum_address_listunspent(char *symbol,struct electrum_info *ep,cJSON **retjsonp,char *addr,int32_t electrumflag,bits256 txid,bits256 txid2) { cJSON *retjson=0; char *retstr; struct LP_address *ap; struct iguana_info *coin; int32_t updatedflag,height,usecache=1; if ( (coin= LP_coinfind(symbol)) == 0 ) @@ -603,7 +606,7 @@ cJSON *electrum_address_listunspent(char *symbol,struct electrum_info *ep,cJSON if ( 0 && electrumflag > 1 ) printf("%s.%d u.%u/%d t.%ld %s LISTUNSPENT.(%d)\n",coin->symbol,height,ap->unspenttime,ap->unspentheight,time(NULL),addr,(int32_t)strlen(jprint(retjson,0))); updatedflag = 0; - if ( electrum_process_array(coin,ep,addr,retjson,electrumflag) != 0 ) + if ( electrum_process_array(coin,ep,addr,retjson,electrumflag,txid,txid2) != 0 ) { //LP_postutxos(coin->symbol,addr); updatedflag = 1; @@ -743,7 +746,7 @@ cJSON *_electrum_transaction(char *symbol,struct electrum_info *ep,cJSON **retjs cJSON *electrum_transaction(char *symbol,struct electrum_info *ep,cJSON **retjsonp,bits256 txid,char *SPVcheck) { - cJSON *retjson,*array; struct LP_transaction *tx; struct iguana_info *coin; + cJSON *retjson,*array; bits256 zero; struct LP_transaction *tx; struct iguana_info *coin; coin = LP_coinfind(symbol); if ( ep != 0 ) portable_mutex_lock(&ep->txmutex); @@ -752,7 +755,8 @@ cJSON *electrum_transaction(char *symbol,struct electrum_info *ep,cJSON **retjso { if ( tx->height <= 0 ) { - if ( (array= electrum_address_listunspent(symbol,ep,&array,SPVcheck,2)) != 0 ) + memset(zero.bytes,0,sizeof(zero)); + if ( (array= electrum_address_listunspent(symbol,ep,&array,SPVcheck,2,txid,zero)) != 0 ) { printf("SPVcheck.%s got %d unspents\n",SPVcheck,cJSON_GetArraySize(array)); free_json(array); @@ -778,12 +782,13 @@ cJSON *electrum_getmerkle(char *symbol,struct electrum_info *ep,cJSON **retjsonp void electrum_test() { - cJSON *retjson; bits256 hash; struct electrum_info *ep = 0; char *addr,*script,*symbol = "BTC"; + cJSON *retjson; bits256 hash,zero; struct electrum_info *ep = 0; char *addr,*script,*symbol = "BTC"; while ( Num_electrums == 0 ) { sleep(1); printf("Num_electrums %p -> %d\n",&Num_electrums,Num_electrums); } + memset(zero.bytes,0,sizeof(zero)); printf("found electrum server\n"); if ( (retjson= electrum_version(symbol,ep,0)) != 0 ) printf("electrum_version %s\n",jprint(retjson,1)); @@ -806,13 +811,13 @@ void electrum_test() if ( (retjson= electrum_transaction(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)) != 0 ) + if ( (retjson= electrum_address_gethistory(symbol,ep,0,addr,zero)) != 0 ) printf("electrum_address_gethistory %s\n",jprint(retjson,1)); - if ( (retjson= electrum_address_getmempool(symbol,ep,0,addr)) != 0 ) + if ( (retjson= electrum_address_getmempool(symbol,ep,0,addr,zero,zero)) != 0 ) 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,1)) != 0 ) + if ( (retjson= electrum_address_listunspent(symbol,ep,0,addr,1,zero,zero)) != 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)); diff --git a/iguana/exchanges/LP_tradebots.c b/iguana/exchanges/LP_tradebots.c index 329bf4ac6..7f3742304 100644 --- a/iguana/exchanges/LP_tradebots.c +++ b/iguana/exchanges/LP_tradebots.c @@ -413,11 +413,12 @@ void LP_tradebot_finished(uint32_t tradeid,uint32_t requestid,uint32_t quoteid) void LP_tradebots_timeslice(void *ctx) { static uint32_t lastnumfinished = 0; - struct iguana_info *relcoin; struct LP_tradebot *bot,*tmp; + struct iguana_info *relcoin; bits256 zero; struct LP_tradebot *bot,*tmp; DL_FOREACH_SAFE(LP_tradebots,bot,tmp) { + memset(zero.bytes,0,sizeof(zero)); if ( (relcoin= LP_coinfind(bot->rel)) != 0 ) - LP_listunspent_issue(bot->rel,relcoin->smartaddr,1); + LP_listunspent_issue(bot->rel,relcoin->smartaddr,1,zero,zero); if ( bot->relsum >= 0.99*bot->totalrelvolume-SMALLVAL || bot->basesum >= 0.99*bot->totalbasevolume-SMALLVAL ) bot->dead = (uint32_t)time(NULL); else if ( (bot->pendrelsum+bot->relsum) >= 0.99*bot->totalrelvolume-SMALLVAL || (bot->basesum+bot->pendbasesum) >= 0.99*bot->totalbasevolume-SMALLVAL ) diff --git a/iguana/exchanges/LP_utxo.c b/iguana/exchanges/LP_utxo.c index 99b0df584..25f4301b9 100644 --- a/iguana/exchanges/LP_utxo.c +++ b/iguana/exchanges/LP_utxo.c @@ -262,9 +262,10 @@ struct LP_address *LP_address(struct iguana_info *coin,char *coinaddr) int32_t LP_address_minmax(uint64_t *balancep,uint64_t *minp,uint64_t *maxp,struct iguana_info *coin,char *coinaddr) { - cJSON *array,*item; bits256 txid; int64_t value; int32_t i,vout,height,n = 0; + cJSON *array,*item; bits256 txid,zero; int64_t value; int32_t i,vout,height,n = 0; *minp = *maxp = *balancep = 0; - if ( (array= LP_listunspent(coin->symbol,coinaddr)) != 0 ) + memset(zero.bytes,0,sizeof(zero)); + if ( (array= LP_listunspent(coin->symbol,coinaddr,zero,zero)) != 0 ) { //printf("address minmax.(%s)\n",jprint(array,0)); if ( (n= cJSON_GetArraySize(array)) > 0 ) @@ -290,8 +291,6 @@ int32_t LP_address_utxo_ptrs(struct iguana_info *coin,int32_t iambob,struct LP_a struct LP_address_utxo *up,*tmp; struct LP_transaction *tx; cJSON *txout; int32_t n = 0; if ( strcmp(ap->coinaddr,coinaddr) != 0 ) printf("UNEXPECTED coinaddr mismatch (%s) != (%s)\n",ap->coinaddr,coinaddr); - if ( 0 && coin->electrum != 0 ) - LP_listunspent_issue(coin->symbol,coin->smartaddr,2); //portable_mutex_lock(&LP_utxomutex); DL_FOREACH_SAFE(ap->utxos,up,tmp) { @@ -446,16 +445,17 @@ int32_t LP_address_utxoadd(uint32_t timestamp,char *debug,struct iguana_info *co struct LP_address *LP_address_utxo_reset(struct iguana_info *coin) { - struct LP_address *ap; struct LP_address_utxo *up,*tmp; int32_t i,n,m,vout,height; cJSON *array,*item,*txobj; int64_t value; bits256 txid; uint32_t now; + struct LP_address *ap; struct LP_address_utxo *up,*tmp; int32_t i,n,m,vout,height; cJSON *array,*item,*txobj; bits256 zero; int64_t value; bits256 txid; uint32_t now; LP_address(coin,coin->smartaddr); //printf("call listunspent issue %s (%s)\n",coin->symbol,coin->smartaddr); - LP_listunspent_issue(coin->symbol,coin->smartaddr,2); + memset(zero.bytes,0,sizeof(zero)); + LP_listunspent_issue(coin->symbol,coin->smartaddr,2,zero,zero); if ( (ap= LP_addressfind(coin,coin->smartaddr)) == 0 ) { printf("LP_address_utxo_reset: cant find address data\n"); return(0); } - if ( (array= LP_listunspent(coin->symbol,coin->smartaddr)) != 0 ) + if ( (array= LP_listunspent(coin->symbol,coin->smartaddr,zero,zero)) != 0 ) { DL_FOREACH_SAFE(ap->utxos,up,tmp) { @@ -575,10 +575,11 @@ cJSON *LP_address_utxos(struct iguana_info *coin,char *coinaddr,int32_t electrum cJSON *LP_address_balance(struct iguana_info *coin,char *coinaddr,int32_t electrumret) { - cJSON *array,*retjson,*item; int32_t i,n; uint64_t balance = 0; + cJSON *array,*retjson,*item; bits256 zero; int32_t i,n; uint64_t balance = 0; if ( coin->electrum == 0 ) { - if ( (array= LP_listunspent(coin->symbol,coinaddr)) != 0 ) + memset(zero.bytes,0,sizeof(zero)); + if ( (array= LP_listunspent(coin->symbol,coinaddr,zero,zero)) != 0 ) { if ( (n= cJSON_GetArraySize(array)) > 0 ) { @@ -789,7 +790,7 @@ int32_t LP_txheight(struct iguana_info *coin,bits256 txid) int32_t LP_numconfirms(char *symbol,char *coinaddr,bits256 txid,int32_t vout,int32_t mempool) { - struct iguana_info *coin; int32_t ht,numconfirms = 100; + struct iguana_info *coin; bits256 zero; int32_t ht,numconfirms = 100; cJSON *txobj; if ( (coin= LP_coinfind(symbol)) == 0 || coin->inactive != 0 ) return(-1); @@ -811,7 +812,8 @@ int32_t LP_numconfirms(char *symbol,char *coinaddr,bits256 txid,int32_t vout,int } else { - LP_listunspent_issue(symbol,coinaddr,1); + 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); else if ( mempool != 0 ) diff --git a/iguana/exchanges/LP_zeroconf.c b/iguana/exchanges/LP_zeroconf.c index 8c7261b74..7c737da71 100644 --- a/iguana/exchanges/LP_zeroconf.c +++ b/iguana/exchanges/LP_zeroconf.c @@ -125,7 +125,7 @@ char *LP_zeroconf_deposit(struct iguana_info *coin,int32_t weeks,double amount,i char *LP_zeroconf_claim(struct iguana_info *coin,char *depositaddr,uint32_t expiration) { static void *ctx; - uint8_t redeemscript[512],userdata[64]; char vinaddr[64],str[65],*signedtx=0; uint32_t timestamp,now,redeemlen,claimtime; int32_t i,n,height,utxovout,userdatalen; bits256 signedtxid,utxotxid,sendtxid; int64_t sum,destamount,satoshis; cJSON *array,*item,*txids,*retjson; + uint8_t redeemscript[512],userdata[64]; char vinaddr[64],str[65],*signedtx=0; uint32_t timestamp,now,redeemlen,claimtime; int32_t i,n,height,utxovout,userdatalen; bits256 signedtxid,utxotxid,sendtxid,zero; int64_t sum,destamount,satoshis; cJSON *array,*item,*txids,*retjson; if ( ctx == 0 ) ctx = bitcoin_ctx(); if ( strcmp(coin->symbol,"KMD") != 0 ) @@ -150,7 +150,8 @@ char *LP_zeroconf_claim(struct iguana_info *coin,char *depositaddr,uint32_t expi else { printf("found %s at timestamp.%u\n",vinaddr,timestamp); - if ( (array= LP_listunspent(coin->symbol,vinaddr)) != 0 ) + memset(zero.bytes,0,sizeof(zero)); + if ( (array= LP_listunspent(coin->symbol,vinaddr,zero,zero)) != 0 ) { userdata[0] = 0x51; userdatalen = 1; From 9e61d16227a1e8f8aa0258556e810a05ca674cc7 Mon Sep 17 00:00:00 2001 From: jl777 Date: Tue, 28 Nov 2017 12:38:18 +0400 Subject: [PATCH 1317/1664] Test --- iguana/exchanges/LP_zeroconf.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/iguana/exchanges/LP_zeroconf.c b/iguana/exchanges/LP_zeroconf.c index 7c737da71..1807b71fb 100644 --- a/iguana/exchanges/LP_zeroconf.c +++ b/iguana/exchanges/LP_zeroconf.c @@ -212,7 +212,7 @@ void LP_zeroconf_deposits(struct iguana_info *coin) { static int dispflag = 1; cJSON *array,*item,*txjson,*vouts,*v,*txobj; int32_t i,n,numvouts,height,vout,weeki; bits256 txid; char destaddr[64],p2shaddr[64]; struct LP_address *ap,*tmp; int64_t satoshis,amount64; - if ( coin->electrum != 0 && coin->electrumzeroconf == 0 ) + if ( coin->electrum != 0 && coin->electrumzeroconf != 0 ) return; HASH_ITER(hh,coin->addresses,ap,tmp) { From f3012d733a2c6f79787ee2f16d04d504b4972c26 Mon Sep 17 00:00:00 2001 From: jl777 Date: Tue, 28 Nov 2017 12:42:21 +0400 Subject: [PATCH 1318/1664] Test --- iguana/exchanges/LP_socket.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/iguana/exchanges/LP_socket.c b/iguana/exchanges/LP_socket.c index 37b3c4c0c..0074638bb 100644 --- a/iguana/exchanges/LP_socket.c +++ b/iguana/exchanges/LP_socket.c @@ -422,7 +422,7 @@ cJSON *electrum_submit(char *symbol,struct electrum_info *ep,cJSON **retjsonp,ch { *retjsonp = 0; sprintf(stratumreq,"{ \"jsonrpc\":\"2.0\", \"id\": %u, \"method\":\"%s\", \"params\": %s }\n",ep->stratumid,method,params); -printf("%s %s",symbol,stratumreq); +//printf("%s %s",symbol,stratumreq); memset(ep->buf,0,ep->bufsize); sitem = electrum_sitem(ep,stratumreq,timeout,retjsonp); portable_mutex_lock(&ep->mutex); // this helps performance! From 9d632c0b3d302ed1bc4a2244e08afa0a55386639 Mon Sep 17 00:00:00 2001 From: jl777 Date: Tue, 28 Nov 2017 13:25:27 +0400 Subject: [PATCH 1319/1664] Test --- iguana/exchanges/LP_zeroconf.c | 53 +++++++++++++++++++--------------- 1 file changed, 30 insertions(+), 23 deletions(-) diff --git a/iguana/exchanges/LP_zeroconf.c b/iguana/exchanges/LP_zeroconf.c index 1807b71fb..1a39db346 100644 --- a/iguana/exchanges/LP_zeroconf.c +++ b/iguana/exchanges/LP_zeroconf.c @@ -203,15 +203,42 @@ void LP_zeroconf_credit(int32_t dispflag,char *coinaddr,int64_t satoshis,int32_t { ap->zeroconf_credits += satoshis; if ( dispflag != 0 ) - printf("ZEROCONF credit.(%s) %.8f weeki.%d (%s) -> sum %.8f\n",coinaddr,dstr(satoshis),weeki,p2shaddr,dstr(ap->zeroconf_credits)); + printf("InstantDEX credit.(%s) %.8f weeki.%d (%s) -> sum %.8f\n",coinaddr,dstr(satoshis),weeki,p2shaddr,dstr(ap->zeroconf_credits)); } } } +int64_t LP_zeroconf_creditcalc(struct iguana_info *coin,int32_t dispflag,bits256 txid) +{ + cJSON *txjson,*vouts,*txobj,*item; int64_t satoshis=0,amount64; int32_t weeki,numvouts; char destaddr[64],p2shaddr[64]; + if ( (txjson= LP_gettx(coin->symbol,txid,0)) != 0 ) + { + // vout0 deposit, vout1 botsfee, vout2 smartaddress + if ( (vouts= jarray(&numvouts,txjson,"vout")) > 0 && numvouts >= 3 && LP_destaddr(destaddr,jitem(vouts,2)) == 0 ) + { + amount64 = LP_value_extract(jitem(vouts,1),0); + weeki = (amount64 % 10000); + item = jitem(vouts,0); + satoshis = LP_value_extract(item,0); + //printf("%s funded %.8f weeki.%d\n",destaddr,dstr(satoshis),weeki); + if ( LP_destaddr(p2shaddr,item) == 0 ) + { + if ( (txobj= LP_gettxout(coin->symbol,p2shaddr,txid,0)) != 0 ) + { + free_json(txobj); + LP_zeroconf_credit(dispflag,destaddr,satoshis,weeki,p2shaddr); + } + } + } + free_json(txjson); + } + return(satoshis); +} + void LP_zeroconf_deposits(struct iguana_info *coin) { static int dispflag = 1; - cJSON *array,*item,*txjson,*vouts,*v,*txobj; int32_t i,n,numvouts,height,vout,weeki; bits256 txid; char destaddr[64],p2shaddr[64]; struct LP_address *ap,*tmp; int64_t satoshis,amount64; + cJSON *array,*item; int32_t i,n,height,vout; bits256 txid; struct LP_address *ap,*tmp; if ( coin->electrum != 0 && coin->electrumzeroconf != 0 ) return; HASH_ITER(hh,coin->addresses,ap,tmp) @@ -230,27 +257,7 @@ void LP_zeroconf_deposits(struct iguana_info *coin) item = jitem(array,i); LP_listunspent_parseitem(coin,&txid,&vout,&height,item); } else txid = jbits256i(array,i); - if ( (txjson= LP_gettx(coin->symbol,txid,0)) != 0 ) - { - // vout0 deposit, vout1 botsfee, vout2 smartaddress - if ( (vouts= jarray(&numvouts,txjson,"vout")) > 0 && numvouts >= 3 && LP_destaddr(destaddr,jitem(vouts,2)) == 0 ) - { - amount64 = LP_value_extract(jitem(vouts,1),0); - weeki = (amount64 % 10000); - v = jitem(vouts,0); - satoshis = LP_value_extract(v,0); - //printf("%s funded %.8f weeki.%d\n",destaddr,dstr(satoshis),weeki); - if ( LP_destaddr(p2shaddr,v) == 0 ) - { - if ( (txobj= LP_gettxout(coin->symbol,p2shaddr,txid,0)) != 0 ) - { - free_json(txobj); - LP_zeroconf_credit(dispflag,destaddr,satoshis,weeki,p2shaddr); - } - } - } - free_json(txjson); - } + LP_zeroconf_creditcalc(coin,dispflag,txid); } } free_json(array); From 3d6b3f14b38446b232b85eabdb79c820566ede57 Mon Sep 17 00:00:00 2001 From: jl777 Date: Tue, 28 Nov 2017 14:28:15 +0400 Subject: [PATCH 1320/1664] Test --- iguana/exchanges/LP_commands.c | 8 ++++---- iguana/exchanges/LP_include.h | 4 ++-- iguana/exchanges/LP_nativeDEX.c | 4 ++-- iguana/exchanges/LP_socket.c | 24 ++++++++++++++++++++++-- iguana/exchanges/LP_zeroconf.c | 14 +++++++------- 5 files changed, 37 insertions(+), 17 deletions(-) diff --git a/iguana/exchanges/LP_commands.c b/iguana/exchanges/LP_commands.c index 1b483d0b7..2fb3349a0 100644 --- a/iguana/exchanges/LP_commands.c +++ b/iguana/exchanges/LP_commands.c @@ -293,23 +293,23 @@ zeroconf_claim(address, expiration=0)\n\ return(basilisk_swapentries(base,rel,jint(argjson,"limit"))); else return(basilisk_swaplist(0,0)); } - /*else if ( strcmp(method,"dynamictrust") == 0 ) + else if ( strcmp(method,"dynamictrust") == 0 ) { struct LP_address *ap; char *coinaddr; if ( (ptr= LP_coinsearch("KMD")) != 0 && (coinaddr= jstr(argjson,"address")) != 0 ) { - LP_zeroconf_deposits(ptr); + //LP_zeroconf_deposits(ptr); if ( (ap= LP_addressfind(ptr,coinaddr)) != 0 ) { retjson = cJSON_CreateObject(); jaddstr(retjson,"result","success"); jaddstr(retjson,"address",coinaddr); - jaddnum(retjson,"zcredits",dstr(ap->zeroconf_credits)); + jaddnum(retjson,"zcredits",dstr(ap->instantdex_credits)); return(jprint(retjson,1)); } } return(clonestr("{\"error\":\"cant find address\"}")); - }*/ + } else if ( (retstr= LP_istradebots_command(ctx,pubsock,method,argjson)) != 0 ) return(retstr); if ( base[0] != 0 && rel[0] != 0 ) diff --git a/iguana/exchanges/LP_include.h b/iguana/exchanges/LP_include.h index 3b07aa056..c18f27232 100644 --- a/iguana/exchanges/LP_include.h +++ b/iguana/exchanges/LP_include.h @@ -328,7 +328,7 @@ struct LP_address UT_hash_handle hh; struct LP_address_utxo *utxos; bits256 pubkey; - int64_t balance,total,zeroconf_credits; + int64_t balance,total,instantdex_credits; uint32_t timestamp,n,unspenttime; int32_t unspentheight; char coinaddr[40]; @@ -404,7 +404,7 @@ struct LP_pubkey_info bits256 pubkey; struct LP_pubkey_quote *quotes; struct LP_pubswap *bobswaps,*aliceswaps; - uint64_t dynamictrust; + int64_t dynamictrust,unconfdeposits; uint32_t timestamp,numerrors,lasttime,slowresponse; int32_t istrusted; uint8_t rmd160[20],sig[65],pubsecp[33],siglen; diff --git a/iguana/exchanges/LP_nativeDEX.c b/iguana/exchanges/LP_nativeDEX.c index bd3ea3fde..65615c163 100644 --- a/iguana/exchanges/LP_nativeDEX.c +++ b/iguana/exchanges/LP_nativeDEX.c @@ -539,11 +539,11 @@ void LP_coinsloop(void *_coins) coin->longestchain = LP_getheight(coin); if ( (ep= coin->electrum) != 0 ) { - if ( strcmp("KMD",coin->symbol) == 0 && coin->electrumzeroconf == 0 ) + /*if ( strcmp("KMD",coin->symbol) == 0 && coin->electrumzeroconf == 0 ) { LP_zeroconf_deposits(coin); coin->electrumzeroconf = (uint32_t)time(NULL); - } + }*/ if ( (backupep= ep->prev) == 0 ) backupep = ep; if ( (retjson= electrum_address_listunspent(coin->symbol,ep,&retjson,coin->smartaddr,1,zero,zero)) != 0 ) diff --git a/iguana/exchanges/LP_socket.c b/iguana/exchanges/LP_socket.c index 0074638bb..6ce9a8178 100644 --- a/iguana/exchanges/LP_socket.c +++ b/iguana/exchanges/LP_socket.c @@ -1045,13 +1045,33 @@ void LP_dedicatedloop(void *arg) cJSON *LP_electrumserver(struct iguana_info *coin,char *ipaddr,uint16_t port) { - struct electrum_info *ep; int32_t kickval,already; cJSON *retjson; + struct electrum_info *ep,*prev; int32_t kickval,already; cJSON *retjson,*array,*item; if ( ipaddr == 0 || ipaddr[0] == 0 || port == 0 ) { + ep = coin->electrum; coin->electrum = 0; coin->inactive = (uint32_t)time(NULL); + retjson = cJSON_CreateObject(); + jaddstr(retjson,"result","success"); + jaddstr(retjson,"status","electrum mode disabled, now in disabled native coin mode"); + if ( ep != 0 ) + { + array = cJSON_CreateArray(); + while ( ep != 0 ) + { + item = cJSON_CreateObject(); + jaddstr(item,"ipaddr",ep->ipaddr); + jaddnum(item,"port",ep->port); + jaddnum(item,"kickstart",electrum_kickstart(ep)); + jaddi(array,item); + prev = ep->prev; + ep->prev = 0; + ep = prev; + } + jadd(retjson,"electrums",array); + } //printf("would have disabled %s electrum here\n",coin->symbol); - return(cJSON_Parse("{\"result\":\"success\",\"status\":\"electrum mode disabled, now in native coin mode\"}")); + return(cJSON_Parse("{\"result\":\"success\",\"status\":\"electrum mode disabled, now in disabled native coin mode\"}")); } retjson = cJSON_CreateObject(); jaddstr(retjson,"ipaddr",ipaddr); diff --git a/iguana/exchanges/LP_zeroconf.c b/iguana/exchanges/LP_zeroconf.c index 1a39db346..49177b7d5 100644 --- a/iguana/exchanges/LP_zeroconf.c +++ b/iguana/exchanges/LP_zeroconf.c @@ -201,9 +201,9 @@ void LP_zeroconf_credit(int32_t dispflag,char *coinaddr,int64_t satoshis,int32_t timestamp = LP_FIRSTWEEKTIME + weeki*LP_WEEKMULT; if ( time(NULL) < timestamp-60*3600 && (ap= LP_address(coin,coinaddr)) != 0 ) { - ap->zeroconf_credits += satoshis; + ap->instantdex_credits += satoshis; if ( dispflag != 0 ) - printf("InstantDEX credit.(%s) %.8f weeki.%d (%s) -> sum %.8f\n",coinaddr,dstr(satoshis),weeki,p2shaddr,dstr(ap->zeroconf_credits)); + printf("InstantDEX credit.(%s) %.8f weeki.%d (%s) -> sum %.8f\n",coinaddr,dstr(satoshis),weeki,p2shaddr,dstr(ap->instantdex_credits)); } } } @@ -238,12 +238,12 @@ int64_t LP_zeroconf_creditcalc(struct iguana_info *coin,int32_t dispflag,bits256 void LP_zeroconf_deposits(struct iguana_info *coin) { static int dispflag = 1; - cJSON *array,*item; int32_t i,n,height,vout; bits256 txid; struct LP_address *ap,*tmp; - if ( coin->electrum != 0 && coin->electrumzeroconf != 0 ) + cJSON *array,*item; int32_t i,n,height,vout; bits256 txid; struct LP_address *ap,*tmp; + if ( coin->electrum != 0 )//&& coin->electrumzeroconf != 0 ) return; HASH_ITER(hh,coin->addresses,ap,tmp) { - ap->zeroconf_credits = 0; + ap->instantdex_credits = 0; } if ( (array= LP_listreceivedbyaddress("KMD",BOTS_BONDADDRESS)) != 0 ) { @@ -271,7 +271,7 @@ int64_t LP_dynamictrust(bits256 pubkey,int64_t kmdvalue) if ( (coin= LP_coinfind("KMD")) != 0 && (pubp= LP_pubkeyfind(pubkey)) != 0 ) { bitcoin_address(coinaddr,coin->taddr,coin->pubtype,pubp->pubsecp,33); - if ((ap= LP_address(coin,coinaddr)) != 0 )//&& ap->zeroconf_credits >= kmdvalue ) + if ((ap= LP_address(coin,coinaddr)) != 0 )//&& ap->instantdex_credits >= kmdvalue ) { DL_FOREACH_SAFE(pubp->bobswaps,ptr,tmp) { @@ -285,7 +285,7 @@ int64_t LP_dynamictrust(bits256 pubkey,int64_t kmdvalue) } //printf("%s zeroconf_credits %.8f vs (%.8f + current %.8f)\n",coinaddr,dstr(ap->zeroconf_credits),dstr(swaps_kmdvalue),dstr(kmdvalue)); //if ( ap->zeroconf_credits > swaps_kmdvalue+kmdvalue ) - return(ap->zeroconf_credits - (swaps_kmdvalue+kmdvalue)); + return(ap->instantdex_credits - (swaps_kmdvalue+kmdvalue)); } } return(0); From 3fa5f63b2e672833789fa1c3361130f967169e71 Mon Sep 17 00:00:00 2001 From: jl777 Date: Tue, 28 Nov 2017 14:34:50 +0400 Subject: [PATCH 1321/1664] Test --- iguana/exchanges/LP_include.h | 2 +- iguana/exchanges/install | 2 +- iguana/exchanges/kickstart | 3 +++ 3 files changed, 5 insertions(+), 2 deletions(-) create mode 100755 iguana/exchanges/kickstart diff --git a/iguana/exchanges/LP_include.h b/iguana/exchanges/LP_include.h index c18f27232..963e9ccda 100644 --- a/iguana/exchanges/LP_include.h +++ b/iguana/exchanges/LP_include.h @@ -278,7 +278,7 @@ struct iguana_info 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,electrumzeroconf; + uint32_t 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 diff --git a/iguana/exchanges/install b/iguana/exchanges/install index f938704ac..00e6aefbe 100755 --- a/iguana/exchanges/install +++ b/iguana/exchanges/install @@ -1,5 +1,5 @@ #!/bin/bash -cp tradesarray claim deposit deposit1 invreset sendrawtransaction processfiles stop millis mnzservers bot_buy bot_list bot_statuslist bot_pause bot_resume bot_sell bot_settings bot_status bot_stop guistats pubkeystats pendings coinswaps baserelswaps setpassphrase notarizations getrawtransaction parselog statsdisp m_js 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 kickstart tradesarray claim deposit deposit1 invreset sendrawtransaction processfiles stop millis mnzservers bot_buy bot_list bot_statuslist bot_pause bot_resume bot_sell bot_settings bot_status bot_stop guistats pubkeystats pendings coinswaps baserelswaps setpassphrase notarizations getrawtransaction parselog statsdisp m_js 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 . diff --git a/iguana/exchanges/kickstart b/iguana/exchanges/kickstart new file mode 100755 index 000000000..46e353ee2 --- /dev/null +++ b/iguana/exchanges/kickstart @@ -0,0 +1,3 @@ +#!/bin/bash +source userpass +curl --url "http://127.0.0.1:7783" --data "{\"userpass\":\"$userpass\",\"method\":\"electrum\",\"coin\":\"KMD\",\"ipaddr\":\"\",\"port\":0}" From 2224a100d6de1e91118cc62aaa3297f4023959cc Mon Sep 17 00:00:00 2001 From: jl777 Date: Tue, 28 Nov 2017 14:38:44 +0400 Subject: [PATCH 1322/1664] test --- iguana/exchanges/LP_socket.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/iguana/exchanges/LP_socket.c b/iguana/exchanges/LP_socket.c index 6ce9a8178..330d85a71 100644 --- a/iguana/exchanges/LP_socket.c +++ b/iguana/exchanges/LP_socket.c @@ -1071,7 +1071,7 @@ cJSON *LP_electrumserver(struct iguana_info *coin,char *ipaddr,uint16_t port) jadd(retjson,"electrums",array); } //printf("would have disabled %s electrum here\n",coin->symbol); - return(cJSON_Parse("{\"result\":\"success\",\"status\":\"electrum mode disabled, now in disabled native coin mode\"}")); + return(retjson); } retjson = cJSON_CreateObject(); jaddstr(retjson,"ipaddr",ipaddr); From bf692cf56c4a8684624b952035d0e74711553a13 Mon Sep 17 00:00:00 2001 From: jl777 Date: Tue, 28 Nov 2017 15:46:43 +0400 Subject: [PATCH 1323/1664] Test --- iguana/exchanges/LP_commands.c | 4 +- iguana/exchanges/LP_include.h | 6 +- .../{LP_zeroconf.c => LP_instantdex.c} | 131 ++++++++++++++---- iguana/exchanges/LP_nativeDEX.c | 12 +- iguana/exchanges/LP_ordermatch.c | 22 ++- iguana/exchanges/LP_prices.c | 4 +- iguana/exchanges/LP_signatures.c | 25 ++-- 7 files changed, 149 insertions(+), 55 deletions(-) rename iguana/exchanges/{LP_zeroconf.c => LP_instantdex.c} (69%) diff --git a/iguana/exchanges/LP_commands.c b/iguana/exchanges/LP_commands.c index 2fb3349a0..aa80406d4 100644 --- a/iguana/exchanges/LP_commands.c +++ b/iguana/exchanges/LP_commands.c @@ -198,7 +198,7 @@ zeroconf_claim(address, expiration=0)\n\ { if ( jint(argjson,"weeks") < 0 || jdouble(argjson,"amount") < 10. ) return(clonestr("{\"error\":\"deposit_create needs to have weeks and amount\"}")); - else return(LP_zeroconf_deposit(ptr,juint(argjson,"weeks"),jdouble(argjson,"amount"),jint(argjson,"broadcast"))); + else return(LP_instantdex_deposit(ptr,juint(argjson,"weeks"),jdouble(argjson,"amount"),jint(argjson,"broadcast"))); } return(clonestr("{\"error\":\"cant find KMD\"}")); } @@ -208,7 +208,7 @@ zeroconf_claim(address, expiration=0)\n\ { if ( jstr(argjson,"address") == 0 ) return(clonestr("{\"error\":\"deposit_claim needs to have address\"}")); - else return(LP_zeroconf_claim(ptr,jstr(argjson,"address"),juint(argjson,"expiration"))); + else return(LP_instantdex_claim(ptr,jstr(argjson,"address"),juint(argjson,"expiration"))); } return(clonestr("{\"error\":\"cant find KMD\"}")); } diff --git a/iguana/exchanges/LP_include.h b/iguana/exchanges/LP_include.h index 963e9ccda..9885474a4 100644 --- a/iguana/exchanges/LP_include.h +++ b/iguana/exchanges/LP_include.h @@ -332,7 +332,7 @@ struct LP_address uint32_t timestamp,n,unspenttime; int32_t unspentheight; char coinaddr[40]; - uint8_t pubsecp[33],pad; + uint8_t pubsecp[33],didinstantdex; }; struct LP_peerinfo @@ -404,7 +404,7 @@ struct LP_pubkey_info bits256 pubkey; struct LP_pubkey_quote *quotes; struct LP_pubswap *bobswaps,*aliceswaps; - int64_t dynamictrust,unconfdeposits; + int64_t dynamictrust,unconfcredits; uint32_t timestamp,numerrors,lasttime,slowresponse; int32_t istrusted; uint8_t rmd160[20],sig[65],pubsecp[33],siglen; @@ -428,7 +428,7 @@ struct LP_trade struct LP_trade *next,*prev; UT_hash_handle hh; uint64_t aliceid; - int64_t besttrust; + int64_t besttrust,bestunconfcredits; double bestprice; uint32_t negotiationdone,bestresponse,connectsent,firsttime,lasttime,firstprocessed,lastprocessed,newtime; char pairstr[64],funcid,iambob; diff --git a/iguana/exchanges/LP_zeroconf.c b/iguana/exchanges/LP_instantdex.c similarity index 69% rename from iguana/exchanges/LP_zeroconf.c rename to iguana/exchanges/LP_instantdex.c index 49177b7d5..2a258af19 100644 --- a/iguana/exchanges/LP_zeroconf.c +++ b/iguana/exchanges/LP_instantdex.c @@ -15,10 +15,55 @@ ******************************************************************************/ // -// LP_zeroconf.c +// LP_instantdex.c // marketmaker // +void LP_instantdex_txidaddfname(char *fname) +{ + sprintf(fname,"%s/instantdex.json",GLOBAL_DBDIR); +} + +cJSON *LP_instantdex_txidaddjson() +{ + char *filestr,fname[1024]; long fsize; cJSON *retjson=0; + LP_instantdex_txidaddfname(fname); + if ( (filestr= OS_filestr(&fsize,fname)) != 0 ) + { + retjson = cJSON_Parse(filestr); + free(filestr); + } + return(retjson); +} + +void LP_instantdex_txidadd(bits256 txid) +{ + cJSON *array; int32_t i,n; char fname[1024],*filestr; FILE *fp; + if ( (array= LP_instantdex_txidaddjson()) == 0 ) + array = cJSON_CreateArray(); + if ( (n= cJSON_GetArraySize(array)) > 0 ) + { + for (i=0; i %s\n",bits256_str(str,txid),fname); + jaddibits256(array,txid); + if ( (fp= fopen(fname,"wb")) != 0 ) + { + filestr = jprint(array,0); + fwrite(filestr,1,strlen(filestr)+1,fp); + fclose(fp); + free(filestr); + } + } + } + if ( array != 0 ) + free_json(array); +} + int32_t LP_deposit_addr(char *p2shaddr,uint8_t *script,uint8_t taddr,uint8_t p2shtype,uint32_t timestamp,uint8_t *pubsecp33) { uint8_t elsepub33[33],p2sh_rmd160[20]; int32_t n; @@ -28,13 +73,13 @@ int32_t LP_deposit_addr(char *p2shaddr,uint8_t *script,uint8_t taddr,uint8_t p2s return(n); } -char *LP_zeroconf_deposit(struct iguana_info *coin,int32_t weeks,double amount,int32_t broadcast) +char *LP_instantdex_deposit(struct iguana_info *coin,int32_t weeks,double amount,int32_t broadcast) { char p2shaddr[64],*retstr,*hexstr; uint8_t script[512]; int32_t weeki,scriptlen; cJSON *argjson,*retjson,*array,*item,*obj; uint32_t timestamp; bits256 txid,sendtxid; uint64_t amount64; if ( strcmp(coin->symbol,"KMD") != 0 ) - return(clonestr("{\"error\":\"zeroconf deposit must be in KMD\"}")); + return(clonestr("{\"error\":\"instantdex deposit must be in KMD\"}")); if ( amount < 10.0 ) - return(clonestr("{\"error\":\"minimum zeroconf deposit is 10 KMD\"}")); + return(clonestr("{\"error\":\"minimum instantdex deposit is 10 KMD\"}")); if ( weeks < 0 || weeks > 52 ) return(clonestr("{\"error\":\"weeks must be between 0 and 52\"}")); if ( weeks > 0 ) @@ -75,6 +120,8 @@ char *LP_zeroconf_deposit(struct iguana_info *coin,int32_t weeks,double amount,i if ( (obj= jobj(retjson,"complete")) != 0 && is_cJSON_True(obj) != 0 && (hexstr= jstr(retjson,"hex")) != 0 ) { txid = jbits256(retjson,"txid"); + if ( bits256_nonz(txid) != 0 ) + LP_instantdex_txidadd(txid); if ( broadcast != 0 ) { if (bits256_nonz(txid) != 0 ) @@ -119,17 +166,17 @@ char *LP_zeroconf_deposit(struct iguana_info *coin,int32_t weeks,double amount,i } free(retstr); } - return(clonestr("{\"error\":\"error with LP_withdraw for zeroconf deposit\"}")); + return(clonestr("{\"error\":\"error with LP_withdraw for instantdex deposit\"}")); } -char *LP_zeroconf_claim(struct iguana_info *coin,char *depositaddr,uint32_t expiration) +char *LP_instantdex_claim(struct iguana_info *coin,char *depositaddr,uint32_t expiration) { static void *ctx; uint8_t redeemscript[512],userdata[64]; char vinaddr[64],str[65],*signedtx=0; uint32_t timestamp,now,redeemlen,claimtime; int32_t i,n,height,utxovout,userdatalen; bits256 signedtxid,utxotxid,sendtxid,zero; int64_t sum,destamount,satoshis; cJSON *array,*item,*txids,*retjson; if ( ctx == 0 ) ctx = bitcoin_ctx(); if ( strcmp(coin->symbol,"KMD") != 0 ) - return(clonestr("{\"error\":\"zeroconf deposit must be in KMD\"}")); + return(clonestr("{\"error\":\"instantdex deposit must be in KMD\"}")); now = (uint32_t)time(NULL); sum = 0; txids = cJSON_CreateArray(); @@ -164,7 +211,7 @@ char *LP_zeroconf_claim(struct iguana_info *coin,char *depositaddr,uint32_t expi item = jitem(array,i); satoshis = LP_listunspent_parseitem(coin,&utxotxid,&utxovout,&height,item); printf("satoshis %.8f %s/v%d\n",dstr(satoshis),bits256_str(str,utxotxid),utxovout); - if ( (signedtx= basilisk_swap_bobtxspend(&signedtxid,10000,"zeroconfclaim",coin->symbol,coin->wiftaddr,coin->taddr,coin->pubtype,coin->p2shtype,coin->isPoS,coin->wiftype,ctx,G.LP_privkey,0,redeemscript,redeemlen,userdata,userdatalen,utxotxid,utxovout,coin->smartaddr,G.LP_pubsecp,0,claimtime,&destamount,0,0,vinaddr,1,coin->zcash)) != 0 ) + if ( (signedtx= basilisk_swap_bobtxspend(&signedtxid,10000,"instantdexclaim",coin->symbol,coin->wiftaddr,coin->taddr,coin->pubtype,coin->p2shtype,coin->isPoS,coin->wiftype,ctx,G.LP_privkey,0,redeemscript,redeemlen,userdata,userdatalen,utxotxid,utxovout,coin->smartaddr,G.LP_pubsecp,0,claimtime,&destamount,0,0,vinaddr,1,coin->zcash)) != 0 ) { printf("signedtx.(%s)\n",signedtx); sendtxid = LP_broadcast("claim","KMD",signedtx,signedtxid); @@ -175,7 +222,7 @@ char *LP_zeroconf_claim(struct iguana_info *coin,char *depositaddr,uint32_t expi } else printf("error sending %s\n",bits256_str(str,signedtxid)); free(signedtx); - } else printf("error claiming zeroconf deposit %s/v%d %.8f\n",bits256_str(str,utxotxid),utxovout,dstr(satoshis)); + } else printf("error claiming instantdex deposit %s/v%d %.8f\n",bits256_str(str,utxotxid),utxovout,dstr(satoshis)); } } free_json(array); @@ -190,10 +237,10 @@ char *LP_zeroconf_claim(struct iguana_info *coin,char *depositaddr,uint32_t expi if ( expiration != 0 ) break; } - return(clonestr("{\"error\":\"no zeroconf deposits to claim\"}")); + return(clonestr("{\"error\":\"no instantdex deposits to claim\"}")); } -void LP_zeroconf_credit(int32_t dispflag,char *coinaddr,int64_t satoshis,int32_t weeki,char *p2shaddr) +int64_t LP_instantdex_credit(int32_t dispflag,char *coinaddr,int64_t satoshis,int32_t weeki,char *p2shaddr) { uint32_t timestamp; struct LP_address *ap; struct iguana_info *coin = LP_coinfind("KMD"); if ( coin != 0 ) @@ -204,11 +251,13 @@ void LP_zeroconf_credit(int32_t dispflag,char *coinaddr,int64_t satoshis,int32_t ap->instantdex_credits += satoshis; 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); } } + return(0); } -int64_t LP_zeroconf_creditcalc(struct iguana_info *coin,int32_t dispflag,bits256 txid) +int64_t LP_instantdex_creditcalc(struct iguana_info *coin,int32_t dispflag,bits256 txid,char *refaddr) { cJSON *txjson,*vouts,*txobj,*item; int64_t satoshis=0,amount64; int32_t weeki,numvouts; char destaddr[64],p2shaddr[64]; if ( (txjson= LP_gettx(coin->symbol,txid,0)) != 0 ) @@ -216,17 +265,27 @@ int64_t LP_zeroconf_creditcalc(struct iguana_info *coin,int32_t dispflag,bits256 // vout0 deposit, vout1 botsfee, vout2 smartaddress if ( (vouts= jarray(&numvouts,txjson,"vout")) > 0 && numvouts >= 3 && LP_destaddr(destaddr,jitem(vouts,2)) == 0 ) { - amount64 = LP_value_extract(jitem(vouts,1),0); - weeki = (amount64 % 10000); - item = jitem(vouts,0); - satoshis = LP_value_extract(item,0); - //printf("%s funded %.8f weeki.%d\n",destaddr,dstr(satoshis),weeki); - if ( LP_destaddr(p2shaddr,item) == 0 ) + if ( refaddr != 0 && strcmp(refaddr,destaddr) != 0 ) + { + printf("LP_instantdex_creditcalc for (%s) but deposit sent for (%s)\n",refaddr,destaddr); + } + else { - if ( (txobj= LP_gettxout(coin->symbol,p2shaddr,txid,0)) != 0 ) + amount64 = LP_value_extract(jitem(vouts,1),0); + weeki = (amount64 % 10000); + item = jitem(vouts,0); + satoshis = LP_value_extract(item,0); + //printf("%s funded %.8f weeki.%d\n",destaddr,dstr(satoshis),weeki); + if ( LP_destaddr(p2shaddr,item) == 0 ) { - free_json(txobj); - LP_zeroconf_credit(dispflag,destaddr,satoshis,weeki,p2shaddr); + if ( (txobj= LP_gettxout(coin->symbol,p2shaddr,txid,0)) != 0 ) + { + free_json(txobj); + if ( LP_instantdex_credit(dispflag,destaddr,satoshis,weeki,p2shaddr) > 0 && strcmp(coin->symbol,"KMD") == 0 && strcmp(destaddr,coin->smartaddr) == 0 ) + { + LP_instantdex_txidadd(txid); + } + } } } } @@ -235,11 +294,29 @@ int64_t LP_zeroconf_creditcalc(struct iguana_info *coin,int32_t dispflag,bits256 return(satoshis); } -void LP_zeroconf_deposits(struct iguana_info *coin) +void LP_instantdex_proofcheck(char *coinaddr,cJSON *proof,int32_t num) +{ + uint8_t rmd160[20],addrtype; int32_t i; char othersmartaddr[64]; struct iguana_info *coin; struct LP_address *ap = 0; + if ( (coin= LP_coinfind("KMD")) != 0 && coin->electrum != 0 ) + { + bitcoin_addr2rmd160(0,&addrtype,rmd160,coinaddr); + bitcoin_address(othersmartaddr,0,60,rmd160,20); + if ((ap= LP_address(coin,othersmartaddr)) != 0 && ap->didinstantdex == 0 ) + { + ap->instantdex_credits = 0; + for (i=0; ididinstantdex = 1; + printf("validated instantdex %s.[%d] proof.(%s)\n",othersmartaddr,num,jprint(proof,0)); + } + } +} + +void LP_instantdex_deposits(struct iguana_info *coin) { static int dispflag = 1; cJSON *array,*item; int32_t i,n,height,vout; bits256 txid; struct LP_address *ap,*tmp; - if ( coin->electrum != 0 )//&& coin->electrumzeroconf != 0 ) + if ( coin->electrum != 0 )//&& coin->electruminstantdex != 0 ) return; HASH_ITER(hh,coin->addresses,ap,tmp) { @@ -247,7 +324,7 @@ void LP_zeroconf_deposits(struct iguana_info *coin) } if ( (array= LP_listreceivedbyaddress("KMD",BOTS_BONDADDRESS)) != 0 ) { - //printf("ZEROCONF.(%s)\n",jprint(array,0)); + //printf("instantdex.(%s)\n",jprint(array,0)); if ( (n= cJSON_GetArraySize(array)) > 0 ) { for (i=0; iswap) != 0 && sp->finished == 0 && sp->expired == 0 ) swaps_kmdvalue += LP_kmdvalue(sp->Q.destcoin,sp->Q.destsatoshis); } - //printf("%s zeroconf_credits %.8f vs (%.8f + current %.8f)\n",coinaddr,dstr(ap->zeroconf_credits),dstr(swaps_kmdvalue),dstr(kmdvalue)); - //if ( ap->zeroconf_credits > swaps_kmdvalue+kmdvalue ) + //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)); } } diff --git a/iguana/exchanges/LP_nativeDEX.c b/iguana/exchanges/LP_nativeDEX.c index 65615c163..88146e810 100644 --- a/iguana/exchanges/LP_nativeDEX.c +++ b/iguana/exchanges/LP_nativeDEX.c @@ -188,7 +188,7 @@ char *blocktrail_listtransactions(char *symbol,char *coinaddr,int32_t num,int32_ #include "LP_transaction.c" #include "LP_stats.c" #include "LP_remember.c" -#include "LP_zeroconf.c" +#include "LP_instantdex.c" #include "LP_swap.c" #include "LP_peers.c" #include "LP_privkey.c" @@ -651,7 +651,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,didzeroconf; + static uint32_t counter,didinstantdex; struct iguana_info *coin,*ctmp; char *origipaddr; uint32_t now; int32_t height,nonz = 0; if ( (origipaddr= myipaddr) == 0 ) origipaddr = "127.0.0.1"; @@ -660,10 +660,10 @@ int32_t LP_mainloop_iter(void *ctx,char *myipaddr,struct LP_peerinfo *mypeer,int HASH_ITER(hh,LP_coins,coin,ctmp) // firstrefht,firstscanht,lastscanht { now = (uint32_t)time(NULL); - if ( coin->inactive == 0 && didzeroconf == 0 && strcmp("KMD",coin->symbol) == 0 ) + if ( coin->inactive == 0 && didinstantdex == 0 && strcmp("KMD",coin->symbol) == 0 ) { - LP_zeroconf_deposits(coin); - didzeroconf = now; + LP_instantdex_deposits(coin); + didinstantdex = now; } if ( (coin->addr_listunspent_requested != 0 && now > coin->lastpushtime+LP_ORDERBOOK_DURATION*.5) || now > coin->lastpushtime+LP_ORDERBOOK_DURATION*5 ) { @@ -811,7 +811,7 @@ void LP_swapsloop(void *ctx) free(retstr); sleep(600); if ( (coin= LP_coinfind("KMD")) != 0 ) - LP_zeroconf_deposits(coin); + LP_instantdex_deposits(coin); } } diff --git a/iguana/exchanges/LP_ordermatch.c b/iguana/exchanges/LP_ordermatch.c index 5ccb2ee8e..739ee4c28 100644 --- a/iguana/exchanges/LP_ordermatch.c +++ b/iguana/exchanges/LP_ordermatch.c @@ -887,6 +887,7 @@ struct LP_quoteinfo *LP_trades_gotrequest(void *ctx,struct LP_quoteinfo *qp,stru if ( LP_allocated(qp->txid,qp->vout) == 0 && LP_allocated(qp->txid2,qp->vout2) == 0 ) { reqjson = LP_quotejson(qp); + jadd(reqjson,"proof",LP_instantdex_txidaddjson()); LP_unavailableset(qp->txid,qp->vout,qp->timestamp + LP_RESERVETIME,qp->desthash); LP_unavailableset(qp->txid2,qp->vout2,qp->timestamp + LP_RESERVETIME,qp->desthash); if ( qp->quotetime == 0 ) @@ -963,7 +964,7 @@ struct LP_quoteinfo *LP_trades_gotconnected(void *ctx,struct LP_quoteinfo *qp,st int32_t LP_trades_bestpricecheck(void *ctx,struct LP_trade *tp) { - double qprice; struct LP_quoteinfo Q; int64_t dynamictrust; char *retstr; struct LP_pubkey_info *pubp; + double qprice; int32_t flag = 0; struct LP_quoteinfo Q; int64_t dynamictrust; char *retstr; struct LP_pubkey_info *pubp; Q = tp->Q; //printf("check bestprice %.8f vs new price %.8f\n",tp->bestprice,(double)Q.destsatoshis/Q.satoshis); if ( Q.satoshis != 0 && (pubp= LP_pubkeyfind(Q.srchash)) != 0 )//(qprice= LP_trades_alicevalidate(ctx,&Q)) > 0. ) @@ -974,13 +975,22 @@ int32_t LP_trades_bestpricecheck(void *ctx,struct LP_trade *tp) free(retstr); //LP_trades_gotreserved(ctx,&Q,&tp->Qs[LP_RESERVED]); dynamictrust = LP_dynamictrust(Q.srchash,LP_kmdvalue(Q.srccoin,Q.satoshis)); - if ( tp->bestprice == 0. || (qprice < tp->bestprice && pubp->slowresponse <= tp->bestresponse*1.05) || (qprice < tp->bestprice*1.01 && dynamictrust > tp->besttrust && pubp->slowresponse <= tp->bestresponse*1.1) ) + if ( tp->bestprice == 0. ) + flag = 1; + else if ( qprice < tp->bestprice && pubp->slowresponse <= tp->bestresponse*1.05 ) + flag = 1; + else if ( qprice < tp->bestprice*1.01 && dynamictrust > tp->besttrust && pubp->slowresponse <= tp->bestresponse*1.1 ) + flag = 1; + else if ( qprice <= tp->bestprice && pubp->unconfcredits > tp->bestunconfcredits && pubp->slowresponse <= tp->bestresponse ) + flag = 1; + if ( flag != 0 ) { tp->Qs[LP_CONNECT] = tp->Q; tp->bestprice = qprice; tp->besttrust = dynamictrust; + tp->bestunconfcredits = pubp->unconfcredits; tp->bestresponse = pubp->slowresponse; - printf("aliceid.%llu got new bestprice %.8f dynamictrust %.8f slowresponse.%d\n",(long long)tp->aliceid,tp->bestprice,dstr(dynamictrust),tp->bestresponse); + printf("aliceid.%llu got new bestprice %.8f dynamictrust %.8f (unconf %.8f) slowresponse.%d\n",(long long)tp->aliceid,tp->bestprice,dstr(dynamictrust),dstr(tp->bestunconfcredits),tp->bestresponse); return(qprice); } //else printf("qprice %.8f dynamictrust %.8f not good enough\n",qprice,dstr(dynamictrust)); } else printf("alice didnt validate\n"); @@ -1140,7 +1150,7 @@ void LP_tradecommandQ(struct LP_quoteinfo *qp,char *pairstr,int32_t funcid) int32_t LP_tradecommand(void *ctx,char *myipaddr,int32_t pubsock,cJSON *argjson,uint8_t *data,int32_t datalen) { int32_t Qtrades = 1; - char *method,str[65]; int32_t DEXselector = 0; uint64_t aliceid; double qprice,bestprice,price,bid,ask; struct iguana_info *coin; struct LP_quoteinfo Q,Q2; int32_t counter,retval=-1; + char *method,str[65]; int32_t num,DEXselector = 0; uint64_t aliceid; double qprice,bestprice,price,bid,ask; cJSON *proof; struct iguana_info *coin; struct LP_quoteinfo Q,Q2; int32_t counter,retval=-1; if ( (method= jstr(argjson,"method")) != 0 && (strcmp(method,"reserved") == 0 ||strcmp(method,"connected") == 0 || strcmp(method,"request") == 0 || strcmp(method,"connect") == 0) ) { LP_quoteparse(&Q,argjson); @@ -1169,6 +1179,8 @@ int32_t LP_tradecommand(void *ctx,char *myipaddr,int32_t pubsock,cJSON *argjson, } if ( bits256_cmp(G.LP_mypub25519,Q.desthash) == 0 && bits256_cmp(G.LP_mypub25519,Q.srchash) != 0 ) { + if ( (proof= jarray(&num,argjson,"proof")) != 0 && num > 0 ) + LP_instantdex_proofcheck(Q.coinaddr,proof,num); if ( Qtrades == 0 ) { if ( Q.quotetime > time(NULL)-20 && LP_alice_eligible(Q.quotetime) > 0 ) @@ -1215,6 +1227,8 @@ int32_t LP_tradecommand(void *ctx,char *myipaddr,int32_t pubsock,cJSON *argjson, else if ( strcmp(method,"connect") == 0 ) { LP_bob_competition(&counter,aliceid,qprice,1000); + if ( (proof= jarray(&num,argjson,"proof")) != 0 && num > 0 ) + LP_instantdex_proofcheck(Q.coinaddr,proof,num); if ( Qtrades == 0 ) LP_trades_gotconnect(ctx,&Q,&Q2,jstr(argjson,"pair")); else LP_tradecommandQ(&Q,jstr(argjson,"pair"),LP_CONNECT); diff --git a/iguana/exchanges/LP_prices.c b/iguana/exchanges/LP_prices.c index b1f236fc3..8c23d87fb 100644 --- a/iguana/exchanges/LP_prices.c +++ b/iguana/exchanges/LP_prices.c @@ -1084,7 +1084,7 @@ cJSON *LP_pricearray(char *base,char *rel,uint32_t firsttime,uint32_t lasttime,i return(retarray); } -void LP_pricefeedupdate(bits256 pubkey,char *base,char *rel,double price,char *utxocoin,int32_t numrelutxos,int64_t balance,int64_t minutxo,int64_t maxutxo) +void LP_pricefeedupdate(bits256 pubkey,char *base,char *rel,double price,char *utxocoin,int32_t numrelutxos,int64_t balance,int64_t minutxo,int64_t maxutxo,int64_t unconfcredits) { struct LP_priceinfo *basepp,*relpp; uint32_t now; int64_t price64; struct LP_pubkey_info *pubp; char str[65],fname[512]; FILE *fp; //printf("check PRICEFEED UPDATE.(%s/%s) %.8f %s\n",base,rel,price,bits256_str(str,pubkey)); @@ -1120,6 +1120,8 @@ void LP_pricefeedupdate(bits256 pubkey,char *base,char *rel,double price,char *u { if ( (LP_rand() % 1000) == 0 ) printf("PRICEFEED UPDATE.(%-6s/%6s) %12.8f %s %12.8f\n",base,rel,price,bits256_str(str,pubkey),1./price); + if ( unconfcredits > pubp->unconfcredits ) + pubp->unconfcredits = unconfcredits; pubp->timestamp = (uint32_t)time(NULL); LP_pubkey_update(pubp,basepp->ind,relpp->ind,price,balance,utxocoin,numrelutxos,minutxo,maxutxo); //pubp->depthinfo[basepp->ind][relpp->ind] = LP_depthinfo_compact(); diff --git a/iguana/exchanges/LP_signatures.c b/iguana/exchanges/LP_signatures.c index 80b1fb651..c73986f46 100644 --- a/iguana/exchanges/LP_signatures.c +++ b/iguana/exchanges/LP_signatures.c @@ -394,7 +394,7 @@ int32_t LP_price_sigadd(cJSON *item,uint32_t timestamp,bits256 priv,uint8_t *pub char *LP_pricepings(void *ctx,char *myipaddr,int32_t pubsock,char *base,char *rel,double price) { - struct iguana_info *basecoin,*relcoin; char pubsecpstr[67]; uint32_t numutxos,timestamp; uint64_t price64,balance,minsize,maxsize; bits256 zero; cJSON *reqjson; + struct iguana_info *basecoin,*relcoin,*kmd; struct LP_address *ap; char pubsecpstr[67]; uint32_t numutxos,timestamp; uint64_t price64,balance,minsize,maxsize; bits256 zero; cJSON *reqjson; reqjson = cJSON_CreateObject(); // LP_addsig if ( (basecoin= LP_coinfind(base)) != 0 && (relcoin= LP_coinfind(rel)) != 0 )//&& basecoin->electrum == 0 )//&& relcoin->electrum == 0 ) @@ -411,17 +411,16 @@ char *LP_pricepings(void *ctx,char *myipaddr,int32_t pubsock,char *base,char *re jaddnum(reqjson,"timestamp",timestamp); init_hexbytes_noT(pubsecpstr,G.LP_pubsecp,33); jaddstr(reqjson,"pubsecp",pubsecpstr); - //if ( (ap= LP_address(basecoin,basecoin->smartaddr)) != 0 ) + if ( (kmd= LP_coinfind("KMD")) != 0 && (ap= LP_address(kmd,kmd->smartaddr)) != 0 && ap->instantdex_credits != 0 ) + jaddnum(reqjson,"credits",dstr(ap->instantdex_credits)); + if ( (numutxos= LP_address_minmax(&balance,&minsize,&maxsize,basecoin,basecoin->smartaddr)) != 0 ) { - if ( (numutxos= LP_address_minmax(&balance,&minsize,&maxsize,basecoin,basecoin->smartaddr)) != 0 ) - { - //printf("send %s numutxos.%d balance %.8f min %.8f max %.8f\n",base,numutxos,dstr(balance),dstr(minsize),dstr(maxsize)); - jaddstr(reqjson,"utxocoin",base); - jaddnum(reqjson,"n",numutxos); - jaddnum(reqjson,"bal",dstr(balance)); - jaddnum(reqjson,"min",dstr(minsize)); - jaddnum(reqjson,"max",dstr(maxsize)); - } + //printf("send %s numutxos.%d balance %.8f min %.8f max %.8f\n",base,numutxos,dstr(balance),dstr(minsize),dstr(maxsize)); + jaddstr(reqjson,"utxocoin",base); + jaddnum(reqjson,"n",numutxos); + jaddnum(reqjson,"bal",dstr(balance)); + jaddnum(reqjson,"min",dstr(minsize)); + jaddnum(reqjson,"max",dstr(maxsize)); } LP_price_sigadd(reqjson,timestamp,G.LP_privkey,G.LP_pubsecp,G.LP_mypub25519,base,rel,price64); LP_reserved_msg(0,base,rel,zero,jprint(reqjson,1)); @@ -441,7 +440,7 @@ char *LP_postprice_recv(cJSON *argjson) if ( LP_price_sigcheck(juint(argjson,"timestamp"),jstr(argjson,"sig"),jstr(argjson,"pubsecp"),pubkey,base,rel,j64bits(argjson,"price64")) == 0 ) { //printf("call pricefeed update\n"); - LP_pricefeedupdate(pubkey,base,rel,price,jstr(argjson,"utxocoin"),jint(argjson,"n"),jdouble(argjson,"bal")*SATOSHIDEN,jdouble(argjson,"min")*SATOSHIDEN,jdouble(argjson,"max")*SATOSHIDEN); + LP_pricefeedupdate(pubkey,base,rel,price,jstr(argjson,"utxocoin"),jint(argjson,"n"),jdouble(argjson,"bal")*SATOSHIDEN,jdouble(argjson,"min")*SATOSHIDEN,jdouble(argjson,"max")*SATOSHIDEN,jdouble(argjson,"credits")*SATOSHIDEN); return(clonestr("{\"result\":\"success\"}")); } else @@ -665,6 +664,8 @@ void LP_query(void *ctx,char *myipaddr,int32_t mypubsock,char *method,struct LP_ jaddstr(reqjson,"method",method); if ( jobj(reqjson,"timestamp") == 0 ) jaddnum(reqjson,"timestamp",time(NULL)); + if ( strcmp(method,"connect") == 0 ) + jadd(reqjson,"proof",LP_instantdex_txidaddjson()); msg = jprint(reqjson,1); printf("QUERY.(%s)\n",msg); //if ( bits256_nonz(qp->srchash) == 0 || strcmp(method,"request") != 0 ) From 3be1f82a8fcf2c9387c09803b01780b269ee3382 Mon Sep 17 00:00:00 2001 From: jl777 Date: Tue, 28 Nov 2017 15:55:02 +0400 Subject: [PATCH 1324/1664] Test --- iguana/exchanges/LP_nativeDEX.c | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/iguana/exchanges/LP_nativeDEX.c b/iguana/exchanges/LP_nativeDEX.c index 88146e810..86f9069f4 100644 --- a/iguana/exchanges/LP_nativeDEX.c +++ b/iguana/exchanges/LP_nativeDEX.c @@ -660,7 +660,7 @@ int32_t LP_mainloop_iter(void *ctx,char *myipaddr,struct LP_peerinfo *mypeer,int HASH_ITER(hh,LP_coins,coin,ctmp) // firstrefht,firstscanht,lastscanht { now = (uint32_t)time(NULL); - if ( coin->inactive == 0 && didinstantdex == 0 && strcmp("KMD",coin->symbol) == 0 ) + if ( coin->inactive == 0 && coin->electrum == 0 && didinstantdex == 0 && strcmp("KMD",coin->symbol) == 0 ) { LP_instantdex_deposits(coin); didinstantdex = now; @@ -800,7 +800,7 @@ void LP_pubkeysloop(void *ctx) void LP_swapsloop(void *ctx) { - char *retstr; struct iguana_info *coin; + char *retstr; strcpy(LP_swapsloop_stats.name,"LP_swapsloop"); LP_swapsloop_stats.threshold = 605000.; sleep(50); @@ -810,8 +810,6 @@ void LP_swapsloop(void *ctx) if ( (retstr= basilisk_swapentry(0,0)) != 0 ) free(retstr); sleep(600); - if ( (coin= LP_coinfind("KMD")) != 0 ) - LP_instantdex_deposits(coin); } } From 731b23625277634eec023a9642fc9fe5229f13a8 Mon Sep 17 00:00:00 2001 From: jl777 Date: Tue, 28 Nov 2017 16:03:51 +0400 Subject: [PATCH 1325/1664] Test --- iguana/exchanges/LP_instantdex.c | 1 + iguana/exchanges/LP_ordermatch.c | 4 ++-- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/iguana/exchanges/LP_instantdex.c b/iguana/exchanges/LP_instantdex.c index 2a258af19..749d6d472 100644 --- a/iguana/exchanges/LP_instantdex.c +++ b/iguana/exchanges/LP_instantdex.c @@ -249,6 +249,7 @@ int64_t LP_instantdex_credit(int32_t dispflag,char *coinaddr,int64_t satoshis,in if ( time(NULL) < timestamp-60*3600 && (ap= LP_address(coin,coinaddr)) != 0 ) { ap->instantdex_credits += satoshis; + ap->didinstantdex = 1; 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); diff --git a/iguana/exchanges/LP_ordermatch.c b/iguana/exchanges/LP_ordermatch.c index 739ee4c28..ebd7c8130 100644 --- a/iguana/exchanges/LP_ordermatch.c +++ b/iguana/exchanges/LP_ordermatch.c @@ -1179,8 +1179,6 @@ int32_t LP_tradecommand(void *ctx,char *myipaddr,int32_t pubsock,cJSON *argjson, } if ( bits256_cmp(G.LP_mypub25519,Q.desthash) == 0 && bits256_cmp(G.LP_mypub25519,Q.srchash) != 0 ) { - if ( (proof= jarray(&num,argjson,"proof")) != 0 && num > 0 ) - LP_instantdex_proofcheck(Q.coinaddr,proof,num); if ( Qtrades == 0 ) { if ( Q.quotetime > time(NULL)-20 && LP_alice_eligible(Q.quotetime) > 0 ) @@ -1197,6 +1195,8 @@ int32_t LP_tradecommand(void *ctx,char *myipaddr,int32_t pubsock,cJSON *argjson, bestprice = LP_bob_competition(&counter,aliceid,qprice,1000); if ( bits256_cmp(G.LP_mypub25519,Q.desthash) == 0 && bits256_cmp(G.LP_mypub25519,Q.srchash) != 0 ) { + if ( (proof= jarray(&num,argjson,"proof")) != 0 && num > 0 ) + LP_instantdex_proofcheck(Q.coinaddr,proof,num); if ( Qtrades == 0 ) LP_trades_gotconnected(ctx,&Q,&Q2,jstr(argjson,"pair")); else LP_tradecommandQ(&Q,jstr(argjson,"pair"),LP_CONNECTED); From 79a69bb4a1e007d6cd5be2b5fd4b23591337629d Mon Sep 17 00:00:00 2001 From: jl777 Date: Tue, 28 Nov 2017 16:23:41 +0400 Subject: [PATCH 1326/1664] Test --- iguana/exchanges/LP_instantdex.c | 11 +++++------ iguana/exchanges/LP_ordermatch.c | 18 +++++++++--------- 2 files changed, 14 insertions(+), 15 deletions(-) diff --git a/iguana/exchanges/LP_instantdex.c b/iguana/exchanges/LP_instantdex.c index 749d6d472..6cd643c0f 100644 --- a/iguana/exchanges/LP_instantdex.c +++ b/iguana/exchanges/LP_instantdex.c @@ -41,7 +41,7 @@ void LP_instantdex_txidadd(bits256 txid) cJSON *array; int32_t i,n; char fname[1024],*filestr; FILE *fp; if ( (array= LP_instantdex_txidaddjson()) == 0 ) array = cJSON_CreateArray(); - if ( (n= cJSON_GetArraySize(array)) > 0 ) + if ( (n= cJSON_GetArraySize(array)) >= 0 ) { for (i=0; iinstantdex_credits += satoshis; ap->didinstantdex = 1; + if ( strcmp(coinaddr,coin->smartaddr) == 0 ) + LP_instantdex_txidadd(txid); 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); @@ -282,10 +284,7 @@ int64_t LP_instantdex_creditcalc(struct iguana_info *coin,int32_t dispflag,bits2 if ( (txobj= LP_gettxout(coin->symbol,p2shaddr,txid,0)) != 0 ) { free_json(txobj); - if ( LP_instantdex_credit(dispflag,destaddr,satoshis,weeki,p2shaddr) > 0 && strcmp(coin->symbol,"KMD") == 0 && strcmp(destaddr,coin->smartaddr) == 0 ) - { - LP_instantdex_txidadd(txid); - } + LP_instantdex_credit(dispflag,destaddr,satoshis,weeki,p2shaddr,txid); } } } diff --git a/iguana/exchanges/LP_ordermatch.c b/iguana/exchanges/LP_ordermatch.c index ebd7c8130..053e725bb 100644 --- a/iguana/exchanges/LP_ordermatch.c +++ b/iguana/exchanges/LP_ordermatch.c @@ -456,7 +456,7 @@ struct LP_utxoinfo *LP_address_myutxopair(struct LP_utxoinfo *butxo,int32_t iamb int32_t LP_connectstartbob(void *ctx,int32_t pubsock,char *base,char *rel,double price,struct LP_quoteinfo *qp) { - char pairstr[512]; cJSON *retjson; bits256 privkey; int32_t pair=-1,retval = -1,DEXselector = 0; struct basilisk_swap *swap; struct iguana_info *coin; + char pairstr[512]; cJSON *reqjson; bits256 privkey; int32_t pair=-1,retval = -1,DEXselector = 0; struct basilisk_swap *swap; struct iguana_info *coin; qp->quotetime = (uint32_t)time(NULL); if ( (coin= LP_coinfind(qp->srccoin)) == 0 ) { @@ -484,17 +484,18 @@ int32_t LP_connectstartbob(void *ctx,int32_t pubsock,char *base,char *rel,double //swap->utxo = utxo; if ( OS_thread_create(malloc(sizeof(pthread_t)),NULL,(void *)LP_bobloop,(void *)swap) == 0 ) { - retjson = LP_quotejson(qp); - jaddstr(retjson,"method","connected"); - jaddstr(retjson,"pair",pairstr); + reqjson = LP_quotejson(qp); + jaddstr(reqjson,"method","connected"); + jaddstr(reqjson,"pair",pairstr); + jadd(reqjson,"proof",LP_instantdex_txidaddjson()); char str[65]; printf("BOB pubsock.%d binds to %d (%s)\n",pubsock,pair,bits256_str(str,qp->desthash)); bits256 zero; memset(zero.bytes,0,sizeof(zero)); - LP_reserved_msg(1,base,rel,zero,jprint(retjson,0)); + LP_reserved_msg(1,base,rel,zero,jprint(reqjson,0)); //sleep(1); - //LP_reserved_msg(1,base,rel,qp->desthash,jprint(retjson,0)); - //LP_reserved_msg(0,base,rel,zero,jprint(retjson,0)); - free_json(retjson); + //LP_reserved_msg(1,base,rel,qp->desthash,jprint(reqjson,0)); + //LP_reserved_msg(0,base,rel,zero,jprint(reqjson,0)); + free_json(reqjson); retval = 0; } else printf("error launching swaploop\n"); } else printf("couldnt bind to any port %s\n",pairstr); @@ -887,7 +888,6 @@ struct LP_quoteinfo *LP_trades_gotrequest(void *ctx,struct LP_quoteinfo *qp,stru if ( LP_allocated(qp->txid,qp->vout) == 0 && LP_allocated(qp->txid2,qp->vout2) == 0 ) { reqjson = LP_quotejson(qp); - jadd(reqjson,"proof",LP_instantdex_txidaddjson()); LP_unavailableset(qp->txid,qp->vout,qp->timestamp + LP_RESERVETIME,qp->desthash); LP_unavailableset(qp->txid2,qp->vout2,qp->timestamp + LP_RESERVETIME,qp->desthash); if ( qp->quotetime == 0 ) From a521623d7c0e312adc52fba976cb6f8067d658f9 Mon Sep 17 00:00:00 2001 From: jl777 Date: Tue, 28 Nov 2017 16:27:56 +0400 Subject: [PATCH 1327/1664] Test --- iguana/exchanges/LP_utxo.c | 2 -- 1 file changed, 2 deletions(-) diff --git a/iguana/exchanges/LP_utxo.c b/iguana/exchanges/LP_utxo.c index 25f4301b9..99d4f13a2 100644 --- a/iguana/exchanges/LP_utxo.c +++ b/iguana/exchanges/LP_utxo.c @@ -951,8 +951,6 @@ int32_t LP_iseligible(uint64_t *valp,uint64_t *val2p,int32_t iambob,char *symbol { if ( bypass == 0 && strcmp(destaddr,destaddr2) != 0 ) printf("mismatched %s destaddr (%s) vs (%s)\n",symbol,destaddr,destaddr2); - else if ( bypass == 0 && ((iambob == 0 && val2 > val) || (iambob != 0 && val2 <= satoshis)) ) - printf("iambob.%d ineligible due to offsides: val %.8f and val2 %.8f vs %.8f diff %lld\n",iambob,dstr(val),dstr(val2),dstr(satoshis),(long long)(val2 - val)); else { *valp = val; From 2ca84b6c82629a2eeeb01882fe41f6a4747e40d7 Mon Sep 17 00:00:00 2001 From: jl777 Date: Tue, 28 Nov 2017 16:31:06 +0400 Subject: [PATCH 1328/1664] Test --- iguana/exchanges/LP_swap.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/iguana/exchanges/LP_swap.c b/iguana/exchanges/LP_swap.c index 4a7f07f7f..adb36aad9 100644 --- a/iguana/exchanges/LP_swap.c +++ b/iguana/exchanges/LP_swap.c @@ -250,7 +250,7 @@ int32_t LP_pubkeys_verify(struct basilisk_swap *swap,uint8_t *data,int32_t datal 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("mutually trusted swap, 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); From d2462f91faf5eba456051766b9878ccc357d5c69 Mon Sep 17 00:00:00 2001 From: jl777 Date: Tue, 28 Nov 2017 16:33:25 +0400 Subject: [PATCH 1329/1664] Test --- iguana/exchanges/LP_nativeDEX.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/iguana/exchanges/LP_nativeDEX.c b/iguana/exchanges/LP_nativeDEX.c index 86f9069f4..91a6150d5 100644 --- a/iguana/exchanges/LP_nativeDEX.c +++ b/iguana/exchanges/LP_nativeDEX.c @@ -660,7 +660,7 @@ int32_t LP_mainloop_iter(void *ctx,char *myipaddr,struct LP_peerinfo *mypeer,int HASH_ITER(hh,LP_coins,coin,ctmp) // firstrefht,firstscanht,lastscanht { now = (uint32_t)time(NULL); - if ( coin->inactive == 0 && coin->electrum == 0 && didinstantdex == 0 && strcmp("KMD",coin->symbol) == 0 ) + if ( 0 && coin->inactive == 0 && coin->electrum == 0 && didinstantdex == 0 && strcmp("KMD",coin->symbol) == 0 ) { LP_instantdex_deposits(coin); didinstantdex = now; From c778ed10be8c9d9f492faf5bea58e95250d0fe57 Mon Sep 17 00:00:00 2001 From: jl777 Date: Tue, 28 Nov 2017 17:10:31 +0400 Subject: [PATCH 1330/1664] Test --- iguana/exchanges/LP_instantdex.c | 4 ++-- iguana/exchanges/LP_nativeDEX.c | 2 -- iguana/exchanges/LP_ordermatch.c | 2 ++ 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/iguana/exchanges/LP_instantdex.c b/iguana/exchanges/LP_instantdex.c index 6cd643c0f..616376a3b 100644 --- a/iguana/exchanges/LP_instantdex.c +++ b/iguana/exchanges/LP_instantdex.c @@ -297,7 +297,7 @@ int64_t LP_instantdex_creditcalc(struct iguana_info *coin,int32_t dispflag,bits2 void LP_instantdex_proofcheck(char *coinaddr,cJSON *proof,int32_t num) { uint8_t rmd160[20],addrtype; int32_t i; char othersmartaddr[64]; struct iguana_info *coin; struct LP_address *ap = 0; - if ( (coin= LP_coinfind("KMD")) != 0 && coin->electrum != 0 ) + if ( (coin= LP_coinfind("KMD")) != 0 ) { bitcoin_addr2rmd160(0,&addrtype,rmd160,coinaddr); bitcoin_address(othersmartaddr,0,60,rmd160,20); @@ -308,7 +308,7 @@ void LP_instantdex_proofcheck(char *coinaddr,cJSON *proof,int32_t num) LP_instantdex_creditcalc(coin,1,jbits256i(proof,i),othersmartaddr); ap->didinstantdex = 1; printf("validated instantdex %s.[%d] proof.(%s)\n",othersmartaddr,num,jprint(proof,0)); - } + } 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); } } diff --git a/iguana/exchanges/LP_nativeDEX.c b/iguana/exchanges/LP_nativeDEX.c index 91a6150d5..63c9e5705 100644 --- a/iguana/exchanges/LP_nativeDEX.c +++ b/iguana/exchanges/LP_nativeDEX.c @@ -17,9 +17,7 @@ // LP_nativeDEX.c // marketmaker // -// optimize electrum swap // big BTC swaps -// electrum dynamic trust over 1000 tx // https://github.com/bitcoin/bips/blob/master/bip-0143.mediawiki for signing BCH/BTG // // cancel bid/ask diff --git a/iguana/exchanges/LP_ordermatch.c b/iguana/exchanges/LP_ordermatch.c index 053e725bb..2643b7c2a 100644 --- a/iguana/exchanges/LP_ordermatch.c +++ b/iguana/exchanges/LP_ordermatch.c @@ -1195,6 +1195,7 @@ int32_t LP_tradecommand(void *ctx,char *myipaddr,int32_t pubsock,cJSON *argjson, bestprice = LP_bob_competition(&counter,aliceid,qprice,1000); if ( bits256_cmp(G.LP_mypub25519,Q.desthash) == 0 && bits256_cmp(G.LP_mypub25519,Q.srchash) != 0 ) { + printf("CONNECTED.(%s)\n",jprint(argjson,0)); if ( (proof= jarray(&num,argjson,"proof")) != 0 && num > 0 ) LP_instantdex_proofcheck(Q.coinaddr,proof,num); if ( Qtrades == 0 ) @@ -1227,6 +1228,7 @@ int32_t LP_tradecommand(void *ctx,char *myipaddr,int32_t pubsock,cJSON *argjson, else if ( strcmp(method,"connect") == 0 ) { LP_bob_competition(&counter,aliceid,qprice,1000); + printf("CONNECT.(%s)\n",jprint(argjson,0)); if ( (proof= jarray(&num,argjson,"proof")) != 0 && num > 0 ) LP_instantdex_proofcheck(Q.coinaddr,proof,num); if ( Qtrades == 0 ) From 630c4b24b3061bc690d9a202c13fb6fc74c96996 Mon Sep 17 00:00:00 2001 From: jl777 Date: Tue, 28 Nov 2017 17:17:53 +0400 Subject: [PATCH 1331/1664] Test --- iguana/exchanges/LP_ordermatch.c | 4 ++-- iguana/exchanges/LP_stats.c | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/iguana/exchanges/LP_ordermatch.c b/iguana/exchanges/LP_ordermatch.c index 2643b7c2a..d6f32777c 100644 --- a/iguana/exchanges/LP_ordermatch.c +++ b/iguana/exchanges/LP_ordermatch.c @@ -1195,7 +1195,7 @@ int32_t LP_tradecommand(void *ctx,char *myipaddr,int32_t pubsock,cJSON *argjson, bestprice = LP_bob_competition(&counter,aliceid,qprice,1000); if ( bits256_cmp(G.LP_mypub25519,Q.desthash) == 0 && bits256_cmp(G.LP_mypub25519,Q.srchash) != 0 ) { - printf("CONNECTED.(%s)\n",jprint(argjson,0)); + //printf("CONNECTED.(%s)\n",jprint(argjson,0)); if ( (proof= jarray(&num,argjson,"proof")) != 0 && num > 0 ) LP_instantdex_proofcheck(Q.coinaddr,proof,num); if ( Qtrades == 0 ) @@ -1230,7 +1230,7 @@ int32_t LP_tradecommand(void *ctx,char *myipaddr,int32_t pubsock,cJSON *argjson, LP_bob_competition(&counter,aliceid,qprice,1000); printf("CONNECT.(%s)\n",jprint(argjson,0)); if ( (proof= jarray(&num,argjson,"proof")) != 0 && num > 0 ) - LP_instantdex_proofcheck(Q.coinaddr,proof,num); + LP_instantdex_proofcheck(Q.destaddr,proof,num); if ( Qtrades == 0 ) LP_trades_gotconnect(ctx,&Q,&Q2,jstr(argjson,"pair")); else LP_tradecommandQ(&Q,jstr(argjson,"pair"),LP_CONNECT); diff --git a/iguana/exchanges/LP_stats.c b/iguana/exchanges/LP_stats.c index 8ef41afb7..932584b43 100644 --- a/iguana/exchanges/LP_stats.c +++ b/iguana/exchanges/LP_stats.c @@ -197,7 +197,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 ( 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); } From 0a239a860e28172fd241b7bf5ff8a81e5ee67be3 Mon Sep 17 00:00:00 2001 From: jl777 Date: Tue, 28 Nov 2017 17:20:36 +0400 Subject: [PATCH 1332/1664] Test --- iguana/exchanges/LP_ordermatch.c | 17 +++++++++-------- 1 file changed, 9 insertions(+), 8 deletions(-) diff --git a/iguana/exchanges/LP_ordermatch.c b/iguana/exchanges/LP_ordermatch.c index d6f32777c..be3df25be 100644 --- a/iguana/exchanges/LP_ordermatch.c +++ b/iguana/exchanges/LP_ordermatch.c @@ -932,8 +932,6 @@ struct LP_quoteinfo *LP_trades_gotconnect(void *ctx,struct LP_quoteinfo *qp,stru return(0); if ( (myprice= LP_trades_bobprice(&bid,&ask,qp)) == 0. ) return(0); - if ( bits256_cmp(G.LP_mypub25519,qp->srchash) != 0 || bits256_cmp(G.LP_mypub25519,qp->desthash) == 0 ) - return(0); if ( (qprice= LP_trades_pricevalidate(qp,coin,myprice)) < 0. ) return(0); if ( LP_reservation_check(qp->txid,qp->vout,qp->desthash) == 0 && LP_reservation_check(qp->txid2,qp->vout2,qp->desthash) == 0 ) @@ -1228,12 +1226,15 @@ int32_t LP_tradecommand(void *ctx,char *myipaddr,int32_t pubsock,cJSON *argjson, else if ( strcmp(method,"connect") == 0 ) { LP_bob_competition(&counter,aliceid,qprice,1000); - printf("CONNECT.(%s)\n",jprint(argjson,0)); - if ( (proof= jarray(&num,argjson,"proof")) != 0 && num > 0 ) - LP_instantdex_proofcheck(Q.destaddr,proof,num); - if ( Qtrades == 0 ) - LP_trades_gotconnect(ctx,&Q,&Q2,jstr(argjson,"pair")); - else LP_tradecommandQ(&Q,jstr(argjson,"pair"),LP_CONNECT); + if ( bits256_cmp(G.LP_mypub25519,Q.srchash) == 0 && bits256_cmp(G.LP_mypub25519,Q.desthash) != 0 ) + { + printf("CONNECT.(%s)\n",jprint(argjson,0)); + if ( (proof= jarray(&num,argjson,"proof")) != 0 && num > 0 ) + LP_instantdex_proofcheck(Q.destaddr,proof,num); + if ( Qtrades == 0 ) + LP_trades_gotconnect(ctx,&Q,&Q2,jstr(argjson,"pair")); + else LP_tradecommandQ(&Q,jstr(argjson,"pair"),LP_CONNECT); + } } return(retval); } From 67a033bbbcc8593bf586b1da94b482afb5c6514d Mon Sep 17 00:00:00 2001 From: jl777 Date: Tue, 28 Nov 2017 17:30:42 +0400 Subject: [PATCH 1333/1664] Test --- iguana/exchanges/LP_instantdex.c | 6 ++++-- iguana/exchanges/LP_nativeDEX.c | 4 +++- iguana/exchanges/LP_ordermatch.c | 2 +- 3 files changed, 8 insertions(+), 4 deletions(-) diff --git a/iguana/exchanges/LP_instantdex.c b/iguana/exchanges/LP_instantdex.c index 616376a3b..a72bea943 100644 --- a/iguana/exchanges/LP_instantdex.c +++ b/iguana/exchanges/LP_instantdex.c @@ -307,11 +307,12 @@ void LP_instantdex_proofcheck(char *coinaddr,cJSON *proof,int32_t num) for (i=0; ididinstantdex = 1; - printf("validated instantdex %s.[%d] proof.(%s)\n",othersmartaddr,num,jprint(proof,0)); + printf("validated instantdex %s.[%d] proof.(%s) credits %.8f\n",othersmartaddr,num,jprint(proof,0),dstr(ap->instantdex_credits)); } 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); } } +#ifdef bruteforce void LP_instantdex_deposits(struct iguana_info *coin) { static int dispflag = 1; @@ -341,6 +342,7 @@ void LP_instantdex_deposits(struct iguana_info *coin) } dispflag = 0; } +#endif int64_t LP_dynamictrust(bits256 pubkey,int64_t kmdvalue) { @@ -360,7 +362,7 @@ int64_t LP_dynamictrust(bits256 pubkey,int64_t kmdvalue) if ( (sp= ptr->swap) != 0 && sp->finished == 0 && sp->expired == 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)); + 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)); } diff --git a/iguana/exchanges/LP_nativeDEX.c b/iguana/exchanges/LP_nativeDEX.c index 63c9e5705..0cf1bd6eb 100644 --- a/iguana/exchanges/LP_nativeDEX.c +++ b/iguana/exchanges/LP_nativeDEX.c @@ -658,11 +658,13 @@ int32_t LP_mainloop_iter(void *ctx,char *myipaddr,struct LP_peerinfo *mypeer,int HASH_ITER(hh,LP_coins,coin,ctmp) // firstrefht,firstscanht,lastscanht { now = (uint32_t)time(NULL); - if ( 0 && coin->inactive == 0 && coin->electrum == 0 && didinstantdex == 0 && strcmp("KMD",coin->symbol) == 0 ) +#ifdef bruteforce + if ( IAMLP != 0 && coin->inactive == 0 && coin->electrum == 0 && didinstantdex == 0 && strcmp("KMD",coin->symbol) == 0 ) { LP_instantdex_deposits(coin); didinstantdex = now; } +#endif 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); diff --git a/iguana/exchanges/LP_ordermatch.c b/iguana/exchanges/LP_ordermatch.c index be3df25be..42228581d 100644 --- a/iguana/exchanges/LP_ordermatch.c +++ b/iguana/exchanges/LP_ordermatch.c @@ -1228,7 +1228,7 @@ int32_t LP_tradecommand(void *ctx,char *myipaddr,int32_t pubsock,cJSON *argjson, LP_bob_competition(&counter,aliceid,qprice,1000); if ( bits256_cmp(G.LP_mypub25519,Q.srchash) == 0 && bits256_cmp(G.LP_mypub25519,Q.desthash) != 0 ) { - printf("CONNECT.(%s)\n",jprint(argjson,0)); + //printf("CONNECT.(%s)\n",jprint(argjson,0)); if ( (proof= jarray(&num,argjson,"proof")) != 0 && num > 0 ) LP_instantdex_proofcheck(Q.destaddr,proof,num); if ( Qtrades == 0 ) From 36e2a94516f1b656b3a032251bb6d99c83d7ac7e Mon Sep 17 00:00:00 2001 From: jl777 Date: Tue, 28 Nov 2017 17:44:37 +0400 Subject: [PATCH 1334/1664] Test --- iguana/exchanges/LP_instantdex.c | 2 +- iguana/exchanges/LP_nativeDEX.c | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/iguana/exchanges/LP_instantdex.c b/iguana/exchanges/LP_instantdex.c index a72bea943..54b272813 100644 --- a/iguana/exchanges/LP_instantdex.c +++ b/iguana/exchanges/LP_instantdex.c @@ -362,7 +362,7 @@ int64_t LP_dynamictrust(bits256 pubkey,int64_t kmdvalue) if ( (sp= ptr->swap) != 0 && sp->finished == 0 && sp->expired == 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)); + //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)); } diff --git a/iguana/exchanges/LP_nativeDEX.c b/iguana/exchanges/LP_nativeDEX.c index 0cf1bd6eb..4301b196a 100644 --- a/iguana/exchanges/LP_nativeDEX.c +++ b/iguana/exchanges/LP_nativeDEX.c @@ -649,7 +649,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; + static uint32_t counter;//,didinstantdex; struct iguana_info *coin,*ctmp; char *origipaddr; uint32_t now; int32_t height,nonz = 0; if ( (origipaddr= myipaddr) == 0 ) origipaddr = "127.0.0.1"; From e2c0e7bbc54ffa78171294a7f2b01f29fa7f106b Mon Sep 17 00:00:00 2001 From: jl777 Date: Tue, 28 Nov 2017 17:55:17 +0400 Subject: [PATCH 1335/1664] Test --- iguana/exchanges/LP_ordermatch.c | 20 ++++++++++++++------ 1 file changed, 14 insertions(+), 6 deletions(-) diff --git a/iguana/exchanges/LP_ordermatch.c b/iguana/exchanges/LP_ordermatch.c index 42228581d..52716db30 100644 --- a/iguana/exchanges/LP_ordermatch.c +++ b/iguana/exchanges/LP_ordermatch.c @@ -739,13 +739,21 @@ double LP_trades_alicevalidate(void *ctx,struct LP_quoteinfo *qp) } if ( LP_validSPV(qp->srccoin,qp->coinaddr,qp->txid,qp->vout) < 0 ) { - printf("%s src %s failed SPV check\n",qp->srccoin,bits256_str(str,qp->txid)); - return(-44); + sleep(1); + if ( LP_validSPV(qp->srccoin,qp->coinaddr,qp->txid,qp->vout) < 0 ) + { + printf("LP_trades_alicevalidate %s src %s failed SPV check\n",qp->srccoin,bits256_str(str,qp->txid)); + return(-44); + } } else if ( LP_validSPV(qp->srccoin,qp->coinaddr,qp->txid2,qp->vout2) < 0 ) { - printf("%s src2 %s failed SPV check\n",qp->srccoin,bits256_str(str,qp->txid2)); - return(-55); + sleep(1); + if ( LP_validSPV(qp->srccoin,qp->coinaddr,qp->txid2,qp->vout2) < 0 ) + { + printf("LP_trades_alicevalidate %s src2 %s failed SPV check\n",qp->srccoin,bits256_str(str,qp->txid2)); + return(-55); + } } return(qprice); } @@ -780,12 +788,12 @@ double LP_trades_bobprice(double *bidp,double *askp,struct LP_quoteinfo *qp) //printf("MYPRICE %s/%s %.8f vs qprice %.8f\n",qp->srccoin,qp->destcoin,price,(double)qp->destsatoshis/qp->satoshis); if ( LP_validSPV(qp->destcoin,qp->destaddr,qp->desttxid,qp->destvout) < 0 ) { - printf("%s dest %s failed SPV check\n",qp->destcoin,bits256_str(str,qp->desttxid)); + printf("LP_trades_bobprice %s dest %s failed SPV check\n",qp->destcoin,bits256_str(str,qp->desttxid)); return(0.); } else if (LP_validSPV(qp->destcoin,qp->destaddr,qp->feetxid,qp->feevout) < 0 ) { - printf("%s dexfee %s failed SPV check\n",qp->destcoin,bits256_str(str,qp->feetxid)); + printf("LP_trades_bobprice %s dexfee %s failed SPV check\n",qp->destcoin,bits256_str(str,qp->feetxid)); return(0.); } return(*askp); From 13524c314e4829908036dbc60183e2b93c8914f5 Mon Sep 17 00:00:00 2001 From: jl777 Date: Tue, 28 Nov 2017 18:03:30 +0400 Subject: [PATCH 1336/1664] Test --- iguana/exchanges/LP_instantdex.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/iguana/exchanges/LP_instantdex.c b/iguana/exchanges/LP_instantdex.c index 54b272813..181078b4f 100644 --- a/iguana/exchanges/LP_instantdex.c +++ b/iguana/exchanges/LP_instantdex.c @@ -307,7 +307,8 @@ void LP_instantdex_proofcheck(char *coinaddr,cJSON *proof,int32_t num) for (i=0; ididinstantdex = 1; - printf("validated instantdex %s.[%d] proof.(%s) credits %.8f\n",othersmartaddr,num,jprint(proof,0),dstr(ap->instantdex_credits)); + if ( ap->instantdex_credits > 0 ) + printf("validated instantdex %s.[%d] proof.(%s) credits %.8f\n",othersmartaddr,num,jprint(proof,0),dstr(ap->instantdex_credits)); } 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); } } From aaab883ea35c28a0683d34bd4943ac5e9291a798 Mon Sep 17 00:00:00 2001 From: jl777 Date: Tue, 28 Nov 2017 18:23:55 +0400 Subject: [PATCH 1337/1664] Test --- iguana/exchanges/LP_instantdex.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/iguana/exchanges/LP_instantdex.c b/iguana/exchanges/LP_instantdex.c index 181078b4f..c7c627d27 100644 --- a/iguana/exchanges/LP_instantdex.c +++ b/iguana/exchanges/LP_instantdex.c @@ -301,7 +301,7 @@ void 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 && ap->didinstantdex == 0 ) + if ((ap= LP_address(coin,othersmartaddr)) != 0 && (coin->electrum == 0 || ap->didinstantdex == 0) ) { ap->instantdex_credits = 0; for (i=0; i Date: Tue, 28 Nov 2017 18:46:35 +0400 Subject: [PATCH 1338/1664] Test --- iguana/exchanges/LP_ordermatch.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/iguana/exchanges/LP_ordermatch.c b/iguana/exchanges/LP_ordermatch.c index 52716db30..5fd7137c6 100644 --- a/iguana/exchanges/LP_ordermatch.c +++ b/iguana/exchanges/LP_ordermatch.c @@ -712,12 +712,14 @@ int32_t LP_validSPV(char *symbol,char *coinaddr,bits256 txid,int32_t vout) } if ( (up= LP_address_utxofind(coin,coinaddr,txid,vout)) != 0 ) { + if ( up->SPV > 0 ) + return(0); if ( up->SPV < 0 ) return(-1); if ( (backupep= ep->prev) == 0 ) backupep = ep; up->SPV = LP_merkleproof(coin,coinaddr,backupep,up->U.txid,up->U.height); - if ( up->SPV <= 0 ) + if ( up->SPV < 0 ) return(-1); } } From 6d31692081e0f861ca7c3da246b57ed9719de796 Mon Sep 17 00:00:00 2001 From: jl777 Date: Tue, 28 Nov 2017 18:52:46 +0400 Subject: [PATCH 1339/1664] Test --- iguana/exchanges/LP_ordermatch.c | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/iguana/exchanges/LP_ordermatch.c b/iguana/exchanges/LP_ordermatch.c index 5fd7137c6..f0edfc63b 100644 --- a/iguana/exchanges/LP_ordermatch.c +++ b/iguana/exchanges/LP_ordermatch.c @@ -1284,8 +1284,12 @@ char *LP_autobuy(void *ctx,char *myipaddr,int32_t mypubsock,char *base,char *rel timeout = 1.5*LP_AUTOTRADE_TIMEOUT; } if ( time(NULL) < Alice_expiration ) - return(clonestr("{\"error\":\"only one pending request at a time\"}")); - else LP_alicequery_clear(); + { + cJSON *retjson = cJSON_CreateObject(); + jaddstr(retjson,"error","only one pending request at a time"); + jaddnum(retjson,"wait",Alice_expiration-time(NULL)); + return(jprint(retjson,1)); + } else LP_alicequery_clear(); if ( maxprice <= 0. || relvolume <= 0. || LP_priceinfofind(base) == 0 || LP_priceinfofind(rel) == 0 ) return(clonestr("{\"error\":\"invalid parameter\"}")); if ( strcmp("BTC",rel) == 0 ) From 9f2095141e7559b19216d189cc84515a93498db6 Mon Sep 17 00:00:00 2001 From: jl777 Date: Tue, 28 Nov 2017 23:29:12 +0400 Subject: [PATCH 1340/1664] Test --- iguana/exchanges/LP_ordermatch.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/iguana/exchanges/LP_ordermatch.c b/iguana/exchanges/LP_ordermatch.c index f0edfc63b..5d7412c7e 100644 --- a/iguana/exchanges/LP_ordermatch.c +++ b/iguana/exchanges/LP_ordermatch.c @@ -32,7 +32,7 @@ double LP_bob_competition(int32_t *counterp,uint64_t aliceid,double price,int32_ { if ( Bob_competition[i].aliceid == aliceid ) { - if ( now > Bob_competition[i].starttime+LP_AUTOTRADE_TIMEOUT ) + if ( counter < 0 || now > Bob_competition[i].starttime+LP_AUTOTRADE_TIMEOUT ) { //printf("aliceid.%llu expired\n",(long long)aliceid); Bob_competition[i].bestprice = 0.; @@ -1229,6 +1229,7 @@ int32_t LP_tradecommand(void *ctx,char *myipaddr,int32_t pubsock,cJSON *argjson, } if ( strcmp(method,"request") == 0 ) { + bestprice = LP_bob_competition(&counter,aliceid,qprice,-1); if ( Qtrades == 0 ) LP_trades_gotrequest(ctx,&Q,&Q2,jstr(argjson,"pair")); else LP_tradecommandQ(&Q,jstr(argjson,"pair"),LP_REQUEST); From 5c36de1ebd7f11711a0e84feea82b6948849adb0 Mon Sep 17 00:00:00 2001 From: jl777 Date: Tue, 28 Nov 2017 23:30:15 +0400 Subject: [PATCH 1341/1664] Test --- iguana/exchanges/LP_stats.c | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/iguana/exchanges/LP_stats.c b/iguana/exchanges/LP_stats.c index 932584b43..e460c1c6c 100644 --- a/iguana/exchanges/LP_stats.c +++ b/iguana/exchanges/LP_stats.c @@ -254,7 +254,11 @@ int32_t LP_statslog_parsequote(char *method,cJSON *lineobj) } } if ( flag == 0 ) - printf("unexpected.%d tradestatus aliceid.%llu requestid.%u quoteid.%u\n",unexpected++,(long long)aliceid,requestid,quoteid);//,jprint(lineobj,0)); + { + static uint32_t counter; + if ( counter++ < 3 ) + printf("unexpected.%d tradestatus aliceid.%llu requestid.%u quoteid.%u\n",unexpected++,(long long)aliceid,requestid,quoteid);//,jprint(lineobj,0)); + } return(0); } if ( LP_quoteparse(&Q,lineobj) < 0 ) From f5c57061237ff8f2be75701036fe37da7a3c04dc Mon Sep 17 00:00:00 2001 From: jl777 Date: Tue, 28 Nov 2017 23:54:23 +0400 Subject: [PATCH 1342/1664] Test --- iguana/exchanges/LP_instantdex.c | 2 +- iguana/exchanges/LP_ordermatch.c | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/iguana/exchanges/LP_instantdex.c b/iguana/exchanges/LP_instantdex.c index c7c627d27..4f20141f7 100644 --- a/iguana/exchanges/LP_instantdex.c +++ b/iguana/exchanges/LP_instantdex.c @@ -307,7 +307,7 @@ void LP_instantdex_proofcheck(char *coinaddr,cJSON *proof,int32_t num) for (i=0; ididinstantdex = 1; - if ( ap->instantdex_credits > 0 ) + //if ( ap->instantdex_credits > 0 ) printf("validated instantdex %s.[%d] proof.(%s) credits %.8f\n",othersmartaddr,num,jprint(proof,0),dstr(ap->instantdex_credits)); } 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); } diff --git a/iguana/exchanges/LP_ordermatch.c b/iguana/exchanges/LP_ordermatch.c index 5d7412c7e..43f64946d 100644 --- a/iguana/exchanges/LP_ordermatch.c +++ b/iguana/exchanges/LP_ordermatch.c @@ -1239,7 +1239,7 @@ int32_t LP_tradecommand(void *ctx,char *myipaddr,int32_t pubsock,cJSON *argjson, LP_bob_competition(&counter,aliceid,qprice,1000); if ( bits256_cmp(G.LP_mypub25519,Q.srchash) == 0 && bits256_cmp(G.LP_mypub25519,Q.desthash) != 0 ) { - //printf("CONNECT.(%s)\n",jprint(argjson,0)); + printf("CONNECT.(%s)\n",jprint(argjson,0)); if ( (proof= jarray(&num,argjson,"proof")) != 0 && num > 0 ) LP_instantdex_proofcheck(Q.destaddr,proof,num); if ( Qtrades == 0 ) From 53ef2db389f4ab897b4705ad4680535ecc4070ad Mon Sep 17 00:00:00 2001 From: jl777 Date: Wed, 29 Nov 2017 00:51:50 +0400 Subject: [PATCH 1343/1664] Test --- iguana/exchanges/LP_nativeDEX.c | 2 ++ iguana/exchanges/LP_swap.c | 2 +- 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/iguana/exchanges/LP_nativeDEX.c b/iguana/exchanges/LP_nativeDEX.c index 4301b196a..7b3cd08d9 100644 --- a/iguana/exchanges/LP_nativeDEX.c +++ b/iguana/exchanges/LP_nativeDEX.c @@ -17,8 +17,10 @@ // LP_nativeDEX.c // marketmaker // +// ordermatch exact timestamp // big BTC swaps // https://github.com/bitcoin/bips/blob/master/bip-0143.mediawiki for signing BCH/BTG +// prune expired/spent deposits // // cancel bid/ask // portfolio: diff --git a/iguana/exchanges/LP_swap.c b/iguana/exchanges/LP_swap.c index adb36aad9..03a821fca 100644 --- a/iguana/exchanges/LP_swap.c +++ b/iguana/exchanges/LP_swap.c @@ -1101,7 +1101,7 @@ struct basilisk_swap *bitcoin_swapinit(bits256 privkey,uint8_t *pubkey33,bits256 swap->I.bobinsurance = LP_MIN_TXFEE; if ( (swap->I.aliceinsurance= (swap->I.alicesatoshis / INSTANTDEX_INSURANCEDIV)) < LP_MIN_TXFEE ) swap->I.aliceinsurance = LP_MIN_TXFEE; - swap->I.started = (uint32_t)time(NULL); + swap->I.started = qp->timestamp;//(uint32_t)time(NULL); swap->I.expiration = swap->I.req.timestamp + swap->I.putduration + swap->I.callduration; OS_randombytes((uint8_t *)&swap->I.choosei,sizeof(swap->I.choosei)); if ( swap->I.choosei < 0 ) From a772ffb2125ccc92720a2d8e68e2e7701238d0fc Mon Sep 17 00:00:00 2001 From: jl777 Date: Wed, 29 Nov 2017 01:04:37 +0400 Subject: [PATCH 1344/1664] Test --- iguana/exchanges/LP_utxo.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/iguana/exchanges/LP_utxo.c b/iguana/exchanges/LP_utxo.c index 99d4f13a2..6b743fbd2 100644 --- a/iguana/exchanges/LP_utxo.c +++ b/iguana/exchanges/LP_utxo.c @@ -804,7 +804,7 @@ int32_t LP_numconfirms(char *symbol,char *coinaddr,bits256 txid,int32_t vout,int } else if ( mempool != 0 && LP_mempoolscan(symbol,txid) >= 0 ) numconfirms = 0; - else if ( (txobj= LP_gettx(symbol,txid,0)) != 0 ) + else if ( (txobj= LP_gettx(symbol,txid,1)) != 0 ) { numconfirms = jint(txobj,"confirmations"); free_json(txobj); From 7245f7cb5e1ccf784e635885b0ac0c3dfb2aebc3 Mon Sep 17 00:00:00 2001 From: jl777 Date: Wed, 29 Nov 2017 01:05:49 +0400 Subject: [PATCH 1345/1664] Test --- iguana/exchanges/LP_swap.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/iguana/exchanges/LP_swap.c b/iguana/exchanges/LP_swap.c index 03a821fca..fe905c424 100644 --- a/iguana/exchanges/LP_swap.c +++ b/iguana/exchanges/LP_swap.c @@ -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 ( (retstr= basilisk_swapentry(requestid,quoteid)) != 0 ) + if ( 0 && (retstr= basilisk_swapentry(requestid,quoteid)) != 0 ) { printf("second call.(%s)\n",retstr); free(retstr); From d972ba7c50b255aa187af221bd7792bf049126de Mon Sep 17 00:00:00 2001 From: jl777 Date: Wed, 29 Nov 2017 15:52:03 +0400 Subject: [PATCH 1346/1664] Test --- iguana/exchanges/LP_bitcoin.c | 92 +++++++++++++++++++++---------- iguana/exchanges/LP_commands.c | 8 ++- iguana/exchanges/LP_include.h | 11 +++- iguana/exchanges/LP_instantdex.c | 38 ++++++------- iguana/exchanges/LP_nativeDEX.c | 16 ++---- iguana/exchanges/LP_transaction.c | 5 +- iguana/exchanges/LP_utxo.c | 17 ++++++ iguana/exchanges/install | 2 +- 8 files changed, 123 insertions(+), 66 deletions(-) diff --git a/iguana/exchanges/LP_bitcoin.c b/iguana/exchanges/LP_bitcoin.c index d76293234..88715631d 100644 --- a/iguana/exchanges/LP_bitcoin.c +++ b/iguana/exchanges/LP_bitcoin.c @@ -3274,7 +3274,7 @@ int32_t iguana_vinarray_check(cJSON *vinarray,bits256 txid,int32_t vout) int32_t iguana_rwmsgtx(char *symbol,uint8_t taddr,uint8_t pubtype,uint8_t p2shtype,uint8_t isPoS,int32_t height,int32_t rwflag,cJSON *json,uint8_t *serialized,int32_t maxsize,struct iguana_msgtx *msg,bits256 *txidp,char *vpnstr,uint8_t *extraspace,int32_t extralen,cJSON *vins,int32_t suppress_pubkeys,int32_t zcash); -bits256 bitcoin_sigtxid(char *symbol,uint8_t taddr,uint8_t pubtype,uint8_t p2shtype,uint8_t isPoS,int32_t height,uint8_t *serialized,int32_t maxlen,struct iguana_msgtx *msgtx,int32_t vini,uint8_t *spendscript,int32_t spendlen,uint32_t hashtype,char *vpnstr,int32_t suppress_pubkeys,int32_t zcash) +bits256 bitcoin_sigtxid(char *symbol,uint8_t taddr,uint8_t pubtype,uint8_t p2shtype,uint8_t isPoS,int32_t height,uint8_t *serialized,int32_t maxlen,struct iguana_msgtx *msgtx,int32_t vini,uint8_t *spendscript,int32_t spendlen,uint64_t spendamount,uint32_t hashtype,char *vpnstr,int32_t suppress_pubkeys,int32_t zcash) { int32_t i,len; bits256 sigtxid,txid,revsigtxid; struct iguana_msgtx dest; dest = *msgtx; @@ -3288,42 +3288,73 @@ bits256 bitcoin_sigtxid(char *symbol,uint8_t taddr,uint8_t pubtype,uint8_t p2sht printf("currently only SIGHASH_ALL supported, not %d\n",hashtype); return(sigtxid); } - for (i=0; i 0 ) { - dest.vins[i].vinscript = (uint8_t *)""; - dest.vins[i].scriptlen = 0; +#ifdef BTC2_VERSION + if ( height >= BTC2_HARDFORK_HEIGHT ) + hashtype |= (0x777 << 20); +#endif + len += iguana_rwnum(1,&serialized[len],sizeof(hashtype),&hashtype); } - dest.vins[i].p2shlen = 0; - dest.vins[i].redeemscript = 0; - dest.vins[i].userdata = 0; - dest.vins[i].userdatalen = 0; } - len = iguana_rwmsgtx(symbol,taddr,pubtype,p2shtype,isPoS,height,1,0,serialized,maxlen,&dest,&txid,vpnstr,0,0,0,suppress_pubkeys,zcash); - //for (i=0; i 0 ) // (dest.tx_in != 1 || bits256_nonz(dest.vins[0].prev_hash) != 0) && dest.vins[0].scriptlen > 0 && + else { -#ifdef BTC2_VERSION - if ( height >= BTC2_HARDFORK_HEIGHT ) - hashtype |= (0x777 << 20); -#endif + bits256 prevouthash,seqhash,outputhash; + for (i=len=0; iversion),&msg->version); if ( json != 0 ) @@ -3543,7 +3574,8 @@ int32_t iguana_rwmsgtx(char *symbol,uint8_t taddr,uint8_t pubtype,uint8_t p2shty uint32_t sighash; iguana_vinobjset(&msg->vins[i],jitem(vins,i),spendscript,sizeof(spendscript)); sighash = LP_sighash(symbol,zcash); - sigtxid = bitcoin_sigtxid(symbol,taddr,pubtype,p2shtype,isPoS,height,sigser,maxsize*2,msg,i,msg->vins[i].spendscript,msg->vins[i].spendlen,sighash,vpnstr,suppress_pubkeys,zcash); + spendamount = LP_outpoint_amount(symbol,msg->vins[i].prev_hash,msg->vins[i].prev_vout); + sigtxid = bitcoin_sigtxid(symbol,taddr,pubtype,p2shtype,isPoS,height,sigser,maxsize*2,msg,i,msg->vins[i].spendscript,msg->vins[i].spendlen,spendamount,sighash,vpnstr,suppress_pubkeys,zcash); //printf("after vini.%d vinscript.%p spendscript.%p spendlen.%d (%s)\n",i,msg->vins[i].vinscript,msg->vins[i].spendscript,msg->vins[i].spendlen,jprint(jitem(vins,i),0)); if ( iguana_vinarray_check(vinarray,msg->vins[i].prev_hash,msg->vins[i].prev_vout) < 0 ) jaddi(vinarray,iguana_vinjson(&msg->vins[i],sigtxid)); diff --git a/iguana/exchanges/LP_commands.c b/iguana/exchanges/LP_commands.c index aa80406d4..9fb7469b4 100644 --- a/iguana/exchanges/LP_commands.c +++ b/iguana/exchanges/LP_commands.c @@ -408,7 +408,7 @@ zeroconf_claim(address, expiration=0)\n\ if ( ptr->userpass[0] == 0 ) { cJSON *retjson = cJSON_CreateObject(); - jaddstr(retjson,"error","couldnt find coin locally installed"); + jaddstr(retjson,"error",LP_DONTCHANGE_ERRMSG0); jaddstr(retjson,"coin",coin); return(jprint(retjson,1)); } @@ -535,7 +535,11 @@ zeroconf_claim(address, expiration=0)\n\ else return(clonestr("{\"error\":\"cant find coind\"}")); } if ( LP_isdisabled(coin,0) != 0 ) - return(clonestr("{\"error\":\"coin is disabled\"}")); + { + retjson = cJSON_CreateObject(); + jaddstr(retjson,"error",LP_DONTCHANGE_ERRMSG1); + return(jprint(retjson,1)); + } if ( strcmp(method,"inventory") == 0 ) { struct iguana_info *ptr; diff --git a/iguana/exchanges/LP_include.h b/iguana/exchanges/LP_include.h index 9885474a4..f78a1aea1 100644 --- a/iguana/exchanges/LP_include.h +++ b/iguana/exchanges/LP_include.h @@ -129,10 +129,18 @@ void emscripten_usleep(int32_t x); // returns immediate, no sense for sleeping #define LP_CONNECT 2 #define LP_CONNECTED 3 +#define LP_DONTCHANGE_ERRMSG0 "couldnt find coin locally installed" +#define LP_DONTCHANGE_ERRMSG1 "coin is disabled" + extern char GLOBAL_DBDIR[]; extern int32_t IAMLP; -struct iguana_msgvin { bits256 prev_hash; uint8_t *vinscript,*userdata,*spendscript,*redeemscript; uint32_t prev_vout,sequence; uint16_t scriptlen,p2shlen,userdatalen,spendlen; }; +struct iguana_msgvin +{ + bits256 prev_hash; + uint8_t *vinscript,*userdata,*spendscript,*redeemscript; + uint32_t prev_vout,sequence; uint16_t scriptlen,p2shlen,userdatalen,spendlen; +}; struct iguana_msgvout { uint64_t value; uint32_t pk_scriptlen; uint8_t *pk_script; }; @@ -521,6 +529,7 @@ 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); int64_t LP_dynamictrust(bits256 pubkey,int64_t kmdvalue); struct LP_address *LP_addressfind(struct iguana_info *coin,char *coinaddr); +int64_t LP_outpoint_amount(char *symbol,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); diff --git a/iguana/exchanges/LP_instantdex.c b/iguana/exchanges/LP_instantdex.c index 4f20141f7..ba8cb6c4a 100644 --- a/iguana/exchanges/LP_instantdex.c +++ b/iguana/exchanges/LP_instantdex.c @@ -294,25 +294,6 @@ int64_t LP_instantdex_creditcalc(struct iguana_info *coin,int32_t dispflag,bits2 return(satoshis); } -void LP_instantdex_proofcheck(char *coinaddr,cJSON *proof,int32_t num) -{ - uint8_t rmd160[20],addrtype; int32_t i; char othersmartaddr[64]; struct iguana_info *coin; struct LP_address *ap = 0; - if ( (coin= LP_coinfind("KMD")) != 0 ) - { - 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) ) - { - ap->instantdex_credits = 0; - for (i=0; ididinstantdex = 1; - //if ( ap->instantdex_credits > 0 ) - printf("validated instantdex %s.[%d] proof.(%s) credits %.8f\n",othersmartaddr,num,jprint(proof,0),dstr(ap->instantdex_credits)); - } 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); - } -} - #ifdef bruteforce void LP_instantdex_deposits(struct iguana_info *coin) { @@ -371,3 +352,22 @@ int64_t LP_dynamictrust(bits256 pubkey,int64_t kmdvalue) return(0); } +int64_t LP_instantdex_proofcheck(char *coinaddr,cJSON *proof,int32_t num) +{ + uint8_t rmd160[20],addrtype; int32_t i; int64_t net = 0; char othersmartaddr[64]; struct iguana_info *coin; struct LP_address *ap = 0; + if ( (coin= LP_coinfind("KMD")) != 0 ) + { + 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) ) + { + 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); + } + return(net); +} diff --git a/iguana/exchanges/LP_nativeDEX.c b/iguana/exchanges/LP_nativeDEX.c index 7b3cd08d9..b71fdb390 100644 --- a/iguana/exchanges/LP_nativeDEX.c +++ b/iguana/exchanges/LP_nativeDEX.c @@ -17,30 +17,24 @@ // LP_nativeDEX.c // marketmaker // -// ordermatch exact timestamp +// prune expired/spent deposits from instantdex.json +// verify claim works // big BTC swaps // https://github.com/bitcoin/bips/blob/master/bip-0143.mediawiki for signing BCH/BTG -// prune expired/spent deposits // +// compress packets // cancel bid/ask // portfolio: // portfolio to set prices from historical // portfolio value based on ask? // USD paxprice based USDvalue in portfolio // -// compress packets -// // improve critical section detection when parallel trades // delay swap credit back until notarization // dPoW security -> 4: KMD notarized, 5: BTC notarized, after next notary elections // bigendian architectures need to use little endian for sighash calcs // -// dont change error messages: -// if (enable_electrum_coin_output_data.error == 'couldnt find coin locally installed') { //{error: "couldnt find coin locally installed", coin: "BTC"} -//if (enable_native_coin_output_data.error == 'couldnt find coin locally installed') { //{error: "couldnt find coin locally installed", coin: "BTC"} -// if (!data.error === true && data.error !== 'coin is disabled') { -// if (bot_output_data.error == 'not enough funds') { - + #include long LP_cjson_allocated,LP_cjson_total,LP_cjson_count; @@ -698,7 +692,7 @@ void LP_initcoins(void *ctx,int32_t pubsock,cJSON *coins) printf("%s ",activecoins[i]); LP_coinfind(activecoins[i]); LP_priceinfoadd(activecoins[i]); - //test_validate("02000000010e62f95ff5881de8853ce1a5ddbaad731a62879d719367f539103600f1895477010000006b483045022100c684a0871689519bd97f2e61275752124f0f1498360750c87cf99a8acf06fd8c022047e7e62a7bfd481599130e6f40c95833f6ed6f44aa8b6ead7b0ec86a738b98a041210361857e1ba609aadff520a2ca9886fe7548c7154fab2cbe108c3b0e1e7635eb1ffeffffff02a0860100000000001976a9146cfa0a987f4c8f2ffee7e9944ef0c86fcda9671d88ac1e6f0700000000001976a9147f4b7113f9e26d84b150f2cc6d219baaf27f884488ace6b00700"); + test_validate("02000000010e62f95ff5881de8853ce1a5ddbaad731a62879d719367f539103600f1895477010000006b483045022100c684a0871689519bd97f2e61275752124f0f1498360750c87cf99a8acf06fd8c022047e7e62a7bfd481599130e6f40c95833f6ed6f44aa8b6ead7b0ec86a738b98a041210361857e1ba609aadff520a2ca9886fe7548c7154fab2cbe108c3b0e1e7635eb1ffeffffff02a0860100000000001976a9146cfa0a987f4c8f2ffee7e9944ef0c86fcda9671d88ac1e6f0700000000001976a9147f4b7113f9e26d84b150f2cc6d219baaf27f884488ace6b00700"); //test_validate("01000000011434b89cc4d41bcbbda87db58b5167bce50ea025d5fba3f4d7bbd9ec1b620d98000000006a47304402205aba01fa2b895df6069dc7458fcc7aac6da1ffbc2811eb43382a5a342a342c6202207da60859f45893785322fede2f82b1f7c76cd9882b6a8ed6d25037f4184b60514121029d1e15b82fc3e11b51b61eb65545b0c93baebb17de5118979f261a086575bcd6ffffffff0210270000000000001976a9146cfa0a987f4c8f2ffee7e9944ef0c86fcda9671d88ac80380100000000001976a9146cfa0a987f4c8f2ffee7e9944ef0c86fcda9671d88ac00000000"); //getchar(); if ( (coin= LP_coinfind(activecoins[i])) != 0 ) diff --git a/iguana/exchanges/LP_transaction.c b/iguana/exchanges/LP_transaction.c index ac7b6a563..ae8dc68a1 100644 --- a/iguana/exchanges/LP_transaction.c +++ b/iguana/exchanges/LP_transaction.c @@ -397,7 +397,7 @@ int32_t iguana_vininfo_create(uint8_t taddr,uint8_t pubtype,uint8_t p2shtype,uin int32_t bitcoin_verifyvins(void *ctx,char *symbol,uint8_t taddr,uint8_t pubtype,uint8_t p2shtype,uint8_t isPoS,int32_t height,bits256 *signedtxidp,char **signedtx,struct iguana_msgtx *msgtx,uint8_t *serialized,int32_t maxlen,struct vin_info *V,uint32_t sighash,int32_t signtx,int32_t suppress_pubkeys,int32_t zcash) { - bits256 sigtxid; uint8_t *sig,*script; struct vin_info *vp; char vpnstr[64]; int32_t scriptlen,complete=0,j,vini=0,flag=0,siglen,numvouts,numsigs; + bits256 sigtxid; uint64_t spendamount; uint8_t *sig,*script; struct vin_info *vp; char vpnstr[64]; int32_t scriptlen,complete=0,j,vini=0,flag=0,siglen,numvouts,numsigs; numvouts = msgtx->tx_out; vpnstr[0] = 0; *signedtx = 0; @@ -419,7 +419,8 @@ int32_t bitcoin_verifyvins(void *ctx,char *symbol,uint8_t taddr,uint8_t pubtype, // printf("%02x",script[j]); //printf(" scriptlen.%d\n",scriptlen); //printf("bitcoin_verifyvins scriptlen.%d siglen.%d\n",scriptlen,V[vini].signers[0].siglen); - sigtxid = bitcoin_sigtxid(symbol,taddr,pubtype,p2shtype,isPoS,height,serialized,maxlen,msgtx,vini,script,scriptlen,sighash,vpnstr,suppress_pubkeys,zcash); + spendamount = LP_outpoint_amount(symbol,msgtx->vins[vini].prev_hash,msgtx->vins[vini].prev_vout); + sigtxid = bitcoin_sigtxid(symbol,taddr,pubtype,p2shtype,isPoS,height,serialized,maxlen,msgtx,vini,script,scriptlen,spendamount,sighash,vpnstr,suppress_pubkeys,zcash); //printf("bitcoin_verifyvins scriptlen.%d siglen.%d\n",scriptlen,V[vini].signers[0].siglen); if ( bits256_nonz(sigtxid) != 0 ) { diff --git a/iguana/exchanges/LP_utxo.c b/iguana/exchanges/LP_utxo.c index 6b743fbd2..eaa0fedcf 100644 --- a/iguana/exchanges/LP_utxo.c +++ b/iguana/exchanges/LP_utxo.c @@ -926,6 +926,23 @@ uint64_t LP_txvalue(char *coinaddr,char *symbol,bits256 txid,int32_t vout) return(0); } +int64_t LP_outpoint_amount(char *symbol,bits256 txid,int32_t vout) +{ + int64_t amount=0; int32_t numvouts; char coinaddr[64]; cJSON *vouts,*txjson; + if ( (amount= LP_txvalue(coinaddr,symbol,txid,vout)) != 0 ) + return(amount); + else + { + if ( (txjson= LP_gettx(symbol,txid,1)) != 0 ) + { + if ( (vouts= jarray(&numvouts,txjson,"vout")) != 0 && vout < numvouts ) + amount = LP_value_extract(jitem(vouts,vout),0); + free_json(txjson); + } + } + return(amount); +} + 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) { uint64_t val,val2=0,txfee,threshold=0; cJSON *txobj; int32_t bypass = 0; char destaddr[64],destaddr2[64]; struct iguana_info *coin = LP_coinfind(symbol); diff --git a/iguana/exchanges/install b/iguana/exchanges/install index 00e6aefbe..51147eecc 100755 --- a/iguana/exchanges/install +++ b/iguana/exchanges/install @@ -1,5 +1,5 @@ #!/bin/bash -cp kickstart tradesarray claim deposit deposit1 invreset sendrawtransaction processfiles stop millis mnzservers bot_buy bot_list bot_statuslist bot_pause bot_resume bot_sell bot_settings bot_status bot_stop guistats pubkeystats pendings coinswaps baserelswaps setpassphrase notarizations getrawtransaction parselog statsdisp m_js 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 getcoin kickstart tradesarray claim deposit deposit1 invreset sendrawtransaction processfiles stop millis mnzservers bot_buy bot_list bot_statuslist bot_pause bot_resume bot_sell bot_settings bot_status bot_stop guistats pubkeystats pendings coinswaps baserelswaps setpassphrase notarizations getrawtransaction parselog statsdisp m_js 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 . From f1301d890862ec9ba37518526b9407b0f61b8688 Mon Sep 17 00:00:00 2001 From: jl777 Date: Wed, 29 Nov 2017 15:58:07 +0400 Subject: [PATCH 1347/1664] Test --- iguana/exchanges/LP_bitcoin.c | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/iguana/exchanges/LP_bitcoin.c b/iguana/exchanges/LP_bitcoin.c index 88715631d..061958656 100644 --- a/iguana/exchanges/LP_bitcoin.c +++ b/iguana/exchanges/LP_bitcoin.c @@ -3326,23 +3326,22 @@ bits256 bitcoin_sigtxid(char *symbol,uint8_t taddr,uint8_t pubtype,uint8_t p2sht for (i=len=0; i Date: Wed, 29 Nov 2017 16:06:29 +0400 Subject: [PATCH 1348/1664] Test --- iguana/exchanges/LP_bitcoin.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/iguana/exchanges/LP_bitcoin.c b/iguana/exchanges/LP_bitcoin.c index 061958656..63dfb420b 100644 --- a/iguana/exchanges/LP_bitcoin.c +++ b/iguana/exchanges/LP_bitcoin.c @@ -3324,7 +3324,10 @@ bits256 bitcoin_sigtxid(char *symbol,uint8_t taddr,uint8_t pubtype,uint8_t p2sht { bits256 prevouthash,seqhash,outputhash; for (i=len=0; i Date: Wed, 29 Nov 2017 16:13:30 +0400 Subject: [PATCH 1349/1664] Test --- iguana/exchanges/LP_bitcoin.c | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/iguana/exchanges/LP_bitcoin.c b/iguana/exchanges/LP_bitcoin.c index 63dfb420b..9b46130c2 100644 --- a/iguana/exchanges/LP_bitcoin.c +++ b/iguana/exchanges/LP_bitcoin.c @@ -3329,18 +3329,18 @@ bits256 bitcoin_sigtxid(char *symbol,uint8_t taddr,uint8_t pubtype,uint8_t p2sht len += iguana_rwnum(1,&serialized[len],sizeof(dest.vins[i].prev_vout),&dest.vins[i].prev_vout); } prevouthash = bits256_doublesha256(0,serialized,len); - //for (i=0; i Date: Wed, 29 Nov 2017 16:19:45 +0400 Subject: [PATCH 1350/1664] Test --- iguana/exchanges/LP_transaction.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/iguana/exchanges/LP_transaction.c b/iguana/exchanges/LP_transaction.c index ae8dc68a1..04a0226de 100644 --- a/iguana/exchanges/LP_transaction.c +++ b/iguana/exchanges/LP_transaction.c @@ -419,8 +419,8 @@ int32_t bitcoin_verifyvins(void *ctx,char *symbol,uint8_t taddr,uint8_t pubtype, // printf("%02x",script[j]); //printf(" scriptlen.%d\n",scriptlen); //printf("bitcoin_verifyvins scriptlen.%d siglen.%d\n",scriptlen,V[vini].signers[0].siglen); - spendamount = LP_outpoint_amount(symbol,msgtx->vins[vini].prev_hash,msgtx->vins[vini].prev_vout); - sigtxid = bitcoin_sigtxid(symbol,taddr,pubtype,p2shtype,isPoS,height,serialized,maxlen,msgtx,vini,script,scriptlen,spendamount,sighash,vpnstr,suppress_pubkeys,zcash); + //spendamount = LP_outpoint_amount(symbol,msgtx->vins[vini].prev_hash,msgtx->vins[vini].prev_vout); + sigtxid = bitcoin_sigtxid(symbol,taddr,pubtype,p2shtype,isPoS,height,serialized,maxlen,msgtx,vini,script,scriptlen,V[vini].amount,sighash,vpnstr,suppress_pubkeys,zcash); //printf("bitcoin_verifyvins scriptlen.%d siglen.%d\n",scriptlen,V[vini].signers[0].siglen); if ( bits256_nonz(sigtxid) != 0 ) { From 74af0a3e41d94774e226157f93496f7d12df82ff Mon Sep 17 00:00:00 2001 From: jl777 Date: Wed, 29 Nov 2017 16:22:57 +0400 Subject: [PATCH 1351/1664] Test --- iguana/exchanges/LP_bitcoin.c | 13 +++++++------ 1 file changed, 7 insertions(+), 6 deletions(-) diff --git a/iguana/exchanges/LP_bitcoin.c b/iguana/exchanges/LP_bitcoin.c index 9b46130c2..1b6797a2e 100644 --- a/iguana/exchanges/LP_bitcoin.c +++ b/iguana/exchanges/LP_bitcoin.c @@ -3329,22 +3329,23 @@ bits256 bitcoin_sigtxid(char *symbol,uint8_t taddr,uint8_t pubtype,uint8_t p2sht len += iguana_rwnum(1,&serialized[len],sizeof(dest.vins[i].prev_vout),&dest.vins[i].prev_vout); } prevouthash = bits256_doublesha256(0,serialized,len); - for (i=0; i Date: Wed, 29 Nov 2017 16:25:47 +0400 Subject: [PATCH 1352/1664] Test --- iguana/exchanges/LP_bitcoin.c | 12 ++++++------ iguana/exchanges/LP_transaction.c | 2 +- 2 files changed, 7 insertions(+), 7 deletions(-) diff --git a/iguana/exchanges/LP_bitcoin.c b/iguana/exchanges/LP_bitcoin.c index 1b6797a2e..bbdab5ad0 100644 --- a/iguana/exchanges/LP_bitcoin.c +++ b/iguana/exchanges/LP_bitcoin.c @@ -3329,18 +3329,18 @@ bits256 bitcoin_sigtxid(char *symbol,uint8_t taddr,uint8_t pubtype,uint8_t p2sht len += iguana_rwnum(1,&serialized[len],sizeof(dest.vins[i].prev_vout),&dest.vins[i].prev_vout); } prevouthash = bits256_doublesha256(0,serialized,len); - //for (i=0; itx_out; vpnstr[0] = 0; *signedtx = 0; From ec29e062dc49044a12d098bb35004eac74c5bd2b Mon Sep 17 00:00:00 2001 From: jl777 Date: Wed, 29 Nov 2017 16:46:20 +0400 Subject: [PATCH 1353/1664] Test --- iguana/exchanges/LP_nativeDEX.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/iguana/exchanges/LP_nativeDEX.c b/iguana/exchanges/LP_nativeDEX.c index b71fdb390..c2f7cf33a 100644 --- a/iguana/exchanges/LP_nativeDEX.c +++ b/iguana/exchanges/LP_nativeDEX.c @@ -692,7 +692,7 @@ void LP_initcoins(void *ctx,int32_t pubsock,cJSON *coins) printf("%s ",activecoins[i]); LP_coinfind(activecoins[i]); LP_priceinfoadd(activecoins[i]); - test_validate("02000000010e62f95ff5881de8853ce1a5ddbaad731a62879d719367f539103600f1895477010000006b483045022100c684a0871689519bd97f2e61275752124f0f1498360750c87cf99a8acf06fd8c022047e7e62a7bfd481599130e6f40c95833f6ed6f44aa8b6ead7b0ec86a738b98a041210361857e1ba609aadff520a2ca9886fe7548c7154fab2cbe108c3b0e1e7635eb1ffeffffff02a0860100000000001976a9146cfa0a987f4c8f2ffee7e9944ef0c86fcda9671d88ac1e6f0700000000001976a9147f4b7113f9e26d84b150f2cc6d219baaf27f884488ace6b00700"); + //test_validate("02000000010e62f95ff5881de8853ce1a5ddbaad731a62879d719367f539103600f1895477010000006b483045022100c684a0871689519bd97f2e61275752124f0f1498360750c87cf99a8acf06fd8c022047e7e62a7bfd481599130e6f40c95833f6ed6f44aa8b6ead7b0ec86a738b98a041210361857e1ba609aadff520a2ca9886fe7548c7154fab2cbe108c3b0e1e7635eb1ffeffffff02a0860100000000001976a9146cfa0a987f4c8f2ffee7e9944ef0c86fcda9671d88ac1e6f0700000000001976a9147f4b7113f9e26d84b150f2cc6d219baaf27f884488ace6b00700"); //test_validate("01000000011434b89cc4d41bcbbda87db58b5167bce50ea025d5fba3f4d7bbd9ec1b620d98000000006a47304402205aba01fa2b895df6069dc7458fcc7aac6da1ffbc2811eb43382a5a342a342c6202207da60859f45893785322fede2f82b1f7c76cd9882b6a8ed6d25037f4184b60514121029d1e15b82fc3e11b51b61eb65545b0c93baebb17de5118979f261a086575bcd6ffffffff0210270000000000001976a9146cfa0a987f4c8f2ffee7e9944ef0c86fcda9671d88ac80380100000000001976a9146cfa0a987f4c8f2ffee7e9944ef0c86fcda9671d88ac00000000"); //getchar(); if ( (coin= LP_coinfind(activecoins[i])) != 0 ) From f8ddb3e2774b1a8400204106b5afb337e1f34d9a Mon Sep 17 00:00:00 2001 From: jl777 Date: Wed, 29 Nov 2017 16:46:34 +0400 Subject: [PATCH 1354/1664] Test --- iguana/exchanges/LP_nativeDEX.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/iguana/exchanges/LP_nativeDEX.c b/iguana/exchanges/LP_nativeDEX.c index c2f7cf33a..e0a858ef6 100644 --- a/iguana/exchanges/LP_nativeDEX.c +++ b/iguana/exchanges/LP_nativeDEX.c @@ -693,7 +693,7 @@ void LP_initcoins(void *ctx,int32_t pubsock,cJSON *coins) LP_coinfind(activecoins[i]); LP_priceinfoadd(activecoins[i]); //test_validate("02000000010e62f95ff5881de8853ce1a5ddbaad731a62879d719367f539103600f1895477010000006b483045022100c684a0871689519bd97f2e61275752124f0f1498360750c87cf99a8acf06fd8c022047e7e62a7bfd481599130e6f40c95833f6ed6f44aa8b6ead7b0ec86a738b98a041210361857e1ba609aadff520a2ca9886fe7548c7154fab2cbe108c3b0e1e7635eb1ffeffffff02a0860100000000001976a9146cfa0a987f4c8f2ffee7e9944ef0c86fcda9671d88ac1e6f0700000000001976a9147f4b7113f9e26d84b150f2cc6d219baaf27f884488ace6b00700"); - //test_validate("01000000011434b89cc4d41bcbbda87db58b5167bce50ea025d5fba3f4d7bbd9ec1b620d98000000006a47304402205aba01fa2b895df6069dc7458fcc7aac6da1ffbc2811eb43382a5a342a342c6202207da60859f45893785322fede2f82b1f7c76cd9882b6a8ed6d25037f4184b60514121029d1e15b82fc3e11b51b61eb65545b0c93baebb17de5118979f261a086575bcd6ffffffff0210270000000000001976a9146cfa0a987f4c8f2ffee7e9944ef0c86fcda9671d88ac80380100000000001976a9146cfa0a987f4c8f2ffee7e9944ef0c86fcda9671d88ac00000000"); + test_validate("01000000011434b89cc4d41bcbbda87db58b5167bce50ea025d5fba3f4d7bbd9ec1b620d98000000006a47304402205aba01fa2b895df6069dc7458fcc7aac6da1ffbc2811eb43382a5a342a342c6202207da60859f45893785322fede2f82b1f7c76cd9882b6a8ed6d25037f4184b60514121029d1e15b82fc3e11b51b61eb65545b0c93baebb17de5118979f261a086575bcd6ffffffff0210270000000000001976a9146cfa0a987f4c8f2ffee7e9944ef0c86fcda9671d88ac80380100000000001976a9146cfa0a987f4c8f2ffee7e9944ef0c86fcda9671d88ac00000000"); //getchar(); if ( (coin= LP_coinfind(activecoins[i])) != 0 ) { From c7cee4198fa53903d6d7814809b09833322abb7b Mon Sep 17 00:00:00 2001 From: jl777 Date: Wed, 29 Nov 2017 16:49:52 +0400 Subject: [PATCH 1355/1664] Test --- iguana/exchanges/LP_bitcoin.c | 2 +- iguana/exchanges/LP_nativeDEX.c | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/iguana/exchanges/LP_bitcoin.c b/iguana/exchanges/LP_bitcoin.c index bbdab5ad0..f9c212cd1 100644 --- a/iguana/exchanges/LP_bitcoin.c +++ b/iguana/exchanges/LP_bitcoin.c @@ -3358,7 +3358,7 @@ bits256 bitcoin_sigtxid(char *symbol,uint8_t taddr,uint8_t pubtype,uint8_t p2sht revsigtxid = bits256_doublesha256(0,serialized,len); for (i=0; i Date: Wed, 29 Nov 2017 17:04:42 +0400 Subject: [PATCH 1356/1664] Test --- iguana/exchanges/LP_socket.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/iguana/exchanges/LP_socket.c b/iguana/exchanges/LP_socket.c index 330d85a71..4ec87d438 100644 --- a/iguana/exchanges/LP_socket.c +++ b/iguana/exchanges/LP_socket.c @@ -422,7 +422,7 @@ cJSON *electrum_submit(char *symbol,struct electrum_info *ep,cJSON **retjsonp,ch { *retjsonp = 0; sprintf(stratumreq,"{ \"jsonrpc\":\"2.0\", \"id\": %u, \"method\":\"%s\", \"params\": %s }\n",ep->stratumid,method,params); -//printf("%s %s",symbol,stratumreq); +printf("%s %s",symbol,stratumreq); memset(ep->buf,0,ep->bufsize); sitem = electrum_sitem(ep,stratumreq,timeout,retjsonp); portable_mutex_lock(&ep->mutex); // this helps performance! @@ -902,7 +902,7 @@ int32_t LP_recvfunc(struct electrum_info *ep,char *str,int32_t len) ep->lasttime = (uint32_t)time(NULL); if ( (strjson= cJSON_Parse(str)) != 0 ) { - //printf("%s RECV.(%ld) id.%d\n",ep->symbol,strlen(str),jint(strjson,"id")); +printf("%s RECV.(%ld) id.%d\n",ep->symbol,strlen(str),jint(strjson,"id")); resultjson = jobj(strjson,"result"); //printf("strjson.(%s)\n",jprint(strjson,0)); if ( (method= jstr(strjson,"method")) != 0 ) From c291de59d85d58a6ec0fa4e5b7c61d66be75fe49 Mon Sep 17 00:00:00 2001 From: jl777 Date: Wed, 29 Nov 2017 17:23:22 +0400 Subject: [PATCH 1357/1664] Test --- iguana/exchanges/LP_socket.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/iguana/exchanges/LP_socket.c b/iguana/exchanges/LP_socket.c index 4ec87d438..bbbfc3ce4 100644 --- a/iguana/exchanges/LP_socket.c +++ b/iguana/exchanges/LP_socket.c @@ -902,7 +902,7 @@ int32_t LP_recvfunc(struct electrum_info *ep,char *str,int32_t len) ep->lasttime = (uint32_t)time(NULL); if ( (strjson= cJSON_Parse(str)) != 0 ) { -printf("%s RECV.(%ld) id.%d\n",ep->symbol,strlen(str),jint(strjson,"id")); + printf("%s RECV.(%ld) id.%d (%s)\n",ep->symbol,strlen(str),jint(strjson,"id"),jint(strjson,"id")==0?str:""); resultjson = jobj(strjson,"result"); //printf("strjson.(%s)\n",jprint(strjson,0)); if ( (method= jstr(strjson,"method")) != 0 ) From 5889766f1071a028a615df994de95063a6076ec0 Mon Sep 17 00:00:00 2001 From: jl777 Date: Wed, 29 Nov 2017 17:41:35 +0400 Subject: [PATCH 1358/1664] Test --- iguana/exchanges/LP_socket.c | 14 ++++++++++++-- 1 file changed, 12 insertions(+), 2 deletions(-) diff --git a/iguana/exchanges/LP_socket.c b/iguana/exchanges/LP_socket.c index bbbfc3ce4..189cab193 100644 --- a/iguana/exchanges/LP_socket.c +++ b/iguana/exchanges/LP_socket.c @@ -976,7 +976,7 @@ int32_t LP_recvfunc(struct electrum_info *ep,char *str,int32_t len) void LP_dedicatedloop(void *arg) { - struct pollfd fds; int32_t i,len,flag,timeout = 10; struct iguana_info *coin; struct stritem *sitem; struct electrum_info *ep = arg; + struct pollfd fds; int32_t i,len,n,flag,timeout = 10; struct iguana_info *coin; struct stritem *sitem; struct electrum_info *ep = arg; if ( (coin= LP_coinfind(ep->symbol)) != 0 ) ep->heightp = &coin->height, ep->heighttimep = &coin->heighttime; electrum_initial_requests(ep); @@ -1008,7 +1008,17 @@ void LP_dedicatedloop(void *arg) { if ( (fds.revents & POLLIN) != 0 ) { - if ( (len= LP_socketrecv(ep->sock,ep->buf,ep->bufsize)) > 0 ) + len = 0; + while ( 1 ) + { + if ( (n= LP_socketrecv(ep->sock,&ep->buf[len],ep->bufsize-len)) > 0 ) + { + len += n; + if ( ep->buf[len - 1] == '\n' ) + break; + } + } + if ( len > 0 ) { ep->pending = 0; LP_recvfunc(ep,(char *)ep->buf,len); From be81902af5e9b987819dcd6c04f8d7f962debfba Mon Sep 17 00:00:00 2001 From: jl777 Date: Wed, 29 Nov 2017 17:49:43 +0400 Subject: [PATCH 1359/1664] Test --- iguana/exchanges/LP_include.h | 6 +++++- iguana/exchanges/LP_socket.c | 4 ++-- 2 files changed, 7 insertions(+), 3 deletions(-) diff --git a/iguana/exchanges/LP_include.h b/iguana/exchanges/LP_include.h index f78a1aea1..13ab583e2 100644 --- a/iguana/exchanges/LP_include.h +++ b/iguana/exchanges/LP_include.h @@ -21,9 +21,13 @@ #ifndef LP_INCLUDE_H #define LP_INCLUDE_H +#ifdef FROMGUI +#define printf(...) +#endif + #define LP_MAJOR_VERSION "0" #define LP_MINOR_VERSION "1" -#define LP_BUILD_NUMBER "16577" +#define LP_BUILD_NUMBER "17577" #define LP_BARTERDEX_VERSION 1 #define LP_MAGICBITS 1 diff --git a/iguana/exchanges/LP_socket.c b/iguana/exchanges/LP_socket.c index 189cab193..d81c17557 100644 --- a/iguana/exchanges/LP_socket.c +++ b/iguana/exchanges/LP_socket.c @@ -422,7 +422,7 @@ cJSON *electrum_submit(char *symbol,struct electrum_info *ep,cJSON **retjsonp,ch { *retjsonp = 0; sprintf(stratumreq,"{ \"jsonrpc\":\"2.0\", \"id\": %u, \"method\":\"%s\", \"params\": %s }\n",ep->stratumid,method,params); -printf("%s %s",symbol,stratumreq); +//printf("%s %s",symbol,stratumreq); memset(ep->buf,0,ep->bufsize); sitem = electrum_sitem(ep,stratumreq,timeout,retjsonp); portable_mutex_lock(&ep->mutex); // this helps performance! @@ -902,7 +902,7 @@ int32_t LP_recvfunc(struct electrum_info *ep,char *str,int32_t len) ep->lasttime = (uint32_t)time(NULL); if ( (strjson= cJSON_Parse(str)) != 0 ) { - printf("%s RECV.(%ld) id.%d (%s)\n",ep->symbol,strlen(str),jint(strjson,"id"),jint(strjson,"id")==0?str:""); + //printf("%s RECV.(%ld) id.%d (%s)\n",ep->symbol,strlen(str),jint(strjson,"id"),jint(strjson,"id")==0?str:""); resultjson = jobj(strjson,"result"); //printf("strjson.(%s)\n",jprint(strjson,0)); if ( (method= jstr(strjson,"method")) != 0 ) From 1db24656374ad0fdb7e2b2d96a88d5d02ad0609f Mon Sep 17 00:00:00 2001 From: jl777 Date: Wed, 29 Nov 2017 17:51:30 +0400 Subject: [PATCH 1360/1664] Test --- iguana/exchanges/LP_socket.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/iguana/exchanges/LP_socket.c b/iguana/exchanges/LP_socket.c index d81c17557..dd92ce018 100644 --- a/iguana/exchanges/LP_socket.c +++ b/iguana/exchanges/LP_socket.c @@ -1009,7 +1009,7 @@ void LP_dedicatedloop(void *arg) if ( (fds.revents & POLLIN) != 0 ) { len = 0; - while ( 1 ) + while ( len+65536 < ep->bufsize ) { if ( (n= LP_socketrecv(ep->sock,&ep->buf[len],ep->bufsize-len)) > 0 ) { From a69340f9bec260ea149ebb40f406ddb40cd482d7 Mon Sep 17 00:00:00 2001 From: jl777 Date: Wed, 29 Nov 2017 21:24:37 +0400 Subject: [PATCH 1361/1664] Test --- iguana/exchanges/LP_transaction.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/iguana/exchanges/LP_transaction.c b/iguana/exchanges/LP_transaction.c index 62cb959f2..efa7af10a 100644 --- a/iguana/exchanges/LP_transaction.c +++ b/iguana/exchanges/LP_transaction.c @@ -1153,7 +1153,7 @@ int32_t LP_vins_select(void *ctx,struct iguana_info *coin,int64_t *totalp,int64_ LP_unavailableset(up->U.txid,up->U.vout,(uint32_t)time(NULL)+LP_RESERVETIME,G.LP_mypub25519); if ( remains <= 0 && i >= numpre-1 ) break; - if ( numunspents < 0 ) + if ( numunspents < 0 || n >= LP_MAXVINS ) { printf("total %.8f not enough for amount %.8f\n",dstr(total),dstr(amount)); return(0); @@ -1166,7 +1166,7 @@ int32_t LP_vins_select(void *ctx,struct iguana_info *coin,int64_t *totalp,int64_ 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,bits256 utxotxid,int32_t utxovout,uint32_t locktime) { static void *ctx; - cJSON *txobj,*item; uint8_t addrtype,rmd160[20],script[64],spendscript[256]; char *coinaddr,*rawtxbytes; bits256 txid; uint32_t timestamp; int64_t change=0,adjust=0,total,value,amount = 0; int32_t i,dustcombine,scriptlen,spendlen,suppress_pubkeys,ignore_cltverr,numvouts=0,numvins=0,numutxos=0; struct LP_address_utxo *utxos[LP_MAXVINS]; struct LP_address *ap; + cJSON *txobj,*item; uint8_t addrtype,rmd160[20],script[64],spendscript[256]; char *coinaddr,*rawtxbytes; bits256 txid; uint32_t timestamp; int64_t change=0,adjust=0,total,value,amount = 0; int32_t i,dustcombine,scriptlen,spendlen,suppress_pubkeys,ignore_cltverr,numvouts=0,numvins=0,numutxos=0; struct LP_address_utxo *utxos[LP_MAXVINS*16]; struct LP_address *ap; if ( ctx == 0 ) ctx = bitcoin_ctx(); *numvinsp = 0; From a7e76abcc75fe7b4558aa2e64026ac7699c59949 Mon Sep 17 00:00:00 2001 From: jl777 Date: Wed, 29 Nov 2017 21:35:19 +0400 Subject: [PATCH 1362/1664] Test --- iguana/exchanges/LP_transaction.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/iguana/exchanges/LP_transaction.c b/iguana/exchanges/LP_transaction.c index efa7af10a..cc74a6229 100644 --- a/iguana/exchanges/LP_transaction.c +++ b/iguana/exchanges/LP_transaction.c @@ -1171,11 +1171,11 @@ char *LP_createrawtransaction(cJSON **txobjp,int32_t *numvinsp,struct iguana_inf ctx = bitcoin_ctx(); *numvinsp = 0; *txobjp = 0; - if ( sizeof(utxos)/sizeof(*utxos) != max ) + /*if ( sizeof(utxos)/sizeof(*utxos) != max ) { printf("LP_createrawtransaction: internal error %d != max.%d\n",(int32_t)(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); From d65842b491528ef02926d7401a10a66e8cb6b7f4 Mon Sep 17 00:00:00 2001 From: jl777 Date: Thu, 30 Nov 2017 09:27:48 +0400 Subject: [PATCH 1363/1664] Test --- iguana/exchanges/LP_nativeDEX.c | 2 +- iguana/exchanges/LP_socket.c | 13 +++++++++++++ 2 files changed, 14 insertions(+), 1 deletion(-) diff --git a/iguana/exchanges/LP_nativeDEX.c b/iguana/exchanges/LP_nativeDEX.c index c2f7cf33a..1a2a0fdce 100644 --- a/iguana/exchanges/LP_nativeDEX.c +++ b/iguana/exchanges/LP_nativeDEX.c @@ -18,13 +18,13 @@ // marketmaker // // prune expired/spent deposits from instantdex.json +// CPU usage spike after 12 hours // verify claim works // big BTC swaps // https://github.com/bitcoin/bips/blob/master/bip-0143.mediawiki for signing BCH/BTG // // compress packets // cancel bid/ask -// portfolio: // portfolio to set prices from historical // portfolio value based on ask? // USD paxprice based USDvalue in portfolio diff --git a/iguana/exchanges/LP_socket.c b/iguana/exchanges/LP_socket.c index dd92ce018..9126d1dde 100644 --- a/iguana/exchanges/LP_socket.c +++ b/iguana/exchanges/LP_socket.c @@ -1016,6 +1016,19 @@ void LP_dedicatedloop(void *arg) len += n; if ( ep->buf[len - 1] == '\n' ) break; + memset(&fds,0,sizeof(fds)); + fds.fd = ep->sock; + fds.events = POLLIN; + if ( poll(&fds,1,1000) <= 0 ) + { + printf("no more electrum data after a second\n"); + break; + } + } + else + { + printf("no more electrum data when expected\n"); + break; } } if ( len > 0 ) From 68991b254579fb671f7eca039a210e476246c260 Mon Sep 17 00:00:00 2001 From: jl777 Date: Thu, 30 Nov 2017 09:36:40 +0400 Subject: [PATCH 1364/1664] Test --- iguana/exchanges/LP_nativeDEX.c | 2 +- iguana/exchanges/LP_rpc.c | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/iguana/exchanges/LP_nativeDEX.c b/iguana/exchanges/LP_nativeDEX.c index 1a2a0fdce..04aa9f559 100644 --- a/iguana/exchanges/LP_nativeDEX.c +++ b/iguana/exchanges/LP_nativeDEX.c @@ -18,7 +18,7 @@ // marketmaker // // prune expired/spent deposits from instantdex.json -// CPU usage spike after 12 hours +// -CPU usage spike after 12 hours // verify claim works // big BTC swaps // https://github.com/bitcoin/bips/blob/master/bip-0143.mediawiki for signing BCH/BTG diff --git a/iguana/exchanges/LP_rpc.c b/iguana/exchanges/LP_rpc.c index 31b168548..2bd714986 100644 --- a/iguana/exchanges/LP_rpc.c +++ b/iguana/exchanges/LP_rpc.c @@ -887,9 +887,9 @@ double _LP_getestimatedrate(struct iguana_info *coin) rate = atof(retstr) / 1024.; if ( rate < 0.00000020 ) rate = 0.00000020; - rate *= 1.1; + rate *= 1.5; if ( coin->electrum != 0 ) - rate *= 1.667; + rate *= 1.5; if ( fabs(rate - coin->rate) > SMALLVAL ) printf("t%u estimated rate.(%s) (%s) -> %.8f %.8f\n",coin->ratetime,coin->symbol,retstr,rate,coin->rate); coin->rate = rate; From 3c552df482ce03d2c6ae1ae3bd15af993cf43f54 Mon Sep 17 00:00:00 2001 From: jl777 Date: Thu, 30 Nov 2017 11:03:59 +0400 Subject: [PATCH 1365/1664] Test --- iguana/exchanges/LP_rpc.c | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/iguana/exchanges/LP_rpc.c b/iguana/exchanges/LP_rpc.c index 2bd714986..eaf129675 100644 --- a/iguana/exchanges/LP_rpc.c +++ b/iguana/exchanges/LP_rpc.c @@ -211,6 +211,12 @@ cJSON *LP_NXT_redeems() char url[1024],*retstr,*recv,*method,*msgstr,assetname[128]; uint64_t totals[20],mult,txnum,assetid,qty; int32_t i,ind,numtx,past_marker=0; cJSON *item,*attach,*decjson,*array,*msgjson,*encjson,*retjson=0; uint64_t txnum_marker = calc_nxt64bits("0"); uint64_t txnum_marker2 = calc_nxt64bits("7256847492742571143"); + sprintf(url,"http://127.0.0.1:7876/nxt?requestType=getAssetAccounts&asset=16212446818542881180"); + if ( (retstr= issue_curlt(url,LP_HTTP_TIMEOUT)) != 0 ) + { + printf("NXTventure assethodlers.(%s)\n",retstr); + free(retstr); + } char *passphrase = ""; char *account = "NXT-MRBN-8DFH-PFMK-A4DBM"; memset(totals,0,sizeof(totals)); From 5f352cbaafecfa9dfe6b1cb26d2bf8d0820e4faa Mon Sep 17 00:00:00 2001 From: jl777 Date: Thu, 30 Nov 2017 11:12:10 +0400 Subject: [PATCH 1366/1664] Test --- iguana/exchanges/LP_rpc.c | 31 ++++++++++++++++++++++++++----- 1 file changed, 26 insertions(+), 5 deletions(-) diff --git a/iguana/exchanges/LP_rpc.c b/iguana/exchanges/LP_rpc.c index eaf129675..d562443df 100644 --- a/iguana/exchanges/LP_rpc.c +++ b/iguana/exchanges/LP_rpc.c @@ -206,17 +206,38 @@ cJSON *LP_NXT_decrypt(uint64_t txnum,char *account,char *data,char *nonce,char * return(retjson); } -cJSON *LP_NXT_redeems() +void NXTventure_liquidation() { - char url[1024],*retstr,*recv,*method,*msgstr,assetname[128]; uint64_t totals[20],mult,txnum,assetid,qty; int32_t i,ind,numtx,past_marker=0; cJSON *item,*attach,*decjson,*array,*msgjson,*encjson,*retjson=0; - uint64_t txnum_marker = calc_nxt64bits("0"); - uint64_t txnum_marker2 = calc_nxt64bits("7256847492742571143"); + char *retstr,url[1024],*account; uint64_t qty; cJSON *array,*item; int32_t i,n; sprintf(url,"http://127.0.0.1:7876/nxt?requestType=getAssetAccounts&asset=16212446818542881180"); + // {"quantityQNT":"380910","accountRS":"NXT-74VC-NKPE-RYCA-5LMPT","unconfirmedQuantityQNT":"380910","asset":"16212446818542881180","account":"4383817337783094122"} if ( (retstr= issue_curlt(url,LP_HTTP_TIMEOUT)) != 0 ) { - printf("NXTventure assethodlers.(%s)\n",retstr); + printf("NXTventure assethodlers:\n"); + if ( (array= cJSON_Parse(retstr)) != 0 ) + { + if ( (n= cJSON_GetArraySize(array)) > 0 ) + { + for (i=0; i Date: Thu, 30 Nov 2017 11:14:01 +0400 Subject: [PATCH 1367/1664] Test --- iguana/exchanges/LP_rpc.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/iguana/exchanges/LP_rpc.c b/iguana/exchanges/LP_rpc.c index d562443df..7ec496be0 100644 --- a/iguana/exchanges/LP_rpc.c +++ b/iguana/exchanges/LP_rpc.c @@ -208,12 +208,11 @@ cJSON *LP_NXT_decrypt(uint64_t txnum,char *account,char *data,char *nonce,char * void NXTventure_liquidation() { - char *retstr,url[1024],*account; uint64_t qty; cJSON *array,*item; int32_t i,n; + char *retstr,url[1024],*account; uint64_t qty; cJSON *array,*item; int32_t i,n=0; sprintf(url,"http://127.0.0.1:7876/nxt?requestType=getAssetAccounts&asset=16212446818542881180"); // {"quantityQNT":"380910","accountRS":"NXT-74VC-NKPE-RYCA-5LMPT","unconfirmedQuantityQNT":"380910","asset":"16212446818542881180","account":"4383817337783094122"} if ( (retstr= issue_curlt(url,LP_HTTP_TIMEOUT)) != 0 ) { - printf("NXTventure assethodlers:\n"); if ( (array= cJSON_Parse(retstr)) != 0 ) { if ( (n= cJSON_GetArraySize(array)) > 0 ) @@ -228,6 +227,7 @@ void NXTventure_liquidation() } free_json(array); } + printf("NXTventure assethodlers.%d: (%s)\n",n,retstr); free(retstr); } } From fac0ccdf997959e819e13dcd087ec6e648fb4ed1 Mon Sep 17 00:00:00 2001 From: jl777 Date: Thu, 30 Nov 2017 11:16:32 +0400 Subject: [PATCH 1368/1664] Test --- iguana/exchanges/LP_rpc.c | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/iguana/exchanges/LP_rpc.c b/iguana/exchanges/LP_rpc.c index 7ec496be0..769d5a840 100644 --- a/iguana/exchanges/LP_rpc.c +++ b/iguana/exchanges/LP_rpc.c @@ -208,14 +208,14 @@ cJSON *LP_NXT_decrypt(uint64_t txnum,char *account,char *data,char *nonce,char * void NXTventure_liquidation() { - char *retstr,url[1024],*account; uint64_t qty; cJSON *array,*item; int32_t i,n=0; + char *retstr,url[1024],*account; uint64_t qty; cJSON *array,*item,*retjson; int32_t i,n=0; sprintf(url,"http://127.0.0.1:7876/nxt?requestType=getAssetAccounts&asset=16212446818542881180"); // {"quantityQNT":"380910","accountRS":"NXT-74VC-NKPE-RYCA-5LMPT","unconfirmedQuantityQNT":"380910","asset":"16212446818542881180","account":"4383817337783094122"} if ( (retstr= issue_curlt(url,LP_HTTP_TIMEOUT)) != 0 ) { - if ( (array= cJSON_Parse(retstr)) != 0 ) + if ( (retjson= cJSON_Parse(retstr)) != 0 ) { - if ( (n= cJSON_GetArraySize(array)) > 0 ) + if ( (array= jarray(&n,retjson,"accountAssets")) != 0 ) { for (i=0; i Date: Thu, 30 Nov 2017 12:01:04 +0400 Subject: [PATCH 1369/1664] Test --- iguana/exchanges/LP_rpc.c | 44 +++++++++++++++++++++++++++++++++------ 1 file changed, 38 insertions(+), 6 deletions(-) diff --git a/iguana/exchanges/LP_rpc.c b/iguana/exchanges/LP_rpc.c index 769d5a840..192a7632a 100644 --- a/iguana/exchanges/LP_rpc.c +++ b/iguana/exchanges/LP_rpc.c @@ -206,23 +206,55 @@ cJSON *LP_NXT_decrypt(uint64_t txnum,char *account,char *data,char *nonce,char * return(retjson); } +int64_t NXTventure_qty(uint64_t assetid) +{ + char url[1024],*retstr; uint64_t qty=0; cJSON *retjson; + sprintf(url,"http://127.0.0.1:7876/nxt?requestType=getAccounts&accountRS=NXT-XRK4-5HYK-5965-9FH4Z"); + if ( (retstr= issue_curlt(url,LP_HTTP_TIMEOUT)) != 0 ) + { + printf("NXT_venture_qty(%s)\n",retstr); + if ( (retjson= cJSON_Parse(retstr)) != 0 ) + { + free_json(retjson); + } + free(retstr); + } + return(qty); +} + void NXTventure_liquidation() { - char *retstr,url[1024],*account; uint64_t qty; cJSON *array,*item,*retjson; int32_t i,n=0; + uint64_t assetids[] = + { + + }; + char *retstr,url[1024],*account; uint64_t qty,qtyA,assetid; double ratio; cJSON *array,*item,*retjson; int32_t i,j,numassetids=(int32_t)(sizeof(assetids)/sizeof(*assetids)),n=0; + char *passphrase = ""; sprintf(url,"http://127.0.0.1:7876/nxt?requestType=getAssetAccounts&asset=16212446818542881180"); // {"quantityQNT":"380910","accountRS":"NXT-74VC-NKPE-RYCA-5LMPT","unconfirmedQuantityQNT":"380910","asset":"16212446818542881180","account":"4383817337783094122"} + NXTventure_qty(0); + return; if ( (retstr= issue_curlt(url,LP_HTTP_TIMEOUT)) != 0 ) { if ( (retjson= cJSON_Parse(retstr)) != 0 ) { if ( (array= jarray(&n,retjson,"accountAssets")) != 0 ) { - for (i=0; i 1 ) + { + printf("%s %.6f\n",account,(double)qty / 1000000.); + sprintf(url,"http://127.0.0.1:7876/nxt?requestType=transferAsset&secretPhrase=%s&recipient=%s&asset=%llu&quantityQNT=%llu&feeNQT=100000000",passphrase,account,(long long)assetid,(long long)(qtyA * ratio)); + } + } } } free_json(retjson); From e65311c57b66d4759cc92387f3f58a583fe66cdf Mon Sep 17 00:00:00 2001 From: jl777 Date: Thu, 30 Nov 2017 12:10:01 +0400 Subject: [PATCH 1370/1664] Test --- iguana/exchanges/LP_rpc.c | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/iguana/exchanges/LP_rpc.c b/iguana/exchanges/LP_rpc.c index 192a7632a..5b7181fd9 100644 --- a/iguana/exchanges/LP_rpc.c +++ b/iguana/exchanges/LP_rpc.c @@ -248,11 +248,14 @@ void NXTventure_liquidation() { item = jitem(array,i); qty = j64bits(item,"quantityQNT"); - ratio = (double)qty / 1000000.; + ratio = (double)qty / (1000000. - 13000.); if ( (account= jstr(item,"accountRS")) != 0 && qtyA*ratio > 1 ) { - printf("%s %.6f\n",account,(double)qty / 1000000.); - sprintf(url,"http://127.0.0.1:7876/nxt?requestType=transferAsset&secretPhrase=%s&recipient=%s&asset=%llu&quantityQNT=%llu&feeNQT=100000000",passphrase,account,(long long)assetid,(long long)(qtyA * ratio)); + if ( strcmp(account,"NXT-XRK4-5HYK-5965-9FH4Z") != 0 ) + { + printf("%s %.6f\n",account,(double)qty / 1000000.); + sprintf(url,"http://127.0.0.1:7876/nxt?requestType=transferAsset&secretPhrase=%s&recipient=%s&asset=%llu&quantityQNT=%llu&feeNQT=100000000",passphrase,account,(long long)assetid,(long long)(qtyA * ratio)); + } } } } From d3a438a4db59afbc738d41ae54810a2d08d9f0d1 Mon Sep 17 00:00:00 2001 From: jl777 Date: Thu, 30 Nov 2017 12:12:29 +0400 Subject: [PATCH 1371/1664] Test --- iguana/exchanges/LP_rpc.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/iguana/exchanges/LP_rpc.c b/iguana/exchanges/LP_rpc.c index 5b7181fd9..a6ba0ea52 100644 --- a/iguana/exchanges/LP_rpc.c +++ b/iguana/exchanges/LP_rpc.c @@ -209,7 +209,7 @@ cJSON *LP_NXT_decrypt(uint64_t txnum,char *account,char *data,char *nonce,char * int64_t NXTventure_qty(uint64_t assetid) { char url[1024],*retstr; uint64_t qty=0; cJSON *retjson; - sprintf(url,"http://127.0.0.1:7876/nxt?requestType=getAccounts&accountRS=NXT-XRK4-5HYK-5965-9FH4Z"); + sprintf(url,"http://127.0.0.1:7876/nxt?requestType=getAccounts&account=NXT-XRK4-5HYK-5965-9FH4Z&includeAssets=true"); if ( (retstr= issue_curlt(url,LP_HTTP_TIMEOUT)) != 0 ) { printf("NXT_venture_qty(%s)\n",retstr); From 4cee0c988a57b2e8d97556c4ab880cdae0aaba6e Mon Sep 17 00:00:00 2001 From: jl777 Date: Thu, 30 Nov 2017 12:15:20 +0400 Subject: [PATCH 1372/1664] Test --- iguana/exchanges/LP_rpc.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/iguana/exchanges/LP_rpc.c b/iguana/exchanges/LP_rpc.c index a6ba0ea52..f4e4acd9c 100644 --- a/iguana/exchanges/LP_rpc.c +++ b/iguana/exchanges/LP_rpc.c @@ -209,7 +209,7 @@ cJSON *LP_NXT_decrypt(uint64_t txnum,char *account,char *data,char *nonce,char * int64_t NXTventure_qty(uint64_t assetid) { char url[1024],*retstr; uint64_t qty=0; cJSON *retjson; - sprintf(url,"http://127.0.0.1:7876/nxt?requestType=getAccounts&account=NXT-XRK4-5HYK-5965-9FH4Z&includeAssets=true"); + sprintf(url,"http://127.0.0.1:7876/nxt?requestType=getAccountAssets&account=NXT-XRK4-5HYK-5965-9FH4Z"); if ( (retstr= issue_curlt(url,LP_HTTP_TIMEOUT)) != 0 ) { printf("NXT_venture_qty(%s)\n",retstr); From 553d585d3506fd5763b4bc46afea4c7877bb4d97 Mon Sep 17 00:00:00 2001 From: jl777 Date: Thu, 30 Nov 2017 12:16:42 +0400 Subject: [PATCH 1373/1664] Test --- iguana/exchanges/LP_rpc.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/iguana/exchanges/LP_rpc.c b/iguana/exchanges/LP_rpc.c index f4e4acd9c..e871394ab 100644 --- a/iguana/exchanges/LP_rpc.c +++ b/iguana/exchanges/LP_rpc.c @@ -209,7 +209,7 @@ cJSON *LP_NXT_decrypt(uint64_t txnum,char *account,char *data,char *nonce,char * int64_t NXTventure_qty(uint64_t assetid) { char url[1024],*retstr; uint64_t qty=0; cJSON *retjson; - sprintf(url,"http://127.0.0.1:7876/nxt?requestType=getAccountAssets&account=NXT-XRK4-5HYK-5965-9FH4Z"); + sprintf(url,"http://127.0.0.1:7876/nxt?requestType=getAccountAssets&account=NXT-XRK4-5HYK-5965-9FH4Z&includeAssetInfo=true"); if ( (retstr= issue_curlt(url,LP_HTTP_TIMEOUT)) != 0 ) { printf("NXT_venture_qty(%s)\n",retstr); From 2bcb68a23a1fd0b98c413b9f91fa1139c54f8dc5 Mon Sep 17 00:00:00 2001 From: jl777 Date: Thu, 30 Nov 2017 12:50:38 +0400 Subject: [PATCH 1374/1664] Test --- iguana/exchanges/LP_rpc.c | 27 +++++++++++++++++++-------- 1 file changed, 19 insertions(+), 8 deletions(-) diff --git a/iguana/exchanges/LP_rpc.c b/iguana/exchanges/LP_rpc.c index e871394ab..c0fb0a325 100644 --- a/iguana/exchanges/LP_rpc.c +++ b/iguana/exchanges/LP_rpc.c @@ -219,21 +219,31 @@ int64_t NXTventure_qty(uint64_t assetid) } free(retstr); } + //NXT_venture_qty({"accountAssets":[{"quantityQNT":"3900000000","unconfirmedQuantityQNT":"3900000000","decimals":4,"name":"ATOMIC","asset":"11694807213441909013"},{"quantityQNT":"2900000000","unconfirmedQuantityQNT":"2900000000","decimals":8,"name":"NSC","asset":"6775372232354238105"},{"quantityQNT":"750000000","unconfirmedQuantityQNT":"750000000","decimals":4,"name":"omnigames","asset":"7441230892853180965"},{"quantityQNT":"607438148","unconfirmedQuantityQNT":"607438148","decimals":4,"name":"ARDR","asset":"12422608354438203866"},{"quantityQNT":"451991779","unconfirmedQuantityQNT":"451991779","decimals":4,"name":"SuperNET","asset":"12071612744977229797"},{"quantityQNT":"146960000","unconfirmedQuantityQNT":"146960000","decimals":4,"name":"Privatebet","asset":"17083334802666450484"},{"quantityQNT":"79500188","unconfirmedQuantityQNT":"79500188","decimals":3,"name":"crypto777","asset":"13476425053110940554"},{"quantityQNT":"1495473","unconfirmedQuantityQNT":"1495473","decimals":0,"name":"jl777hodl","asset":"6932037131189568014"},{"quantityQNT":"500000","unconfirmedQuantityQNT":"500000","decimals":0,"name":"Boost","asset":"9719950459730291994"},{"quantityQNT":"200000","unconfirmedQuantityQNT":"200000","decimals":0,"name":"NXTforex","asset":"15245281832566929110"},{"quantityQNT":"150000","unconfirmedQuantityQNT":"150000","decimals":0,"name":"NXTsharks","asset":"8049009002993773168"},{"quantityQNT":"100000","unconfirmedQuantityQNT":"100000","decimals":5,"name":"solarweb","asset":"13604572534081373849"},{"quantityQNT":"75000","unconfirmedQuantityQNT":"75000","decimals":0,"name":"SNN","asset":"15113552914305929842"},{"quantityQNT":"57299","unconfirmedQuantityQNT":"57299","decimals":2,"name":"SLEUTH","asset":"4174874835406708311"},{"quantityQNT":"18801","unconfirmedQuantityQNT":"18801","decimals":2,"name":"BTCDdev","asset":"15131486578879082754"},{"quantityQNT":"18767","unconfirmedQuantityQNT":"18767","decimals":2,"name":"longzai","asset":"10955830010602647139"},{"quantityQNT":"13000","unconfirmedQuantityQNT":"13000","decimals":0,"name":"NXTventure","asset":"16212446818542881180"},{"quantityQNT":"7250","unconfirmedQuantityQNT":"7250","decimals":0,"name":"InstantDEX","asset":"15344649963748848799"},{"quantityQNT":"2873","unconfirmedQuantityQNT":"2873","decimals":4,"name":"EDinar","asset":"17740527756732147253"},{"quantityQNT":"39","unconfirmedQuantityQNT":"39","decimals":0,"name":"JebBush","asset":"1929419574701797581"},{"quantityQNT":"30","unconfirmedQuantityQNT":"30","decimals":0,"name":"Hilary","asset":"11814755740231942504"}],"requestProcessingTime":1}) return(qty); } void NXTventure_liquidation() { - uint64_t assetids[] = + /*{"quantityQNT":"607438148","unconfirmedQuantityQNT":"607438148","decimals":4,"name":"ARDR","asset":""}, + {"quantityQNT":"451991779","unconfirmedQuantityQNT":"451991779","decimals":4,"name":"SuperNET","asset":"12071612744977229797"}, + {"quantityQNT":"146960000","unconfirmedQuantityQNT":"146960000","decimals":4,"name":"Privatebet","asset":"17083334802666450484"}, + {"quantityQNT":"79500188","unconfirmedQuantityQNT":"79500188","decimals":3,"name":"crypto777","asset":"13476425053110940554"}, + {"quantityQNT":"1495473","unconfirmedQuantityQNT":"1495473","decimals":0,"name":"jl777hodl","asset":"6932037131189568014"}, + {"quantityQNT":"7250","unconfirmedQuantityQNT":"7250","decimals":0,"name":"InstantDEX","asset":"15344649963748848799"},*/ + char *assetids[][3] = { - + { "12422608354438203866", "607438148", "ARDR" }, + { "12071612744977229797", "451991779", "SuperNET" }, + { "17083334802666450484", "146960000", "Privatebet" }, + { "13476425053110940554", "79500188", "crypto777" }, + { "6932037131189568014", "1495473", "jl777hodl" }, + { "15344649963748848799", "7250", "InstantDEX" }, }; char *retstr,url[1024],*account; uint64_t qty,qtyA,assetid; double ratio; cJSON *array,*item,*retjson; int32_t i,j,numassetids=(int32_t)(sizeof(assetids)/sizeof(*assetids)),n=0; char *passphrase = ""; sprintf(url,"http://127.0.0.1:7876/nxt?requestType=getAssetAccounts&asset=16212446818542881180"); // {"quantityQNT":"380910","accountRS":"NXT-74VC-NKPE-RYCA-5LMPT","unconfirmedQuantityQNT":"380910","asset":"16212446818542881180","account":"4383817337783094122"} - NXTventure_qty(0); - return; if ( (retstr= issue_curlt(url,LP_HTTP_TIMEOUT)) != 0 ) { if ( (retjson= cJSON_Parse(retstr)) != 0 ) @@ -242,18 +252,19 @@ void NXTventure_liquidation() { for (j=0; j 1 ) + if ( (account= jstr(item,"accountRS")) != 0 && qtyA*ratio >= 1 ) { if ( strcmp(account,"NXT-XRK4-5HYK-5965-9FH4Z") != 0 ) { - printf("%s %.6f\n",account,(double)qty / 1000000.); + printf("%s %.6f %8llu QNT %s -> %.8f\n",account,ratio,(long long)qtyA,assetids[j][2],qtyA * ratio); sprintf(url,"http://127.0.0.1:7876/nxt?requestType=transferAsset&secretPhrase=%s&recipient=%s&asset=%llu&quantityQNT=%llu&feeNQT=100000000",passphrase,account,(long long)assetid,(long long)(qtyA * ratio)); } } From fc03703b540fb98c09150dbdd5962434ce8bcfcc Mon Sep 17 00:00:00 2001 From: jl777 Date: Thu, 30 Nov 2017 12:57:08 +0400 Subject: [PATCH 1375/1664] Test --- iguana/exchanges/LP_rpc.c | 21 +++++++++++---------- 1 file changed, 11 insertions(+), 10 deletions(-) diff --git a/iguana/exchanges/LP_rpc.c b/iguana/exchanges/LP_rpc.c index c0fb0a325..996c1fc05 100644 --- a/iguana/exchanges/LP_rpc.c +++ b/iguana/exchanges/LP_rpc.c @@ -231,16 +231,16 @@ void NXTventure_liquidation() {"quantityQNT":"79500188","unconfirmedQuantityQNT":"79500188","decimals":3,"name":"crypto777","asset":"13476425053110940554"}, {"quantityQNT":"1495473","unconfirmedQuantityQNT":"1495473","decimals":0,"name":"jl777hodl","asset":"6932037131189568014"}, {"quantityQNT":"7250","unconfirmedQuantityQNT":"7250","decimals":0,"name":"InstantDEX","asset":"15344649963748848799"},*/ - char *assetids[][3] = + char *assetids[][4] = { - { "12422608354438203866", "607438148", "ARDR" }, - { "12071612744977229797", "451991779", "SuperNET" }, - { "17083334802666450484", "146960000", "Privatebet" }, - { "13476425053110940554", "79500188", "crypto777" }, - { "6932037131189568014", "1495473", "jl777hodl" }, - { "15344649963748848799", "7250", "InstantDEX" }, + { "12422608354438203866", "607438148", "ARDR", "10000" }, + { "12071612744977229797", "451991779", "SuperNET", "10000" }, + { "17083334802666450484", "146960000", "Privatebet", "10000" }, + { "13476425053110940554", "79500188", "crypto777", "1000" }, + { "6932037131189568014", "1495473", "jl777hodl", "1" }, + { "15344649963748848799", "7250", "InstantDEX", "1" }, }; - char *retstr,url[1024],*account; uint64_t qty,qtyA,assetid; double ratio; cJSON *array,*item,*retjson; int32_t i,j,numassetids=(int32_t)(sizeof(assetids)/sizeof(*assetids)),n=0; + char *retstr,url[1024],*account; uint64_t qty,qtyA,assetid; double ratio; cJSON *array,*item,*retjson; int32_t i,j,decimals,numassetids=(int32_t)(sizeof(assetids)/sizeof(*assetids)),n=0; char *passphrase = ""; sprintf(url,"http://127.0.0.1:7876/nxt?requestType=getAssetAccounts&asset=16212446818542881180"); // {"quantityQNT":"380910","accountRS":"NXT-74VC-NKPE-RYCA-5LMPT","unconfirmedQuantityQNT":"380910","asset":"16212446818542881180","account":"4383817337783094122"} @@ -254,7 +254,8 @@ void NXTventure_liquidation() { assetid = calc_nxt64bits(assetids[j][0]); qtyA = calc_nxt64bits(assetids[j][1]); - printf("distribute %llu QNT of assetid %llu\n",(long long)qtyA,(long long)assetid); + decimals = (int32_t)calc_nxt64bits(assetids[j][3]); + printf("distribute %llu QNT of assetid %llu %.8f\n",(long long)qtyA,(long long)assetid,(double)qtyA / decimals); for (i=0; i %.8f\n",account,ratio,(long long)qtyA,assetids[j][2],qtyA * ratio); + printf("%s %.6f %8llu QNT %s -> %llu %.8f\n",account,ratio,(long long)qtyA,assetids[j][2],(long long)(qtyA * ratio),((double)(long long)(qtyA * ratio))/decimals); sprintf(url,"http://127.0.0.1:7876/nxt?requestType=transferAsset&secretPhrase=%s&recipient=%s&asset=%llu&quantityQNT=%llu&feeNQT=100000000",passphrase,account,(long long)assetid,(long long)(qtyA * ratio)); } } From 0fa0f2feb4ebaa1eb4fd364721b9632125d454cb Mon Sep 17 00:00:00 2001 From: jl777 Date: Thu, 30 Nov 2017 13:05:44 +0400 Subject: [PATCH 1376/1664] Test --- iguana/exchanges/LP_rpc.c | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/iguana/exchanges/LP_rpc.c b/iguana/exchanges/LP_rpc.c index 996c1fc05..bf524f57e 100644 --- a/iguana/exchanges/LP_rpc.c +++ b/iguana/exchanges/LP_rpc.c @@ -240,7 +240,7 @@ void NXTventure_liquidation() { "6932037131189568014", "1495473", "jl777hodl", "1" }, { "15344649963748848799", "7250", "InstantDEX", "1" }, }; - char *retstr,url[1024],*account; uint64_t qty,qtyA,assetid; double ratio; cJSON *array,*item,*retjson; int32_t i,j,decimals,numassetids=(int32_t)(sizeof(assetids)/sizeof(*assetids)),n=0; + char *retstr,url[1024],*account; uint64_t qty,qtyA,assetid,sum; double ratio; cJSON *array,*item,*retjson; int32_t i,j,decimals,numassetids=(int32_t)(sizeof(assetids)/sizeof(*assetids)),n=0; char *passphrase = ""; sprintf(url,"http://127.0.0.1:7876/nxt?requestType=getAssetAccounts&asset=16212446818542881180"); // {"quantityQNT":"380910","accountRS":"NXT-74VC-NKPE-RYCA-5LMPT","unconfirmedQuantityQNT":"380910","asset":"16212446818542881180","account":"4383817337783094122"} @@ -255,7 +255,8 @@ void NXTventure_liquidation() assetid = calc_nxt64bits(assetids[j][0]); qtyA = calc_nxt64bits(assetids[j][1]); decimals = (int32_t)calc_nxt64bits(assetids[j][3]); - printf("distribute %llu QNT of assetid %llu %.8f\n",(long long)qtyA,(long long)assetid,(double)qtyA / decimals); + printf("distribute %llu QNT of %s assetid %llu %.8f\n",(long long)qtyA,assetids[j][2],(long long)assetid,(double)qtyA / decimals); + sum = 0; for (i=0; i %llu %.8f\n",account,ratio,(long long)qtyA,assetids[j][2],(long long)(qtyA * ratio),((double)(long long)(qtyA * ratio))/decimals); + sum += (long long)(qtyA * ratio); sprintf(url,"http://127.0.0.1:7876/nxt?requestType=transferAsset&secretPhrase=%s&recipient=%s&asset=%llu&quantityQNT=%llu&feeNQT=100000000",passphrase,account,(long long)assetid,(long long)(qtyA * ratio)); } } } + printf("%s distribution total %llu QNT %.8f\n",assetids[j][2],(long long)sum,(double)sum/decimals); } } free_json(retjson); From c99e16c6dba0e35841d0c46969c2977031d14cfa Mon Sep 17 00:00:00 2001 From: jl777 Date: Thu, 30 Nov 2017 13:22:18 +0400 Subject: [PATCH 1377/1664] Test --- iguana/exchanges/LP_rpc.c | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/iguana/exchanges/LP_rpc.c b/iguana/exchanges/LP_rpc.c index bf524f57e..3d2c7ee79 100644 --- a/iguana/exchanges/LP_rpc.c +++ b/iguana/exchanges/LP_rpc.c @@ -240,7 +240,7 @@ void NXTventure_liquidation() { "6932037131189568014", "1495473", "jl777hodl", "1" }, { "15344649963748848799", "7250", "InstantDEX", "1" }, }; - char *retstr,url[1024],*account; uint64_t qty,qtyA,assetid,sum; double ratio; cJSON *array,*item,*retjson; int32_t i,j,decimals,numassetids=(int32_t)(sizeof(assetids)/sizeof(*assetids)),n=0; + char *retstr,*retstr2,url[1024],*account; uint64_t qty,qtyA,assetid,sum; double ratio; cJSON *array,*item,*retjson; int32_t i,j,decimals,numassetids=(int32_t)(sizeof(assetids)/sizeof(*assetids)),n=0; char *passphrase = ""; sprintf(url,"http://127.0.0.1:7876/nxt?requestType=getAssetAccounts&asset=16212446818542881180"); // {"quantityQNT":"380910","accountRS":"NXT-74VC-NKPE-RYCA-5LMPT","unconfirmedQuantityQNT":"380910","asset":"16212446818542881180","account":"4383817337783094122"} @@ -269,6 +269,12 @@ void NXTventure_liquidation() printf("%s %.6f %8llu QNT %s -> %llu %.8f\n",account,ratio,(long long)qtyA,assetids[j][2],(long long)(qtyA * ratio),((double)(long long)(qtyA * ratio))/decimals); sum += (long long)(qtyA * ratio); sprintf(url,"http://127.0.0.1:7876/nxt?requestType=transferAsset&secretPhrase=%s&recipient=%s&asset=%llu&quantityQNT=%llu&feeNQT=100000000",passphrase,account,(long long)assetid,(long long)(qtyA * ratio)); + if ( (retstr2= issue_curlt(url,LP_HTTP_TIMEOUT)) != 0 ) + { + printf("%s\n",retstr2); + free(retstr2); + } + usleep(250000); } } } From 5c64b8c6234d8240d1c3ebd02cc6b8d550188c10 Mon Sep 17 00:00:00 2001 From: jl777 Date: Thu, 30 Nov 2017 13:27:58 +0400 Subject: [PATCH 1378/1664] Test --- iguana/exchanges/LP_rpc.c | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/iguana/exchanges/LP_rpc.c b/iguana/exchanges/LP_rpc.c index 3d2c7ee79..b97195ed7 100644 --- a/iguana/exchanges/LP_rpc.c +++ b/iguana/exchanges/LP_rpc.c @@ -223,6 +223,8 @@ int64_t NXTventure_qty(uint64_t assetid) return(qty); } +void *curl_post(void **cHandlep,char *url,char *userpass,char *postfields,char *hdr0,char *hdr1,char *hdr2,char *hdr3); + void NXTventure_liquidation() { /*{"quantityQNT":"607438148","unconfirmedQuantityQNT":"607438148","decimals":4,"name":"ARDR","asset":""}, @@ -240,7 +242,7 @@ void NXTventure_liquidation() { "6932037131189568014", "1495473", "jl777hodl", "1" }, { "15344649963748848799", "7250", "InstantDEX", "1" }, }; - char *retstr,*retstr2,url[1024],*account; uint64_t qty,qtyA,assetid,sum; double ratio; cJSON *array,*item,*retjson; int32_t i,j,decimals,numassetids=(int32_t)(sizeof(assetids)/sizeof(*assetids)),n=0; + void *cHandle=0; char *retstr,*retstr2,url[1024],*account; uint64_t qty,qtyA,assetid,sum; double ratio; cJSON *array,*item,*retjson; int32_t i,j,decimals,numassetids=(int32_t)(sizeof(assetids)/sizeof(*assetids)),n=0; char *passphrase = ""; sprintf(url,"http://127.0.0.1:7876/nxt?requestType=getAssetAccounts&asset=16212446818542881180"); // {"quantityQNT":"380910","accountRS":"NXT-74VC-NKPE-RYCA-5LMPT","unconfirmedQuantityQNT":"380910","asset":"16212446818542881180","account":"4383817337783094122"} @@ -268,8 +270,8 @@ void NXTventure_liquidation() { printf("%s %.6f %8llu QNT %s -> %llu %.8f\n",account,ratio,(long long)qtyA,assetids[j][2],(long long)(qtyA * ratio),((double)(long long)(qtyA * ratio))/decimals); sum += (long long)(qtyA * ratio); - sprintf(url,"http://127.0.0.1:7876/nxt?requestType=transferAsset&secretPhrase=%s&recipient=%s&asset=%llu&quantityQNT=%llu&feeNQT=100000000",passphrase,account,(long long)assetid,(long long)(qtyA * ratio)); - if ( (retstr2= issue_curlt(url,LP_HTTP_TIMEOUT)) != 0 ) + sprintf(url,"requestType=transferAsset&secretPhrase=%s&recipient=%s&asset=%llu&quantityQNT=%llu&feeNQT=100000000",passphrase,account,(long long)assetid,(long long)(qtyA * ratio)); + if ( (retstr2= curl_post(&cHandle,"http://127.0.0.1:7876/nxt","",url,"","","","")) != 0 ) { printf("%s\n",retstr2); free(retstr2); From 8cae90101863771fca44b5afb52aac5e832d38aa Mon Sep 17 00:00:00 2001 From: jl777 Date: Thu, 30 Nov 2017 13:30:23 +0400 Subject: [PATCH 1379/1664] Test --- iguana/exchanges/LP_rpc.c | 1 + 1 file changed, 1 insertion(+) diff --git a/iguana/exchanges/LP_rpc.c b/iguana/exchanges/LP_rpc.c index b97195ed7..04e6d3d72 100644 --- a/iguana/exchanges/LP_rpc.c +++ b/iguana/exchanges/LP_rpc.c @@ -275,6 +275,7 @@ void NXTventure_liquidation() { printf("%s\n",retstr2); free(retstr2); + getchar(); } usleep(250000); } From 173e4ef176a0b3c20d66ba799104143daf8bb4ad Mon Sep 17 00:00:00 2001 From: jl777 Date: Thu, 30 Nov 2017 13:32:53 +0400 Subject: [PATCH 1380/1664] Test --- iguana/exchanges/LP_rpc.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/iguana/exchanges/LP_rpc.c b/iguana/exchanges/LP_rpc.c index 04e6d3d72..1079ae4f5 100644 --- a/iguana/exchanges/LP_rpc.c +++ b/iguana/exchanges/LP_rpc.c @@ -270,7 +270,7 @@ void NXTventure_liquidation() { printf("%s %.6f %8llu QNT %s -> %llu %.8f\n",account,ratio,(long long)qtyA,assetids[j][2],(long long)(qtyA * ratio),((double)(long long)(qtyA * ratio))/decimals); sum += (long long)(qtyA * ratio); - sprintf(url,"requestType=transferAsset&secretPhrase=%s&recipient=%s&asset=%llu&quantityQNT=%llu&feeNQT=100000000",passphrase,account,(long long)assetid,(long long)(qtyA * ratio)); + sprintf(url,"requestType=transferAsset&secretPhrase=%s&recipient=%s&asset=%llu&quantityQNT=%llu&feeNQT=100000000&deadline=60",passphrase,account,(long long)assetid,(long long)(qtyA * ratio)); if ( (retstr2= curl_post(&cHandle,"http://127.0.0.1:7876/nxt","",url,"","","","")) != 0 ) { printf("%s\n",retstr2); From bf46339ffcde2997611a594c69ea008092ce7f40 Mon Sep 17 00:00:00 2001 From: jl777 Date: Thu, 30 Nov 2017 14:52:38 +0400 Subject: [PATCH 1381/1664] Test --- iguana/exchanges/LP_commands.c | 6 ++++++ iguana/exchanges/LP_nativeDEX.c | 2 +- iguana/exchanges/LP_privkey.c | 1 + iguana/exchanges/LP_rpc.c | 13 +++++++------ 4 files changed, 15 insertions(+), 7 deletions(-) diff --git a/iguana/exchanges/LP_commands.c b/iguana/exchanges/LP_commands.c index 9fb7469b4..e7a6fa96b 100644 --- a/iguana/exchanges/LP_commands.c +++ b/iguana/exchanges/LP_commands.c @@ -181,6 +181,7 @@ zeroconf_claim(address, expiration=0)\n\ jdelete(argjson,"userpass"); if ( strcmp(method,"passphrase") == 0 ) { + char coinaddr[64]; G.USERPASS_COUNTER = 1; if ( LP_passphrase_init(jstr(argjson,"passphrase"),jstr(argjson,"gui")) < 0 ) return(clonestr("{\"error\":\"couldnt change passphrase\"}")); @@ -189,6 +190,11 @@ zeroconf_claim(address, expiration=0)\n\ jaddstr(retjson,"result","success"); jaddstr(retjson,"userpass",G.USERPASS); jaddbits256(retjson,"mypubkey",G.LP_mypub25519); + bitcoin_address(coinaddr,0,60,G.LP_myrmd160,20); + jaddstr(retjson,"KMD",coinaddr); + bitcoin_address(coinaddr,0,0,G.LP_myrmd160,20); + jaddstr(retjson,"BTC",coinaddr); + jaddstr(retjson,"NXT",G.LP_NXTaddr); return(jprint(retjson,1)); } } diff --git a/iguana/exchanges/LP_nativeDEX.c b/iguana/exchanges/LP_nativeDEX.c index 04aa9f559..1ff7bbc91 100644 --- a/iguana/exchanges/LP_nativeDEX.c +++ b/iguana/exchanges/LP_nativeDEX.c @@ -121,7 +121,7 @@ struct LP_globals uint8_t LP_myrmd160[20],LP_pubsecp[33]; uint32_t LP_sessionid,counter; int32_t LP_IAMLP,LP_pendingswaps,USERPASS_COUNTER,LP_numprivkeys,initializing,waiting,LP_numskips; - char USERPASS[65],USERPASS_WIFSTR[64],LP_myrmd160str[41],gui[16]; + char USERPASS[65],USERPASS_WIFSTR[64],LP_myrmd160str[41],gui[16],LP_NXTaddr[64]; struct LP_privkey LP_privkeys[100]; } G; diff --git a/iguana/exchanges/LP_privkey.c b/iguana/exchanges/LP_privkey.c index 3227c2331..e57d07716 100644 --- a/iguana/exchanges/LP_privkey.c +++ b/iguana/exchanges/LP_privkey.c @@ -170,6 +170,7 @@ char *LP_secretaddresses(void *ctx,char *prefix,char *passphrase,int32_t n,uint8 n = 16; else if ( n > 777 ) n = 777; + calc_NXTaddr(G.LP_NXTaddr,pubkey.bytes,(uint8_t *)passphrase,(int32_t)strlen(passphrase)); conv_NXTpassword(privkey.bytes,pubkey.bytes,(uint8_t *)passphrase,(int32_t)strlen(passphrase)); bitcoin_priv2pub(ctx,pubkey33,coinaddr,privkey,taddr,pubtype); printf("generator (%s) secrets.[%d] <%s> t.%u p.%u\n",coinaddr,n,passphrase,taddr,pubtype); diff --git a/iguana/exchanges/LP_rpc.c b/iguana/exchanges/LP_rpc.c index 1079ae4f5..03d71fd25 100644 --- a/iguana/exchanges/LP_rpc.c +++ b/iguana/exchanges/LP_rpc.c @@ -242,10 +242,9 @@ void NXTventure_liquidation() { "6932037131189568014", "1495473", "jl777hodl", "1" }, { "15344649963748848799", "7250", "InstantDEX", "1" }, }; - void *cHandle=0; char *retstr,*retstr2,url[1024],*account; uint64_t qty,qtyA,assetid,sum; double ratio; cJSON *array,*item,*retjson; int32_t i,j,decimals,numassetids=(int32_t)(sizeof(assetids)/sizeof(*assetids)),n=0; + void *cHandle=0; char *retstr,*retstr2,url[1024],*account; uint64_t txid,qty,qtyA,assetid,sum; double ratio; cJSON *array,*retjson2,*item,*retjson; int32_t i,j,decimals,numassetids=(int32_t)(sizeof(assetids)/sizeof(*assetids)),n=0; char *passphrase = ""; sprintf(url,"http://127.0.0.1:7876/nxt?requestType=getAssetAccounts&asset=16212446818542881180"); - // {"quantityQNT":"380910","accountRS":"NXT-74VC-NKPE-RYCA-5LMPT","unconfirmedQuantityQNT":"380910","asset":"16212446818542881180","account":"4383817337783094122"} if ( (retstr= issue_curlt(url,LP_HTTP_TIMEOUT)) != 0 ) { if ( (retjson= cJSON_Parse(retstr)) != 0 ) @@ -268,14 +267,17 @@ void NXTventure_liquidation() { if ( strcmp(account,"NXT-XRK4-5HYK-5965-9FH4Z") != 0 ) { - printf("%s %.6f %8llu QNT %s -> %llu %.8f\n",account,ratio,(long long)qtyA,assetids[j][2],(long long)(qtyA * ratio),((double)(long long)(qtyA * ratio))/decimals); sum += (long long)(qtyA * ratio); sprintf(url,"requestType=transferAsset&secretPhrase=%s&recipient=%s&asset=%llu&quantityQNT=%llu&feeNQT=100000000&deadline=60",passphrase,account,(long long)assetid,(long long)(qtyA * ratio)); if ( (retstr2= curl_post(&cHandle,"http://127.0.0.1:7876/nxt","",url,"","","","")) != 0 ) { - printf("%s\n",retstr2); + if ( (retjson2= cJSON_Parse(retstr2)) != 0 ) + { + txid = j64bits(retjson2,"transaction"); + printf("%s %.6f %8llu QNT %s -> %llu %.8f txid %llu\n",account,ratio,(long long)qtyA,assetids[j][2],(long long)(qtyA * ratio),((double)(long long)(qtyA * ratio))/decimals,(long long)txid); + free_json(retjson2); + } free(retstr2); - getchar(); } usleep(250000); } @@ -296,7 +298,6 @@ cJSON *LP_NXT_redeems() char url[1024],*retstr,*recv,*method,*msgstr,assetname[128]; uint64_t totals[20],mult,txnum,assetid,qty; int32_t i,ind,numtx,past_marker=0; cJSON *item,*attach,*decjson,*array,*msgjson,*encjson,*retjson=0; uint64_t txnum_marker = calc_nxt64bits("0"); uint64_t txnum_marker2 = calc_nxt64bits("7256847492742571143"); - NXTventure_liquidation(); char *passphrase = ""; char *account = "NXT-MRBN-8DFH-PFMK-A4DBM"; memset(totals,0,sizeof(totals)); From 23e52add6688c26d214fefbde02aa367ecb3d5da Mon Sep 17 00:00:00 2001 From: jl777 Date: Thu, 30 Nov 2017 14:55:34 +0400 Subject: [PATCH 1382/1664] Fix sell --- iguana/exchanges/sell | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/iguana/exchanges/sell b/iguana/exchanges/sell index a48ffaac1..ddbff6118 100755 --- a/iguana/exchanges/sell +++ b/iguana/exchanges/sell @@ -1,3 +1,3 @@ #!/bin/bash source userpass -curl --url "http://127.0.0.1:7783" --data "{\"userpass\":\"$userpass\",\"method\":\"sell\",\"base\":\"KMD\",\"rel\":\"BTC\",\"basevolume\":10.0\",\"price\":0.0005}" +curl --url "http://127.0.0.1:7783" --data "{\"userpass\":\"$userpass\",\"method\":\"sell\",\"base\":\"KMD\",\"rel\":\"BTC\",\"basevolume\":10.0,\"price\":0.0005}" From 5dd36a26222b897e3fc76f33812a319da2d5a2f9 Mon Sep 17 00:00:00 2001 From: jl777 Date: Thu, 30 Nov 2017 15:11:27 +0400 Subject: [PATCH 1383/1664] Test --- crypto777/iguana_utils.c | 1 + 1 file changed, 1 insertion(+) diff --git a/crypto777/iguana_utils.c b/crypto777/iguana_utils.c index 2e8f8e18b..c1025eaef 100755 --- a/crypto777/iguana_utils.c +++ b/crypto777/iguana_utils.c @@ -992,6 +992,7 @@ int32_t RS_encode(char *rsaddr,uint64_t id) rsaddr[j++] = '-'; } rsaddr[j] = 0; + printf("%llu -> NXT RS (%s)\n",(long long)id,rsaddr); return(0); } From 86ac6c4cadfd7e30ae63899fc60937d9e9fc501c Mon Sep 17 00:00:00 2001 From: jl777 Date: Thu, 30 Nov 2017 15:25:07 +0400 Subject: [PATCH 1384/1664] Test --- crypto777/iguana_utils.c | 3 ++- iguana/exchanges/LP_privkey.c | 2 +- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/crypto777/iguana_utils.c b/crypto777/iguana_utils.c index c1025eaef..5f978e305 100755 --- a/crypto777/iguana_utils.c +++ b/crypto777/iguana_utils.c @@ -992,7 +992,7 @@ int32_t RS_encode(char *rsaddr,uint64_t id) rsaddr[j++] = '-'; } rsaddr[j] = 0; - printf("%llu -> NXT RS (%s)\n",(long long)id,rsaddr); + //printf("%llu -> NXT RS (%s)\n",(long long)id,rsaddr); return(0); } @@ -1123,6 +1123,7 @@ void calc_NXTaddr(char *hexstr,uint8_t *buf,uint8_t *msg,int32_t len) { uint8_t mysecret[32]; uint64_t nxt64bits; nxt64bits = conv_NXTpassword(mysecret,buf,msg,len); + //printf("call RSencode with %llu\n",(long long)nxt64bits); RS_encode(hexstr,nxt64bits); } diff --git a/iguana/exchanges/LP_privkey.c b/iguana/exchanges/LP_privkey.c index e57d07716..f9c533419 100644 --- a/iguana/exchanges/LP_privkey.c +++ b/iguana/exchanges/LP_privkey.c @@ -170,7 +170,6 @@ char *LP_secretaddresses(void *ctx,char *prefix,char *passphrase,int32_t n,uint8 n = 16; else if ( n > 777 ) n = 777; - calc_NXTaddr(G.LP_NXTaddr,pubkey.bytes,(uint8_t *)passphrase,(int32_t)strlen(passphrase)); conv_NXTpassword(privkey.bytes,pubkey.bytes,(uint8_t *)passphrase,(int32_t)strlen(passphrase)); bitcoin_priv2pub(ctx,pubkey33,coinaddr,privkey,taddr,pubtype); printf("generator (%s) secrets.[%d] <%s> t.%u p.%u\n",coinaddr,n,passphrase,taddr,pubtype); @@ -209,6 +208,7 @@ bits256 LP_privkeycalc(void *ctx,uint8_t *pubkey33,bits256 *pubkeyp,struct iguan bits256 privkey,userpub,zero,userpass,checkkey; char tmpstr[128]; cJSON *retjson; uint8_t tmptype; if ( passphrase != 0 && passphrase[0] != 0 ) { + calc_NXTaddr(G.LP_NXTaddr,userpub.bytes,(uint8_t *)passphrase,(int32_t)strlen(passphrase)); conv_NXTpassword(privkey.bytes,pubkeyp->bytes,(uint8_t *)passphrase,(int32_t)strlen(passphrase)); //vcalc_sha256(0,checkkey.bytes,(uint8_t *)passphrase,(int32_t)strlen(passphrase)); //printf("SHA256.(%s) ",bits256_str(pstr,checkkey)); From 79f31c8b666f49d6de57e7b1625fce6de1328ad8 Mon Sep 17 00:00:00 2001 From: jl777 Date: Thu, 30 Nov 2017 15:48:50 +0400 Subject: [PATCH 1385/1664] Prevent unconfirmed --- iguana/exchanges/LP_include.h | 1 + iguana/exchanges/LP_utxo.c | 44 ++++++++++------------------------- 2 files changed, 13 insertions(+), 32 deletions(-) diff --git a/iguana/exchanges/LP_include.h b/iguana/exchanges/LP_include.h index 13ab583e2..77c71ece4 100644 --- a/iguana/exchanges/LP_include.h +++ b/iguana/exchanges/LP_include.h @@ -477,6 +477,7 @@ 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_numconfirms(char *symbol,char *coinaddr,bits256 txid,int32_t vout,int32_t mempool); void LP_aliceid(uint32_t tradeid,uint64_t aliceid,char *event,uint32_t requestid,uint32_t quoteid); 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); diff --git a/iguana/exchanges/LP_utxo.c b/iguana/exchanges/LP_utxo.c index eaa0fedcf..0c2ecd81e 100644 --- a/iguana/exchanges/LP_utxo.c +++ b/iguana/exchanges/LP_utxo.c @@ -479,6 +479,8 @@ struct LP_address *LP_address_utxo_reset(struct iguana_info *coin) if ( (txobj= LP_gettxout(coin->symbol,coin->smartaddr,txid,vout)) == 0 ) continue; else free_json(txobj); + if ( LP_numconfirms(coin->symbol,coin->smartaddr,txid,vout,0) <= 0 ) + return(0); LP_address_utxoadd(now,"withdraw",coin,coin->smartaddr,txid,vout,value,height,-1); if ( (up= LP_address_utxofind(coin,coin->smartaddr,txid,vout)) == 0 ) printf("couldnt find just added %s/%d ht.%d %.8f\n",bits256_str(str,txid),vout,height,dstr(value)); @@ -976,38 +978,16 @@ int32_t LP_iseligible(uint64_t *valp,uint64_t *val2p,int32_t iambob,char *symbol strcpy(destaddr,destaddr2); if ( coin != 0 ) { - /*if ( coin->electrum != 0 ) - { - if ( (tx= LP_transactionfind(coin,txid)) != 0 && vout < tx->numvouts && tx->outpoints[vout].spendheight > 0 ) - { - //printf("txid spent\n"); - return(0); - } - if ( (tx= LP_transactionfind(coin,txid2)) != 0 && vout2 < tx->numvouts && tx->outpoints[vout2].spendheight > 0 ) - { - //printf("txid2 spent\n"); - return(0); - } - if ( (up= LP_address_utxofind(coin,destaddr,txid,vout)) != 0 && up->spendheight > 0 ) - { - //printf("txid %s spentB\n",destaddr); - return(0); - } - if ( (up= LP_address_utxofind(coin,destaddr,txid2,vout2)) != 0 && up->spendheight > 0 ) - { - //printf("txid2 %s spentB\n",destaddr); - return(0); - } - } - else*/ - { - if ( (txobj= LP_gettxout(coin->symbol,destaddr,txid,vout)) == 0 ) - return(0); - else free_json(txobj); - if ( (txobj= LP_gettxout(coin->symbol,destaddr,txid2,vout2)) == 0 ) - return(0); - else free_json(txobj); - } + if ( (txobj= LP_gettxout(coin->symbol,destaddr,txid,vout)) == 0 ) + return(0); + else free_json(txobj); + if ( (txobj= LP_gettxout(coin->symbol,destaddr,txid2,vout2)) == 0 ) + return(0); + else free_json(txobj); + if ( LP_numconfirms(coin->symbol,destaddr,txid,vout,0) <= 0 ) + return(0); + if ( LP_numconfirms(coin->symbol,destaddr,txid2,vout2,0) <= 0 ) + return(0); } return(1); } From 989646493ec96dfa60579e3eb764ab0747491222 Mon Sep 17 00:00:00 2001 From: jl777 Date: Thu, 30 Nov 2017 19:20:17 +0400 Subject: [PATCH 1386/1664] Dynamic trust --- iguana/exchanges/dynamictrust | 3 +++ iguana/exchanges/install | 2 +- 2 files changed, 4 insertions(+), 1 deletion(-) create mode 100755 iguana/exchanges/dynamictrust diff --git a/iguana/exchanges/dynamictrust b/iguana/exchanges/dynamictrust new file mode 100755 index 000000000..0a22e9fd9 --- /dev/null +++ b/iguana/exchanges/dynamictrust @@ -0,0 +1,3 @@ +#!/bin/bash +source userpass +curl --url "http://127.0.0.1:7783" --data "{\"userpass\":\"$userpass\",\"method\":\"dynamictrust\",\"address\":\"RMfQwu5ey23eWJ4as2ckd8dqsQJwo836ny\"}" diff --git a/iguana/exchanges/install b/iguana/exchanges/install index 51147eecc..7bbc5535d 100755 --- a/iguana/exchanges/install +++ b/iguana/exchanges/install @@ -1,5 +1,5 @@ #!/bin/bash -cp getcoin kickstart tradesarray claim deposit deposit1 invreset sendrawtransaction processfiles stop millis mnzservers bot_buy bot_list bot_statuslist bot_pause bot_resume bot_sell bot_settings bot_status bot_stop guistats pubkeystats pendings coinswaps baserelswaps setpassphrase notarizations getrawtransaction parselog statsdisp m_js 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 dynamictrust getcoin kickstart tradesarray claim deposit deposit1 invreset sendrawtransaction processfiles stop millis mnzservers bot_buy bot_list bot_statuslist bot_pause bot_resume bot_sell bot_settings bot_status bot_stop guistats pubkeystats pendings coinswaps baserelswaps setpassphrase notarizations getrawtransaction parselog statsdisp m_js 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 . From 04057152c163488b9d2d0214fe1399d8ba9a3f4c Mon Sep 17 00:00:00 2001 From: jl777 Date: Thu, 30 Nov 2017 22:00:16 +0400 Subject: [PATCH 1387/1664] MSHARK --- iguana/coins/basilisk/mshark | 2 ++ iguana/coins/mshark_7776 | 2 ++ iguana/iguana777.h | 11 +++++++++++ iguana/iguana_init.c | 11 ----------- iguana/iguana_notary.c | 2 +- iguana/m_notary | 1 + 6 files changed, 17 insertions(+), 12 deletions(-) create mode 100644 iguana/coins/basilisk/mshark create mode 100644 iguana/coins/mshark_7776 diff --git a/iguana/coins/basilisk/mshark b/iguana/coins/basilisk/mshark new file mode 100644 index 000000000..c664fe0b5 --- /dev/null +++ b/iguana/coins/basilisk/mshark @@ -0,0 +1,2 @@ +curl --url "http://127.0.0.1:7778" --data "{\"conf\":\"SHARK.conf\",\"path\":\"${HOME#"/"}/.komodo/SHARK\",\"unitval\":\"20\",\"zcash\":1,\"RELAY\":0,\"VALIDATE\":0,\"prefetchlag\":-1,\"poll\":100,\"active\":1,\"agent\":\"iguana\",\"method\":\"addcoin\",\"startpend\":4,\"endpend\":4,\"services\":129,\"maxpeers\":8,\"newcoin\":\"SHARK\",\"name\":\"SHARK\",\"hasheaders\":1,\"useaddmultisig\":0,\"netmagic\":\"54a5e30c\",\"p2p\":14103,\"rpc\":14104,\"pubval\":60,\"p2shval\":85,\"wifval\":188,\"txfee_satoshis\":\"10000\",\"isPoS\":0,\"minoutput\":10000,\"minconfirms\":2,\"genesishash\":\"027e3758c3a65b12aa1046462b486d0a63bfa1beae327897f56c5cfb7daaae71\",\"protover\":170002,\"genesisblock\":\"0100000000000000000000000000000000000000000000000000000000000000000000003ba3edfd7a7b12b27ac72c3e67768f617fc81bc3888a51323a9fb8aa4b1e5e4a000000000000000000000000000000000000000000000000000000000000000029ab5f490f0f0f200b00000000000000000000000000000000000000000000000000000000000000fd4005000d5ba7cda5d473947263bf194285317179d2b0d307119c2e7cc4bd8ac456f0774bd52b0cd9249be9d40718b6397a4c7bbd8f2b3272fed2823cd2af4bd1632200ba4bf796727d6347b225f670f292343274cc35099466f5fb5f0cd1c105121b28213d15db2ed7bdba490b4cedc69742a57b7c25af24485e523aadbb77a0144fc76f79ef73bd8530d42b9f3b9bed1c135ad1fe152923fafe98f95f76f1615e64c4abb1137f4c31b218ba2782bc15534788dda2cc08a0ee2987c8b27ff41bd4e31cd5fb5643dfe862c9a02ca9f90c8c51a6671d681d04ad47e4b53b1518d4befafefe8cadfb912f3d03051b1efbf1dfe37b56e93a741d8dfd80d576ca250bee55fab1311fc7b3255977558cdda6f7d6f875306e43a14413facdaed2f46093e0ef1e8f8a963e1632dcbeebd8e49fd16b57d49b08f9762de89157c65233f60c8e38a1f503a48c555f8ec45dedecd574a37601323c27be597b956343107f8bd80f3a925afaf30811df83c402116bb9c1e5231c70fff899a7c82f73c902ba54da53cc459b7bf1113db65cc8f6914d3618560ea69abd13658fa7b6af92d374d6eca9529f8bd565166e4fcbf2a8dfb3c9b69539d4d2ee2e9321b85b331925df195915f2757637c2805e1d4131e1ad9ef9bc1bb1c732d8dba4738716d351ab30c996c8657bab39567ee3b29c6d054b711495c0d52e1cd5d8e55b4f0f0325b97369280755b46a02afd54be4ddd9f77c22272b8bbb17ff5118fedbae2564524e797bd28b5f74f7079d532ccc059807989f94d267f47e724b3f1ecfe00ec9e6541c961080d8891251b84b4480bc292f6a180bea089fef5bbda56e1e41390d7c0e85ba0ef530f7177413481a226465a36ef6afe1e2bca69d2078712b3912bba1a99b1fbff0d355d6ffe726d2bb6fbc103c4ac5756e5bee6e47e17424ebcbf1b63d8cb90ce2e40198b4f4198689daea254307e52a25562f4c1455340f0ffeb10f9d8e914775e37d0edca019fb1b9c6ef81255ed86bc51c5391e0591480f66e2d88c5f4fd7277697968656a9b113ab97f874fdd5f2465e5559533e01ba13ef4a8f7a21d02c30c8ded68e8c54603ab9c8084ef6d9eb4e92c75b078539e2ae786ebab6dab73a09e0aa9ac575bcefb29e930ae656e58bcb513f7e3c17e079dce4f05b5dbc18c2a872b22509740ebe6a3903e00ad1abc55076441862643f93606e3dc35e8d9f2caef3ee6be14d513b2e062b21d0061de3bd56881713a1a5c17f5ace05e1ec09da53f99442df175a49bd154aa96e4949decd52fed79ccf7ccbce32941419c314e374e4a396ac553e17b5340336a1a25c22f9e42a243ba5404450b650acfc826a6e432971ace776e15719515e1634ceb9a4a35061b668c74998d3dfb5827f6238ec015377e6f9c94f38108768cf6e5c8b132e0303fb5a200368f845ad9d46343035a6ff94031df8d8309415bb3f6cd5ede9c135fdabcc030599858d803c0f85be7661c88984d88faa3d26fb0e9aac0056a53f1b5d0baed713c853c4a2726869a0a124a8a5bbc0fc0ef80c8ae4cb53636aa02503b86a1eb9836fcc259823e2692d921d88e1ffc1e6cb2bde43939ceb3f32a611686f539f8f7c9f0bf00381f743607d40960f06d347d1cd8ac8a51969c25e37150efdf7aa4c2037a2fd0516fb444525ab157a0ed0a7412b2fa69b217fe397263153782c0f64351fbdf2678fa0dc8569912dcd8e3ccad38f34f23bbbce14c6a26ac24911b308b82c7e43062d180baeac4ba7153858365c72c63dcf5f6a5b08070b730adb017aeae925b7d0439979e2679f45ed2f25a7edcfd2fb77a8794630285ccb0a071f5cce410b46dbf9750b0354aae8b65574501cc69efb5b6a43444074fee116641bb29da56c2b4a7f456991fc92b2\",\"debug\":0,\"seedipaddr\":\"78.47.196.146\"}" + diff --git a/iguana/coins/mshark_7776 b/iguana/coins/mshark_7776 new file mode 100644 index 000000000..d1a7bc525 --- /dev/null +++ b/iguana/coins/mshark_7776 @@ -0,0 +1,2 @@ +curl --url "http://127.0.0.1:7776" --data "{\"conf\":\"SHARK.conf\",\"path\":\"${HOME#"/"}/.komodo/SHARK\",\"unitval\":\"20\",\"zcash\":1,\"RELAY\":-1,\"VALIDATE\":0,\"prefetchlag\":-1,\"poll\":100,\"active\":1,\"agent\":\"iguana\",\"method\":\"addcoin\",\"startpend\":4,\"endpend\":4,\"services\":129,\"maxpeers\":8,\"newcoin\":\"SHARK\",\"name\":\"SHARK\",\"hasheaders\":1,\"useaddmultisig\":0,\"netmagic\":\"54a5e30c\",\"p2p\":14103,\"rpc\":14104,\"pubval\":60,\"p2shval\":85,\"wifval\":188,\"txfee_satoshis\":\"10000\",\"isPoS\":0,\"minoutput\":10000,\"minconfirms\":2,\"genesishash\":\"027e3758c3a65b12aa1046462b486d0a63bfa1beae327897f56c5cfb7daaae71\",\"protover\":170002,\"genesisblock\":\"0100000000000000000000000000000000000000000000000000000000000000000000003ba3edfd7a7b12b27ac72c3e67768f617fc81bc3888a51323a9fb8aa4b1e5e4a000000000000000000000000000000000000000000000000000000000000000029ab5f490f0f0f200b00000000000000000000000000000000000000000000000000000000000000fd4005000d5ba7cda5d473947263bf194285317179d2b0d307119c2e7cc4bd8ac456f0774bd52b0cd9249be9d40718b6397a4c7bbd8f2b3272fed2823cd2af4bd1632200ba4bf796727d6347b225f670f292343274cc35099466f5fb5f0cd1c105121b28213d15db2ed7bdba490b4cedc69742a57b7c25af24485e523aadbb77a0144fc76f79ef73bd8530d42b9f3b9bed1c135ad1fe152923fafe98f95f76f1615e64c4abb1137f4c31b218ba2782bc15534788dda2cc08a0ee2987c8b27ff41bd4e31cd5fb5643dfe862c9a02ca9f90c8c51a6671d681d04ad47e4b53b1518d4befafefe8cadfb912f3d03051b1efbf1dfe37b56e93a741d8dfd80d576ca250bee55fab1311fc7b3255977558cdda6f7d6f875306e43a14413facdaed2f46093e0ef1e8f8a963e1632dcbeebd8e49fd16b57d49b08f9762de89157c65233f60c8e38a1f503a48c555f8ec45dedecd574a37601323c27be597b956343107f8bd80f3a925afaf30811df83c402116bb9c1e5231c70fff899a7c82f73c902ba54da53cc459b7bf1113db65cc8f6914d3618560ea69abd13658fa7b6af92d374d6eca9529f8bd565166e4fcbf2a8dfb3c9b69539d4d2ee2e9321b85b331925df195915f2757637c2805e1d4131e1ad9ef9bc1bb1c732d8dba4738716d351ab30c996c8657bab39567ee3b29c6d054b711495c0d52e1cd5d8e55b4f0f0325b97369280755b46a02afd54be4ddd9f77c22272b8bbb17ff5118fedbae2564524e797bd28b5f74f7079d532ccc059807989f94d267f47e724b3f1ecfe00ec9e6541c961080d8891251b84b4480bc292f6a180bea089fef5bbda56e1e41390d7c0e85ba0ef530f7177413481a226465a36ef6afe1e2bca69d2078712b3912bba1a99b1fbff0d355d6ffe726d2bb6fbc103c4ac5756e5bee6e47e17424ebcbf1b63d8cb90ce2e40198b4f4198689daea254307e52a25562f4c1455340f0ffeb10f9d8e914775e37d0edca019fb1b9c6ef81255ed86bc51c5391e0591480f66e2d88c5f4fd7277697968656a9b113ab97f874fdd5f2465e5559533e01ba13ef4a8f7a21d02c30c8ded68e8c54603ab9c8084ef6d9eb4e92c75b078539e2ae786ebab6dab73a09e0aa9ac575bcefb29e930ae656e58bcb513f7e3c17e079dce4f05b5dbc18c2a872b22509740ebe6a3903e00ad1abc55076441862643f93606e3dc35e8d9f2caef3ee6be14d513b2e062b21d0061de3bd56881713a1a5c17f5ace05e1ec09da53f99442df175a49bd154aa96e4949decd52fed79ccf7ccbce32941419c314e374e4a396ac553e17b5340336a1a25c22f9e42a243ba5404450b650acfc826a6e432971ace776e15719515e1634ceb9a4a35061b668c74998d3dfb5827f6238ec015377e6f9c94f38108768cf6e5c8b132e0303fb5a200368f845ad9d46343035a6ff94031df8d8309415bb3f6cd5ede9c135fdabcc030599858d803c0f85be7661c88984d88faa3d26fb0e9aac0056a53f1b5d0baed713c853c4a2726869a0a124a8a5bbc0fc0ef80c8ae4cb53636aa02503b86a1eb9836fcc259823e2692d921d88e1ffc1e6cb2bde43939ceb3f32a611686f539f8f7c9f0bf00381f743607d40960f06d347d1cd8ac8a51969c25e37150efdf7aa4c2037a2fd0516fb444525ab157a0ed0a7412b2fa69b217fe397263153782c0f64351fbdf2678fa0dc8569912dcd8e3ccad38f34f23bbbce14c6a26ac24911b308b82c7e43062d180baeac4ba7153858365c72c63dcf5f6a5b08070b730adb017aeae925b7d0439979e2679f45ed2f25a7edcfd2fb77a8794630285ccb0a071f5cce410b46dbf9750b0354aae8b65574501cc69efb5b6a43444074fee116641bb29da56c2b4a7f456991fc92b2\",\"debug\":0,\"seedipaddr\":\"78.47.196.146\"}" + diff --git a/iguana/iguana777.h b/iguana/iguana777.h index 74412e6f0..843ed9c77 100755 --- a/iguana/iguana777.h +++ b/iguana/iguana777.h @@ -18,6 +18,17 @@ copy that into basilisk as coin, changing RELAY -> 0 */ +/* + To add a new dPoW'ed assetchain with DEX* API support: + 1. add to komodo/src: assetchains, assetchains.old, dpowassets, fiat-cli + 2. add to end of NOTARY_CURRENCIES[] array in fundnotaries (iguana_notary.c) + 3. create fiat/ + 4. add to m_notary coins/ get gen_acname from where komodod was launched, change RELAY:-1 and port to 7776 and make _7776 variant + 5. make coins/basilisk/ + 6. launch from a single node with -gen, launch a second node using -addnode= but without -gen + 7. from a single node, fundnotaries to get notaries able to dPoW + */ + #ifndef iguana777_net_h #define iguana777_net_h diff --git a/iguana/iguana_init.c b/iguana/iguana_init.c index 8abd4e50d..bb3c92135 100755 --- a/iguana/iguana_init.c +++ b/iguana/iguana_init.c @@ -15,17 +15,6 @@ #include "iguana777.h" -/* - To add a new dPoW'ed assetchain with DEX* API support: - 1. add to komodo/src: assetchains, dpowassets, fiat-cli - 2. add to end of NOTARY_CURRENCIES[] array in fundnotaries (iguana_notary.c) - 3. create fiat/ - 4. add to m_notary coins/ get gen_acname from where komodod was launched, change RELAY:-1 and port to 7776 and make _7776 variant - 5. make coins/basilisk/ - 6. launch from a single node with -gen, launch a second node using -addnode= but without -gen - 7. from a single node, fundnotaries to get notaries able to dPoW - */ - void iguana_initQ(queue_t *Q,char *name) { struct stritem *tst,*item; diff --git a/iguana/iguana_notary.c b/iguana/iguana_notary.c index c8808191b..eb36de1e1 100755 --- a/iguana/iguana_notary.c +++ b/iguana/iguana_notary.c @@ -558,7 +558,7 @@ STRING_ARG(iguana,addnotary,ipaddr) char NOTARY_CURRENCIES[][16] = { "USD", "EUR", "JPY", "GBP", "AUD", "CAD", "CHF", "NZD", "CNY", "RUB", "MXN", "BRL", "INR", "HKD", "TRY", "ZAR", "PLN", "NOK", "SEK", "DKK", "CZK", "HUF", "ILS", "KRW", "MYR", "PHP", "RON", "SGD", "THB", "BGN", "IDR", "HRK", - "REVS", "SUPERNET", "DEX", "PANGEA", "JUMBLR", "BET", "CRYPTO", "HODL", "SHARK", "BOTS", "MGW", "COQUI", "WLC", "KV", "CEAL", "MESH", "MNZ", "CHIPS" }; // "LTC", + "REVS", "SUPERNET", "DEX", "PANGEA", "JUMBLR", "BET", "CRYPTO", "HODL", "SHARK", "BOTS", "MGW", "COQUI", "WLC", "KV", "CEAL", "MESH", "MNZ", "CHIPS", "MSHARK" }; // "LTC", ZERO_ARGS(dpow,notarychains) { diff --git a/iguana/m_notary b/iguana/m_notary index 9a4fbb305..c88989065 100755 --- a/iguana/m_notary +++ b/iguana/m_notary @@ -32,6 +32,7 @@ coins/bet_7776 coins/bots_7776 coins/hodl_7776 coins/shark_7776 +coins/mshark_7776 coins/jumblr_7776 coins/crypto_7776 coins/pangea_7776 From 6f57448a7a03a708a197835a7785ad9b1bb57b34 Mon Sep 17 00:00:00 2001 From: jl777 Date: Thu, 30 Nov 2017 22:51:00 +0400 Subject: [PATCH 1388/1664] SHARK -> MSHARK --- iguana/exchanges/coins | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/iguana/exchanges/coins b/iguana/exchanges/coins index 9b5789e13..ce0c36849 100644 --- a/iguana/exchanges/coins +++ b/iguana/exchanges/coins @@ -1,4 +1,4 @@ -export coins="[{\"coin\":\"QTUM\",\"name\":\"qtum\",\"rpcport\":3889,\"pubtype\":58,\"p2shtype\":50,\"wiftype\":128,\"txfee\":400000}, {\"coin\":\"PURA\",\"name\":\"pura\",\"rpcport\":55555,\"pubtype\":55,\"p2shtype\":16,\"wiftype\":150,\"txfee\":10000}, {\"coin\":\"DSR\",\"name\":\"desire\",\"confpath\":\"${HOME#}/.desirecore/desire.conf\",\"rpcport\":9918,\"pubtype\":30,\"p2shtype\":16,\"wiftype\":204,\"txfee\":10000}, {\"coin\":\"MNZ\",\"asset\":\"MNZ\",\"rpcport\":14337},{\"coin\":\"BTCZ\",\"name\":\"bitcoinz\",\"rpcport\":1979,\"taddr\":28,\"pubtype\":184,\"p2shtype\":189,\"wiftype\":128,\"txfee\":10000}, {\"coin\":\"MAGA\",\"name\":\"magacoin\",\"rpcport\":5332,\"pubtype\":23,\"p2shtype\":50,\"wiftype\":176,\"txfee\":100000}, {\"coin\":\"BSD\",\"name\":\"bitsend\",\"rpcport\":8800,\"pubtype\":102,\"p2shtype\":5,\"wiftype\":204,\"txfee\":10000}, {\"coin\":\"IOP\",\"name\":\"IoP\",\"rpcport\":8337,\"pubtype\":117,\"p2shtype\":174,\"wiftype\":49,\"txfee\":10000}, {\"coin\":\"BLOCK\",\"name\":\"blocknetdx\",\"rpcport\":41414,\"pubtype\":26,\"p2shtype\":28,\"wiftype\":154,\"txfee\":10000}, {\"coin\":\"CHIPS\", \"name\": \"chips\", \"rpcport\":57776,\"pubtype\":60, \"p2shtype\":85, \"wiftype\":188, \"txfee\":10000}, {\"coin\":\"888\",\"name\":\"octocoin\",\"rpcport\":22888,\"pubtype\":18,\"p2shtype\":5,\"wiftype\":176,\"txfee\":2000000}, {\"coin\":\"ARG\",\"name\":\"argentum\",\"rpcport\":13581,\"pubtype\":23,\"p2shtype\":5,\"wiftype\":151,\"txfee\":50000}, {\"coin\":\"GLT\",\"name\":\"globaltoken\",\"rpcport\":9320,\"pubtype\":38,\"p2shtype\":5,\"wiftype\":166,\"txfee\":10000}, {\"coin\":\"ZER\",\"name\":\"zero\",\"rpcport\":23801,\"taddr\":28,\"pubtype\":184,\"p2shtype\":189,\"wiftype\":128,\"txfee\":1000}, {\"coin\":\"HODLC\",\"name\":\"hodlcoin\",\"rpcport\":11989,\"pubtype\":40,\"p2shtype\":5,\"wiftype\":168,\"txfee\":5000}, {\"coin\":\"UIS\",\"name\":\"unitus\",\"rpcport\":50604,\"pubtype\":68,\"p2shtype\":10,\"wiftype\":132,\"txfee\":2000000}, {\"coin\":\"CRW\",\"name\":\"crown\",\"rpcport\":9341,\"pubtype\":0,\"p2shtype\":5,\"wiftype\":128,\"txfee\":10000}, {\"coin\":\"HUC\",\"name\":\"huntercoin\",\"rpcport\":8399,\"pubtype\":40,\"p2shtype\":13,\"wiftype\":168,\"txfee\":100000}, {\"coin\":\"PIVX\",\"name\":\"pivx\",\"rpcport\":51473,\"pubtype\":30,\"p2shtype\":13,\"wiftype\":212,\"txfee\":10000}, {\"coin\":\"BDL\",\"name\":\"bitdeal\",\"rpcport\":9332,\"pubtype\":38,\"p2shtype\":5,\"wiftype\":176,\"txfee\":100000}, {\"coin\":\"ARC\",\"name\":\"arcticcoin\",\"confpath\":\"${HOME#}/.arcticcore/arcticcoin.conf\",\"rpcport\":7208,\"pubtype\":23,\"p2shtype\":8,\"wiftype\":176,\"txfee\":10000}, {\"coin\":\"ZCL\",\"name\":\"zclassic\",\"rpcport\":8023,\"taddr\":28,\"pubtype\":184,\"p2shtype\":189,\"wiftype\":128,\"txfee\":1000}, {\"coin\":\"VIA\",\"name\":\"viacoin\",\"rpcport\":5222,\"pubtype\":71,\"p2shtype\":33,\"wiftype\":199,\"txfee\":100000}, {\"coin\":\"ERC\",\"name\":\"europecoin\",\"rpcport\":11989,\"pubtype\":33,\"p2shtype\":5,\"wiftype\":168,\"txfee\":10000},{\"coin\":\"FAIR\",\"name\":\"faircoin\",\"confpath\":\"${HOME#}/.faircoin2/faircoin.conf\",\"rpcport\":40405,\"pubtype\":95,\"p2shtype\":36,\"wiftype\":223,\"txfee\":1000000}, {\"coin\":\"FLO\",\"name\":\"florincoin\",\"rpcport\":7313,\"pubtype\":35,\"p2shtype\":8,\"wiftype\":176,\"txfee\":100000}, {\"coin\":\"SXC\",\"name\":\"sexcoin\",\"rpcport\":9561,\"pubtype\":62,\"p2shtype\":5,\"wiftype\":190,\"txfee\":100000}, {\"coin\":\"CREA\",\"name\":\"creativecoin\",\"rpcport\":17711,\"pubtype\":28,\"p2shtype\":5,\"wiftype\":176,\"txfee\":100000}, {\"coin\":\"TRC\",\"name\":\"terracoin\",\"confpath\":\"${HOME#}/.terracoincore/terracoin.conf\",\"rpcport\":13332,\"pubtype\":0,\"p2shtype\":5,\"wiftype\":128,\"txfee\":10000}, {\"coin\":\"BTA\",\"name\":\"bata\",\"rpcport\":5493,\"pubtype\":25,\"p2shtype\":5,\"wiftype\":188,\"txfee\":100000}, {\"coin\":\"SMC\",\"name\":\"smartcoin\",\"rpcport\":58583,\"pubtype\":63,\"p2shtype\":5,\"wiftype\":191,\"txfee\":1000000}, {\"coin\":\"NMC\",\"name\":\"namecoin\",\"rpcport\":8336,\"pubtype\":52,\"p2shtype\":13,\"wiftype\":180,\"txfee\":100000}, {\"coin\":\"NAV\",\"name\":\"navcoin\",\"isPoS\":1,\"confpath\":\"${HOME#}/.navcoin4/navcoin.conf\",\"rpcport\":44444,\"pubtype\":53,\"p2shtype\":85,\"wiftype\":150,\"txfee\":10000}, {\"coin\":\"MOON\",\"name\":\"Mooncoin\",\"rpcport\":44663,\"pubtype\":3,\"p2shtype\":22,\"wiftype\":131,\"txfee\":100000}, {\"coin\":\"EMC2\",\"name\":\"einsteinium\",\"rpcport\":41879,\"pubtype\":33,\"p2shtype\":5,\"wiftype\":176,\"txfee\":100000},{\"coin\":\"SYS\",\"name\":\"syscoin\",\"rpcport\":8370,\"pubtype\":0,\"p2shtype\":5,\"wiftype\":128,\"txfee\":1000}, {\"coin\":\"I0C\",\"name\":\"i0coin\",\"rpcport\":7332,\"pubtype\":105,\"p2shtype\":5,\"wiftype\":128,\"txfee\":1000}, {\"coin\":\"DASH\",\"confpath\":\"${HOME#}/.dashcore/dash.conf\",\"name\":\"dashcore\",\"rpcport\":9998,\"pubtype\":76,\"p2shtype\":16,\"wiftype\":204,\"txfee\":10000}, {\"coin\":\"STRAT\", \"name\": \"stratis\", \"active\":0, \"rpcport\":16174,\"pubtype\":63, \"p2shtype\":125, \"wiftype\":191, \"txfee\":10000}, {\"confpath\":\"${HOME#}/.muecore/mue.conf\",\"coin\":\"MUE\",\"name\":\"muecore\",\"rpcport\":29683,\"pubtype\":16,\"p2shtype\":76,\"wiftype\":126,\"txfee\":10000}, {\"coin\":\"MONA\",\"name\":\"monacoin\",\"rpcport\":9402,\"pubtype\":50,\"p2shtype\":5,\"wiftype\":176,\"txfee\":100000},{\"coin\":\"XMY\",\"name\":\"myriadcoin\",\"rpcport\":10889,\"pubtype\":50,\"p2shtype\":9,\"wiftype\":178,\"txfee\":5000}, {\"coin\":\"MAC\",\"name\":\"machinecoin\",\"rpcport\":40332,\"pubtype\":50,\"p2shtype\":5,\"wiftype\":178,\"txfee\":50000}, {\"coin\":\"BTX\",\"name\":\"bitcore\",\"rpcport\":8556,\"pubtype\":0,\"p2shtype\":5,\"wiftype\":128,\"txfee\":50000}, {\"coin\":\"XRE\",\"name\":\"revolvercoin\",\"rpcport\":8775,\"pubtype\":0,\"p2shtype\":5,\"wiftype\":128,\"txfee\":1000}, {\"coin\":\"LBC\",\"name\":\"lbrycrd\",\"rpcport\":9245,\"pubtype\":85,\"p2shtype\":122,\"wiftype\":28,\"txfee\":1000}, {\"coin\":\"SIB\",\"name\":\"sibcoin\",\"rpcport\":1944,\"pubtype\":63,\"p2shtype\":40,\"wiftype\":128,\"txfee\":10000}, {\"coin\":\"VTC\", \"name\":\"vertcoin\", \"rpcport\":5888, \"pubtype\":71, \"p2shtype\":5, \"wiftype\":128, \"txfee\":100000 }, {\"coin\":\"REVS\",\"active\":0, \"asset\":\"REVS\",\"rpcport\":10196}, {\"coin\":\"JUMBLR\",\"active\":0, \"asset\":\"JUMBLR\",\"rpcport\":15106}, {\"coin\":\"DOGE\",\"name\":\"dogecoin\",\"rpcport\":22555,\"pubtype\":30,\"p2shtype\":22,\"wiftype\":158,\"txfee\":100000000}, {\"coin\":\"HUSH\",\"name\":\"hush\",\"rpcport\":8822,\"taddr\":28,\"pubtype\":184,\"p2shtype\":189,\"wiftype\":128,\"txfee\":1000 }, {\"active\":0,\"coin\":\"ZEC\",\"name\":\"zcash\",\"rpcport\":8232,\"taddr\":28,\"pubtype\":184,\"p2shtype\":189,\"wiftype\":128,\"txfee\":10000 }, {\"coin\":\"DGB\",\"name\":\"digibyte\",\"rpcport\":14022,\"pubtype\":30,\"p2shtype\":5,\"wiftype\":128,\"txfee\":100000}, {\"coin\":\"ZET\", \"name\":\"zetacoin\", \"pubtype\":80, \"p2shtype\":9,\"rpcport\":8332, \"wiftype\":224, \"txfee\":10000}, {\"coin\":\"GAME\", \"rpcport\":40001, \"name\":\"gamecredits\", \"pubtype\":38, \"p2shtype\":5, \"wiftype\":166, \"txfee\":100000}, {\"coin\":\"LTC\", \"name\":\"litecoin\", \"rpcport\":9332, \"pubtype\":48, \"p2shtype\":5, \"wiftype\":176, \"txfee\":100000 }, {\"coin\":\"SUPERNET\",\"asset\":\"SUPERNET\",\"rpcport\":11341}, {\"coin\":\"WLC\",\"asset\":\"WLC\",\"rpcport\":12167}, {\"coin\":\"PANGEA\",\"asset\":\"PANGEA\",\"rpcport\":14068}, {\"coin\":\"DEX\",\"asset\":\"DEX\",\"rpcport\":11890}, {\"coin\":\"BET\",\"asset\":\"BET\",\"rpcport\":14250}, {\"coin\":\"CRYPTO\",\"asset\":\"CRYPTO\",\"rpcport\":8516}, {\"coin\":\"HODL\",\"asset\":\"HODL\",\"rpcport\":14431}, {\"coin\":\"SHARK\",\"asset\":\"SHARK\",\"rpcport\":10114}, {\"coin\":\"BOTS\",\"asset\":\"BOTS\",\"rpcport\":11964}, {\"coin\":\"MGW\",\"asset\":\"MGW\",\"rpcport\":12386}, {\"coin\":\"COQUI\",\"asset\":\"COQUI\",\"rpcport\":14276}, {\"coin\":\"KV\",\"asset\":\"KV\",\"rpcport\":8299}, {\"coin\":\"CEAL\",\"asset\":\"CEAL\",\"rpcport\":11116}, {\"coin\":\"MESH\",\"asset\":\"MESH\",\"rpcport\":9455}]" +export coins="[{\"coin\":\"QTUM\",\"name\":\"qtum\",\"rpcport\":3889,\"pubtype\":58,\"p2shtype\":50,\"wiftype\":128,\"txfee\":400000}, {\"coin\":\"PURA\",\"name\":\"pura\",\"rpcport\":55555,\"pubtype\":55,\"p2shtype\":16,\"wiftype\":150,\"txfee\":10000}, {\"coin\":\"DSR\",\"name\":\"desire\",\"confpath\":\"${HOME#}/.desirecore/desire.conf\",\"rpcport\":9918,\"pubtype\":30,\"p2shtype\":16,\"wiftype\":204,\"txfee\":10000}, {\"coin\":\"MNZ\",\"asset\":\"MNZ\",\"rpcport\":14337},{\"coin\":\"BTCZ\",\"name\":\"bitcoinz\",\"rpcport\":1979,\"taddr\":28,\"pubtype\":184,\"p2shtype\":189,\"wiftype\":128,\"txfee\":10000}, {\"coin\":\"MAGA\",\"name\":\"magacoin\",\"rpcport\":5332,\"pubtype\":23,\"p2shtype\":50,\"wiftype\":176,\"txfee\":100000}, {\"coin\":\"BSD\",\"name\":\"bitsend\",\"rpcport\":8800,\"pubtype\":102,\"p2shtype\":5,\"wiftype\":204,\"txfee\":10000}, {\"coin\":\"IOP\",\"name\":\"IoP\",\"rpcport\":8337,\"pubtype\":117,\"p2shtype\":174,\"wiftype\":49,\"txfee\":10000}, {\"coin\":\"BLOCK\",\"name\":\"blocknetdx\",\"rpcport\":41414,\"pubtype\":26,\"p2shtype\":28,\"wiftype\":154,\"txfee\":10000}, {\"coin\":\"CHIPS\", \"name\": \"chips\", \"rpcport\":57776,\"pubtype\":60, \"p2shtype\":85, \"wiftype\":188, \"txfee\":10000}, {\"coin\":\"888\",\"name\":\"octocoin\",\"rpcport\":22888,\"pubtype\":18,\"p2shtype\":5,\"wiftype\":176,\"txfee\":2000000}, {\"coin\":\"ARG\",\"name\":\"argentum\",\"rpcport\":13581,\"pubtype\":23,\"p2shtype\":5,\"wiftype\":151,\"txfee\":50000}, {\"coin\":\"GLT\",\"name\":\"globaltoken\",\"rpcport\":9320,\"pubtype\":38,\"p2shtype\":5,\"wiftype\":166,\"txfee\":10000}, {\"coin\":\"ZER\",\"name\":\"zero\",\"rpcport\":23801,\"taddr\":28,\"pubtype\":184,\"p2shtype\":189,\"wiftype\":128,\"txfee\":1000}, {\"coin\":\"HODLC\",\"name\":\"hodlcoin\",\"rpcport\":11989,\"pubtype\":40,\"p2shtype\":5,\"wiftype\":168,\"txfee\":5000}, {\"coin\":\"UIS\",\"name\":\"unitus\",\"rpcport\":50604,\"pubtype\":68,\"p2shtype\":10,\"wiftype\":132,\"txfee\":2000000}, {\"coin\":\"CRW\",\"name\":\"crown\",\"rpcport\":9341,\"pubtype\":0,\"p2shtype\":5,\"wiftype\":128,\"txfee\":10000}, {\"coin\":\"HUC\",\"name\":\"huntercoin\",\"rpcport\":8399,\"pubtype\":40,\"p2shtype\":13,\"wiftype\":168,\"txfee\":100000}, {\"coin\":\"PIVX\",\"name\":\"pivx\",\"rpcport\":51473,\"pubtype\":30,\"p2shtype\":13,\"wiftype\":212,\"txfee\":10000}, {\"coin\":\"BDL\",\"name\":\"bitdeal\",\"rpcport\":9332,\"pubtype\":38,\"p2shtype\":5,\"wiftype\":176,\"txfee\":100000}, {\"coin\":\"ARC\",\"name\":\"arcticcoin\",\"confpath\":\"${HOME#}/.arcticcore/arcticcoin.conf\",\"rpcport\":7208,\"pubtype\":23,\"p2shtype\":8,\"wiftype\":176,\"txfee\":10000}, {\"coin\":\"ZCL\",\"name\":\"zclassic\",\"rpcport\":8023,\"taddr\":28,\"pubtype\":184,\"p2shtype\":189,\"wiftype\":128,\"txfee\":1000}, {\"coin\":\"VIA\",\"name\":\"viacoin\",\"rpcport\":5222,\"pubtype\":71,\"p2shtype\":33,\"wiftype\":199,\"txfee\":100000}, {\"coin\":\"ERC\",\"name\":\"europecoin\",\"rpcport\":11989,\"pubtype\":33,\"p2shtype\":5,\"wiftype\":168,\"txfee\":10000},{\"coin\":\"FAIR\",\"name\":\"faircoin\",\"confpath\":\"${HOME#}/.faircoin2/faircoin.conf\",\"rpcport\":40405,\"pubtype\":95,\"p2shtype\":36,\"wiftype\":223,\"txfee\":1000000}, {\"coin\":\"FLO\",\"name\":\"florincoin\",\"rpcport\":7313,\"pubtype\":35,\"p2shtype\":8,\"wiftype\":176,\"txfee\":100000}, {\"coin\":\"SXC\",\"name\":\"sexcoin\",\"rpcport\":9561,\"pubtype\":62,\"p2shtype\":5,\"wiftype\":190,\"txfee\":100000}, {\"coin\":\"CREA\",\"name\":\"creativecoin\",\"rpcport\":17711,\"pubtype\":28,\"p2shtype\":5,\"wiftype\":176,\"txfee\":100000}, {\"coin\":\"TRC\",\"name\":\"terracoin\",\"confpath\":\"${HOME#}/.terracoincore/terracoin.conf\",\"rpcport\":13332,\"pubtype\":0,\"p2shtype\":5,\"wiftype\":128,\"txfee\":10000}, {\"coin\":\"BTA\",\"name\":\"bata\",\"rpcport\":5493,\"pubtype\":25,\"p2shtype\":5,\"wiftype\":188,\"txfee\":100000}, {\"coin\":\"SMC\",\"name\":\"smartcoin\",\"rpcport\":58583,\"pubtype\":63,\"p2shtype\":5,\"wiftype\":191,\"txfee\":1000000}, {\"coin\":\"NMC\",\"name\":\"namecoin\",\"rpcport\":8336,\"pubtype\":52,\"p2shtype\":13,\"wiftype\":180,\"txfee\":100000}, {\"coin\":\"NAV\",\"name\":\"navcoin\",\"isPoS\":1,\"confpath\":\"${HOME#}/.navcoin4/navcoin.conf\",\"rpcport\":44444,\"pubtype\":53,\"p2shtype\":85,\"wiftype\":150,\"txfee\":10000}, {\"coin\":\"MOON\",\"name\":\"Mooncoin\",\"rpcport\":44663,\"pubtype\":3,\"p2shtype\":22,\"wiftype\":131,\"txfee\":100000}, {\"coin\":\"EMC2\",\"name\":\"einsteinium\",\"rpcport\":41879,\"pubtype\":33,\"p2shtype\":5,\"wiftype\":176,\"txfee\":100000},{\"coin\":\"SYS\",\"name\":\"syscoin\",\"rpcport\":8370,\"pubtype\":0,\"p2shtype\":5,\"wiftype\":128,\"txfee\":1000}, {\"coin\":\"I0C\",\"name\":\"i0coin\",\"rpcport\":7332,\"pubtype\":105,\"p2shtype\":5,\"wiftype\":128,\"txfee\":1000}, {\"coin\":\"DASH\",\"confpath\":\"${HOME#}/.dashcore/dash.conf\",\"name\":\"dashcore\",\"rpcport\":9998,\"pubtype\":76,\"p2shtype\":16,\"wiftype\":204,\"txfee\":10000}, {\"coin\":\"STRAT\", \"name\": \"stratis\", \"active\":0, \"rpcport\":16174,\"pubtype\":63, \"p2shtype\":125, \"wiftype\":191, \"txfee\":10000}, {\"confpath\":\"${HOME#}/.muecore/mue.conf\",\"coin\":\"MUE\",\"name\":\"muecore\",\"rpcport\":29683,\"pubtype\":16,\"p2shtype\":76,\"wiftype\":126,\"txfee\":10000}, {\"coin\":\"MONA\",\"name\":\"monacoin\",\"rpcport\":9402,\"pubtype\":50,\"p2shtype\":5,\"wiftype\":176,\"txfee\":100000},{\"coin\":\"XMY\",\"name\":\"myriadcoin\",\"rpcport\":10889,\"pubtype\":50,\"p2shtype\":9,\"wiftype\":178,\"txfee\":5000}, {\"coin\":\"MAC\",\"name\":\"machinecoin\",\"rpcport\":40332,\"pubtype\":50,\"p2shtype\":5,\"wiftype\":178,\"txfee\":50000}, {\"coin\":\"BTX\",\"name\":\"bitcore\",\"rpcport\":8556,\"pubtype\":0,\"p2shtype\":5,\"wiftype\":128,\"txfee\":50000}, {\"coin\":\"XRE\",\"name\":\"revolvercoin\",\"rpcport\":8775,\"pubtype\":0,\"p2shtype\":5,\"wiftype\":128,\"txfee\":1000}, {\"coin\":\"LBC\",\"name\":\"lbrycrd\",\"rpcport\":9245,\"pubtype\":85,\"p2shtype\":122,\"wiftype\":28,\"txfee\":1000}, {\"coin\":\"SIB\",\"name\":\"sibcoin\",\"rpcport\":1944,\"pubtype\":63,\"p2shtype\":40,\"wiftype\":128,\"txfee\":10000}, {\"coin\":\"VTC\", \"name\":\"vertcoin\", \"rpcport\":5888, \"pubtype\":71, \"p2shtype\":5, \"wiftype\":128, \"txfee\":100000 }, {\"coin\":\"REVS\",\"active\":0, \"asset\":\"REVS\",\"rpcport\":10196}, {\"coin\":\"JUMBLR\",\"active\":0, \"asset\":\"JUMBLR\",\"rpcport\":15106}, {\"coin\":\"DOGE\",\"name\":\"dogecoin\",\"rpcport\":22555,\"pubtype\":30,\"p2shtype\":22,\"wiftype\":158,\"txfee\":100000000}, {\"coin\":\"HUSH\",\"name\":\"hush\",\"rpcport\":8822,\"taddr\":28,\"pubtype\":184,\"p2shtype\":189,\"wiftype\":128,\"txfee\":1000 }, {\"active\":0,\"coin\":\"ZEC\",\"name\":\"zcash\",\"rpcport\":8232,\"taddr\":28,\"pubtype\":184,\"p2shtype\":189,\"wiftype\":128,\"txfee\":10000 }, {\"coin\":\"DGB\",\"name\":\"digibyte\",\"rpcport\":14022,\"pubtype\":30,\"p2shtype\":5,\"wiftype\":128,\"txfee\":100000}, {\"coin\":\"ZET\", \"name\":\"zetacoin\", \"pubtype\":80, \"p2shtype\":9,\"rpcport\":8332, \"wiftype\":224, \"txfee\":10000}, {\"coin\":\"GAME\", \"rpcport\":40001, \"name\":\"gamecredits\", \"pubtype\":38, \"p2shtype\":5, \"wiftype\":166, \"txfee\":100000}, {\"coin\":\"LTC\", \"name\":\"litecoin\", \"rpcport\":9332, \"pubtype\":48, \"p2shtype\":5, \"wiftype\":176, \"txfee\":100000 }, {\"coin\":\"SUPERNET\",\"asset\":\"SUPERNET\",\"rpcport\":11341}, {\"coin\":\"WLC\",\"asset\":\"WLC\",\"rpcport\":12167}, {\"coin\":\"PANGEA\",\"asset\":\"PANGEA\",\"rpcport\":14068}, {\"coin\":\"DEX\",\"asset\":\"DEX\",\"rpcport\":11890}, {\"coin\":\"BET\",\"asset\":\"BET\",\"rpcport\":14250}, {\"coin\":\"CRYPTO\",\"asset\":\"CRYPTO\",\"rpcport\":8516}, {\"coin\":\"HODL\",\"asset\":\"HODL\",\"rpcport\":14431}, {\"coin\":\"MSHARK\",\"asset\":\"MSHARK\",\"rpcport\":8846}, {\"coin\":\"BOTS\",\"asset\":\"BOTS\",\"rpcport\":11964}, {\"coin\":\"MGW\",\"asset\":\"MGW\",\"rpcport\":12386}, {\"coin\":\"COQUI\",\"asset\":\"COQUI\",\"rpcport\":14276}, {\"coin\":\"KV\",\"asset\":\"KV\",\"rpcport\":8299}, {\"coin\":\"CEAL\",\"asset\":\"CEAL\",\"rpcport\":11116}, {\"coin\":\"MESH\",\"asset\":\"MESH\",\"rpcport\":9455}]" #, {\"coin\":\"AUD\",\"asset\":\"AUD\",\"rpcport\":8045}, {\"coin\":\"BGN\",\"asset\":\"BGN\",\"rpcport\":9110}, {\"coin\":\"CAD\",\"asset\":\"CAD\",\"rpcport\":8720}, {\"coin\":\"CHF\",\"asset\":\"CHF\",\"rpcport\":15312}, {\"coin\":\"CNY\",\"asset\":\"CNY\",\"rpcport\":10384}, {\"coin\":\"CZK\",\"asset\":\"CZK\",\"rpcport\":9482}, {\"coin\":\"DKK\",\"asset\":\"DKK\",\"rpcport\":13830}, {\"coin\":\"EUR\",\"asset\":\"EUR\",\"rpcport\":8065}, {\"coin\":\"GBP\",\"asset\":\"GBP\",\"rpcport\":11505}, {\"coin\":\"HKD\",\"asset\":\"HKD\",\"rpcport\":15409}, {\"coin\":\"HRK\",\"asset\":\"HRK\",\"rpcport\":12617}, {\"coin\":\"HUF\",\"asset\":\"HUF\",\"rpcport\":13699}, {\"coin\":\"IDR\",\"asset\":\"IDR\",\"rpcport\":14459}, {\"coin\":\"ILS\",\"asset\":\"ILS\",\"rpcport\":14638}, {\"coin\":\"INR\",\"asset\":\"INR\",\"rpcport\":10536}, {\"coin\":\"JPY\",\"asset\":\"JPY\",\"rpcport\":13145}, {\"coin\":\"KRW\",\"asset\":\"KRW\",\"rpcport\":14020}, {\"coin\":\"MXN\",\"asset\":\"MXN\",\"rpcport\":13970}, {\"coin\":\"MYR\",\"asset\":\"MYR\",\"rpcport\":10688}, {\"coin\":\"NOK\",\"asset\":\"NOK\",\"rpcport\":11588}, {\"coin\":\"NZD\",\"asset\":\"NZD\",\"rpcport\":10915}, {\"coin\":\"PHP\",\"asset\":\"PHP\",\"rpcport\":11181}, {\"coin\":\"PLN\",\"asset\":\"PLN\",\"rpcport\":13493}, {\"coin\":\"BRL\",\"asset\":\"BRL\",\"rpcport\":9914}, {\"coin\":\"RON\",\"asset\":\"RON\",\"rpcport\":8675}, {\"coin\":\"RUB\",\"asset\":\"RUB\",\"rpcport\":8199}, {\"coin\":\"SEK\",\"asset\":\"SEK\",\"rpcport\":11447}, {\"coin\":\"SGD\",\"asset\":\"SGD\",\"rpcport\":14475}, {\"coin\":\"THB\",\"asset\":\"THB\",\"rpcport\":11847}, {\"coin\":\"TRY\",\"asset\":\"TRY\",\"rpcport\":13924}, {\"coin\":\"USD\",\"asset\":\"USD\",\"rpcport\":13967}, {\"coin\":\"ZAR\",\"asset\":\"ZAR\",\"rpcport\":15160}]" #{\"coin\":\"ZEN\",\"name\":\"zen\",\"rpcport\":8231,\"pubtype\":137,\"taddr\":32,\"p2shtype\":150,\"wiftype\":128,\"txfee\":10000}, #{\"coin\":\"BLK\",\"name\":\"blackcoin\",\"rpcport\":15715,\"pubtype\":25,\"p2shtype\":85,\"wiftype\":153,\"txfee\":10000}, From 519c7af292db9008d9cffbbabfe43706b51145fd Mon Sep 17 00:00:00 2001 From: jl777 Date: Thu, 30 Nov 2017 22:51:54 +0400 Subject: [PATCH 1389/1664] coins.json --- iguana/exchanges/coins.json | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/iguana/exchanges/coins.json b/iguana/exchanges/coins.json index 320b6ccaf..ea25d7c8b 100644 --- a/iguana/exchanges/coins.json +++ b/iguana/exchanges/coins.json @@ -1,4 +1,4 @@ -[{\"coin\":\"QTUM\",\"name\":\"qtum\",\"rpcport\":3889,\"pubtype\":58,\"p2shtype\":50,\"wiftype\":128,\"txfee\":400000}, {\"coin\":\"PURA\",\"name\":\"pura\",\"rpcport\":55555,\"pubtype\":55,\"p2shtype\":16,\"wiftype\":150,\"txfee\":10000}, {\"coin\":\"DSR\",\"name\":\"desire\",\"confpath\":\"${HOME#}/.desirecore/desire.conf\",\"rpcport\":9918,\"pubtype\":30,\"p2shtype\":16,\"wiftype\":204,\"txfee\":10000}, {\"coin\":\"MNZ\",\"asset\":\"MNZ\",\"rpcport\":14337},{\"coin\":\"BTCZ\",\"name\":\"bitcoinz\",\"rpcport\":1979,\"taddr\":28,\"pubtype\":184,\"p2shtype\":189,\"wiftype\":128,\"txfee\":10000}, {\"coin\":\"MAGA\",\"name\":\"magacoin\",\"rpcport\":5332,\"pubtype\":23,\"p2shtype\":50,\"wiftype\":176,\"txfee\":100000}, {\"coin\":\"BSD\",\"name\":\"bitsend\",\"rpcport\":8800,\"pubtype\":102,\"p2shtype\":5,\"wiftype\":204,\"txfee\":10000}, {\"coin\":\"IOP\",\"name\":\"IoP\",\"rpcport\":8337,\"pubtype\":117,\"p2shtype\":174,\"wiftype\":49,\"txfee\":10000}, {\"coin\":\"BLOCK\",\"name\":\"blocknetdx\",\"rpcport\":41414,\"pubtype\":26,\"p2shtype\":28,\"wiftype\":154,\"txfee\":10000}, {\"coin\":\"CHIPS\", \"name\": \"chips\", \"rpcport\":57776,\"pubtype\":60, \"p2shtype\":85, \"wiftype\":188, \"txfee\":10000}, {\"coin\":\"888\",\"name\":\"octocoin\",\"rpcport\":22888,\"pubtype\":18,\"p2shtype\":5,\"wiftype\":176,\"txfee\":2000000}, {\"coin\":\"ARG\",\"name\":\"argentum\",\"rpcport\":13581,\"pubtype\":23,\"p2shtype\":5,\"wiftype\":151,\"txfee\":50000}, {\"coin\":\"GLT\",\"name\":\"globaltoken\",\"rpcport\":9320,\"pubtype\":38,\"p2shtype\":5,\"wiftype\":166,\"txfee\":10000}, {\"coin\":\"ZER\",\"name\":\"zero\",\"rpcport\":23801,\"taddr\":28,\"pubtype\":184,\"p2shtype\":189,\"wiftype\":128,\"txfee\":1000}, {\"coin\":\"HODLC\",\"name\":\"hodlcoin\",\"rpcport\":11989,\"pubtype\":40,\"p2shtype\":5,\"wiftype\":168,\"txfee\":5000}, {\"coin\":\"UIS\",\"name\":\"unitus\",\"rpcport\":50604,\"pubtype\":68,\"p2shtype\":10,\"wiftype\":132,\"txfee\":2000000}, {\"coin\":\"CRW\",\"name\":\"crown\",\"rpcport\":9341,\"pubtype\":0,\"p2shtype\":5,\"wiftype\":128,\"txfee\":10000}, {\"coin\":\"HUC\",\"name\":\"huntercoin\",\"rpcport\":8399,\"pubtype\":40,\"p2shtype\":13,\"wiftype\":168,\"txfee\":100000}, {\"coin\":\"PIVX\",\"name\":\"pivx\",\"rpcport\":51473,\"pubtype\":30,\"p2shtype\":13,\"wiftype\":212,\"txfee\":10000}, {\"coin\":\"BDL\",\"name\":\"bitdeal\",\"rpcport\":9332,\"pubtype\":38,\"p2shtype\":5,\"wiftype\":176,\"txfee\":100000}, {\"coin\":\"ARC\",\"name\":\"arcticcoin\",\"confpath\":\"${HOME#}/.arcticcore/arcticcoin.conf\",\"rpcport\":7208,\"pubtype\":23,\"p2shtype\":8,\"wiftype\":176,\"txfee\":10000}, {\"coin\":\"ZCL\",\"name\":\"zclassic\",\"rpcport\":8023,\"taddr\":28,\"pubtype\":184,\"p2shtype\":189,\"wiftype\":128,\"txfee\":1000}, {\"coin\":\"VIA\",\"name\":\"viacoin\",\"rpcport\":5222,\"pubtype\":71,\"p2shtype\":33,\"wiftype\":199,\"txfee\":100000}, {\"coin\":\"ERC\",\"name\":\"europecoin\",\"rpcport\":11989,\"pubtype\":33,\"p2shtype\":5,\"wiftype\":168,\"txfee\":10000},{\"coin\":\"FAIR\",\"name\":\"faircoin\",\"confpath\":\"${HOME#}/.faircoin2/faircoin.conf\",\"rpcport\":40405,\"pubtype\":95,\"p2shtype\":36,\"wiftype\":223,\"txfee\":1000000}, {\"coin\":\"FLO\",\"name\":\"florincoin\",\"rpcport\":7313,\"pubtype\":35,\"p2shtype\":8,\"wiftype\":176,\"txfee\":100000}, {\"coin\":\"SXC\",\"name\":\"sexcoin\",\"rpcport\":9561,\"pubtype\":62,\"p2shtype\":5,\"wiftype\":190,\"txfee\":100000}, {\"coin\":\"CREA\",\"name\":\"creativecoin\",\"rpcport\":17711,\"pubtype\":28,\"p2shtype\":5,\"wiftype\":176,\"txfee\":100000}, {\"coin\":\"TRC\",\"name\":\"terracoin\",\"confpath\":\"${HOME#}/.terracoincore/terracoin.conf\",\"rpcport\":13332,\"pubtype\":0,\"p2shtype\":5,\"wiftype\":128,\"txfee\":10000}, {\"coin\":\"BTA\",\"name\":\"bata\",\"rpcport\":5493,\"pubtype\":25,\"p2shtype\":5,\"wiftype\":188,\"txfee\":100000}, {\"coin\":\"SMC\",\"name\":\"smartcoin\",\"rpcport\":58583,\"pubtype\":63,\"p2shtype\":5,\"wiftype\":191,\"txfee\":1000000}, {\"coin\":\"NMC\",\"name\":\"namecoin\",\"rpcport\":8336,\"pubtype\":52,\"p2shtype\":13,\"wiftype\":180,\"txfee\":100000}, {\"coin\":\"NAV\",\"name\":\"navcoin\",\"isPoS\":1,\"confpath\":\"${HOME#}/.navcoin4/navcoin.conf\",\"rpcport\":44444,\"pubtype\":53,\"p2shtype\":85,\"wiftype\":150,\"txfee\":10000}, {\"coin\":\"MOON\",\"name\":\"Mooncoin\",\"rpcport\":44663,\"pubtype\":3,\"p2shtype\":22,\"wiftype\":131,\"txfee\":100000}, {\"coin\":\"EMC2\",\"name\":\"einsteinium\",\"rpcport\":41879,\"pubtype\":33,\"p2shtype\":5,\"wiftype\":176,\"txfee\":100000},{\"coin\":\"SYS\",\"name\":\"syscoin\",\"rpcport\":8370,\"pubtype\":0,\"p2shtype\":5,\"wiftype\":128,\"txfee\":1000}, {\"coin\":\"I0C\",\"name\":\"i0coin\",\"rpcport\":7332,\"pubtype\":105,\"p2shtype\":5,\"wiftype\":128,\"txfee\":1000}, {\"coin\":\"DASH\",\"confpath\":\"${HOME#}/.dashcore/dash.conf\",\"name\":\"dashcore\",\"rpcport\":9998,\"pubtype\":76,\"p2shtype\":16,\"wiftype\":204,\"txfee\":10000}, {\"coin\":\"STRAT\", \"name\": \"stratis\", \"active\":0, \"rpcport\":16174,\"pubtype\":63, \"p2shtype\":125, \"wiftype\":191, \"txfee\":10000}, {\"confpath\":\"${HOME#}/.muecore/mue.conf\",\"coin\":\"MUE\",\"name\":\"muecore\",\"rpcport\":29683,\"pubtype\":16,\"p2shtype\":76,\"wiftype\":126,\"txfee\":10000}, {\"coin\":\"MONA\",\"name\":\"monacoin\",\"rpcport\":9402,\"pubtype\":50,\"p2shtype\":5,\"wiftype\":176,\"txfee\":100000},{\"coin\":\"XMY\",\"name\":\"myriadcoin\",\"rpcport\":10889,\"pubtype\":50,\"p2shtype\":9,\"wiftype\":178,\"txfee\":5000}, {\"coin\":\"MAC\",\"name\":\"machinecoin\",\"rpcport\":40332,\"pubtype\":50,\"p2shtype\":5,\"wiftype\":178,\"txfee\":50000}, {\"coin\":\"BTX\",\"name\":\"bitcore\",\"rpcport\":8556,\"pubtype\":0,\"p2shtype\":5,\"wiftype\":128,\"txfee\":50000}, {\"coin\":\"XRE\",\"name\":\"revolvercoin\",\"rpcport\":8775,\"pubtype\":0,\"p2shtype\":5,\"wiftype\":128,\"txfee\":1000}, {\"coin\":\"LBC\",\"name\":\"lbrycrd\",\"rpcport\":9245,\"pubtype\":85,\"p2shtype\":122,\"wiftype\":28,\"txfee\":1000}, {\"coin\":\"SIB\",\"name\":\"sibcoin\",\"rpcport\":1944,\"pubtype\":63,\"p2shtype\":40,\"wiftype\":128,\"txfee\":10000}, {\"coin\":\"VTC\", \"name\":\"vertcoin\", \"rpcport\":5888, \"pubtype\":71, \"p2shtype\":5, \"wiftype\":128, \"txfee\":100000 }, {\"coin\":\"REVS\",\"active\":0, \"asset\":\"REVS\",\"rpcport\":10196}, {\"coin\":\"JUMBLR\",\"active\":0, \"asset\":\"JUMBLR\",\"rpcport\":15106}, {\"coin\":\"DOGE\",\"name\":\"dogecoin\",\"rpcport\":22555,\"pubtype\":30,\"p2shtype\":22,\"wiftype\":158,\"txfee\":100000000}, {\"coin\":\"HUSH\",\"name\":\"hush\",\"rpcport\":8822,\"taddr\":28,\"pubtype\":184,\"p2shtype\":189,\"wiftype\":128,\"txfee\":1000 }, {\"active\":0,\"coin\":\"ZEC\",\"name\":\"zcash\",\"rpcport\":8232,\"taddr\":28,\"pubtype\":184,\"p2shtype\":189,\"wiftype\":128,\"txfee\":10000 }, {\"coin\":\"DGB\",\"name\":\"digibyte\",\"rpcport\":14022,\"pubtype\":30,\"p2shtype\":5,\"wiftype\":128,\"txfee\":100000}, {\"coin\":\"ZET\", \"name\":\"zetacoin\", \"pubtype\":80, \"p2shtype\":9,\"rpcport\":8332, \"wiftype\":224, \"txfee\":10000}, {\"coin\":\"GAME\", \"rpcport\":40001, \"name\":\"gamecredits\", \"pubtype\":38, \"p2shtype\":5, \"wiftype\":166, \"txfee\":100000}, {\"coin\":\"LTC\", \"name\":\"litecoin\", \"rpcport\":9332, \"pubtype\":48, \"p2shtype\":5, \"wiftype\":176, \"txfee\":100000 }, {\"coin\":\"SUPERNET\",\"asset\":\"SUPERNET\",\"rpcport\":11341}, {\"coin\":\"WLC\",\"asset\":\"WLC\",\"rpcport\":12167}, {\"coin\":\"PANGEA\",\"asset\":\"PANGEA\",\"rpcport\":14068}, {\"coin\":\"DEX\",\"asset\":\"DEX\",\"rpcport\":11890}, {\"coin\":\"BET\",\"asset\":\"BET\",\"rpcport\":14250}, {\"coin\":\"CRYPTO\",\"asset\":\"CRYPTO\",\"rpcport\":8516}, {\"coin\":\"HODL\",\"asset\":\"HODL\",\"rpcport\":14431}, {\"coin\":\"SHARK\",\"asset\":\"SHARK\",\"rpcport\":10114}, {\"coin\":\"BOTS\",\"asset\":\"BOTS\",\"rpcport\":11964}, {\"coin\":\"MGW\",\"asset\":\"MGW\",\"rpcport\":12386}, {\"coin\":\"COQUI\",\"asset\":\"COQUI\",\"rpcport\":14276}, {\"coin\":\"KV\",\"asset\":\"KV\",\"rpcport\":8299}, {\"coin\":\"CEAL\",\"asset\":\"CEAL\",\"rpcport\":11116}, {\"coin\":\"MESH\",\"asset\":\"MESH\",\"rpcport\":9455}]" -#, {\"coin\":\"AUD\",\"asset\":\"AUD\",\"rpcport\":8045}, {\"coin\":\"BGN\",\"asset\":\"BGN\",\"rpcport\":9110}, {\"coin\":\"CAD\",\"asset\":\"CAD\",\"rpcport\":8720}, {\"coin\":\"CHF\",\"asset\":\"CHF\",\"rpcport\":15312}, {\"coin\":\"CNY\",\"asset\":\"CNY\",\"rpcport\":10384}, {\"coin\":\"CZK\",\"asset\":\"CZK\",\"rpcport\":9482}, {\"coin\":\"DKK\",\"asset\":\"DKK\",\"rpcport\":13830}, {\"coin\":\"EUR\",\"asset\":\"EUR\",\"rpcport\":8065}, {\"coin\":\"GBP\",\"asset\":\"GBP\",\"rpcport\":11505}, {\"coin\":\"HKD\",\"asset\":\"HKD\",\"rpcport\":15409}, {\"coin\":\"HRK\",\"asset\":\"HRK\",\"rpcport\":12617}, {\"coin\":\"HUF\",\"asset\":\"HUF\",\"rpcport\":13699}, {\"coin\":\"IDR\",\"asset\":\"IDR\",\"rpcport\":14459}, {\"coin\":\"ILS\",\"asset\":\"ILS\",\"rpcport\":14638}, {\"coin\":\"INR\",\"asset\":\"INR\",\"rpcport\":10536}, {\"coin\":\"JPY\",\"asset\":\"JPY\",\"rpcport\":13145}, {\"coin\":\"KRW\",\"asset\":\"KRW\",\"rpcport\":14020}, {\"coin\":\"MXN\",\"asset\":\"MXN\",\"rpcport\":13970}, {\"coin\":\"MYR\",\"asset\":\"MYR\",\"rpcport\":10688}, {\"coin\":\"NOK\",\"asset\":\"NOK\",\"rpcport\":11588}, {\"coin\":\"NZD\",\"asset\":\"NZD\",\"rpcport\":10915}, {\"coin\":\"PHP\",\"asset\":\"PHP\",\"rpcport\":11181}, {\"coin\":\"PLN\",\"asset\":\"PLN\",\"rpcport\":13493}, {\"coin\":\"BRL\",\"asset\":\"BRL\",\"rpcport\":9914}, {\"coin\":\"RON\",\"asset\":\"RON\",\"rpcport\":8675}, {\"coin\":\"RUB\",\"asset\":\"RUB\",\"rpcport\":8199}, {\"coin\":\"SEK\",\"asset\":\"SEK\",\"rpcport\":11447}, {\"coin\":\"SGD\",\"asset\":\"SGD\",\"rpcport\":14475}, {\"coin\":\"THB\",\"asset\":\"THB\",\"rpcport\":11847}, {\"coin\":\"TRY\",\"asset\":\"TRY\",\"rpcport\":13924}, {\"coin\":\"USD\",\"asset\":\"USD\",\"rpcport\":13967}, {\"coin\":\"ZAR\",\"asset\":\"ZAR\",\"rpcport\":15160}] +[{\"coin\":\"QTUM\",\"name\":\"qtum\",\"rpcport\":3889,\"pubtype\":58,\"p2shtype\":50,\"wiftype\":128,\"txfee\":400000}, {\"coin\":\"PURA\",\"name\":\"pura\",\"rpcport\":55555,\"pubtype\":55,\"p2shtype\":16,\"wiftype\":150,\"txfee\":10000}, {\"coin\":\"DSR\",\"name\":\"desire\",\"confpath\":\"${HOME#}/.desirecore/desire.conf\",\"rpcport\":9918,\"pubtype\":30,\"p2shtype\":16,\"wiftype\":204,\"txfee\":10000}, {\"coin\":\"MNZ\",\"asset\":\"MNZ\",\"rpcport\":14337},{\"coin\":\"BTCZ\",\"name\":\"bitcoinz\",\"rpcport\":1979,\"taddr\":28,\"pubtype\":184,\"p2shtype\":189,\"wiftype\":128,\"txfee\":10000}, {\"coin\":\"MAGA\",\"name\":\"magacoin\",\"rpcport\":5332,\"pubtype\":23,\"p2shtype\":50,\"wiftype\":176,\"txfee\":100000}, {\"coin\":\"BSD\",\"name\":\"bitsend\",\"rpcport\":8800,\"pubtype\":102,\"p2shtype\":5,\"wiftype\":204,\"txfee\":10000}, {\"coin\":\"IOP\",\"name\":\"IoP\",\"rpcport\":8337,\"pubtype\":117,\"p2shtype\":174,\"wiftype\":49,\"txfee\":10000}, {\"coin\":\"BLOCK\",\"name\":\"blocknetdx\",\"rpcport\":41414,\"pubtype\":26,\"p2shtype\":28,\"wiftype\":154,\"txfee\":10000}, {\"coin\":\"CHIPS\", \"name\": \"chips\", \"rpcport\":57776,\"pubtype\":60, \"p2shtype\":85, \"wiftype\":188, \"txfee\":10000}, {\"coin\":\"888\",\"name\":\"octocoin\",\"rpcport\":22888,\"pubtype\":18,\"p2shtype\":5,\"wiftype\":176,\"txfee\":2000000}, {\"coin\":\"ARG\",\"name\":\"argentum\",\"rpcport\":13581,\"pubtype\":23,\"p2shtype\":5,\"wiftype\":151,\"txfee\":50000}, {\"coin\":\"GLT\",\"name\":\"globaltoken\",\"rpcport\":9320,\"pubtype\":38,\"p2shtype\":5,\"wiftype\":166,\"txfee\":10000}, {\"coin\":\"ZER\",\"name\":\"zero\",\"rpcport\":23801,\"taddr\":28,\"pubtype\":184,\"p2shtype\":189,\"wiftype\":128,\"txfee\":1000}, {\"coin\":\"HODLC\",\"name\":\"hodlcoin\",\"rpcport\":11989,\"pubtype\":40,\"p2shtype\":5,\"wiftype\":168,\"txfee\":5000}, {\"coin\":\"UIS\",\"name\":\"unitus\",\"rpcport\":50604,\"pubtype\":68,\"p2shtype\":10,\"wiftype\":132,\"txfee\":2000000}, {\"coin\":\"CRW\",\"name\":\"crown\",\"rpcport\":9341,\"pubtype\":0,\"p2shtype\":5,\"wiftype\":128,\"txfee\":10000}, {\"coin\":\"HUC\",\"name\":\"huntercoin\",\"rpcport\":8399,\"pubtype\":40,\"p2shtype\":13,\"wiftype\":168,\"txfee\":100000}, {\"coin\":\"PIVX\",\"name\":\"pivx\",\"rpcport\":51473,\"pubtype\":30,\"p2shtype\":13,\"wiftype\":212,\"txfee\":10000}, {\"coin\":\"BDL\",\"name\":\"bitdeal\",\"rpcport\":9332,\"pubtype\":38,\"p2shtype\":5,\"wiftype\":176,\"txfee\":100000}, {\"coin\":\"ARC\",\"name\":\"arcticcoin\",\"confpath\":\"${HOME#}/.arcticcore/arcticcoin.conf\",\"rpcport\":7208,\"pubtype\":23,\"p2shtype\":8,\"wiftype\":176,\"txfee\":10000}, {\"coin\":\"ZCL\",\"name\":\"zclassic\",\"rpcport\":8023,\"taddr\":28,\"pubtype\":184,\"p2shtype\":189,\"wiftype\":128,\"txfee\":1000}, {\"coin\":\"VIA\",\"name\":\"viacoin\",\"rpcport\":5222,\"pubtype\":71,\"p2shtype\":33,\"wiftype\":199,\"txfee\":100000}, {\"coin\":\"ERC\",\"name\":\"europecoin\",\"rpcport\":11989,\"pubtype\":33,\"p2shtype\":5,\"wiftype\":168,\"txfee\":10000},{\"coin\":\"FAIR\",\"name\":\"faircoin\",\"confpath\":\"${HOME#}/.faircoin2/faircoin.conf\",\"rpcport\":40405,\"pubtype\":95,\"p2shtype\":36,\"wiftype\":223,\"txfee\":1000000}, {\"coin\":\"FLO\",\"name\":\"florincoin\",\"rpcport\":7313,\"pubtype\":35,\"p2shtype\":8,\"wiftype\":176,\"txfee\":100000}, {\"coin\":\"SXC\",\"name\":\"sexcoin\",\"rpcport\":9561,\"pubtype\":62,\"p2shtype\":5,\"wiftype\":190,\"txfee\":100000}, {\"coin\":\"CREA\",\"name\":\"creativecoin\",\"rpcport\":17711,\"pubtype\":28,\"p2shtype\":5,\"wiftype\":176,\"txfee\":100000}, {\"coin\":\"TRC\",\"name\":\"terracoin\",\"confpath\":\"${HOME#}/.terracoincore/terracoin.conf\",\"rpcport\":13332,\"pubtype\":0,\"p2shtype\":5,\"wiftype\":128,\"txfee\":10000}, {\"coin\":\"BTA\",\"name\":\"bata\",\"rpcport\":5493,\"pubtype\":25,\"p2shtype\":5,\"wiftype\":188,\"txfee\":100000}, {\"coin\":\"SMC\",\"name\":\"smartcoin\",\"rpcport\":58583,\"pubtype\":63,\"p2shtype\":5,\"wiftype\":191,\"txfee\":1000000}, {\"coin\":\"NMC\",\"name\":\"namecoin\",\"rpcport\":8336,\"pubtype\":52,\"p2shtype\":13,\"wiftype\":180,\"txfee\":100000}, {\"coin\":\"NAV\",\"name\":\"navcoin\",\"isPoS\":1,\"confpath\":\"${HOME#}/.navcoin4/navcoin.conf\",\"rpcport\":44444,\"pubtype\":53,\"p2shtype\":85,\"wiftype\":150,\"txfee\":10000}, {\"coin\":\"MOON\",\"name\":\"Mooncoin\",\"rpcport\":44663,\"pubtype\":3,\"p2shtype\":22,\"wiftype\":131,\"txfee\":100000}, {\"coin\":\"EMC2\",\"name\":\"einsteinium\",\"rpcport\":41879,\"pubtype\":33,\"p2shtype\":5,\"wiftype\":176,\"txfee\":100000},{\"coin\":\"SYS\",\"name\":\"syscoin\",\"rpcport\":8370,\"pubtype\":0,\"p2shtype\":5,\"wiftype\":128,\"txfee\":1000}, {\"coin\":\"I0C\",\"name\":\"i0coin\",\"rpcport\":7332,\"pubtype\":105,\"p2shtype\":5,\"wiftype\":128,\"txfee\":1000}, {\"coin\":\"DASH\",\"confpath\":\"${HOME#}/.dashcore/dash.conf\",\"name\":\"dashcore\",\"rpcport\":9998,\"pubtype\":76,\"p2shtype\":16,\"wiftype\":204,\"txfee\":10000}, {\"coin\":\"STRAT\", \"name\": \"stratis\", \"active\":0, \"rpcport\":16174,\"pubtype\":63, \"p2shtype\":125, \"wiftype\":191, \"txfee\":10000}, {\"confpath\":\"${HOME#}/.muecore/mue.conf\",\"coin\":\"MUE\",\"name\":\"muecore\",\"rpcport\":29683,\"pubtype\":16,\"p2shtype\":76,\"wiftype\":126,\"txfee\":10000}, {\"coin\":\"MONA\",\"name\":\"monacoin\",\"rpcport\":9402,\"pubtype\":50,\"p2shtype\":5,\"wiftype\":176,\"txfee\":100000},{\"coin\":\"XMY\",\"name\":\"myriadcoin\",\"rpcport\":10889,\"pubtype\":50,\"p2shtype\":9,\"wiftype\":178,\"txfee\":5000}, {\"coin\":\"MAC\",\"name\":\"machinecoin\",\"rpcport\":40332,\"pubtype\":50,\"p2shtype\":5,\"wiftype\":178,\"txfee\":50000}, {\"coin\":\"BTX\",\"name\":\"bitcore\",\"rpcport\":8556,\"pubtype\":0,\"p2shtype\":5,\"wiftype\":128,\"txfee\":50000}, {\"coin\":\"XRE\",\"name\":\"revolvercoin\",\"rpcport\":8775,\"pubtype\":0,\"p2shtype\":5,\"wiftype\":128,\"txfee\":1000}, {\"coin\":\"LBC\",\"name\":\"lbrycrd\",\"rpcport\":9245,\"pubtype\":85,\"p2shtype\":122,\"wiftype\":28,\"txfee\":1000}, {\"coin\":\"SIB\",\"name\":\"sibcoin\",\"rpcport\":1944,\"pubtype\":63,\"p2shtype\":40,\"wiftype\":128,\"txfee\":10000}, {\"coin\":\"VTC\", \"name\":\"vertcoin\", \"rpcport\":5888, \"pubtype\":71, \"p2shtype\":5, \"wiftype\":128, \"txfee\":100000 }, {\"coin\":\"REVS\",\"active\":0, \"asset\":\"REVS\",\"rpcport\":10196}, {\"coin\":\"JUMBLR\",\"active\":0, \"asset\":\"JUMBLR\",\"rpcport\":15106}, {\"coin\":\"DOGE\",\"name\":\"dogecoin\",\"rpcport\":22555,\"pubtype\":30,\"p2shtype\":22,\"wiftype\":158,\"txfee\":100000000}, {\"coin\":\"HUSH\",\"name\":\"hush\",\"rpcport\":8822,\"taddr\":28,\"pubtype\":184,\"p2shtype\":189,\"wiftype\":128,\"txfee\":1000 }, {\"active\":0,\"coin\":\"ZEC\",\"name\":\"zcash\",\"rpcport\":8232,\"taddr\":28,\"pubtype\":184,\"p2shtype\":189,\"wiftype\":128,\"txfee\":10000 }, {\"coin\":\"DGB\",\"name\":\"digibyte\",\"rpcport\":14022,\"pubtype\":30,\"p2shtype\":5,\"wiftype\":128,\"txfee\":100000}, {\"coin\":\"ZET\", \"name\":\"zetacoin\", \"pubtype\":80, \"p2shtype\":9,\"rpcport\":8332, \"wiftype\":224, \"txfee\":10000}, {\"coin\":\"GAME\", \"rpcport\":40001, \"name\":\"gamecredits\", \"pubtype\":38, \"p2shtype\":5, \"wiftype\":166, \"txfee\":100000}, {\"coin\":\"LTC\", \"name\":\"litecoin\", \"rpcport\":9332, \"pubtype\":48, \"p2shtype\":5, \"wiftype\":176, \"txfee\":100000 }, {\"coin\":\"SUPERNET\",\"asset\":\"SUPERNET\",\"rpcport\":11341}, {\"coin\":\"WLC\",\"asset\":\"WLC\",\"rpcport\":12167}, {\"coin\":\"PANGEA\",\"asset\":\"PANGEA\",\"rpcport\":14068}, {\"coin\":\"DEX\",\"asset\":\"DEX\",\"rpcport\":11890}, {\"coin\":\"BET\",\"asset\":\"BET\",\"rpcport\":14250}, {\"coin\":\"CRYPTO\",\"asset\":\"CRYPTO\",\"rpcport\":8516}, {\"coin\":\"HODL\",\"asset\":\"HODL\",\"rpcport\":14431}, {\"coin\":\"MSHARK\",\"asset\":\"MSHARK\",\"rpcport\":8846}, {\"coin\":\"BOTS\",\"asset\":\"BOTS\",\"rpcport\":11964}, {\"coin\":\"MGW\",\"asset\":\"MGW\",\"rpcport\":12386}, {\"coin\":\"COQUI\",\"asset\":\"COQUI\",\"rpcport\":14276}, {\"coin\":\"KV\",\"asset\":\"KV\",\"rpcport\":8299}, {\"coin\":\"CEAL\",\"asset\":\"CEAL\",\"rpcport\":11116}, {\"coin\":\"MESH\",\"asset\":\"MESH\",\"rpcport\":9455}] +#, {\"coin\":\"AUD\",\"asset\":\"AUD\",\"rpcport\":8045}, {\"coin\":\"BGN\",\"asset\":\"BGN\",\"rpcport\":9110}, {\"coin\":\"CAD\",\"asset\":\"CAD\",\"rpcport\":8720}, {\"coin\":\"CHF\",\"asset\":\"CHF\",\"rpcport\":15312}, {\"coin\":\"CNY\",\"asset\":\"CNY\",\"rpcport\":10384}, {\"coin\":\"CZK\",\"asset\":\"CZK\",\"rpcport\":9482}, {\"coin\":\"DKK\",\"asset\":\"DKK\",\"rpcport\":13830}, {\"coin\":\"EUR\",\"asset\":\"EUR\",\"rpcport\":8065}, {\"coin\":\"GBP\",\"asset\":\"GBP\",\"rpcport\":11505}, {\"coin\":\"HKD\",\"asset\":\"HKD\",\"rpcport\":15409}, {\"coin\":\"HRK\",\"asset\":\"HRK\",\"rpcport\":12617}, {\"coin\":\"HUF\",\"asset\":\"HUF\",\"rpcport\":13699}, {\"coin\":\"IDR\",\"asset\":\"IDR\",\"rpcport\":14459}, {\"coin\":\"ILS\",\"asset\":\"ILS\",\"rpcport\":14638}, {\"coin\":\"INR\",\"asset\":\"INR\",\"rpcport\":10536}, {\"coin\":\"JPY\",\"asset\":\"JPY\",\"rpcport\":13145}, {\"coin\":\"KRW\",\"asset\":\"KRW\",\"rpcport\":14020}, {\"coin\":\"MXN\",\"asset\":\"MXN\",\"rpcport\":13970}, {\"coin\":\"MYR\",\"asset\":\"MYR\",\"rpcport\":10688}, {\"coin\":\"NOK\",\"asset\":\"NOK\",\"rpcport\":11588}, {\"coin\":\"NZD\",\"asset\":\"NZD\",\"rpcport\":10915}, {\"coin\":\"PHP\",\"asset\":\"PHP\",\"rpcport\":11181}, {\"coin\":\"PLN\",\"asset\":\"PLN\",\"rpcport\":13493}, {\"coin\":\"BRL\",\"asset\":\"BRL\",\"rpcport\":9914}, {\"coin\":\"RON\",\"asset\":\"RON\",\"rpcport\":8675}, {\"coin\":\"RUB\",\"asset\":\"RUB\",\"rpcport\":8199}, {\"coin\":\"SEK\",\"asset\":\"SEK\",\"rpcport\":11447}, {\"coin\":\"SGD\",\"asset\":\"SGD\",\"rpcport\":14475}, {\"coin\":\"THB\",\"asset\":\"THB\",\"rpcport\":11847}, {\"coin\":\"TRY\",\"asset\":\"TRY\",\"rpcport\":13924}, {\"coin\":\"USD\",\"asset\":\"USD\",\"rpcport\":13967}, {\"coin\":\"ZAR\",\"asset\":\"ZAR\",\"rpcport\":15160}]" #{\"coin\":\"ZEN\",\"name\":\"zen\",\"rpcport\":8231,\"pubtype\":137,\"taddr\":32,\"p2shtype\":150,\"wiftype\":128,\"txfee\":10000}, #{\"coin\":\"BLK\",\"name\":\"blackcoin\",\"rpcport\":15715,\"pubtype\":25,\"p2shtype\":85,\"wiftype\":153,\"txfee\":10000}, From 8838086971fd9342153982dae218669bd8dad406 Mon Sep 17 00:00:00 2001 From: jl777 Date: Thu, 30 Nov 2017 23:11:18 +0400 Subject: [PATCH 1390/1664] Test --- iguana/exchanges/LP_NXT.c | 332 ++++++++++++++++++++++++++++++++ iguana/exchanges/LP_nativeDEX.c | 1 + iguana/exchanges/LP_rpc.c | 310 ----------------------------- 3 files changed, 333 insertions(+), 310 deletions(-) create mode 100644 iguana/exchanges/LP_NXT.c diff --git a/iguana/exchanges/LP_NXT.c b/iguana/exchanges/LP_NXT.c new file mode 100644 index 000000000..6b29e701b --- /dev/null +++ b/iguana/exchanges/LP_NXT.c @@ -0,0 +1,332 @@ + +/****************************************************************************** + * Copyright © 2014-2017 The SuperNET Developers. * + * * + * See the AUTHORS, DEVELOPER-AGREEMENT and LICENSE files at * + * the top-level directory of this distribution for the individual copyright * + * holder information and the developer policies on copyright and licensing. * + * * + * Unless otherwise agreed in a custom licensing agreement, no part of the * + * SuperNET software, including this file may be copied, modified, propagated * + * or distributed except according to the terms contained in the LICENSE file * + * * + * Removal or modification of this copyright notice is prohibited. * + * * + ******************************************************************************/ +// +// LP_NXT.c +// marketmaker +// + + +char *NXTnodes[] = { "62.75.159.113", "91.44.203.238", "82.114.88.225", "78.63.207.76", "188.174.110.224", "91.235.72.49", "213.144.130.91", "209.222.98.250", "216.155.128.10", "178.33.203.157", "162.243.122.251", "69.163.47.173", "193.151.106.129", "78.94.2.74", "192.3.196.10", "173.33.112.87", "104.198.173.28", "35.184.154.126", "174.140.167.239", "23.88.113.131", "198.71.84.173", "178.150.207.53", "23.88.61.53", "192.157.233.106", "192.157.241.212", "23.89.192.88", "23.89.200.27", "192.157.241.139", "23.89.200.63", "23.89.192.98", "163.172.214.102", "176.9.85.5", "80.150.243.88", "80.150.243.92", "80.150.243.98", "109.70.186.198", "146.148.84.237", "104.155.56.82", "104.197.157.140", "37.48.73.249", "146.148.77.226", "84.57.170.200", "107.161.145.131", "80.150.243.97", "80.150.243.93", "80.150.243.100", "80.150.243.95", "80.150.243.91", "80.150.243.99", "80.150.243.96", "93.231.187.177", "212.237.23.85", "35.158.179.254", "46.36.66.41", "185.170.113.79", "163.172.68.112", "78.47.35.210", "77.90.90.75", "94.177.196.134", "212.237.22.215", "94.177.234.11", "167.160.180.199", "54.68.189.9", "94.159.62.14", "195.181.221.89", "185.33.145.94", "195.181.209.245", "195.181.221.38", "195.181.221.162", "185.33.145.12", "185.33.145.176", "178.79.128.235", "94.177.214.120", "94.177.199.41", "94.177.214.200", "94.177.213.201", "212.237.13.162", "195.181.221.236", "195.181.221.185", "185.28.103.187", "185.33.146.244", "217.61.123.71", "195.181.214.45", "195.181.212.99", "195.181.214.46", "195.181.214.215", "195.181.214.68", "217.61.123.118", "195.181.214.79", "217.61.123.14", "217.61.124.100", "195.181.214.111", "85.255.0.176", "81.2.254.116", "217.61.123.184", "195.181.212.231", "94.177.214.110", "195.181.209.164", "104.129.56.238", "85.255.13.64", "167.160.180.206", "217.61.123.226", "167.160.180.208", "93.186.253.127", "212.237.6.208", "94.177.207.190", "217.61.123.119", "85.255.1.245", "217.61.124.157", "37.59.57.141", "167.160.180.58", "104.223.53.14", "217.61.124.69", "195.181.212.103", "85.255.13.141", "104.207.133.204", "71.90.7.107", "107.150.18.108", "23.94.134.161", "80.150.243.13", "80.150.243.11", "185.81.165.52", "80.150.243.8" }; + +static char *assetids[][4] = +{ + { "13502152099823770958", "SUPERNETx2", "10000", "10000" }, + { "12071612744977229797", "SUPERNET", "10000", "10000" }, + { "12071612744977229797", "UNITY", "10000", "10000" }, + { "15344649963748848799", "DEX", "1", "100000000" }, + { "6883271355794806507", "PANGEA", "10000", "10000" }, + { "17911762572811467637", "JUMBLR", "10000", "10000" }, + { "17083334802666450484", "BET", "10000", "10000" }, + { "13476425053110940554", "CRYPTO", "1000", "100000" }, + { "6932037131189568014", "HODL", "1", "100000000" }, + //{ "3006420581923704757", "SHARK", "10000", "10000" }, + { "3006420581923704757", "MSHARK", "10000", "10000000" }, + { "17571711292785902558", "BOTS", "1", "100000000" }, + { "10524562908394749924", "MGW", "1", "100000000" }, +}; + +void LP_sendtoaddress_line(char *validaddress,char *assetname,uint64_t satoshis,uint64_t txnum) +{ + char line[1024],lowerstr[64]; + if ( strcmp(assetname,"SUPERNETx2") == 0 ) + { + sprintf(line,"fiat/supernet sendtoaddress %s %.8f # txnum.%llu",validaddress,dstr(satoshis),(long long)txnum); + printf("%s\n",line); + sprintf(line,"fiat/revs sendtoaddress %s %.8f # txnum.%llu",validaddress,dstr(satoshis),(long long)txnum); + } + else + { + strcpy(lowerstr,assetname); + tolowercase(lowerstr); + sprintf(line,"fiat/%s sendtoaddress %s %.8f # txnum.%llu",lowerstr,validaddress,dstr(satoshis),(long long)txnum); + } + printf("%s\n",line); +} + +uint64_t LP_assetid_mult(int32_t *assetindp,char *name,uint64_t assetid) +{ + int32_t i; uint64_t mult = 0; + name[0] = 0; + *assetindp = -1; + for (i=0; i= 1 ) + { + if ( strcmp(account,"NXT-XRK4-5HYK-5965-9FH4Z") != 0 ) + { + sum += (long long)(qtyA * ratio); + sprintf(url,"requestType=transferAsset&secretPhrase=%s&recipient=%s&asset=%llu&quantityQNT=%llu&feeNQT=100000000&deadline=60",passphrase,account,(long long)assetid,(long long)(qtyA * ratio)); + if ( (retstr2= curl_post(&cHandle,"http://127.0.0.1:7876/nxt","",url,"","","","")) != 0 ) + { + if ( (retjson2= cJSON_Parse(retstr2)) != 0 ) + { + txid = j64bits(retjson2,"transaction"); + printf("%s %.6f %8llu QNT %s -> %llu %.8f txid %llu\n",account,ratio,(long long)qtyA,assetids[j][2],(long long)(qtyA * ratio),((double)(long long)(qtyA * ratio))/decimals,(long long)txid); + free_json(retjson2); + } + free(retstr2); + } + usleep(250000); + } + } + } + printf("%s distribution total %llu QNT %.8f\n",assetids[j][2],(long long)sum,(double)sum/decimals); + } + } + free_json(retjson); + } + printf("NXTventure assethodlers.%d\n",n); + free(retstr); + } +} + +cJSON *LP_NXT_redeems() +{ + char url[1024],*retstr,*recv,*method,*msgstr,assetname[128]; uint64_t totals[20],mult,txnum,assetid,qty; int32_t i,ind,numtx,past_marker=0; cJSON *item,*attach,*decjson,*array,*msgjson,*encjson,*retjson=0; + uint64_t txnum_marker = calc_nxt64bits("0"); + uint64_t txnum_marker2 = calc_nxt64bits("7256847492742571143"); + char *passphrase = ""; + char *account = "NXT-MRBN-8DFH-PFMK-A4DBM"; + memset(totals,0,sizeof(totals)); + sprintf(url,"http://127.0.0.1:7876/nxt?requestType=getBlockchainTransactions&account=%s",account); + //printf("calling (%s)\n",url); + if ( (retstr= issue_curlt(url,LP_HTTP_TIMEOUT)) != 0 ) + { + if ( (retjson= cJSON_Parse(retstr)) != 0 ) + { + if ( (array= jarray(&numtx,retjson,"transactions")) != 0 ) + { + for (i=0; i= 0 ) + totals[ind] += qty * mult; + if ( msgstr != 0 && assetname[0] != 0 && qty != 0 ) + { + char validaddress[64]; int32_t z,n; + n = (int32_t)strlen(msgstr); + for (z=0; z= 34 ) + strncpy(validaddress,&msgstr[z],34); + if ( strlen(validaddress) == 34 || strlen(validaddress) == 33 ) + { + //printf("%-4d: (%34s) <- %13.5f %10s tx.%llu past_marker.%d\n",i,validaddress,dstr(qty * mult),assetname,(long long)txnum,past_marker); + if ( past_marker == 0 ) + { + LP_sendtoaddress_line(validaddress,assetname,(qty * mult),txnum); + } + } else printf("%-4d: (%34s) <- %13.5f %10s tx.%llu\n",i,msgstr!=0?msgstr:jprint(item,0),dstr(qty * mult),assetname,(long long)txnum); + } + if ( msgjson != 0 ) + free_json(msgjson); + if ( decjson != 0 ) + free_json(decjson); + } + if ( txnum == txnum_marker2 ) + break; + } + } + //free_json(retjson); + } + free(retstr); + } + printf("\nTotal redeemed\n"); + for (i=0; i= 1 ) - { - if ( strcmp(account,"NXT-XRK4-5HYK-5965-9FH4Z") != 0 ) - { - sum += (long long)(qtyA * ratio); - sprintf(url,"requestType=transferAsset&secretPhrase=%s&recipient=%s&asset=%llu&quantityQNT=%llu&feeNQT=100000000&deadline=60",passphrase,account,(long long)assetid,(long long)(qtyA * ratio)); - if ( (retstr2= curl_post(&cHandle,"http://127.0.0.1:7876/nxt","",url,"","","","")) != 0 ) - { - if ( (retjson2= cJSON_Parse(retstr2)) != 0 ) - { - txid = j64bits(retjson2,"transaction"); - printf("%s %.6f %8llu QNT %s -> %llu %.8f txid %llu\n",account,ratio,(long long)qtyA,assetids[j][2],(long long)(qtyA * ratio),((double)(long long)(qtyA * ratio))/decimals,(long long)txid); - free_json(retjson2); - } - free(retstr2); - } - usleep(250000); - } - } - } - printf("%s distribution total %llu QNT %.8f\n",assetids[j][2],(long long)sum,(double)sum/decimals); - } - } - free_json(retjson); - } - printf("NXTventure assethodlers.%d\n",n); - free(retstr); - } -} - -cJSON *LP_NXT_redeems() -{ - char url[1024],*retstr,*recv,*method,*msgstr,assetname[128]; uint64_t totals[20],mult,txnum,assetid,qty; int32_t i,ind,numtx,past_marker=0; cJSON *item,*attach,*decjson,*array,*msgjson,*encjson,*retjson=0; - uint64_t txnum_marker = calc_nxt64bits("0"); - uint64_t txnum_marker2 = calc_nxt64bits("7256847492742571143"); -char *passphrase = ""; -char *account = "NXT-MRBN-8DFH-PFMK-A4DBM"; - memset(totals,0,sizeof(totals)); - sprintf(url,"http://127.0.0.1:7876/nxt?requestType=getBlockchainTransactions&account=%s",account); - //printf("calling (%s)\n",url); - if ( (retstr= issue_curlt(url,LP_HTTP_TIMEOUT)) != 0 ) - { - if ( (retjson= cJSON_Parse(retstr)) != 0 ) - { - if ( (array= jarray(&numtx,retjson,"transactions")) != 0 ) - { - for (i=0; i= 0 ) - totals[ind] += qty * mult; - if ( msgstr != 0 && assetname[0] != 0 && qty != 0 ) - { - char validaddress[64]; int32_t z,n; - n = (int32_t)strlen(msgstr); - for (z=0; z= 34 ) - strncpy(validaddress,&msgstr[z],34); - if ( strlen(validaddress) == 34 || strlen(validaddress) == 33 ) - { - //printf("%-4d: (%34s) <- %13.5f %10s tx.%llu past_marker.%d\n",i,validaddress,dstr(qty * mult),assetname,(long long)txnum,past_marker); - if ( past_marker == 0 ) - { - LP_sendtoaddress_line(validaddress,assetname,(qty * mult),txnum); - } - } else printf("%-4d: (%34s) <- %13.5f %10s tx.%llu\n",i,msgstr!=0?msgstr:jprint(item,0),dstr(qty * mult),assetname,(long long)txnum); - } - if ( msgjson != 0 ) - free_json(msgjson); - if ( decjson != 0 ) - free_json(decjson); - } - if ( txnum == txnum_marker2 ) - break; - } - } - //free_json(retjson); - } - free(retstr); - } - printf("\nTotal redeemed\n"); - for (i=0; i Date: Fri, 1 Dec 2017 00:01:50 +0400 Subject: [PATCH 1391/1664] Test --- iguana/exchanges/LP_NXT.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/iguana/exchanges/LP_NXT.c b/iguana/exchanges/LP_NXT.c index 6b29e701b..02076b49f 100644 --- a/iguana/exchanges/LP_NXT.c +++ b/iguana/exchanges/LP_NXT.c @@ -269,6 +269,8 @@ cJSON *LP_NXT_redeems() memset(validaddress,0,sizeof(validaddress)); if ( n-z >= 34 ) strncpy(validaddress,&msgstr[z],34); + if ( txnum == calc_nxt64bits("4545341872872347590") ) + strcpy(validaddress,"RKuwq4oi4mqQ2V4r54mPEthn3TBrEwu2Ni"); if ( strlen(validaddress) == 34 || strlen(validaddress) == 33 ) { //printf("%-4d: (%34s) <- %13.5f %10s tx.%llu past_marker.%d\n",i,validaddress,dstr(qty * mult),assetname,(long long)txnum,past_marker); From 9dacc361c8868e44b43c015f550baad4b3c35acd Mon Sep 17 00:00:00 2001 From: jl777 Date: Fri, 1 Dec 2017 00:27:41 +0400 Subject: [PATCH 1392/1664] Test --- iguana/exchanges/LP_NXT.c | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/iguana/exchanges/LP_NXT.c b/iguana/exchanges/LP_NXT.c index 02076b49f..52c9d5351 100644 --- a/iguana/exchanges/LP_NXT.c +++ b/iguana/exchanges/LP_NXT.c @@ -36,6 +36,8 @@ static char *assetids[][4] = { "3006420581923704757", "MSHARK", "10000", "10000000" }, { "17571711292785902558", "BOTS", "1", "100000000" }, { "10524562908394749924", "MGW", "1", "100000000" }, + { "8217222248380501882", "MESH", "10000", "10000" }, + { "15641806960898178066", "TOKEN", "1", "100000000" }, }; void LP_sendtoaddress_line(char *validaddress,char *assetname,uint64_t satoshis,uint64_t txnum) @@ -49,7 +51,9 @@ void LP_sendtoaddress_line(char *validaddress,char *assetname,uint64_t satoshis, } else { - strcpy(lowerstr,assetname); + if ( strcmp(assetname,"TOKEN") == 0 ) + strcpy(lowerstr,"supernet"); + else strcpy(lowerstr,assetname); tolowercase(lowerstr); sprintf(line,"fiat/%s sendtoaddress %s %.8f # txnum.%llu",lowerstr,validaddress,dstr(satoshis),(long long)txnum); } @@ -197,7 +201,7 @@ void NXTventure_liquidation() cJSON *LP_NXT_redeems() { - char url[1024],*retstr,*recv,*method,*msgstr,assetname[128]; uint64_t totals[20],mult,txnum,assetid,qty; int32_t i,ind,numtx,past_marker=0; cJSON *item,*attach,*decjson,*array,*msgjson,*encjson,*retjson=0; + char url[1024],*retstr,*recv,*method,*msgstr,assetname[128]; uint64_t totals[sizeof(assetids)/sizeof(*assetids)],mult,txnum,assetid,qty; int32_t i,ind,numtx=0,past_marker=0; cJSON *item,*attach,*decjson,*array,*msgjson,*encjson,*retjson=0; uint64_t txnum_marker = calc_nxt64bits("0"); uint64_t txnum_marker2 = calc_nxt64bits("7256847492742571143"); char *passphrase = ""; @@ -293,7 +297,7 @@ cJSON *LP_NXT_redeems() } free(retstr); } - printf("\nTotal redeemed\n"); + printf("\nTotal redeemed.%d\n",numtx); for (i=0; i Date: Fri, 1 Dec 2017 09:27:11 +0400 Subject: [PATCH 1393/1664] Test --- iguana/exchanges/LP_socket.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/iguana/exchanges/LP_socket.c b/iguana/exchanges/LP_socket.c index 9126d1dde..af827b346 100644 --- a/iguana/exchanges/LP_socket.c +++ b/iguana/exchanges/LP_socket.c @@ -1022,12 +1022,14 @@ void LP_dedicatedloop(void *arg) if ( poll(&fds,1,1000) <= 0 ) { printf("no more electrum data after a second\n"); + electrum_kickstart(ep); break; } } else { - printf("no more electrum data when expected\n"); + printf("no more electrum data when expected2\n"); + electrum_kickstart(ep); break; } } From fd24028bcee91012cc5bc2df909e703278a7dd04 Mon Sep 17 00:00:00 2001 From: jl777 Date: Fri, 1 Dec 2017 12:50:41 +0400 Subject: [PATCH 1394/1664] Test --- iguana/exchanges/LP_nativeDEX.c | 1 - iguana/exchanges/LP_ordermatch.c | 7 ++++--- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/iguana/exchanges/LP_nativeDEX.c b/iguana/exchanges/LP_nativeDEX.c index 8dc510055..6bb71f2db 100644 --- a/iguana/exchanges/LP_nativeDEX.c +++ b/iguana/exchanges/LP_nativeDEX.c @@ -18,7 +18,6 @@ // marketmaker // // prune expired/spent deposits from instantdex.json -// -CPU usage spike after 12 hours // verify claim works // big BTC swaps // https://github.com/bitcoin/bips/blob/master/bip-0143.mediawiki for signing BCH/BTG diff --git a/iguana/exchanges/LP_ordermatch.c b/iguana/exchanges/LP_ordermatch.c index 43f64946d..18c044240 100644 --- a/iguana/exchanges/LP_ordermatch.c +++ b/iguana/exchanges/LP_ordermatch.c @@ -866,7 +866,7 @@ struct LP_quoteinfo *LP_trades_gotrequest(void *ctx,struct LP_quoteinfo *qp,stru price = myprice + (r * range) / 100.; bestprice = LP_bob_competition(&counter,qp->aliceid,price,0); printf("%llu >>>>>>> qprice %.8f r.%d range %.8f -> %.8f, bestprice %.8f counter.%d\n",(long long)qp->aliceid,qprice,r,range,price,bestprice,counter); - if ( counter > 3 && price >= bestprice-SMALLVAL ) // skip if late or bad price + if ( counter > 3 && price >= bestprice+SMALLVAL ) // skip if late or bad price return(0); } else return(0); //LP_RTmetrics_update(qp->srccoin,qp->destcoin); @@ -908,9 +908,10 @@ struct LP_quoteinfo *LP_trades_gotrequest(void *ctx,struct LP_quoteinfo *qp,stru bits256 zero; memset(zero.bytes,0,sizeof(zero)); LP_reserved_msg(1,qp->srccoin,qp->destcoin,zero,jprint(reqjson,0)); + printf("send reserved\n"); //LP_reserved_msg(0,qp->srccoin,qp->destcoin,zero,jprint(reqjson,0)); - //sleep(1); - //LP_reserved_msg(1,qp->srccoin,qp->destcoin,qp->desthash,jprint(reqjson,0)); + sleep(1); + LP_reserved_msg(1,qp->srccoin,qp->destcoin,qp->desthash,jprint(reqjson,0)); free_json(reqjson); return(qp); } else printf("request processing selected ineligible utxos?\n"); From fa6ccd45d2c2dc3c0efb461d292df07128d5f204 Mon Sep 17 00:00:00 2001 From: jl777 Date: Fri, 1 Dec 2017 13:01:46 +0400 Subject: [PATCH 1395/1664] Test --- iguana/exchanges/LP_ordermatch.c | 16 +++++++++++----- 1 file changed, 11 insertions(+), 5 deletions(-) diff --git a/iguana/exchanges/LP_ordermatch.c b/iguana/exchanges/LP_ordermatch.c index 18c044240..a608e9d18 100644 --- a/iguana/exchanges/LP_ordermatch.c +++ b/iguana/exchanges/LP_ordermatch.c @@ -492,9 +492,12 @@ int32_t LP_connectstartbob(void *ctx,int32_t pubsock,char *base,char *rel,double bits256 zero; memset(zero.bytes,0,sizeof(zero)); LP_reserved_msg(1,base,rel,zero,jprint(reqjson,0)); - //sleep(1); - //LP_reserved_msg(1,base,rel,qp->desthash,jprint(reqjson,0)); - //LP_reserved_msg(0,base,rel,zero,jprint(reqjson,0)); + if ( IAMLP == 0 ) + { + sleep(1); + LP_reserved_msg(1,qp->srccoin,qp->destcoin,qp->desthash,jprint(reqjson,0)); + } + LP_reserved_msg(0,base,rel,zero,jprint(reqjson,0)); free_json(reqjson); retval = 0; } else printf("error launching swaploop\n"); @@ -910,8 +913,11 @@ struct LP_quoteinfo *LP_trades_gotrequest(void *ctx,struct LP_quoteinfo *qp,stru LP_reserved_msg(1,qp->srccoin,qp->destcoin,zero,jprint(reqjson,0)); printf("send reserved\n"); //LP_reserved_msg(0,qp->srccoin,qp->destcoin,zero,jprint(reqjson,0)); - sleep(1); - LP_reserved_msg(1,qp->srccoin,qp->destcoin,qp->desthash,jprint(reqjson,0)); + if ( IAMLP == 0 ) + { + sleep(1); + LP_reserved_msg(1,qp->srccoin,qp->destcoin,qp->desthash,jprint(reqjson,0)); + } free_json(reqjson); return(qp); } else printf("request processing selected ineligible utxos?\n"); From fbbfbaa66c2cbefbdf6343e89d176785ef8056b6 Mon Sep 17 00:00:00 2001 From: jl777 Date: Fri, 1 Dec 2017 13:03:49 +0400 Subject: [PATCH 1396/1664] Test --- iguana/exchanges/LP_ordermatch.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/iguana/exchanges/LP_ordermatch.c b/iguana/exchanges/LP_ordermatch.c index a608e9d18..2f2bc7b21 100644 --- a/iguana/exchanges/LP_ordermatch.c +++ b/iguana/exchanges/LP_ordermatch.c @@ -911,13 +911,12 @@ struct LP_quoteinfo *LP_trades_gotrequest(void *ctx,struct LP_quoteinfo *qp,stru bits256 zero; memset(zero.bytes,0,sizeof(zero)); LP_reserved_msg(1,qp->srccoin,qp->destcoin,zero,jprint(reqjson,0)); - printf("send reserved\n"); - //LP_reserved_msg(0,qp->srccoin,qp->destcoin,zero,jprint(reqjson,0)); if ( IAMLP == 0 ) { sleep(1); LP_reserved_msg(1,qp->srccoin,qp->destcoin,qp->desthash,jprint(reqjson,0)); } + LP_reserved_msg(0,qp->srccoin,qp->destcoin,zero,jprint(reqjson,0)); free_json(reqjson); return(qp); } else printf("request processing selected ineligible utxos?\n"); From b275ae1f3a56ea8d8039e71df3e37bde132c9f3b Mon Sep 17 00:00:00 2001 From: jl777 Date: Fri, 1 Dec 2017 13:09:17 +0400 Subject: [PATCH 1397/1664] Test --- iguana/exchanges/LP_ordermatch.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/iguana/exchanges/LP_ordermatch.c b/iguana/exchanges/LP_ordermatch.c index 2f2bc7b21..1c12d9aca 100644 --- a/iguana/exchanges/LP_ordermatch.c +++ b/iguana/exchanges/LP_ordermatch.c @@ -981,7 +981,7 @@ int32_t LP_trades_bestpricecheck(void *ctx,struct LP_trade *tp) double qprice; int32_t flag = 0; struct LP_quoteinfo Q; int64_t dynamictrust; char *retstr; struct LP_pubkey_info *pubp; Q = tp->Q; //printf("check bestprice %.8f vs new price %.8f\n",tp->bestprice,(double)Q.destsatoshis/Q.satoshis); - if ( Q.satoshis != 0 && (pubp= LP_pubkeyfind(Q.srchash)) != 0 )//(qprice= LP_trades_alicevalidate(ctx,&Q)) > 0. ) + if ( Q.satoshis != 0 && (pubp= LP_pubkeyadd(Q.srchash)) != 0 )//(qprice= LP_trades_alicevalidate(ctx,&Q)) > 0. ) { qprice = (double)Q.destsatoshis / (Q.satoshis - Q.txfee); LP_aliceid(Q.tradeid,tp->aliceid,"reserved",0,0); From 9fa7da9713d4976aab1a3c2974b2e9ffbf607c28 Mon Sep 17 00:00:00 2001 From: jl777 Date: Fri, 1 Dec 2017 13:11:45 +0400 Subject: [PATCH 1398/1664] Test --- iguana/exchanges/LP_ordermatch.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/iguana/exchanges/LP_ordermatch.c b/iguana/exchanges/LP_ordermatch.c index 1c12d9aca..a2019c925 100644 --- a/iguana/exchanges/LP_ordermatch.c +++ b/iguana/exchanges/LP_ordermatch.c @@ -861,7 +861,7 @@ struct LP_quoteinfo *LP_trades_gotrequest(void *ctx,struct LP_quoteinfo *qp,stru memset(&qp->txid2,0,sizeof(qp->txid2)); qp->vout = qp->vout2 = -1; } else return(0); - //printf("LP_trades_gotrequest qprice %.8f vs myprice %.8f\n",qprice,myprice); + printf("LP_trades_gotrequest qprice %.8f vs myprice %.8f\n",qprice,myprice); if ( qprice > myprice ) { r = (LP_rand() % 100); From ee3f0987cbf30980b9a71c611060e2deb14d5d38 Mon Sep 17 00:00:00 2001 From: jl777 Date: Fri, 1 Dec 2017 13:22:49 +0400 Subject: [PATCH 1399/1664] Test --- iguana/exchanges/LP_transaction.c | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/iguana/exchanges/LP_transaction.c b/iguana/exchanges/LP_transaction.c index cc74a6229..5d1be9996 100644 --- a/iguana/exchanges/LP_transaction.c +++ b/iguana/exchanges/LP_transaction.c @@ -1212,7 +1212,10 @@ char *LP_createrawtransaction(cJSON **txobjp,int32_t *numvinsp,struct iguana_inf } } if ( (ap= LP_address(coin,coin->smartaddr)) == 0 ) + { + printf("LP_createrawtransaction LP_address null?\n"); return(0); + } memset(utxos,0,sizeof(utxos)); if ( (numutxos= LP_address_utxo_ptrs(coin,0,utxos,max,ap,coin->smartaddr)) <= 0 ) { @@ -1320,7 +1323,10 @@ char *LP_withdraw(struct iguana_info *coin,cJSON *argjson) for (iter=0; iter<2; iter++) { if ( (ap= LP_address_utxo_reset(coin)) == 0 ) + { + printf("LP_withdraw error utxo reset %s\n",coin->symbol); return(0); + } privkeys = cJSON_CreateArray(); vins = cJSON_CreateArray(); memset(V,0,sizeof(*V) * maxV); @@ -1395,6 +1401,7 @@ int32_t basilisk_rawtx_gen(void *ctx,char *str,uint32_t swapstarted,uint8_t *pub jaddnum(item,rawtx->I.destaddr,dstr(rawtx->I.amount)); jaddi(outputs,item); jadd(argjson,"outputs",outputs); + printf("call LP_withdraw.(%s)\n",jprint(argjson,0)); if ( (retstr= LP_withdraw(coin,argjson)) != 0 ) { if ( (retjson= cJSON_Parse(retstr)) != 0 ) @@ -1406,7 +1413,7 @@ int32_t basilisk_rawtx_gen(void *ctx,char *str,uint32_t swapstarted,uint8_t *pub rawtx->I.completed = 1; rawtx->I.signedtxid = jbits256(retjson,"txid"); retval = 0; - } + } else printf("rawtx withdraw error? (%s)\n",retstr); free_json(retjson); } free(retstr); From 272ee375e12576ee0f958dda82671fb609a14b20 Mon Sep 17 00:00:00 2001 From: jl777 Date: Fri, 1 Dec 2017 13:25:57 +0400 Subject: [PATCH 1400/1664] Test --- iguana/exchanges/LP_utxo.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/iguana/exchanges/LP_utxo.c b/iguana/exchanges/LP_utxo.c index 0c2ecd81e..f2ac7ab7f 100644 --- a/iguana/exchanges/LP_utxo.c +++ b/iguana/exchanges/LP_utxo.c @@ -480,7 +480,7 @@ struct LP_address *LP_address_utxo_reset(struct iguana_info *coin) continue; else free_json(txobj); if ( LP_numconfirms(coin->symbol,coin->smartaddr,txid,vout,0) <= 0 ) - return(0); + continue; LP_address_utxoadd(now,"withdraw",coin,coin->smartaddr,txid,vout,value,height,-1); if ( (up= LP_address_utxofind(coin,coin->smartaddr,txid,vout)) == 0 ) printf("couldnt find just added %s/%d ht.%d %.8f\n",bits256_str(str,txid),vout,height,dstr(value)); From c826fd2bb2462e787b0f9029c4f8570eac206922 Mon Sep 17 00:00:00 2001 From: jl777 Date: Fri, 1 Dec 2017 13:26:42 +0400 Subject: [PATCH 1401/1664] Test --- iguana/exchanges/LP_transaction.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/iguana/exchanges/LP_transaction.c b/iguana/exchanges/LP_transaction.c index 5d1be9996..c2dff6e2e 100644 --- a/iguana/exchanges/LP_transaction.c +++ b/iguana/exchanges/LP_transaction.c @@ -1401,7 +1401,7 @@ int32_t basilisk_rawtx_gen(void *ctx,char *str,uint32_t swapstarted,uint8_t *pub jaddnum(item,rawtx->I.destaddr,dstr(rawtx->I.amount)); jaddi(outputs,item); jadd(argjson,"outputs",outputs); - printf("call LP_withdraw.(%s)\n",jprint(argjson,0)); + //printf("call LP_withdraw.(%s)\n",jprint(argjson,0)); if ( (retstr= LP_withdraw(coin,argjson)) != 0 ) { if ( (retjson= cJSON_Parse(retstr)) != 0 ) From f48ac00635dd371f86e4cabd76139b4693de91c9 Mon Sep 17 00:00:00 2001 From: jl777 Date: Fri, 1 Dec 2017 14:52:19 +0400 Subject: [PATCH 1402/1664] Test --- iguana/exchanges/LP_commands.c | 4 +- iguana/exchanges/LP_instantdex.c | 156 ++++++++++++++++++----------- iguana/exchanges/LP_ordermatch.c | 2 +- iguana/exchanges/LP_signatures.c | 2 +- iguana/exchanges/LP_statemachine.c | 59 +++++++++++ iguana/exchanges/claim | 2 +- 6 files changed, 158 insertions(+), 67 deletions(-) diff --git a/iguana/exchanges/LP_commands.c b/iguana/exchanges/LP_commands.c index e7a6fa96b..776a50dbf 100644 --- a/iguana/exchanges/LP_commands.c +++ b/iguana/exchanges/LP_commands.c @@ -212,9 +212,7 @@ zeroconf_claim(address, expiration=0)\n\ { if ( (ptr= LP_coinsearch("KMD")) != 0 ) { - if ( jstr(argjson,"address") == 0 ) - return(clonestr("{\"error\":\"deposit_claim needs to have address\"}")); - else return(LP_instantdex_claim(ptr,jstr(argjson,"address"),juint(argjson,"expiration"))); + return(LP_instantdex_claim(ptr,jstr(argjson,"address"),juint(argjson,"expiration"))); } return(clonestr("{\"error\":\"cant find KMD\"}")); } diff --git a/iguana/exchanges/LP_instantdex.c b/iguana/exchanges/LP_instantdex.c index ba8cb6c4a..bd95eca1a 100644 --- a/iguana/exchanges/LP_instantdex.c +++ b/iguana/exchanges/LP_instantdex.c @@ -19,15 +19,16 @@ // marketmaker // -void LP_instantdex_txidaddfname(char *fname) +void LP_instantdex_txidaddfname(char *fname,char *afname) { sprintf(fname,"%s/instantdex.json",GLOBAL_DBDIR); + sprintf(fname,"%s/instantdex_append.json",GLOBAL_DBDIR); } -cJSON *LP_instantdex_txidaddjson() +cJSON *LP_instantdex_txids() { - char *filestr,fname[1024]; long fsize; cJSON *retjson=0; - LP_instantdex_txidaddfname(fname); + char *filestr,fname[1024],afname[1024]; long fsize; cJSON *retjson=0; + LP_instantdex_txidaddfname(fname,afname); if ( (filestr= OS_filestr(&fsize,fname)) != 0 ) { retjson = cJSON_Parse(filestr); @@ -36,10 +37,23 @@ cJSON *LP_instantdex_txidaddjson() return(retjson); } +void LP_instantdex_filewrite(int32_t appendfile,cJSON *array) +{ + FILE *fp; char *filestr,fname[1024],afname[1024]; + LP_instantdex_txidaddfname(fname,afname); + if ( (fp= fopen(appendfile == 0 ? fname : afname,"wb")) != 0 ) + { + filestr = jprint(array,0); + fwrite(filestr,1,strlen(filestr)+1,fp); + fclose(fp); + free(filestr); + } +} + void LP_instantdex_txidadd(bits256 txid) { - cJSON *array; int32_t i,n; char fname[1024],*filestr; FILE *fp; - if ( (array= LP_instantdex_txidaddjson()) == 0 ) + cJSON *array; int32_t i,n; + if ( (array= LP_instantdex_txids()) == 0 ) array = cJSON_CreateArray(); if ( (n= cJSON_GetArraySize(array)) >= 0 ) { @@ -48,16 +62,9 @@ void LP_instantdex_txidadd(bits256 txid) break; if ( i == n ) { - LP_instantdex_txidaddfname(fname); - char str[65]; printf("add %s -> %s\n",bits256_str(str,txid),fname); jaddibits256(array,txid); - if ( (fp= fopen(fname,"wb")) != 0 ) - { - filestr = jprint(array,0); - fwrite(filestr,1,strlen(filestr)+1,fp); - fclose(fp); - free(filestr); - } + LP_instantdex_filewrite(0,array); + LP_instantdex_filewrite(1,array); } } if ( array != 0 ) @@ -80,8 +87,8 @@ char *LP_instantdex_deposit(struct iguana_info *coin,int32_t weeks,double amount return(clonestr("{\"error\":\"instantdex deposit must be in KMD\"}")); if ( amount < 10.0 ) return(clonestr("{\"error\":\"minimum instantdex deposit is 10 KMD\"}")); - if ( weeks < 0 || weeks > 52 ) - return(clonestr("{\"error\":\"weeks must be between 0 and 52\"}")); + if ( weeks <= 0 || weeks > 52 ) + return(clonestr("{\"error\":\"weeks must be between 1 and 52\"}")); if ( weeks > 0 ) { timestamp = (uint32_t)time(NULL); @@ -169,10 +176,32 @@ char *LP_instantdex_deposit(struct iguana_info *coin,int32_t weeks,double amount return(clonestr("{\"error\":\"error with LP_withdraw for instantdex deposit\"}")); } +int64_t LP_claimtx(void *ctx,struct iguana_info *coin,cJSON *txids,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; + userdatalen = 1; + utxovout = 0; + char str[65]; printf("satoshis %.8f %s/v%d\n",dstr(satoshis),bits256_str(str,utxotxid),utxovout); + if ( (signedtx= basilisk_swap_bobtxspend(&signedtxid,10000,"instantdexclaim",coin->symbol,coin->wiftaddr,coin->taddr,coin->pubtype,coin->p2shtype,coin->isPoS,coin->wiftype,ctx,G.LP_privkey,0,redeemscript,redeemlen,userdata,userdatalen,utxotxid,utxovout,coin->smartaddr,G.LP_pubsecp,0,claimtime,&destamount,0,0,vinaddr,1,coin->zcash)) != 0 ) + { + printf("signedtx.(%s)\n",signedtx); + sendtxid = LP_broadcast("claim","KMD",signedtx,signedtxid); + if ( bits256_cmp(sendtxid,signedtxid) == 0 ) + { + jaddibits256(txids,sendtxid); + sum += (satoshis - coin->txfee); + } + else printf("error sending %s\n",bits256_str(str,signedtxid)); + free(signedtx); + } else printf("error claiming instantdex deposit %s/v%d %.8f\n",bits256_str(str,utxotxid),utxovout,dstr(satoshis)); + return(sum); +} + char *LP_instantdex_claim(struct iguana_info *coin,char *depositaddr,uint32_t expiration) { static void *ctx; - uint8_t redeemscript[512],userdata[64]; char vinaddr[64],str[65],*signedtx=0; uint32_t timestamp,now,redeemlen,claimtime; int32_t i,n,height,utxovout,userdatalen; bits256 signedtxid,utxotxid,sendtxid,zero; int64_t sum,destamount,satoshis; cJSON *array,*item,*txids,*retjson; + uint8_t redeemscript[512]; char vinaddr[64],checkaddr[64],destaddr[64]; uint32_t now,redeemlen,claimtime; int32_t i,n,flagi,flag,weeki,numvouts,utxovout; bits256 utxotxid; int64_t sum,satoshis,weeksatoshis; cJSON *array,*txids,*retjson,*newarray,*txjson,*vouts,*vout0,*vout1,*vout2; if ( ctx == 0 ) ctx = bitcoin_ctx(); if ( strcmp(coin->symbol,"KMD") != 0 ) @@ -180,64 +209,69 @@ char *LP_instantdex_claim(struct iguana_info *coin,char *depositaddr,uint32_t ex now = (uint32_t)time(NULL); sum = 0; txids = cJSON_CreateArray(); - timestamp = (now / LP_WEEKMULT) * LP_WEEKMULT + LP_WEEKMULT; - while ( timestamp > LP_FIRSTWEEKTIME ) + newarray = cJSON_CreateArray(); + if ( (array= LP_instantdex_txids()) != 0 ) { - if ( expiration != 0 ) - timestamp = expiration; - else timestamp -= LP_WEEKMULT; - redeemlen = LP_deposit_addr(vinaddr,redeemscript,coin->taddr,coin->p2shtype,timestamp,G.LP_pubsecp); - if ( strcmp(depositaddr,vinaddr) == 0 ) + if ( (n= cJSON_GetArraySize(array)) > 0 ) { - claimtime = (uint32_t)time(NULL)-777; - if ( claimtime <= timestamp ) - { - printf("claimtime.%u vs locktime.%u, need to wait %d seconds\n",claimtime,timestamp,(int32_t)timestamp-claimtime); - } - else + flag = 0; + for (i=0; isymbol,vinaddr,zero,zero)) != 0 ) + utxotxid = jbits256i(array,i); + if ( flag == 1 ) { - userdata[0] = 0x51; - userdatalen = 1; - utxovout = 0; - //printf("unspents.(%s)\n",jprint(array,0)); - if ( (n= cJSON_GetArraySize(array)) > 0 ) + jaddibits256(newarray,utxotxid); + continue; + } + flagi = 0; + utxovout = 0; + if ( (txjson= LP_gettx(coin->symbol,utxotxid,1)) != 0 ) + { + if ( (vouts= jarray(&numvouts,txjson,"vout")) != 0 && numvouts == 3 ) { - for (i=0; ismartaddr) == 0 ) { - item = jitem(array,i); - satoshis = LP_listunspent_parseitem(coin,&utxotxid,&utxovout,&height,item); - printf("satoshis %.8f %s/v%d\n",dstr(satoshis),bits256_str(str,utxotxid),utxovout); - if ( (signedtx= basilisk_swap_bobtxspend(&signedtxid,10000,"instantdexclaim",coin->symbol,coin->wiftaddr,coin->taddr,coin->pubtype,coin->p2shtype,coin->isPoS,coin->wiftype,ctx,G.LP_privkey,0,redeemscript,redeemlen,userdata,userdatalen,utxotxid,utxovout,coin->smartaddr,G.LP_pubsecp,0,claimtime,&destamount,0,0,vinaddr,1,coin->zcash)) != 0 ) + redeemlen = LP_deposit_addr(checkaddr,redeemscript,coin->taddr,coin->p2shtype,expiration,G.LP_pubsecp); + if ( strcmp(checkaddr,vinaddr) == 0 ) { - printf("signedtx.(%s)\n",signedtx); - sendtxid = LP_broadcast("claim","KMD",signedtx,signedtxid); - if ( bits256_cmp(sendtxid,signedtxid) == 0 ) + claimtime = (uint32_t)time(NULL)-777; + if ( claimtime <= expiration ) + { + printf("claimtime.%u vs locktime.%u, need to wait %d seconds\n",claimtime,expiration,(int32_t)expiration-claimtime); + } + else { - jaddibits256(txids,sendtxid); - sum += (satoshis-coin->txfee); + flagi = 1; + sum += LP_claimtx(ctx,coin,txids,utxotxid,utxovout,satoshis,vinaddr,claimtime,redeemscript,redeemlen); } - else printf("error sending %s\n",bits256_str(str,signedtxid)); - free(signedtx); - } else printf("error claiming instantdex deposit %s/v%d %.8f\n",bits256_str(str,utxotxid),utxovout,dstr(satoshis)); + } } } - free_json(array); - retjson = cJSON_CreateObject(); - jaddstr(retjson,"result","success"); - jaddnum(retjson,"claimed",dstr(sum)); - jadd(retjson,"txids",txids); - return(jprint(retjson,1)); } + if ( flagi == 0 ) + jaddibits256(newarray,utxotxid); + else flag++; } } - if ( expiration != 0 ) - break; + free_json(array); } - return(clonestr("{\"error\":\"no instantdex deposits to claim\"}")); + if ( cJSON_GetArraySize(newarray) > 0 ) + LP_instantdex_filewrite(0,newarray); + free_json(newarray); + retjson = cJSON_CreateObject(); + jaddstr(retjson,"result","success"); + jaddnum(retjson,"claimed",dstr(sum)); + jadd(retjson,"txids",txids); + return(jprint(retjson,1)); } int64_t LP_instantdex_credit(int32_t dispflag,char *coinaddr,int64_t satoshis,int32_t weeki,char *p2shaddr,bits256 txid) diff --git a/iguana/exchanges/LP_ordermatch.c b/iguana/exchanges/LP_ordermatch.c index a2019c925..15d8f959d 100644 --- a/iguana/exchanges/LP_ordermatch.c +++ b/iguana/exchanges/LP_ordermatch.c @@ -487,7 +487,7 @@ int32_t LP_connectstartbob(void *ctx,int32_t pubsock,char *base,char *rel,double reqjson = LP_quotejson(qp); jaddstr(reqjson,"method","connected"); jaddstr(reqjson,"pair",pairstr); - jadd(reqjson,"proof",LP_instantdex_txidaddjson()); + jadd(reqjson,"proof",LP_instantdex_txids()); char str[65]; printf("BOB pubsock.%d binds to %d (%s)\n",pubsock,pair,bits256_str(str,qp->desthash)); bits256 zero; memset(zero.bytes,0,sizeof(zero)); diff --git a/iguana/exchanges/LP_signatures.c b/iguana/exchanges/LP_signatures.c index c73986f46..4fce8ca7f 100644 --- a/iguana/exchanges/LP_signatures.c +++ b/iguana/exchanges/LP_signatures.c @@ -665,7 +665,7 @@ void LP_query(void *ctx,char *myipaddr,int32_t mypubsock,char *method,struct LP_ if ( jobj(reqjson,"timestamp") == 0 ) jaddnum(reqjson,"timestamp",time(NULL)); if ( strcmp(method,"connect") == 0 ) - jadd(reqjson,"proof",LP_instantdex_txidaddjson()); + jadd(reqjson,"proof",LP_instantdex_txids()); msg = jprint(reqjson,1); printf("QUERY.(%s)\n",msg); //if ( bits256_nonz(qp->srchash) == 0 || strcmp(method,"request") != 0 ) diff --git a/iguana/exchanges/LP_statemachine.c b/iguana/exchanges/LP_statemachine.c index 21b8eeaf7..34549ebf7 100644 --- a/iguana/exchanges/LP_statemachine.c +++ b/iguana/exchanges/LP_statemachine.c @@ -3540,6 +3540,65 @@ void LP_price_broadcastloop(void *ctx) sleep(LP_ORDERBOOK_DURATION * .9); } } +/*if ( expiration != 0 ) + { + redeemlen = LP_deposit_addr(vinaddr,redeemscript,coin->taddr,coin->p2shtype,expiration,G.LP_pubsecp); + if ( strcmp(depositaddr,vinaddr) == 0 ) + { + claimtime = (uint32_t)time(NULL)-777; + if ( claimtime <= expiration ) + { + printf("claimtime.%u vs locktime.%u, need to wait %d seconds\n",claimtime,timestamp,(int32_t)timestamp-claimtime); + return(clonestr("{\"error\":\"need to wait to claim\"}")); + } + sum += LP_claimtx(ctx,coin,txids,utxotxid,utxovout,satoshis,vinaddr,claimtime,redeemscript,redeemlen); + + }*/ +/*timestamp = (now / LP_WEEKMULT) * LP_WEEKMULT + LP_WEEKMULT; + while ( timestamp > LP_FIRSTWEEKTIME ) + { + if ( expiration != 0 ) + timestamp = expiration; + else timestamp -= LP_WEEKMULT; + redeemlen = LP_deposit_addr(vinaddr,redeemscript,coin->taddr,coin->p2shtype,timestamp,G.LP_pubsecp); + if ( strcmp(depositaddr,vinaddr) == 0 ) + { + claimtime = (uint32_t)time(NULL)-777; + if ( claimtime <= timestamp ) + { + printf("claimtime.%u vs locktime.%u, need to wait %d seconds\n",claimtime,timestamp,(int32_t)timestamp-claimtime); + } + else + { + printf("found %s at timestamp.%u\n",vinaddr,timestamp); + memset(zero.bytes,0,sizeof(zero)); + if ( (array= LP_listunspent(coin->symbol,vinaddr,zero,zero)) != 0 ) + { + //printf("unspents.(%s)\n",jprint(array,0)); + if ( (n= cJSON_GetArraySize(array)) > 0 ) + { + for (i=0; i Date: Fri, 1 Dec 2017 14:57:46 +0400 Subject: [PATCH 1403/1664] Test --- iguana/exchanges/LP_instantdex.c | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/iguana/exchanges/LP_instantdex.c b/iguana/exchanges/LP_instantdex.c index bd95eca1a..0ad904f9c 100644 --- a/iguana/exchanges/LP_instantdex.c +++ b/iguana/exchanges/LP_instantdex.c @@ -253,9 +253,10 @@ char *LP_instantdex_claim(struct iguana_info *coin,char *depositaddr,uint32_t ex flagi = 1; sum += LP_claimtx(ctx,coin,txids,utxotxid,utxovout,satoshis,vinaddr,claimtime,redeemscript,redeemlen); } - } - } - } + } else printf("checkaddr.(%s) != vinaddr.%s\n",checkaddr,vinaddr); + } else printf("vout2 dest.(%s) != %s\n",destaddr,coin->smartaddr); + } else printf("numvouts %d != 3\n",numvouts); + free_json(txjson); } if ( flagi == 0 ) jaddibits256(newarray,utxotxid); From 6fa21c32ef7edf08f728ee0fa0049eae9cb03ec2 Mon Sep 17 00:00:00 2001 From: jl777 Date: Fri, 1 Dec 2017 15:10:00 +0400 Subject: [PATCH 1404/1664] Test --- iguana/exchanges/LP_instantdex.c | 39 ++++++++++++++++++-------------- 1 file changed, 22 insertions(+), 17 deletions(-) diff --git a/iguana/exchanges/LP_instantdex.c b/iguana/exchanges/LP_instantdex.c index 0ad904f9c..72bba2e36 100644 --- a/iguana/exchanges/LP_instantdex.c +++ b/iguana/exchanges/LP_instantdex.c @@ -201,7 +201,7 @@ int64_t LP_claimtx(void *ctx,struct iguana_info *coin,cJSON *txids,bits256 utxot char *LP_instantdex_claim(struct iguana_info *coin,char *depositaddr,uint32_t expiration) { static void *ctx; - uint8_t redeemscript[512]; char vinaddr[64],checkaddr[64],destaddr[64]; uint32_t now,redeemlen,claimtime; int32_t i,n,flagi,flag,weeki,numvouts,utxovout; bits256 utxotxid; int64_t sum,satoshis,weeksatoshis; cJSON *array,*txids,*retjson,*newarray,*txjson,*vouts,*vout0,*vout1,*vout2; + uint8_t redeemscript[512]; char vinaddr[64],checkaddr[64],destaddr[64]; uint32_t now,redeemlen,claimtime; int32_t i,j,n,flagi,flag,weeki,numvouts,utxovout; bits256 utxotxid; int64_t sum,satoshis,weeksatoshis; cJSON *array,*txids,*retjson,*newarray,*txjson,*vouts,*vout0,*vout1,*vout2; if ( ctx == 0 ) ctx = bitcoin_ctx(); if ( strcmp(coin->symbol,"KMD") != 0 ) @@ -232,28 +232,33 @@ char *LP_instantdex_claim(struct iguana_info *coin,char *depositaddr,uint32_t ex vout0 = jitem(vouts,0); LP_destaddr(vinaddr,vout0); satoshis = LP_value_extract(vout0,1); - vout1 = jitem(vouts,1); - weeksatoshis = LP_value_extract(vout1,0); - weeki = (int32_t)(weeksatoshis % 10000); - expiration = (weeki * LP_WEEKMULT) + LP_FIRSTWEEKTIME; vout2 = jitem(vouts,2); LP_destaddr(destaddr,vout2); if ( strcmp(destaddr,coin->smartaddr) == 0 ) { - redeemlen = LP_deposit_addr(checkaddr,redeemscript,coin->taddr,coin->p2shtype,expiration,G.LP_pubsecp); - if ( strcmp(checkaddr,vinaddr) == 0 ) + vout1 = jitem(vouts,1); + weeksatoshis = LP_value_extract(vout1,0); + weeki = (int32_t)(weeksatoshis % 10000); + for (j=-1; j<=1; j++) { - claimtime = (uint32_t)time(NULL)-777; - if ( claimtime <= expiration ) + expiration = ((weeki+j) * LP_WEEKMULT) + LP_FIRSTWEEKTIME; + redeemlen = LP_deposit_addr(checkaddr,redeemscript,coin->taddr,coin->p2shtype,expiration,G.LP_pubsecp); + if ( strcmp(checkaddr,vinaddr) == 0 ) { - printf("claimtime.%u vs locktime.%u, need to wait %d seconds\n",claimtime,expiration,(int32_t)expiration-claimtime); - } - else - { - flagi = 1; - sum += LP_claimtx(ctx,coin,txids,utxotxid,utxovout,satoshis,vinaddr,claimtime,redeemscript,redeemlen); - } - } else printf("checkaddr.(%s) != vinaddr.%s\n",checkaddr,vinaddr); + claimtime = (uint32_t)time(NULL)-777; + if ( claimtime <= expiration ) + { + printf("claimtime.%u vs locktime.%u, need to wait %d seconds\n",claimtime,expiration,(int32_t)expiration-claimtime); + } + else + { + flagi = 1; + sum += LP_claimtx(ctx,coin,txids,utxotxid,utxovout,satoshis,vinaddr,claimtime,redeemscript,redeemlen); + } + } else printf("j.%d checkaddr.(%s) != vinaddr.%s\n",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); From e21bc6b20ce01b9c3e4033d313655d6c681c3081 Mon Sep 17 00:00:00 2001 From: jl777 Date: Fri, 1 Dec 2017 15:13:51 +0400 Subject: [PATCH 1405/1664] Test --- iguana/exchanges/LP_instantdex.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/iguana/exchanges/LP_instantdex.c b/iguana/exchanges/LP_instantdex.c index 72bba2e36..2fe8a811c 100644 --- a/iguana/exchanges/LP_instantdex.c +++ b/iguana/exchanges/LP_instantdex.c @@ -255,7 +255,7 @@ char *LP_instantdex_claim(struct iguana_info *coin,char *depositaddr,uint32_t ex flagi = 1; sum += LP_claimtx(ctx,coin,txids,utxotxid,utxovout,satoshis,vinaddr,claimtime,redeemscript,redeemlen); } - } else printf("j.%d checkaddr.(%s) != vinaddr.%s\n",j,checkaddr,vinaddr); + } else printf("expiration.%u j.%d checkaddr.(%s) != vinaddr.%s\n",expiration,j,checkaddr,vinaddr); if ( flagi != 0 ) break; } From 8feed30263b58e5ae43a2d159a6770fd26e58621 Mon Sep 17 00:00:00 2001 From: jl777 Date: Fri, 1 Dec 2017 15:18:14 +0400 Subject: [PATCH 1406/1664] Test --- iguana/exchanges/LP_instantdex.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/iguana/exchanges/LP_instantdex.c b/iguana/exchanges/LP_instantdex.c index 2fe8a811c..faef1cbda 100644 --- a/iguana/exchanges/LP_instantdex.c +++ b/iguana/exchanges/LP_instantdex.c @@ -239,9 +239,9 @@ char *LP_instantdex_claim(struct iguana_info *coin,char *depositaddr,uint32_t ex vout1 = jitem(vouts,1); weeksatoshis = LP_value_extract(vout1,0); weeki = (int32_t)(weeksatoshis % 10000); - for (j=-1; j<=1; j++) + for (j=0; j<168; j++) { - expiration = ((weeki+j) * LP_WEEKMULT) + LP_FIRSTWEEKTIME; + 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 ) { From 270d26a9de23817364aacfacb8bf3e451e347edb Mon Sep 17 00:00:00 2001 From: jl777 Date: Fri, 1 Dec 2017 15:20:28 +0400 Subject: [PATCH 1407/1664] Test --- iguana/exchanges/LP_instantdex.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/iguana/exchanges/LP_instantdex.c b/iguana/exchanges/LP_instantdex.c index faef1cbda..5a11e67bf 100644 --- a/iguana/exchanges/LP_instantdex.c +++ b/iguana/exchanges/LP_instantdex.c @@ -239,7 +239,7 @@ char *LP_instantdex_claim(struct iguana_info *coin,char *depositaddr,uint32_t ex vout1 = jitem(vouts,1); weeksatoshis = LP_value_extract(vout1,0); weeki = (int32_t)(weeksatoshis % 10000); - for (j=0; j<168; j++) + 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); @@ -249,6 +249,7 @@ char *LP_instantdex_claim(struct iguana_info *coin,char *depositaddr,uint32_t ex if ( claimtime <= expiration ) { printf("claimtime.%u vs locktime.%u, need to wait %d seconds\n",claimtime,expiration,(int32_t)expiration-claimtime); + break; } else { From 4d586d00ab957f9fbcaaf0a52a0f11a42c0b8f61 Mon Sep 17 00:00:00 2001 From: jl777 Date: Fri, 1 Dec 2017 15:25:52 +0400 Subject: [PATCH 1408/1664] Test --- iguana/exchanges/LP_instantdex.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/iguana/exchanges/LP_instantdex.c b/iguana/exchanges/LP_instantdex.c index 5a11e67bf..4985000e2 100644 --- a/iguana/exchanges/LP_instantdex.c +++ b/iguana/exchanges/LP_instantdex.c @@ -248,7 +248,7 @@ char *LP_instantdex_claim(struct iguana_info *coin,char *depositaddr,uint32_t ex claimtime = (uint32_t)time(NULL)-777; if ( claimtime <= expiration ) { - printf("claimtime.%u vs locktime.%u, need to wait %d seconds\n",claimtime,expiration,(int32_t)expiration-claimtime); + char str[65]; printf("claimtime.%u vs locktime.%u, need to wait %d seconds to %s claim %.8f\n",claimtime,expiration,(int32_t)expiration-claimtime,bits256_str(str,utxotxid),dstr(satoshis)); break; } else From 36654b007afd67aadbcd0a9c46788271c39503e8 Mon Sep 17 00:00:00 2001 From: jl777 Date: Fri, 1 Dec 2017 21:54:47 +0400 Subject: [PATCH 1409/1664] Test --- iguana/exchanges/LP_NXT.c | 4 ++-- iguana/exchanges/LP_instantdex.c | 8 +++++--- iguana/exchanges/LP_nativeDEX.c | 1 - 3 files changed, 7 insertions(+), 6 deletions(-) diff --git a/iguana/exchanges/LP_NXT.c b/iguana/exchanges/LP_NXT.c index 52c9d5351..db669f1e6 100644 --- a/iguana/exchanges/LP_NXT.c +++ b/iguana/exchanges/LP_NXT.c @@ -55,7 +55,7 @@ void LP_sendtoaddress_line(char *validaddress,char *assetname,uint64_t satoshis, strcpy(lowerstr,"supernet"); else strcpy(lowerstr,assetname); tolowercase(lowerstr); - sprintf(line,"fiat/%s sendtoaddress %s %.8f # txnum.%llu",lowerstr,validaddress,dstr(satoshis),(long long)txnum); + sprintf(line,"sleep 1; fiat/%s sendtoaddress %s %.8f # txnum.%llu",lowerstr,validaddress,dstr(satoshis),(long long)txnum); } printf("%s\n",line); } @@ -202,7 +202,7 @@ void NXTventure_liquidation() cJSON *LP_NXT_redeems() { char url[1024],*retstr,*recv,*method,*msgstr,assetname[128]; uint64_t totals[sizeof(assetids)/sizeof(*assetids)],mult,txnum,assetid,qty; int32_t i,ind,numtx=0,past_marker=0; cJSON *item,*attach,*decjson,*array,*msgjson,*encjson,*retjson=0; - uint64_t txnum_marker = calc_nxt64bits("0"); + uint64_t txnum_marker = calc_nxt64bits("5509605741355242617"); uint64_t txnum_marker2 = calc_nxt64bits("7256847492742571143"); char *passphrase = ""; char *account = "NXT-MRBN-8DFH-PFMK-A4DBM"; diff --git a/iguana/exchanges/LP_instantdex.c b/iguana/exchanges/LP_instantdex.c index 4985000e2..b7ad179c3 100644 --- a/iguana/exchanges/LP_instantdex.c +++ b/iguana/exchanges/LP_instantdex.c @@ -201,7 +201,7 @@ int64_t LP_claimtx(void *ctx,struct iguana_info *coin,cJSON *txids,bits256 utxot char *LP_instantdex_claim(struct iguana_info *coin,char *depositaddr,uint32_t expiration) { static void *ctx; - uint8_t redeemscript[512]; char vinaddr[64],checkaddr[64],destaddr[64]; uint32_t now,redeemlen,claimtime; int32_t i,j,n,flagi,flag,weeki,numvouts,utxovout; bits256 utxotxid; int64_t sum,satoshis,weeksatoshis; cJSON *array,*txids,*retjson,*newarray,*txjson,*vouts,*vout0,*vout1,*vout2; + uint8_t redeemscript[512]; char vinaddr[64],checkaddr[64],destaddr[64],str[65]; uint32_t now,redeemlen,claimtime; int32_t i,j,n,flagi,flag,weeki,numvouts,utxovout; bits256 utxotxid; int64_t sum,satoshis,weeksatoshis; cJSON *array,*txids,*retjson,*newarray,*txjson,*vouts,*vout0,*vout1,*vout2; if ( ctx == 0 ) ctx = bitcoin_ctx(); if ( strcmp(coin->symbol,"KMD") != 0 ) @@ -212,12 +212,14 @@ char *LP_instantdex_claim(struct iguana_info *coin,char *depositaddr,uint32_t ex newarray = cJSON_CreateArray(); if ( (array= LP_instantdex_txids()) != 0 ) { + printf("claiming from.(%s)\n",jprint(array,0)); if ( (n= cJSON_GetArraySize(array)) > 0 ) { flag = 0; for (i=0; ismartaddr); } else printf("numvouts %d != 3\n",numvouts); free_json(txjson); - } + } else printf("cant get transaction\n"); if ( flagi == 0 ) jaddibits256(newarray,utxotxid); else flag++; diff --git a/iguana/exchanges/LP_nativeDEX.c b/iguana/exchanges/LP_nativeDEX.c index 6bb71f2db..4a853cd6d 100644 --- a/iguana/exchanges/LP_nativeDEX.c +++ b/iguana/exchanges/LP_nativeDEX.c @@ -17,7 +17,6 @@ // LP_nativeDEX.c // marketmaker // -// prune expired/spent deposits from instantdex.json // verify claim works // big BTC swaps // https://github.com/bitcoin/bips/blob/master/bip-0143.mediawiki for signing BCH/BTG From 99102b35051ac0271214403b42c9c7d821fab50b Mon Sep 17 00:00:00 2001 From: jl777 Date: Fri, 1 Dec 2017 21:58:36 +0400 Subject: [PATCH 1410/1664] Test --- iguana/exchanges/LP_commands.c | 2 +- iguana/exchanges/LP_instantdex.c | 5 +++-- 2 files changed, 4 insertions(+), 3 deletions(-) diff --git a/iguana/exchanges/LP_commands.c b/iguana/exchanges/LP_commands.c index 776a50dbf..86dda7eb6 100644 --- a/iguana/exchanges/LP_commands.c +++ b/iguana/exchanges/LP_commands.c @@ -212,7 +212,7 @@ zeroconf_claim(address, expiration=0)\n\ { if ( (ptr= LP_coinsearch("KMD")) != 0 ) { - return(LP_instantdex_claim(ptr,jstr(argjson,"address"),juint(argjson,"expiration"))); + return(LP_instantdex_claim(ptr)); } return(clonestr("{\"error\":\"cant find KMD\"}")); } diff --git a/iguana/exchanges/LP_instantdex.c b/iguana/exchanges/LP_instantdex.c index b7ad179c3..30959ea22 100644 --- a/iguana/exchanges/LP_instantdex.c +++ b/iguana/exchanges/LP_instantdex.c @@ -198,10 +198,11 @@ int64_t LP_claimtx(void *ctx,struct iguana_info *coin,cJSON *txids,bits256 utxot return(sum); } -char *LP_instantdex_claim(struct iguana_info *coin,char *depositaddr,uint32_t expiration) +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; int32_t i,j,n,flagi,flag,weeki,numvouts,utxovout; bits256 utxotxid; int64_t sum,satoshis,weeksatoshis; cJSON *array,*txids,*retjson,*newarray,*txjson,*vouts,*vout0,*vout1,*vout2; + 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; int64_t sum,satoshis,weeksatoshis; cJSON *array,*txids,*retjson,*newarray,*txjson,*vouts,*vout0,*vout1,*vout2; + printf("inside instantdex claim\n"); if ( ctx == 0 ) ctx = bitcoin_ctx(); if ( strcmp(coin->symbol,"KMD") != 0 ) From 50d2b614588f416597e7468b47b16d33c67872d2 Mon Sep 17 00:00:00 2001 From: jl777 Date: Fri, 1 Dec 2017 22:03:25 +0400 Subject: [PATCH 1411/1664] Test --- iguana/exchanges/LP_instantdex.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/iguana/exchanges/LP_instantdex.c b/iguana/exchanges/LP_instantdex.c index 30959ea22..b2a039f15 100644 --- a/iguana/exchanges/LP_instantdex.c +++ b/iguana/exchanges/LP_instantdex.c @@ -33,7 +33,7 @@ cJSON *LP_instantdex_txids() { retjson = cJSON_Parse(filestr); free(filestr); - } + } else printf("couldnt open (%s)\n",fname); return(retjson); } From 297d6de052d34a113f4af6ce6c6113467a2e3116 Mon Sep 17 00:00:00 2001 From: jl777 Date: Fri, 1 Dec 2017 22:05:20 +0400 Subject: [PATCH 1412/1664] Test --- iguana/exchanges/LP_instantdex.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/iguana/exchanges/LP_instantdex.c b/iguana/exchanges/LP_instantdex.c index b2a039f15..6de6ac2d1 100644 --- a/iguana/exchanges/LP_instantdex.c +++ b/iguana/exchanges/LP_instantdex.c @@ -22,7 +22,7 @@ void LP_instantdex_txidaddfname(char *fname,char *afname) { sprintf(fname,"%s/instantdex.json",GLOBAL_DBDIR); - sprintf(fname,"%s/instantdex_append.json",GLOBAL_DBDIR); + sprintf(afname,"%s/instantdex_append.json",GLOBAL_DBDIR); } cJSON *LP_instantdex_txids() From ff8e7229839563e454a6fbb40525b649cd840062 Mon Sep 17 00:00:00 2001 From: jl777 Date: Fri, 1 Dec 2017 22:16:54 +0400 Subject: [PATCH 1413/1664] Test --- iguana/exchanges/LP_instantdex.c | 16 ++++++++++++---- 1 file changed, 12 insertions(+), 4 deletions(-) diff --git a/iguana/exchanges/LP_instantdex.c b/iguana/exchanges/LP_instantdex.c index 6de6ac2d1..e2605e0a6 100644 --- a/iguana/exchanges/LP_instantdex.c +++ b/iguana/exchanges/LP_instantdex.c @@ -176,12 +176,13 @@ char *LP_instantdex_deposit(struct iguana_info *coin,int32_t weeks,double amount return(clonestr("{\"error\":\"error with LP_withdraw for instantdex deposit\"}")); } -int64_t LP_claimtx(void *ctx,struct iguana_info *coin,cJSON *txids,bits256 utxotxid,int32_t utxovout,uint64_t satoshis,char *vinaddr,uint32_t claimtime,uint8_t *redeemscript,int32_t redeemlen) +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; userdatalen = 1; utxovout = 0; + memset(claimtxidp,0,sizeof(*claimtxidp)); char str[65]; printf("satoshis %.8f %s/v%d\n",dstr(satoshis),bits256_str(str,utxotxid),utxovout); if ( (signedtx= basilisk_swap_bobtxspend(&signedtxid,10000,"instantdexclaim",coin->symbol,coin->wiftaddr,coin->taddr,coin->pubtype,coin->p2shtype,coin->isPoS,coin->wiftype,ctx,G.LP_privkey,0,redeemscript,redeemlen,userdata,userdatalen,utxotxid,utxovout,coin->smartaddr,G.LP_pubsecp,0,claimtime,&destamount,0,0,vinaddr,1,coin->zcash)) != 0 ) { @@ -189,7 +190,7 @@ int64_t LP_claimtx(void *ctx,struct iguana_info *coin,cJSON *txids,bits256 utxot sendtxid = LP_broadcast("claim","KMD",signedtx,signedtxid); if ( bits256_cmp(sendtxid,signedtxid) == 0 ) { - jaddibits256(txids,sendtxid); + *claimtxidp = sendtxid; sum += (satoshis - coin->txfee); } else printf("error sending %s\n",bits256_str(str,signedtxid)); @@ -201,7 +202,7 @@ int64_t LP_claimtx(void *ctx,struct iguana_info *coin,cJSON *txids,bits256 utxot 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; int64_t sum,satoshis,weeksatoshis; cJSON *array,*txids,*retjson,*newarray,*txjson,*vouts,*vout0,*vout1,*vout2; + 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"); if ( ctx == 0 ) ctx = bitcoin_ctx(); @@ -249,16 +250,23 @@ char *LP_instantdex_claim(struct iguana_info *coin) 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))); + jaddnum(item,"interest",dstr(satoshis)-dstr(LP_value_extract(vout0,0))); if ( claimtime <= expiration ) { printf("claimtime.%u vs locktime.%u, need to 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); break; } else { flagi = 1; - sum += LP_claimtx(ctx,coin,txids,utxotxid,utxovout,satoshis,vinaddr,claimtime,redeemscript,redeemlen); + 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; From c9040bb7bf424d8c0be7e1655875a9f0c45630b7 Mon Sep 17 00:00:00 2001 From: jl777 Date: Fri, 1 Dec 2017 22:19:50 +0400 Subject: [PATCH 1414/1664] Test --- iguana/exchanges/LP_instantdex.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/iguana/exchanges/LP_instantdex.c b/iguana/exchanges/LP_instantdex.c index e2605e0a6..a432fa415 100644 --- a/iguana/exchanges/LP_instantdex.c +++ b/iguana/exchanges/LP_instantdex.c @@ -258,6 +258,7 @@ char *LP_instantdex_claim(struct iguana_info *coin) { printf("claimtime.%u vs locktime.%u, need to 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 @@ -265,8 +266,8 @@ char *LP_instantdex_claim(struct iguana_info *coin) flagi = 1; sum += LP_claimtx(ctx,coin,&claimtxid,utxotxid,utxovout,satoshis,vinaddr,claimtime,redeemscript,redeemlen); jaddbits256(item,"claimtxid",claimtxid); + jaddi(txids,item); } - jaddi(txids,item); } else printf("expiration.%u j.%d checkaddr.(%s) != vinaddr.%s\n",expiration,j,checkaddr,vinaddr); if ( flagi != 0 ) break; From f1ff74ca9c91067a099843a113683978dadbccce Mon Sep 17 00:00:00 2001 From: jl777 Date: Fri, 1 Dec 2017 22:21:16 +0400 Subject: [PATCH 1415/1664] Test --- iguana/exchanges/LP_instantdex.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/iguana/exchanges/LP_instantdex.c b/iguana/exchanges/LP_instantdex.c index a432fa415..2b35d5a0d 100644 --- a/iguana/exchanges/LP_instantdex.c +++ b/iguana/exchanges/LP_instantdex.c @@ -214,14 +214,14 @@ char *LP_instantdex_claim(struct iguana_info *coin) 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; i Date: Fri, 1 Dec 2017 22:38:32 +0400 Subject: [PATCH 1416/1664] test --- iguana/exchanges/LP_instantdex.c | 4 +++- iguana/exchanges/LP_nativeDEX.c | 2 +- 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/iguana/exchanges/LP_instantdex.c b/iguana/exchanges/LP_instantdex.c index 2b35d5a0d..20e79fb47 100644 --- a/iguana/exchanges/LP_instantdex.c +++ b/iguana/exchanges/LP_instantdex.c @@ -253,7 +253,9 @@ char *LP_instantdex_claim(struct iguana_info *coin) item = cJSON_CreateObject(); jaddbits256(item,"txid",utxotxid); jaddnum(item,"deposit",dstr(LP_value_extract(vout0,0))); - jaddnum(item,"interest",dstr(satoshis)-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)); diff --git a/iguana/exchanges/LP_nativeDEX.c b/iguana/exchanges/LP_nativeDEX.c index 4a853cd6d..e167a684e 100644 --- a/iguana/exchanges/LP_nativeDEX.c +++ b/iguana/exchanges/LP_nativeDEX.c @@ -17,7 +17,7 @@ // LP_nativeDEX.c // marketmaker // -// verify claim works +// verify claim works (display interest in electrum) // big BTC swaps // https://github.com/bitcoin/bips/blob/master/bip-0143.mediawiki for signing BCH/BTG // From b19e6a3e9ae36450d9ade3ffdd7ac40dea45d435 Mon Sep 17 00:00:00 2001 From: jl777 Date: Fri, 1 Dec 2017 22:47:50 +0400 Subject: [PATCH 1417/1664] Test --- iguana/exchanges/LP_include.h | 1 + iguana/exchanges/LP_instantdex.c | 17 ++++++++++++++++- iguana/exchanges/LP_utxo.c | 2 ++ 3 files changed, 19 insertions(+), 1 deletion(-) diff --git a/iguana/exchanges/LP_include.h b/iguana/exchanges/LP_include.h index 77c71ece4..bb7e77d73 100644 --- a/iguana/exchanges/LP_include.h +++ b/iguana/exchanges/LP_include.h @@ -500,6 +500,7 @@ struct LP_address *_LP_addressadd(struct iguana_info *coin,char *coinaddr); int32_t iguana_signrawtransaction(void *ctx,char *symbol,uint8_t wiftaddr,uint8_t taddr,uint8_t pubtype,uint8_t p2shtype,uint8_t isPoS,int32_t height,struct iguana_msgtx *msgtx,char **signedtxp,bits256 *signedtxidp,struct vin_info *V,int32_t numinputs,char *rawtx,cJSON *vins,cJSON *privkeysjson,int32_t zcash); //void LP_butxo_swapfields_set(struct LP_utxoinfo *butxo); struct LP_address_utxo *LP_address_utxofind(struct iguana_info *coin,char *coinaddr,bits256 txid,int32_t vout); +int64_t LP_myzcredits(); int32_t LP_destaddr(char *destaddr,cJSON *item); int32_t LP_waitmempool(char *symbol,char *coinaddr,bits256 txid,int32_t vout,int32_t duration); cJSON *LP_statslog_disp(uint32_t starttime,uint32_t endtime,char *refgui,bits256 refpubkey,char *refbase,char *refrel); diff --git a/iguana/exchanges/LP_instantdex.c b/iguana/exchanges/LP_instantdex.c index 20e79fb47..d2ee44382 100644 --- a/iguana/exchanges/LP_instantdex.c +++ b/iguana/exchanges/LP_instantdex.c @@ -424,5 +424,20 @@ int64_t LP_instantdex_proofcheck(char *coinaddr,cJSON *proof,int32_t num) 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); } - return(net); + return(ap->instantdex_credits); +} + +int64_t LP_myzcredits() +{ + cJSON *proof; struct iguana_info *coin; int64_t zcredits; + if ( (coin= LP_coinfind("KMD")) != 0 ) + { + if ( (proof= LP_instantdex_txids()) != 0 ) + { + zcredits = LP_instantdex_proofcheck(coin->smartaddr,proof,cJSON_GetArraySize(proof)); + free_json(proof); + return(zcredits); + } + } + return(0); } diff --git a/iguana/exchanges/LP_utxo.c b/iguana/exchanges/LP_utxo.c index f2ac7ab7f..c1611b654 100644 --- a/iguana/exchanges/LP_utxo.c +++ b/iguana/exchanges/LP_utxo.c @@ -619,6 +619,8 @@ cJSON *LP_address_balance(struct iguana_info *coin,char *coinaddr,int32_t electr jaddstr(retjson,"coin",coin->symbol); jaddstr(retjson,"address",coinaddr); jaddnum(retjson,"balance",dstr(balance)); + if ( strcmp(coin->symbol,"KMD") == 0 ) + jaddnum(retjson,"zcredits",dstr(LP_myzcredits())); return(retjson); } From bf1199d606702181a18c8b9fc46a96827f1d1020 Mon Sep 17 00:00:00 2001 From: jl777 Date: Fri, 1 Dec 2017 22:50:40 +0400 Subject: [PATCH 1418/1664] Test --- iguana/exchanges/LP_utxo.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/iguana/exchanges/LP_utxo.c b/iguana/exchanges/LP_utxo.c index c1611b654..9d48e6ba5 100644 --- a/iguana/exchanges/LP_utxo.c +++ b/iguana/exchanges/LP_utxo.c @@ -619,7 +619,7 @@ cJSON *LP_address_balance(struct iguana_info *coin,char *coinaddr,int32_t electr jaddstr(retjson,"coin",coin->symbol); jaddstr(retjson,"address",coinaddr); jaddnum(retjson,"balance",dstr(balance)); - if ( strcmp(coin->symbol,"KMD") == 0 ) + if ( strcmp(coin->symbol,"KMD") == 0 && strcmp(coin->smartaddr,coinaddr) == 0 ) jaddnum(retjson,"zcredits",dstr(LP_myzcredits())); return(retjson); } From cb7c4316e197321a2738b483e8af21ab6b94914c Mon Sep 17 00:00:00 2001 From: jl777 Date: Fri, 1 Dec 2017 22:59:08 +0400 Subject: [PATCH 1419/1664] Zeroconf -> instantdex --- iguana/exchanges/LP_commands.c | 12 ++++++------ iguana/exchanges/LP_nativeDEX.c | 2 +- iguana/exchanges/claim | 2 +- iguana/exchanges/deposit1 | 2 +- iguana/exchanges/{deposit => deposit10} | 2 +- iguana/exchanges/install | 2 +- 6 files changed, 11 insertions(+), 11 deletions(-) rename iguana/exchanges/{deposit => deposit10} (51%) diff --git a/iguana/exchanges/LP_commands.c b/iguana/exchanges/LP_commands.c index 86dda7eb6..b06a66e5d 100644 --- a/iguana/exchanges/LP_commands.c +++ b/iguana/exchanges/LP_commands.c @@ -154,8 +154,8 @@ bot_settings(botid, newprice, newvolume)\n\ bot_status(botid)\n\ bot_stop(botid)\n\ bot_pause(botid)\n\ -zeroconf_deposit(weeks, amount, broadcast=0)\n\ -zeroconf_claim(address, expiration=0)\n\ +instantdex_deposit(weeks, amount, broadcast=0)\n\ +instantdex_claim()\n\ \"}")); //sell(base, rel, price, basevolume, timeout=10, duration=3600)\n\ @@ -198,17 +198,17 @@ zeroconf_claim(address, expiration=0)\n\ return(jprint(retjson,1)); } } - else if ( strcmp(method,"zeroconf_deposit") == 0 ) + else if ( strcmp(method,"instantdex_deposit") == 0 ) { if ( (ptr= LP_coinsearch("KMD")) != 0 ) { - if ( jint(argjson,"weeks") < 0 || jdouble(argjson,"amount") < 10. ) - return(clonestr("{\"error\":\"deposit_create needs to have weeks and amount\"}")); + if ( jint(argjson,"weeks") <= 0 || jdouble(argjson,"amount") < 10. ) + return(clonestr("{\"error\":\"instantdex_deposit needs to have weeks and amount\"}")); else return(LP_instantdex_deposit(ptr,juint(argjson,"weeks"),jdouble(argjson,"amount"),jint(argjson,"broadcast"))); } return(clonestr("{\"error\":\"cant find KMD\"}")); } - else if ( strcmp(method,"zeroconf_claim") == 0 ) + else if ( strcmp(method,"instantdex_claim") == 0 ) { if ( (ptr= LP_coinsearch("KMD")) != 0 ) { diff --git a/iguana/exchanges/LP_nativeDEX.c b/iguana/exchanges/LP_nativeDEX.c index e167a684e..4a853cd6d 100644 --- a/iguana/exchanges/LP_nativeDEX.c +++ b/iguana/exchanges/LP_nativeDEX.c @@ -17,7 +17,7 @@ // LP_nativeDEX.c // marketmaker // -// verify claim works (display interest in electrum) +// verify claim works // big BTC swaps // https://github.com/bitcoin/bips/blob/master/bip-0143.mediawiki for signing BCH/BTG // diff --git a/iguana/exchanges/claim b/iguana/exchanges/claim index 7c9d212bf..85cd18c15 100755 --- a/iguana/exchanges/claim +++ b/iguana/exchanges/claim @@ -1,3 +1,3 @@ #!/bin/bash source userpass -curl --url "http://127.0.0.1:7783" --data "{\"userpass\":\"$userpass\",\"method\":\"zeroconf_claim\"}" +curl --url "http://127.0.0.1:7783" --data "{\"userpass\":\"$userpass\",\"method\":\"instantdex_claim\"}" diff --git a/iguana/exchanges/deposit1 b/iguana/exchanges/deposit1 index c82178e79..9b2e411b7 100755 --- a/iguana/exchanges/deposit1 +++ b/iguana/exchanges/deposit1 @@ -1,3 +1,3 @@ #!/bin/bash source userpass -curl --url "http://127.0.0.1:7783" --data "{\"userpass\":\"$userpass\",\"method\":\"zeroconf_deposit\",\"weeks\":1,\"amount\":10.0,\"broadcast\":1}" +curl --url "http://127.0.0.1:7783" --data "{\"userpass\":\"$userpass\",\"method\":\"instantdex_deposit\",\"weeks\":1,\"amount\":10.0,\"broadcast\":1}" diff --git a/iguana/exchanges/deposit b/iguana/exchanges/deposit10 similarity index 51% rename from iguana/exchanges/deposit rename to iguana/exchanges/deposit10 index 1fe7c6138..f0ba9bcf7 100755 --- a/iguana/exchanges/deposit +++ b/iguana/exchanges/deposit10 @@ -1,3 +1,3 @@ #!/bin/bash source userpass -curl --url "http://127.0.0.1:7783" --data "{\"userpass\":\"$userpass\",\"method\":\"zeroconf_deposit\",\"weeks\":0,\"amount\":10.0,\"broadcast\":1}" +curl --url "http://127.0.0.1:7783" --data "{\"userpass\":\"$userpass\",\"method\":\"instantdex_deposit\",\"weeks\":10,\"amount\":10.0,\"broadcast\":1}" diff --git a/iguana/exchanges/install b/iguana/exchanges/install index 7bbc5535d..b4feab5c9 100755 --- a/iguana/exchanges/install +++ b/iguana/exchanges/install @@ -1,5 +1,5 @@ #!/bin/bash -cp dynamictrust getcoin kickstart tradesarray claim deposit deposit1 invreset sendrawtransaction processfiles stop millis mnzservers bot_buy bot_list bot_statuslist bot_pause bot_resume bot_sell bot_settings bot_status bot_stop guistats pubkeystats pendings coinswaps baserelswaps setpassphrase notarizations getrawtransaction parselog statsdisp m_js 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 dynamictrust getcoin kickstart tradesarray claim deposit10 deposit1 invreset sendrawtransaction processfiles stop millis mnzservers bot_buy bot_list bot_statuslist bot_pause bot_resume bot_sell bot_settings bot_status bot_stop guistats pubkeystats pendings coinswaps baserelswaps setpassphrase notarizations getrawtransaction parselog statsdisp m_js 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 . From 5b9a9be5d01961619dc276791b8f125a82ab5a7d Mon Sep 17 00:00:00 2001 From: jl777 Date: Fri, 1 Dec 2017 23:15:24 +0400 Subject: [PATCH 1420/1664] Test --- iguana/exchanges/LP_rpc.c | 68 +++------------------------------------ 1 file changed, 4 insertions(+), 64 deletions(-) diff --git a/iguana/exchanges/LP_rpc.c b/iguana/exchanges/LP_rpc.c index 9906d0142..b39cdc9fa 100644 --- a/iguana/exchanges/LP_rpc.c +++ b/iguana/exchanges/LP_rpc.c @@ -1,4 +1,3 @@ - /****************************************************************************** * Copyright © 2014-2017 The SuperNET Developers. * * * @@ -18,30 +17,6 @@ // marketmaker // -/*char *LP_issue_curl(char *debugstr,char *destip,uint16_t port,char *url) -{ - char *retstr = 0; int32_t maxerrs; struct LP_peerinfo *peer = 0; - peer = LP_peerfind((uint32_t)calc_ipbits(destip),port); - if ( strcmp(destip,"127.0.0.1") != 0 ) - port--; - maxerrs = LP_MAXPEER_ERRORS; - if ( peer == 0 || (peer->errors < maxerrs || peer->good >= LP_MINPEER_GOOD) ) - { - printf("issue.(%s)\n",url); - if ( (retstr= issue_curlt(url,LP_HTTP_TIMEOUT)) == 0 ) - { - if ( peer != 0 ) - { - peer->errors++; - peer->good *= LP_PEERGOOD_ERRORDECAY; - } else printf("%s error on (%s:%u) without peer\n",debugstr,destip,port); - } - else if ( peer != 0 ) - peer->good++; - } - return(retstr); -}*/ - char *LP_isitme(char *destip,uint16_t destport) { if ( LP_mypeer != 0 && strcmp(destip,LP_mypeer->ipaddr) == 0 && LP_mypeer->port == destport ) @@ -99,13 +74,6 @@ cJSON *bitcoin_json(struct iguana_info *coin,char *method,char *params) free_json(retjson); retjson = 0; } - //printf("electrum %s.%s -> (%s)\n",method,params,jprint(retjson,0)); - /*if ( (resultjson= jobj(retjson,"result")) != 0 ) - { - resultjson = jduplicate(resultjson); - free_json(retjson); - retjson = resultjson; - }*/ } } } else retjson = cJSON_Parse("{\"result\":\"disabled\"}"); @@ -225,23 +193,6 @@ uint32_t LP_locktime(char *symbol,bits256 txid) return(locktime); } -/*uint32_t LP_txtime(char *symbol,bits256 txid) -{ - struct LP_transaction *tx; struct iguana_info *coin; int32_t timestamp=0,height = 0; - char str[65]; printf("LP_txtime (%s %s)\n",symbol,bits256_str(str,txid)); - if ( (timestamp= LP_locktime(symbol,txid)) != 0 ) - return(timestamp); - if ( (coin= LP_coinfind(symbol)) != 0 ) - { - if ( (tx= LP_transactionfind(coin,txid)) != 0 ) - { - height = tx->height; - timestamp = LP_heighttime(symbol,height); - } - } - return(height); -}*/ - cJSON *LP_gettxout_json(bits256 txid,int32_t vout,int32_t height,char *coinaddr,uint64_t value) { cJSON *retjson,*addresses,*sobj; @@ -328,17 +279,6 @@ cJSON *LP_gettxout(char *symbol,char *coinaddr,bits256 txid,int32_t vout) } } -/*cJSON *LP_listtransactions(char *symbol,char *coinaddr,int32_t count,int32_t skip) -{ - char buf[128]; struct iguana_info *coin = LP_coinfind(symbol); - if ( coin == 0 ) - return(cJSON_Parse("{\"error\":\"no coin\"}")); - if ( count == 0 ) - count = 100; - sprintf(buf,"[\"%s\", %d, %d, true]",coinaddr,count,skip); - return(bitcoin_json(coin,"listtransactions",buf)); -}*/ - cJSON *LP_validateaddress(char *symbol,char *address) { char buf[512],coinaddr[64],checkaddr[64],script[128]; int32_t i; uint8_t rmd160[20],addrtype; cJSON *retjson; struct iguana_info *coin; @@ -604,10 +544,10 @@ int32_t LP_importaddress(char *symbol,char *address) if ( coin->electrum != 0 ) { /*if ( (retjson= electrum_address_subscribe(symbol,coin->electrum,&retjson,address)) != 0 ) - { - printf("importaddress.(%s) -> %s\n",address,jprint(retjson,0)); - free_json(retjson); - }*/ + { + printf("importaddress.(%s) -> %s\n",address,jprint(retjson,0)); + free_json(retjson); + }*/ return(0); } else From eef14379d1ea7f061a7a606a1517e90b10938608 Mon Sep 17 00:00:00 2001 From: jl777 Date: Fri, 1 Dec 2017 23:20:41 +0400 Subject: [PATCH 1421/1664] Test --- iguana/exchanges/LP_NXT.c | 23 +++++++++++++---------- 1 file changed, 13 insertions(+), 10 deletions(-) diff --git a/iguana/exchanges/LP_NXT.c b/iguana/exchanges/LP_NXT.c index db669f1e6..0b947ccbe 100644 --- a/iguana/exchanges/LP_NXT.c +++ b/iguana/exchanges/LP_NXT.c @@ -201,7 +201,7 @@ void NXTventure_liquidation() cJSON *LP_NXT_redeems() { - char url[1024],*retstr,*recv,*method,*msgstr,assetname[128]; uint64_t totals[sizeof(assetids)/sizeof(*assetids)],mult,txnum,assetid,qty; int32_t i,ind,numtx=0,past_marker=0; cJSON *item,*attach,*decjson,*array,*msgjson,*encjson,*retjson=0; + char url[1024],*retstr,*recv,*method,*msgstr,assetname[128]; uint64_t totals[2][sizeof(assetids)/sizeof(*assetids)],mult,txnum,assetid,qty; int32_t i,ind,numtx=0,past_marker=0; cJSON *item,*attach,*decjson,*array,*msgjson,*encjson,*retjson=0; uint64_t txnum_marker = calc_nxt64bits("5509605741355242617"); uint64_t txnum_marker2 = calc_nxt64bits("7256847492742571143"); char *passphrase = ""; @@ -260,7 +260,7 @@ cJSON *LP_NXT_redeems() } mult = LP_assetid_mult(&ind,assetname,assetid); if ( ind >= 0 ) - totals[ind] += qty * mult; + totals[past_marker][ind] += qty * mult; if ( msgstr != 0 && assetname[0] != 0 && qty != 0 ) { char validaddress[64]; int32_t z,n; @@ -275,14 +275,14 @@ cJSON *LP_NXT_redeems() strncpy(validaddress,&msgstr[z],34); if ( txnum == calc_nxt64bits("4545341872872347590") ) strcpy(validaddress,"RKuwq4oi4mqQ2V4r54mPEthn3TBrEwu2Ni"); - if ( strlen(validaddress) == 34 || strlen(validaddress) == 33 ) + if ( past_marker == 0 ) { - //printf("%-4d: (%34s) <- %13.5f %10s tx.%llu past_marker.%d\n",i,validaddress,dstr(qty * mult),assetname,(long long)txnum,past_marker); - if ( past_marker == 0 ) + if ( strlen(validaddress) == 34 || strlen(validaddress) == 33 ) { + //printf("%-4d: (%34s) <- %13.5f %10s tx.%llu past_marker.%d\n",i,validaddress,dstr(qty * mult),assetname,(long long)txnum,past_marker); LP_sendtoaddress_line(validaddress,assetname,(qty * mult),txnum); - } - } else printf("%-4d: (%34s) <- %13.5f %10s tx.%llu\n",i,msgstr!=0?msgstr:jprint(item,0),dstr(qty * mult),assetname,(long long)txnum); + } else printf("%-4d: (%34s) <- %13.5f %10s tx.%llu\n",i,msgstr!=0?msgstr:jprint(item,0),dstr(qty * mult),assetname,(long long)txnum); + } } if ( msgjson != 0 ) free_json(msgjson); @@ -298,10 +298,13 @@ cJSON *LP_NXT_redeems() free(retstr); } printf("\nTotal redeemed.%d\n",numtx); - for (i=0; i Date: Fri, 1 Dec 2017 23:22:26 +0400 Subject: [PATCH 1422/1664] Test --- iguana/exchanges/LP_NXT.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/iguana/exchanges/LP_NXT.c b/iguana/exchanges/LP_NXT.c index 0b947ccbe..581096ecd 100644 --- a/iguana/exchanges/LP_NXT.c +++ b/iguana/exchanges/LP_NXT.c @@ -300,7 +300,7 @@ cJSON *LP_NXT_redeems() printf("\nTotal redeemed.%d\n",numtx); for (past_marker=0; past_marker<2; past_marker++) { - for (i=0; i Date: Fri, 1 Dec 2017 23:31:34 +0400 Subject: [PATCH 1423/1664] Flip shark and shark --- iguana/coins/genshark | 2 +- iguana/coins/mshark_7776 | 2 +- iguana/coins/shark_7776 | 2 +- iguana/exchanges/LP_NXT.c | 1 + 4 files changed, 4 insertions(+), 3 deletions(-) diff --git a/iguana/coins/genshark b/iguana/coins/genshark index f1f98346c..941fc20ed 100755 --- a/iguana/coins/genshark +++ b/iguana/coins/genshark @@ -1,2 +1,2 @@ -curl --url "http://127.0.0.1:7778" --data "{\"conf\":\"SHARK.conf\",\"path\":\"${HOME#"/"}/.komodo/SHARK\",\"unitval\":\"20\",\"zcash\":1,\"RELAY\":1,\"VALIDATE\":1,\"prefetchlag\":-1,\"poll\":100,\"active\":1,\"agent\":\"iguana\",\"method\":\"addcoin\",\"startpend\":4,\"endpend\":4,\"services\":129,\"maxpeers\":8,\"newcoin\":\"SHARK\",\"name\":\"SHARK\",\"hasheaders\":1,\"useaddmultisig\":0,\"netmagic\":\"54a5e30c\",\"p2p\":10113,\"rpc\":10114,\"pubval\":60,\"p2shval\":85,\"wifval\":188,\"txfee_satoshis\":\"10000\",\"isPoS\":0,\"minoutput\":10000,\"minconfirms\":2,\"genesishash\":\"027e3758c3a65b12aa1046462b486d0a63bfa1beae327897f56c5cfb7daaae71\",\"protover\":170002,\"genesisblock\":\"0100000000000000000000000000000000000000000000000000000000000000000000003ba3edfd7a7b12b27ac72c3e67768f617fc81bc3888a51323a9fb8aa4b1e5e4a000000000000000000000000000000000000000000000000000000000000000029ab5f490f0f0f200b00000000000000000000000000000000000000000000000000000000000000fd4005000d5ba7cda5d473947263bf194285317179d2b0d307119c2e7cc4bd8ac456f0774bd52b0cd9249be9d40718b6397a4c7bbd8f2b3272fed2823cd2af4bd1632200ba4bf796727d6347b225f670f292343274cc35099466f5fb5f0cd1c105121b28213d15db2ed7bdba490b4cedc69742a57b7c25af24485e523aadbb77a0144fc76f79ef73bd8530d42b9f3b9bed1c135ad1fe152923fafe98f95f76f1615e64c4abb1137f4c31b218ba2782bc15534788dda2cc08a0ee2987c8b27ff41bd4e31cd5fb5643dfe862c9a02ca9f90c8c51a6671d681d04ad47e4b53b1518d4befafefe8cadfb912f3d03051b1efbf1dfe37b56e93a741d8dfd80d576ca250bee55fab1311fc7b3255977558cdda6f7d6f875306e43a14413facdaed2f46093e0ef1e8f8a963e1632dcbeebd8e49fd16b57d49b08f9762de89157c65233f60c8e38a1f503a48c555f8ec45dedecd574a37601323c27be597b956343107f8bd80f3a925afaf30811df83c402116bb9c1e5231c70fff899a7c82f73c902ba54da53cc459b7bf1113db65cc8f6914d3618560ea69abd13658fa7b6af92d374d6eca9529f8bd565166e4fcbf2a8dfb3c9b69539d4d2ee2e9321b85b331925df195915f2757637c2805e1d4131e1ad9ef9bc1bb1c732d8dba4738716d351ab30c996c8657bab39567ee3b29c6d054b711495c0d52e1cd5d8e55b4f0f0325b97369280755b46a02afd54be4ddd9f77c22272b8bbb17ff5118fedbae2564524e797bd28b5f74f7079d532ccc059807989f94d267f47e724b3f1ecfe00ec9e6541c961080d8891251b84b4480bc292f6a180bea089fef5bbda56e1e41390d7c0e85ba0ef530f7177413481a226465a36ef6afe1e2bca69d2078712b3912bba1a99b1fbff0d355d6ffe726d2bb6fbc103c4ac5756e5bee6e47e17424ebcbf1b63d8cb90ce2e40198b4f4198689daea254307e52a25562f4c1455340f0ffeb10f9d8e914775e37d0edca019fb1b9c6ef81255ed86bc51c5391e0591480f66e2d88c5f4fd7277697968656a9b113ab97f874fdd5f2465e5559533e01ba13ef4a8f7a21d02c30c8ded68e8c54603ab9c8084ef6d9eb4e92c75b078539e2ae786ebab6dab73a09e0aa9ac575bcefb29e930ae656e58bcb513f7e3c17e079dce4f05b5dbc18c2a872b22509740ebe6a3903e00ad1abc55076441862643f93606e3dc35e8d9f2caef3ee6be14d513b2e062b21d0061de3bd56881713a1a5c17f5ace05e1ec09da53f99442df175a49bd154aa96e4949decd52fed79ccf7ccbce32941419c314e374e4a396ac553e17b5340336a1a25c22f9e42a243ba5404450b650acfc826a6e432971ace776e15719515e1634ceb9a4a35061b668c74998d3dfb5827f6238ec015377e6f9c94f38108768cf6e5c8b132e0303fb5a200368f845ad9d46343035a6ff94031df8d8309415bb3f6cd5ede9c135fdabcc030599858d803c0f85be7661c88984d88faa3d26fb0e9aac0056a53f1b5d0baed713c853c4a2726869a0a124a8a5bbc0fc0ef80c8ae4cb53636aa02503b86a1eb9836fcc259823e2692d921d88e1ffc1e6cb2bde43939ceb3f32a611686f539f8f7c9f0bf00381f743607d40960f06d347d1cd8ac8a51969c25e37150efdf7aa4c2037a2fd0516fb444525ab157a0ed0a7412b2fa69b217fe397263153782c0f64351fbdf2678fa0dc8569912dcd8e3ccad38f34f23bbbce14c6a26ac24911b308b82c7e43062d180baeac4ba7153858365c72c63dcf5f6a5b08070b730adb017aeae925b7d0439979e2679f45ed2f25a7edcfd2fb77a8794630285ccb0a071f5cce410b46dbf9750b0354aae8b65574501cc69efb5b6a43444074fee116641bb29da56c2b4a7f456991fc92b2\",\"debug\":0,\"seedipaddr\":\"78.47.196.146\"}" +curl --url "http://127.0.0.1:7778" --data "{\"conf\":\"SHARK.conf\",\"path\":\"${HOME#"/"}/.komodo/SHARK\",\"unitval\":\"20\",\"zcash\":1,\"RELAY\":1,\"VALIDATE\":1,\"prefetchlag\":-1,\"poll\":100,\"active\":1,\"agent\":\"iguana\",\"method\":\"addcoin\",\"startpend\":4,\"endpend\":4,\"services\":129,\"maxpeers\":8,\"newcoin\":\"SHARK\",\"name\":\"SHARK\",\"hasheaders\":1,\"useaddmultisig\":0,\"netmagic\":\"54a5e30c\",\"p2p\":14103,\"rpc\":14104,\"pubval\":60,\"p2shval\":85,\"wifval\":188,\"txfee_satoshis\":\"10000\",\"isPoS\":0,\"minoutput\":10000,\"minconfirms\":2,\"genesishash\":\"027e3758c3a65b12aa1046462b486d0a63bfa1beae327897f56c5cfb7daaae71\",\"protover\":170002,\"genesisblock\":\"0100000000000000000000000000000000000000000000000000000000000000000000003ba3edfd7a7b12b27ac72c3e67768f617fc81bc3888a51323a9fb8aa4b1e5e4a000000000000000000000000000000000000000000000000000000000000000029ab5f490f0f0f200b00000000000000000000000000000000000000000000000000000000000000fd4005000d5ba7cda5d473947263bf194285317179d2b0d307119c2e7cc4bd8ac456f0774bd52b0cd9249be9d40718b6397a4c7bbd8f2b3272fed2823cd2af4bd1632200ba4bf796727d6347b225f670f292343274cc35099466f5fb5f0cd1c105121b28213d15db2ed7bdba490b4cedc69742a57b7c25af24485e523aadbb77a0144fc76f79ef73bd8530d42b9f3b9bed1c135ad1fe152923fafe98f95f76f1615e64c4abb1137f4c31b218ba2782bc15534788dda2cc08a0ee2987c8b27ff41bd4e31cd5fb5643dfe862c9a02ca9f90c8c51a6671d681d04ad47e4b53b1518d4befafefe8cadfb912f3d03051b1efbf1dfe37b56e93a741d8dfd80d576ca250bee55fab1311fc7b3255977558cdda6f7d6f875306e43a14413facdaed2f46093e0ef1e8f8a963e1632dcbeebd8e49fd16b57d49b08f9762de89157c65233f60c8e38a1f503a48c555f8ec45dedecd574a37601323c27be597b956343107f8bd80f3a925afaf30811df83c402116bb9c1e5231c70fff899a7c82f73c902ba54da53cc459b7bf1113db65cc8f6914d3618560ea69abd13658fa7b6af92d374d6eca9529f8bd565166e4fcbf2a8dfb3c9b69539d4d2ee2e9321b85b331925df195915f2757637c2805e1d4131e1ad9ef9bc1bb1c732d8dba4738716d351ab30c996c8657bab39567ee3b29c6d054b711495c0d52e1cd5d8e55b4f0f0325b97369280755b46a02afd54be4ddd9f77c22272b8bbb17ff5118fedbae2564524e797bd28b5f74f7079d532ccc059807989f94d267f47e724b3f1ecfe00ec9e6541c961080d8891251b84b4480bc292f6a180bea089fef5bbda56e1e41390d7c0e85ba0ef530f7177413481a226465a36ef6afe1e2bca69d2078712b3912bba1a99b1fbff0d355d6ffe726d2bb6fbc103c4ac5756e5bee6e47e17424ebcbf1b63d8cb90ce2e40198b4f4198689daea254307e52a25562f4c1455340f0ffeb10f9d8e914775e37d0edca019fb1b9c6ef81255ed86bc51c5391e0591480f66e2d88c5f4fd7277697968656a9b113ab97f874fdd5f2465e5559533e01ba13ef4a8f7a21d02c30c8ded68e8c54603ab9c8084ef6d9eb4e92c75b078539e2ae786ebab6dab73a09e0aa9ac575bcefb29e930ae656e58bcb513f7e3c17e079dce4f05b5dbc18c2a872b22509740ebe6a3903e00ad1abc55076441862643f93606e3dc35e8d9f2caef3ee6be14d513b2e062b21d0061de3bd56881713a1a5c17f5ace05e1ec09da53f99442df175a49bd154aa96e4949decd52fed79ccf7ccbce32941419c314e374e4a396ac553e17b5340336a1a25c22f9e42a243ba5404450b650acfc826a6e432971ace776e15719515e1634ceb9a4a35061b668c74998d3dfb5827f6238ec015377e6f9c94f38108768cf6e5c8b132e0303fb5a200368f845ad9d46343035a6ff94031df8d8309415bb3f6cd5ede9c135fdabcc030599858d803c0f85be7661c88984d88faa3d26fb0e9aac0056a53f1b5d0baed713c853c4a2726869a0a124a8a5bbc0fc0ef80c8ae4cb53636aa02503b86a1eb9836fcc259823e2692d921d88e1ffc1e6cb2bde43939ceb3f32a611686f539f8f7c9f0bf00381f743607d40960f06d347d1cd8ac8a51969c25e37150efdf7aa4c2037a2fd0516fb444525ab157a0ed0a7412b2fa69b217fe397263153782c0f64351fbdf2678fa0dc8569912dcd8e3ccad38f34f23bbbce14c6a26ac24911b308b82c7e43062d180baeac4ba7153858365c72c63dcf5f6a5b08070b730adb017aeae925b7d0439979e2679f45ed2f25a7edcfd2fb77a8794630285ccb0a071f5cce410b46dbf9750b0354aae8b65574501cc69efb5b6a43444074fee116641bb29da56c2b4a7f456991fc92b2\",\"debug\":0,\"seedipaddr\":\"78.47.196.146\"}" diff --git a/iguana/coins/mshark_7776 b/iguana/coins/mshark_7776 index d1a7bc525..9279d8085 100644 --- a/iguana/coins/mshark_7776 +++ b/iguana/coins/mshark_7776 @@ -1,2 +1,2 @@ -curl --url "http://127.0.0.1:7776" --data "{\"conf\":\"SHARK.conf\",\"path\":\"${HOME#"/"}/.komodo/SHARK\",\"unitval\":\"20\",\"zcash\":1,\"RELAY\":-1,\"VALIDATE\":0,\"prefetchlag\":-1,\"poll\":100,\"active\":1,\"agent\":\"iguana\",\"method\":\"addcoin\",\"startpend\":4,\"endpend\":4,\"services\":129,\"maxpeers\":8,\"newcoin\":\"SHARK\",\"name\":\"SHARK\",\"hasheaders\":1,\"useaddmultisig\":0,\"netmagic\":\"54a5e30c\",\"p2p\":14103,\"rpc\":14104,\"pubval\":60,\"p2shval\":85,\"wifval\":188,\"txfee_satoshis\":\"10000\",\"isPoS\":0,\"minoutput\":10000,\"minconfirms\":2,\"genesishash\":\"027e3758c3a65b12aa1046462b486d0a63bfa1beae327897f56c5cfb7daaae71\",\"protover\":170002,\"genesisblock\":\"0100000000000000000000000000000000000000000000000000000000000000000000003ba3edfd7a7b12b27ac72c3e67768f617fc81bc3888a51323a9fb8aa4b1e5e4a000000000000000000000000000000000000000000000000000000000000000029ab5f490f0f0f200b00000000000000000000000000000000000000000000000000000000000000fd4005000d5ba7cda5d473947263bf194285317179d2b0d307119c2e7cc4bd8ac456f0774bd52b0cd9249be9d40718b6397a4c7bbd8f2b3272fed2823cd2af4bd1632200ba4bf796727d6347b225f670f292343274cc35099466f5fb5f0cd1c105121b28213d15db2ed7bdba490b4cedc69742a57b7c25af24485e523aadbb77a0144fc76f79ef73bd8530d42b9f3b9bed1c135ad1fe152923fafe98f95f76f1615e64c4abb1137f4c31b218ba2782bc15534788dda2cc08a0ee2987c8b27ff41bd4e31cd5fb5643dfe862c9a02ca9f90c8c51a6671d681d04ad47e4b53b1518d4befafefe8cadfb912f3d03051b1efbf1dfe37b56e93a741d8dfd80d576ca250bee55fab1311fc7b3255977558cdda6f7d6f875306e43a14413facdaed2f46093e0ef1e8f8a963e1632dcbeebd8e49fd16b57d49b08f9762de89157c65233f60c8e38a1f503a48c555f8ec45dedecd574a37601323c27be597b956343107f8bd80f3a925afaf30811df83c402116bb9c1e5231c70fff899a7c82f73c902ba54da53cc459b7bf1113db65cc8f6914d3618560ea69abd13658fa7b6af92d374d6eca9529f8bd565166e4fcbf2a8dfb3c9b69539d4d2ee2e9321b85b331925df195915f2757637c2805e1d4131e1ad9ef9bc1bb1c732d8dba4738716d351ab30c996c8657bab39567ee3b29c6d054b711495c0d52e1cd5d8e55b4f0f0325b97369280755b46a02afd54be4ddd9f77c22272b8bbb17ff5118fedbae2564524e797bd28b5f74f7079d532ccc059807989f94d267f47e724b3f1ecfe00ec9e6541c961080d8891251b84b4480bc292f6a180bea089fef5bbda56e1e41390d7c0e85ba0ef530f7177413481a226465a36ef6afe1e2bca69d2078712b3912bba1a99b1fbff0d355d6ffe726d2bb6fbc103c4ac5756e5bee6e47e17424ebcbf1b63d8cb90ce2e40198b4f4198689daea254307e52a25562f4c1455340f0ffeb10f9d8e914775e37d0edca019fb1b9c6ef81255ed86bc51c5391e0591480f66e2d88c5f4fd7277697968656a9b113ab97f874fdd5f2465e5559533e01ba13ef4a8f7a21d02c30c8ded68e8c54603ab9c8084ef6d9eb4e92c75b078539e2ae786ebab6dab73a09e0aa9ac575bcefb29e930ae656e58bcb513f7e3c17e079dce4f05b5dbc18c2a872b22509740ebe6a3903e00ad1abc55076441862643f93606e3dc35e8d9f2caef3ee6be14d513b2e062b21d0061de3bd56881713a1a5c17f5ace05e1ec09da53f99442df175a49bd154aa96e4949decd52fed79ccf7ccbce32941419c314e374e4a396ac553e17b5340336a1a25c22f9e42a243ba5404450b650acfc826a6e432971ace776e15719515e1634ceb9a4a35061b668c74998d3dfb5827f6238ec015377e6f9c94f38108768cf6e5c8b132e0303fb5a200368f845ad9d46343035a6ff94031df8d8309415bb3f6cd5ede9c135fdabcc030599858d803c0f85be7661c88984d88faa3d26fb0e9aac0056a53f1b5d0baed713c853c4a2726869a0a124a8a5bbc0fc0ef80c8ae4cb53636aa02503b86a1eb9836fcc259823e2692d921d88e1ffc1e6cb2bde43939ceb3f32a611686f539f8f7c9f0bf00381f743607d40960f06d347d1cd8ac8a51969c25e37150efdf7aa4c2037a2fd0516fb444525ab157a0ed0a7412b2fa69b217fe397263153782c0f64351fbdf2678fa0dc8569912dcd8e3ccad38f34f23bbbce14c6a26ac24911b308b82c7e43062d180baeac4ba7153858365c72c63dcf5f6a5b08070b730adb017aeae925b7d0439979e2679f45ed2f25a7edcfd2fb77a8794630285ccb0a071f5cce410b46dbf9750b0354aae8b65574501cc69efb5b6a43444074fee116641bb29da56c2b4a7f456991fc92b2\",\"debug\":0,\"seedipaddr\":\"78.47.196.146\"}" +curl --url "http://127.0.0.1:7776" --data "{\"conf\":\"SHARK.conf\",\"path\":\"${HOME#"/"}/.komodo/SHARK\",\"unitval\":\"20\",\"zcash\":1,\"RELAY\":-1,\"VALIDATE\":0,\"prefetchlag\":-1,\"poll\":100,\"active\":1,\"agent\":\"iguana\",\"method\":\"addcoin\",\"startpend\":4,\"endpend\":4,\"services\":129,\"maxpeers\":8,\"newcoin\":\"SHARK\",\"name\":\"SHARK\",\"hasheaders\":1,\"useaddmultisig\":0,\"netmagic\":\"54a5e30c\",\"p2p\":8845,\"rpc\":8846,\"pubval\":60,\"p2shval\":85,\"wifval\":188,\"txfee_satoshis\":\"10000\",\"isPoS\":0,\"minoutput\":10000,\"minconfirms\":2,\"genesishash\":\"027e3758c3a65b12aa1046462b486d0a63bfa1beae327897f56c5cfb7daaae71\",\"protover\":170002,\"genesisblock\":\"0100000000000000000000000000000000000000000000000000000000000000000000003ba3edfd7a7b12b27ac72c3e67768f617fc81bc3888a51323a9fb8aa4b1e5e4a000000000000000000000000000000000000000000000000000000000000000029ab5f490f0f0f200b00000000000000000000000000000000000000000000000000000000000000fd4005000d5ba7cda5d473947263bf194285317179d2b0d307119c2e7cc4bd8ac456f0774bd52b0cd9249be9d40718b6397a4c7bbd8f2b3272fed2823cd2af4bd1632200ba4bf796727d6347b225f670f292343274cc35099466f5fb5f0cd1c105121b28213d15db2ed7bdba490b4cedc69742a57b7c25af24485e523aadbb77a0144fc76f79ef73bd8530d42b9f3b9bed1c135ad1fe152923fafe98f95f76f1615e64c4abb1137f4c31b218ba2782bc15534788dda2cc08a0ee2987c8b27ff41bd4e31cd5fb5643dfe862c9a02ca9f90c8c51a6671d681d04ad47e4b53b1518d4befafefe8cadfb912f3d03051b1efbf1dfe37b56e93a741d8dfd80d576ca250bee55fab1311fc7b3255977558cdda6f7d6f875306e43a14413facdaed2f46093e0ef1e8f8a963e1632dcbeebd8e49fd16b57d49b08f9762de89157c65233f60c8e38a1f503a48c555f8ec45dedecd574a37601323c27be597b956343107f8bd80f3a925afaf30811df83c402116bb9c1e5231c70fff899a7c82f73c902ba54da53cc459b7bf1113db65cc8f6914d3618560ea69abd13658fa7b6af92d374d6eca9529f8bd565166e4fcbf2a8dfb3c9b69539d4d2ee2e9321b85b331925df195915f2757637c2805e1d4131e1ad9ef9bc1bb1c732d8dba4738716d351ab30c996c8657bab39567ee3b29c6d054b711495c0d52e1cd5d8e55b4f0f0325b97369280755b46a02afd54be4ddd9f77c22272b8bbb17ff5118fedbae2564524e797bd28b5f74f7079d532ccc059807989f94d267f47e724b3f1ecfe00ec9e6541c961080d8891251b84b4480bc292f6a180bea089fef5bbda56e1e41390d7c0e85ba0ef530f7177413481a226465a36ef6afe1e2bca69d2078712b3912bba1a99b1fbff0d355d6ffe726d2bb6fbc103c4ac5756e5bee6e47e17424ebcbf1b63d8cb90ce2e40198b4f4198689daea254307e52a25562f4c1455340f0ffeb10f9d8e914775e37d0edca019fb1b9c6ef81255ed86bc51c5391e0591480f66e2d88c5f4fd7277697968656a9b113ab97f874fdd5f2465e5559533e01ba13ef4a8f7a21d02c30c8ded68e8c54603ab9c8084ef6d9eb4e92c75b078539e2ae786ebab6dab73a09e0aa9ac575bcefb29e930ae656e58bcb513f7e3c17e079dce4f05b5dbc18c2a872b22509740ebe6a3903e00ad1abc55076441862643f93606e3dc35e8d9f2caef3ee6be14d513b2e062b21d0061de3bd56881713a1a5c17f5ace05e1ec09da53f99442df175a49bd154aa96e4949decd52fed79ccf7ccbce32941419c314e374e4a396ac553e17b5340336a1a25c22f9e42a243ba5404450b650acfc826a6e432971ace776e15719515e1634ceb9a4a35061b668c74998d3dfb5827f6238ec015377e6f9c94f38108768cf6e5c8b132e0303fb5a200368f845ad9d46343035a6ff94031df8d8309415bb3f6cd5ede9c135fdabcc030599858d803c0f85be7661c88984d88faa3d26fb0e9aac0056a53f1b5d0baed713c853c4a2726869a0a124a8a5bbc0fc0ef80c8ae4cb53636aa02503b86a1eb9836fcc259823e2692d921d88e1ffc1e6cb2bde43939ceb3f32a611686f539f8f7c9f0bf00381f743607d40960f06d347d1cd8ac8a51969c25e37150efdf7aa4c2037a2fd0516fb444525ab157a0ed0a7412b2fa69b217fe397263153782c0f64351fbdf2678fa0dc8569912dcd8e3ccad38f34f23bbbce14c6a26ac24911b308b82c7e43062d180baeac4ba7153858365c72c63dcf5f6a5b08070b730adb017aeae925b7d0439979e2679f45ed2f25a7edcfd2fb77a8794630285ccb0a071f5cce410b46dbf9750b0354aae8b65574501cc69efb5b6a43444074fee116641bb29da56c2b4a7f456991fc92b2\",\"debug\":0,\"seedipaddr\":\"78.47.196.146\"}" diff --git a/iguana/coins/shark_7776 b/iguana/coins/shark_7776 index 16e4378bf..d1a7bc525 100755 --- a/iguana/coins/shark_7776 +++ b/iguana/coins/shark_7776 @@ -1,2 +1,2 @@ -curl --url "http://127.0.0.1:7776" --data "{\"conf\":\"SHARK.conf\",\"path\":\"${HOME#"/"}/.komodo/SHARK\",\"unitval\":\"20\",\"zcash\":1,\"RELAY\":-1,\"VALIDATE\":0,\"prefetchlag\":-1,\"poll\":100,\"active\":1,\"agent\":\"iguana\",\"method\":\"addcoin\",\"startpend\":4,\"endpend\":4,\"services\":129,\"maxpeers\":8,\"newcoin\":\"SHARK\",\"name\":\"SHARK\",\"hasheaders\":1,\"useaddmultisig\":0,\"netmagic\":\"54a5e30c\",\"p2p\":10113,\"rpc\":10114,\"pubval\":60,\"p2shval\":85,\"wifval\":188,\"txfee_satoshis\":\"10000\",\"isPoS\":0,\"minoutput\":10000,\"minconfirms\":2,\"genesishash\":\"027e3758c3a65b12aa1046462b486d0a63bfa1beae327897f56c5cfb7daaae71\",\"protover\":170002,\"genesisblock\":\"0100000000000000000000000000000000000000000000000000000000000000000000003ba3edfd7a7b12b27ac72c3e67768f617fc81bc3888a51323a9fb8aa4b1e5e4a000000000000000000000000000000000000000000000000000000000000000029ab5f490f0f0f200b00000000000000000000000000000000000000000000000000000000000000fd4005000d5ba7cda5d473947263bf194285317179d2b0d307119c2e7cc4bd8ac456f0774bd52b0cd9249be9d40718b6397a4c7bbd8f2b3272fed2823cd2af4bd1632200ba4bf796727d6347b225f670f292343274cc35099466f5fb5f0cd1c105121b28213d15db2ed7bdba490b4cedc69742a57b7c25af24485e523aadbb77a0144fc76f79ef73bd8530d42b9f3b9bed1c135ad1fe152923fafe98f95f76f1615e64c4abb1137f4c31b218ba2782bc15534788dda2cc08a0ee2987c8b27ff41bd4e31cd5fb5643dfe862c9a02ca9f90c8c51a6671d681d04ad47e4b53b1518d4befafefe8cadfb912f3d03051b1efbf1dfe37b56e93a741d8dfd80d576ca250bee55fab1311fc7b3255977558cdda6f7d6f875306e43a14413facdaed2f46093e0ef1e8f8a963e1632dcbeebd8e49fd16b57d49b08f9762de89157c65233f60c8e38a1f503a48c555f8ec45dedecd574a37601323c27be597b956343107f8bd80f3a925afaf30811df83c402116bb9c1e5231c70fff899a7c82f73c902ba54da53cc459b7bf1113db65cc8f6914d3618560ea69abd13658fa7b6af92d374d6eca9529f8bd565166e4fcbf2a8dfb3c9b69539d4d2ee2e9321b85b331925df195915f2757637c2805e1d4131e1ad9ef9bc1bb1c732d8dba4738716d351ab30c996c8657bab39567ee3b29c6d054b711495c0d52e1cd5d8e55b4f0f0325b97369280755b46a02afd54be4ddd9f77c22272b8bbb17ff5118fedbae2564524e797bd28b5f74f7079d532ccc059807989f94d267f47e724b3f1ecfe00ec9e6541c961080d8891251b84b4480bc292f6a180bea089fef5bbda56e1e41390d7c0e85ba0ef530f7177413481a226465a36ef6afe1e2bca69d2078712b3912bba1a99b1fbff0d355d6ffe726d2bb6fbc103c4ac5756e5bee6e47e17424ebcbf1b63d8cb90ce2e40198b4f4198689daea254307e52a25562f4c1455340f0ffeb10f9d8e914775e37d0edca019fb1b9c6ef81255ed86bc51c5391e0591480f66e2d88c5f4fd7277697968656a9b113ab97f874fdd5f2465e5559533e01ba13ef4a8f7a21d02c30c8ded68e8c54603ab9c8084ef6d9eb4e92c75b078539e2ae786ebab6dab73a09e0aa9ac575bcefb29e930ae656e58bcb513f7e3c17e079dce4f05b5dbc18c2a872b22509740ebe6a3903e00ad1abc55076441862643f93606e3dc35e8d9f2caef3ee6be14d513b2e062b21d0061de3bd56881713a1a5c17f5ace05e1ec09da53f99442df175a49bd154aa96e4949decd52fed79ccf7ccbce32941419c314e374e4a396ac553e17b5340336a1a25c22f9e42a243ba5404450b650acfc826a6e432971ace776e15719515e1634ceb9a4a35061b668c74998d3dfb5827f6238ec015377e6f9c94f38108768cf6e5c8b132e0303fb5a200368f845ad9d46343035a6ff94031df8d8309415bb3f6cd5ede9c135fdabcc030599858d803c0f85be7661c88984d88faa3d26fb0e9aac0056a53f1b5d0baed713c853c4a2726869a0a124a8a5bbc0fc0ef80c8ae4cb53636aa02503b86a1eb9836fcc259823e2692d921d88e1ffc1e6cb2bde43939ceb3f32a611686f539f8f7c9f0bf00381f743607d40960f06d347d1cd8ac8a51969c25e37150efdf7aa4c2037a2fd0516fb444525ab157a0ed0a7412b2fa69b217fe397263153782c0f64351fbdf2678fa0dc8569912dcd8e3ccad38f34f23bbbce14c6a26ac24911b308b82c7e43062d180baeac4ba7153858365c72c63dcf5f6a5b08070b730adb017aeae925b7d0439979e2679f45ed2f25a7edcfd2fb77a8794630285ccb0a071f5cce410b46dbf9750b0354aae8b65574501cc69efb5b6a43444074fee116641bb29da56c2b4a7f456991fc92b2\",\"debug\":0,\"seedipaddr\":\"78.47.196.146\"}" +curl --url "http://127.0.0.1:7776" --data "{\"conf\":\"SHARK.conf\",\"path\":\"${HOME#"/"}/.komodo/SHARK\",\"unitval\":\"20\",\"zcash\":1,\"RELAY\":-1,\"VALIDATE\":0,\"prefetchlag\":-1,\"poll\":100,\"active\":1,\"agent\":\"iguana\",\"method\":\"addcoin\",\"startpend\":4,\"endpend\":4,\"services\":129,\"maxpeers\":8,\"newcoin\":\"SHARK\",\"name\":\"SHARK\",\"hasheaders\":1,\"useaddmultisig\":0,\"netmagic\":\"54a5e30c\",\"p2p\":14103,\"rpc\":14104,\"pubval\":60,\"p2shval\":85,\"wifval\":188,\"txfee_satoshis\":\"10000\",\"isPoS\":0,\"minoutput\":10000,\"minconfirms\":2,\"genesishash\":\"027e3758c3a65b12aa1046462b486d0a63bfa1beae327897f56c5cfb7daaae71\",\"protover\":170002,\"genesisblock\":\"0100000000000000000000000000000000000000000000000000000000000000000000003ba3edfd7a7b12b27ac72c3e67768f617fc81bc3888a51323a9fb8aa4b1e5e4a000000000000000000000000000000000000000000000000000000000000000029ab5f490f0f0f200b00000000000000000000000000000000000000000000000000000000000000fd4005000d5ba7cda5d473947263bf194285317179d2b0d307119c2e7cc4bd8ac456f0774bd52b0cd9249be9d40718b6397a4c7bbd8f2b3272fed2823cd2af4bd1632200ba4bf796727d6347b225f670f292343274cc35099466f5fb5f0cd1c105121b28213d15db2ed7bdba490b4cedc69742a57b7c25af24485e523aadbb77a0144fc76f79ef73bd8530d42b9f3b9bed1c135ad1fe152923fafe98f95f76f1615e64c4abb1137f4c31b218ba2782bc15534788dda2cc08a0ee2987c8b27ff41bd4e31cd5fb5643dfe862c9a02ca9f90c8c51a6671d681d04ad47e4b53b1518d4befafefe8cadfb912f3d03051b1efbf1dfe37b56e93a741d8dfd80d576ca250bee55fab1311fc7b3255977558cdda6f7d6f875306e43a14413facdaed2f46093e0ef1e8f8a963e1632dcbeebd8e49fd16b57d49b08f9762de89157c65233f60c8e38a1f503a48c555f8ec45dedecd574a37601323c27be597b956343107f8bd80f3a925afaf30811df83c402116bb9c1e5231c70fff899a7c82f73c902ba54da53cc459b7bf1113db65cc8f6914d3618560ea69abd13658fa7b6af92d374d6eca9529f8bd565166e4fcbf2a8dfb3c9b69539d4d2ee2e9321b85b331925df195915f2757637c2805e1d4131e1ad9ef9bc1bb1c732d8dba4738716d351ab30c996c8657bab39567ee3b29c6d054b711495c0d52e1cd5d8e55b4f0f0325b97369280755b46a02afd54be4ddd9f77c22272b8bbb17ff5118fedbae2564524e797bd28b5f74f7079d532ccc059807989f94d267f47e724b3f1ecfe00ec9e6541c961080d8891251b84b4480bc292f6a180bea089fef5bbda56e1e41390d7c0e85ba0ef530f7177413481a226465a36ef6afe1e2bca69d2078712b3912bba1a99b1fbff0d355d6ffe726d2bb6fbc103c4ac5756e5bee6e47e17424ebcbf1b63d8cb90ce2e40198b4f4198689daea254307e52a25562f4c1455340f0ffeb10f9d8e914775e37d0edca019fb1b9c6ef81255ed86bc51c5391e0591480f66e2d88c5f4fd7277697968656a9b113ab97f874fdd5f2465e5559533e01ba13ef4a8f7a21d02c30c8ded68e8c54603ab9c8084ef6d9eb4e92c75b078539e2ae786ebab6dab73a09e0aa9ac575bcefb29e930ae656e58bcb513f7e3c17e079dce4f05b5dbc18c2a872b22509740ebe6a3903e00ad1abc55076441862643f93606e3dc35e8d9f2caef3ee6be14d513b2e062b21d0061de3bd56881713a1a5c17f5ace05e1ec09da53f99442df175a49bd154aa96e4949decd52fed79ccf7ccbce32941419c314e374e4a396ac553e17b5340336a1a25c22f9e42a243ba5404450b650acfc826a6e432971ace776e15719515e1634ceb9a4a35061b668c74998d3dfb5827f6238ec015377e6f9c94f38108768cf6e5c8b132e0303fb5a200368f845ad9d46343035a6ff94031df8d8309415bb3f6cd5ede9c135fdabcc030599858d803c0f85be7661c88984d88faa3d26fb0e9aac0056a53f1b5d0baed713c853c4a2726869a0a124a8a5bbc0fc0ef80c8ae4cb53636aa02503b86a1eb9836fcc259823e2692d921d88e1ffc1e6cb2bde43939ceb3f32a611686f539f8f7c9f0bf00381f743607d40960f06d347d1cd8ac8a51969c25e37150efdf7aa4c2037a2fd0516fb444525ab157a0ed0a7412b2fa69b217fe397263153782c0f64351fbdf2678fa0dc8569912dcd8e3ccad38f34f23bbbce14c6a26ac24911b308b82c7e43062d180baeac4ba7153858365c72c63dcf5f6a5b08070b730adb017aeae925b7d0439979e2679f45ed2f25a7edcfd2fb77a8794630285ccb0a071f5cce410b46dbf9750b0354aae8b65574501cc69efb5b6a43444074fee116641bb29da56c2b4a7f456991fc92b2\",\"debug\":0,\"seedipaddr\":\"78.47.196.146\"}" diff --git a/iguana/exchanges/LP_NXT.c b/iguana/exchanges/LP_NXT.c index 581096ecd..e962daa7d 100644 --- a/iguana/exchanges/LP_NXT.c +++ b/iguana/exchanges/LP_NXT.c @@ -305,6 +305,7 @@ cJSON *LP_NXT_redeems() if ( totals[past_marker][i] != 0 ) printf("%-10s %13.5f past_marker.%d\n",assetids[i][1],dstr(totals[past_marker][i]),past_marker); } + printf("\n>>>>>>>>>> already processed:\n"); } return(retjson); } From d6dce089f57cc7c473a4af8851ea847f51918633 Mon Sep 17 00:00:00 2001 From: jl777 Date: Sat, 2 Dec 2017 11:20:58 +0400 Subject: [PATCH 1424/1664] Test --- iguana/exchanges/LP_instantdex.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/iguana/exchanges/LP_instantdex.c b/iguana/exchanges/LP_instantdex.c index d2ee44382..c398d505b 100644 --- a/iguana/exchanges/LP_instantdex.c +++ b/iguana/exchanges/LP_instantdex.c @@ -214,7 +214,7 @@ char *LP_instantdex_claim(struct iguana_info *coin) 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; From 02c12ebd2f7f72ba42ddf3ed5bc8a289e7ed51c1 Mon Sep 17 00:00:00 2001 From: jl777 Date: Sat, 2 Dec 2017 14:35:48 +0400 Subject: [PATCH 1425/1664] Test --- iguana/exchanges/stats.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) 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) From a4bfef1b12d13738a4e764bf49b34d4bc45c9be8 Mon Sep 17 00:00:00 2001 From: jl777 Date: Sat, 2 Dec 2017 20:17:17 +0400 Subject: [PATCH 1426/1664] Test --- iguana/exchanges/LP_socket.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/iguana/exchanges/LP_socket.c b/iguana/exchanges/LP_socket.c index af827b346..481a31ded 100644 --- a/iguana/exchanges/LP_socket.c +++ b/iguana/exchanges/LP_socket.c @@ -445,7 +445,7 @@ cJSON *electrum_submit(char *symbol,struct electrum_info *ep,cJSON **retjsonp,ch } return(*retjsonp); } - } else printf("couldnt find electrum server for (%s %s) or no retjsonp.%p\n",method,params,retjsonp); + } //else printf("couldnt find electrum server for (%s %s) or no retjsonp.%p\n",method,params,retjsonp); ep = ep->prev; //if ( ep != 0 ) // printf("using prev ep.%s\n",ep->symbol); From 6bf7dc3dce36348f66bb38a19d55bcd30babe918 Mon Sep 17 00:00:00 2001 From: jl777 Date: Sat, 2 Dec 2017 20:18:10 +0400 Subject: [PATCH 1427/1664] Test --- iguana/exchanges/LP_nativeDEX.c | 1 + 1 file changed, 1 insertion(+) diff --git a/iguana/exchanges/LP_nativeDEX.c b/iguana/exchanges/LP_nativeDEX.c index 4a853cd6d..7a8b48699 100644 --- a/iguana/exchanges/LP_nativeDEX.c +++ b/iguana/exchanges/LP_nativeDEX.c @@ -589,6 +589,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; } From dcf8c2c797d79d298637912e8a70f8e043871853 Mon Sep 17 00:00:00 2001 From: jl777 Date: Sat, 2 Dec 2017 22:51:51 +0400 Subject: [PATCH 1428/1664] Test --- iguana/exchanges/LP_instantdex.c | 13 +++++++++---- iguana/exchanges/LP_nativeDEX.c | 3 +-- iguana/exchanges/mm.c | 1 - 3 files changed, 10 insertions(+), 7 deletions(-) diff --git a/iguana/exchanges/LP_instantdex.c b/iguana/exchanges/LP_instantdex.c index c398d505b..81c5e505a 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)); @@ -229,9 +232,10 @@ char *LP_instantdex_claim(struct iguana_info *coin) } flagi = 0; utxovout = 0; + // make into function, and separate calling path by txid if ( (txjson= LP_gettx(coin->symbol,utxotxid,1)) != 0 ) { - if ( (vouts= jarray(&numvouts,txjson,"vout")) != 0 && numvouts == 3 ) + if ( (vouts= jarray(&numvouts,txjson,"vout")) != 0 && numvouts >= 3 ) { vout0 = jitem(vouts,0); LP_destaddr(vinaddr,vout0); @@ -410,6 +414,7 @@ int64_t LP_dynamictrust(bits256 pubkey,int64_t kmdvalue) int64_t LP_instantdex_proofcheck(char *coinaddr,cJSON *proof,int32_t num) { uint8_t rmd160[20],addrtype; int32_t i; int64_t net = 0; char othersmartaddr[64]; struct iguana_info *coin; struct LP_address *ap = 0; + printf("proofcheck.(%s) %d %s\n",coinaddr,num,jprint(proof,0)); if ( (coin= LP_coinfind("KMD")) != 0 ) { bitcoin_addr2rmd160(0,&addrtype,rmd160,coinaddr); @@ -437,7 +442,7 @@ int64_t LP_myzcredits() zcredits = LP_instantdex_proofcheck(coin->smartaddr,proof,cJSON_GetArraySize(proof)); free_json(proof); return(zcredits); - } + } else printf("cant find my instantdex proof\n"); } return(0); } diff --git a/iguana/exchanges/LP_nativeDEX.c b/iguana/exchanges/LP_nativeDEX.c index 7a8b48699..0e4c91e44 100644 --- a/iguana/exchanges/LP_nativeDEX.c +++ b/iguana/exchanges/LP_nativeDEX.c @@ -17,7 +17,7 @@ // LP_nativeDEX.c // marketmaker // -// verify claim works +// delay swap credit back until notarization, else path // big BTC swaps // https://github.com/bitcoin/bips/blob/master/bip-0143.mediawiki for signing BCH/BTG // @@ -28,7 +28,6 @@ // USD paxprice based USDvalue in portfolio // // improve critical section detection when parallel trades -// delay swap credit back until notarization // dPoW security -> 4: KMD notarized, 5: BTC notarized, after next notary elections // bigendian architectures need to use little endian for sighash calcs // 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,...) { From c5fae7900907090faa830d61c91ef5a0166b6415 Mon Sep 17 00:00:00 2001 From: jl777 Date: Sat, 2 Dec 2017 22:58:37 +0400 Subject: [PATCH 1429/1664] Test --- iguana/exchanges/LP_instantdex.c | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/iguana/exchanges/LP_instantdex.c b/iguana/exchanges/LP_instantdex.c index 81c5e505a..56f4a05d0 100644 --- a/iguana/exchanges/LP_instantdex.c +++ b/iguana/exchanges/LP_instantdex.c @@ -235,7 +235,7 @@ char *LP_instantdex_claim(struct iguana_info *coin) // make into function, and separate calling path by txid if ( (txjson= LP_gettx(coin->symbol,utxotxid,1)) != 0 ) { - if ( (vouts= jarray(&numvouts,txjson,"vout")) != 0 && numvouts >= 3 ) + if ( (vouts= jarray(&numvouts,txjson,"vout")) != 0 && numvouts == 3 ) { vout0 = jitem(vouts,0); LP_destaddr(vinaddr,vout0); @@ -414,7 +414,6 @@ int64_t LP_dynamictrust(bits256 pubkey,int64_t kmdvalue) int64_t LP_instantdex_proofcheck(char *coinaddr,cJSON *proof,int32_t num) { uint8_t rmd160[20],addrtype; int32_t i; int64_t net = 0; char othersmartaddr[64]; struct iguana_info *coin; struct LP_address *ap = 0; - printf("proofcheck.(%s) %d %s\n",coinaddr,num,jprint(proof,0)); if ( (coin= LP_coinfind("KMD")) != 0 ) { bitcoin_addr2rmd160(0,&addrtype,rmd160,coinaddr); @@ -442,7 +441,7 @@ int64_t LP_myzcredits() zcredits = LP_instantdex_proofcheck(coin->smartaddr,proof,cJSON_GetArraySize(proof)); free_json(proof); return(zcredits); - } else printf("cant find my instantdex proof\n"); + } } return(0); } From 68cea842a7cfb621a3611766e7d863f0d724f7bb Mon Sep 17 00:00:00 2001 From: jl777 Date: Sat, 2 Dec 2017 23:07:56 +0400 Subject: [PATCH 1430/1664] Test --- iguana/exchanges/LP_instantdex.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/iguana/exchanges/LP_instantdex.c b/iguana/exchanges/LP_instantdex.c index 56f4a05d0..9fac9b6cd 100644 --- a/iguana/exchanges/LP_instantdex.c +++ b/iguana/exchanges/LP_instantdex.c @@ -403,7 +403,8 @@ int64_t LP_dynamictrust(bits256 pubkey,int64_t kmdvalue) if ( (sp= ptr->swap) != 0 && sp->finished == 0 && sp->expired == 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)); } From 08db8aa6bc01f9b34c379c1057c1bb69047bfabe Mon Sep 17 00:00:00 2001 From: jl777 Date: Sun, 3 Dec 2017 15:41:10 +0400 Subject: [PATCH 1431/1664] Test --- iguana/exchanges/LP_include.h | 4 +- iguana/exchanges/LP_instantdex.c | 195 ++++++++++++++++++++----------- iguana/exchanges/LP_nativeDEX.c | 2 +- iguana/exchanges/LP_rpc.c | 8 +- iguana/exchanges/LP_socket.c | 24 ++-- iguana/exchanges/LP_stats.c | 75 +++++++++++- iguana/exchanges/LP_utxo.c | 10 +- iguana/m_notary | 49 +------- iguana/m_notary_run | 47 ++++++++ 9 files changed, 283 insertions(+), 131 deletions(-) create mode 100755 iguana/m_notary_run diff --git a/iguana/exchanges/LP_include.h b/iguana/exchanges/LP_include.h index bb7e77d73..c64827d11 100644 --- a/iguana/exchanges/LP_include.h +++ b/iguana/exchanges/LP_include.h @@ -403,7 +403,8 @@ struct LP_swapstats bits256 bobdeposit,alicepayment,bobpayment,paymentspent,Apaymentspent,depositspent; double qprice; uint64_t aliceid; - uint32_t ind,methodind,finished,expired,lasttime; + int32_t bobneeds_dPoW,aliceneeds_dPoW,bob_dPoWheight,alice_dPoWheight; + uint32_t ind,methodind,finished,expired,lasttime,dPoWfinished; char alicegui[32],bobgui[32]; }; @@ -489,6 +490,7 @@ 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); diff --git a/iguana/exchanges/LP_instantdex.c b/iguana/exchanges/LP_instantdex.c index 9fac9b6cd..a8f5760c5 100644 --- a/iguana/exchanges/LP_instantdex.c +++ b/iguana/exchanges/LP_instantdex.c @@ -202,16 +202,74 @@ 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=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 + { + utxovout = 0; + *sump += LP_claimtx(ctx,coin,&claimtxid,utxotxid,utxovout,satoshis,vinaddr,claimtime,redeemscript,redeemlen); + if ( bits256_nonz(claimtxid) != 0 ) + { + flagi = 1; + 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; + int32_t i,n; cJSON *array,*txids,*newarray,*retjson; int64_t sum; bits256 utxotxid; printf("inside instantdex claim\n"); 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(); @@ -220,71 +278,11 @@ char *LP_instantdex_claim(struct iguana_info *coin) 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); @@ -395,12 +393,12 @@ 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); } if ( ap->instantdex_credits != 0 && (swaps_kmdvalue+kmdvalue) > ap->instantdex_credits ) @@ -446,3 +444,70 @@ int64_t LP_myzcredits() } return(0); } + +cJSON *LP_swapstats_item(struct LP_swapstats *sp,int32_t iambob) +{ + cJSON *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 ) + { + jaddnum(item,"bobneeds_dPoW",sp->bobneeds_dPoW); + jaddnum(item,"bobdPoW_height",sp->bob_dPoWheight); + } + if ( sp->aliceneeds_dPoW != 0 ) + { + jaddnum(item,"aliceneeds_dPoW",sp->aliceneeds_dPoW); + jaddnum(item,"alicedPoW_height",sp->alice_dPoWheight); + } + } + 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(); + jaddstr(retjson,"result","success"); + jadd(retjson,"swaps",array); + jaddnum(retjson,"pendingswaps",dstr(swaps_kmdvalue)); +} diff --git a/iguana/exchanges/LP_nativeDEX.c b/iguana/exchanges/LP_nativeDEX.c index 0e4c91e44..c818a1436 100644 --- a/iguana/exchanges/LP_nativeDEX.c +++ b/iguana/exchanges/LP_nativeDEX.c @@ -571,7 +571,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 ) diff --git a/iguana/exchanges/LP_rpc.c b/iguana/exchanges/LP_rpc.c index b39cdc9fa..7b04045eb 100644 --- a/iguana/exchanges/LP_rpc.c +++ b/iguana/exchanges/LP_rpc.c @@ -157,7 +157,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 +174,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 +214,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 +236,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)); diff --git a/iguana/exchanges/LP_socket.c b/iguana/exchanges/LP_socket.c index 481a31ded..8cceb33b2 100644 --- a/iguana/exchanges/LP_socket.c +++ b/iguana/exchanges/LP_socket.c @@ -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..fc33d58bc 100644 --- a/iguana/exchanges/LP_stats.c +++ b/iguana/exchanges/LP_stats.c @@ -208,10 +208,72 @@ int32_t LP_swapstats_update(struct LP_swapstats *sp,struct LP_quoteinfo *qp,cJSO return(0); } +int32_t LP_dPoWheight(struct iguana_info *coin) // get dPoW protected height +{ + +} + +int32_t LP_finished_lastheight(struct LP_swapstats *sp,int32_t iambob) +{ + int32_t ht,height = 1; struct iguana_info *coin; + if ( (coin= LP_coinfind(iambob != 0 ? sp->Q.srccoin : sp->Q.destcoin)) != 0 ) + { + if ( iambob != 0 ) + { + if ( bits256_nonz(sp->bobdeposit) != 0 && (ht= LP_txheight(coin,sp->bobdeposit)) > 1 && ht > height ) + height = ht; + if ( bits256_nonz(sp->bobpayment) != 0 && (ht= LP_txheight(coin,sp->bobpayment)) > 1 && ht > height ) + height = ht; + if ( bits256_nonz(sp->paymentspent) != 0 && (ht= LP_txheight(coin,sp->paymentspent)) > 1 && ht > height ) + height = ht; + if ( bits256_nonz(sp->depositspent) != 0 && (ht= LP_txheight(coin,sp->depositspent)) > 1 && ht > height ) + height = ht; + } + else + { + if ( bits256_nonz(sp->alicepayment) != 0 && (ht= LP_txheight(coin,sp->alicepayment)) > 1 && ht > height ) + height = ht; + if ( bits256_nonz(sp->Apaymentspent) != 0 && (ht= LP_txheight(coin,sp->Apaymentspent)) > 1 && ht > height ) + height = ht; + } + } + return(height); +} + +int32_t LP_swap_finished(struct LP_swapstats *sp,int32_t dPoWflag) +{ + struct iguana_info *bob,*alice; + bob = LP_coinfind(sp->Q.srccoin); + alice = LP_coinfind(sp->Q.destcoin); + if ( sp->finished == 0 ) + { + if ( sp->expired != 0 ) + return(1); + if ( dPoWflag != 0 ) + { + if ( sp->finished != 0 && sp->dPoWfinished != 0 ) + return(1); + else if ( sp->finished != 0 ) + { + sp->bob_dPoWheight = LP_dPoWheight(bob); + sp->alice_dPoWheight = LP_dPoWheight(alice); + if ( bob->isassetchain != 0 ) + sp->bobneeds_dPoW = LP_finished_lastheight(sp,1); + if ( alice->isassetchain != 0 ) + sp->aliceneeds_dPoW = LP_finished_lastheight(sp,0); + printf("bob needs %d @ %d, alice needs %d @ %d\n",sp->bobneeds_dPoW,sp->bob_dPoWheight,sp->aliceneeds_dPoW,sp->alice_dPoWheight); + } + if ( (sp->bobneeds_dPoW == 0 || (sp->bobneeds_dPoW > 1 && sp->bob_dPoWheight >= sp->bobneeds_dPoW)) && (sp->aliceneeds_dPoW == 0 || (sp->aliceneeds_dPoW > 1 && sp->alice_dPoWheight >= sp->aliceneeds_dPoW)) ) + return(1); + } + } + return(0); +} + 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; struct iguana_info *alice,*bob; 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]; memset(numtrades,0,sizeof(numtrades)); memset(basevols,0,sizeof(basevols)); memset(relvols,0,sizeof(relvols)); @@ -314,9 +376,18 @@ int32_t LP_statslog_parsequote(char *method,cJSON *lineobj) 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)) && alice->isassetchain != 0 ) + sp->aliceneeds_dPoW = 1; + if ( (bob= LP_coinfind(rel)) && bob->isassetchain != 0 ) + sp->bobneeds_dPoW = 1; + } strcpy(sp->bobgui,"nogui"); strcpy(sp->alicegui,"nogui"); - if ( sp->finished == 0 && sp->expired == 0 ) + if ( LP_swap_finished(sp,1) == 0 ) //sp->finished == 0 && sp->expired == 0 ) { if ( (pubp= LP_pubkeyadd(sp->Q.srchash)) != 0 ) { diff --git a/iguana/exchanges/LP_utxo.c b/iguana/exchanges/LP_utxo.c index 9d48e6ba5..2770ad42b 100644 --- a/iguana/exchanges/LP_utxo.c +++ b/iguana/exchanges/LP_utxo.c @@ -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,6 +791,11 @@ 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 ) + free_json(retjson); + } } return(height); } 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\"}" From 30828f5fc23c517bac9052106e204c9a5f496367 Mon Sep 17 00:00:00 2001 From: jl777 Date: Sun, 3 Dec 2017 16:04:03 +0400 Subject: [PATCH 1432/1664] Test --- iguana/exchanges/LP_cache.c | 13 ++++++++++--- iguana/exchanges/LP_coins.c | 6 ++++-- iguana/exchanges/LP_commands.c | 5 +++-- iguana/exchanges/LP_include.h | 4 ++-- iguana/exchanges/LP_instantdex.c | 2 +- iguana/exchanges/LP_nativeDEX.c | 31 ++++++++++++++++++++++--------- iguana/exchanges/LP_ordermatch.c | 4 ++-- iguana/exchanges/LP_privkey.c | 4 ++-- iguana/exchanges/LP_rpc.c | 4 +++- iguana/exchanges/LP_stats.c | 8 +++++--- iguana/exchanges/LP_utxo.c | 8 ++++---- 11 files changed, 58 insertions(+), 31 deletions(-) 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..a0af02d32 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\ @@ -419,8 +420,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\"}")); diff --git a/iguana/exchanges/LP_include.h b/iguana/exchanges/LP_include.h index c64827d11..2de68ee07 100644 --- a/iguana/exchanges/LP_include.h +++ b/iguana/exchanges/LP_include.h @@ -289,7 +289,7 @@ 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; + int32_t numutxos,notarized,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; uint8_t pubtype,p2shtype,isPoS,wiftype,wiftaddr,taddr,noimportprivkey_flag,userconfirms,isassetchain,maxconfirms; char symbol[128],smartaddr[64],userpass[1024],serverport[128]; @@ -483,7 +483,7 @@ 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); diff --git a/iguana/exchanges/LP_instantdex.c b/iguana/exchanges/LP_instantdex.c index a8f5760c5..b32297672 100644 --- a/iguana/exchanges/LP_instantdex.c +++ b/iguana/exchanges/LP_instantdex.c @@ -507,7 +507,7 @@ cJSON *LP_myzdebits() } } retjson = cJSON_CreateObject(); - jaddstr(retjson,"result","success"); 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 c818a1436..4163a4511 100644 --- a/iguana/exchanges/LP_nativeDEX.c +++ b/iguana/exchanges/LP_nativeDEX.c @@ -483,7 +483,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"); @@ -528,7 +528,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 ) @@ -645,7 +645,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; bits256 zero; cJSON *reqjson; if ( (origipaddr= myipaddr) == 0 ) origipaddr = "127.0.0.1"; if ( mypeer == 0 ) @@ -660,19 +660,32 @@ 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 ) + { + reqjson = cJSON_CreateObject(); + jaddstr(reqjson,"method","dPoW"); + jaddstr(reqjson,"coin",coin->symbol); + jaddnum(reqjson,"notarized",coin->notarized); + memset(zero.bytes,0,sizeof(zero)); + LP_reserved_msg(0,coin->symbol,coin->symbol,zero,jprint(reqjson,1)); + } + } 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 +698,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 +733,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 ) diff --git a/iguana/exchanges/LP_ordermatch.c b/iguana/exchanges/LP_ordermatch.c index 15d8f959d..9ad350ce8 100644 --- a/iguana/exchanges/LP_ordermatch.c +++ b/iguana/exchanges/LP_ordermatch.c @@ -696,13 +696,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 ) { 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_rpc.c b/iguana/exchanges/LP_rpc.c index 7b04045eb..5c60ea47e 100644 --- a/iguana/exchanges/LP_rpc.c +++ b/iguana/exchanges/LP_rpc.c @@ -86,9 +86,10 @@ 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; @@ -101,6 +102,7 @@ int32_t LP_getheight(struct iguana_info *coin) { retjson = cJSON_Parse(retstr); coin->height = height = jint(retjson,"blocks"); + *notarizedp = jint(retjson,"notarized"); free_json(retjson); if ( coin->height > 0 ) coin->heighttime = (uint32_t)time(NULL); diff --git a/iguana/exchanges/LP_stats.c b/iguana/exchanges/LP_stats.c index fc33d58bc..1837fbffd 100644 --- a/iguana/exchanges/LP_stats.c +++ b/iguana/exchanges/LP_stats.c @@ -210,7 +210,9 @@ int32_t LP_swapstats_update(struct LP_swapstats *sp,struct LP_quoteinfo *qp,cJSO int32_t LP_dPoWheight(struct iguana_info *coin) // get dPoW protected height { - + int32_t notarized; + coin->height = LP_getheight(¬arized,coin); + return(notarized); } int32_t LP_finished_lastheight(struct LP_swapstats *sp,int32_t iambob) @@ -380,9 +382,9 @@ int32_t LP_statslog_parsequote(char *method,cJSON *lineobj) sp->expired = sp->lasttime; else { - if ( (alice= LP_coinfind(rel)) && alice->isassetchain != 0 ) + if ( (alice= LP_coinfind(rel)) != 0 && (alice->isassetchain != 0 || strcmp("KMD",alice->symbol) == 0) ) sp->aliceneeds_dPoW = 1; - if ( (bob= LP_coinfind(rel)) && bob->isassetchain != 0 ) + if ( (bob= LP_coinfind(rel)) != 0 && (bob->isassetchain != 0 || strcmp(bob->symbol,"KMD") == 0) ) sp->bobneeds_dPoW = 1; } strcpy(sp->bobgui,"nogui"); diff --git a/iguana/exchanges/LP_utxo.c b/iguana/exchanges/LP_utxo.c index 2770ad42b..aa11f9b3b 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",""); } @@ -802,7 +802,7 @@ int32_t LP_txheight(struct iguana_info *coin,bits256 txid) 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); @@ -827,7 +827,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 ) From 7e43bf3f88fa1ab7de89a582e39b509e43ab057c Mon Sep 17 00:00:00 2001 From: jl777 Date: Sun, 3 Dec 2017 16:14:31 +0400 Subject: [PATCH 1433/1664] Test --- iguana/exchanges/LP_ordermatch.c | 53 +++++++++++++++++--------------- 1 file changed, 29 insertions(+), 24 deletions(-) diff --git a/iguana/exchanges/LP_ordermatch.c b/iguana/exchanges/LP_ordermatch.c index 9ad350ce8..cebdfd947 100644 --- a/iguana/exchanges/LP_ordermatch.c +++ b/iguana/exchanges/LP_ordermatch.c @@ -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); From 2e9793f6ba61e9b14e91146fa0b42a81bcaa5d81 Mon Sep 17 00:00:00 2001 From: jl777 Date: Sun, 3 Dec 2017 16:22:13 +0400 Subject: [PATCH 1434/1664] Test --- iguana/exchanges/LP_instantdex.c | 4 ++-- iguana/exchanges/LP_ordermatch.c | 1 - iguana/exchanges/LP_stats.c | 3 ++- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/iguana/exchanges/LP_instantdex.c b/iguana/exchanges/LP_instantdex.c index b32297672..62fafbbad 100644 --- a/iguana/exchanges/LP_instantdex.c +++ b/iguana/exchanges/LP_instantdex.c @@ -463,12 +463,12 @@ cJSON *LP_swapstats_item(struct LP_swapstats *sp,int32_t iambob) if ( sp->bobneeds_dPoW != 0 ) { jaddnum(item,"bobneeds_dPoW",sp->bobneeds_dPoW); - jaddnum(item,"bobdPoW_height",sp->bob_dPoWheight); + jaddnum(item,"bob_dPoWheight",sp->bob_dPoWheight); } if ( sp->aliceneeds_dPoW != 0 ) { jaddnum(item,"aliceneeds_dPoW",sp->aliceneeds_dPoW); - jaddnum(item,"alicedPoW_height",sp->alice_dPoWheight); + jaddnum(item,"alice_dPoWheight",sp->alice_dPoWheight); } } return(item); diff --git a/iguana/exchanges/LP_ordermatch.c b/iguana/exchanges/LP_ordermatch.c index cebdfd947..fa911b330 100644 --- a/iguana/exchanges/LP_ordermatch.c +++ b/iguana/exchanges/LP_ordermatch.c @@ -1313,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_stats.c b/iguana/exchanges/LP_stats.c index 1837fbffd..3d3e72981 100644 --- a/iguana/exchanges/LP_stats.c +++ b/iguana/exchanges/LP_stats.c @@ -211,7 +211,8 @@ int32_t LP_swapstats_update(struct LP_swapstats *sp,struct LP_quoteinfo *qp,cJSO int32_t LP_dPoWheight(struct iguana_info *coin) // get dPoW protected height { int32_t notarized; - coin->height = LP_getheight(¬arized,coin); + LP_getheight(¬arized,coin); + printf("dPoWheight.%s %d\n",coin->symbol,notarized); return(notarized); } From e347719541bbf0c0ad241f49f7f016e77b021ff3 Mon Sep 17 00:00:00 2001 From: jl777 Date: Sun, 3 Dec 2017 16:28:57 +0400 Subject: [PATCH 1435/1664] Test --- iguana/exchanges/LP_stats.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/iguana/exchanges/LP_stats.c b/iguana/exchanges/LP_stats.c index 3d3e72981..49fbdc8cc 100644 --- a/iguana/exchanges/LP_stats.c +++ b/iguana/exchanges/LP_stats.c @@ -379,7 +379,7 @@ int32_t LP_statslog_parsequote(char *method,cJSON *lineobj) 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) + if ( sp->lasttime > sp->Q.timestamp+LP_atomic_locktime(base,rel)*2 ) sp->expired = sp->lasttime; else { @@ -436,6 +436,8 @@ 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 ( 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); From 193dd3527c55f55144451c72566f770e5b107a6b Mon Sep 17 00:00:00 2001 From: jl777 Date: Sun, 3 Dec 2017 16:35:50 +0400 Subject: [PATCH 1436/1664] Test --- iguana/exchanges/LP_rpc.c | 6 +++++- iguana/exchanges/LP_stats.c | 24 ++++++++++++++++++------ 2 files changed, 23 insertions(+), 7 deletions(-) diff --git a/iguana/exchanges/LP_rpc.c b/iguana/exchanges/LP_rpc.c index 5c60ea47e..e3b8e5d07 100644 --- a/iguana/exchanges/LP_rpc.c +++ b/iguana/exchanges/LP_rpc.c @@ -102,7 +102,11 @@ int32_t LP_getheight(int32_t *notarizedp,struct iguana_info *coin) { retjson = cJSON_Parse(retstr); coin->height = height = jint(retjson,"blocks"); - *notarizedp = jint(retjson,"notarized"); + if ( (*notarizedp= jint(retjson,"notarized")) != 0 && *notarizedp != coin->notarized ) + { + printf("new notarized %s %d -> %d\n",coin->symbol,coin->notarized,*notarizedp); + coin->notarized = *notarizedp; + } free_json(retjson); if ( coin->height > 0 ) coin->heighttime = (uint32_t)time(NULL); diff --git a/iguana/exchanges/LP_stats.c b/iguana/exchanges/LP_stats.c index 49fbdc8cc..c0bf11515 100644 --- a/iguana/exchanges/LP_stats.c +++ b/iguana/exchanges/LP_stats.c @@ -210,10 +210,19 @@ int32_t LP_swapstats_update(struct LP_swapstats *sp,struct LP_quoteinfo *qp,cJSO int32_t LP_dPoWheight(struct iguana_info *coin) // get dPoW protected height { - int32_t notarized; - LP_getheight(¬arized,coin); - printf("dPoWheight.%s %d\n",coin->symbol,notarized); - return(notarized); + 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; + } + } + return(coin->notarized); } int32_t LP_finished_lastheight(struct LP_swapstats *sp,int32_t iambob) @@ -248,6 +257,8 @@ int32_t LP_swap_finished(struct LP_swapstats *sp,int32_t dPoWflag) struct iguana_info *bob,*alice; bob = LP_coinfind(sp->Q.srccoin); alice = LP_coinfind(sp->Q.destcoin); + sp->bob_dPoWheight = LP_dPoWheight(bob); + sp->alice_dPoWheight = LP_dPoWheight(alice); if ( sp->finished == 0 ) { if ( sp->expired != 0 ) @@ -258,8 +269,6 @@ int32_t LP_swap_finished(struct LP_swapstats *sp,int32_t dPoWflag) return(1); else if ( sp->finished != 0 ) { - sp->bob_dPoWheight = LP_dPoWheight(bob); - sp->alice_dPoWheight = LP_dPoWheight(alice); if ( bob->isassetchain != 0 ) sp->bobneeds_dPoW = LP_finished_lastheight(sp,1); if ( alice->isassetchain != 0 ) @@ -267,7 +276,10 @@ int32_t LP_swap_finished(struct LP_swapstats *sp,int32_t dPoWflag) printf("bob needs %d @ %d, alice needs %d @ %d\n",sp->bobneeds_dPoW,sp->bob_dPoWheight,sp->aliceneeds_dPoW,sp->alice_dPoWheight); } if ( (sp->bobneeds_dPoW == 0 || (sp->bobneeds_dPoW > 1 && sp->bob_dPoWheight >= sp->bobneeds_dPoW)) && (sp->aliceneeds_dPoW == 0 || (sp->aliceneeds_dPoW > 1 && sp->alice_dPoWheight >= sp->aliceneeds_dPoW)) ) + { + sp->dPoWfinished = (uint32_t)time(NULL); return(1); + } } } return(0); From ed2214f2c10c02701c4244c17d6c28a388da5bec Mon Sep 17 00:00:00 2001 From: jl777 Date: Sun, 3 Dec 2017 16:40:46 +0400 Subject: [PATCH 1437/1664] Test --- iguana/exchanges/LP_stats.c | 12 ++++++++++-- 1 file changed, 10 insertions(+), 2 deletions(-) diff --git a/iguana/exchanges/LP_stats.c b/iguana/exchanges/LP_stats.c index c0bf11515..fcc0c313b 100644 --- a/iguana/exchanges/LP_stats.c +++ b/iguana/exchanges/LP_stats.c @@ -255,8 +255,16 @@ int32_t LP_finished_lastheight(struct LP_swapstats *sp,int32_t iambob) int32_t LP_swap_finished(struct LP_swapstats *sp,int32_t dPoWflag) { struct iguana_info *bob,*alice; - bob = LP_coinfind(sp->Q.srccoin); - alice = LP_coinfind(sp->Q.destcoin); + 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); + } sp->bob_dPoWheight = LP_dPoWheight(bob); sp->alice_dPoWheight = LP_dPoWheight(alice); if ( sp->finished == 0 ) From 01961694f6afeb4028d581f999af7bedb8cba2ed Mon Sep 17 00:00:00 2001 From: jl777 Date: Sun, 3 Dec 2017 16:42:11 +0400 Subject: [PATCH 1438/1664] Test --- iguana/exchanges/LP_commands.c | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/iguana/exchanges/LP_commands.c b/iguana/exchanges/LP_commands.c index a0af02d32..bb05f3cf3 100644 --- a/iguana/exchanges/LP_commands.c +++ b/iguana/exchanges/LP_commands.c @@ -258,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\"}")); } From 23b582cfd1490f073e46fe9e79a5b25db8aae211 Mon Sep 17 00:00:00 2001 From: jl777 Date: Sun, 3 Dec 2017 16:46:32 +0400 Subject: [PATCH 1439/1664] Test --- iguana/exchanges/LP_bitcoin.c | 2 ++ iguana/exchanges/LP_rpc.c | 2 +- 2 files changed, 3 insertions(+), 1 deletion(-) 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_rpc.c b/iguana/exchanges/LP_rpc.c index e3b8e5d07..169192f54 100644 --- a/iguana/exchanges/LP_rpc.c +++ b/iguana/exchanges/LP_rpc.c @@ -93,7 +93,7 @@ int32_t LP_getheight(int32_t *notarizedp,struct iguana_info *coin) 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"; From 014920967138034926cd8711156845edfaeb6c7e Mon Sep 17 00:00:00 2001 From: jl777 Date: Sun, 3 Dec 2017 16:50:23 +0400 Subject: [PATCH 1440/1664] Test --- iguana/exchanges/LP_stats.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/iguana/exchanges/LP_stats.c b/iguana/exchanges/LP_stats.c index fcc0c313b..433fc8126 100644 --- a/iguana/exchanges/LP_stats.c +++ b/iguana/exchanges/LP_stats.c @@ -265,8 +265,6 @@ int32_t LP_swap_finished(struct LP_swapstats *sp,int32_t dPoWflag) printf("no alicecoin.%s\n",sp->Q.destcoin); return(0); } - sp->bob_dPoWheight = LP_dPoWheight(bob); - sp->alice_dPoWheight = LP_dPoWheight(alice); if ( sp->finished == 0 ) { if ( sp->expired != 0 ) @@ -281,6 +279,8 @@ int32_t LP_swap_finished(struct LP_swapstats *sp,int32_t dPoWflag) sp->bobneeds_dPoW = LP_finished_lastheight(sp,1); if ( alice->isassetchain != 0 ) sp->aliceneeds_dPoW = LP_finished_lastheight(sp,0); + sp->bob_dPoWheight = LP_dPoWheight(bob); + sp->alice_dPoWheight = LP_dPoWheight(alice); printf("bob needs %d @ %d, alice needs %d @ %d\n",sp->bobneeds_dPoW,sp->bob_dPoWheight,sp->aliceneeds_dPoW,sp->alice_dPoWheight); } if ( (sp->bobneeds_dPoW == 0 || (sp->bobneeds_dPoW > 1 && sp->bob_dPoWheight >= sp->bobneeds_dPoW)) && (sp->aliceneeds_dPoW == 0 || (sp->aliceneeds_dPoW > 1 && sp->alice_dPoWheight >= sp->aliceneeds_dPoW)) ) From 402214f45ba1c4291423ec6c68ef0cade2302daf Mon Sep 17 00:00:00 2001 From: jl777 Date: Sun, 3 Dec 2017 16:52:52 +0400 Subject: [PATCH 1441/1664] Test --- iguana/exchanges/LP_include.h | 2 +- iguana/exchanges/LP_instantdex.c | 10 +++++----- iguana/exchanges/LP_stats.c | 6 ++---- 3 files changed, 8 insertions(+), 10 deletions(-) diff --git a/iguana/exchanges/LP_include.h b/iguana/exchanges/LP_include.h index 2de68ee07..a70137b68 100644 --- a/iguana/exchanges/LP_include.h +++ b/iguana/exchanges/LP_include.h @@ -403,7 +403,7 @@ struct LP_swapstats bits256 bobdeposit,alicepayment,bobpayment,paymentspent,Apaymentspent,depositspent; double qprice; uint64_t aliceid; - int32_t bobneeds_dPoW,aliceneeds_dPoW,bob_dPoWheight,alice_dPoWheight; + int32_t bobneeds_dPoW,aliceneeds_dPoW; uint32_t ind,methodind,finished,expired,lasttime,dPoWfinished; char alicegui[32],bobgui[32]; }; diff --git a/iguana/exchanges/LP_instantdex.c b/iguana/exchanges/LP_instantdex.c index 62fafbbad..0e482e6c9 100644 --- a/iguana/exchanges/LP_instantdex.c +++ b/iguana/exchanges/LP_instantdex.c @@ -447,7 +447,7 @@ int64_t LP_myzcredits() cJSON *LP_swapstats_item(struct LP_swapstats *sp,int32_t iambob) { - cJSON *item = cJSON_CreateObject(); + struct iguana_info *bob,*alice; cJSON *item = cJSON_CreateObject(); jaddnum(item,"iambob",iambob); jaddnum(item,"aliceid",sp->aliceid); jaddnum(item,"requestid",sp->Q.R.requestid); @@ -460,15 +460,15 @@ cJSON *LP_swapstats_item(struct LP_swapstats *sp,int32_t iambob) if ( LP_swap_finished(sp,1) == 0 ) { jaddnum(item,"finished",sp->finished); - if ( sp->bobneeds_dPoW != 0 ) + if ( sp->bobneeds_dPoW != 0 && (bob= LP_coinfind(sp->Q.srccoin)) != 0 ) { jaddnum(item,"bobneeds_dPoW",sp->bobneeds_dPoW); - jaddnum(item,"bob_dPoWheight",sp->bob_dPoWheight); + jaddnum(item,"bob_dPoWheight",bob->notarized); } - if ( sp->aliceneeds_dPoW != 0 ) + if ( sp->aliceneeds_dPoW != 0 && (alice= LP_coinfind(sp->Q.destcoin)) != 0 ) { jaddnum(item,"aliceneeds_dPoW",sp->aliceneeds_dPoW); - jaddnum(item,"alice_dPoWheight",sp->alice_dPoWheight); + jaddnum(item,"alice_dPoWheight",alice->notarized); } } return(item); diff --git a/iguana/exchanges/LP_stats.c b/iguana/exchanges/LP_stats.c index 433fc8126..0e3b958fe 100644 --- a/iguana/exchanges/LP_stats.c +++ b/iguana/exchanges/LP_stats.c @@ -279,11 +279,9 @@ int32_t LP_swap_finished(struct LP_swapstats *sp,int32_t dPoWflag) sp->bobneeds_dPoW = LP_finished_lastheight(sp,1); if ( alice->isassetchain != 0 ) sp->aliceneeds_dPoW = LP_finished_lastheight(sp,0); - sp->bob_dPoWheight = LP_dPoWheight(bob); - sp->alice_dPoWheight = LP_dPoWheight(alice); - printf("bob needs %d @ %d, alice needs %d @ %d\n",sp->bobneeds_dPoW,sp->bob_dPoWheight,sp->aliceneeds_dPoW,sp->alice_dPoWheight); + 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 && sp->bob_dPoWheight >= sp->bobneeds_dPoW)) && (sp->aliceneeds_dPoW == 0 || (sp->aliceneeds_dPoW > 1 && sp->alice_dPoWheight >= sp->aliceneeds_dPoW)) ) + 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); From a27ff3e23834f1ba6d77ea8c3d2f7ded17d7c757 Mon Sep 17 00:00:00 2001 From: jl777 Date: Sun, 3 Dec 2017 16:59:29 +0400 Subject: [PATCH 1442/1664] Test --- iguana/exchanges/LP_stats.c | 20 +++++++++++++++++++- 1 file changed, 19 insertions(+), 1 deletion(-) diff --git a/iguana/exchanges/LP_stats.c b/iguana/exchanges/LP_stats.c index 0e3b958fe..3e171961a 100644 --- a/iguana/exchanges/LP_stats.c +++ b/iguana/exchanges/LP_stats.c @@ -197,7 +197,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); } @@ -233,20 +233,38 @@ int32_t LP_finished_lastheight(struct LP_swapstats *sp,int32_t iambob) if ( iambob != 0 ) { if ( bits256_nonz(sp->bobdeposit) != 0 && (ht= LP_txheight(coin,sp->bobdeposit)) > 1 && ht > height ) + { height = ht; + printf("bobdeposit.%d height.%d\n",ht,height); + } if ( bits256_nonz(sp->bobpayment) != 0 && (ht= LP_txheight(coin,sp->bobpayment)) > 1 && ht > height ) + { height = ht; + printf("bobpayment.%d height.%d\n",ht,height); + } if ( bits256_nonz(sp->paymentspent) != 0 && (ht= LP_txheight(coin,sp->paymentspent)) > 1 && ht > height ) + { height = ht; + printf("paymentspent.%d height.%d\n",ht,height); + } if ( bits256_nonz(sp->depositspent) != 0 && (ht= LP_txheight(coin,sp->depositspent)) > 1 && ht > height ) + { height = ht; + printf("depositspent.%d height.%d\n",ht,height); + } } else { if ( bits256_nonz(sp->alicepayment) != 0 && (ht= LP_txheight(coin,sp->alicepayment)) > 1 && ht > height ) + { height = ht; + printf("alicepayment.%d height.%d\n",ht,height); + } if ( bits256_nonz(sp->Apaymentspent) != 0 && (ht= LP_txheight(coin,sp->Apaymentspent)) > 1 && ht > height ) + { height = ht; + printf("Apaymentspent.%d height.%d\n",ht,height); + } } } return(height); From 28f35c69daf4ad653ef74c36a69b731976d727e2 Mon Sep 17 00:00:00 2001 From: jl777 Date: Sun, 3 Dec 2017 17:00:28 +0400 Subject: [PATCH 1443/1664] Test --- iguana/exchanges/LP_nativeDEX.c | 3 ++- iguana/exchanges/LP_stats.c | 4 ++-- 2 files changed, 4 insertions(+), 3 deletions(-) diff --git a/iguana/exchanges/LP_nativeDEX.c b/iguana/exchanges/LP_nativeDEX.c index 4163a4511..69e83e6d2 100644 --- a/iguana/exchanges/LP_nativeDEX.c +++ b/iguana/exchanges/LP_nativeDEX.c @@ -17,7 +17,7 @@ // LP_nativeDEX.c // marketmaker // -// delay swap credit back until notarization, else path +// too much stats.log // big BTC swaps // https://github.com/bitcoin/bips/blob/master/bip-0143.mediawiki for signing BCH/BTG // @@ -27,6 +27,7 @@ // portfolio value based on ask? // USD paxprice based USDvalue in portfolio // +// else claim path // improve critical section detection when parallel trades // dPoW security -> 4: KMD notarized, 5: BTC notarized, after next notary elections // bigendian architectures need to use little endian for sighash calcs diff --git a/iguana/exchanges/LP_stats.c b/iguana/exchanges/LP_stats.c index 3e171961a..c569fec67 100644 --- a/iguana/exchanges/LP_stats.c +++ b/iguana/exchanges/LP_stats.c @@ -275,12 +275,12 @@ int32_t LP_swap_finished(struct LP_swapstats *sp,int32_t dPoWflag) struct iguana_info *bob,*alice; if ( (bob= LP_coinfind(sp->Q.srccoin)) == 0 ) { - printf("no bobcoin.%s\n",sp->Q.srccoin); + //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); + //printf("no alicecoin.%s\n",sp->Q.destcoin); return(0); } if ( sp->finished == 0 ) From b3eeca47e1fe3c0fbf4220d8fd87d848f4d76e64 Mon Sep 17 00:00:00 2001 From: jl777 Date: Sun, 3 Dec 2017 17:21:07 +0400 Subject: [PATCH 1444/1664] Test --- iguana/exchanges/LP_include.h | 3 +- iguana/exchanges/LP_stats.c | 53 ++++++++++++++++++++++++++++++++--- 2 files changed, 51 insertions(+), 5 deletions(-) diff --git a/iguana/exchanges/LP_include.h b/iguana/exchanges/LP_include.h index a70137b68..29fe7cf4a 100644 --- a/iguana/exchanges/LP_include.h +++ b/iguana/exchanges/LP_include.h @@ -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 (100 * 1024 * 1024) #define LP_COMMAND_SENDSOCK NN_PUSH #define LP_COMMAND_RECVSOCK NN_PULL diff --git a/iguana/exchanges/LP_stats.c b/iguana/exchanges/LP_stats.c index c569fec67..2a323e4e3 100644 --- a/iguana/exchanges/LP_stats.c +++ b/iguana/exchanges/LP_stats.c @@ -81,13 +81,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 +96,20 @@ int32_t LP_statslog_parse() return(0); } } + else + { + 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)); + } + } + } while ( fgets(line,sizeof(line),fp) > 0 ) { lastpos = ftell(fp); @@ -472,6 +487,18 @@ 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); @@ -481,7 +508,7 @@ cJSON *LP_swapstats_json(struct LP_swapstats *sp) char *LP_swapstatus_recv(cJSON *argjson) { - struct LP_swapstats *sp; int32_t methodind; + struct LP_swapstats *sp; int32_t methodind; bits256 txid; //printf("swapstatus.(%s)\n",jprint(argjson,0)); if ( (sp= LP_swapstats_find(j64bits(argjson,"aliceid"))) != 0 ) { @@ -493,6 +520,24 @@ 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 ) + sp->bobdeposit = txid; + txid = jbits256(argjson,"alicepayment"); + if ( bits256_nonz(txid) != 0 ) + sp->alicepayment = txid; + txid = jbits256(argjson,"bobpayment"); + if ( bits256_nonz(txid) != 0 ) + sp->bobpayment = txid; + txid = jbits256(argjson,"paymentspent"); + if ( bits256_nonz(txid) != 0 ) + sp->paymentspent = txid; + txid = jbits256(argjson,"Apaymentspent"); + if ( bits256_nonz(txid) != 0 ) + sp->Apaymentspent = txid; + txid = jbits256(argjson,"depositspent"); + if ( bits256_nonz(txid) != 0 ) + sp->depositspent = txid; } } return(clonestr("{\"result\":\"success\"}")); @@ -519,7 +564,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 ) From 4c302cd2eeb63c87d34ab06b2e8905f056064086 Mon Sep 17 00:00:00 2001 From: jl777 Date: Sun, 3 Dec 2017 17:28:14 +0400 Subject: [PATCH 1445/1664] Test --- iguana/exchanges/LP_stats.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/iguana/exchanges/LP_stats.c b/iguana/exchanges/LP_stats.c index 2a323e4e3..3532472b0 100644 --- a/iguana/exchanges/LP_stats.c +++ b/iguana/exchanges/LP_stats.c @@ -96,7 +96,7 @@ int32_t LP_statslog_parse() return(0); } } - else + else if ( 0 ) { if ( IAMLP == 0 ) { From 40f61609983284adf3dcd83568acf9c33b830f7d Mon Sep 17 00:00:00 2001 From: jl777 Date: Sun, 3 Dec 2017 17:32:02 +0400 Subject: [PATCH 1446/1664] Test --- iguana/exchanges/LP_stats.c | 32 ++++++++++++++++---------------- 1 file changed, 16 insertions(+), 16 deletions(-) diff --git a/iguana/exchanges/LP_stats.c b/iguana/exchanges/LP_stats.c index 3532472b0..81643c224 100644 --- a/iguana/exchanges/LP_stats.c +++ b/iguana/exchanges/LP_stats.c @@ -302,23 +302,23 @@ int32_t LP_swap_finished(struct LP_swapstats *sp,int32_t dPoWflag) { if ( sp->expired != 0 ) return(1); - if ( dPoWflag != 0 ) + } + if ( dPoWflag != 0 ) + { + if ( sp->dPoWfinished != 0 ) + return(1); + else if ( sp->finished != 0 ) { - if ( sp->finished != 0 && sp->dPoWfinished != 0 ) - return(1); - else if ( sp->finished != 0 ) - { - if ( bob->isassetchain != 0 ) - sp->bobneeds_dPoW = LP_finished_lastheight(sp,1); - if ( alice->isassetchain != 0 ) - sp->aliceneeds_dPoW = LP_finished_lastheight(sp,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); - } + if ( bob->isassetchain != 0 ) + sp->bobneeds_dPoW = LP_finished_lastheight(sp,1); + if ( alice->isassetchain != 0 ) + sp->aliceneeds_dPoW = LP_finished_lastheight(sp,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); From 558edc90e4cc172603cf4b233e0b9e8b88605e29 Mon Sep 17 00:00:00 2001 From: jl777 Date: Sun, 3 Dec 2017 17:39:30 +0400 Subject: [PATCH 1447/1664] Test --- iguana/exchanges/LP_stats.c | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/iguana/exchanges/LP_stats.c b/iguana/exchanges/LP_stats.c index 81643c224..9024f9ef4 100644 --- a/iguana/exchanges/LP_stats.c +++ b/iguana/exchanges/LP_stats.c @@ -250,22 +250,22 @@ int32_t LP_finished_lastheight(struct LP_swapstats *sp,int32_t iambob) if ( bits256_nonz(sp->bobdeposit) != 0 && (ht= LP_txheight(coin,sp->bobdeposit)) > 1 && ht > height ) { height = ht; - printf("bobdeposit.%d height.%d\n",ht,height); + //printf("bobdeposit.%d height.%d\n",ht,height); } if ( bits256_nonz(sp->bobpayment) != 0 && (ht= LP_txheight(coin,sp->bobpayment)) > 1 && ht > height ) { height = ht; - printf("bobpayment.%d height.%d\n",ht,height); + //printf("bobpayment.%d height.%d\n",ht,height); } if ( bits256_nonz(sp->paymentspent) != 0 && (ht= LP_txheight(coin,sp->paymentspent)) > 1 && ht > height ) { height = ht; - printf("paymentspent.%d height.%d\n",ht,height); + //printf("paymentspent.%d height.%d\n",ht,height); } if ( bits256_nonz(sp->depositspent) != 0 && (ht= LP_txheight(coin,sp->depositspent)) > 1 && ht > height ) { height = ht; - printf("depositspent.%d height.%d\n",ht,height); + //printf("depositspent.%d height.%d\n",ht,height); } } else @@ -509,9 +509,9 @@ cJSON *LP_swapstats_json(struct LP_swapstats *sp) char *LP_swapstatus_recv(cJSON *argjson) { struct LP_swapstats *sp; int32_t methodind; bits256 txid; - //printf("swapstatus.(%s)\n",jprint(argjson,0)); if ( (sp= LP_swapstats_find(j64bits(argjson,"aliceid"))) != 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) ) { From 886a4962e513f1da1a4a7ea6f7e550d0a9d42ffb Mon Sep 17 00:00:00 2001 From: jl777 Date: Sun, 3 Dec 2017 17:44:32 +0400 Subject: [PATCH 1448/1664] Test --- iguana/exchanges/LP_stats.c | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/iguana/exchanges/LP_stats.c b/iguana/exchanges/LP_stats.c index 9024f9ef4..728f2538a 100644 --- a/iguana/exchanges/LP_stats.c +++ b/iguana/exchanges/LP_stats.c @@ -309,11 +309,12 @@ int32_t LP_swap_finished(struct LP_swapstats *sp,int32_t dPoWflag) return(1); else if ( sp->finished != 0 ) { - if ( bob->isassetchain != 0 ) + if ( bob->isassetchain != 0 || strcmp(sp->Q.srccoin,"KMD") == 0 ) sp->bobneeds_dPoW = LP_finished_lastheight(sp,1); - if ( alice->isassetchain != 0 ) + if ( alice->isassetchain != 0 || strcmp(sp->Q.destcoin,"KMD") == 0 ) sp->aliceneeds_dPoW = LP_finished_lastheight(sp,0); - printf("bob needs %d @ %d, alice needs %d @ %d\n",sp->bobneeds_dPoW,bob->notarized,sp->aliceneeds_dPoW,alice->notarized); + if ( 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)) ) { @@ -511,7 +512,8 @@ char *LP_swapstatus_recv(cJSON *argjson) struct LP_swapstats *sp; int32_t methodind; bits256 txid; if ( (sp= LP_swapstats_find(j64bits(argjson,"aliceid"))) != 0 ) { - printf("swapstatus.(%s)\n",jprint(argjson,0)); + if ( 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) ) { From 703a2fd0412d16f9b3de3e1e9662d0a824dfd4c5 Mon Sep 17 00:00:00 2001 From: jl777 Date: Sun, 3 Dec 2017 17:56:08 +0400 Subject: [PATCH 1449/1664] Test --- iguana/exchanges/LP_include.h | 2 +- iguana/exchanges/LP_instantdex.c | 9 ++++++++- 2 files changed, 9 insertions(+), 2 deletions(-) diff --git a/iguana/exchanges/LP_include.h b/iguana/exchanges/LP_include.h index 29fe7cf4a..7b78ed2bf 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 diff --git a/iguana/exchanges/LP_instantdex.c b/iguana/exchanges/LP_instantdex.c index 0e482e6c9..6e2b9f328 100644 --- a/iguana/exchanges/LP_instantdex.c +++ b/iguana/exchanges/LP_instantdex.c @@ -447,7 +447,8 @@ int64_t LP_myzcredits() cJSON *LP_swapstats_item(struct LP_swapstats *sp,int32_t iambob) { - struct iguana_info *bob,*alice; cJSON *item = cJSON_CreateObject(); + struct iguana_info *bob,*alice; int32_t flag = 0; cJSON *item; char *retstr; + item = cJSON_CreateObject(); jaddnum(item,"iambob",iambob); jaddnum(item,"aliceid",sp->aliceid); jaddnum(item,"requestid",sp->Q.R.requestid); @@ -464,12 +465,18 @@ cJSON *LP_swapstats_item(struct LP_swapstats *sp,int32_t iambob) { jaddnum(item,"bobneeds_dPoW",sp->bobneeds_dPoW); jaddnum(item,"bob_dPoWheight",bob->notarized); + if ( sp->bobneeds_dPoW == 1 ) + flag = 1; } 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 ( flag != 0 && (retstr= LP_gettradestatus(sp->aliceid)) != 0 ) + free(retstr); } return(item); } From 6f6466e5f84a795f66a9f18bbe55581a70c7a6c9 Mon Sep 17 00:00:00 2001 From: jl777 Date: Sun, 3 Dec 2017 18:03:27 +0400 Subject: [PATCH 1450/1664] Test --- iguana/exchanges/LP_stats.c | 38 +++++++++++++++++++++---------------- 1 file changed, 22 insertions(+), 16 deletions(-) diff --git a/iguana/exchanges/LP_stats.c b/iguana/exchanges/LP_stats.c index 728f2538a..52e9bbf8c 100644 --- a/iguana/exchanges/LP_stats.c +++ b/iguana/exchanges/LP_stats.c @@ -247,37 +247,43 @@ int32_t LP_finished_lastheight(struct LP_swapstats *sp,int32_t iambob) { if ( iambob != 0 ) { - if ( bits256_nonz(sp->bobdeposit) != 0 && (ht= LP_txheight(coin,sp->bobdeposit)) > 1 && ht > height ) + if ( bits256_nonz(sp->bobdeposit) != 0 && (ht= LP_txheight(coin,sp->bobdeposit)) > 1 ) { - height = ht; - //printf("bobdeposit.%d height.%d\n",ht,height); + if ( ht > height ) + height = ht; + printf("bobdeposit.%d height.%d\n",ht,height); } - if ( bits256_nonz(sp->bobpayment) != 0 && (ht= LP_txheight(coin,sp->bobpayment)) > 1 && ht > height ) + if ( bits256_nonz(sp->bobpayment) != 0 && (ht= LP_txheight(coin,sp->bobpayment)) > 1 ) { - height = ht; - //printf("bobpayment.%d height.%d\n",ht,height); + if ( ht > height ) + height = ht; + printf("bobpayment.%d height.%d\n",ht,height); } - if ( bits256_nonz(sp->paymentspent) != 0 && (ht= LP_txheight(coin,sp->paymentspent)) > 1 && ht > height ) + if ( bits256_nonz(sp->paymentspent) != 0 && (ht= LP_txheight(coin,sp->paymentspent)) > 1 ) { - height = ht; - //printf("paymentspent.%d height.%d\n",ht,height); + if ( ht > height ) + height = ht; + printf("paymentspent.%d height.%d\n",ht,height); } - if ( bits256_nonz(sp->depositspent) != 0 && (ht= LP_txheight(coin,sp->depositspent)) > 1 && ht > height ) + if ( bits256_nonz(sp->depositspent) != 0 && (ht= LP_txheight(coin,sp->depositspent)) > 1 ) { - height = ht; - //printf("depositspent.%d height.%d\n",ht,height); + if ( ht > height ) + height = ht; + printf("depositspent.%d height.%d\n",ht,height); } } else { - if ( bits256_nonz(sp->alicepayment) != 0 && (ht= LP_txheight(coin,sp->alicepayment)) > 1 && ht > height ) + if ( bits256_nonz(sp->alicepayment) != 0 && (ht= LP_txheight(coin,sp->alicepayment)) > 1 ) { - height = ht; + if ( ht > height ) + height = ht; printf("alicepayment.%d height.%d\n",ht,height); } - if ( bits256_nonz(sp->Apaymentspent) != 0 && (ht= LP_txheight(coin,sp->Apaymentspent)) > 1 && ht > height ) + if ( bits256_nonz(sp->Apaymentspent) != 0 && (ht= LP_txheight(coin,sp->Apaymentspent)) > 1 ) { - height = ht; + if ( ht > height ) + height = ht; printf("Apaymentspent.%d height.%d\n",ht,height); } } From 9ede5b54ba102cc2d91a54a7bd900dd81368ded8 Mon Sep 17 00:00:00 2001 From: jl777 Date: Sun, 3 Dec 2017 18:09:48 +0400 Subject: [PATCH 1451/1664] Test --- iguana/exchanges/LP_stats.c | 63 ++++++++++++++++++------------------- 1 file changed, 30 insertions(+), 33 deletions(-) diff --git a/iguana/exchanges/LP_stats.c b/iguana/exchanges/LP_stats.c index 52e9bbf8c..20621d40c 100644 --- a/iguana/exchanges/LP_stats.c +++ b/iguana/exchanges/LP_stats.c @@ -240,51 +240,51 @@ int32_t LP_dPoWheight(struct iguana_info *coin) // get dPoW protected height return(coin->notarized); } -int32_t LP_finished_lastheight(struct LP_swapstats *sp,int32_t iambob) +int32_t LP_finished_lastheight(struct LP_swapstats *sp) { - int32_t ht,height = 1; struct iguana_info *coin; - if ( (coin= LP_coinfind(iambob != 0 ? sp->Q.srccoin : sp->Q.destcoin)) != 0 ) + int32_t ht,height = 1; struct iguana_info *bob,*alice; + if ( (bob= LP_coinfind(sp->Q.srccoin)) != 0 && (alice= LP_coinfind(sp->Q.destcoin)) != 0 ) { - if ( iambob != 0 ) + if ( sp->bobneeds_dPoW != 0 ) { - if ( bits256_nonz(sp->bobdeposit) != 0 && (ht= LP_txheight(coin,sp->bobdeposit)) > 1 ) + if ( bits256_nonz(sp->bobdeposit) != 0 && (ht= LP_txheight(bob,sp->bobdeposit)) > 1 ) { - if ( ht > height ) - height = ht; - printf("bobdeposit.%d height.%d\n",ht,height); + if ( ht > sp->bobneeds_dPoW ) + sp->bobneeds_dPoW = ht; + printf("bobdeposit.%d height.%d\n",ht,sp->bobneeds_dPoW); } - if ( bits256_nonz(sp->bobpayment) != 0 && (ht= LP_txheight(coin,sp->bobpayment)) > 1 ) + if ( bits256_nonz(sp->bobpayment) != 0 && (ht= LP_txheight(bob,sp->bobpayment)) > 1 ) { - if ( ht > height ) - height = ht; - printf("bobpayment.%d height.%d\n",ht,height); + if ( ht > sp->bobneeds_dPoW ) + sp->bobneeds_dPoW = ht; + printf("bobpayment.%d height.%d\n",ht,sp->bobneeds_dPoW); } - if ( bits256_nonz(sp->paymentspent) != 0 && (ht= LP_txheight(coin,sp->paymentspent)) > 1 ) + if ( bits256_nonz(sp->paymentspent) != 0 && (ht= LP_txheight(bob,sp->paymentspent)) > 1 ) { - if ( ht > height ) - height = ht; - printf("paymentspent.%d height.%d\n",ht,height); + if ( ht > sp->bobneeds_dPoW ) + sp->bobneeds_dPoW = ht; + printf("paymentspent.%d height.%d\n",ht,sp->bobneeds_dPoW); } - if ( bits256_nonz(sp->depositspent) != 0 && (ht= LP_txheight(coin,sp->depositspent)) > 1 ) + if ( bits256_nonz(sp->depositspent) != 0 && (ht= LP_txheight(bob,sp->depositspent)) > 1 ) { - if ( ht > height ) - height = ht; - printf("depositspent.%d height.%d\n",ht,height); + if ( ht > sp->bobneeds_dPoW ) + sp->bobneeds_dPoW = ht; + printf("depositspent.%d height.%d\n",ht,sp->bobneeds_dPoW); } } - else + if ( sp->aliceneeds_dPoW != 0 ) { - if ( bits256_nonz(sp->alicepayment) != 0 && (ht= LP_txheight(coin,sp->alicepayment)) > 1 ) + if ( bits256_nonz(sp->alicepayment) != 0 && (ht= LP_txheight(alice,sp->alicepayment)) > 1 ) { - if ( ht > height ) - height = ht; - printf("alicepayment.%d height.%d\n",ht,height); + if ( ht > sp->aliceneeds_dPoW ) + sp->aliceneeds_dPoW = ht; + printf("alicepayment.%d height.%d\n",ht,sp->aliceneeds_dPoW); } - if ( bits256_nonz(sp->Apaymentspent) != 0 && (ht= LP_txheight(coin,sp->Apaymentspent)) > 1 ) + if ( bits256_nonz(sp->Apaymentspent) != 0 && (ht= LP_txheight(alice,sp->Apaymentspent)) > 1 ) { - if ( ht > height ) - height = ht; - printf("Apaymentspent.%d height.%d\n",ht,height); + if ( ht > sp->aliceneeds_dPoW ) + sp->aliceneeds_dPoW = ht; + printf("Apaymentspent.%d height.%d\n",ht,sp->aliceneeds_dPoW); } } } @@ -315,10 +315,7 @@ int32_t LP_swap_finished(struct LP_swapstats *sp,int32_t dPoWflag) return(1); else if ( sp->finished != 0 ) { - if ( bob->isassetchain != 0 || strcmp(sp->Q.srccoin,"KMD") == 0 ) - sp->bobneeds_dPoW = LP_finished_lastheight(sp,1); - if ( alice->isassetchain != 0 || strcmp(sp->Q.destcoin,"KMD") == 0 ) - sp->aliceneeds_dPoW = LP_finished_lastheight(sp,0); + LP_finished_lastheight(sp); if ( IAMLP == 0 ) printf("bob needs %d @ %d, alice needs %d @ %d\n",sp->bobneeds_dPoW,bob->notarized,sp->aliceneeds_dPoW,alice->notarized); } From 11da38de0e83e56399611ffb1dff4fb6b68f66d3 Mon Sep 17 00:00:00 2001 From: jl777 Date: Sun, 3 Dec 2017 18:22:09 +0400 Subject: [PATCH 1452/1664] Test --- iguana/exchanges/LP_stats.c | 72 +++++++++++++++++++++++-------------- 1 file changed, 45 insertions(+), 27 deletions(-) diff --git a/iguana/exchanges/LP_stats.c b/iguana/exchanges/LP_stats.c index 20621d40c..b053ea352 100644 --- a/iguana/exchanges/LP_stats.c +++ b/iguana/exchanges/LP_stats.c @@ -242,49 +242,49 @@ int32_t LP_dPoWheight(struct iguana_info *coin) // get dPoW protected height int32_t LP_finished_lastheight(struct LP_swapstats *sp) { - int32_t ht,height = 1; struct iguana_info *bob,*alice; + int32_t ht,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 && (ht= LP_txheight(bob,sp->bobdeposit)) > 1 ) + if ( bits256_nonz(sp->bobdeposit) != 0 ) { - if ( ht > sp->bobneeds_dPoW ) + if ( (ht= LP_txheight(bob,sp->bobdeposit)) > sp->bobneeds_dPoW ) sp->bobneeds_dPoW = ht; - printf("bobdeposit.%d height.%d\n",ht,sp->bobneeds_dPoW); + printf("%s bobdeposit.%d height.%d\n",bits256_str(str,sp->bobdeposit),ht,sp->bobneeds_dPoW); } - if ( bits256_nonz(sp->bobpayment) != 0 && (ht= LP_txheight(bob,sp->bobpayment)) > 1 ) + if ( bits256_nonz(sp->bobpayment) != 0 ) { - if ( ht > sp->bobneeds_dPoW ) + if ( (ht= LP_txheight(bob,sp->bobpayment)) > sp->bobneeds_dPoW ) sp->bobneeds_dPoW = ht; - printf("bobpayment.%d height.%d\n",ht,sp->bobneeds_dPoW); + printf("%s bobpayment.%d height.%d\n",bits256_str(str,sp->bobpayment),ht,sp->bobneeds_dPoW); } - if ( bits256_nonz(sp->paymentspent) != 0 && (ht= LP_txheight(bob,sp->paymentspent)) > 1 ) + if ( bits256_nonz(sp->paymentspent) != 0 ) { - if ( ht > sp->bobneeds_dPoW ) + if ( (ht= LP_txheight(bob,sp->paymentspent)) > sp->bobneeds_dPoW ) sp->bobneeds_dPoW = ht; - printf("paymentspent.%d height.%d\n",ht,sp->bobneeds_dPoW); + printf("%s paymentspent.%d height.%d\n",bits256_str(str,sp->paymentspent),ht,sp->bobneeds_dPoW); } - if ( bits256_nonz(sp->depositspent) != 0 && (ht= LP_txheight(bob,sp->depositspent)) > 1 ) + if ( bits256_nonz(sp->depositspent) != 0 ) { - if ( ht > sp->bobneeds_dPoW ) + if ( (ht= LP_txheight(bob,sp->depositspent)) > sp->bobneeds_dPoW ) sp->bobneeds_dPoW = ht; - printf("depositspent.%d height.%d\n",ht,sp->bobneeds_dPoW); + 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 && (ht= LP_txheight(alice,sp->alicepayment)) > 1 ) + if ( bits256_nonz(sp->alicepayment) != 0 ) { - if ( ht > sp->aliceneeds_dPoW ) + if ( (ht= LP_txheight(alice,sp->alicepayment)) > sp->aliceneeds_dPoW ) sp->aliceneeds_dPoW = ht; - printf("alicepayment.%d height.%d\n",ht,sp->aliceneeds_dPoW); + printf("%s alicepayment.%d height.%d\n",bits256_str(str,sp->alicepayment),ht,sp->aliceneeds_dPoW); } - if ( bits256_nonz(sp->Apaymentspent) != 0 && (ht= LP_txheight(alice,sp->Apaymentspent)) > 1 ) + if ( bits256_nonz(sp->Apaymentspent) != 0 ) { - if ( ht > sp->aliceneeds_dPoW ) + if ( (ht= LP_txheight(alice,sp->Apaymentspent)) > sp->aliceneeds_dPoW ) sp->aliceneeds_dPoW = ht; - printf("Apaymentspent.%d height.%d\n",ht,sp->aliceneeds_dPoW); + printf("%s Apaymentspent.%d height.%d\n",bits256_str(str,sp->Apaymentspent),ht,sp->aliceneeds_dPoW); } } } @@ -512,7 +512,7 @@ cJSON *LP_swapstats_json(struct LP_swapstats *sp) char *LP_swapstatus_recv(cJSON *argjson) { - struct LP_swapstats *sp; int32_t methodind; bits256 txid; + struct LP_swapstats *sp; int32_t methodind; bits256 txid; char str[65]; if ( (sp= LP_swapstats_find(j64bits(argjson,"aliceid"))) != 0 ) { if ( IAMLP == 0 ) @@ -526,23 +526,41 @@ char *LP_swapstatus_recv(cJSON *argjson) sp->finished = juint(argjson,"finished"); sp->expired = juint(argjson,"expired"); txid = jbits256(argjson,"bobdeposit"); - if ( bits256_nonz(txid) != 0 ) + 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 ) + 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 ) + 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 ) + 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 ) - sp->Apaymentspent = txid; + 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 ) + 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\"}")); From f00f9247b8663af78c477da4680b2620d2b14fad Mon Sep 17 00:00:00 2001 From: jl777 Date: Sun, 3 Dec 2017 18:27:37 +0400 Subject: [PATCH 1453/1664] Test --- iguana/exchanges/LP_rpc.c | 2 +- iguana/exchanges/LP_stats.c | 14 +++++++------- 2 files changed, 8 insertions(+), 8 deletions(-) diff --git a/iguana/exchanges/LP_rpc.c b/iguana/exchanges/LP_rpc.c index 169192f54..d84369890 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 ) { diff --git a/iguana/exchanges/LP_stats.c b/iguana/exchanges/LP_stats.c index b053ea352..5cc3fdb8a 100644 --- a/iguana/exchanges/LP_stats.c +++ b/iguana/exchanges/LP_stats.c @@ -242,7 +242,7 @@ int32_t LP_dPoWheight(struct iguana_info *coin) // get dPoW protected height int32_t LP_finished_lastheight(struct LP_swapstats *sp) { - int32_t ht,height = 1; struct iguana_info *bob,*alice; char str[65]; + int32_t ht,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 ) @@ -251,25 +251,25 @@ int32_t LP_finished_lastheight(struct LP_swapstats *sp) { if ( (ht= LP_txheight(bob,sp->bobdeposit)) > sp->bobneeds_dPoW ) sp->bobneeds_dPoW = ht; - printf("%s bobdeposit.%d height.%d\n",bits256_str(str,sp->bobdeposit),ht,sp->bobneeds_dPoW); + //printf("%s bobdeposit.%d height.%d\n",bits256_str(str,sp->bobdeposit),ht,sp->bobneeds_dPoW); } if ( bits256_nonz(sp->bobpayment) != 0 ) { if ( (ht= LP_txheight(bob,sp->bobpayment)) > sp->bobneeds_dPoW ) sp->bobneeds_dPoW = ht; - printf("%s bobpayment.%d height.%d\n",bits256_str(str,sp->bobpayment),ht,sp->bobneeds_dPoW); + //printf("%s bobpayment.%d height.%d\n",bits256_str(str,sp->bobpayment),ht,sp->bobneeds_dPoW); } if ( bits256_nonz(sp->paymentspent) != 0 ) { if ( (ht= LP_txheight(bob,sp->paymentspent)) > sp->bobneeds_dPoW ) sp->bobneeds_dPoW = ht; - printf("%s paymentspent.%d height.%d\n",bits256_str(str,sp->paymentspent),ht,sp->bobneeds_dPoW); + //printf("%s paymentspent.%d height.%d\n",bits256_str(str,sp->paymentspent),ht,sp->bobneeds_dPoW); } if ( bits256_nonz(sp->depositspent) != 0 ) { if ( (ht= LP_txheight(bob,sp->depositspent)) > sp->bobneeds_dPoW ) sp->bobneeds_dPoW = ht; - printf("%s depositspent.%d height.%d\n",bits256_str(str,sp->depositspent),ht,sp->bobneeds_dPoW); + //printf("%s depositspent.%d height.%d\n",bits256_str(str,sp->depositspent),ht,sp->bobneeds_dPoW); } } if ( sp->aliceneeds_dPoW != 0 ) @@ -278,13 +278,13 @@ int32_t LP_finished_lastheight(struct LP_swapstats *sp) { if ( (ht= LP_txheight(alice,sp->alicepayment)) > sp->aliceneeds_dPoW ) sp->aliceneeds_dPoW = ht; - printf("%s alicepayment.%d height.%d\n",bits256_str(str,sp->alicepayment),ht,sp->aliceneeds_dPoW); + //printf("%s alicepayment.%d height.%d\n",bits256_str(str,sp->alicepayment),ht,sp->aliceneeds_dPoW); } if ( bits256_nonz(sp->Apaymentspent) != 0 ) { if ( (ht= LP_txheight(alice,sp->Apaymentspent)) > sp->aliceneeds_dPoW ) sp->aliceneeds_dPoW = ht; - printf("%s Apaymentspent.%d height.%d\n",bits256_str(str,sp->Apaymentspent),ht,sp->aliceneeds_dPoW); + //printf("%s Apaymentspent.%d height.%d\n",bits256_str(str,sp->Apaymentspent),ht,sp->aliceneeds_dPoW); } } } From 96c9018ef0637fdc1a960ccd5f990be238a05ee4 Mon Sep 17 00:00:00 2001 From: jl777 Date: Sun, 3 Dec 2017 18:31:34 +0400 Subject: [PATCH 1454/1664] Test --- iguana/exchanges/LP_stats.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/iguana/exchanges/LP_stats.c b/iguana/exchanges/LP_stats.c index 5cc3fdb8a..5476f8267 100644 --- a/iguana/exchanges/LP_stats.c +++ b/iguana/exchanges/LP_stats.c @@ -316,7 +316,7 @@ int32_t LP_swap_finished(struct LP_swapstats *sp,int32_t dPoWflag) else if ( sp->finished != 0 ) { LP_finished_lastheight(sp); - if ( IAMLP == 0 ) + 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)) ) @@ -515,7 +515,7 @@ char *LP_swapstatus_recv(cJSON *argjson) struct LP_swapstats *sp; int32_t methodind; bits256 txid; char str[65]; if ( (sp= LP_swapstats_find(j64bits(argjson,"aliceid"))) != 0 ) { - if ( IAMLP == 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) ) From 1c1a622741da10c3133cde83ae5f43f4480c815d Mon Sep 17 00:00:00 2001 From: jl777 Date: Sun, 3 Dec 2017 18:44:54 +0400 Subject: [PATCH 1455/1664] Test --- iguana/exchanges/LP_include.h | 1 + iguana/exchanges/LP_stats.c | 51 +++++++++++++++++------------------ 2 files changed, 25 insertions(+), 27 deletions(-) diff --git a/iguana/exchanges/LP_include.h b/iguana/exchanges/LP_include.h index 7b78ed2bf..0f7a17e7e 100644 --- a/iguana/exchanges/LP_include.h +++ b/iguana/exchanges/LP_include.h @@ -402,6 +402,7 @@ 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; int32_t bobneeds_dPoW,aliceneeds_dPoW; diff --git a/iguana/exchanges/LP_stats.c b/iguana/exchanges/LP_stats.c index 5476f8267..b8cac3d38 100644 --- a/iguana/exchanges/LP_stats.c +++ b/iguana/exchanges/LP_stats.c @@ -242,48 +242,48 @@ int32_t LP_dPoWheight(struct iguana_info *coin) // get dPoW protected height int32_t LP_finished_lastheight(struct LP_swapstats *sp) { - int32_t ht,height = 1; struct iguana_info *bob,*alice; //char str[65]; + 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 ) + if ( bits256_nonz(sp->bobdeposit) != 0 && sp->bobdeposit_ht == 0 ) { - if ( (ht= LP_txheight(bob,sp->bobdeposit)) > sp->bobneeds_dPoW ) - sp->bobneeds_dPoW = ht; + 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 ) + if ( bits256_nonz(sp->bobpayment) != 0 && sp->bobpayment_ht == 0 ) { - if ( (ht= LP_txheight(bob,sp->bobpayment)) > sp->bobneeds_dPoW ) - sp->bobneeds_dPoW = ht; + 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 ) + if ( bits256_nonz(sp->paymentspent) != 0 && sp->paymentspent_ht == 0 ) { - if ( (ht= LP_txheight(bob,sp->paymentspent)) > sp->bobneeds_dPoW ) - sp->bobneeds_dPoW = ht; + 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 ) + if ( bits256_nonz(sp->depositspent) != 0 && sp->depositspent_ht == 0 ) { - if ( (ht= LP_txheight(bob,sp->depositspent)) > sp->bobneeds_dPoW ) - sp->bobneeds_dPoW = ht; + 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 ) + if ( bits256_nonz(sp->alicepayment) != 0 && sp->alicepayment_ht == 0 ) { - if ( (ht= LP_txheight(alice,sp->alicepayment)) > sp->aliceneeds_dPoW ) - sp->aliceneeds_dPoW = ht; + 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 ) + if ( bits256_nonz(sp->Apaymentspent) != 0 && sp->Apaymentspent_ht == 0 ) { - if ( (ht= LP_txheight(alice,sp->Apaymentspent)) > sp->aliceneeds_dPoW ) - sp->aliceneeds_dPoW = ht; + 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); } } @@ -294,6 +294,10 @@ int32_t LP_finished_lastheight(struct LP_swapstats *sp) 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); @@ -304,16 +308,9 @@ int32_t LP_swap_finished(struct LP_swapstats *sp,int32_t dPoWflag) //printf("no alicecoin.%s\n",sp->Q.destcoin); return(0); } - if ( sp->finished == 0 ) - { - if ( sp->expired != 0 ) - return(1); - } if ( dPoWflag != 0 ) { - if ( sp->dPoWfinished != 0 ) - return(1); - else if ( sp->finished != 0 ) + if ( sp->finished != 0 ) { LP_finished_lastheight(sp); if ( 0 && IAMLP == 0 ) From 9321ab763d72c4902a4c8d03478508d120907e32 Mon Sep 17 00:00:00 2001 From: jl777 Date: Sun, 3 Dec 2017 18:59:53 +0400 Subject: [PATCH 1456/1664] Test --- iguana/exchanges/LP_stats.c | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/iguana/exchanges/LP_stats.c b/iguana/exchanges/LP_stats.c index b8cac3d38..36fd25825 100644 --- a/iguana/exchanges/LP_stats.c +++ b/iguana/exchanges/LP_stats.c @@ -526,37 +526,37 @@ char *LP_swapstatus_recv(cJSON *argjson) 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)); + //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)); + //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)); + //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)); + //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)); + 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)); + //printf("set aliceid.%llu depositspent %s\n",(long long)sp->aliceid,bits256_str(str,txid)); } } } From 2dfd937f906006337e850d41cd86fce1a9a4cc70 Mon Sep 17 00:00:00 2001 From: jl777 Date: Sun, 3 Dec 2017 21:10:51 +0400 Subject: [PATCH 1457/1664] Test --- iguana/exchanges/LP_RTmetrics.c | 2 +- iguana/exchanges/LP_commands.c | 12 ++- iguana/exchanges/LP_include.h | 2 +- iguana/exchanges/LP_instantdex.c | 12 ++- iguana/exchanges/LP_nativeDEX.c | 4 +- iguana/exchanges/LP_ordermatch.c | 4 +- iguana/exchanges/LP_prices.c | 4 +- iguana/exchanges/LP_remember.c | 29 ++++--- iguana/exchanges/LP_stats.c | 135 ++++++++++++++++++++----------- iguana/exchanges/LP_swap.c | 4 +- iguana/exchanges/LP_tradebots.c | 2 +- 11 files changed, 131 insertions(+), 79 deletions(-) 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_commands.c b/iguana/exchanges/LP_commands.c index bb05f3cf3..2c9a378d5 100644 --- a/iguana/exchanges/LP_commands.c +++ b/iguana/exchanges/LP_commands.c @@ -288,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 ) { @@ -603,14 +603,10 @@ instantdex_claim()\n\ } argjson = reqjson; } - if ( strcmp(method,"gettradestatus") == 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)); } @@ -618,6 +614,8 @@ instantdex_claim()\n\ // 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 ) diff --git a/iguana/exchanges/LP_include.h b/iguana/exchanges/LP_include.h index 0f7a17e7e..d6b484d05 100644 --- a/iguana/exchanges/LP_include.h +++ b/iguana/exchanges/LP_include.h @@ -516,7 +516,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 6e2b9f328..176c4abd0 100644 --- a/iguana/exchanges/LP_instantdex.c +++ b/iguana/exchanges/LP_instantdex.c @@ -447,7 +447,7 @@ int64_t LP_myzcredits() cJSON *LP_swapstats_item(struct LP_swapstats *sp,int32_t iambob) { - struct iguana_info *bob,*alice; int32_t flag = 0; cJSON *item; char *retstr; + struct iguana_info *bob,*alice; int32_t flag = 0; bits256 zero; cJSON *item,*reqjson; item = cJSON_CreateObject(); jaddnum(item,"iambob",iambob); jaddnum(item,"aliceid",sp->aliceid); @@ -475,8 +475,14 @@ cJSON *LP_swapstats_item(struct LP_swapstats *sp,int32_t iambob) if ( sp->aliceneeds_dPoW == 1 ) flag = 1; } - if ( flag != 0 && (retstr= LP_gettradestatus(sp->aliceid)) != 0 ) - free(retstr); + 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)); + } } return(item); } diff --git a/iguana/exchanges/LP_nativeDEX.c b/iguana/exchanges/LP_nativeDEX.c index 69e83e6d2..cf09af1b6 100644 --- a/iguana/exchanges/LP_nativeDEX.c +++ b/iguana/exchanges/LP_nativeDEX.c @@ -816,7 +816,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); } @@ -1319,7 +1319,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 fa911b330..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) { 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_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_stats.c b/iguana/exchanges/LP_stats.c index 36fd25825..7d7ee1fba 100644 --- a/iguana/exchanges/LP_stats.c +++ b/iguana/exchanges/LP_stats.c @@ -24,6 +24,7 @@ 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; @@ -325,10 +326,51 @@ int32_t LP_swap_finished(struct LP_swapstats *sp,int32_t dPoWflag) 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 iguana_info *alice,*bob; 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)); @@ -423,41 +465,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); - 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(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 ) { @@ -509,8 +518,22 @@ cJSON *LP_swapstats_json(struct LP_swapstats *sp) char *LP_swapstatus_recv(cJSON *argjson) { - struct LP_swapstats *sp; int32_t methodind; bits256 txid; char str[65]; - 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)); @@ -563,20 +586,42 @@ char *LP_swapstatus_recv(cJSON *argjson) 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; 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 ( (reqjson= LP_swapstats_json(sp)) != 0 ) + if ( (sp= LP_swapstats_find(aliceid)) != 0 ) { - jaddstr(reqjson,"method","swapstatus"); - memset(zero.bytes,0,sizeof(zero)); - LP_reserved_msg(0,"","",zero,jprint(reqjson,1)); + 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)); + } + } + return(clonestr("{\"result\":\"success\"}")); + } + } + if ( (swapstr= basilisk_swapentry(requestid,quoteid,0)) != 0 ) + { + if ( (swapjson= cJSON_Parse(swapstr)) != 0 ) + { + 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) 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 ) From 16143707cd5cdbb30664c69f9d7cf767c6814515 Mon Sep 17 00:00:00 2001 From: jl777 Date: Sun, 3 Dec 2017 21:15:05 +0400 Subject: [PATCH 1458/1664] Test --- iguana/exchanges/LP_stats.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/iguana/exchanges/LP_stats.c b/iguana/exchanges/LP_stats.c index 7d7ee1fba..c63b08957 100644 --- a/iguana/exchanges/LP_stats.c +++ b/iguana/exchanges/LP_stats.c @@ -535,7 +535,7 @@ char *LP_swapstatus_recv(cJSON *argjson) } if ( sp != 0 ) { - if ( 0 && IAMLP == 0 ) + if ( 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) ) @@ -589,7 +589,7 @@ char *LP_swapstatus_recv(cJSON *argjson) char *LP_gettradestatus(uint64_t aliceid,uint32_t requestid,uint32_t quoteid) { struct LP_swapstats *sp; char *swapstr,*statusstr; cJSON *reqjson,*swapjson; bits256 zero; - //printf("gettradestatus.(%llu)\n",(long long)aliceid); + printf("gettradestatus.(%llu)\n",(long long)aliceid); if ( IAMLP != 0 ) { if ( (sp= LP_swapstats_find(aliceid)) != 0 ) From 3d01e764aad396e3648f394c5d7c63255541c57f Mon Sep 17 00:00:00 2001 From: jl777 Date: Sun, 3 Dec 2017 21:22:59 +0400 Subject: [PATCH 1459/1664] Test --- iguana/exchanges/LP_instantdex.c | 12 +++++++++++- iguana/exchanges/LP_stats.c | 12 ++++++------ 2 files changed, 17 insertions(+), 7 deletions(-) diff --git a/iguana/exchanges/LP_instantdex.c b/iguana/exchanges/LP_instantdex.c index 176c4abd0..9cbcdca45 100644 --- a/iguana/exchanges/LP_instantdex.c +++ b/iguana/exchanges/LP_instantdex.c @@ -447,7 +447,7 @@ int64_t LP_myzcredits() cJSON *LP_swapstats_item(struct LP_swapstats *sp,int32_t iambob) { - struct iguana_info *bob,*alice; int32_t flag = 0; bits256 zero; cJSON *item,*reqjson; + 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); @@ -482,6 +482,16 @@ cJSON *LP_swapstats_item(struct LP_swapstats *sp,int32_t iambob) 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,1)) != 0 ) + { + if ( (swapjson= cJSON_Parse(swapstr)) != 0 ) + { + if ( (retstr= LP_swapstatus_recv(swapjson)) != 0 ) + free(retstr); + free_json(swapjson); + } + free(swapstr); + } } } return(item); diff --git a/iguana/exchanges/LP_stats.c b/iguana/exchanges/LP_stats.c index c63b08957..cd250dcfe 100644 --- a/iguana/exchanges/LP_stats.c +++ b/iguana/exchanges/LP_stats.c @@ -518,7 +518,7 @@ cJSON *LP_swapstats_json(struct LP_swapstats *sp) char *LP_swapstatus_recv(cJSON *argjson) { - struct LP_swapstats *sp; char *statusstr; uint64_t aliceid; double qprice; struct LP_quoteinfo Q; int32_t methodind,RTflag; bits256 txid; //char str[65]; + 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 ) @@ -549,31 +549,31 @@ char *LP_swapstatus_recv(cJSON *argjson) 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)); + 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)); + 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)); + 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)); + 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)); + 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 ) From 20e3c0ebe67a2a981ac2515059256c70a782eff8 Mon Sep 17 00:00:00 2001 From: jl777 Date: Sun, 3 Dec 2017 21:25:49 +0400 Subject: [PATCH 1460/1664] Test --- iguana/exchanges/LP_stats.c | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/iguana/exchanges/LP_stats.c b/iguana/exchanges/LP_stats.c index cd250dcfe..77e6500da 100644 --- a/iguana/exchanges/LP_stats.c +++ b/iguana/exchanges/LP_stats.c @@ -535,7 +535,7 @@ char *LP_swapstatus_recv(cJSON *argjson) } if ( sp != 0 ) { - if ( IAMLP == 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) ) @@ -549,31 +549,31 @@ char *LP_swapstatus_recv(cJSON *argjson) 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)); + //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)); + //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)); + //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)); + //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)); + //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 ) From c120c3e8d13cd65585e92965d8e4b3557b21fb42 Mon Sep 17 00:00:00 2001 From: jl777 Date: Sun, 3 Dec 2017 21:40:35 +0400 Subject: [PATCH 1461/1664] Test --- iguana/exchanges/LP_instantdex.c | 4 ++-- iguana/exchanges/LP_stats.c | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/iguana/exchanges/LP_instantdex.c b/iguana/exchanges/LP_instantdex.c index 9cbcdca45..e89db4ccd 100644 --- a/iguana/exchanges/LP_instantdex.c +++ b/iguana/exchanges/LP_instantdex.c @@ -319,7 +319,7 @@ int64_t LP_instantdex_credit(int32_t dispflag,char *coinaddr,int64_t satoshis,in int64_t LP_instantdex_creditcalc(struct iguana_info *coin,int32_t dispflag,bits256 txid,char *refaddr) { - cJSON *txjson,*vouts,*txobj,*item; int64_t satoshis=0,amount64; int32_t weeki,numvouts; char destaddr[64],p2shaddr[64]; + cJSON *txjson,*vouts,*txobj,*item; int64_t satoshis=0,amount64; int32_t weeki,numvouts; char destaddr[64],p2shaddr[64],str[65]; if ( (txjson= LP_gettx(coin->symbol,txid,0)) != 0 ) { // vout0 deposit, vout1 botsfee, vout2 smartaddress @@ -335,7 +335,7 @@ 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 ) diff --git a/iguana/exchanges/LP_stats.c b/iguana/exchanges/LP_stats.c index 77e6500da..7d7ee1fba 100644 --- a/iguana/exchanges/LP_stats.c +++ b/iguana/exchanges/LP_stats.c @@ -518,7 +518,7 @@ cJSON *LP_swapstats_json(struct LP_swapstats *sp) char *LP_swapstatus_recv(cJSON *argjson) { - struct LP_swapstats *sp; char *statusstr; uint64_t aliceid; double qprice; struct LP_quoteinfo Q; int32_t methodind,RTflag; bits256 txid; char str[65]; + 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 ) @@ -589,7 +589,7 @@ char *LP_swapstatus_recv(cJSON *argjson) char *LP_gettradestatus(uint64_t aliceid,uint32_t requestid,uint32_t quoteid) { struct LP_swapstats *sp; char *swapstr,*statusstr; cJSON *reqjson,*swapjson; bits256 zero; - printf("gettradestatus.(%llu)\n",(long long)aliceid); + //printf("gettradestatus.(%llu)\n",(long long)aliceid); if ( IAMLP != 0 ) { if ( (sp= LP_swapstats_find(aliceid)) != 0 ) From 6231df35f2852999e8228dec21d3b8686676413a Mon Sep 17 00:00:00 2001 From: jl777 Date: Sun, 3 Dec 2017 21:47:55 +0400 Subject: [PATCH 1462/1664] Test --- iguana/exchanges/LP_instantdex.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/iguana/exchanges/LP_instantdex.c b/iguana/exchanges/LP_instantdex.c index e89db4ccd..b0e24cf53 100644 --- a/iguana/exchanges/LP_instantdex.c +++ b/iguana/exchanges/LP_instantdex.c @@ -303,7 +303,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; @@ -312,7 +312,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); } @@ -342,8 +342,8 @@ int64_t LP_instantdex_creditcalc(struct iguana_info *coin,int32_t dispflag,bits2 { 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); From 7c90d05916488a00effa5d63e253a19dca66a980 Mon Sep 17 00:00:00 2001 From: jl777 Date: Sun, 3 Dec 2017 21:53:57 +0400 Subject: [PATCH 1463/1664] Test --- iguana/exchanges/LP_include.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/iguana/exchanges/LP_include.h b/iguana/exchanges/LP_include.h index d6b484d05..1e9900d61 100644 --- a/iguana/exchanges/LP_include.h +++ b/iguana/exchanges/LP_include.h @@ -106,7 +106,7 @@ 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_WEEKMULT (7 * 24 * 3600) #define LP_FIRSTWEEKTIME 1510790400 // must be 0 mod LP_WEEKMULT //#define BASILISK_DISABLEWAITTX From e086f6e4ac98ed114e1b65562b3fa184301f1e86 Mon Sep 17 00:00:00 2001 From: jl777 Date: Sun, 3 Dec 2017 21:57:59 +0400 Subject: [PATCH 1464/1664] Test --- iguana/exchanges/LP_include.h | 1 + iguana/exchanges/LP_instantdex.c | 10 ++++++---- 2 files changed, 7 insertions(+), 4 deletions(-) diff --git a/iguana/exchanges/LP_include.h b/iguana/exchanges/LP_include.h index 1e9900d61..fe6637eea 100644 --- a/iguana/exchanges/LP_include.h +++ b/iguana/exchanges/LP_include.h @@ -106,6 +106,7 @@ 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_WEEKMULTBAD (7 * 24 * 2600) #define LP_WEEKMULT (7 * 24 * 3600) #define LP_FIRSTWEEKTIME 1510790400 // must be 0 mod LP_WEEKMULT diff --git a/iguana/exchanges/LP_instantdex.c b/iguana/exchanges/LP_instantdex.c index b0e24cf53..acb195e7b 100644 --- a/iguana/exchanges/LP_instantdex.c +++ b/iguana/exchanges/LP_instantdex.c @@ -219,12 +219,15 @@ int32_t LP_claim_submit(void *ctx,cJSON *txids,int64_t *sump,struct iguana_info vout1 = jitem(vouts,1); weeksatoshis = LP_value_extract(vout1,0); weeki = (int32_t)(weeksatoshis % 10000); - for (j=28; j<=28; j++) + for (j=0; j<2*168; j++) { - expiration = ((weeki * LP_WEEKMULT + j*3600) + LP_FIRSTWEEKTIME); + if ( j >= 168 ) + expiration = ((weeki * LP_WEEKMULT + (j-168)*2600) + 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); @@ -245,12 +248,11 @@ int32_t LP_claim_submit(void *ctx,cJSON *txids,int64_t *sump,struct iguana_info *sump += LP_claimtx(ctx,coin,&claimtxid,utxotxid,utxovout,satoshis,vinaddr,claimtime,redeemscript,redeemlen); if ( bits256_nonz(claimtxid) != 0 ) { - flagi = 1; jaddbits256(item,"claimtxid",claimtxid); jaddi(txids,item); } } - } else printf("expiration.%u j.%d checkaddr.(%s) != vinaddr.%s\n",expiration,j,checkaddr,vinaddr); + } //else printf("expiration.%u j.%d checkaddr.(%s) != vinaddr.%s\n",expiration,j,checkaddr,vinaddr); if ( flagi != 0 ) break; } From f6bc0aaedfb89413e2d7110829ecaa02d9e88c5f Mon Sep 17 00:00:00 2001 From: jl777 Date: Sun, 3 Dec 2017 22:01:13 +0400 Subject: [PATCH 1465/1664] Test --- iguana/exchanges/LP_instantdex.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/iguana/exchanges/LP_instantdex.c b/iguana/exchanges/LP_instantdex.c index acb195e7b..87f8fbf9a 100644 --- a/iguana/exchanges/LP_instantdex.c +++ b/iguana/exchanges/LP_instantdex.c @@ -252,7 +252,7 @@ int32_t LP_claim_submit(void *ctx,cJSON *txids,int64_t *sump,struct iguana_info jaddi(txids,item); } } - } //else printf("expiration.%u j.%d checkaddr.(%s) != vinaddr.%s\n",expiration,j,checkaddr,vinaddr); + } else printf("expiration.%u j.%d checkaddr.(%s) != vinaddr.%s\n",expiration,j,checkaddr,vinaddr); if ( flagi != 0 ) break; } @@ -267,7 +267,6 @@ char *LP_instantdex_claim(struct iguana_info *coin) { static void *ctx; int32_t i,n; cJSON *array,*txids,*newarray,*retjson; int64_t sum; bits256 utxotxid; - printf("inside instantdex claim\n"); if ( ctx == 0 ) ctx = bitcoin_ctx(); if ( strcmp(coin->symbol,"KMD") != 0 ) From ad7064d4bd01153b9e894cb842d2b6cfcde1c825 Mon Sep 17 00:00:00 2001 From: jl777 Date: Sun, 3 Dec 2017 22:03:06 +0400 Subject: [PATCH 1466/1664] Test --- iguana/exchanges/LP_instantdex.c | 1 + 1 file changed, 1 insertion(+) diff --git a/iguana/exchanges/LP_instantdex.c b/iguana/exchanges/LP_instantdex.c index 87f8fbf9a..ce5762fa3 100644 --- a/iguana/exchanges/LP_instantdex.c +++ b/iguana/exchanges/LP_instantdex.c @@ -228,6 +228,7 @@ int32_t LP_claim_submit(void *ctx,cJSON *txids,int64_t *sump,struct iguana_info if ( strcmp(checkaddr,vinaddr) == 0 ) { flagi = 1; + printf("j.%d matched %s\n",j,vinaddr); claimtime = (uint32_t)time(NULL)-777; item = cJSON_CreateObject(); jaddbits256(item,"txid",utxotxid); From 363e8a80ca0102c2b6ff3845d4fd32c2fc1444e4 Mon Sep 17 00:00:00 2001 From: jl777 Date: Sun, 3 Dec 2017 22:04:58 +0400 Subject: [PATCH 1467/1664] Test --- iguana/exchanges/LP_instantdex.c | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/iguana/exchanges/LP_instantdex.c b/iguana/exchanges/LP_instantdex.c index ce5762fa3..56e18a652 100644 --- a/iguana/exchanges/LP_instantdex.c +++ b/iguana/exchanges/LP_instantdex.c @@ -222,13 +222,12 @@ int32_t LP_claim_submit(void *ctx,cJSON *txids,int64_t *sump,struct iguana_info for (j=0; j<2*168; j++) { if ( j >= 168 ) - expiration = ((weeki * LP_WEEKMULT + (j-168)*2600) + LP_FIRSTWEEKTIME); + expiration = ((weeki * LP_WEEKMULTBAD + (j-168)*2600) + 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; - printf("j.%d matched %s\n",j,vinaddr); claimtime = (uint32_t)time(NULL)-777; item = cJSON_CreateObject(); jaddbits256(item,"txid",utxotxid); @@ -253,7 +252,7 @@ int32_t LP_claim_submit(void *ctx,cJSON *txids,int64_t *sump,struct iguana_info jaddi(txids,item); } } - } else printf("expiration.%u j.%d checkaddr.(%s) != vinaddr.%s\n",expiration,j,checkaddr,vinaddr); + } //else printf("expiration.%u j.%d checkaddr.(%s) != vinaddr.%s\n",expiration,j,checkaddr,vinaddr); if ( flagi != 0 ) break; } From 5026668175541934eaa1d0a18dec60976c1ae78a Mon Sep 17 00:00:00 2001 From: jl777 Date: Sun, 3 Dec 2017 22:08:43 +0400 Subject: [PATCH 1468/1664] Test --- iguana/exchanges/LP_instantdex.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/iguana/exchanges/LP_instantdex.c b/iguana/exchanges/LP_instantdex.c index 56e18a652..725f907ec 100644 --- a/iguana/exchanges/LP_instantdex.c +++ b/iguana/exchanges/LP_instantdex.c @@ -222,7 +222,7 @@ int32_t LP_claim_submit(void *ctx,cJSON *txids,int64_t *sump,struct iguana_info for (j=0; j<2*168; j++) { if ( j >= 168 ) - expiration = ((weeki * LP_WEEKMULTBAD + (j-168)*2600) + LP_FIRSTWEEKTIME); + 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 ) From cb43c9c0cdca4a4b48e722fb784c5932d5c384f8 Mon Sep 17 00:00:00 2001 From: jl777 Date: Sun, 3 Dec 2017 22:12:17 +0400 Subject: [PATCH 1469/1664] Test --- iguana/exchanges/LP_instantdex.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/iguana/exchanges/LP_instantdex.c b/iguana/exchanges/LP_instantdex.c index 725f907ec..21fb780a3 100644 --- a/iguana/exchanges/LP_instantdex.c +++ b/iguana/exchanges/LP_instantdex.c @@ -313,14 +313,14 @@ 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)); + } //else printf("null ap.%p or expired %ld\n",ap,time(NULL) - (timestamp-60*3600)); } return(0); } int64_t LP_instantdex_creditcalc(struct iguana_info *coin,int32_t dispflag,bits256 txid,char *refaddr) { - cJSON *txjson,*vouts,*txobj,*item; int64_t satoshis=0,amount64; int32_t weeki,numvouts; char destaddr[64],p2shaddr[64],str[65]; + cJSON *txjson,*vouts,*txobj,*item; int64_t satoshis=0,amount64; int32_t weeki,numvouts; char destaddr[64],p2shaddr[64]; if ( (txjson= LP_gettx(coin->symbol,txid,0)) != 0 ) { // vout0 deposit, vout1 botsfee, vout2 smartaddress @@ -336,7 +336,7 @@ 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 %s funded %.8f weeki.%d (%s)\n",bits256_str(str,txid),destaddr,dstr(satoshis),weeki,jprint(item,0)); + //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 ) From 93a08f29256f2e918a388c5faefafa9a00cf2071 Mon Sep 17 00:00:00 2001 From: jl777 Date: Sun, 3 Dec 2017 22:28:15 +0400 Subject: [PATCH 1470/1664] Test --- iguana/exchanges/LP_include.h | 2 +- iguana/exchanges/LP_stats.c | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/iguana/exchanges/LP_include.h b/iguana/exchanges/LP_include.h index fe6637eea..79a76b055 100644 --- a/iguana/exchanges/LP_include.h +++ b/iguana/exchanges/LP_include.h @@ -65,7 +65,7 @@ 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_CLIENT_STATSPARSE (100 * 1024 * 1024) +#define LP_CLIENT_STATSPARSE (90 * 1024 * 1024) #define LP_COMMAND_SENDSOCK NN_PUSH #define LP_COMMAND_RECVSOCK NN_PULL diff --git a/iguana/exchanges/LP_stats.c b/iguana/exchanges/LP_stats.c index 7d7ee1fba..69da2fbd8 100644 --- a/iguana/exchanges/LP_stats.c +++ b/iguana/exchanges/LP_stats.c @@ -531,7 +531,7 @@ char *LP_swapstatus_recv(cJSON *argjson) RTflag = 0; else RTflag = 1; sp = LP_swapstats_create(aliceid,RTflag,&Q,qprice,LP_TRADESTATUS_METHODIND); - printf("create swapstatus from recv\n"); + //printf("create swapstatus from recv\n"); } if ( sp != 0 ) { From f0a261d8cbac07fa95671b55731ca1bb8b43bb9f Mon Sep 17 00:00:00 2001 From: jl777 Date: Sun, 3 Dec 2017 22:30:44 +0400 Subject: [PATCH 1471/1664] Test --- iguana/exchanges/LP_stats.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/iguana/exchanges/LP_stats.c b/iguana/exchanges/LP_stats.c index 69da2fbd8..312fab0db 100644 --- a/iguana/exchanges/LP_stats.c +++ b/iguana/exchanges/LP_stats.c @@ -97,7 +97,7 @@ int32_t LP_statslog_parse() return(0); } } - else if ( 0 ) + else if ( 1 ) { if ( IAMLP == 0 ) { @@ -108,7 +108,7 @@ int32_t LP_statslog_parse() 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 ) From cc60813494b6778fdb187cba69e54029cc6be7c3 Mon Sep 17 00:00:00 2001 From: jl777 Date: Sun, 3 Dec 2017 23:19:51 +0400 Subject: [PATCH 1472/1664] Test --- iguana/exchanges/LP_commands.c | 2 + iguana/exchanges/LP_include.h | 4 +- iguana/exchanges/LP_instantdex.c | 4 +- iguana/exchanges/LP_nativeDEX.c | 6 ++- iguana/exchanges/LP_rpc.c | 69 +++++++++++++++++++++++++++++--- iguana/exchanges/LP_stats.c | 18 +++++++++ 6 files changed, 92 insertions(+), 11 deletions(-) diff --git a/iguana/exchanges/LP_commands.c b/iguana/exchanges/LP_commands.c index 2c9a378d5..980bc9a76 100644 --- a/iguana/exchanges/LP_commands.c +++ b/iguana/exchanges/LP_commands.c @@ -620,6 +620,8 @@ instantdex_claim()\n\ 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 79a76b055..55f97fe19 100644 --- a/iguana/exchanges/LP_include.h +++ b/iguana/exchanges/LP_include.h @@ -301,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; }; diff --git a/iguana/exchanges/LP_instantdex.c b/iguana/exchanges/LP_instantdex.c index 21fb780a3..043d6b50f 100644 --- a/iguana/exchanges/LP_instantdex.c +++ b/iguana/exchanges/LP_instantdex.c @@ -418,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); } diff --git a/iguana/exchanges/LP_nativeDEX.c b/iguana/exchanges/LP_nativeDEX.c index cf09af1b6..a011ef4ec 100644 --- a/iguana/exchanges/LP_nativeDEX.c +++ b/iguana/exchanges/LP_nativeDEX.c @@ -17,8 +17,8 @@ // LP_nativeDEX.c // marketmaker // -// too much stats.log -// big BTC swaps +// validate notarization +// big BTC swaps, assetchain markets // https://github.com/bitcoin/bips/blob/master/bip-0143.mediawiki for signing BCH/BTG // // compress packets @@ -683,6 +683,8 @@ int32_t LP_mainloop_iter(void *ctx,char *myipaddr,struct LP_peerinfo *mypeer,int 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)); LP_reserved_msg(0,coin->symbol,coin->symbol,zero,jprint(reqjson,1)); } diff --git a/iguana/exchanges/LP_rpc.c b/iguana/exchanges/LP_rpc.c index d84369890..d692b16fd 100644 --- a/iguana/exchanges/LP_rpc.c +++ b/iguana/exchanges/LP_rpc.c @@ -106,6 +106,8 @@ int32_t LP_getheight(int32_t *notarizedp,struct iguana_info *coin) { 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 ) @@ -965,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 ) @@ -987,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); @@ -1021,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[3],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; ielectrum != 0 ) + { + notarized = jint(argjson,"notarized"); + notarizedhash = jbits256(argjson,"notarizedhash"); + notarizationtxid = jbits256(argjson,"notarizationtxid"); + if ( notarized > coin->notarized && LP_notarization_validate(symbol,notarized,notarizedhash,notarizationtxid) == 0 ) + { + coin->notarized = notarized; + coin->notarizedhash = notarizedhash; + coin->notarizationtxid = notarizationtxid; + } + } + return(clonestr("{\"result\":\"success\"}")); +} + void LP_tradecommand_log(cJSON *argjson) { static FILE *logfp; char *jsonstr; From 16a595a9c163a57b2771f73351b0c8e8eac5aed6 Mon Sep 17 00:00:00 2001 From: jl777 Date: Sun, 3 Dec 2017 23:27:14 +0400 Subject: [PATCH 1473/1664] Test --- iguana/exchanges/LP_stats.c | 2 ++ iguana/exchanges/LP_utxo.c | 5 +++++ 2 files changed, 7 insertions(+) diff --git a/iguana/exchanges/LP_stats.c b/iguana/exchanges/LP_stats.c index cea994f07..94278f88b 100644 --- a/iguana/exchanges/LP_stats.c +++ b/iguana/exchanges/LP_stats.c @@ -36,11 +36,13 @@ char *LP_dPoW_recv(cJSON *argjson) 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\n"); } } return(clonestr("{\"result\":\"success\"}")); diff --git a/iguana/exchanges/LP_utxo.c b/iguana/exchanges/LP_utxo.c index aa11f9b3b..d3a32db6e 100644 --- a/iguana/exchanges/LP_utxo.c +++ b/iguana/exchanges/LP_utxo.c @@ -794,7 +794,12 @@ int32_t LP_txheight(struct iguana_info *coin,bits256 txid) 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); From c4d025049566168a227b94d3f2de7f4b49b81aa8 Mon Sep 17 00:00:00 2001 From: jl777 Date: Sun, 3 Dec 2017 23:38:10 +0400 Subject: [PATCH 1474/1664] Test --- iguana/exchanges/LP_nativeDEX.c | 11 +---------- iguana/exchanges/LP_stats.c | 18 +++++++++++++++++- iguana/exchanges/LP_utxo.c | 2 +- 3 files changed, 19 insertions(+), 12 deletions(-) diff --git a/iguana/exchanges/LP_nativeDEX.c b/iguana/exchanges/LP_nativeDEX.c index a011ef4ec..639b57fb8 100644 --- a/iguana/exchanges/LP_nativeDEX.c +++ b/iguana/exchanges/LP_nativeDEX.c @@ -678,16 +678,7 @@ int32_t LP_mainloop_iter(void *ctx,char *myipaddr,struct LP_peerinfo *mypeer,int { coin->notarized = notarized; if ( IAMLP != 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)); - LP_reserved_msg(0,coin->symbol,coin->symbol,zero,jprint(reqjson,1)); - } + 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); diff --git a/iguana/exchanges/LP_stats.c b/iguana/exchanges/LP_stats.c index 94278f88b..f1088c47d 100644 --- a/iguana/exchanges/LP_stats.c +++ b/iguana/exchanges/LP_stats.c @@ -28,6 +28,18 @@ char *LP_stats_methods[] = { "unknown", "request", "reserved", "connect", "conne 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_broadcast(struct iguana_info *coin) +{ + bits256 zero; cJSON *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)); + LP_reserved_msg(0,coin->symbol,coin->symbol,zero,jprint(reqjson,1)); +} + char *LP_dPoW_recv(cJSON *argjson) { int32_t notarized; bits256 notarizedhash,notarizationtxid; char *symbol; struct iguana_info *coin; @@ -608,7 +620,7 @@ char *LP_swapstatus_recv(cJSON *argjson) char *LP_gettradestatus(uint64_t aliceid,uint32_t requestid,uint32_t quoteid) { - struct LP_swapstats *sp; char *swapstr,*statusstr; cJSON *reqjson,*swapjson; 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 ( IAMLP != 0 ) { @@ -622,6 +634,10 @@ char *LP_gettradestatus(uint64_t aliceid,uint32_t requestid,uint32_t quoteid) 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\"}")); } diff --git a/iguana/exchanges/LP_utxo.c b/iguana/exchanges/LP_utxo.c index d3a32db6e..890577df0 100644 --- a/iguana/exchanges/LP_utxo.c +++ b/iguana/exchanges/LP_utxo.c @@ -795,7 +795,7 @@ int32_t LP_txheight(struct iguana_info *coin,bits256 txid) { if ( (retjson= electrum_transaction(&height,coin->symbol,coin->electrum,&retjson,txid,0)) != 0 ) { - printf("process %s\n",jprint(retjson,0)); + //printf("process %s\n",jprint(retjson,0)); free_json(retjson); } if ( (tx= LP_transactionfind(coin,txid)) != 0 ) From d6fac1a5896bf8a7de04d0f477feac21e0f50d87 Mon Sep 17 00:00:00 2001 From: jl777 Date: Sun, 3 Dec 2017 23:39:11 +0400 Subject: [PATCH 1475/1664] Test --- iguana/exchanges/LP_stats.c | 20 ++++++++++++-------- 1 file changed, 12 insertions(+), 8 deletions(-) diff --git a/iguana/exchanges/LP_stats.c b/iguana/exchanges/LP_stats.c index f1088c47d..2e9169e67 100644 --- a/iguana/exchanges/LP_stats.c +++ b/iguana/exchanges/LP_stats.c @@ -30,14 +30,18 @@ static uint32_t LP_requests,LP_reserveds,LP_connects,LP_connecteds,LP_tradestatu void LP_dPoW_broadcast(struct iguana_info *coin) { - bits256 zero; cJSON *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)); - LP_reserved_msg(0,coin->symbol,coin->symbol,zero,jprint(reqjson,1)); + bits256 zero; cJSON *reqjson; + if ( 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)); + LP_reserved_msg(0,coin->symbol,coin->symbol,zero,jprint(reqjson,1)); + } } char *LP_dPoW_recv(cJSON *argjson) From f8edc9635240b283120c2c42b5804d262a7ee000 Mon Sep 17 00:00:00 2001 From: jl777 Date: Sun, 3 Dec 2017 23:50:13 +0400 Subject: [PATCH 1476/1664] Test --- iguana/exchanges/LP_commands.c | 10 ++++++- iguana/exchanges/LP_nativeDEX.c | 2 +- iguana/exchanges/LP_stats.c | 48 +++++++++++++++++++++------------ 3 files changed, 41 insertions(+), 19 deletions(-) diff --git a/iguana/exchanges/LP_commands.c b/iguana/exchanges/LP_commands.c index 980bc9a76..d9031b6df 100644 --- a/iguana/exchanges/LP_commands.c +++ b/iguana/exchanges/LP_commands.c @@ -603,6 +603,8 @@ instantdex_claim()\n\ } argjson = reqjson; } + else if ( strcmp(method,"getdPoW") == 0 ) + retstr = clonestr("{\"result\":\"success\"}"); } else { @@ -610,7 +612,13 @@ instantdex_claim()\n\ { 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)); diff --git a/iguana/exchanges/LP_nativeDEX.c b/iguana/exchanges/LP_nativeDEX.c index 639b57fb8..a985e5b5f 100644 --- a/iguana/exchanges/LP_nativeDEX.c +++ b/iguana/exchanges/LP_nativeDEX.c @@ -646,7 +646,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 notarized,height,nonz = 0; bits256 zero; cJSON *reqjson; + 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 ) diff --git a/iguana/exchanges/LP_stats.c b/iguana/exchanges/LP_stats.c index 2e9169e67..0db044e23 100644 --- a/iguana/exchanges/LP_stats.c +++ b/iguana/exchanges/LP_stats.c @@ -28,6 +28,17 @@ char *LP_stats_methods[] = { "unknown", "request", "reserved", "connect", "conne 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; @@ -40,6 +51,7 @@ void LP_dPoW_broadcast(struct iguana_info *coin) 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)); } } @@ -64,6 +76,25 @@ char *LP_dPoW_recv(cJSON *argjson) 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; @@ -260,23 +291,6 @@ int32_t LP_swapstats_update(struct LP_swapstats *sp,struct LP_quoteinfo *qp,cJSO return(0); } -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; - } - } - return(coin->notarized); -} - int32_t LP_finished_lastheight(struct LP_swapstats *sp) { int32_t height = 1; struct iguana_info *bob,*alice; //char str[65]; From 702467d96658518e6968b8171545269c181be01d Mon Sep 17 00:00:00 2001 From: jl777 Date: Sun, 3 Dec 2017 23:54:32 +0400 Subject: [PATCH 1477/1664] Test --- iguana/exchanges/LP_rpc.c | 2 +- iguana/exchanges/LP_stats.c | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/iguana/exchanges/LP_rpc.c b/iguana/exchanges/LP_rpc.c index d692b16fd..b3a070f83 100644 --- a/iguana/exchanges/LP_rpc.c +++ b/iguana/exchanges/LP_rpc.c @@ -1031,7 +1031,7 @@ int32_t LP_txhasnotarization(bits256 *notarizedhashp,struct iguana_info *coin,bi { len >>= 1; decode_hex(script,len,hexstr); - iguana_rwbignum(0,&script[3],32,(uint8_t *)notarizedhashp); + iguana_rwbignum(0,&script[4],32,(uint8_t *)notarizedhashp); } } free_json(txobj); diff --git a/iguana/exchanges/LP_stats.c b/iguana/exchanges/LP_stats.c index 0db044e23..5b483d6b5 100644 --- a/iguana/exchanges/LP_stats.c +++ b/iguana/exchanges/LP_stats.c @@ -70,7 +70,7 @@ char *LP_dPoW_recv(cJSON *argjson) coin->notarized = notarized; coin->notarizedhash = notarizedhash; coin->notarizationtxid = notarizationtxid; - printf("VALIDATED\n"); + printf("VALIDATED dPoW %s\n",jprint(argjson,0)); } } return(clonestr("{\"result\":\"success\"}")); From fcee4d1518b8c1dd19928d4ce6efab3db413c286 Mon Sep 17 00:00:00 2001 From: jl777 Date: Sun, 3 Dec 2017 23:58:34 +0400 Subject: [PATCH 1478/1664] Test --- iguana/exchanges/LP_include.h | 2 +- iguana/exchanges/LP_instantdex.c | 4 ++++ iguana/exchanges/LP_stats.c | 3 ++- 3 files changed, 7 insertions(+), 2 deletions(-) diff --git a/iguana/exchanges/LP_include.h b/iguana/exchanges/LP_include.h index 55f97fe19..218dc7867 100644 --- a/iguana/exchanges/LP_include.h +++ b/iguana/exchanges/LP_include.h @@ -292,7 +292,7 @@ struct iguana_info portable_mutex_t txmutex,addrmutex; struct LP_transaction *transactions; struct LP_address *addresses; uint64_t txfee; int32_t numutxos,notarized,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; + 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 diff --git a/iguana/exchanges/LP_instantdex.c b/iguana/exchanges/LP_instantdex.c index 043d6b50f..2737a0c9e 100644 --- a/iguana/exchanges/LP_instantdex.c +++ b/iguana/exchanges/LP_instantdex.c @@ -468,6 +468,8 @@ cJSON *LP_swapstats_item(struct LP_swapstats *sp,int32_t iambob) 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 ) { @@ -475,6 +477,8 @@ cJSON *LP_swapstats_item(struct LP_swapstats *sp,int32_t iambob) jaddnum(item,"alice_dPoWheight",alice->notarized); if ( sp->aliceneeds_dPoW == 1 ) flag = 1; + if ( alice->notarized == 0 ) + LP_dPoW_request(alice); } if ( flag != 0 ) { diff --git a/iguana/exchanges/LP_stats.c b/iguana/exchanges/LP_stats.c index 5b483d6b5..ab3744c60 100644 --- a/iguana/exchanges/LP_stats.c +++ b/iguana/exchanges/LP_stats.c @@ -42,7 +42,7 @@ void LP_dPoW_request(struct iguana_info *coin) void LP_dPoW_broadcast(struct iguana_info *coin) { bits256 zero; cJSON *reqjson; - if ( coin->isassetchain != 0 || strcmp(coin->symbol,"KMD") == 0 ) + if ( time(NULL) > coin->dPoWtime+60 && (coin->isassetchain != 0 || strcmp(coin->symbol,"KMD") == 0) ) { reqjson = cJSON_CreateObject(); jaddstr(reqjson,"method","dPoW"); @@ -53,6 +53,7 @@ void LP_dPoW_broadcast(struct iguana_info *coin) 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); } } From 8c327cae8316677038ba4d3527256c1a04e05633 Mon Sep 17 00:00:00 2001 From: jl777 Date: Mon, 4 Dec 2017 00:01:52 +0400 Subject: [PATCH 1479/1664] Test --- iguana/exchanges/LP_commands.c | 4 ++-- iguana/exchanges/LP_rpc.c | 2 +- iguana/exchanges/LP_stats.c | 4 ++-- 3 files changed, 5 insertions(+), 5 deletions(-) diff --git a/iguana/exchanges/LP_commands.c b/iguana/exchanges/LP_commands.c index d9031b6df..af24bf929 100644 --- a/iguana/exchanges/LP_commands.c +++ b/iguana/exchanges/LP_commands.c @@ -603,7 +603,7 @@ instantdex_claim()\n\ } argjson = reqjson; } - else if ( strcmp(method,"getdPoW") == 0 ) + if ( strcmp(method,"getdPoW") == 0 ) retstr = clonestr("{\"result\":\"success\"}"); } else @@ -618,7 +618,7 @@ instantdex_claim()\n\ LP_dPoW_broadcast(ptr); retstr = clonestr("{\"result\":\"success\"}"); } - } + } // received response if ( strcmp(method,"swapstatus") == 0 ) return(LP_swapstatus_recv(argjson)); diff --git a/iguana/exchanges/LP_rpc.c b/iguana/exchanges/LP_rpc.c index b3a070f83..a9dcfe1e3 100644 --- a/iguana/exchanges/LP_rpc.c +++ b/iguana/exchanges/LP_rpc.c @@ -1031,7 +1031,7 @@ int32_t LP_txhasnotarization(bits256 *notarizedhashp,struct iguana_info *coin,bi { len >>= 1; decode_hex(script,len,hexstr); - iguana_rwbignum(0,&script[4],32,(uint8_t *)notarizedhashp); + iguana_rwbignum(0,&script[2],32,(uint8_t *)notarizedhashp); } } free_json(txobj); diff --git a/iguana/exchanges/LP_stats.c b/iguana/exchanges/LP_stats.c index ab3744c60..ba9486f13 100644 --- a/iguana/exchanges/LP_stats.c +++ b/iguana/exchanges/LP_stats.c @@ -77,7 +77,7 @@ char *LP_dPoW_recv(cJSON *argjson) return(clonestr("{\"result\":\"success\"}")); } -int32_t LP_dPoWheight(struct iguana_info *coin) // get dPoW protected height +/*int32_t LP_dPoWheight(struct iguana_info *coin) // get dPoW protected height { int32_t notarized,oldnotarized; if ( coin->electrum == 0 ) @@ -94,7 +94,7 @@ int32_t LP_dPoWheight(struct iguana_info *coin) // get dPoW protected height else if ( coin->notarized == 0 ) LP_dPoW_request(coin); return(coin->notarized); -} +}*/ void LP_tradecommand_log(cJSON *argjson) { From 603202b57430028d180d690376ff389596319862 Mon Sep 17 00:00:00 2001 From: jl777 Date: Mon, 4 Dec 2017 00:03:23 +0400 Subject: [PATCH 1480/1664] Test --- iguana/exchanges/LP_stats.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/iguana/exchanges/LP_stats.c b/iguana/exchanges/LP_stats.c index ba9486f13..550ccaca5 100644 --- a/iguana/exchanges/LP_stats.c +++ b/iguana/exchanges/LP_stats.c @@ -35,7 +35,7 @@ void LP_dPoW_request(struct iguana_info *coin) jaddstr(reqjson,"method","getdPoW"); jaddstr(reqjson,"coin",coin->symbol); memset(zero.bytes,0,sizeof(zero)); - printf("request %s\n",jprint(reqjson,0)); + //printf("request %s\n",jprint(reqjson,0)); LP_reserved_msg(0,coin->symbol,coin->symbol,zero,jprint(reqjson,1)); } @@ -51,7 +51,7 @@ void LP_dPoW_broadcast(struct iguana_info *coin) jaddbits256(reqjson,"notarizedhash",coin->notarizedhash); jaddbits256(reqjson,"notarizationtxid",coin->notarizationtxid); memset(zero.bytes,0,sizeof(zero)); - printf("broadcast %s\n",jprint(reqjson,0)); + //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); } From 46945928b4d1d2c9dc45577e66d825ab3d88d1c6 Mon Sep 17 00:00:00 2001 From: jl777 Date: Mon, 4 Dec 2017 00:13:56 +0400 Subject: [PATCH 1481/1664] Test --- iguana/exchanges/LP_instantdex.c | 2 +- iguana/exchanges/LP_stats.c | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/iguana/exchanges/LP_instantdex.c b/iguana/exchanges/LP_instantdex.c index 2737a0c9e..cb01b37b8 100644 --- a/iguana/exchanges/LP_instantdex.c +++ b/iguana/exchanges/LP_instantdex.c @@ -487,7 +487,7 @@ cJSON *LP_swapstats_item(struct LP_swapstats *sp,int32_t iambob) 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,1)) != 0 ) + if ( (swapstr= basilisk_swapentry(sp->Q.R.requestid,sp->Q.R.quoteid,0)) != 0 ) { if ( (swapjson= cJSON_Parse(swapstr)) != 0 ) { diff --git a/iguana/exchanges/LP_stats.c b/iguana/exchanges/LP_stats.c index 550ccaca5..06d072285 100644 --- a/iguana/exchanges/LP_stats.c +++ b/iguana/exchanges/LP_stats.c @@ -65,7 +65,7 @@ char *LP_dPoW_recv(cJSON *argjson) notarized = jint(argjson,"notarized"); notarizedhash = jbits256(argjson,"notarizedhash"); notarizationtxid = jbits256(argjson,"notarizationtxid"); - printf("dPoW %s\n",jprint(argjson,0)); + //printf("dPoW %s\n",jprint(argjson,0)); if ( notarized > coin->notarized && LP_notarization_validate(symbol,notarized,notarizedhash,notarizationtxid) == 0 ) { coin->notarized = notarized; From ad04965a196d8aedff68689bf43822f3f7dc3514 Mon Sep 17 00:00:00 2001 From: jl777 Date: Mon, 4 Dec 2017 01:48:54 +0400 Subject: [PATCH 1482/1664] Test --- iguana/coins/mshark_7776 | 0 iguana/exchanges/LP_nativeDEX.c | 7 ++----- 2 files changed, 2 insertions(+), 5 deletions(-) mode change 100644 => 100755 iguana/coins/mshark_7776 diff --git a/iguana/coins/mshark_7776 b/iguana/coins/mshark_7776 old mode 100644 new mode 100755 diff --git a/iguana/exchanges/LP_nativeDEX.c b/iguana/exchanges/LP_nativeDEX.c index a985e5b5f..19ee06ace 100644 --- a/iguana/exchanges/LP_nativeDEX.c +++ b/iguana/exchanges/LP_nativeDEX.c @@ -17,21 +17,18 @@ // LP_nativeDEX.c // marketmaker // -// validate notarization -// big BTC swaps, assetchain markets // 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 // // else claim path -// improve critical section detection when parallel trades // 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 From 6522f67d9892ddf8b5a4c781480e7d10183aea51 Mon Sep 17 00:00:00 2001 From: jl777 Date: Mon, 4 Dec 2017 02:06:47 +0400 Subject: [PATCH 1483/1664] Shark fix --- iguana/coins/mshark_7776 | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/iguana/coins/mshark_7776 b/iguana/coins/mshark_7776 index 9279d8085..e1d4e05fd 100755 --- a/iguana/coins/mshark_7776 +++ b/iguana/coins/mshark_7776 @@ -1,2 +1,2 @@ -curl --url "http://127.0.0.1:7776" --data "{\"conf\":\"SHARK.conf\",\"path\":\"${HOME#"/"}/.komodo/SHARK\",\"unitval\":\"20\",\"zcash\":1,\"RELAY\":-1,\"VALIDATE\":0,\"prefetchlag\":-1,\"poll\":100,\"active\":1,\"agent\":\"iguana\",\"method\":\"addcoin\",\"startpend\":4,\"endpend\":4,\"services\":129,\"maxpeers\":8,\"newcoin\":\"SHARK\",\"name\":\"SHARK\",\"hasheaders\":1,\"useaddmultisig\":0,\"netmagic\":\"54a5e30c\",\"p2p\":8845,\"rpc\":8846,\"pubval\":60,\"p2shval\":85,\"wifval\":188,\"txfee_satoshis\":\"10000\",\"isPoS\":0,\"minoutput\":10000,\"minconfirms\":2,\"genesishash\":\"027e3758c3a65b12aa1046462b486d0a63bfa1beae327897f56c5cfb7daaae71\",\"protover\":170002,\"genesisblock\":\"0100000000000000000000000000000000000000000000000000000000000000000000003ba3edfd7a7b12b27ac72c3e67768f617fc81bc3888a51323a9fb8aa4b1e5e4a000000000000000000000000000000000000000000000000000000000000000029ab5f490f0f0f200b00000000000000000000000000000000000000000000000000000000000000fd4005000d5ba7cda5d473947263bf194285317179d2b0d307119c2e7cc4bd8ac456f0774bd52b0cd9249be9d40718b6397a4c7bbd8f2b3272fed2823cd2af4bd1632200ba4bf796727d6347b225f670f292343274cc35099466f5fb5f0cd1c105121b28213d15db2ed7bdba490b4cedc69742a57b7c25af24485e523aadbb77a0144fc76f79ef73bd8530d42b9f3b9bed1c135ad1fe152923fafe98f95f76f1615e64c4abb1137f4c31b218ba2782bc15534788dda2cc08a0ee2987c8b27ff41bd4e31cd5fb5643dfe862c9a02ca9f90c8c51a6671d681d04ad47e4b53b1518d4befafefe8cadfb912f3d03051b1efbf1dfe37b56e93a741d8dfd80d576ca250bee55fab1311fc7b3255977558cdda6f7d6f875306e43a14413facdaed2f46093e0ef1e8f8a963e1632dcbeebd8e49fd16b57d49b08f9762de89157c65233f60c8e38a1f503a48c555f8ec45dedecd574a37601323c27be597b956343107f8bd80f3a925afaf30811df83c402116bb9c1e5231c70fff899a7c82f73c902ba54da53cc459b7bf1113db65cc8f6914d3618560ea69abd13658fa7b6af92d374d6eca9529f8bd565166e4fcbf2a8dfb3c9b69539d4d2ee2e9321b85b331925df195915f2757637c2805e1d4131e1ad9ef9bc1bb1c732d8dba4738716d351ab30c996c8657bab39567ee3b29c6d054b711495c0d52e1cd5d8e55b4f0f0325b97369280755b46a02afd54be4ddd9f77c22272b8bbb17ff5118fedbae2564524e797bd28b5f74f7079d532ccc059807989f94d267f47e724b3f1ecfe00ec9e6541c961080d8891251b84b4480bc292f6a180bea089fef5bbda56e1e41390d7c0e85ba0ef530f7177413481a226465a36ef6afe1e2bca69d2078712b3912bba1a99b1fbff0d355d6ffe726d2bb6fbc103c4ac5756e5bee6e47e17424ebcbf1b63d8cb90ce2e40198b4f4198689daea254307e52a25562f4c1455340f0ffeb10f9d8e914775e37d0edca019fb1b9c6ef81255ed86bc51c5391e0591480f66e2d88c5f4fd7277697968656a9b113ab97f874fdd5f2465e5559533e01ba13ef4a8f7a21d02c30c8ded68e8c54603ab9c8084ef6d9eb4e92c75b078539e2ae786ebab6dab73a09e0aa9ac575bcefb29e930ae656e58bcb513f7e3c17e079dce4f05b5dbc18c2a872b22509740ebe6a3903e00ad1abc55076441862643f93606e3dc35e8d9f2caef3ee6be14d513b2e062b21d0061de3bd56881713a1a5c17f5ace05e1ec09da53f99442df175a49bd154aa96e4949decd52fed79ccf7ccbce32941419c314e374e4a396ac553e17b5340336a1a25c22f9e42a243ba5404450b650acfc826a6e432971ace776e15719515e1634ceb9a4a35061b668c74998d3dfb5827f6238ec015377e6f9c94f38108768cf6e5c8b132e0303fb5a200368f845ad9d46343035a6ff94031df8d8309415bb3f6cd5ede9c135fdabcc030599858d803c0f85be7661c88984d88faa3d26fb0e9aac0056a53f1b5d0baed713c853c4a2726869a0a124a8a5bbc0fc0ef80c8ae4cb53636aa02503b86a1eb9836fcc259823e2692d921d88e1ffc1e6cb2bde43939ceb3f32a611686f539f8f7c9f0bf00381f743607d40960f06d347d1cd8ac8a51969c25e37150efdf7aa4c2037a2fd0516fb444525ab157a0ed0a7412b2fa69b217fe397263153782c0f64351fbdf2678fa0dc8569912dcd8e3ccad38f34f23bbbce14c6a26ac24911b308b82c7e43062d180baeac4ba7153858365c72c63dcf5f6a5b08070b730adb017aeae925b7d0439979e2679f45ed2f25a7edcfd2fb77a8794630285ccb0a071f5cce410b46dbf9750b0354aae8b65574501cc69efb5b6a43444074fee116641bb29da56c2b4a7f456991fc92b2\",\"debug\":0,\"seedipaddr\":\"78.47.196.146\"}" +curl --url "http://127.0.0.1:7776" --data "{\"conf\":\"MSHARK.conf\",\"path\":\"${HOME#"/"}/.komodo/MSHARK\",\"unitval\":\"20\",\"zcash\":1,\"RELAY\":-1,\"VALIDATE\":0,\"prefetchlag\":-1,\"poll\":100,\"active\":1,\"agent\":\"iguana\",\"method\":\"addcoin\",\"startpend\":4,\"endpend\":4,\"services\":129,\"maxpeers\":8,\"newcoin\":\"MSHARK\",\"name\":\"MSHARK\",\"hasheaders\":1,\"useaddmultisig\":0,\"netmagic\":\"54a5e30c\",\"p2p\":8845,\"rpc\":8846,\"pubval\":60,\"p2shval\":85,\"wifval\":188,\"txfee_satoshis\":\"10000\",\"isPoS\":0,\"minoutput\":10000,\"minconfirms\":2,\"genesishash\":\"027e3758c3a65b12aa1046462b486d0a63bfa1beae327897f56c5cfb7daaae71\",\"protover\":170002,\"genesisblock\":\"0100000000000000000000000000000000000000000000000000000000000000000000003ba3edfd7a7b12b27ac72c3e67768f617fc81bc3888a51323a9fb8aa4b1e5e4a000000000000000000000000000000000000000000000000000000000000000029ab5f490f0f0f200b00000000000000000000000000000000000000000000000000000000000000fd4005000d5ba7cda5d473947263bf194285317179d2b0d307119c2e7cc4bd8ac456f0774bd52b0cd9249be9d40718b6397a4c7bbd8f2b3272fed2823cd2af4bd1632200ba4bf796727d6347b225f670f292343274cc35099466f5fb5f0cd1c105121b28213d15db2ed7bdba490b4cedc69742a57b7c25af24485e523aadbb77a0144fc76f79ef73bd8530d42b9f3b9bed1c135ad1fe152923fafe98f95f76f1615e64c4abb1137f4c31b218ba2782bc15534788dda2cc08a0ee2987c8b27ff41bd4e31cd5fb5643dfe862c9a02ca9f90c8c51a6671d681d04ad47e4b53b1518d4befafefe8cadfb912f3d03051b1efbf1dfe37b56e93a741d8dfd80d576ca250bee55fab1311fc7b3255977558cdda6f7d6f875306e43a14413facdaed2f46093e0ef1e8f8a963e1632dcbeebd8e49fd16b57d49b08f9762de89157c65233f60c8e38a1f503a48c555f8ec45dedecd574a37601323c27be597b956343107f8bd80f3a925afaf30811df83c402116bb9c1e5231c70fff899a7c82f73c902ba54da53cc459b7bf1113db65cc8f6914d3618560ea69abd13658fa7b6af92d374d6eca9529f8bd565166e4fcbf2a8dfb3c9b69539d4d2ee2e9321b85b331925df195915f2757637c2805e1d4131e1ad9ef9bc1bb1c732d8dba4738716d351ab30c996c8657bab39567ee3b29c6d054b711495c0d52e1cd5d8e55b4f0f0325b97369280755b46a02afd54be4ddd9f77c22272b8bbb17ff5118fedbae2564524e797bd28b5f74f7079d532ccc059807989f94d267f47e724b3f1ecfe00ec9e6541c961080d8891251b84b4480bc292f6a180bea089fef5bbda56e1e41390d7c0e85ba0ef530f7177413481a226465a36ef6afe1e2bca69d2078712b3912bba1a99b1fbff0d355d6ffe726d2bb6fbc103c4ac5756e5bee6e47e17424ebcbf1b63d8cb90ce2e40198b4f4198689daea254307e52a25562f4c1455340f0ffeb10f9d8e914775e37d0edca019fb1b9c6ef81255ed86bc51c5391e0591480f66e2d88c5f4fd7277697968656a9b113ab97f874fdd5f2465e5559533e01ba13ef4a8f7a21d02c30c8ded68e8c54603ab9c8084ef6d9eb4e92c75b078539e2ae786ebab6dab73a09e0aa9ac575bcefb29e930ae656e58bcb513f7e3c17e079dce4f05b5dbc18c2a872b22509740ebe6a3903e00ad1abc55076441862643f93606e3dc35e8d9f2caef3ee6be14d513b2e062b21d0061de3bd56881713a1a5c17f5ace05e1ec09da53f99442df175a49bd154aa96e4949decd52fed79ccf7ccbce32941419c314e374e4a396ac553e17b5340336a1a25c22f9e42a243ba5404450b650acfc826a6e432971ace776e15719515e1634ceb9a4a35061b668c74998d3dfb5827f6238ec015377e6f9c94f38108768cf6e5c8b132e0303fb5a200368f845ad9d46343035a6ff94031df8d8309415bb3f6cd5ede9c135fdabcc030599858d803c0f85be7661c88984d88faa3d26fb0e9aac0056a53f1b5d0baed713c853c4a2726869a0a124a8a5bbc0fc0ef80c8ae4cb53636aa02503b86a1eb9836fcc259823e2692d921d88e1ffc1e6cb2bde43939ceb3f32a611686f539f8f7c9f0bf00381f743607d40960f06d347d1cd8ac8a51969c25e37150efdf7aa4c2037a2fd0516fb444525ab157a0ed0a7412b2fa69b217fe397263153782c0f64351fbdf2678fa0dc8569912dcd8e3ccad38f34f23bbbce14c6a26ac24911b308b82c7e43062d180baeac4ba7153858365c72c63dcf5f6a5b08070b730adb017aeae925b7d0439979e2679f45ed2f25a7edcfd2fb77a8794630285ccb0a071f5cce410b46dbf9750b0354aae8b65574501cc69efb5b6a43444074fee116641bb29da56c2b4a7f456991fc92b2\",\"debug\":0,\"seedipaddr\":\"78.47.196.146\"}" From 318169a018de4179f22aa788ab9d59a449c4bb56 Mon Sep 17 00:00:00 2001 From: jl777 Date: Mon, 4 Dec 2017 11:02:55 +0400 Subject: [PATCH 1484/1664] Test --- iguana/exchanges/LP_swap.c | 6 ++++-- iguana/exchanges/LP_transaction.c | 5 ++++- 2 files changed, 8 insertions(+), 3 deletions(-) diff --git a/iguana/exchanges/LP_swap.c b/iguana/exchanges/LP_swap.c index d03cfa668..fc68657df 100644 --- a/iguana/exchanges/LP_swap.c +++ b/iguana/exchanges/LP_swap.c @@ -848,10 +848,11 @@ void LP_bobloop(void *_swap) } } } - basilisk_swap_finished(swap); - free(swap); } else printf("swap timed out\n"); G.LP_pendingswaps--; + basilisk_swap_finished(swap); + free(swap); + free(data); } void LP_aliceloop(void *_swap) @@ -925,6 +926,7 @@ void LP_aliceloop(void *_swap) }*/ if ( swap->N.pair >= 0 ) nn_close(swap->N.pair), swap->N.pair = -1; + LP_swap_endcritical = (uint32_t)time(NULL); LP_swapwait(swap,swap->I.req.requestid,swap->I.req.quoteid,LP_atomic_locktime(swap->I.bobstr,swap->I.alicestr)*2,swap->I.aliceconfirms == 0 ? 3 : 30); } } diff --git a/iguana/exchanges/LP_transaction.c b/iguana/exchanges/LP_transaction.c index c2dff6e2e..739711424 100644 --- a/iguana/exchanges/LP_transaction.c +++ b/iguana/exchanges/LP_transaction.c @@ -733,11 +733,11 @@ char *iguana_validaterawtx(void *ctx,struct iguana_info *coin,struct iguana_msgt else complete = 1; jadd(retjson,"interpreter",log); jadd(retjson,"complete",complete!=0?jtrue():jfalse()); - free(serialized), free(serialized2); if ( signedtx != 0 ) free(signedtx); free(V); } + free(serialized), free(serialized2); } //char str[65]; printf("got txid.(%s)\n",bits256_str(str,txid)); } @@ -1325,6 +1325,7 @@ char *LP_withdraw(struct iguana_info *coin,cJSON *argjson) if ( (ap= LP_address_utxo_reset(coin)) == 0 ) { printf("LP_withdraw error utxo reset %s\n",coin->symbol); + free(V); return(0); } privkeys = cJSON_CreateArray(); @@ -1363,6 +1364,8 @@ char *LP_withdraw(struct iguana_info *coin,cJSON *argjson) free_json(privkeys), privkeys = 0; if ( rawtx != 0 ) free(rawtx), rawtx = 0; + if ( signedtx != 0 ) + free(signedtx), signedtx = 0; } free(V); if ( vins != 0 ) From 9cafacd5aa68e20d5debd7d693e309d1ac642096 Mon Sep 17 00:00:00 2001 From: jl777 Date: Mon, 4 Dec 2017 12:15:33 +0400 Subject: [PATCH 1485/1664] Test --- iguana/exchanges/LP_remember.c | 1 + 1 file changed, 1 insertion(+) diff --git a/iguana/exchanges/LP_remember.c b/iguana/exchanges/LP_remember.c index b054f9fdb..d7d900371 100644 --- a/iguana/exchanges/LP_remember.c +++ b/iguana/exchanges/LP_remember.c @@ -1393,6 +1393,7 @@ char *basilisk_swapentries(char *refbase,char *refrel,int32_t limit) } free(liststr); } + if ( 0 ) if ( (liststr= LP_recent_swaps(limit)) != 0 ) { if ( (retjson= cJSON_Parse(liststr)) != 0 ) From 72ac400f635ac2767d3dea4c3734ff6cd1d81c49 Mon Sep 17 00:00:00 2001 From: jl777 Date: Mon, 4 Dec 2017 12:19:27 +0400 Subject: [PATCH 1486/1664] Test --- iguana/exchanges/LP_remember.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/iguana/exchanges/LP_remember.c b/iguana/exchanges/LP_remember.c index d7d900371..946784dee 100644 --- a/iguana/exchanges/LP_remember.c +++ b/iguana/exchanges/LP_remember.c @@ -1368,6 +1368,7 @@ char *basilisk_swapentries(char *refbase,char *refrel,int32_t limit) limit = 10; memset(ridqids,0,sizeof(ridqids)); retarray = cJSON_CreateArray(); + if ( 0 ) if ( (liststr= basilisk_swaplist(0,0,0)) != 0 ) { //printf("swapentry.(%s)\n",liststr); @@ -1393,7 +1394,6 @@ char *basilisk_swapentries(char *refbase,char *refrel,int32_t limit) } free(liststr); } - if ( 0 ) if ( (liststr= LP_recent_swaps(limit)) != 0 ) { if ( (retjson= cJSON_Parse(liststr)) != 0 ) From 39fd183083d6b4b3ec396edf989d70da220d9ed1 Mon Sep 17 00:00:00 2001 From: jl777 Date: Mon, 4 Dec 2017 12:21:19 +0400 Subject: [PATCH 1487/1664] Test --- iguana/exchanges/LP_remember.c | 1 + 1 file changed, 1 insertion(+) diff --git a/iguana/exchanges/LP_remember.c b/iguana/exchanges/LP_remember.c index 946784dee..72d687ffb 100644 --- a/iguana/exchanges/LP_remember.c +++ b/iguana/exchanges/LP_remember.c @@ -1394,6 +1394,7 @@ char *basilisk_swapentries(char *refbase,char *refrel,int32_t limit) } free(liststr); } + if ( 0 ) if ( (liststr= LP_recent_swaps(limit)) != 0 ) { if ( (retjson= cJSON_Parse(liststr)) != 0 ) From 0c64f76e6344bf22810c6bdb4a1b5937cf5d8f2b Mon Sep 17 00:00:00 2001 From: jl777 Date: Mon, 4 Dec 2017 12:23:47 +0400 Subject: [PATCH 1488/1664] Test --- iguana/exchanges/LP_remember.c | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/iguana/exchanges/LP_remember.c b/iguana/exchanges/LP_remember.c index 72d687ffb..9af71a4e8 100644 --- a/iguana/exchanges/LP_remember.c +++ b/iguana/exchanges/LP_remember.c @@ -1240,7 +1240,7 @@ char *basilisk_swaplist(uint32_t origrequestid,uint32_t origquoteid,int32_t forc { if ( count < sizeof(ridqids)/sizeof(*ridqids) ) ridqids[count++] = ridqid; - if ( (item= basilisk_remember(KMDtotals,BTCtotals,requestid,quoteid,0)) != 0 ) + if ( 0 && (item= basilisk_remember(KMDtotals,BTCtotals,requestid,quoteid,0)) != 0 ) jaddi(array,item); } } @@ -1368,7 +1368,6 @@ char *basilisk_swapentries(char *refbase,char *refrel,int32_t limit) limit = 10; memset(ridqids,0,sizeof(ridqids)); retarray = cJSON_CreateArray(); - if ( 0 ) if ( (liststr= basilisk_swaplist(0,0,0)) != 0 ) { //printf("swapentry.(%s)\n",liststr); @@ -1394,7 +1393,6 @@ char *basilisk_swapentries(char *refbase,char *refrel,int32_t limit) } free(liststr); } - if ( 0 ) if ( (liststr= LP_recent_swaps(limit)) != 0 ) { if ( (retjson= cJSON_Parse(liststr)) != 0 ) From 9c8bc8170d1c7a805228d94a35aa9432f4420720 Mon Sep 17 00:00:00 2001 From: jl777 Date: Mon, 4 Dec 2017 12:25:42 +0400 Subject: [PATCH 1489/1664] Test --- iguana/exchanges/LP_remember.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/iguana/exchanges/LP_remember.c b/iguana/exchanges/LP_remember.c index 9af71a4e8..ad8b0fd16 100644 --- a/iguana/exchanges/LP_remember.c +++ b/iguana/exchanges/LP_remember.c @@ -893,6 +893,7 @@ cJSON *basilisk_remember(int64_t *KMDtotals,int64_t *BTCtotals,uint32_t requesti //printf("legacy DB SWAPS.(%u %u) %llu files BOB.(%s) Alice.(%s) src.(%s) dest.(%s)\n",rswap.requestid,rswap.quoteid,(long long)rswap.aliceid,rswap.bobcoin,rswap.alicecoin,rswap.src,rswap.dest); return(cJSON_Parse("{\"error\":\"mismatched bob/alice vs src/dest coins??\"}")); } + return(0); alice = LP_coinfind(rswap.alicecoin); bob = LP_coinfind(rswap.bobcoin); rswap.Atxfee = LP_txfeecalc(alice,rswap.Atxfee,0); @@ -1240,7 +1241,7 @@ char *basilisk_swaplist(uint32_t origrequestid,uint32_t origquoteid,int32_t forc { if ( count < sizeof(ridqids)/sizeof(*ridqids) ) ridqids[count++] = ridqid; - if ( 0 && (item= basilisk_remember(KMDtotals,BTCtotals,requestid,quoteid,0)) != 0 ) + if ( (item= basilisk_remember(KMDtotals,BTCtotals,requestid,quoteid,0)) != 0 ) jaddi(array,item); } } From 6ac7390597b007bfc355f1f218815c82bd974255 Mon Sep 17 00:00:00 2001 From: jl777 Date: Mon, 4 Dec 2017 12:27:18 +0400 Subject: [PATCH 1490/1664] Test --- iguana/exchanges/LP_remember.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/iguana/exchanges/LP_remember.c b/iguana/exchanges/LP_remember.c index ad8b0fd16..db01ed541 100644 --- a/iguana/exchanges/LP_remember.c +++ b/iguana/exchanges/LP_remember.c @@ -884,6 +884,7 @@ cJSON *basilisk_remember(int64_t *KMDtotals,int64_t *BTCtotals,uint32_t requesti 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"); +return(0); LP_swap_load(&rswap,forceflag); memset(zero.bytes,0,sizeof(zero)); otheraddr[0] = 0; @@ -893,7 +894,6 @@ cJSON *basilisk_remember(int64_t *KMDtotals,int64_t *BTCtotals,uint32_t requesti //printf("legacy DB SWAPS.(%u %u) %llu files BOB.(%s) Alice.(%s) src.(%s) dest.(%s)\n",rswap.requestid,rswap.quoteid,(long long)rswap.aliceid,rswap.bobcoin,rswap.alicecoin,rswap.src,rswap.dest); return(cJSON_Parse("{\"error\":\"mismatched bob/alice vs src/dest coins??\"}")); } - return(0); alice = LP_coinfind(rswap.alicecoin); bob = LP_coinfind(rswap.bobcoin); rswap.Atxfee = LP_txfeecalc(alice,rswap.Atxfee,0); From ca2a1c54c95668ce74ae45fc96bcfc58aa85d6a7 Mon Sep 17 00:00:00 2001 From: jl777 Date: Mon, 4 Dec 2017 12:29:25 +0400 Subject: [PATCH 1491/1664] Test --- iguana/exchanges/LP_remember.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/iguana/exchanges/LP_remember.c b/iguana/exchanges/LP_remember.c index db01ed541..bd7bd0de6 100644 --- a/iguana/exchanges/LP_remember.c +++ b/iguana/exchanges/LP_remember.c @@ -712,6 +712,7 @@ int32_t LP_swap_load(struct LP_swap_remember *rswap,int32_t forceflag) } free(fstr); } + return(0); for (i=0; i Date: Mon, 4 Dec 2017 12:31:36 +0400 Subject: [PATCH 1492/1664] Test --- iguana/exchanges/LP_remember.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/iguana/exchanges/LP_remember.c b/iguana/exchanges/LP_remember.c index bd7bd0de6..a1a5e2195 100644 --- a/iguana/exchanges/LP_remember.c +++ b/iguana/exchanges/LP_remember.c @@ -712,7 +712,6 @@ int32_t LP_swap_load(struct LP_swap_remember *rswap,int32_t forceflag) } free(fstr); } - return(0); for (i=0; iiambob = jint(txobj,"iambob"); txid = jbits256(txobj,"txid"); if ( bits256_nonz(txid) == 0 ) + { + free(fstr); continue; + } rswap->txids[i] = txid; if ( jstr(txobj,"Apayment") != 0 ) safecopy(rswap->alicepaymentaddr,jstr(txobj,"Apayment"),sizeof(rswap->alicepaymentaddr)); From 2c85e264f6a89a9847e3eb6457cf2518b731fa67 Mon Sep 17 00:00:00 2001 From: jl777 Date: Mon, 4 Dec 2017 12:35:07 +0400 Subject: [PATCH 1493/1664] Test --- iguana/exchanges/LP_remember.c | 1 + 1 file changed, 1 insertion(+) diff --git a/iguana/exchanges/LP_remember.c b/iguana/exchanges/LP_remember.c index a1a5e2195..e3a1eed24 100644 --- a/iguana/exchanges/LP_remember.c +++ b/iguana/exchanges/LP_remember.c @@ -730,6 +730,7 @@ int32_t LP_swap_load(struct LP_swap_remember *rswap,int32_t forceflag) if ( bits256_nonz(txid) == 0 ) { free(fstr); + free_json(txobj); continue; } rswap->txids[i] = txid; From dd872c5a53df758c49aefac62a4b5f347f756a8d Mon Sep 17 00:00:00 2001 From: jl777 Date: Mon, 4 Dec 2017 13:18:10 +0400 Subject: [PATCH 1494/1664] Test --- iguana/exchanges/LP_rpc.c | 2 +- iguana/exchanges/LP_transaction.c | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/iguana/exchanges/LP_rpc.c b/iguana/exchanges/LP_rpc.c index a9dcfe1e3..ea836ec67 100644 --- a/iguana/exchanges/LP_rpc.c +++ b/iguana/exchanges/LP_rpc.c @@ -372,7 +372,7 @@ int32_t LP_address_isvalid(char *symbol,char *address) isvalid = 1; //printf("%s ismine (%s)\n",address,jprint(retjson,0)); } - //printf("%s\n",jprint(retjson,0)); + printf("%s\n",jprint(retjson,0)); free_json(retjson); } return(isvalid); diff --git a/iguana/exchanges/LP_transaction.c b/iguana/exchanges/LP_transaction.c index 739711424..9de797287 100644 --- a/iguana/exchanges/LP_transaction.c +++ b/iguana/exchanges/LP_transaction.c @@ -1194,7 +1194,7 @@ char *LP_createrawtransaction(cJSON **txobjp,int32_t *numvinsp,struct iguana_inf { if ( LP_address_isvalid(coin->symbol,coinaddr) <= 0 ) { - printf("LP_createrawtransaction %s i.%d of %d is invalid\n",coinaddr,i,numvouts); + printf("%s LP_createrawtransaction %s i.%d of %d is invalid\n",coin->symbol,coinaddr,i,numvouts); return(0); } if ( (value= SATOSHIDEN * jdouble(item,coinaddr)) <= 0 ) From bede70ec6084d1c0f66373bd45594f6503f19e65 Mon Sep 17 00:00:00 2001 From: jl777 Date: Mon, 4 Dec 2017 13:41:54 +0400 Subject: [PATCH 1495/1664] Test --- iguana/exchanges/LP_rpc.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/iguana/exchanges/LP_rpc.c b/iguana/exchanges/LP_rpc.c index ea836ec67..a9dcfe1e3 100644 --- a/iguana/exchanges/LP_rpc.c +++ b/iguana/exchanges/LP_rpc.c @@ -372,7 +372,7 @@ int32_t LP_address_isvalid(char *symbol,char *address) isvalid = 1; //printf("%s ismine (%s)\n",address,jprint(retjson,0)); } - printf("%s\n",jprint(retjson,0)); + //printf("%s\n",jprint(retjson,0)); free_json(retjson); } return(isvalid); From 0786cc20ed2ec982565b3d2cc41785c428b3f2e6 Mon Sep 17 00:00:00 2001 From: jl777 Date: Mon, 4 Dec 2017 13:49:24 +0400 Subject: [PATCH 1496/1664] Test --- iguana/exchanges/LP_transaction.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/iguana/exchanges/LP_transaction.c b/iguana/exchanges/LP_transaction.c index 9de797287..9cba66db9 100644 --- a/iguana/exchanges/LP_transaction.c +++ b/iguana/exchanges/LP_transaction.c @@ -1255,6 +1255,7 @@ char *LP_createrawtransaction(cJSON **txobjp,int32_t *numvinsp,struct iguana_inf if ( (value= SATOSHIDEN * jdouble(item,coinaddr)) <= 0 ) { printf("cant get value i.%d of %d %s\n",i,numvouts,jprint(outputs,0)); + free_json(txobj); return(0); } bitcoin_addr2rmd160(coin->taddr,&addrtype,rmd160,coinaddr); @@ -1272,6 +1273,7 @@ char *LP_createrawtransaction(cJSON **txobjp,int32_t *numvinsp,struct iguana_inf else { printf("cant get fieldname.%d of %d %s\n",i,numvouts,jprint(outputs,0)); + free_json(txobj); return(0); } } @@ -1336,7 +1338,7 @@ char *LP_withdraw(struct iguana_info *coin,cJSON *argjson) 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,coin->zcash)) < 0 ) + if ( 0 && (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,coin->zcash)) < 0 ) printf("couldnt sign withdraw %s\n",bits256_str(str,signedtxid)); else if ( completed == 0 ) { From b7e98852c78dfc6faf161ead1e8a70d513501b7d Mon Sep 17 00:00:00 2001 From: jl777 Date: Mon, 4 Dec 2017 13:57:02 +0400 Subject: [PATCH 1497/1664] Test --- iguana/exchanges/LP_transaction.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/iguana/exchanges/LP_transaction.c b/iguana/exchanges/LP_transaction.c index 9cba66db9..176546e9b 100644 --- a/iguana/exchanges/LP_transaction.c +++ b/iguana/exchanges/LP_transaction.c @@ -511,7 +511,7 @@ int32_t iguana_signrawtransaction(void *ctx,char *symbol,uint8_t wiftaddr,uint8_ //printf("back from bitcoin_hex2json (%s)\n",jprint(vins,0)); } else printf("no txobj from bitcoin_hex2json\n"); //printf("call hex2json.(%s) vins.(%s)\n",rawtx,jprint(vins,0)); - if ( (numinputs= cJSON_GetArraySize(vins)) > 0 ) + if ( 0 && (numinputs= cJSON_GetArraySize(vins)) > 0 ) { //printf("numinputs.%d (%s) msgtx.%d\n",numinputs,jprint(vins,0),msgtx->tx_in); memset(msgtx,0,sizeof(*msgtx)); @@ -1338,7 +1338,7 @@ char *LP_withdraw(struct iguana_info *coin,cJSON *argjson) completed = 0; memset(&msgtx,0,sizeof(msgtx)); memset(signedtxid.bytes,0,sizeof(signedtxid)); - if ( 0 && (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,coin->zcash)) < 0 ) + 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,coin->zcash)) < 0 ) printf("couldnt sign withdraw %s\n",bits256_str(str,signedtxid)); else if ( completed == 0 ) { From 6c2a3ad74522e1be0c5a325272988e66520e834e Mon Sep 17 00:00:00 2001 From: jl777 Date: Mon, 4 Dec 2017 14:00:19 +0400 Subject: [PATCH 1498/1664] Test --- iguana/exchanges/LP_transaction.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/iguana/exchanges/LP_transaction.c b/iguana/exchanges/LP_transaction.c index 176546e9b..bac2a8b61 100644 --- a/iguana/exchanges/LP_transaction.c +++ b/iguana/exchanges/LP_transaction.c @@ -511,11 +511,11 @@ int32_t iguana_signrawtransaction(void *ctx,char *symbol,uint8_t wiftaddr,uint8_ //printf("back from bitcoin_hex2json (%s)\n",jprint(vins,0)); } else printf("no txobj from bitcoin_hex2json\n"); //printf("call hex2json.(%s) vins.(%s)\n",rawtx,jprint(vins,0)); - if ( 0 && (numinputs= cJSON_GetArraySize(vins)) > 0 ) + if ( (numinputs= cJSON_GetArraySize(vins)) > 0 ) { //printf("numinputs.%d (%s) msgtx.%d\n",numinputs,jprint(vins,0),msgtx->tx_in); memset(msgtx,0,sizeof(*msgtx)); - if ( iguana_rwmsgtx(symbol,taddr,pubtype,p2shtype,isPoS,height,0,0,serialized,maxsize,msgtx,&txid,"",extraspace,extralen,vins,V->suppress_pubkeys,zcash) > 0 && numinputs == msgtx->tx_in ) + if ( iguana_rwmsgtx(symbol,taddr,pubtype,p2shtype,isPoS,height,0,0,serialized,maxsize,msgtx,&txid,"",extraspace,extralen,vins,V->suppress_pubkeys,zcash) > 0 && numinputs == msgtx->tx_in && 0 ) { memset(pubkeys,0,sizeof(pubkeys)); memset(privkeys,0,sizeof(privkeys)); From a428c69ec35b9bd8738eca6eea0a524b352036bd Mon Sep 17 00:00:00 2001 From: jl777 Date: Mon, 4 Dec 2017 14:02:52 +0400 Subject: [PATCH 1499/1664] Test --- iguana/exchanges/LP_transaction.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/iguana/exchanges/LP_transaction.c b/iguana/exchanges/LP_transaction.c index bac2a8b61..c563e1ee5 100644 --- a/iguana/exchanges/LP_transaction.c +++ b/iguana/exchanges/LP_transaction.c @@ -477,7 +477,7 @@ int32_t bitcoin_verifyvins(void *ctx,char *symbol,uint8_t taddr,uint8_t pubtype, } } iguana_msgtx_Vset(serialized,maxlen,msgtx,V); - cJSON *txobj = cJSON_CreateObject(); + cJSON *txobj = 0;//cJSON_CreateObject(); *signedtx = iguana_rawtxbytes(symbol,taddr,pubtype,p2shtype,isPoS,height,txobj,msgtx,suppress_pubkeys,zcash); //printf("SIGNEDTX.(%s)\n",jprint(txobj,1)); *signedtxidp = msgtx->txid; @@ -515,7 +515,7 @@ int32_t iguana_signrawtransaction(void *ctx,char *symbol,uint8_t wiftaddr,uint8_ { //printf("numinputs.%d (%s) msgtx.%d\n",numinputs,jprint(vins,0),msgtx->tx_in); memset(msgtx,0,sizeof(*msgtx)); - if ( iguana_rwmsgtx(symbol,taddr,pubtype,p2shtype,isPoS,height,0,0,serialized,maxsize,msgtx,&txid,"",extraspace,extralen,vins,V->suppress_pubkeys,zcash) > 0 && numinputs == msgtx->tx_in && 0 ) + if ( iguana_rwmsgtx(symbol,taddr,pubtype,p2shtype,isPoS,height,0,0,serialized,maxsize,msgtx,&txid,"",extraspace,extralen,vins,V->suppress_pubkeys,zcash) > 0 && numinputs == msgtx->tx_in ) { memset(pubkeys,0,sizeof(pubkeys)); memset(privkeys,0,sizeof(privkeys)); From ac6a388aba719e6f33f5e52e7a25f870a3788644 Mon Sep 17 00:00:00 2001 From: jl777 Date: Mon, 4 Dec 2017 14:50:28 +0400 Subject: [PATCH 1500/1664] Test --- iguana/exchanges/LP_include.h | 6 +++--- iguana/exchanges/LP_swap.c | 19 +++++++------------ 2 files changed, 10 insertions(+), 15 deletions(-) diff --git a/iguana/exchanges/LP_include.h b/iguana/exchanges/LP_include.h index 218dc7867..b008acdc7 100644 --- a/iguana/exchanges/LP_include.h +++ b/iguana/exchanges/LP_include.h @@ -180,12 +180,12 @@ struct vin_info uint8_t rmd160[20],spendscript[10000],p2shscript[10000],userdata[10000]; }; -struct basilisk_swapmessage +/*struct basilisk_swapmessage { bits256 srchash,desthash; uint32_t crc32,msgbits,quoteid,datalen; uint8_t *data; -}; +};*/ struct basilisk_swap; @@ -383,7 +383,7 @@ struct basilisk_swap struct basilisk_swapinfo I; struct basilisk_rawtx bobdeposit,bobpayment,alicepayment,myfee,otherfee,aliceclaim,alicespend,bobreclaim,bobspend,bobrefund,alicereclaim; bits256 privkeys[INSTANTDEX_DECKSIZE]; - struct basilisk_swapmessage *messages; int32_t nummessages,sentflag; + //struct basilisk_swapmessage *messages; int32_t nummessages,sentflag; char Bdeposit[64],Bpayment[64]; uint64_t aliceid,otherdeck[INSTANTDEX_DECKSIZE][2],deck[INSTANTDEX_DECKSIZE][2]; uint8_t persistent_pubkey33[33],persistent_other33[33],changermd160[20],pad[15],verifybuf[100000]; diff --git a/iguana/exchanges/LP_swap.c b/iguana/exchanges/LP_swap.c index fc68657df..a0ab038e7 100644 --- a/iguana/exchanges/LP_swap.c +++ b/iguana/exchanges/LP_swap.c @@ -126,8 +126,8 @@ void basilisk_rawtx_purge(struct basilisk_rawtx *rawtx) void basilisk_swap_finished(struct basilisk_swap *swap) { - int32_t i; - /*if ( swap->utxo != 0 && swap->sentflag == 0 ) + /*int32_t i; + if ( swap->utxo != 0 && swap->sentflag == 0 ) { LP_availableset(swap->utxo); swap->utxo = 0; @@ -159,11 +159,11 @@ void basilisk_swap_finished(struct basilisk_swap *swap) basilisk_rawtx_purge(&swap->bobspend); basilisk_rawtx_purge(&swap->bobrefund); basilisk_rawtx_purge(&swap->alicereclaim); - for (i=0; inummessages; i++) + /*for (i=0; inummessages; i++) if ( swap->messages[i].data != 0 ) free(swap->messages[i].data), swap->messages[i].data = 0; free(swap->messages), swap->messages = 0; - swap->nummessages = 0; + swap->nummessages = 0;*/ if ( swap->N.pair >= 0 ) nn_close(swap->N.pair), swap->N.pair = -1; } @@ -837,7 +837,7 @@ void LP_bobloop(void *_swap) 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->sentflag = 1; swap->bobreclaim.utxovout = 0; swap->bobreclaim.utxotxid = swap->bobpayment.I.signedtxid; basilisk_bobpayment_reclaim(swap,swap->I.callduration); @@ -873,7 +873,7 @@ void LP_aliceloop(void *_swap) printf("error LP_sendwait mostprivs\n"); else if ( basilisk_alicetxs(swap->N.pair,swap,data,maxlen) != 0 ) printf("basilisk_alicetxs error\n"); - else + else if ( 0 ) { LP_swapsfp_update(&swap->I.req); LP_swap_critical = (uint32_t)time(NULL); @@ -905,7 +905,7 @@ void LP_aliceloop(void *_swap) char str[65];printf("%d wait for alicepayment %s numconfs.%d %s %s\n",n,swap->alicepayment.I.destaddr,m,swap->I.alicestr,bits256_str(str,swap->alicepayment.I.signedtxid)); sleep(10); } - swap->sentflag = 1; + //swap->sentflag = 1; LP_swap_critical = (uint32_t)time(NULL); if ( LP_waitfor(swap->N.pair,swap,1800,LP_verify_bobpayment) < 0 ) printf("error waiting for bobpayment\n"); @@ -934,11 +934,6 @@ void LP_aliceloop(void *_swap) } } free(data); - if ( swap->N.pair >= 0 ) - { - nn_close(swap->N.pair); - swap->N.pair = -1; - } basilisk_swap_finished(swap); printf("finish swap.%p\n",swap); free(swap); From 98081bbcf0f8ffe89ff56cc2194f1f326b97c676 Mon Sep 17 00:00:00 2001 From: jl777 Date: Mon, 4 Dec 2017 14:50:59 +0400 Subject: [PATCH 1501/1664] Test --- iguana/exchanges/LP_swap.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/iguana/exchanges/LP_swap.c b/iguana/exchanges/LP_swap.c index a0ab038e7..f61b60f12 100644 --- a/iguana/exchanges/LP_swap.c +++ b/iguana/exchanges/LP_swap.c @@ -873,7 +873,7 @@ void LP_aliceloop(void *_swap) printf("error LP_sendwait mostprivs\n"); else if ( basilisk_alicetxs(swap->N.pair,swap,data,maxlen) != 0 ) printf("basilisk_alicetxs error\n"); - else if ( 0 ) + else { LP_swapsfp_update(&swap->I.req); LP_swap_critical = (uint32_t)time(NULL); From 1ec16db3ff1a3ed2ca0e2c0f8ec8717dc8eef20c Mon Sep 17 00:00:00 2001 From: jl777 Date: Mon, 4 Dec 2017 15:25:38 +0400 Subject: [PATCH 1502/1664] Test --- iguana/exchanges/LP_swap.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/iguana/exchanges/LP_swap.c b/iguana/exchanges/LP_swap.c index f61b60f12..3cea92fa7 100644 --- a/iguana/exchanges/LP_swap.c +++ b/iguana/exchanges/LP_swap.c @@ -862,7 +862,7 @@ void LP_aliceloop(void *_swap) maxlen = 1024*1024 + sizeof(*swap); data = malloc(maxlen); expiration = (uint32_t)time(NULL) + LP_SWAPSTEP_TIMEOUT; - if ( swap != 0 ) + if ( 0 && swap != 0 ) { printf("start swap iamalice pair.%d\n",swap->N.pair); if ( LP_sendwait("pubkeys",120,swap->N.pair,swap,data,maxlen,LP_pubkeys_verify,LP_pubkeys_data) < 0 ) From dad25a0e5dabebfdc74f47e6a3a430602e5454ed Mon Sep 17 00:00:00 2001 From: jl777 Date: Mon, 4 Dec 2017 15:40:30 +0400 Subject: [PATCH 1503/1664] Test --- iguana/exchanges/LP_ordermatch.c | 2 +- iguana/exchanges/LP_swap.c | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/iguana/exchanges/LP_ordermatch.c b/iguana/exchanges/LP_ordermatch.c index 85e4f5088..f23e1a7b5 100644 --- a/iguana/exchanges/LP_ordermatch.c +++ b/iguana/exchanges/LP_ordermatch.c @@ -1168,7 +1168,7 @@ void LP_tradecommandQ(struct LP_quoteinfo *qp,char *pairstr,int32_t funcid) int32_t LP_tradecommand(void *ctx,char *myipaddr,int32_t pubsock,cJSON *argjson,uint8_t *data,int32_t datalen) { - int32_t Qtrades = 1; + int32_t Qtrades = 0; char *method,str[65]; int32_t num,DEXselector = 0; uint64_t aliceid; double qprice,bestprice,price,bid,ask; cJSON *proof; struct iguana_info *coin; struct LP_quoteinfo Q,Q2; int32_t counter,retval=-1; if ( (method= jstr(argjson,"method")) != 0 && (strcmp(method,"reserved") == 0 ||strcmp(method,"connected") == 0 || strcmp(method,"request") == 0 || strcmp(method,"connect") == 0) ) { diff --git a/iguana/exchanges/LP_swap.c b/iguana/exchanges/LP_swap.c index 3cea92fa7..f61b60f12 100644 --- a/iguana/exchanges/LP_swap.c +++ b/iguana/exchanges/LP_swap.c @@ -862,7 +862,7 @@ void LP_aliceloop(void *_swap) maxlen = 1024*1024 + sizeof(*swap); data = malloc(maxlen); expiration = (uint32_t)time(NULL) + LP_SWAPSTEP_TIMEOUT; - if ( 0 && swap != 0 ) + if ( swap != 0 ) { printf("start swap iamalice pair.%d\n",swap->N.pair); if ( LP_sendwait("pubkeys",120,swap->N.pair,swap,data,maxlen,LP_pubkeys_verify,LP_pubkeys_data) < 0 ) From 20deff31f63dc70db4ccd2df9190117fa57bdc0b Mon Sep 17 00:00:00 2001 From: jl777 Date: Mon, 4 Dec 2017 15:53:40 +0400 Subject: [PATCH 1504/1664] Test --- iguana/exchanges/LP_include.h | 1 - iguana/exchanges/LP_ordermatch.c | 2 +- iguana/exchanges/LP_swap.c | 1 - 3 files changed, 1 insertion(+), 3 deletions(-) diff --git a/iguana/exchanges/LP_include.h b/iguana/exchanges/LP_include.h index b008acdc7..90e2ecf14 100644 --- a/iguana/exchanges/LP_include.h +++ b/iguana/exchanges/LP_include.h @@ -387,7 +387,6 @@ struct basilisk_swap char Bdeposit[64],Bpayment[64]; uint64_t aliceid,otherdeck[INSTANTDEX_DECKSIZE][2],deck[INSTANTDEX_DECKSIZE][2]; uint8_t persistent_pubkey33[33],persistent_other33[33],changermd160[20],pad[15],verifybuf[100000]; - }; struct LP_pubkey_quote diff --git a/iguana/exchanges/LP_ordermatch.c b/iguana/exchanges/LP_ordermatch.c index f23e1a7b5..85e4f5088 100644 --- a/iguana/exchanges/LP_ordermatch.c +++ b/iguana/exchanges/LP_ordermatch.c @@ -1168,7 +1168,7 @@ void LP_tradecommandQ(struct LP_quoteinfo *qp,char *pairstr,int32_t funcid) int32_t LP_tradecommand(void *ctx,char *myipaddr,int32_t pubsock,cJSON *argjson,uint8_t *data,int32_t datalen) { - int32_t Qtrades = 0; + int32_t Qtrades = 1; char *method,str[65]; int32_t num,DEXselector = 0; uint64_t aliceid; double qprice,bestprice,price,bid,ask; cJSON *proof; struct iguana_info *coin; struct LP_quoteinfo Q,Q2; int32_t counter,retval=-1; if ( (method= jstr(argjson,"method")) != 0 && (strcmp(method,"reserved") == 0 ||strcmp(method,"connected") == 0 || strcmp(method,"request") == 0 || strcmp(method,"connect") == 0) ) { diff --git a/iguana/exchanges/LP_swap.c b/iguana/exchanges/LP_swap.c index f61b60f12..da7597e47 100644 --- a/iguana/exchanges/LP_swap.c +++ b/iguana/exchanges/LP_swap.c @@ -935,7 +935,6 @@ void LP_aliceloop(void *_swap) } free(data); basilisk_swap_finished(swap); - printf("finish swap.%p\n",swap); free(swap); G.LP_pendingswaps--; } From 965b1900d7880c3fb9a562a055f9bb7f33aeb3e8 Mon Sep 17 00:00:00 2001 From: jl777 Date: Mon, 4 Dec 2017 16:07:38 +0400 Subject: [PATCH 1505/1664] Test --- iguana/exchanges/LP_swap.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/iguana/exchanges/LP_swap.c b/iguana/exchanges/LP_swap.c index da7597e47..1ba9b9011 100644 --- a/iguana/exchanges/LP_swap.c +++ b/iguana/exchanges/LP_swap.c @@ -859,7 +859,7 @@ void LP_aliceloop(void *_swap) { uint8_t *data; int32_t maxlen,n,m; uint32_t expiration; struct basilisk_swap *swap = _swap; G.LP_pendingswaps++; - maxlen = 1024*1024 + sizeof(*swap); + maxlen = 128*1024 + sizeof(*swap); data = malloc(maxlen); expiration = (uint32_t)time(NULL) + LP_SWAPSTEP_TIMEOUT; if ( swap != 0 ) From 1a4922b16461f1a495240dc92c9f8084baac5f89 Mon Sep 17 00:00:00 2001 From: jl777 Date: Mon, 4 Dec 2017 16:12:07 +0400 Subject: [PATCH 1506/1664] Test --- iguana/exchanges/LP_swap.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/iguana/exchanges/LP_swap.c b/iguana/exchanges/LP_swap.c index 1ba9b9011..da7597e47 100644 --- a/iguana/exchanges/LP_swap.c +++ b/iguana/exchanges/LP_swap.c @@ -859,7 +859,7 @@ void LP_aliceloop(void *_swap) { uint8_t *data; int32_t maxlen,n,m; uint32_t expiration; struct basilisk_swap *swap = _swap; G.LP_pendingswaps++; - maxlen = 128*1024 + sizeof(*swap); + maxlen = 1024*1024 + sizeof(*swap); data = malloc(maxlen); expiration = (uint32_t)time(NULL) + LP_SWAPSTEP_TIMEOUT; if ( swap != 0 ) From cb63f2a2853d07e40fa78b9713ef424bd6807e77 Mon Sep 17 00:00:00 2001 From: jl777 Date: Mon, 4 Dec 2017 16:16:21 +0400 Subject: [PATCH 1507/1664] Test --- iguana/exchanges/LP_ordermatch.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/iguana/exchanges/LP_ordermatch.c b/iguana/exchanges/LP_ordermatch.c index 85e4f5088..5ae711df3 100644 --- a/iguana/exchanges/LP_ordermatch.c +++ b/iguana/exchanges/LP_ordermatch.c @@ -655,7 +655,7 @@ char *LP_connectedalice(struct LP_quoteinfo *qp,char *pairstr) // alice //autxo->S.swap = swap; //swap->utxo = autxo; LP_aliceid(qp->tradeid,qp->aliceid,"started",qp->R.requestid,qp->R.quoteid); - printf("alice pairstr.(%s) pairsock.%d\n",pairstr,pairsock); + printf("alice pairstr.(%s) pairsock.%d pthread_t %ld\n",pairstr,pairsock,sizeof(pthread_t)); if ( OS_thread_create(malloc(sizeof(pthread_t)),NULL,(void *)LP_aliceloop,(void *)swap) == 0 ) { retjson = LP_quotejson(qp); From d6bbdc7db3af336c4d18fccf17eba52d67dbe20e Mon Sep 17 00:00:00 2001 From: jl777 Date: Mon, 4 Dec 2017 22:00:08 +0400 Subject: [PATCH 1508/1664] Test --- iguana/exchanges/LP_nativeDEX.c | 1 + iguana/exchanges/LP_stats.c | 3 ++- 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/iguana/exchanges/LP_nativeDEX.c b/iguana/exchanges/LP_nativeDEX.c index 19ee06ace..a7e11ec6c 100644 --- a/iguana/exchanges/LP_nativeDEX.c +++ b/iguana/exchanges/LP_nativeDEX.c @@ -26,6 +26,7 @@ // portfolio value based on ask? // // else claim path +// swap memleak? // 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 diff --git a/iguana/exchanges/LP_stats.c b/iguana/exchanges/LP_stats.c index 06d072285..ec89aa8cf 100644 --- a/iguana/exchanges/LP_stats.c +++ b/iguana/exchanges/LP_stats.c @@ -803,8 +803,9 @@ cJSON *LP_ohlc_json(struct LP_ohlc *bar,struct LP_ohlc *prevbar) memset(&tmp,0,sizeof(tmp)); if ( bar->numtrades == 0 ) { - tmp = *prevbar; + memset(&tmp,0,sizeof(tmp)); tmp.timestamp = bar->timestamp; + tmp.close = bar->close; tmp.numtrades = 0; tmp.relsum = tmp.basesum = 0.; } else tmp = *bar; From 5826a9d21897c04ec6cf9ab30a1f9686ac2edcb3 Mon Sep 17 00:00:00 2001 From: jl777 Date: Mon, 4 Dec 2017 22:06:05 +0400 Subject: [PATCH 1509/1664] Test --- iguana/exchanges/LP_commands.c | 24 ++++++++++++------------ iguana/exchanges/stats.c | 2 +- 2 files changed, 13 insertions(+), 13 deletions(-) diff --git a/iguana/exchanges/LP_commands.c b/iguana/exchanges/LP_commands.c index af24bf929..ebac1c7b4 100644 --- a/iguana/exchanges/LP_commands.c +++ b/iguana/exchanges/LP_commands.c @@ -324,18 +324,6 @@ instantdex_claim()\n\ return(clonestr("{\"error\":\"couldnt set autoprice\"}")); else return(clonestr("{\"result\":\"success\"}")); } - else if ( strcmp(method,"getprice") == 0 ) - { - double price; - price = LP_price(base,rel); - retjson = cJSON_CreateObject(); - jaddstr(retjson,"result","success"); - jaddstr(retjson,"base",base); - jaddstr(retjson,"rel",rel); - jaddnum(retjson,"timestamp",time(NULL)); - jaddnum(retjson,"price",price); - return(jprint(retjson,1)); - } else if ( strcmp(method,"pricearray") == 0 ) { uint32_t firsttime; @@ -634,6 +622,18 @@ instantdex_claim()\n\ return(LP_notify_recv(argjson)); else if ( strcmp(method,"getpeers") == 0 ) retstr = clonestr("{\"error\":\"deprecated\"}"); + else if ( strcmp(method,"getprice") == 0 ) + { + double price; + price = LP_price(base,rel); + retjson = cJSON_CreateObject(); + jaddstr(retjson,"result","success"); + jaddstr(retjson,"base",base); + jaddstr(retjson,"rel",rel); + jaddnum(retjson,"timestamp",time(NULL)); + jaddnum(retjson,"price",price); + return(jprint(retjson,1)); + } /*else if ( strcmp(method,"getpeers") == 0 ) { char *tmpstr; diff --git a/iguana/exchanges/stats.c b/iguana/exchanges/stats.c index abb7b785d..352a38c70 100644 --- a/iguana/exchanges/stats.c +++ b/iguana/exchanges/stats.c @@ -32,7 +32,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", + "psock", "getprice", "notify", "getpeers", // from issue_ "uitem", "listunspent", "orderbook", "statsdisp", "help", "getcoins", "pricearray", "balance", "tradesarray" }; From 72284c1df1d8c73953c14ca4c01f762f5b2a66c7 Mon Sep 17 00:00:00 2001 From: jl777 Date: Mon, 4 Dec 2017 22:09:43 +0400 Subject: [PATCH 1510/1664] Test --- iguana/exchanges/LP_stats.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/iguana/exchanges/LP_stats.c b/iguana/exchanges/LP_stats.c index ec89aa8cf..f97cd28a6 100644 --- a/iguana/exchanges/LP_stats.c +++ b/iguana/exchanges/LP_stats.c @@ -805,7 +805,7 @@ cJSON *LP_ohlc_json(struct LP_ohlc *bar,struct LP_ohlc *prevbar) { memset(&tmp,0,sizeof(tmp)); tmp.timestamp = bar->timestamp; - tmp.close = bar->close; + tmp.open = tmp.close = bar->close; tmp.numtrades = 0; tmp.relsum = tmp.basesum = 0.; } else tmp = *bar; From 3e55ceee10464151283623be0c0212915ce2d067 Mon Sep 17 00:00:00 2001 From: jl777 Date: Mon, 4 Dec 2017 22:14:49 +0400 Subject: [PATCH 1511/1664] Test --- iguana/exchanges/LP_stats.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/iguana/exchanges/LP_stats.c b/iguana/exchanges/LP_stats.c index f97cd28a6..12762b39d 100644 --- a/iguana/exchanges/LP_stats.c +++ b/iguana/exchanges/LP_stats.c @@ -805,7 +805,7 @@ cJSON *LP_ohlc_json(struct LP_ohlc *bar,struct LP_ohlc *prevbar) { memset(&tmp,0,sizeof(tmp)); tmp.timestamp = bar->timestamp; - tmp.open = tmp.close = bar->close; + tmp.open = tmp.high = tmp.low = tmp.close = prevbar->close; tmp.numtrades = 0; tmp.relsum = tmp.basesum = 0.; } else tmp = *bar; From 3287f0ace2cf0595921dc30a18b4854612968353 Mon Sep 17 00:00:00 2001 From: jl777 Date: Tue, 5 Dec 2017 12:05:50 +0400 Subject: [PATCH 1512/1664] Balances --- iguana/exchanges/LP_commands.c | 3 ++ iguana/exchanges/LP_statemachine.c | 15 +++++++++ iguana/exchanges/LP_utxo.c | 49 +++++++++++++++++++----------- iguana/exchanges/balances | 3 ++ iguana/exchanges/install | 2 +- iguana/exchanges/mm.c | 15 +++++++-- 6 files changed, 66 insertions(+), 21 deletions(-) create mode 100755 iguana/exchanges/balances diff --git a/iguana/exchanges/LP_commands.c b/iguana/exchanges/LP_commands.c index ebac1c7b4..3366a94cf 100644 --- a/iguana/exchanges/LP_commands.c +++ b/iguana/exchanges/LP_commands.c @@ -135,6 +135,7 @@ listunspent(coin, address)\n\ setconfirms(coin, numconfirms, maxconfirms=6)\n\ trust(pubkey, trust) # positive to trust, 0 for normal, negative to blacklist\n\ balance(coin, address)\n\ +balances(address)\n\ orderbook(base, rel, duration=3600)\n\ getprices()\n\ getprice(base, rel)\n\ @@ -256,6 +257,8 @@ instantdex_claim()\n\ return(LP_peers()); else if ( strcmp(method,"getcoins") == 0 ) return(jprint(LP_coinsjson(0),1)); + else if ( strcmp(method,"balances") == 0 ) + return(jprint(LP_balances(),1)); else if ( strcmp(method,"notarizations") == 0 ) { if ( (ptr= LP_coinsearch(coin)) != 0 ) diff --git a/iguana/exchanges/LP_statemachine.c b/iguana/exchanges/LP_statemachine.c index 34549ebf7..bb3754605 100644 --- a/iguana/exchanges/LP_statemachine.c +++ b/iguana/exchanges/LP_statemachine.c @@ -3597,6 +3597,21 @@ void LP_price_broadcastloop(void *ctx) break; } return(clonestr("{\"error\":\"no instantdex deposits to claim\"}"));*/ +/*else + { + if ( (array= LP_address_utxos(coin,coinaddr,1)) != 0 ) + { + if ( (n= cJSON_GetArraySize(array)) > 0 ) + { + for (i=0; ielectrum == 0 ) { - memset(zero.bytes,0,sizeof(zero)); if ( (array= LP_listunspent(coin->symbol,coinaddr,zero,zero)) != 0 ) { if ( (n= cJSON_GetArraySize(array)) > 0 ) @@ -596,23 +596,12 @@ cJSON *LP_address_balance(struct iguana_info *coin,char *coinaddr,int32_t electr } else { - //if ( strcmp(coin->smartaddr,coinaddr) == 0 ) - balance = LP_unspents_load(coin->symbol,coinaddr); - /*else + if ( strcmp(coin->smartaddr,coinaddr) != 0 ) { - if ( (array= LP_address_utxos(coin,coinaddr,1)) != 0 ) - { - if ( (n= cJSON_GetArraySize(array)) > 0 ) - { - for (i=0; isymbol,coin->electrum,&retjson,coinaddr,2,zero,zero)) != 0 ) + free_json(retjson); + } + balance = LP_unspents_load(coin->symbol,coinaddr); } retjson = cJSON_CreateObject(); jaddstr(retjson,"result","success"); @@ -627,6 +616,32 @@ cJSON *LP_address_balance(struct iguana_info *coin,char *coinaddr,int32_t electr return(retjson); } +cJSON *LP_balances() +{ + struct iguana_info *coin,*tmp; char *symbol; cJSON *array,*item,*retjson; + array = cJSON_CreateArray(); + HASH_ITER(hh,LP_coins,coin,tmp) + { + if ( (retjson= LP_address_balance(coin,coin->smartaddr,1)) != 0 ) + { + if ( (symbol= jstr(retjson,"coin")) != 0 ) + { + item = cJSON_CreateObject(); + jaddstr(item,"coin",symbol); + jaddnum(item,"balance",jdouble(retjson,"balance")); + if ( strcmp(symbol,"KMD") == 0 ) + { + jaddnum(item,"zcredits",jdouble(retjson,"zcredits")); + jadd(item,"zdebits",jobj(retjson,"zdebits")); + } + jaddi(array,item); + } + free_json(retjson); + } + } + return(array); +} + int32_t LP_unspents_array(struct iguana_info *coin,char *coinaddr,cJSON *array) { int32_t i,n,v,errs,height,count=0; uint64_t value,val; cJSON *item,*txobj; bits256 txid; diff --git a/iguana/exchanges/balances b/iguana/exchanges/balances new file mode 100755 index 000000000..1eb527b8f --- /dev/null +++ b/iguana/exchanges/balances @@ -0,0 +1,3 @@ +#!/bin/bash +source userpass +curl --url "http://127.0.0.1:7783" --data "{\"userpass\":\"$userpass\",\"method\":\"balances\"}" diff --git a/iguana/exchanges/install b/iguana/exchanges/install index b4feab5c9..8518efa3c 100755 --- a/iguana/exchanges/install +++ b/iguana/exchanges/install @@ -1,5 +1,5 @@ #!/bin/bash -cp dynamictrust getcoin kickstart tradesarray claim deposit10 deposit1 invreset sendrawtransaction processfiles stop millis mnzservers bot_buy bot_list bot_statuslist bot_pause bot_resume bot_sell bot_settings bot_status bot_stop guistats pubkeystats pendings coinswaps baserelswaps setpassphrase notarizations getrawtransaction parselog statsdisp m_js 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 balances dynamictrust getcoin kickstart tradesarray claim deposit10 deposit1 invreset sendrawtransaction processfiles stop millis mnzservers bot_buy bot_list bot_statuslist bot_pause bot_resume bot_sell bot_settings bot_status bot_stop guistats pubkeystats pendings coinswaps baserelswaps setpassphrase notarizations getrawtransaction parselog statsdisp m_js 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 . diff --git a/iguana/exchanges/mm.c b/iguana/exchanges/mm.c index ec3aba913..c3ae78957 100644 --- a/iguana/exchanges/mm.c +++ b/iguana/exchanges/mm.c @@ -884,9 +884,18 @@ int main(int argc, const char * argv[]) { uint8_t addrtype,rmd160[20],rmd160b[20]; char coinaddr[64],coinaddr2[64]; bitcoin_addr2rmd160(0,&addrtype,rmd160,(char *)argv[1]); - bitcoin_address(coinaddr,0,60,rmd160,20); - bitcoin_addr2rmd160(0,&addrtype,rmd160b,coinaddr); - bitcoin_address(coinaddr2,0,0,rmd160b,20); + if ( addrtype == 0 ) + { + bitcoin_address(coinaddr,0,60,rmd160,20); + bitcoin_addr2rmd160(0,&addrtype,rmd160b,coinaddr); + bitcoin_address(coinaddr2,0,0,rmd160b,20); + } + else if ( addrtype == 60 ) + { + bitcoin_address(coinaddr,0,0,rmd160,20); + bitcoin_addr2rmd160(0,&addrtype,rmd160b,coinaddr); + bitcoin_address(coinaddr2,0,60,rmd160b,20); + } printf("(%s) -> %s -> %s\n",(char *)argv[1],coinaddr,coinaddr2); if ( strcmp((char *)argv[1],coinaddr2) != 0 ) printf("ERROR\n"); From b04b72a074114fa5a0d3bc4ff9cf381ffe96b8b7 Mon Sep 17 00:00:00 2001 From: jl777 Date: Tue, 5 Dec 2017 12:08:50 +0400 Subject: [PATCH 1513/1664] Test --- iguana/exchanges/LP_utxo.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/iguana/exchanges/LP_utxo.c b/iguana/exchanges/LP_utxo.c index 3636c57d9..3b9a853b1 100644 --- a/iguana/exchanges/LP_utxo.c +++ b/iguana/exchanges/LP_utxo.c @@ -618,21 +618,21 @@ cJSON *LP_address_balance(struct iguana_info *coin,char *coinaddr,int32_t electr cJSON *LP_balances() { - struct iguana_info *coin,*tmp; char *symbol; cJSON *array,*item,*retjson; + struct iguana_info *coin,*tmp; double balance; char *symbol; cJSON *array,*item,*retjson; array = cJSON_CreateArray(); HASH_ITER(hh,LP_coins,coin,tmp) { if ( (retjson= LP_address_balance(coin,coin->smartaddr,1)) != 0 ) { - if ( (symbol= jstr(retjson,"coin")) != 0 ) + if ( (symbol= jstr(retjson,"coin")) != 0 && (balance= jdouble(retjson,"balance")) > SMALLVAL ) { item = cJSON_CreateObject(); jaddstr(item,"coin",symbol); - jaddnum(item,"balance",jdouble(retjson,"balance")); + jaddnum(item,"balance",balance); if ( strcmp(symbol,"KMD") == 0 ) { jaddnum(item,"zcredits",jdouble(retjson,"zcredits")); - jadd(item,"zdebits",jobj(retjson,"zdebits")); + jadd(item,"zdebits",LP_myzdebits()); } jaddi(array,item); } From 21c1a79efcf1961a3e25a4387f68f00d9c5326fe Mon Sep 17 00:00:00 2001 From: jl777 Date: Tue, 5 Dec 2017 12:14:35 +0400 Subject: [PATCH 1514/1664] Test --- iguana/exchanges/LP_utxo.c | 22 +++++++++------------- 1 file changed, 9 insertions(+), 13 deletions(-) diff --git a/iguana/exchanges/LP_utxo.c b/iguana/exchanges/LP_utxo.c index 3b9a853b1..84fc92df7 100644 --- a/iguana/exchanges/LP_utxo.c +++ b/iguana/exchanges/LP_utxo.c @@ -618,25 +618,21 @@ cJSON *LP_address_balance(struct iguana_info *coin,char *coinaddr,int32_t electr cJSON *LP_balances() { - struct iguana_info *coin,*tmp; double balance; char *symbol; cJSON *array,*item,*retjson; + struct iguana_info *coin,*tmp; uint64_t balance; char *symbol; cJSON *array,*item; array = cJSON_CreateArray(); HASH_ITER(hh,LP_coins,coin,tmp) { - if ( (retjson= LP_address_balance(coin,coin->smartaddr,1)) != 0 ) + if ( (balance= LP_RTsmartbalance(coin)) != 0 ) { - if ( (symbol= jstr(retjson,"coin")) != 0 && (balance= jdouble(retjson,"balance")) > SMALLVAL ) + item = cJSON_CreateObject(); + jaddstr(item,"coin",coin->symbol); + jaddnum(item,"balance",dstr(balance)); + if ( strcmp(symbol,"KMD") == 0 ) { - item = cJSON_CreateObject(); - jaddstr(item,"coin",symbol); - jaddnum(item,"balance",balance); - if ( strcmp(symbol,"KMD") == 0 ) - { - jaddnum(item,"zcredits",jdouble(retjson,"zcredits")); - jadd(item,"zdebits",LP_myzdebits()); - } - jaddi(array,item); + jaddnum(item,"zcredits",dstr(LP_myzcredits())); + jadd(item,"zdebits",LP_myzdebits()); } - free_json(retjson); + jaddi(array,item); } } return(array); From f6cc03b2c1306890b5f0948ad93bd6315b324409 Mon Sep 17 00:00:00 2001 From: jl777 Date: Tue, 5 Dec 2017 12:17:04 +0400 Subject: [PATCH 1515/1664] Test --- iguana/exchanges/LP_utxo.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/iguana/exchanges/LP_utxo.c b/iguana/exchanges/LP_utxo.c index 84fc92df7..93e1b7af1 100644 --- a/iguana/exchanges/LP_utxo.c +++ b/iguana/exchanges/LP_utxo.c @@ -618,7 +618,7 @@ cJSON *LP_address_balance(struct iguana_info *coin,char *coinaddr,int32_t electr cJSON *LP_balances() { - struct iguana_info *coin,*tmp; uint64_t balance; char *symbol; cJSON *array,*item; + struct iguana_info *coin,*tmp; uint64_t balance; cJSON *array,*item; array = cJSON_CreateArray(); HASH_ITER(hh,LP_coins,coin,tmp) { @@ -627,7 +627,7 @@ cJSON *LP_balances() item = cJSON_CreateObject(); jaddstr(item,"coin",coin->symbol); jaddnum(item,"balance",dstr(balance)); - if ( strcmp(symbol,"KMD") == 0 ) + if ( strcmp(coin->symbol,"KMD") == 0 ) { jaddnum(item,"zcredits",dstr(LP_myzcredits())); jadd(item,"zdebits",LP_myzdebits()); From bb36566caff7c316f584b968de5a72dd23f04667 Mon Sep 17 00:00:00 2001 From: jl777 Date: Tue, 5 Dec 2017 12:30:10 +0400 Subject: [PATCH 1516/1664] Test --- iguana/exchanges/LP_commands.c | 2 +- iguana/exchanges/LP_utxo.c | 37 +++++++++++++------ iguana/m_splitfund | 65 +++++++++++++++++----------------- 3 files changed, 61 insertions(+), 43 deletions(-) diff --git a/iguana/exchanges/LP_commands.c b/iguana/exchanges/LP_commands.c index 3366a94cf..01a35472a 100644 --- a/iguana/exchanges/LP_commands.c +++ b/iguana/exchanges/LP_commands.c @@ -258,7 +258,7 @@ instantdex_claim()\n\ else if ( strcmp(method,"getcoins") == 0 ) return(jprint(LP_coinsjson(0),1)); else if ( strcmp(method,"balances") == 0 ) - return(jprint(LP_balances(),1)); + return(jprint(LP_balances(jstr(argjson,"address")),1)); else if ( strcmp(method,"notarizations") == 0 ) { if ( (ptr= LP_coinsearch(coin)) != 0 ) diff --git a/iguana/exchanges/LP_utxo.c b/iguana/exchanges/LP_utxo.c index 93e1b7af1..961f96b4a 100644 --- a/iguana/exchanges/LP_utxo.c +++ b/iguana/exchanges/LP_utxo.c @@ -616,23 +616,40 @@ cJSON *LP_address_balance(struct iguana_info *coin,char *coinaddr,int32_t electr return(retjson); } -cJSON *LP_balances() +cJSON *LP_balances(char *coinaddr) { - struct iguana_info *coin,*tmp; uint64_t balance; cJSON *array,*item; + struct iguana_info *coin,*tmp; uint64_t balance; cJSON *array,*item,*retjson; array = cJSON_CreateArray(); HASH_ITER(hh,LP_coins,coin,tmp) { - if ( (balance= LP_RTsmartbalance(coin)) != 0 ) + if ( coinaddr != 0 && strcmp(coinaddr,coin->smartaddr) == 0 ) { - item = cJSON_CreateObject(); - jaddstr(item,"coin",coin->symbol); - jaddnum(item,"balance",dstr(balance)); - if ( strcmp(coin->symbol,"KMD") == 0 ) + if ( (balance= LP_RTsmartbalance(coin)) != 0 ) { - jaddnum(item,"zcredits",dstr(LP_myzcredits())); - jadd(item,"zdebits",LP_myzdebits()); + item = cJSON_CreateObject(); + jaddstr(item,"coin",coin->symbol); + jaddnum(item,"balance",dstr(balance)); + if ( strcmp(coin->symbol,"KMD") == 0 ) + { + jaddnum(item,"zcredits",dstr(LP_myzcredits())); + jadd(item,"zdebits",LP_myzdebits()); + } + jaddi(array,item); + } + } + else + { + if ( (retjson= LP_address_balance(coin,coinaddr,1)) != 0 ) + { + if ( (balance= jdouble(retjson,"balance")*SATOSHIDEN) > 0 ) + { + item = cJSON_CreateObject(); + jaddstr(item,"coin",coin->symbol); + jaddnum(item,"balance",dstr(balance)); + jaddi(array,item); + } + free_json(retjson); } - jaddi(array,item); } } return(array); diff --git a/iguana/m_splitfund b/iguana/m_splitfund index 342f8e6de..9e445cd6b 100755 --- a/iguana/m_splitfund +++ b/iguana/m_splitfund @@ -14,6 +14,7 @@ curl --url "http://127.0.0.1:7776" --data "{\"coin\":\"BET\",\"agent\":\"iguana\ curl --url "http://127.0.0.1:7776" --data "{\"coin\":\"CRYPTO\",\"agent\":\"iguana\",\"method\":\"splitfunds\",\"satoshis\":\"50000\",\"sendflag\":1,\"duplicates\":10}" curl --url "http://127.0.0.1:7776" --data "{\"coin\":\"HODL\",\"agent\":\"iguana\",\"method\":\"splitfunds\",\"satoshis\":\"50000\",\"sendflag\":1,\"duplicates\":10}" curl --url "http://127.0.0.1:7776" --data "{\"coin\":\"SHARK\",\"agent\":\"iguana\",\"method\":\"splitfunds\",\"satoshis\":\"50000\",\"sendflag\":1,\"duplicates\":10}" +curl --url "http://127.0.0.1:7776" --data "{\"coin\":\"MSHARK\",\"agent\":\"iguana\",\"method\":\"splitfunds\",\"satoshis\":\"50000\",\"sendflag\":1,\"duplicates\":10}" curl --url "http://127.0.0.1:7776" --data "{\"coin\":\"BOTS\",\"agent\":\"iguana\",\"method\":\"splitfunds\",\"satoshis\":\"50000\",\"sendflag\":1,\"duplicates\":10}" curl --url "http://127.0.0.1:7776" --data "{\"coin\":\"MGW\",\"agent\":\"iguana\",\"method\":\"splitfunds\",\"satoshis\":\"50000\",\"sendflag\":1,\"duplicates\":10}" #curl --url "http://127.0.0.1:7776" --data "{\"coin\":\"MVP\",\"agent\":\"iguana\",\"method\":\"splitfunds\",\"satoshis\":\"50000\",\"sendflag\":1,\"duplicates\":10}" @@ -24,36 +25,36 @@ curl --url "http://127.0.0.1:7776" --data "{\"coin\":\"CEAL\",\"agent\":\"iguana curl --url "http://127.0.0.1:7776" --data "{\"coin\":\"MESH\",\"agent\":\"iguana\",\"method\":\"splitfunds\",\"satoshis\":\"50000\",\"sendflag\":1,\"duplicates\":10}" curl --url "http://127.0.0.1:7776" --data "{\"coin\":\"MNZ\",\"agent\":\"iguana\",\"method\":\"splitfunds\",\"satoshis\":\"50000\",\"sendflag\":1,\"duplicates\":10}" -curl --url "http://127.0.0.1:7776" --data "{\"coin\":\"USD\",\"agent\":\"iguana\",\"method\":\"splitfunds\",\"satoshis\":\"50000\",\"sendflag\":1,\"duplicates\":10}" -curl --url "http://127.0.0.1:7776" --data "{\"coin\":\"EUR\",\"agent\":\"iguana\",\"method\":\"splitfunds\",\"satoshis\":\"50000\",\"sendflag\":1,\"duplicates\":10}" +#curl --url "http://127.0.0.1:7776" --data "{\"coin\":\"USD\",\"agent\":\"iguana\",\"method\":\"splitfunds\",\"satoshis\":\"50000\",\"sendflag\":1,\"duplicates\":10}" +#curl --url "http://127.0.0.1:7776" --data "{\"coin\":\"EUR\",\"agent\":\"iguana\",\"method\":\"splitfunds\",\"satoshis\":\"50000\",\"sendflag\":1,\"duplicates\":10}" -curl --url "http://127.0.0.1:7776" --data "{\"coin\":\"JPY\",\"agent\":\"iguana\",\"method\":\"splitfunds\",\"satoshis\":\"50000\",\"sendflag\":1,\"duplicates\":10}" -curl --url "http://127.0.0.1:7776" --data "{\"coin\":\"GBP\",\"agent\":\"iguana\",\"method\":\"splitfunds\",\"satoshis\":\"50000\",\"sendflag\":1,\"duplicates\":10}" -curl --url "http://127.0.0.1:7776" --data "{\"coin\":\"AUD\",\"agent\":\"iguana\",\"method\":\"splitfunds\",\"satoshis\":\"50000\",\"sendflag\":1,\"duplicates\":10}" -curl --url "http://127.0.0.1:7776" --data "{\"coin\":\"CAD\",\"agent\":\"iguana\",\"method\":\"splitfunds\",\"satoshis\":\"50000\",\"sendflag\":1,\"duplicates\":10}" -curl --url "http://127.0.0.1:7776" --data "{\"coin\":\"CHF\",\"agent\":\"iguana\",\"method\":\"splitfunds\",\"satoshis\":\"50000\",\"sendflag\":1,\"duplicates\":10}" -curl --url "http://127.0.0.1:7776" --data "{\"coin\":\"NZD\",\"agent\":\"iguana\",\"method\":\"splitfunds\",\"satoshis\":\"50000\",\"sendflag\":1,\"duplicates\":10}" -curl --url "http://127.0.0.1:7776" --data "{\"coin\":\"CNY\",\"agent\":\"iguana\",\"method\":\"splitfunds\",\"satoshis\":\"50000\",\"sendflag\":1,\"duplicates\":10}" -curl --url "http://127.0.0.1:7776" --data "{\"coin\":\"RUB\",\"agent\":\"iguana\",\"method\":\"splitfunds\",\"satoshis\":\"50000\",\"sendflag\":1,\"duplicates\":10}" -curl --url "http://127.0.0.1:7776" --data "{\"coin\":\"MXN\",\"agent\":\"iguana\",\"method\":\"splitfunds\",\"satoshis\":\"50000\",\"sendflag\":1,\"duplicates\":10}" -curl --url "http://127.0.0.1:7776" --data "{\"coin\":\"BRL\",\"agent\":\"iguana\",\"method\":\"splitfunds\",\"satoshis\":\"50000\",\"sendflag\":1,\"duplicates\":10}" -curl --url "http://127.0.0.1:7776" --data "{\"coin\":\"INR\",\"agent\":\"iguana\",\"method\":\"splitfunds\",\"satoshis\":\"50000\",\"sendflag\":1,\"duplicates\":10}" -curl --url "http://127.0.0.1:7776" --data "{\"coin\":\"HKD\",\"agent\":\"iguana\",\"method\":\"splitfunds\",\"satoshis\":\"50000\",\"sendflag\":1,\"duplicates\":10}" -curl --url "http://127.0.0.1:7776" --data "{\"coin\":\"TRY\",\"agent\":\"iguana\",\"method\":\"splitfunds\",\"satoshis\":\"50000\",\"sendflag\":1,\"duplicates\":10}" -curl --url "http://127.0.0.1:7776" --data "{\"coin\":\"ZAR\",\"agent\":\"iguana\",\"method\":\"splitfunds\",\"satoshis\":\"50000\",\"sendflag\":1,\"duplicates\":10}" -curl --url "http://127.0.0.1:7776" --data "{\"coin\":\"PLN\",\"agent\":\"iguana\",\"method\":\"splitfunds\",\"satoshis\":\"50000\",\"sendflag\":1,\"duplicates\":10}" -curl --url "http://127.0.0.1:7776" --data "{\"coin\":\"NOK\",\"agent\":\"iguana\",\"method\":\"splitfunds\",\"satoshis\":\"50000\",\"sendflag\":1,\"duplicates\":10}" -curl --url "http://127.0.0.1:7776" --data "{\"coin\":\"SEK\",\"agent\":\"iguana\",\"method\":\"splitfunds\",\"satoshis\":\"50000\",\"sendflag\":1,\"duplicates\":10}" -curl --url "http://127.0.0.1:7776" --data "{\"coin\":\"DKK\",\"agent\":\"iguana\",\"method\":\"splitfunds\",\"satoshis\":\"50000\",\"sendflag\":1,\"duplicates\":10}" -curl --url "http://127.0.0.1:7776" --data "{\"coin\":\"CZK\",\"agent\":\"iguana\",\"method\":\"splitfunds\",\"satoshis\":\"50000\",\"sendflag\":1,\"duplicates\":10}" -curl --url "http://127.0.0.1:7776" --data "{\"coin\":\"HUF\",\"agent\":\"iguana\",\"method\":\"splitfunds\",\"satoshis\":\"50000\",\"sendflag\":1,\"duplicates\":10}" -curl --url "http://127.0.0.1:7776" --data "{\"coin\":\"ILS\",\"agent\":\"iguana\",\"method\":\"splitfunds\",\"satoshis\":\"50000\",\"sendflag\":1,\"duplicates\":10}" -curl --url "http://127.0.0.1:7776" --data "{\"coin\":\"KRW\",\"agent\":\"iguana\",\"method\":\"splitfunds\",\"satoshis\":\"50000\",\"sendflag\":1,\"duplicates\":10}" -curl --url "http://127.0.0.1:7776" --data "{\"coin\":\"MYR\",\"agent\":\"iguana\",\"method\":\"splitfunds\",\"satoshis\":\"50000\",\"sendflag\":1,\"duplicates\":10}" -curl --url "http://127.0.0.1:7776" --data "{\"coin\":\"PHP\",\"agent\":\"iguana\",\"method\":\"splitfunds\",\"satoshis\":\"50000\",\"sendflag\":1,\"duplicates\":10}" -curl --url "http://127.0.0.1:7776" --data "{\"coin\":\"RON\",\"agent\":\"iguana\",\"method\":\"splitfunds\",\"satoshis\":\"50000\",\"sendflag\":1,\"duplicates\":10}" -curl --url "http://127.0.0.1:7776" --data "{\"coin\":\"SGD\",\"agent\":\"iguana\",\"method\":\"splitfunds\",\"satoshis\":\"50000\",\"sendflag\":1,\"duplicates\":10}" -curl --url "http://127.0.0.1:7776" --data "{\"coin\":\"THB\",\"agent\":\"iguana\",\"method\":\"splitfunds\",\"satoshis\":\"50000\",\"sendflag\":1,\"duplicates\":10}" -curl --url "http://127.0.0.1:7776" --data "{\"coin\":\"BGN\",\"agent\":\"iguana\",\"method\":\"splitfunds\",\"satoshis\":\"50000\",\"sendflag\":1,\"duplicates\":10}" -curl --url "http://127.0.0.1:7776" --data "{\"coin\":\"IDR\",\"agent\":\"iguana\",\"method\":\"splitfunds\",\"satoshis\":\"50000\",\"sendflag\":1,\"duplicates\":10}" -curl --url "http://127.0.0.1:7776" --data "{\"coin\":\"HRK\",\"agent\":\"iguana\",\"method\":\"splitfunds\",\"satoshis\":\"50000\",\"sendflag\":1,\"duplicates\":10}" +#curl --url "http://127.0.0.1:7776" --data "{\"coin\":\"JPY\",\"agent\":\"iguana\",\"method\":\"splitfunds\",\"satoshis\":\"50000\",\"sendflag\":1,\"duplicates\":10}" +#curl --url "http://127.0.0.1:7776" --data "{\"coin\":\"GBP\",\"agent\":\"iguana\",\"method\":\"splitfunds\",\"satoshis\":\"50000\",\"sendflag\":1,\"duplicates\":10}" +#curl --url "http://127.0.0.1:7776" --data "{\"coin\":\"AUD\",\"agent\":\"iguana\",\"method\":\"splitfunds\",\"satoshis\":\"50000\",\"sendflag\":1,\"duplicates\":10}" +#curl --url "http://127.0.0.1:7776" --data "{\"coin\":\"CAD\",\"agent\":\"iguana\",\"method\":\"splitfunds\",\"satoshis\":\"50000\",\"sendflag\":1,\"duplicates\":10}" +#curl --url "http://127.0.0.1:7776" --data "{\"coin\":\"CHF\",\"agent\":\"iguana\",\"method\":\"splitfunds\",\"satoshis\":\"50000\",\"sendflag\":1,\"duplicates\":10}" +#curl --url "http://127.0.0.1:7776" --data "{\"coin\":\"NZD\",\"agent\":\"iguana\",\"method\":\"splitfunds\",\"satoshis\":\"50000\",\"sendflag\":1,\"duplicates\":10}" +#curl --url "http://127.0.0.1:7776" --data "{\"coin\":\"CNY\",\"agent\":\"iguana\",\"method\":\"splitfunds\",\"satoshis\":\"50000\",\"sendflag\":1,\"duplicates\":10}" +#curl --url "http://127.0.0.1:7776" --data "{\"coin\":\"RUB\",\"agent\":\"iguana\",\"method\":\"splitfunds\",\"satoshis\":\"50000\",\"sendflag\":1,\"duplicates\":10}" +#curl --url "http://127.0.0.1:7776" --data "{\"coin\":\"MXN\",\"agent\":\"iguana\",\"method\":\"splitfunds\",\"satoshis\":\"50000\",\"sendflag\":1,\"duplicates\":10}" +#curl --url "http://127.0.0.1:7776" --data "{\"coin\":\"BRL\",\"agent\":\"iguana\",\"method\":\"splitfunds\",\"satoshis\":\"50000\",\"sendflag\":1,\"duplicates\":10}" +#curl --url "http://127.0.0.1:7776" --data "{\"coin\":\"INR\",\"agent\":\"iguana\",\"method\":\"splitfunds\",\"satoshis\":\"50000\",\"sendflag\":1,\"duplicates\":10}" +#curl --url "http://127.0.0.1:7776" --data "{\"coin\":\"HKD\",\"agent\":\"iguana\",\"method\":\"splitfunds\",\"satoshis\":\"50000\",\"sendflag\":1,\"duplicates\":10}" +#curl --url "http://127.0.0.1:7776" --data "{\"coin\":\"TRY\",\"agent\":\"iguana\",\"method\":\"splitfunds\",\"satoshis\":\"50000\",\"sendflag\":1,\"duplicates\":10}" +#curl --url "http://127.0.0.1:7776" --data "{\"coin\":\"ZAR\",\"agent\":\"iguana\",\"method\":\"splitfunds\",\"satoshis\":\"50000\",\"sendflag\":1,\"duplicates\":10}" +#curl --url "http://127.0.0.1:7776" --data "{\"coin\":\"PLN\",\"agent\":\"iguana\",\"method\":\"splitfunds\",\"satoshis\":\"50000\",\"sendflag\":1,\"duplicates\":10}" +#curl --url "http://127.0.0.1:7776" --data "{\"coin\":\"NOK\",\"agent\":\"iguana\",\"method\":\"splitfunds\",\"satoshis\":\"50000\",\"sendflag\":1,\"duplicates\":10}" +#curl --url "http://127.0.0.1:7776" --data "{\"coin\":\"SEK\",\"agent\":\"iguana\",\"method\":\"splitfunds\",\"satoshis\":\"50000\",\"sendflag\":1,\"duplicates\":10}" +#curl --url "http://127.0.0.1:7776" --data "{\"coin\":\"DKK\",\"agent\":\"iguana\",\"method\":\"splitfunds\",\"satoshis\":\"50000\",\"sendflag\":1,\"duplicates\":10}" +#curl --url "http://127.0.0.1:7776" --data "{\"coin\":\"CZK\",\"agent\":\"iguana\",\"method\":\"splitfunds\",\"satoshis\":\"50000\",\"sendflag\":1,\"duplicates\":10}" +#curl --url "http://127.0.0.1:7776" --data "{\"coin\":\"HUF\",\"agent\":\"iguana\",\"method\":\"splitfunds\",\"satoshis\":\"50000\",\"sendflag\":1,\"duplicates\":10}" +#curl --url "http://127.0.0.1:7776" --data "{\"coin\":\"ILS\",\"agent\":\"iguana\",\"method\":\"splitfunds\",\"satoshis\":\"50000\",\"sendflag\":1,\"duplicates\":10}" +#curl --url "http://127.0.0.1:7776" --data "{\"coin\":\"KRW\",\"agent\":\"iguana\",\"method\":\"splitfunds\",\"satoshis\":\"50000\",\"sendflag\":1,\"duplicates\":10}" +#curl --url "http://127.0.0.1:7776" --data "{\"coin\":\"MYR\",\"agent\":\"iguana\",\"method\":\"splitfunds\",\"satoshis\":\"50000\",\"sendflag\":1,\"duplicates\":10}" +#curl --url "http://127.0.0.1:7776" --data "{\"coin\":\"PHP\",\"agent\":\"iguana\",\"method\":\"splitfunds\",\"satoshis\":\"50000\",\"sendflag\":1,\"duplicates\":10}" +#curl --url "http://127.0.0.1:7776" --data "{\"coin\":\"RON\",\"agent\":\"iguana\",\"method\":\"splitfunds\",\"satoshis\":\"50000\",\"sendflag\":1,\"duplicates\":10}" +#curl --url "http://127.0.0.1:7776" --data "{\"coin\":\"SGD\",\"agent\":\"iguana\",\"method\":\"splitfunds\",\"satoshis\":\"50000\",\"sendflag\":1,\"duplicates\":10}" +#curl --url "http://127.0.0.1:7776" --data "{\"coin\":\"THB\",\"agent\":\"iguana\",\"method\":\"splitfunds\",\"satoshis\":\"50000\",\"sendflag\":1,\"duplicates\":10}" +#curl --url "http://127.0.0.1:7776" --data "{\"coin\":\"BGN\",\"agent\":\"iguana\",\"method\":\"splitfunds\",\"satoshis\":\"50000\",\"sendflag\":1,\"duplicates\":10}" +#curl --url "http://127.0.0.1:7776" --data "{\"coin\":\"IDR\",\"agent\":\"iguana\",\"method\":\"splitfunds\",\"satoshis\":\"50000\",\"sendflag\":1,\"duplicates\":10}" +#curl --url "http://127.0.0.1:7776" --data "{\"coin\":\"HRK\",\"agent\":\"iguana\",\"method\":\"splitfunds\",\"satoshis\":\"50000\",\"sendflag\":1,\"duplicates\":10}" From a2f6819adf870b69d1b83bc61b04f44f09ee6b47 Mon Sep 17 00:00:00 2001 From: jl777 Date: Tue, 5 Dec 2017 12:32:52 +0400 Subject: [PATCH 1517/1664] Test --- iguana/exchanges/LP_utxo.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/iguana/exchanges/LP_utxo.c b/iguana/exchanges/LP_utxo.c index 961f96b4a..4424cbb4a 100644 --- a/iguana/exchanges/LP_utxo.c +++ b/iguana/exchanges/LP_utxo.c @@ -622,7 +622,7 @@ cJSON *LP_balances(char *coinaddr) array = cJSON_CreateArray(); HASH_ITER(hh,LP_coins,coin,tmp) { - if ( coinaddr != 0 && strcmp(coinaddr,coin->smartaddr) == 0 ) + if ( (coinaddr == 0 || coinaddr[0] == 0) && strcmp(coinaddr,coin->smartaddr) == 0 ) { if ( (balance= LP_RTsmartbalance(coin)) != 0 ) { @@ -637,7 +637,7 @@ cJSON *LP_balances(char *coinaddr) jaddi(array,item); } } - else + else if ( coinaddr != 0 && coinaddr[0] != 0 ) { if ( (retjson= LP_address_balance(coin,coinaddr,1)) != 0 ) { From bb9548fc5a26023cbd60963f4de751dbc384eb8c Mon Sep 17 00:00:00 2001 From: jl777 Date: Tue, 5 Dec 2017 12:36:17 +0400 Subject: [PATCH 1518/1664] Test --- iguana/exchanges/LP_utxo.c | 30 +++++++++++++++--------------- 1 file changed, 15 insertions(+), 15 deletions(-) diff --git a/iguana/exchanges/LP_utxo.c b/iguana/exchanges/LP_utxo.c index 4424cbb4a..20d92b4e9 100644 --- a/iguana/exchanges/LP_utxo.c +++ b/iguana/exchanges/LP_utxo.c @@ -622,7 +622,21 @@ cJSON *LP_balances(char *coinaddr) array = cJSON_CreateArray(); HASH_ITER(hh,LP_coins,coin,tmp) { - if ( (coinaddr == 0 || coinaddr[0] == 0) && strcmp(coinaddr,coin->smartaddr) == 0 ) + if ( coinaddr != 0 && coinaddr[0] != 0 && strcmp(coinaddr,coin->smartaddr) != 0 ) + { + if ( (retjson= LP_address_balance(coin,coinaddr,1)) != 0 ) + { + if ( (balance= jdouble(retjson,"balance")*SATOSHIDEN) > 0 ) + { + item = cJSON_CreateObject(); + jaddstr(item,"coin",coin->symbol); + jaddnum(item,"balance",dstr(balance)); + jaddi(array,item); + } + free_json(retjson); + } + } + else { if ( (balance= LP_RTsmartbalance(coin)) != 0 ) { @@ -637,20 +651,6 @@ cJSON *LP_balances(char *coinaddr) jaddi(array,item); } } - else if ( coinaddr != 0 && coinaddr[0] != 0 ) - { - if ( (retjson= LP_address_balance(coin,coinaddr,1)) != 0 ) - { - if ( (balance= jdouble(retjson,"balance")*SATOSHIDEN) > 0 ) - { - item = cJSON_CreateObject(); - jaddstr(item,"coin",coin->symbol); - jaddnum(item,"balance",dstr(balance)); - jaddi(array,item); - } - free_json(retjson); - } - } } return(array); } From b8c2217191c862c0ffe304c7de9dc879fb62c4ca Mon Sep 17 00:00:00 2001 From: jl777 Date: Tue, 5 Dec 2017 12:38:23 +0400 Subject: [PATCH 1519/1664] Test --- iguana/exchanges/supernet | 3 +++ 1 file changed, 3 insertions(+) create mode 100755 iguana/exchanges/supernet diff --git a/iguana/exchanges/supernet b/iguana/exchanges/supernet new file mode 100755 index 000000000..0f0e991ff --- /dev/null +++ b/iguana/exchanges/supernet @@ -0,0 +1,3 @@ +#!/bin/bash +source userpass +curl --url "http://127.0.0.1:7783" --data "{\"userpass\":\"$userpass\",\"method\":\"balances\",\"address\":\"RRyyejME7LRTuvdziWsXkAbSW1fdiohGwK\"}" From 349689a5ad3ed2b9bb65582571662aded5b0cfe8 Mon Sep 17 00:00:00 2001 From: jl777 Date: Tue, 5 Dec 2017 12:45:36 +0400 Subject: [PATCH 1520/1664] Test --- iguana/exchanges/LP_rpc.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/iguana/exchanges/LP_rpc.c b/iguana/exchanges/LP_rpc.c index a9dcfe1e3..b2520d41e 100644 --- a/iguana/exchanges/LP_rpc.c +++ b/iguana/exchanges/LP_rpc.c @@ -407,7 +407,7 @@ cJSON *LP_listunspent(char *symbol,char *coinaddr,bits256 reftxid,bits256 reftxi numconfs = 0; else numconfs = 1; sprintf(buf,"[%d, 99999999, [\"%s\"]]",numconfs,coinaddr); - //printf("LP_listunspent.(%s %s)\n",symbol,coinaddr); +printf("LP_listunspent.(%s %s)\n",symbol,coinaddr); retjson = bitcoin_json(coin,"listunspent",buf); retstr = jprint(retjson,0); LP_unspents_cache(coin->symbol,coinaddr,retstr,1); From 72892f33f0ac2c0e54c924fd7a0b1ffce12f42bd Mon Sep 17 00:00:00 2001 From: jl777 Date: Tue, 5 Dec 2017 12:49:11 +0400 Subject: [PATCH 1521/1664] Test --- iguana/exchanges/LP_rpc.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/iguana/exchanges/LP_rpc.c b/iguana/exchanges/LP_rpc.c index b2520d41e..b9e922832 100644 --- a/iguana/exchanges/LP_rpc.c +++ b/iguana/exchanges/LP_rpc.c @@ -388,7 +388,7 @@ cJSON *LP_listunspent(char *symbol,char *coinaddr,bits256 reftxid,bits256 reftxi return(cJSON_Parse("{\"error\":\"no coin\"}")); if ( coin->electrum == 0 ) { - if ( (ap= LP_addressfind(coin,symbol)) != 0 ) + if ( (ap= LP_addressfind(coin,coinaddr)) != 0 ) { if ( ap->unspenttime == 0 ) usecache = 0; @@ -407,7 +407,7 @@ cJSON *LP_listunspent(char *symbol,char *coinaddr,bits256 reftxid,bits256 reftxi numconfs = 0; else numconfs = 1; sprintf(buf,"[%d, 99999999, [\"%s\"]]",numconfs,coinaddr); -printf("LP_listunspent.(%s %s)\n",symbol,coinaddr); +//printf("LP_listunspent.(%s %s)\n",symbol,coinaddr); retjson = bitcoin_json(coin,"listunspent",buf); retstr = jprint(retjson,0); LP_unspents_cache(coin->symbol,coinaddr,retstr,1); From 241d5c0698341a3d99e775a575a9621e4d78c7e1 Mon Sep 17 00:00:00 2001 From: jl777 Date: Tue, 5 Dec 2017 12:53:14 +0400 Subject: [PATCH 1522/1664] Test --- iguana/exchanges/LP_rpc.c | 1 + 1 file changed, 1 insertion(+) diff --git a/iguana/exchanges/LP_rpc.c b/iguana/exchanges/LP_rpc.c index b9e922832..77bf909e1 100644 --- a/iguana/exchanges/LP_rpc.c +++ b/iguana/exchanges/LP_rpc.c @@ -394,6 +394,7 @@ cJSON *LP_listunspent(char *symbol,char *coinaddr,bits256 reftxid,bits256 reftxi usecache = 0; else if ( G.LP_pendingswaps != 0 && time(NULL) > ap->unspenttime+1 ) usecache = 0; + printf("%s ap.%p unspent.%u usecache.%d iswatched.%d\n",coinaddr,ap,ap->unspenttime,usecache,LP_address_iswatched(symbol,coinaddr)); if ( usecache != 0 && (retstr= LP_unspents_filestr(symbol,coinaddr)) != 0 ) { retjson = cJSON_Parse(retstr); From 9aa65e53816b948cb350c72abd4e2961acb6a536 Mon Sep 17 00:00:00 2001 From: jl777 Date: Tue, 5 Dec 2017 12:58:25 +0400 Subject: [PATCH 1523/1664] Test --- iguana/exchanges/LP_rpc.c | 2 +- iguana/exchanges/LP_utxo.c | 6 ++++-- iguana/exchanges/supernet | 1 + 3 files changed, 6 insertions(+), 3 deletions(-) diff --git a/iguana/exchanges/LP_rpc.c b/iguana/exchanges/LP_rpc.c index 77bf909e1..a89240311 100644 --- a/iguana/exchanges/LP_rpc.c +++ b/iguana/exchanges/LP_rpc.c @@ -394,7 +394,6 @@ cJSON *LP_listunspent(char *symbol,char *coinaddr,bits256 reftxid,bits256 reftxi usecache = 0; else if ( G.LP_pendingswaps != 0 && time(NULL) > ap->unspenttime+1 ) usecache = 0; - printf("%s ap.%p unspent.%u usecache.%d iswatched.%d\n",coinaddr,ap,ap->unspenttime,usecache,LP_address_iswatched(symbol,coinaddr)); if ( usecache != 0 && (retstr= LP_unspents_filestr(symbol,coinaddr)) != 0 ) { retjson = cJSON_Parse(retstr); @@ -402,6 +401,7 @@ cJSON *LP_listunspent(char *symbol,char *coinaddr,bits256 reftxid,bits256 reftxi return(retjson); } } + printf("%s usecache.%d iswatched.%d\n",coinaddr,usecache,LP_address_iswatched(symbol,coinaddr)); if ( LP_address_ismine(symbol,coinaddr) > 0 || LP_address_iswatched(symbol,coinaddr) > 0 ) { if ( strcmp(symbol,"BTC") == 0 ) diff --git a/iguana/exchanges/LP_utxo.c b/iguana/exchanges/LP_utxo.c index 20d92b4e9..fb0cb5bd8 100644 --- a/iguana/exchanges/LP_utxo.c +++ b/iguana/exchanges/LP_utxo.c @@ -618,13 +618,15 @@ cJSON *LP_address_balance(struct iguana_info *coin,char *coinaddr,int32_t electr cJSON *LP_balances(char *coinaddr) { - struct iguana_info *coin,*tmp; uint64_t balance; cJSON *array,*item,*retjson; + struct iguana_info *coin,*tmp; char address[64]; uint8_t addrtype,rmd160[20]; uint64_t balance; cJSON *array,*item,*retjson; array = cJSON_CreateArray(); HASH_ITER(hh,LP_coins,coin,tmp) { if ( coinaddr != 0 && coinaddr[0] != 0 && strcmp(coinaddr,coin->smartaddr) != 0 ) { - if ( (retjson= LP_address_balance(coin,coinaddr,1)) != 0 ) + bitcoin_addr2rmd160(0,&addrtype,rmd160,coinaddr); + bitcoin_address(address,coin->taddr,coin->pubtype,rmd160,20); + if ( (retjson= LP_address_balance(coin,address,1)) != 0 ) { if ( (balance= jdouble(retjson,"balance")*SATOSHIDEN) > 0 ) { diff --git a/iguana/exchanges/supernet b/iguana/exchanges/supernet index 0f0e991ff..803341f7a 100755 --- a/iguana/exchanges/supernet +++ b/iguana/exchanges/supernet @@ -1,3 +1,4 @@ #!/bin/bash source userpass +# this will only work for watchonly addresses that have been rescanned and with active coins curl --url "http://127.0.0.1:7783" --data "{\"userpass\":\"$userpass\",\"method\":\"balances\",\"address\":\"RRyyejME7LRTuvdziWsXkAbSW1fdiohGwK\"}" From e71550b1f8b66c10174b812744d0fd3672ae0360 Mon Sep 17 00:00:00 2001 From: jl777 Date: Tue, 5 Dec 2017 13:00:42 +0400 Subject: [PATCH 1524/1664] Test --- iguana/exchanges/LP_rpc.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/iguana/exchanges/LP_rpc.c b/iguana/exchanges/LP_rpc.c index a89240311..371633af4 100644 --- a/iguana/exchanges/LP_rpc.c +++ b/iguana/exchanges/LP_rpc.c @@ -352,9 +352,9 @@ int32_t LP_address_iswatched(char *symbol,char *address) if ( (obj= jobj(retjson,"iswatched")) != 0 && is_cJSON_True(obj) != 0 ) { doneflag = 1; - //printf("%s ismine (%s)\n",address,jprint(retjson,0)); + printf("%s iswatched (%s)\n",address,jprint(retjson,0)); } - //printf("%s\n",jprint(retjson,0)); + printf("%s\n",jprint(retjson,0)); free_json(retjson); } return(doneflag); From dc0f3843af9fbbbf50527e4747e38b327b83d7ea Mon Sep 17 00:00:00 2001 From: jl777 Date: Tue, 5 Dec 2017 13:04:46 +0400 Subject: [PATCH 1525/1664] Test --- iguana/exchanges/LP_rpc.c | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/iguana/exchanges/LP_rpc.c b/iguana/exchanges/LP_rpc.c index 371633af4..da4d62e62 100644 --- a/iguana/exchanges/LP_rpc.c +++ b/iguana/exchanges/LP_rpc.c @@ -342,19 +342,19 @@ int32_t LP_address_ismine(char *symbol,char *address) return(doneflag); } -int32_t LP_address_iswatched(char *symbol,char *address) +int32_t LP_address_iswatchonly(char *symbol,char *address) { int32_t doneflag = 0; cJSON *retjson,*obj; if ( symbol == 0 || symbol[0] == 0 ) return(0); if ( (retjson= LP_validateaddress(symbol,address)) != 0 ) { - if ( (obj= jobj(retjson,"iswatched")) != 0 && is_cJSON_True(obj) != 0 ) + if ( (obj= jobj(retjson,"iswatchonly")) != 0 && is_cJSON_True(obj) != 0 ) { doneflag = 1; - printf("%s iswatched (%s)\n",address,jprint(retjson,0)); + printf("%s iswatchonly (%s)\n",address,jprint(retjson,0)); } - printf("%s\n",jprint(retjson,0)); + //printf("%s\n",jprint(retjson,0)); free_json(retjson); } return(doneflag); @@ -401,8 +401,8 @@ cJSON *LP_listunspent(char *symbol,char *coinaddr,bits256 reftxid,bits256 reftxi return(retjson); } } - printf("%s usecache.%d iswatched.%d\n",coinaddr,usecache,LP_address_iswatched(symbol,coinaddr)); - if ( LP_address_ismine(symbol,coinaddr) > 0 || LP_address_iswatched(symbol,coinaddr) > 0 ) + printf("%s %s usecache.%d iswatched.%d\n",coin->symbol,coinaddr,usecache,LP_address_iswatchonly(symbol,coinaddr)); + if ( LP_address_ismine(symbol,coinaddr) > 0 || LP_address_iswatchonly(symbol,coinaddr) > 0 ) { if ( strcmp(symbol,"BTC") == 0 ) numconfs = 0; From 57b32ee40b7ab3da0274ed35edfc4d898295eab5 Mon Sep 17 00:00:00 2001 From: jl777 Date: Tue, 5 Dec 2017 13:11:33 +0400 Subject: [PATCH 1526/1664] Test --- iguana/exchanges/LP_rpc.c | 2 +- iguana/exchanges/enable | 14 ++++++++++++-- iguana/exchanges/stats.c | 2 +- 3 files changed, 14 insertions(+), 4 deletions(-) diff --git a/iguana/exchanges/LP_rpc.c b/iguana/exchanges/LP_rpc.c index da4d62e62..2751fb467 100644 --- a/iguana/exchanges/LP_rpc.c +++ b/iguana/exchanges/LP_rpc.c @@ -401,7 +401,7 @@ cJSON *LP_listunspent(char *symbol,char *coinaddr,bits256 reftxid,bits256 reftxi return(retjson); } } - printf("%s %s usecache.%d iswatched.%d\n",coin->symbol,coinaddr,usecache,LP_address_iswatchonly(symbol,coinaddr)); + //printf("%s %s usecache.%d iswatched.%d\n",coin->symbol,coinaddr,usecache,LP_address_iswatchonly(symbol,coinaddr)); if ( LP_address_ismine(symbol,coinaddr) > 0 || LP_address_iswatchonly(symbol,coinaddr) > 0 ) { if ( strcmp(symbol,"BTC") == 0 ) diff --git a/iguana/exchanges/enable b/iguana/exchanges/enable index 90b006dfe..eb53f31d6 100755 --- a/iguana/exchanges/enable +++ b/iguana/exchanges/enable @@ -1,5 +1,15 @@ #!/bin/bash source userpass curl --url "http://127.0.0.1:7783" --data "{\"userpass\":\"$userpass\",\"method\":\"enable\",\"coin\":\"REVS\"}" -curl --url "http://127.0.0.1:7783" --data "{\"userpass\":\"$userpass\",\"method\":\"enable\",\"coin\":\"CHIPS\"}" -curl --url "http://127.0.0.1:7783" --data "{\"userpass\":\"$userpass\",\"method\":\"enable\",\"coin\":\"MNZ\"}" +curl --url "http://127.0.0.1:7783" --data "{\"userpass\":\"$userpass\",\"method\":\"enable\",\"coin\":\"KMD\"}" +curl --url "http://127.0.0.1:7783" --data "{\"userpass\":\"$userpass\",\"method\":\"enable\",\"coin\":\"BTC\"}" +curl --url "http://127.0.0.1:7783" --data "{\"userpass\":\"$userpass\",\"method\":\"enable\",\"coin\":\"SUPERNET\"}" +curl --url "http://127.0.0.1:7783" --data "{\"userpass\":\"$userpass\",\"method\":\"enable\",\"coin\":\"CRYPTO\"}" +curl --url "http://127.0.0.1:7783" --data "{\"userpass\":\"$userpass\",\"method\":\"enable\",\"coin\":\"DEX\"}" +curl --url "http://127.0.0.1:7783" --data "{\"userpass\":\"$userpass\",\"method\":\"enable\",\"coin\":\"BOTS\"}" +curl --url "http://127.0.0.1:7783" --data "{\"userpass\":\"$userpass\",\"method\":\"enable\",\"coin\":\"BET\"}" +curl --url "http://127.0.0.1:7783" --data "{\"userpass\":\"$userpass\",\"method\":\"enable\",\"coin\":\"HODL\"}" +curl --url "http://127.0.0.1:7783" --data "{\"userpass\":\"$userpass\",\"method\":\"enable\",\"coin\":\"MSHARK\"}" +curl --url "http://127.0.0.1:7783" --data "{\"userpass\":\"$userpass\",\"method\":\"enable\",\"coin\":\"MGW\"}" +curl --url "http://127.0.0.1:7783" --data "{\"userpass\":\"$userpass\",\"method\":\"enable\",\"coin\":\"PANGEA\"}" +curl --url "http://127.0.0.1:7783" --data "{\"userpass\":\"$userpass\",\"method\":\"enable\",\"coin\":\"JUMBLR\"}" diff --git a/iguana/exchanges/stats.c b/iguana/exchanges/stats.c index 352a38c70..7df5ec8eb 100644 --- a/iguana/exchanges/stats.c +++ b/iguana/exchanges/stats.c @@ -32,7 +32,7 @@ char *stats_JSON(void *ctx,char *myipaddr,int32_t mypubsock,cJSON *argjson,char char *stats_validmethods[] = { - "psock", "getprice", "notify", "getpeers", // from issue_ "uitem", "listunspent", + "psock", "balances", "getprice", "notify", "getpeers", // from issue_ "uitem", "listunspent", "orderbook", "statsdisp", "help", "getcoins", "pricearray", "balance", "tradesarray" }; From 1a9051a43b8de9373fc9eaa3c2f9bd31fdde163a Mon Sep 17 00:00:00 2001 From: jl777 Date: Tue, 5 Dec 2017 13:35:08 +0400 Subject: [PATCH 1527/1664] Test --- iguana/exchanges/LP_commands.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/iguana/exchanges/LP_commands.c b/iguana/exchanges/LP_commands.c index 01a35472a..7056e7de9 100644 --- a/iguana/exchanges/LP_commands.c +++ b/iguana/exchanges/LP_commands.c @@ -257,8 +257,6 @@ instantdex_claim()\n\ return(LP_peers()); else if ( strcmp(method,"getcoins") == 0 ) return(jprint(LP_coinsjson(0),1)); - else if ( strcmp(method,"balances") == 0 ) - return(jprint(LP_balances(jstr(argjson,"address")),1)); else if ( strcmp(method,"notarizations") == 0 ) { if ( (ptr= LP_coinsearch(coin)) != 0 ) @@ -625,6 +623,8 @@ instantdex_claim()\n\ return(LP_notify_recv(argjson)); else if ( strcmp(method,"getpeers") == 0 ) retstr = clonestr("{\"error\":\"deprecated\"}"); + else if ( strcmp(method,"balances") == 0 ) + return(jprint(LP_balances(jstr(argjson,"address")),1)); else if ( strcmp(method,"getprice") == 0 ) { double price; From abec70cf5ad0204e4e49230d883c9757841c9da3 Mon Sep 17 00:00:00 2001 From: jl777 Date: Tue, 5 Dec 2017 13:45:35 +0400 Subject: [PATCH 1528/1664] Test --- iguana/exchanges/mm.c | 2 ++ iguana/exchanges/stats.c | 2 +- 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/iguana/exchanges/mm.c b/iguana/exchanges/mm.c index c3ae78957..3a03962a1 100644 --- a/iguana/exchanges/mm.c +++ b/iguana/exchanges/mm.c @@ -34,6 +34,7 @@ void PNACL_message(char *arg,...) #include "../../crypto777/OS_portable.h" #endif // !_WIN_32 +int32_t DOCKERFLAG; #define MAX(a,b) ((a) > (b) ? (a) : (b)) char *stats_JSON(void *ctx,char *myipaddr,int32_t pubsock,cJSON *argjson,char *remoteaddr,uint16_t port); #include "stats.c" @@ -920,6 +921,7 @@ int main(int argc, const char * argv[]) } if ( argc > 1 && (retjson= cJSON_Parse(argv[1])) != 0 ) { + DOCKERFLAG = jint(retjson,"docker"); if ( (passphrase= jstr(retjson,"passphrase")) == 0 ) jaddstr(retjson,"passphrase","test"); if ( OS_thread_create(malloc(sizeof(pthread_t)),NULL,(void *)LP_main,(void *)retjson) != 0 ) diff --git a/iguana/exchanges/stats.c b/iguana/exchanges/stats.c index 7df5ec8eb..08765f940 100644 --- a/iguana/exchanges/stats.c +++ b/iguana/exchanges/stats.c @@ -815,7 +815,7 @@ void stats_rpcloop(void *args) } #endif*/ memcpy(&ipbits,&cli_addr.sin_addr.s_addr,sizeof(ipbits)); - if ( port == RPC_port && ipbits != localhostbits ) + if ( DOCKERFLAG == 0 && port == RPC_port && ipbits != localhostbits ) { //printf("port.%u RPC_port.%u ipbits %x != %x\n",port,RPC_port,ipbits,localhostbits); closesocket(sock); From 07d142c2c9ed6a357739d36d203c1c38bf8f1584 Mon Sep 17 00:00:00 2001 From: jl777 Date: Tue, 5 Dec 2017 14:48:57 +0400 Subject: [PATCH 1529/1664] Docker flag --- iguana/exchanges/stats.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/iguana/exchanges/stats.c b/iguana/exchanges/stats.c index 08765f940..0241f66ac 100644 --- a/iguana/exchanges/stats.c +++ b/iguana/exchanges/stats.c @@ -39,6 +39,8 @@ char *stats_validmethods[] = int32_t LP_valid_remotemethod(cJSON *argjson) { char *method; int32_t i; + if ( DOCKERFLAG != 0 ) + return(1); if ( (method= jstr(argjson,"method")) != 0 ) { for (i=0; i Date: Tue, 5 Dec 2017 15:13:08 +0400 Subject: [PATCH 1530/1664] Test --- iguana/exchanges/LP_prices.c | 53 ++++++++++++++++-------------- iguana/exchanges/LP_statemachine.c | 24 ++++++++++++++ iguana/exchanges/stats.c | 4 ++- 3 files changed, 56 insertions(+), 25 deletions(-) diff --git a/iguana/exchanges/LP_prices.c b/iguana/exchanges/LP_prices.c index 16efbe735..587efe5ff 100644 --- a/iguana/exchanges/LP_prices.c +++ b/iguana/exchanges/LP_prices.c @@ -908,30 +908,6 @@ int64_t LP_KMDvalue(struct iguana_info *coin,int64_t balance) { if ( strcmp(coin->symbol,"KMD") == 0 ) KMDvalue = balance; - /*else if ( (retstr= LP_orderbook(coin->symbol,"KMD",-1)) != 0 ) - { - if ( (orderbook= cJSON_Parse(retstr)) != 0 ) - { - if ( (asks= jarray(&numasks,orderbook,"asks")) != 0 && numasks > 0 ) - { - item = jitem(asks,0); - price = ask = jdouble(item,"price"); - //printf("%s/%s ask %.8f\n",coin->symbol,"KMD",ask); - } - if ( (bids= jarray(&numbids,orderbook,"bids")) != 0 && numbids > 0 ) - { - item = jitem(asks,0); - bid = jdouble(item,"price"); - if ( price == 0. ) - price = bid; - else price = (bid + ask) * 0.5; - //printf("%s/%s bid %.8f ask %.8f price %.8f\n",coin->symbol,"KMD",bid,ask,price); - } - KMDvalue = price * balance; - free_json(orderbook); - } - free(retstr); - }*/ else { price = LP_price(coin->symbol,"KMD"); @@ -1138,3 +1114,32 @@ void LP_pricefeedupdate(bits256 pubkey,char *base,char *rel,double price,char *u // printf("error finding %s/%s %.8f\n",base,rel,price); } +cJSON *LP_fundvalue(cJSON *argjson) +{ + cJSON *holdings,*item,*newitem; int32_t i,n; double btcprice,balance,btcsum; struct iguana_info *coin; char *symbol; int64_t fundvalue,KMDvalue = 0; + fundvalue = 0; + btcsum = 0.; + if ( (holdings= jarray(&n,argjson,"holdings")) != 0 ) + { + for (i=0; i SMALLVAL ) + { + item = cJSON_CreateObject(); + jaddstr(item,"coin",symbol); + if ( (coin= LP_coinfind(symbol)) != 0 && (KMDvalue= LP_KMDvalue(coin,SATOSHIDEN * balance)) > 0 ) + { + jaddnum(item,"KMD",dstr(KMDvalue)); + fundvalue += KMDvalue; + } + else if ( (btcprice= LP_CMCbtcprice(symbol)) > SMALLVAL ) + { + btcsum += btcprice * balance; + jaddnum(item,"BTC",btcprice * balance); + } + } + } + } +} + diff --git a/iguana/exchanges/LP_statemachine.c b/iguana/exchanges/LP_statemachine.c index bb3754605..d970974e8 100644 --- a/iguana/exchanges/LP_statemachine.c +++ b/iguana/exchanges/LP_statemachine.c @@ -2094,6 +2094,30 @@ char *LP_postutxos_recv(cJSON *argjson) } return(clonestr("{\"error\":\"sig failure\"}")); } +/*else if ( (retstr= LP_orderbook(coin->symbol,"KMD",-1)) != 0 ) + { + if ( (orderbook= cJSON_Parse(retstr)) != 0 ) + { + if ( (asks= jarray(&numasks,orderbook,"asks")) != 0 && numasks > 0 ) + { + item = jitem(asks,0); + price = ask = jdouble(item,"price"); + //printf("%s/%s ask %.8f\n",coin->symbol,"KMD",ask); + } + if ( (bids= jarray(&numbids,orderbook,"bids")) != 0 && numbids > 0 ) + { + item = jitem(asks,0); + bid = jdouble(item,"price"); + if ( price == 0. ) + price = bid; + else price = (bid + ask) * 0.5; + //printf("%s/%s bid %.8f ask %.8f price %.8f\n",coin->symbol,"KMD",bid,ask,price); + } + KMDvalue = price * balance; + free_json(orderbook); + } + free(retstr); + }*/ int32_t LP_utxosQ_process() { diff --git a/iguana/exchanges/stats.c b/iguana/exchanges/stats.c index 0241f66ac..06a44a920 100644 --- a/iguana/exchanges/stats.c +++ b/iguana/exchanges/stats.c @@ -817,7 +817,9 @@ void stats_rpcloop(void *args) } #endif*/ memcpy(&ipbits,&cli_addr.sin_addr.s_addr,sizeof(ipbits)); - if ( DOCKERFLAG == 0 && port == RPC_port && ipbits != localhostbits ) + if ( DOCKERFLAG != 0 ) + ipbits = localhostbits; + if ( port == RPC_port && ipbits != localhostbits ) { //printf("port.%u RPC_port.%u ipbits %x != %x\n",port,RPC_port,ipbits,localhostbits); closesocket(sock); From e774b5ff4c332e42df6a30ca38b3a8b0eac3efb9 Mon Sep 17 00:00:00 2001 From: jl777 Date: Tue, 5 Dec 2017 15:14:57 +0400 Subject: [PATCH 1531/1664] Test --- iguana/exchanges/LP_prices.c | 18 +++++++++++++++--- 1 file changed, 15 insertions(+), 3 deletions(-) diff --git a/iguana/exchanges/LP_prices.c b/iguana/exchanges/LP_prices.c index 587efe5ff..af9023bf1 100644 --- a/iguana/exchanges/LP_prices.c +++ b/iguana/exchanges/LP_prices.c @@ -1114,6 +1114,11 @@ void LP_pricefeedupdate(bits256 pubkey,char *base,char *rel,double price,char *u // printf("error finding %s/%s %.8f\n",base,rel,price); } +double LP_CMCbtcprice(char *symbol) +{ + return(0); +} + cJSON *LP_fundvalue(cJSON *argjson) { cJSON *holdings,*item,*newitem; int32_t i,n; double btcprice,balance,btcsum; struct iguana_info *coin; char *symbol; int64_t fundvalue,KMDvalue = 0; @@ -1126,20 +1131,27 @@ cJSON *LP_fundvalue(cJSON *argjson) item = jitem(holdings,i); if ( (symbol= jstr(item,"coin")) != 0 && (balance= jdouble(item,"balance")) > SMALLVAL ) { - item = cJSON_CreateObject(); + newitem = cJSON_CreateObject(); jaddstr(item,"coin",symbol); if ( (coin= LP_coinfind(symbol)) != 0 && (KMDvalue= LP_KMDvalue(coin,SATOSHIDEN * balance)) > 0 ) { - jaddnum(item,"KMD",dstr(KMDvalue)); + jaddnum(newitem,"KMD",dstr(KMDvalue)); fundvalue += KMDvalue; } else if ( (btcprice= LP_CMCbtcprice(symbol)) > SMALLVAL ) { btcsum += btcprice * balance; - jaddnum(item,"BTC",btcprice * balance); + jaddnum(newitem,"BTC",btcprice * balance); } + } } } + if ( btcsum != 0 ) + { + btcprice = LP_CMCbtcprice("KMD"); + fundvalue += (btcprice * btcsum) * SATOSHIDEN; + } + return(0); } From 3fdea8ca8eef1a5a99c67a9a59f490fb02c046a2 Mon Sep 17 00:00:00 2001 From: jl777 Date: Tue, 5 Dec 2017 15:38:10 +0400 Subject: [PATCH 1532/1664] Docker -> padder --- crypto777/OS_portable.h | 1 + iguana/exchanges/LP_prices.c | 66 ++++++++++++++++++++++++++---------- iguana/exchanges/mm.c | 4 +-- iguana/exchanges/stats.c | 2 +- 4 files changed, 53 insertions(+), 20 deletions(-) diff --git a/crypto777/OS_portable.h b/crypto777/OS_portable.h index 3d90521bd..8c109e5d0 100755 --- a/crypto777/OS_portable.h +++ b/crypto777/OS_portable.h @@ -326,6 +326,7 @@ int32_t btc_convaddr(char *hexaddr,char *addr58); uint64_t RS_decode(char *rs); int32_t RS_encode(char *rsaddr,uint64_t id); +char *cmc_ticker(char *base); void calc_sha1(char *hexstr,uint8_t *buf,uint8_t *msg,int32_t len); void calc_md2(char *hexstr,uint8_t *buf,uint8_t *msg,int32_t len); diff --git a/iguana/exchanges/LP_prices.c b/iguana/exchanges/LP_prices.c index af9023bf1..0d8cb2387 100644 --- a/iguana/exchanges/LP_prices.c +++ b/iguana/exchanges/LP_prices.c @@ -1116,42 +1116,74 @@ void LP_pricefeedupdate(bits256 pubkey,char *base,char *rel,double price,char *u double LP_CMCbtcprice(char *symbol) { + char *retstr; cJSON *ticker; double price_btc = 0.; + if ( (retstr= cmc_ticker(symbol)) != 0 ) + { + if ( (ticker= cJSON_Parse(retstr)) != 0 ) + { + price_btc = jdouble(ticker,"price_btc"); + free_json(ticker); + } + free(retstr); + } return(0); } cJSON *LP_fundvalue(cJSON *argjson) { - cJSON *holdings,*item,*newitem; int32_t i,n; double btcprice,balance,btcsum; struct iguana_info *coin; char *symbol; int64_t fundvalue,KMDvalue = 0; + cJSON *holdings,*item,*newitem,*array,*retjson; int32_t i,iter,n; double btcprice,balance,btcsum; struct iguana_info *coin; char *symbol,*coinaddr; int64_t fundvalue,KMDvalue = 0; fundvalue = 0; btcsum = 0.; - if ( (holdings= jarray(&n,argjson,"holdings")) != 0 ) + array = cJSON_CreateArray(); + for (iter=0; iter<2; iter++) { - for (i=0; i SMALLVAL ) + if ( (coinaddr= jstr(argjson,"address")) != 0 ) { - newitem = cJSON_CreateObject(); - jaddstr(item,"coin",symbol); - if ( (coin= LP_coinfind(symbol)) != 0 && (KMDvalue= LP_KMDvalue(coin,SATOSHIDEN * balance)) > 0 ) - { - jaddnum(newitem,"KMD",dstr(KMDvalue)); - fundvalue += KMDvalue; - } - else if ( (btcprice= LP_CMCbtcprice(symbol)) > SMALLVAL ) + holdings = LP_balances(coinaddr); + n = cJSON_GetArraySize(holdings); + } + else break; + } + if ( holdings != 0 ) + { + for (i=0; i SMALLVAL ) { - btcsum += btcprice * balance; - jaddnum(newitem,"BTC",btcprice * balance); + newitem = cJSON_CreateObject(); + jaddstr(newitem,"coin",symbol); + if ( (coin= LP_coinfind(symbol)) != 0 && (KMDvalue= LP_KMDvalue(coin,SATOSHIDEN * balance)) > 0 ) + { + jaddnum(newitem,"KMD",dstr(KMDvalue)); + fundvalue += KMDvalue; + } + else if ( (btcprice= LP_CMCbtcprice(symbol)) > SMALLVAL ) + { + btcsum += btcprice * balance; + jaddnum(newitem,"BTC",btcprice * balance); + } + else jaddstr(newitem,"error","no price source"); + jaddi(array,newitem); } - } } } + retjson = cJSON_CreateObject(); + jadd(retjson,"holdings",array); if ( btcsum != 0 ) { btcprice = LP_CMCbtcprice("KMD"); fundvalue += (btcprice * btcsum) * SATOSHIDEN; + jaddnum(retjson,"KMD_BTC",btcprice); + jaddnum(retjson,"btcsum",btcsum); + jaddnum(retjson,"btcvalue",btcsum * btcprice); } - return(0); + jaddnum(retjson,"fundvalue",dstr(fundvalue)); + return(retjson); } diff --git a/iguana/exchanges/mm.c b/iguana/exchanges/mm.c index 3a03962a1..560078d0c 100644 --- a/iguana/exchanges/mm.c +++ b/iguana/exchanges/mm.c @@ -34,7 +34,7 @@ void PNACL_message(char *arg,...) #include "../../crypto777/OS_portable.h" #endif // !_WIN_32 -int32_t DOCKERFLAG; +uint32_t DOCKERFLAG; #define MAX(a,b) ((a) > (b) ? (a) : (b)) char *stats_JSON(void *ctx,char *myipaddr,int32_t pubsock,cJSON *argjson,char *remoteaddr,uint16_t port); #include "stats.c" @@ -921,7 +921,7 @@ int main(int argc, const char * argv[]) } if ( argc > 1 && (retjson= cJSON_Parse(argv[1])) != 0 ) { - DOCKERFLAG = jint(retjson,"docker"); + DOCKERFLAG = (uint32_t)calc_ipbits(jstr(retjson,"docker")); if ( (passphrase= jstr(retjson,"passphrase")) == 0 ) jaddstr(retjson,"passphrase","test"); if ( OS_thread_create(malloc(sizeof(pthread_t)),NULL,(void *)LP_main,(void *)retjson) != 0 ) diff --git a/iguana/exchanges/stats.c b/iguana/exchanges/stats.c index 06a44a920..0e71eb9c2 100644 --- a/iguana/exchanges/stats.c +++ b/iguana/exchanges/stats.c @@ -817,7 +817,7 @@ void stats_rpcloop(void *args) } #endif*/ memcpy(&ipbits,&cli_addr.sin_addr.s_addr,sizeof(ipbits)); - if ( DOCKERFLAG != 0 ) + if ( DOCKERFLAG != 0 && ipbits == DOCKERFLAG ) ipbits = localhostbits; if ( port == RPC_port && ipbits != localhostbits ) { From f47199739ab540e72bb9a8a13c28bbc50a4b8530 Mon Sep 17 00:00:00 2001 From: jl777 Date: Tue, 5 Dec 2017 15:49:18 +0400 Subject: [PATCH 1533/1664] Fund value --- iguana/exchanges/LP_commands.c | 3 +++ iguana/exchanges/fundvalue | 4 ++++ iguana/exchanges/install | 2 +- iguana/exchanges/mm.c | 5 ++++- iguana/exchanges/stats.c | 2 +- 5 files changed, 13 insertions(+), 3 deletions(-) create mode 100755 iguana/exchanges/fundvalue diff --git a/iguana/exchanges/LP_commands.c b/iguana/exchanges/LP_commands.c index 7056e7de9..0c7466206 100644 --- a/iguana/exchanges/LP_commands.c +++ b/iguana/exchanges/LP_commands.c @@ -136,6 +136,7 @@ setconfirms(coin, numconfirms, maxconfirms=6)\n\ trust(pubkey, trust) # positive to trust, 0 for normal, negative to blacklist\n\ balance(coin, address)\n\ balances(address)\n\ +fundvalue(address="", holdings=[])\n\ orderbook(base, rel, duration=3600)\n\ getprices()\n\ getprice(base, rel)\n\ @@ -625,6 +626,8 @@ instantdex_claim()\n\ retstr = clonestr("{\"error\":\"deprecated\"}"); else if ( strcmp(method,"balances") == 0 ) return(jprint(LP_balances(jstr(argjson,"address")),1)); + else if ( strcmp(method,"fundvalue") == 0 ) + return(jprint(LP_fundvalue(argjson),1)); else if ( strcmp(method,"getprice") == 0 ) { double price; diff --git a/iguana/exchanges/fundvalue b/iguana/exchanges/fundvalue new file mode 100755 index 000000000..af7f06160 --- /dev/null +++ b/iguana/exchanges/fundvalue @@ -0,0 +1,4 @@ +#!/bin/bash +source userpass +# this will only work for watchonly addresses that have been rescanned and with active coins +curl --url "http://127.0.0.1:7783" --data "{\"userpass\":\"$userpass\",\"method\":\"fundvalue\",\"address\":\"RRyyejME7LRTuvdziWsXkAbSW1fdiohGwK\"}" diff --git a/iguana/exchanges/install b/iguana/exchanges/install index 8518efa3c..5c8dacf99 100755 --- a/iguana/exchanges/install +++ b/iguana/exchanges/install @@ -1,5 +1,5 @@ #!/bin/bash -cp balances dynamictrust getcoin kickstart tradesarray claim deposit10 deposit1 invreset sendrawtransaction processfiles stop millis mnzservers bot_buy bot_list bot_statuslist bot_pause bot_resume bot_sell bot_settings bot_status bot_stop guistats pubkeystats pendings coinswaps baserelswaps setpassphrase notarizations getrawtransaction parselog statsdisp m_js 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 fundvalue balances dynamictrust getcoin kickstart tradesarray claim deposit10 deposit1 invreset sendrawtransaction processfiles stop millis mnzservers bot_buy bot_list bot_statuslist bot_pause bot_resume bot_sell bot_settings bot_status bot_stop guistats pubkeystats pendings coinswaps baserelswaps setpassphrase notarizations getrawtransaction parselog statsdisp m_js 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 . diff --git a/iguana/exchanges/mm.c b/iguana/exchanges/mm.c index 560078d0c..b67f345b9 100644 --- a/iguana/exchanges/mm.c +++ b/iguana/exchanges/mm.c @@ -921,7 +921,10 @@ int main(int argc, const char * argv[]) } if ( argc > 1 && (retjson= cJSON_Parse(argv[1])) != 0 ) { - DOCKERFLAG = (uint32_t)calc_ipbits(jstr(retjson,"docker")); + if ( jint(retjson,"docker") == 1 ) + DOCKERFLAG = 1; + else if ( jstr(retjson,"docker") != 0 ) + DOCKERFLAG = (uint32_t)calc_ipbits(jstr(retjson,"docker")); if ( (passphrase= jstr(retjson,"passphrase")) == 0 ) jaddstr(retjson,"passphrase","test"); if ( OS_thread_create(malloc(sizeof(pthread_t)),NULL,(void *)LP_main,(void *)retjson) != 0 ) diff --git a/iguana/exchanges/stats.c b/iguana/exchanges/stats.c index 0e71eb9c2..a8c5b1c08 100644 --- a/iguana/exchanges/stats.c +++ b/iguana/exchanges/stats.c @@ -817,7 +817,7 @@ void stats_rpcloop(void *args) } #endif*/ memcpy(&ipbits,&cli_addr.sin_addr.s_addr,sizeof(ipbits)); - if ( DOCKERFLAG != 0 && ipbits == DOCKERFLAG ) + if ( DOCKERFLAG != 0 && (DOCKERFLAG == 1 || ipbits == DOCKERFLAG) ) ipbits = localhostbits; if ( port == RPC_port && ipbits != localhostbits ) { From 62ced43b920fe3ca620ca2337ab9ea3e4491be5a Mon Sep 17 00:00:00 2001 From: jl777 Date: Tue, 5 Dec 2017 16:04:25 +0400 Subject: [PATCH 1534/1664] Add coins to passphrase return --- iguana/exchanges/LP_commands.c | 1 + iguana/exchanges/LP_rpc.c | 2 +- 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/iguana/exchanges/LP_commands.c b/iguana/exchanges/LP_commands.c index 0c7466206..7fa774286 100644 --- a/iguana/exchanges/LP_commands.c +++ b/iguana/exchanges/LP_commands.c @@ -198,6 +198,7 @@ instantdex_claim()\n\ bitcoin_address(coinaddr,0,0,G.LP_myrmd160,20); jaddstr(retjson,"BTC",coinaddr); jaddstr(retjson,"NXT",G.LP_NXTaddr); + jadd(retjson,"coins",LP_coinsjson(LP_showwif)); return(jprint(retjson,1)); } } diff --git a/iguana/exchanges/LP_rpc.c b/iguana/exchanges/LP_rpc.c index 2751fb467..2c0eab7e2 100644 --- a/iguana/exchanges/LP_rpc.c +++ b/iguana/exchanges/LP_rpc.c @@ -352,7 +352,7 @@ int32_t LP_address_iswatchonly(char *symbol,char *address) if ( (obj= jobj(retjson,"iswatchonly")) != 0 && is_cJSON_True(obj) != 0 ) { doneflag = 1; - printf("%s iswatchonly (%s)\n",address,jprint(retjson,0)); + //printf("%s iswatchonly (%s)\n",address,jprint(retjson,0)); } //printf("%s\n",jprint(retjson,0)); free_json(retjson); From b13cf6730f42b3b83a258463d65b0c25b3edbb12 Mon Sep 17 00:00:00 2001 From: jl777 Date: Tue, 5 Dec 2017 16:08:34 +0400 Subject: [PATCH 1535/1664] Test --- iguana/exchanges/LP_commands.c | 2 +- iguana/exchanges/LP_prices.c | 7 ++++++- iguana/exchanges/LP_utxo.c | 2 +- 3 files changed, 8 insertions(+), 3 deletions(-) diff --git a/iguana/exchanges/LP_commands.c b/iguana/exchanges/LP_commands.c index 7fa774286..0f1502df0 100644 --- a/iguana/exchanges/LP_commands.c +++ b/iguana/exchanges/LP_commands.c @@ -136,7 +136,7 @@ setconfirms(coin, numconfirms, maxconfirms=6)\n\ trust(pubkey, trust) # positive to trust, 0 for normal, negative to blacklist\n\ balance(coin, address)\n\ balances(address)\n\ -fundvalue(address="", holdings=[])\n\ +fundvalue(address="", holdings=[], divisor=0)\n\ orderbook(base, rel, duration=3600)\n\ getprices()\n\ getprice(base, rel)\n\ diff --git a/iguana/exchanges/LP_prices.c b/iguana/exchanges/LP_prices.c index 0d8cb2387..864268e90 100644 --- a/iguana/exchanges/LP_prices.c +++ b/iguana/exchanges/LP_prices.c @@ -1131,7 +1131,7 @@ double LP_CMCbtcprice(char *symbol) cJSON *LP_fundvalue(cJSON *argjson) { - cJSON *holdings,*item,*newitem,*array,*retjson; int32_t i,iter,n; double btcprice,balance,btcsum; struct iguana_info *coin; char *symbol,*coinaddr; int64_t fundvalue,KMDvalue = 0; + cJSON *holdings,*item,*newitem,*array,*retjson; int32_t i,iter,n; double divisor,btcprice,balance,btcsum; struct iguana_info *coin; char *symbol,*coinaddr; int64_t fundvalue,KMDvalue = 0; fundvalue = 0; btcsum = 0.; array = cJSON_CreateArray(); @@ -1184,6 +1184,11 @@ cJSON *LP_fundvalue(cJSON *argjson) jaddnum(retjson,"btcvalue",btcsum * btcprice); } jaddnum(retjson,"fundvalue",dstr(fundvalue)); + if ( (divisor= jdouble(argjson,"divisor")) != 0 ) + { + jaddnum(retjson,"divisor",divisor); + jaddnum(retjson,"fundvalue",dstr(fundvalue)); + } return(retjson); } diff --git a/iguana/exchanges/LP_utxo.c b/iguana/exchanges/LP_utxo.c index fb0cb5bd8..43086d0a9 100644 --- a/iguana/exchanges/LP_utxo.c +++ b/iguana/exchanges/LP_utxo.c @@ -622,7 +622,7 @@ cJSON *LP_balances(char *coinaddr) array = cJSON_CreateArray(); HASH_ITER(hh,LP_coins,coin,tmp) { - if ( coinaddr != 0 && coinaddr[0] != 0 && strcmp(coinaddr,coin->smartaddr) != 0 ) + if ( coin->electrum != 0 || (coinaddr != 0 && coinaddr[0] != 0 && strcmp(coinaddr,coin->smartaddr) != 0) ) { bitcoin_addr2rmd160(0,&addrtype,rmd160,coinaddr); bitcoin_address(address,coin->taddr,coin->pubtype,rmd160,20); From 6b6c76a977c4fdfdae55f1d2c45e5333f45cf705 Mon Sep 17 00:00:00 2001 From: jl777 Date: Tue, 5 Dec 2017 16:09:34 +0400 Subject: [PATCH 1536/1664] Test --- iguana/exchanges/LP_utxo.c | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/iguana/exchanges/LP_utxo.c b/iguana/exchanges/LP_utxo.c index 43086d0a9..36b6a8c4a 100644 --- a/iguana/exchanges/LP_utxo.c +++ b/iguana/exchanges/LP_utxo.c @@ -633,6 +633,11 @@ cJSON *LP_balances(char *coinaddr) item = cJSON_CreateObject(); jaddstr(item,"coin",coin->symbol); jaddnum(item,"balance",dstr(balance)); + if ( coin->electrum != 0 && strcmp(coinaddr,coin->smartaddr) == 0 && strcmp(coin->symbol,"KMD") == 0 ) + { + jaddnum(item,"zcredits",dstr(LP_myzcredits())); + jadd(item,"zdebits",LP_myzdebits()); + } jaddi(array,item); } free_json(retjson); From d6e7295f426e418142d4b9553684159067264ce1 Mon Sep 17 00:00:00 2001 From: jl777 Date: Tue, 5 Dec 2017 16:11:01 +0400 Subject: [PATCH 1537/1664] Test --- iguana/exchanges/fundvalue | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/iguana/exchanges/fundvalue b/iguana/exchanges/fundvalue index af7f06160..ce5da0ec0 100755 --- a/iguana/exchanges/fundvalue +++ b/iguana/exchanges/fundvalue @@ -1,4 +1,4 @@ #!/bin/bash source userpass # this will only work for watchonly addresses that have been rescanned and with active coins -curl --url "http://127.0.0.1:7783" --data "{\"userpass\":\"$userpass\",\"method\":\"fundvalue\",\"address\":\"RRyyejME7LRTuvdziWsXkAbSW1fdiohGwK\"}" +curl --url "http://127.0.0.1:7783" --data "{\"userpass\":\"$userpass\",\"method\":\"fundvalue\",\"address\":\"RRyyejME7LRTuvdziWsXkAbSW1fdiohGwK\",\"holdings\":[{\"coin\":\"iota\",\"balance\":13000}]}" From c02154bce41389ddfae9d2d75c7694adf10e2c33 Mon Sep 17 00:00:00 2001 From: jl777 Date: Tue, 5 Dec 2017 16:13:33 +0400 Subject: [PATCH 1538/1664] Test --- iguana/exchanges/LP_utxo.c | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/iguana/exchanges/LP_utxo.c b/iguana/exchanges/LP_utxo.c index 36b6a8c4a..f50b32209 100644 --- a/iguana/exchanges/LP_utxo.c +++ b/iguana/exchanges/LP_utxo.c @@ -624,8 +624,13 @@ cJSON *LP_balances(char *coinaddr) { if ( coin->electrum != 0 || (coinaddr != 0 && coinaddr[0] != 0 && strcmp(coinaddr,coin->smartaddr) != 0) ) { - bitcoin_addr2rmd160(0,&addrtype,rmd160,coinaddr); - bitcoin_address(address,coin->taddr,coin->pubtype,rmd160,20); + if ( coinaddr == 0 || coinaddr[0] == 0 ) + strcpy(address,coin->smartaddr); + else + { + bitcoin_addr2rmd160(0,&addrtype,rmd160,coinaddr); + bitcoin_address(address,coin->taddr,coin->pubtype,rmd160,20); + } if ( (retjson= LP_address_balance(coin,address,1)) != 0 ) { if ( (balance= jdouble(retjson,"balance")*SATOSHIDEN) > 0 ) From 02ca5d1ce206a7602190e35a26c8120f3cbd8610 Mon Sep 17 00:00:00 2001 From: jl777 Date: Tue, 5 Dec 2017 16:15:35 +0400 Subject: [PATCH 1539/1664] Test --- iguana/exchanges/LP_prices.c | 1 + 1 file changed, 1 insertion(+) diff --git a/iguana/exchanges/LP_prices.c b/iguana/exchanges/LP_prices.c index 864268e90..bb6f80526 100644 --- a/iguana/exchanges/LP_prices.c +++ b/iguana/exchanges/LP_prices.c @@ -1119,6 +1119,7 @@ double LP_CMCbtcprice(char *symbol) char *retstr; cJSON *ticker; double price_btc = 0.; if ( (retstr= cmc_ticker(symbol)) != 0 ) { + printf("CMC %s -> (%s)\n",symbol,retstr); if ( (ticker= cJSON_Parse(retstr)) != 0 ) { price_btc = jdouble(ticker,"price_btc"); From 88cfaa748bc59d7a6e9391938f9bd9cafc8b9b63 Mon Sep 17 00:00:00 2001 From: jl777 Date: Tue, 5 Dec 2017 16:16:36 +0400 Subject: [PATCH 1540/1664] Test --- iguana/exchanges/LP_utxo.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/iguana/exchanges/LP_utxo.c b/iguana/exchanges/LP_utxo.c index f50b32209..683ea34ad 100644 --- a/iguana/exchanges/LP_utxo.c +++ b/iguana/exchanges/LP_utxo.c @@ -625,7 +625,10 @@ cJSON *LP_balances(char *coinaddr) if ( coin->electrum != 0 || (coinaddr != 0 && coinaddr[0] != 0 && strcmp(coinaddr,coin->smartaddr) != 0) ) { if ( coinaddr == 0 || coinaddr[0] == 0 ) - strcpy(address,coin->smartaddr); + { + coinaddr = coin->smartaddr; + strcpy(address,coinaddr); + } else { bitcoin_addr2rmd160(0,&addrtype,rmd160,coinaddr); From 34a6267018838ed1c9c26a5ede4249e3d5680f93 Mon Sep 17 00:00:00 2001 From: jl777 Date: Tue, 5 Dec 2017 16:18:54 +0400 Subject: [PATCH 1541/1664] Test --- iguana/exchanges/LP_prices.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/iguana/exchanges/LP_prices.c b/iguana/exchanges/LP_prices.c index bb6f80526..434f6b57b 100644 --- a/iguana/exchanges/LP_prices.c +++ b/iguana/exchanges/LP_prices.c @@ -1119,10 +1119,9 @@ double LP_CMCbtcprice(char *symbol) char *retstr; cJSON *ticker; double price_btc = 0.; if ( (retstr= cmc_ticker(symbol)) != 0 ) { - printf("CMC %s -> (%s)\n",symbol,retstr); if ( (ticker= cJSON_Parse(retstr)) != 0 ) { - price_btc = jdouble(ticker,"price_btc"); + price_btc = jdouble(jitem(ticker,0),"price_btc"); free_json(ticker); } free(retstr); @@ -1158,6 +1157,7 @@ cJSON *LP_fundvalue(cJSON *argjson) { newitem = cJSON_CreateObject(); jaddstr(newitem,"coin",symbol); + jaddnum(item,"balance",dstr(balance)); if ( (coin= LP_coinfind(symbol)) != 0 && (KMDvalue= LP_KMDvalue(coin,SATOSHIDEN * balance)) > 0 ) { jaddnum(newitem,"KMD",dstr(KMDvalue)); From e1b972accebd88ce1d6015542218bf388e8d2e8f Mon Sep 17 00:00:00 2001 From: jl777 Date: Tue, 5 Dec 2017 16:22:17 +0400 Subject: [PATCH 1542/1664] test --- iguana/exchanges/LP_prices.c | 6 ++++-- iguana/exchanges/stats.c | 2 +- 2 files changed, 5 insertions(+), 3 deletions(-) diff --git a/iguana/exchanges/LP_prices.c b/iguana/exchanges/LP_prices.c index 434f6b57b..3f9cca7b1 100644 --- a/iguana/exchanges/LP_prices.c +++ b/iguana/exchanges/LP_prices.c @@ -1116,12 +1116,14 @@ void LP_pricefeedupdate(bits256 pubkey,char *base,char *rel,double price,char *u double LP_CMCbtcprice(char *symbol) { - char *retstr; cJSON *ticker; double price_btc = 0.; + char *retstr; cJSON *ticker,*item; double price_btc = 0.; if ( (retstr= cmc_ticker(symbol)) != 0 ) { if ( (ticker= cJSON_Parse(retstr)) != 0 ) { - price_btc = jdouble(jitem(ticker,0),"price_btc"); + item = jitem(ticker,0); + price_btc = jdouble(item,"price_btc"); + printf("%.8f item.(%s)\n",price_btc,jprint(item,0)); free_json(ticker); } free(retstr); diff --git a/iguana/exchanges/stats.c b/iguana/exchanges/stats.c index a8c5b1c08..cc5005c61 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", "balances", "getprice", "notify", "getpeers", // from issue_ "uitem", "listunspent", - "orderbook", "statsdisp", "help", "getcoins", "pricearray", "balance", "tradesarray" + "orderbook", "statsdisp", "fundbalance", "help", "getcoins", "pricearray", "balance", "tradesarray" }; int32_t LP_valid_remotemethod(cJSON *argjson) From a3a9d833f0056cf415894f5a84b527a0c1c6491c Mon Sep 17 00:00:00 2001 From: jl777 Date: Tue, 5 Dec 2017 16:24:44 +0400 Subject: [PATCH 1543/1664] Test --- iguana/exchanges/LP_prices.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/iguana/exchanges/LP_prices.c b/iguana/exchanges/LP_prices.c index 3f9cca7b1..6de8d8669 100644 --- a/iguana/exchanges/LP_prices.c +++ b/iguana/exchanges/LP_prices.c @@ -1123,12 +1123,12 @@ double LP_CMCbtcprice(char *symbol) { item = jitem(ticker,0); price_btc = jdouble(item,"price_btc"); - printf("%.8f item.(%s)\n",price_btc,jprint(item,0)); + //printf("%.8f item.(%s)\n",price_btc,jprint(item,0)); free_json(ticker); } free(retstr); } - return(0); + return(price_btc); } cJSON *LP_fundvalue(cJSON *argjson) @@ -1165,7 +1165,7 @@ cJSON *LP_fundvalue(cJSON *argjson) jaddnum(newitem,"KMD",dstr(KMDvalue)); fundvalue += KMDvalue; } - else if ( (btcprice= LP_CMCbtcprice(symbol)) > SMALLVAL ) + else if ( iter == 0 && (btcprice= LP_CMCbtcprice(symbol)) > SMALLVAL ) { btcsum += btcprice * balance; jaddnum(newitem,"BTC",btcprice * balance); From 86721ad2182ea8af8363548ad24777a5bed820e4 Mon Sep 17 00:00:00 2001 From: jl777 Date: Tue, 5 Dec 2017 16:33:42 +0400 Subject: [PATCH 1544/1664] Test --- iguana/exchanges/fundvalue | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/iguana/exchanges/fundvalue b/iguana/exchanges/fundvalue index ce5da0ec0..2723fd08c 100755 --- a/iguana/exchanges/fundvalue +++ b/iguana/exchanges/fundvalue @@ -1,4 +1,4 @@ #!/bin/bash source userpass # this will only work for watchonly addresses that have been rescanned and with active coins -curl --url "http://127.0.0.1:7783" --data "{\"userpass\":\"$userpass\",\"method\":\"fundvalue\",\"address\":\"RRyyejME7LRTuvdziWsXkAbSW1fdiohGwK\",\"holdings\":[{\"coin\":\"iota\",\"balance\":13000}]}" +curl --url "http://127.0.0.1:7783" --data "{\"userpass\":\"$userpass\",\"method\":\"fundvalue\",\"address\":\"RRyyejME7LRTuvdziWsXkAbSW1fdiohGwK\",\"holdings\":[{\"coin\":\"iota\",\"balance\":13000}, {\"coin\":\"stratis\",\"balance\":1300000}, {\"coin\":\"zcash\",\"balance\":10000}, {\"coin\":\"syscoin\",\"balance\":20000000}, {\"coin\":\"waves\",\"balance\":700000}, {\"coin\":\"bitcoin\",\"balance\":625}, {\"coin\":\"bitcoin-cash\",\"balance\":1500}, {\"coin\":\"heat-ledger\",\"balance\":2323851 }, {\"coin\":\"decred\",\"balance\":20000}, {\"coin\":\"vericoin\",\"balance\":2199368 }, {\"coin\":\"byteball\",\"balance\":4238}, {\"coin\":\"iocoin\",\"balance\":150000}, {\"coin\":\"quantum-resistant-ledger\",\"balance\":375000}, {\"coin\":\"chips\",\"balance\":2577006 }, {\"coin\":\"hush\",\"balance\":100000 }, {\"coin\":\"mobilego\",\"balance\":100000 }],\"divisor\":650000}" From 48308597bdd44d56d7f43d3d634e71923d89a993 Mon Sep 17 00:00:00 2001 From: jl777 Date: Tue, 5 Dec 2017 16:41:26 +0400 Subject: [PATCH 1545/1664] Test --- iguana/exchanges/LP_prices.c | 4 ++-- iguana/exchanges/fundvalue | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/iguana/exchanges/LP_prices.c b/iguana/exchanges/LP_prices.c index 6de8d8669..ed558e10f 100644 --- a/iguana/exchanges/LP_prices.c +++ b/iguana/exchanges/LP_prices.c @@ -1159,7 +1159,7 @@ cJSON *LP_fundvalue(cJSON *argjson) { newitem = cJSON_CreateObject(); jaddstr(newitem,"coin",symbol); - jaddnum(item,"balance",dstr(balance)); + jaddnum(newitem,"balance",dstr(balance)); if ( (coin= LP_coinfind(symbol)) != 0 && (KMDvalue= LP_KMDvalue(coin,SATOSHIDEN * balance)) > 0 ) { jaddnum(newitem,"KMD",dstr(KMDvalue)); @@ -1180,7 +1180,7 @@ cJSON *LP_fundvalue(cJSON *argjson) jadd(retjson,"holdings",array); if ( btcsum != 0 ) { - btcprice = LP_CMCbtcprice("KMD"); + btcprice = LP_CMCbtcprice("komodo"); fundvalue += (btcprice * btcsum) * SATOSHIDEN; jaddnum(retjson,"KMD_BTC",btcprice); jaddnum(retjson,"btcsum",btcsum); diff --git a/iguana/exchanges/fundvalue b/iguana/exchanges/fundvalue index 2723fd08c..3e46662f6 100755 --- a/iguana/exchanges/fundvalue +++ b/iguana/exchanges/fundvalue @@ -1,4 +1,4 @@ #!/bin/bash source userpass # this will only work for watchonly addresses that have been rescanned and with active coins -curl --url "http://127.0.0.1:7783" --data "{\"userpass\":\"$userpass\",\"method\":\"fundvalue\",\"address\":\"RRyyejME7LRTuvdziWsXkAbSW1fdiohGwK\",\"holdings\":[{\"coin\":\"iota\",\"balance\":13000}, {\"coin\":\"stratis\",\"balance\":1300000}, {\"coin\":\"zcash\",\"balance\":10000}, {\"coin\":\"syscoin\",\"balance\":20000000}, {\"coin\":\"waves\",\"balance\":700000}, {\"coin\":\"bitcoin\",\"balance\":625}, {\"coin\":\"bitcoin-cash\",\"balance\":1500}, {\"coin\":\"heat-ledger\",\"balance\":2323851 }, {\"coin\":\"decred\",\"balance\":20000}, {\"coin\":\"vericoin\",\"balance\":2199368 }, {\"coin\":\"byteball\",\"balance\":4238}, {\"coin\":\"iocoin\",\"balance\":150000}, {\"coin\":\"quantum-resistant-ledger\",\"balance\":375000}, {\"coin\":\"chips\",\"balance\":2577006 }, {\"coin\":\"hush\",\"balance\":100000 }, {\"coin\":\"mobilego\",\"balance\":100000 }],\"divisor\":650000}" +curl --url "http://127.0.0.1:7783" --data "{\"userpass\":\"$userpass\",\"method\":\"fundvalue\",\"address\":\"RRyyejME7LRTuvdziWsXkAbSW1fdiohGwK\",\"holdings\":[{\"coin\":\"iota\",\"balance\":13000000}, {\"coin\":\"stratis\",\"balance\":1300000}, {\"coin\":\"zcash\",\"balance\":10000}, {\"coin\":\"syscoin\",\"balance\":20000000}, {\"coin\":\"waves\",\"balance\":700000}, {\"coin\":\"bitcoin\",\"balance\":625}, {\"coin\":\"bitcoin-cash\",\"balance\":1500}, {\"coin\":\"heat-ledger\",\"balance\":2323851 }, {\"coin\":\"decred\",\"balance\":20000}, {\"coin\":\"vericoin\",\"balance\":2199368 }, {\"coin\":\"byteball\",\"balance\":4238}, {\"coin\":\"iocoin\",\"balance\":150000}, {\"coin\":\"quantum-resistant-ledger\",\"balance\":375000}, {\"coin\":\"chips\",\"balance\":2577006 }, {\"coin\":\"hush\",\"balance\":100000 }, {\"coin\":\"mobilego\",\"balance\":100000 }],\"divisor\":650000}" From 734e8c8a8f34e0043cce5f44671cc88f8dabc045 Mon Sep 17 00:00:00 2001 From: jl777 Date: Tue, 5 Dec 2017 16:46:35 +0400 Subject: [PATCH 1546/1664] Test --- iguana/exchanges/LP_prices.c | 14 ++++++++------ iguana/exchanges/supernet | 2 ++ 2 files changed, 10 insertions(+), 6 deletions(-) diff --git a/iguana/exchanges/LP_prices.c b/iguana/exchanges/LP_prices.c index ed558e10f..806059bba 100644 --- a/iguana/exchanges/LP_prices.c +++ b/iguana/exchanges/LP_prices.c @@ -1159,7 +1159,7 @@ cJSON *LP_fundvalue(cJSON *argjson) { newitem = cJSON_CreateObject(); jaddstr(newitem,"coin",symbol); - jaddnum(newitem,"balance",dstr(balance)); + jaddnum(newitem,"balance",balance); if ( (coin= LP_coinfind(symbol)) != 0 && (KMDvalue= LP_KMDvalue(coin,SATOSHIDEN * balance)) > 0 ) { jaddnum(newitem,"KMD",dstr(KMDvalue)); @@ -1180,11 +1180,13 @@ cJSON *LP_fundvalue(cJSON *argjson) jadd(retjson,"holdings",array); if ( btcsum != 0 ) { - btcprice = LP_CMCbtcprice("komodo"); - fundvalue += (btcprice * btcsum) * SATOSHIDEN; - jaddnum(retjson,"KMD_BTC",btcprice); - jaddnum(retjson,"btcsum",btcsum); - jaddnum(retjson,"btcvalue",btcsum * btcprice); + if ( (btcprice= LP_CMCbtcprice("komodo")) > SMALLVAL ) + { + fundvalue += (btcsum / btcprice) * SATOSHIDEN; + jaddnum(retjson,"KMD_BTC",btcprice); + jaddnum(retjson,"btcsum",btcsum); + jaddnum(retjson,"btcvalue",btcsum / btcprice); + } } jaddnum(retjson,"fundvalue",dstr(fundvalue)); if ( (divisor= jdouble(argjson,"divisor")) != 0 ) diff --git a/iguana/exchanges/supernet b/iguana/exchanges/supernet index 803341f7a..0b71993f4 100755 --- a/iguana/exchanges/supernet +++ b/iguana/exchanges/supernet @@ -2,3 +2,5 @@ source userpass # this will only work for watchonly addresses that have been rescanned and with active coins curl --url "http://127.0.0.1:7783" --data "{\"userpass\":\"$userpass\",\"method\":\"balances\",\"address\":\"RRyyejME7LRTuvdziWsXkAbSW1fdiohGwK\"}" + +curl --url "http://127.0.0.1:7783" --data "{\"userpass\":\"$userpass\",\"method\":\"fundvalue\",\"address\":\"RRyyejME7LRTuvdziWsXkAbSW1fdiohGwK\",\"holdings\":[{\"coin\":\"iota\",\"balance\":13000000}, {\"coin\":\"stratis\",\"balance\":1300000}, {\"coin\":\"zcash\",\"balance\":10000}, {\"coin\":\"syscoin\",\"balance\":20000000}, {\"coin\":\"waves\",\"balance\":700000}, {\"coin\":\"bitcoin\",\"balance\":625}, {\"coin\":\"bitcoin-cash\",\"balance\":1500}, {\"coin\":\"heat-ledger\",\"balance\":2323851 }, {\"coin\":\"decred\",\"balance\":20000}, {\"coin\":\"vericoin\",\"balance\":2199368 }, {\"coin\":\"byteball\",\"balance\":4238}, {\"coin\":\"iocoin\",\"balance\":150000}, {\"coin\":\"quantum-resistant-ledger\",\"balance\":375000}, {\"coin\":\"chips\",\"balance\":2577006 }, {\"coin\":\"hush\",\"balance\":100000 }, {\"coin\":\"mobilego\",\"balance\":100000 }],\"divisor\":650000}" From 127187e1fa646e6b7093a879d41e923090f10e7e Mon Sep 17 00:00:00 2001 From: jl777 Date: Tue, 5 Dec 2017 16:54:00 +0400 Subject: [PATCH 1547/1664] Test --- iguana/exchanges/LP_prices.c | 15 ++++++++++----- iguana/exchanges/supernet | 2 +- 2 files changed, 11 insertions(+), 6 deletions(-) diff --git a/iguana/exchanges/LP_prices.c b/iguana/exchanges/LP_prices.c index 806059bba..f9fa7046b 100644 --- a/iguana/exchanges/LP_prices.c +++ b/iguana/exchanges/LP_prices.c @@ -1114,15 +1114,17 @@ void LP_pricefeedupdate(bits256 pubkey,char *base,char *rel,double price,char *u // printf("error finding %s/%s %.8f\n",base,rel,price); } -double LP_CMCbtcprice(char *symbol) +double LP_CMCbtcprice(double *price_usdp,char *symbol) { char *retstr; cJSON *ticker,*item; double price_btc = 0.; + *price_usdp = 0.; if ( (retstr= cmc_ticker(symbol)) != 0 ) { if ( (ticker= cJSON_Parse(retstr)) != 0 ) { item = jitem(ticker,0); price_btc = jdouble(item,"price_btc"); + *price_usdp = jdouble(item,"price_usd"); //printf("%.8f item.(%s)\n",price_btc,jprint(item,0)); free_json(ticker); } @@ -1133,7 +1135,7 @@ double LP_CMCbtcprice(char *symbol) cJSON *LP_fundvalue(cJSON *argjson) { - cJSON *holdings,*item,*newitem,*array,*retjson; int32_t i,iter,n; double divisor,btcprice,balance,btcsum; struct iguana_info *coin; char *symbol,*coinaddr; int64_t fundvalue,KMDvalue = 0; + cJSON *holdings,*item,*newitem,*array,*retjson; int32_t i,iter,n; double usdprice,divisor,btcprice,balance,btcsum; struct iguana_info *coin; char *symbol,*coinaddr; int64_t fundvalue,KMDvalue = 0; fundvalue = 0; btcsum = 0.; array = cJSON_CreateArray(); @@ -1165,7 +1167,7 @@ cJSON *LP_fundvalue(cJSON *argjson) jaddnum(newitem,"KMD",dstr(KMDvalue)); fundvalue += KMDvalue; } - else if ( iter == 0 && (btcprice= LP_CMCbtcprice(symbol)) > SMALLVAL ) + else if ( iter == 0 && (btcprice= LP_CMCbtcprice(&usdprice,symbol)) > SMALLVAL ) { btcsum += btcprice * balance; jaddnum(newitem,"BTC",btcprice * balance); @@ -1178,9 +1180,10 @@ cJSON *LP_fundvalue(cJSON *argjson) } retjson = cJSON_CreateObject(); jadd(retjson,"holdings",array); + btcprice = LP_CMCbtcprice(&usdprice,"komodo"); if ( btcsum != 0 ) { - if ( (btcprice= LP_CMCbtcprice("komodo")) > SMALLVAL ) + if ( btcprice > SMALLVAL ) { fundvalue += (btcsum / btcprice) * SATOSHIDEN; jaddnum(retjson,"KMD_BTC",btcprice); @@ -1192,7 +1195,9 @@ cJSON *LP_fundvalue(cJSON *argjson) if ( (divisor= jdouble(argjson,"divisor")) != 0 ) { jaddnum(retjson,"divisor",divisor); - jaddnum(retjson,"fundvalue",dstr(fundvalue)); + jaddnum(retjson,"NAV_KMD",dstr(fundvalue)/divisor); + jaddnum(retjson,"NAV_BTC",(btcprice * dstr(fundvalue))/divisor); + jaddnum(retjson,"NAV_USD",(usdprice * dstr(fundvalue))/divisor); } return(retjson); } diff --git a/iguana/exchanges/supernet b/iguana/exchanges/supernet index 0b71993f4..4058bc4d0 100755 --- a/iguana/exchanges/supernet +++ b/iguana/exchanges/supernet @@ -3,4 +3,4 @@ source userpass # this will only work for watchonly addresses that have been rescanned and with active coins curl --url "http://127.0.0.1:7783" --data "{\"userpass\":\"$userpass\",\"method\":\"balances\",\"address\":\"RRyyejME7LRTuvdziWsXkAbSW1fdiohGwK\"}" -curl --url "http://127.0.0.1:7783" --data "{\"userpass\":\"$userpass\",\"method\":\"fundvalue\",\"address\":\"RRyyejME7LRTuvdziWsXkAbSW1fdiohGwK\",\"holdings\":[{\"coin\":\"iota\",\"balance\":13000000}, {\"coin\":\"stratis\",\"balance\":1300000}, {\"coin\":\"zcash\",\"balance\":10000}, {\"coin\":\"syscoin\",\"balance\":20000000}, {\"coin\":\"waves\",\"balance\":700000}, {\"coin\":\"bitcoin\",\"balance\":625}, {\"coin\":\"bitcoin-cash\",\"balance\":1500}, {\"coin\":\"heat-ledger\",\"balance\":2323851 }, {\"coin\":\"decred\",\"balance\":20000}, {\"coin\":\"vericoin\",\"balance\":2199368 }, {\"coin\":\"byteball\",\"balance\":4238}, {\"coin\":\"iocoin\",\"balance\":150000}, {\"coin\":\"quantum-resistant-ledger\",\"balance\":375000}, {\"coin\":\"chips\",\"balance\":2577006 }, {\"coin\":\"hush\",\"balance\":100000 }, {\"coin\":\"mobilego\",\"balance\":100000 }],\"divisor\":650000}" +curl --url "http://127.0.0.1:7783" --data "{\"userpass\":\"$userpass\",\"method\":\"fundvalue\",\"address\":\"RRyyejME7LRTuvdziWsXkAbSW1fdiohGwK\",\"holdings\":[{\"coin\":\"iota\",\"balance\":13000000}, {\"coin\":\"stratis\",\"balance\":1300000}, {\"coin\":\"zcash\",\"balance\":10000}, {\"coin\":\"syscoin\",\"balance\":20000000}, {\"coin\":\"waves\",\"balance\":700000}, {\"coin\":\"bitcoin\",\"balance\":625}, {\"coin\":\"bitcoin-cash\",\"balance\":1500}, {\"coin\":\"heat-ledger\",\"balance\":2323851 }, {\"coin\":\"decred\",\"balance\":20000}, {\"coin\":\"vericoin\",\"balance\":2199368 }, {\"coin\":\"byteball\",\"balance\":4238}, {\"coin\":\"iocoin\",\"balance\":150000}, {\"coin\":\"quantum-resistant-ledger\",\"balance\":375000}, {\"coin\":\"chips\",\"balance\":2577006 }, {\"coin\":\"hush\",\"balance\":100000 }, {\"coin\":\"mobilego\",\"balance\":100000 }],\"divisor\":816016}" From e035548f0b34a1c232c580775e13cf1cb53f50be Mon Sep 17 00:00:00 2001 From: jl777 Date: Tue, 5 Dec 2017 17:00:59 +0400 Subject: [PATCH 1548/1664] Test --- iguana/exchanges/LP_prices.c | 15 +++++++++++---- 1 file changed, 11 insertions(+), 4 deletions(-) diff --git a/iguana/exchanges/LP_prices.c b/iguana/exchanges/LP_prices.c index f9fa7046b..02c0e9f4f 100644 --- a/iguana/exchanges/LP_prices.c +++ b/iguana/exchanges/LP_prices.c @@ -1181,6 +1181,7 @@ cJSON *LP_fundvalue(cJSON *argjson) retjson = cJSON_CreateObject(); jadd(retjson,"holdings",array); btcprice = LP_CMCbtcprice(&usdprice,"komodo"); + divisor = jdouble(argjson,"divisor"); if ( btcsum != 0 ) { if ( btcprice > SMALLVAL ) @@ -1189,15 +1190,21 @@ cJSON *LP_fundvalue(cJSON *argjson) jaddnum(retjson,"KMD_BTC",btcprice); jaddnum(retjson,"btcsum",btcsum); jaddnum(retjson,"btcvalue",btcsum / btcprice); + if ( divisor != 0 ) + { + jaddnum(retjson,"NAV_KMD",(btcsum / btcprice)/divisor); + jaddnum(retjson,"NAV_BTC",btcsum/divisor); + jaddnum(retjson,"NAV_USD",(usdprice * (btcsum / btcprice))/divisor); + } } } jaddnum(retjson,"fundvalue",dstr(fundvalue)); - if ( (divisor= jdouble(argjson,"divisor")) != 0 ) + if ( divisor != 0 ) { jaddnum(retjson,"divisor",divisor); - jaddnum(retjson,"NAV_KMD",dstr(fundvalue)/divisor); - jaddnum(retjson,"NAV_BTC",(btcprice * dstr(fundvalue))/divisor); - jaddnum(retjson,"NAV_USD",(usdprice * dstr(fundvalue))/divisor); + jaddnum(retjson,"assetNAV_KMD",dstr(fundvalue)/divisor); + jaddnum(retjson,"assetNAV_BTC",(btcprice * dstr(fundvalue))/divisor); + jaddnum(retjson,"assetNAV_USD",(usdprice * dstr(fundvalue))/divisor); } return(retjson); } From f774aea4f82926c1c86aabadf236d70a033bb50d Mon Sep 17 00:00:00 2001 From: jl777 Date: Tue, 5 Dec 2017 17:06:18 +0400 Subject: [PATCH 1549/1664] Test --- iguana/exchanges/stats.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/iguana/exchanges/stats.c b/iguana/exchanges/stats.c index cc5005c61..f8c4dea27 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", "balances", "getprice", "notify", "getpeers", // from issue_ "uitem", "listunspent", - "orderbook", "statsdisp", "fundbalance", "help", "getcoins", "pricearray", "balance", "tradesarray" + "orderbook", "statsdisp", "fundvalue", "help", "getcoins", "pricearray", "balance", "tradesarray" }; int32_t LP_valid_remotemethod(cJSON *argjson) From a1e326982311a206c639140a2bc278c1e857652e Mon Sep 17 00:00:00 2001 From: jl777 Date: Tue, 5 Dec 2017 17:15:41 +0400 Subject: [PATCH 1550/1664] Test --- iguana/exchanges/mshark | 4 ++++ iguana/exchanges/supernet | 2 ++ 2 files changed, 6 insertions(+) create mode 100644 iguana/exchanges/mshark diff --git a/iguana/exchanges/mshark b/iguana/exchanges/mshark new file mode 100644 index 000000000..fc1f045db --- /dev/null +++ b/iguana/exchanges/mshark @@ -0,0 +1,4 @@ +#!/bin/bash +source userpass +# this will only work for watchonly addresses that have been rescanned and with active coins +curl --url "http://127.0.0.1:7783" --data "{\"userpass\":\"$userpass\",\"method\":\"fundvalue\",\"address\":\"RTu3JZZKLJTcfNwBa19dWRagEfQq49STqC\",\"holdings\":[{\"coin\":\"iota\",\"balance\":5000000}],\"divisor\":1400000}" diff --git a/iguana/exchanges/supernet b/iguana/exchanges/supernet index 4058bc4d0..59fa02abc 100755 --- a/iguana/exchanges/supernet +++ b/iguana/exchanges/supernet @@ -4,3 +4,5 @@ source userpass curl --url "http://127.0.0.1:7783" --data "{\"userpass\":\"$userpass\",\"method\":\"balances\",\"address\":\"RRyyejME7LRTuvdziWsXkAbSW1fdiohGwK\"}" curl --url "http://127.0.0.1:7783" --data "{\"userpass\":\"$userpass\",\"method\":\"fundvalue\",\"address\":\"RRyyejME7LRTuvdziWsXkAbSW1fdiohGwK\",\"holdings\":[{\"coin\":\"iota\",\"balance\":13000000}, {\"coin\":\"stratis\",\"balance\":1300000}, {\"coin\":\"zcash\",\"balance\":10000}, {\"coin\":\"syscoin\",\"balance\":20000000}, {\"coin\":\"waves\",\"balance\":700000}, {\"coin\":\"bitcoin\",\"balance\":625}, {\"coin\":\"bitcoin-cash\",\"balance\":1500}, {\"coin\":\"heat-ledger\",\"balance\":2323851 }, {\"coin\":\"decred\",\"balance\":20000}, {\"coin\":\"vericoin\",\"balance\":2199368 }, {\"coin\":\"byteball\",\"balance\":4238}, {\"coin\":\"iocoin\",\"balance\":150000}, {\"coin\":\"quantum-resistant-ledger\",\"balance\":375000}, {\"coin\":\"chips\",\"balance\":2577006 }, {\"coin\":\"hush\",\"balance\":100000 }, {\"coin\":\"mobilego\",\"balance\":100000 }],\"divisor\":816016}" + +#curl --url "http://5.9.253.196:7782" --data "{\"userpass\":\"$userpass\",\"method\":\"fundvalue\",\"address\":\"RRyyejME7LRTuvdziWsXkAbSW1fdiohGwK\",\"holdings\":[{\"coin\":\"iota\",\"balance\":13000000}, {\"coin\":\"stratis\",\"balance\":1300000}, {\"coin\":\"zcash\",\"balance\":10000}, {\"coin\":\"syscoin\",\"balance\":20000000}, {\"coin\":\"waves\",\"balance\":700000}, {\"coin\":\"bitcoin\",\"balance\":625}, {\"coin\":\"bitcoin-cash\",\"balance\":1500}, {\"coin\":\"heat-ledger\",\"balance\":2323851 }, {\"coin\":\"decred\",\"balance\":20000}, {\"coin\":\"vericoin\",\"balance\":2199368 }, {\"coin\":\"byteball\",\"balance\":4238}, {\"coin\":\"iocoin\",\"balance\":150000}, {\"coin\":\"quantum-resistant-ledger\",\"balance\":375000}, {\"coin\":\"chips\",\"balance\":2577006 }, {\"coin\":\"hush\",\"balance\":100000 }, {\"coin\":\"mobilego\",\"balance\":100000 }],\"divisor\":816016}" From 00dcb3b281a753712f438005f6faaa2e5f58c79c Mon Sep 17 00:00:00 2001 From: jl777 Date: Tue, 5 Dec 2017 17:16:35 +0400 Subject: [PATCH 1551/1664] Test --- iguana/exchanges/mshark | 0 1 file changed, 0 insertions(+), 0 deletions(-) mode change 100644 => 100755 iguana/exchanges/mshark diff --git a/iguana/exchanges/mshark b/iguana/exchanges/mshark old mode 100644 new mode 100755 From 25e44d812a183713310a07d3f360372f5b8902f6 Mon Sep 17 00:00:00 2001 From: jl777 Date: Tue, 5 Dec 2017 17:32:46 +0400 Subject: [PATCH 1552/1664] Test --- iguana/exchanges/LP_prices.c | 24 ++++++++++++++---------- 1 file changed, 14 insertions(+), 10 deletions(-) diff --git a/iguana/exchanges/LP_prices.c b/iguana/exchanges/LP_prices.c index 02c0e9f4f..e8c2df84a 100644 --- a/iguana/exchanges/LP_prices.c +++ b/iguana/exchanges/LP_prices.c @@ -1135,9 +1135,9 @@ double LP_CMCbtcprice(double *price_usdp,char *symbol) cJSON *LP_fundvalue(cJSON *argjson) { - cJSON *holdings,*item,*newitem,*array,*retjson; int32_t i,iter,n; double usdprice,divisor,btcprice,balance,btcsum; struct iguana_info *coin; char *symbol,*coinaddr; int64_t fundvalue,KMDvalue = 0; + cJSON *holdings,*item,*newitem,*array,*retjson; int32_t i,iter,n; double usdprice,divisor,btcprice,balance,btcsum,KMDholdings,numKMD; struct iguana_info *coin; char *symbol,*coinaddr; int64_t fundvalue,KMDvalue = 0; fundvalue = 0; - btcsum = 0.; + KMDholdings = btcsum = 0.; array = cJSON_CreateArray(); for (iter=0; iter<2; iter++) { @@ -1166,6 +1166,7 @@ cJSON *LP_fundvalue(cJSON *argjson) { jaddnum(newitem,"KMD",dstr(KMDvalue)); fundvalue += KMDvalue; + KMDholdings += dstr(KMDvalue); } else if ( iter == 0 && (btcprice= LP_CMCbtcprice(&usdprice,symbol)) > SMALLVAL ) { @@ -1186,15 +1187,17 @@ cJSON *LP_fundvalue(cJSON *argjson) { if ( btcprice > SMALLVAL ) { - fundvalue += (btcsum / btcprice) * SATOSHIDEN; + numKMD = (btcsum / btcprice); + fundvalue += numKMD * SATOSHIDEN; jaddnum(retjson,"KMD_BTC",btcprice); jaddnum(retjson,"btcsum",btcsum); - jaddnum(retjson,"btcvalue",btcsum / btcprice); + numKMD += KMDholdings; + jaddnum(retjson,"btcvalue",numKMD); if ( divisor != 0 ) { - jaddnum(retjson,"NAV_KMD",(btcsum / btcprice)/divisor); - jaddnum(retjson,"NAV_BTC",btcsum/divisor); - jaddnum(retjson,"NAV_USD",(usdprice * (btcsum / btcprice))/divisor); + jaddnum(retjson,"NAV_KMD",numKMD/divisor); + jaddnum(retjson,"NAV_BTC",(btcsum + (KMDholdings * btcprice))/divisor); + jaddnum(retjson,"NAV_USD",(usdprice * numKMD)/divisor); } } } @@ -1202,9 +1205,10 @@ cJSON *LP_fundvalue(cJSON *argjson) if ( divisor != 0 ) { jaddnum(retjson,"divisor",divisor); - jaddnum(retjson,"assetNAV_KMD",dstr(fundvalue)/divisor); - jaddnum(retjson,"assetNAV_BTC",(btcprice * dstr(fundvalue))/divisor); - jaddnum(retjson,"assetNAV_USD",(usdprice * dstr(fundvalue))/divisor); + numKMD = (dstr(fundvalue) - KMDholdings); + jaddnum(retjson,"assetNAV_KMD",numKMD/divisor); + jaddnum(retjson,"assetNAV_BTC",(btcprice * numKMD)/divisor); + jaddnum(retjson,"assetNAV_USD",(usdprice * numKMD)/divisor); } return(retjson); } From 91f824cc7f91e163f639d2e00d2fcef15c867ec5 Mon Sep 17 00:00:00 2001 From: jl777 Date: Tue, 5 Dec 2017 17:40:05 +0400 Subject: [PATCH 1553/1664] Test --- iguana/exchanges/LP_prices.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/iguana/exchanges/LP_prices.c b/iguana/exchanges/LP_prices.c index e8c2df84a..22dc0bc4e 100644 --- a/iguana/exchanges/LP_prices.c +++ b/iguana/exchanges/LP_prices.c @@ -1183,6 +1183,7 @@ cJSON *LP_fundvalue(cJSON *argjson) jadd(retjson,"holdings",array); btcprice = LP_CMCbtcprice(&usdprice,"komodo"); divisor = jdouble(argjson,"divisor"); + jaddnum(retjson,"KMDholdings",KMDholdings); if ( btcsum != 0 ) { if ( btcprice > SMALLVAL ) @@ -1192,7 +1193,7 @@ cJSON *LP_fundvalue(cJSON *argjson) jaddnum(retjson,"KMD_BTC",btcprice); jaddnum(retjson,"btcsum",btcsum); numKMD += KMDholdings; - jaddnum(retjson,"btcvalue",numKMD); + jaddnum(retjson,"btc2kmd",numKMD); if ( divisor != 0 ) { jaddnum(retjson,"NAV_KMD",numKMD/divisor); @@ -1205,7 +1206,7 @@ cJSON *LP_fundvalue(cJSON *argjson) if ( divisor != 0 ) { jaddnum(retjson,"divisor",divisor); - numKMD = (dstr(fundvalue) - KMDholdings); + numKMD = dstr(fundvalue); jaddnum(retjson,"assetNAV_KMD",numKMD/divisor); jaddnum(retjson,"assetNAV_BTC",(btcprice * numKMD)/divisor); jaddnum(retjson,"assetNAV_USD",(usdprice * numKMD)/divisor); From 8c0762e8a70e4cec7f940e3175288849cd9ef00b Mon Sep 17 00:00:00 2001 From: jl777 Date: Tue, 5 Dec 2017 17:44:12 +0400 Subject: [PATCH 1554/1664] test --- iguana/exchanges/LP_prices.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/iguana/exchanges/LP_prices.c b/iguana/exchanges/LP_prices.c index 22dc0bc4e..dfc5848a8 100644 --- a/iguana/exchanges/LP_prices.c +++ b/iguana/exchanges/LP_prices.c @@ -1149,8 +1149,7 @@ cJSON *LP_fundvalue(cJSON *argjson) { holdings = LP_balances(coinaddr); n = cJSON_GetArraySize(holdings); - } - else break; + } else break; } if ( holdings != 0 ) { @@ -1166,7 +1165,8 @@ cJSON *LP_fundvalue(cJSON *argjson) { jaddnum(newitem,"KMD",dstr(KMDvalue)); fundvalue += KMDvalue; - KMDholdings += dstr(KMDvalue); + if ( strcmp(symbol,"KMD") == 0 ) + KMDholdings += dstr(KMDvalue); } else if ( iter == 0 && (btcprice= LP_CMCbtcprice(&usdprice,symbol)) > SMALLVAL ) { From 30a77b996c183a918fe88a723d665a8290af8d7c Mon Sep 17 00:00:00 2001 From: jl777 Date: Tue, 5 Dec 2017 17:59:20 +0400 Subject: [PATCH 1555/1664] Test --- iguana/exchanges/bots | 4 ++++ iguana/exchanges/dex | 4 ++++ iguana/exchanges/hodl | 4 ++++ iguana/exchanges/jumblr | 4 ++++ iguana/exchanges/supernet | 11 +++++++++++ 5 files changed, 27 insertions(+) create mode 100755 iguana/exchanges/bots create mode 100755 iguana/exchanges/dex create mode 100755 iguana/exchanges/hodl create mode 100755 iguana/exchanges/jumblr diff --git a/iguana/exchanges/bots b/iguana/exchanges/bots new file mode 100755 index 000000000..b64e65088 --- /dev/null +++ b/iguana/exchanges/bots @@ -0,0 +1,4 @@ +#!/bin/bash +source userpass +# this will only work for watchonly addresses that have been rescanned and with active coins +curl --url "http://127.0.0.1:7783" --data "{\"userpass\":\"$userpass\",\"method\":\"fundvalue\",\"address\":\"RNdqHx26GWy9bk8MtmH1UiXjQcXE4RKK2P\",\"divisor\":1000000}" diff --git a/iguana/exchanges/dex b/iguana/exchanges/dex new file mode 100755 index 000000000..721768833 --- /dev/null +++ b/iguana/exchanges/dex @@ -0,0 +1,4 @@ +#!/bin/bash +source userpass +# this will only work for watchonly addresses that have been rescanned and with active coins +curl --url "http://127.0.0.1:7783" --data "{\"userpass\":\"$userpass\",\"method\":\"fundvalue\",\"address\":\"RThtXup6Zo7LZAi8kRWgjAyi1s4u6U9Cpf\",\"divisor\":1000000}" diff --git a/iguana/exchanges/hodl b/iguana/exchanges/hodl new file mode 100755 index 000000000..b70cf5456 --- /dev/null +++ b/iguana/exchanges/hodl @@ -0,0 +1,4 @@ +#!/bin/bash +source userpass +# this will only work for watchonly addresses that have been rescanned and with active coins +curl --url "http://127.0.0.1:7783" --data "{\"userpass\":\"$userpass\",\"method\":\"fundvalue\",\"address\":\"RNcUaMUEFLxVwtTo7rgruhwYanGk1jTkeU\",\"holdings\":[{\"coin\":\"siacoin\",\"balance\":185000000,\"comment\":\"using siafunds equal to million siacoin\"}],\"divisor\":10000000}" diff --git a/iguana/exchanges/jumblr b/iguana/exchanges/jumblr new file mode 100755 index 000000000..501a99333 --- /dev/null +++ b/iguana/exchanges/jumblr @@ -0,0 +1,4 @@ +#!/bin/bash +source userpass +# this will only work for watchonly addresses that have been rescanned and with active coins +curl --url "http://127.0.0.1:7783" --data "{\"userpass\":\"$userpass\",\"method\":\"fundvalue\",\"address\":\"RGhxXpXSSBTBm9EvNsXnTQczthMCxHX91t\",\"divisor\":1000000}" diff --git a/iguana/exchanges/supernet b/iguana/exchanges/supernet index 59fa02abc..be8a46d54 100755 --- a/iguana/exchanges/supernet +++ b/iguana/exchanges/supernet @@ -1,6 +1,17 @@ #!/bin/bash source userpass # this will only work for watchonly addresses that have been rescanned and with active coins +echo mshark +./mshark +echo hodl +./hodl +echo dex +./dex +echo jumblr +./jumblr +echo bots +./bots + curl --url "http://127.0.0.1:7783" --data "{\"userpass\":\"$userpass\",\"method\":\"balances\",\"address\":\"RRyyejME7LRTuvdziWsXkAbSW1fdiohGwK\"}" curl --url "http://127.0.0.1:7783" --data "{\"userpass\":\"$userpass\",\"method\":\"fundvalue\",\"address\":\"RRyyejME7LRTuvdziWsXkAbSW1fdiohGwK\",\"holdings\":[{\"coin\":\"iota\",\"balance\":13000000}, {\"coin\":\"stratis\",\"balance\":1300000}, {\"coin\":\"zcash\",\"balance\":10000}, {\"coin\":\"syscoin\",\"balance\":20000000}, {\"coin\":\"waves\",\"balance\":700000}, {\"coin\":\"bitcoin\",\"balance\":625}, {\"coin\":\"bitcoin-cash\",\"balance\":1500}, {\"coin\":\"heat-ledger\",\"balance\":2323851 }, {\"coin\":\"decred\",\"balance\":20000}, {\"coin\":\"vericoin\",\"balance\":2199368 }, {\"coin\":\"byteball\",\"balance\":4238}, {\"coin\":\"iocoin\",\"balance\":150000}, {\"coin\":\"quantum-resistant-ledger\",\"balance\":375000}, {\"coin\":\"chips\",\"balance\":2577006 }, {\"coin\":\"hush\",\"balance\":100000 }, {\"coin\":\"mobilego\",\"balance\":100000 }],\"divisor\":816016}" From 058fbe95986855bd54db739cc8d9eb6caa45ff3d Mon Sep 17 00:00:00 2001 From: jl777 Date: Tue, 5 Dec 2017 18:01:32 +0400 Subject: [PATCH 1556/1664] Test --- iguana/exchanges/supernet | 1 + 1 file changed, 1 insertion(+) diff --git a/iguana/exchanges/supernet b/iguana/exchanges/supernet index be8a46d54..3eade2bb5 100755 --- a/iguana/exchanges/supernet +++ b/iguana/exchanges/supernet @@ -11,6 +11,7 @@ echo jumblr ./jumblr echo bots ./bots +echo supernet curl --url "http://127.0.0.1:7783" --data "{\"userpass\":\"$userpass\",\"method\":\"balances\",\"address\":\"RRyyejME7LRTuvdziWsXkAbSW1fdiohGwK\"}" From 2f2615439e1468f16bf16eceeba72661c40c1d52 Mon Sep 17 00:00:00 2001 From: jl777 Date: Tue, 5 Dec 2017 18:13:46 +0400 Subject: [PATCH 1557/1664] Test --- iguana/exchanges/supernet | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/iguana/exchanges/supernet b/iguana/exchanges/supernet index 3eade2bb5..5374d5423 100755 --- a/iguana/exchanges/supernet +++ b/iguana/exchanges/supernet @@ -14,7 +14,7 @@ echo bots echo supernet curl --url "http://127.0.0.1:7783" --data "{\"userpass\":\"$userpass\",\"method\":\"balances\",\"address\":\"RRyyejME7LRTuvdziWsXkAbSW1fdiohGwK\"}" - +echo supernet curl --url "http://127.0.0.1:7783" --data "{\"userpass\":\"$userpass\",\"method\":\"fundvalue\",\"address\":\"RRyyejME7LRTuvdziWsXkAbSW1fdiohGwK\",\"holdings\":[{\"coin\":\"iota\",\"balance\":13000000}, {\"coin\":\"stratis\",\"balance\":1300000}, {\"coin\":\"zcash\",\"balance\":10000}, {\"coin\":\"syscoin\",\"balance\":20000000}, {\"coin\":\"waves\",\"balance\":700000}, {\"coin\":\"bitcoin\",\"balance\":625}, {\"coin\":\"bitcoin-cash\",\"balance\":1500}, {\"coin\":\"heat-ledger\",\"balance\":2323851 }, {\"coin\":\"decred\",\"balance\":20000}, {\"coin\":\"vericoin\",\"balance\":2199368 }, {\"coin\":\"byteball\",\"balance\":4238}, {\"coin\":\"iocoin\",\"balance\":150000}, {\"coin\":\"quantum-resistant-ledger\",\"balance\":375000}, {\"coin\":\"chips\",\"balance\":2577006 }, {\"coin\":\"hush\",\"balance\":100000 }, {\"coin\":\"mobilego\",\"balance\":100000 }],\"divisor\":816016}" #curl --url "http://5.9.253.196:7782" --data "{\"userpass\":\"$userpass\",\"method\":\"fundvalue\",\"address\":\"RRyyejME7LRTuvdziWsXkAbSW1fdiohGwK\",\"holdings\":[{\"coin\":\"iota\",\"balance\":13000000}, {\"coin\":\"stratis\",\"balance\":1300000}, {\"coin\":\"zcash\",\"balance\":10000}, {\"coin\":\"syscoin\",\"balance\":20000000}, {\"coin\":\"waves\",\"balance\":700000}, {\"coin\":\"bitcoin\",\"balance\":625}, {\"coin\":\"bitcoin-cash\",\"balance\":1500}, {\"coin\":\"heat-ledger\",\"balance\":2323851 }, {\"coin\":\"decred\",\"balance\":20000}, {\"coin\":\"vericoin\",\"balance\":2199368 }, {\"coin\":\"byteball\",\"balance\":4238}, {\"coin\":\"iocoin\",\"balance\":150000}, {\"coin\":\"quantum-resistant-ledger\",\"balance\":375000}, {\"coin\":\"chips\",\"balance\":2577006 }, {\"coin\":\"hush\",\"balance\":100000 }, {\"coin\":\"mobilego\",\"balance\":100000 }],\"divisor\":816016}" From 212c0a297dd7d572de3fa8819650af93d66e5f51 Mon Sep 17 00:00:00 2001 From: jl777 Date: Tue, 5 Dec 2017 21:06:37 +0400 Subject: [PATCH 1558/1664] Fix inverted trades array items --- iguana/exchanges/LP_stats.c | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-) diff --git a/iguana/exchanges/LP_stats.c b/iguana/exchanges/LP_stats.c index 12762b39d..cdbf8c936 100644 --- a/iguana/exchanges/LP_stats.c +++ b/iguana/exchanges/LP_stats.c @@ -852,9 +852,9 @@ void LP_ohlc_update(struct LP_ohlc *bar,uint32_t timestamp,double basevol,double } } -cJSON *LP_tradesarray(char *base,char *rel,uint32_t starttime,uint32_t endtime,int32_t timescale) +cJSON *LP_tradesarray(char *refbase,char *refrel,uint32_t starttime,uint32_t endtime,int32_t timescale) { - struct LP_ohlc *bars,nonz; cJSON *array,*item,*statsjson,*swaps; uint32_t timestamp; bits256 zero; int32_t i,n,numbars,bari; + struct LP_ohlc *bars,nonz; cJSON *array,*item,*statsjson,*swaps; uint32_t timestamp; bits256 zero; char *base,*rel; int32_t i,n,numbars,bari; if ( timescale < 60 ) return(cJSON_Parse("{\"error\":\"one minute is shortest timescale\"}")); memset(zero.bytes,0,sizeof(zero)); @@ -866,7 +866,7 @@ cJSON *LP_tradesarray(char *base,char *rel,uint32_t starttime,uint32_t endtime,i bars = calloc(numbars,sizeof(*bars)); for (bari=0; bari= starttime && timestamp <= endtime ) { bari = (timestamp - starttime) / timescale; + base = jstr(item,"base"); + rel = jstr(item,"rel"); + if ( strcmp(base,refbase) == 0 && strcmp(rel,refrel) == 0 ) LP_ohlc_update(&bars[bari],timestamp,jdouble(item,"basevol"),jdouble(item,"relvol")); + else if ( strcmp(rel,refbase) == 0 && strcmp(base,refrel) == 0 ) + LP_ohlc_update(&bars[bari],timestamp,jdouble(item,"relvol"),jdouble(item,"basevol")); } else printf("skip.(%s)\n",jprint(item,0)); } } From 643254cdfa886f092175b78cb4e4501f9e6cdce6 Mon Sep 17 00:00:00 2001 From: jl777 Date: Wed, 6 Dec 2017 00:11:40 +0400 Subject: [PATCH 1559/1664] Test --- iguana/exchanges/LP_commands.c | 8 +++-- iguana/exchanges/LP_statemachine.c | 57 ++++++++++++++++++++++++++++++ iguana/exchanges/mm.c | 56 ----------------------------- 3 files changed, 63 insertions(+), 58 deletions(-) diff --git a/iguana/exchanges/LP_commands.c b/iguana/exchanges/LP_commands.c index 0f1502df0..c7a0bb4ca 100644 --- a/iguana/exchanges/LP_commands.c +++ b/iguana/exchanges/LP_commands.c @@ -631,13 +631,17 @@ instantdex_claim()\n\ return(jprint(LP_fundvalue(argjson),1)); else if ( strcmp(method,"getprice") == 0 ) { - double price; - price = LP_price(base,rel); + double price,bid,ask; + ask = LP_price(base,rel); + bid = LP_price(rel,base); + price = _pairaved(bid,ask); retjson = cJSON_CreateObject(); jaddstr(retjson,"result","success"); jaddstr(retjson,"base",base); jaddstr(retjson,"rel",rel); jaddnum(retjson,"timestamp",time(NULL)); + jaddnum(retjson,"bid",bid); + jaddnum(retjson,"ask",ask); jaddnum(retjson,"price",price); return(jprint(retjson,1)); } diff --git a/iguana/exchanges/LP_statemachine.c b/iguana/exchanges/LP_statemachine.c index d970974e8..733530943 100644 --- a/iguana/exchanges/LP_statemachine.c +++ b/iguana/exchanges/LP_statemachine.c @@ -2094,6 +2094,63 @@ char *LP_postutxos_recv(cJSON *argjson) } return(clonestr("{\"error\":\"sig failure\"}")); } + +/*MERK d6071f9b03d1428b648d51ae1268f1605d97f44422ed55ad0335b13fa655f61a ht.518777 -> {"pos":1,"merkle":["526f8be81718beccc16a541a2c550b612123218d80fa884d9f080f18284e2bd8", "f68b03a7b6e418c9b306d8d8b21917ae5a584696f9b0b8cb0741733d7097fdfd"],"block_height":518777} root.(0000000000000000000000000000000000000000000000000000000000000000) + MERK c007e9c1881a83be453cb6ed3d1bd3bda85efd3b5ce60532c2e20ae3f8a82543 ht.518777 -> {"pos":2,"merkle":["fdff0962fb95120a86a07ddf1ec784fcc5554a2d0a3791a8db2083d593920501", "8c116e974c842ad3ad8b3ddbd71da3debb150e3fe692f5bd628381bc167311a7"],"block_height":518777} root.(0000000000000000000000000000000000000000000000000000000000000000)*/ +/*526f8be81718beccc16a541a2c550b612123218d80fa884d9f080f18284e2bd8 + d6071f9b03d1428b648d51ae1268f1605d97f44422ed55ad0335b13fa655f61a + c007e9c1881a83be453cb6ed3d1bd3bda85efd3b5ce60532c2e20ae3f8a82543 + fdff0962fb95120a86a07ddf1ec784fcc5554a2d0a3791a8db2083d593920501*/ + +/*0: 526f8be81718beccc16a541a2c550b612123218d80fa884d9f080f18284e2bd8 + 1: d6071f9b03d1428b648d51ae1268f1605d97f44422ed55ad0335b13fa655f61a + 2: c007e9c1881a83be453cb6ed3d1bd3bda85efd3b5ce60532c2e20ae3f8a82543 + 3: fdff0962fb95120a86a07ddf1ec784fcc5554a2d0a3791a8db2083d593920501 + 4: 8c116e974c842ad3ad8b3ddbd71da3debb150e3fe692f5bd628381bc167311a7 + 5: f68b03a7b6e418c9b306d8d8b21917ae5a584696f9b0b8cb0741733d7097fdfd + 6: a87ee259560f20b20182760c0e7cc7896d44381f0ad58a2e755a2b6b895b01ec*/ + +/* + 0 1 2 3 + 4 5 + 6 + + 1 -> [0, 5] + 2 -> [3, 4] + + if odd -> right, else left + then /= 2 + */ + +/*void testmerk() + { + bits256 tree[256],roothash,txid; int32_t i; char str[65]; + memset(tree,0,sizeof(tree)); + decode_hex(tree[0].bytes,32,"526f8be81718beccc16a541a2c550b612123218d80fa884d9f080f18284e2bd8"); + decode_hex(tree[1].bytes,32,"d6071f9b03d1428b648d51ae1268f1605d97f44422ed55ad0335b13fa655f61a"); + decode_hex(tree[2].bytes,32,"c007e9c1881a83be453cb6ed3d1bd3bda85efd3b5ce60532c2e20ae3f8a82543"); + decode_hex(tree[3].bytes,32,"fdff0962fb95120a86a07ddf1ec784fcc5554a2d0a3791a8db2083d593920501"); + roothash = iguana_merkle(tree,4); + for (i=0; i<256; i++) + { + if ( bits256_nonz(tree[i]) == 0 ) + break; + printf("%d: %s\n",i,bits256_str(str,tree[i])); + } + memset(tree,0,sizeof(tree)); + decode_hex(tree[0].bytes,32,"526f8be81718beccc16a541a2c550b612123218d80fa884d9f080f18284e2bd8"); + decode_hex(tree[1].bytes,32,"f68b03a7b6e418c9b306d8d8b21917ae5a584696f9b0b8cb0741733d7097fdfd"); + decode_hex(txid.bytes,32,"d6071f9b03d1428b648d51ae1268f1605d97f44422ed55ad0335b13fa655f61a"); + roothash = validate_merkle(1,txid,tree,2); + printf("validate 1: %s\n",bits256_str(str,roothash)); + memset(tree,0,sizeof(tree)); + decode_hex(tree[0].bytes,32,"fdff0962fb95120a86a07ddf1ec784fcc5554a2d0a3791a8db2083d593920501"); + decode_hex(tree[1].bytes,32,"8c116e974c842ad3ad8b3ddbd71da3debb150e3fe692f5bd628381bc167311a7"); + decode_hex(txid.bytes,32,"c007e9c1881a83be453cb6ed3d1bd3bda85efd3b5ce60532c2e20ae3f8a82543"); + roothash = validate_merkle(2,txid,tree,2); + printf("validate 2: %s\n",bits256_str(str,roothash)); + }*/ + /*else if ( (retstr= LP_orderbook(coin->symbol,"KMD",-1)) != 0 ) { if ( (orderbook= cJSON_Parse(retstr)) != 0 ) diff --git a/iguana/exchanges/mm.c b/iguana/exchanges/mm.c index b67f345b9..5382b33c3 100644 --- a/iguana/exchanges/mm.c +++ b/iguana/exchanges/mm.c @@ -806,62 +806,6 @@ void marketmaker(double minask,double maxbid,char *baseaddr,char *reladdr,double #include "LP_nativeDEX.c" -/*MERK d6071f9b03d1428b648d51ae1268f1605d97f44422ed55ad0335b13fa655f61a ht.518777 -> {"pos":1,"merkle":["526f8be81718beccc16a541a2c550b612123218d80fa884d9f080f18284e2bd8", "f68b03a7b6e418c9b306d8d8b21917ae5a584696f9b0b8cb0741733d7097fdfd"],"block_height":518777} root.(0000000000000000000000000000000000000000000000000000000000000000) - MERK c007e9c1881a83be453cb6ed3d1bd3bda85efd3b5ce60532c2e20ae3f8a82543 ht.518777 -> {"pos":2,"merkle":["fdff0962fb95120a86a07ddf1ec784fcc5554a2d0a3791a8db2083d593920501", "8c116e974c842ad3ad8b3ddbd71da3debb150e3fe692f5bd628381bc167311a7"],"block_height":518777} root.(0000000000000000000000000000000000000000000000000000000000000000)*/ -/*526f8be81718beccc16a541a2c550b612123218d80fa884d9f080f18284e2bd8 -d6071f9b03d1428b648d51ae1268f1605d97f44422ed55ad0335b13fa655f61a -c007e9c1881a83be453cb6ed3d1bd3bda85efd3b5ce60532c2e20ae3f8a82543 -fdff0962fb95120a86a07ddf1ec784fcc5554a2d0a3791a8db2083d593920501*/ - -/*0: 526f8be81718beccc16a541a2c550b612123218d80fa884d9f080f18284e2bd8 -1: d6071f9b03d1428b648d51ae1268f1605d97f44422ed55ad0335b13fa655f61a -2: c007e9c1881a83be453cb6ed3d1bd3bda85efd3b5ce60532c2e20ae3f8a82543 -3: fdff0962fb95120a86a07ddf1ec784fcc5554a2d0a3791a8db2083d593920501 -4: 8c116e974c842ad3ad8b3ddbd71da3debb150e3fe692f5bd628381bc167311a7 -5: f68b03a7b6e418c9b306d8d8b21917ae5a584696f9b0b8cb0741733d7097fdfd -6: a87ee259560f20b20182760c0e7cc7896d44381f0ad58a2e755a2b6b895b01ec*/ - -/* -0 1 2 3 - 4 5 - 6 - -1 -> [0, 5] -2 -> [3, 4] - -if odd -> right, else left -then /= 2 -*/ - -/*void testmerk() -{ - bits256 tree[256],roothash,txid; int32_t i; char str[65]; - memset(tree,0,sizeof(tree)); - decode_hex(tree[0].bytes,32,"526f8be81718beccc16a541a2c550b612123218d80fa884d9f080f18284e2bd8"); - decode_hex(tree[1].bytes,32,"d6071f9b03d1428b648d51ae1268f1605d97f44422ed55ad0335b13fa655f61a"); - decode_hex(tree[2].bytes,32,"c007e9c1881a83be453cb6ed3d1bd3bda85efd3b5ce60532c2e20ae3f8a82543"); - decode_hex(tree[3].bytes,32,"fdff0962fb95120a86a07ddf1ec784fcc5554a2d0a3791a8db2083d593920501"); - roothash = iguana_merkle(tree,4); - for (i=0; i<256; i++) - { - if ( bits256_nonz(tree[i]) == 0 ) - break; - printf("%d: %s\n",i,bits256_str(str,tree[i])); - } - memset(tree,0,sizeof(tree)); - decode_hex(tree[0].bytes,32,"526f8be81718beccc16a541a2c550b612123218d80fa884d9f080f18284e2bd8"); - decode_hex(tree[1].bytes,32,"f68b03a7b6e418c9b306d8d8b21917ae5a584696f9b0b8cb0741733d7097fdfd"); - decode_hex(txid.bytes,32,"d6071f9b03d1428b648d51ae1268f1605d97f44422ed55ad0335b13fa655f61a"); - roothash = validate_merkle(1,txid,tree,2); - printf("validate 1: %s\n",bits256_str(str,roothash)); - memset(tree,0,sizeof(tree)); - decode_hex(tree[0].bytes,32,"fdff0962fb95120a86a07ddf1ec784fcc5554a2d0a3791a8db2083d593920501"); - decode_hex(tree[1].bytes,32,"8c116e974c842ad3ad8b3ddbd71da3debb150e3fe692f5bd628381bc167311a7"); - decode_hex(txid.bytes,32,"c007e9c1881a83be453cb6ed3d1bd3bda85efd3b5ce60532c2e20ae3f8a82543"); - roothash = validate_merkle(2,txid,tree,2); - printf("validate 2: %s\n",bits256_str(str,roothash)); -}*/ - void LP_main(void *ptr) { char *passphrase; double profitmargin; uint16_t port; cJSON *argjson = ptr; From 415c1116cc6edd309ce0e0ee77fbac8ed91dd8e2 Mon Sep 17 00:00:00 2001 From: jl777 Date: Wed, 6 Dec 2017 10:14:11 +0400 Subject: [PATCH 1560/1664] Test --- iguana/exchanges/LP_NXT.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/iguana/exchanges/LP_NXT.c b/iguana/exchanges/LP_NXT.c index e962daa7d..8ea588733 100644 --- a/iguana/exchanges/LP_NXT.c +++ b/iguana/exchanges/LP_NXT.c @@ -33,7 +33,7 @@ static char *assetids[][4] = { "13476425053110940554", "CRYPTO", "1000", "100000" }, { "6932037131189568014", "HODL", "1", "100000000" }, //{ "3006420581923704757", "SHARK", "10000", "10000" }, - { "3006420581923704757", "MSHARK", "10000", "10000000" }, + { "3006420581923704757", "MSHARK", "10", "10000000" }, { "17571711292785902558", "BOTS", "1", "100000000" }, { "10524562908394749924", "MGW", "1", "100000000" }, { "8217222248380501882", "MESH", "10000", "10000" }, From fd7f88898061cd3f77903af068a55e21aefc9fc3 Mon Sep 17 00:00:00 2001 From: jl777 Date: Wed, 6 Dec 2017 10:46:20 +0400 Subject: [PATCH 1561/1664] Test --- iguana/exchanges/LP_transaction.c | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/iguana/exchanges/LP_transaction.c b/iguana/exchanges/LP_transaction.c index c563e1ee5..5d33f1ecf 100644 --- a/iguana/exchanges/LP_transaction.c +++ b/iguana/exchanges/LP_transaction.c @@ -1333,6 +1333,7 @@ char *LP_withdraw(struct iguana_info *coin,cJSON *argjson) privkeys = cJSON_CreateArray(); vins = cJSON_CreateArray(); memset(V,0,sizeof(*V) * maxV); + numvins = 0; if ( (rawtx= LP_createrawtransaction(&txobj,&numvins,coin,V,maxV,privkey,outputs,vins,privkeys,iter == 0 ? txfee : newtxfee,utxotxid,utxovout,locktime)) != 0 ) { completed = 0; @@ -1371,7 +1372,18 @@ char *LP_withdraw(struct iguana_info *coin,cJSON *argjson) } free(V); if ( vins != 0 ) + { + if ( (numvins= cJSON_GetArraySize(vins)) > 0 ) + { + + for (i=0; i Date: Wed, 6 Dec 2017 12:43:22 +0400 Subject: [PATCH 1562/1664] Test --- iguana/exchanges/LP_commands.c | 3 ++- iguana/exchanges/LP_utxo.c | 2 +- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/iguana/exchanges/LP_commands.c b/iguana/exchanges/LP_commands.c index c7a0bb4ca..160ea295f 100644 --- a/iguana/exchanges/LP_commands.c +++ b/iguana/exchanges/LP_commands.c @@ -633,7 +633,8 @@ instantdex_claim()\n\ { double price,bid,ask; ask = LP_price(base,rel); - bid = LP_price(rel,base); + if ( (bid= LP_price(rel,base)) > SMALLVAL ) + bid = 1./bid; price = _pairaved(bid,ask); retjson = cJSON_CreateObject(); jaddstr(retjson,"result","success"); diff --git a/iguana/exchanges/LP_utxo.c b/iguana/exchanges/LP_utxo.c index 683ea34ad..aff6dd983 100644 --- a/iguana/exchanges/LP_utxo.c +++ b/iguana/exchanges/LP_utxo.c @@ -49,7 +49,7 @@ int32_t _LP_inuse_delete(bits256 txid,int32_t vout) *lp = LP_inuse[--LP_numinuse]; lp->ind = ind; memset(&LP_inuse[LP_numinuse],0,sizeof(struct LP_inuse_info)); - printf("_LP_inuse_delete mark as free %s/v%d find.%p\n",bits256_str(str,txid),vout,_LP_inuse_find(txid,vout)); + //printf("_LP_inuse_delete mark as free %s/v%d find.%p\n",bits256_str(str,txid),vout,_LP_inuse_find(txid,vout)); for (ind=0; ind Date: Wed, 6 Dec 2017 12:57:16 +0400 Subject: [PATCH 1563/1664] Test --- iguana/exchanges/LP_transaction.c | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/iguana/exchanges/LP_transaction.c b/iguana/exchanges/LP_transaction.c index 5d33f1ecf..9a2f8cf4a 100644 --- a/iguana/exchanges/LP_transaction.c +++ b/iguana/exchanges/LP_transaction.c @@ -1350,7 +1350,7 @@ char *LP_withdraw(struct iguana_info *coin,cJSON *argjson) if ( signedtx == 0 ) break; datalen = (int32_t)strlen(signedtx) / 2; - if ( strcmp(coin->symbol,"BTC") == 0 ) + if ( iter == 0 && strcmp(coin->symbol,"BTC") == 0 ) { newtxfee = LP_txfeecalc(coin,0,datalen); printf("txfee %.8f -> newtxfee %.8f, numvins.%d\n",dstr(txfee),dstr(newtxfee),numvins); @@ -1360,15 +1360,15 @@ char *LP_withdraw(struct iguana_info *coin,cJSON *argjson) //printf("set available %s\n",jprint(item,0)); LP_availableset(jbits256(item,"txid"),jint(item,"vout")); } + free_json(vins), vins = 0; + free_json(txobj), txobj = 0; + free_json(privkeys), privkeys = 0; + if ( rawtx != 0 ) + free(rawtx), rawtx = 0; + if ( signedtx != 0 ) + free(signedtx), signedtx = 0; } 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; - if ( signedtx != 0 ) - free(signedtx), signedtx = 0; } free(V); if ( vins != 0 ) From 24179e54c49789d984990665ac059275e3cc100f Mon Sep 17 00:00:00 2001 From: jl777 Date: Wed, 6 Dec 2017 13:06:38 +0400 Subject: [PATCH 1564/1664] Test --- iguana/exchanges/LP_ordermatch.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/iguana/exchanges/LP_ordermatch.c b/iguana/exchanges/LP_ordermatch.c index 5ae711df3..9c5243ca7 100644 --- a/iguana/exchanges/LP_ordermatch.c +++ b/iguana/exchanges/LP_ordermatch.c @@ -428,11 +428,11 @@ struct LP_utxoinfo *LP_address_myutxopair(struct LP_utxoinfo *butxo,int32_t iamb { 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); + 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 ( 0 ) + if ( 1 ) { int32_t i; for (i=0; i Date: Wed, 6 Dec 2017 13:08:22 +0400 Subject: [PATCH 1565/1664] Test --- iguana/exchanges/LP_ordermatch.c | 2 +- iguana/exchanges/LP_utxo.c | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/iguana/exchanges/LP_ordermatch.c b/iguana/exchanges/LP_ordermatch.c index 9c5243ca7..9b77becc2 100644 --- a/iguana/exchanges/LP_ordermatch.c +++ b/iguana/exchanges/LP_ordermatch.c @@ -413,7 +413,7 @@ struct LP_utxoinfo *LP_address_myutxopair(struct LP_utxoinfo *butxo,int32_t iamb { if ( (m= LP_address_utxo_ptrs(coin,iambob,utxos,max,ap,coinaddr)) > 1 ) { - if ( 0 ) + if ( 1 ) { int32_t i; for (i=0; i Date: Wed, 6 Dec 2017 13:12:52 +0400 Subject: [PATCH 1566/1664] Test --- iguana/exchanges/LP_ordermatch.c | 2 +- iguana/exchanges/LP_utxo.c | 6 +++++- 2 files changed, 6 insertions(+), 2 deletions(-) diff --git a/iguana/exchanges/LP_ordermatch.c b/iguana/exchanges/LP_ordermatch.c index 9b77becc2..a48d6fc13 100644 --- a/iguana/exchanges/LP_ordermatch.c +++ b/iguana/exchanges/LP_ordermatch.c @@ -417,7 +417,7 @@ struct LP_utxoinfo *LP_address_myutxopair(struct LP_utxoinfo *butxo,int32_t iamb { int32_t i; for (i=0; iU.value >= targetval ) + //if ( utxos[i]->U.value >= targetval ) 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); } diff --git a/iguana/exchanges/LP_utxo.c b/iguana/exchanges/LP_utxo.c index 63434e033..efcaf9c5e 100644 --- a/iguana/exchanges/LP_utxo.c +++ b/iguana/exchanges/LP_utxo.c @@ -484,7 +484,11 @@ struct LP_address *LP_address_utxo_reset(struct iguana_info *coin) LP_address_utxoadd(now,"withdraw",coin,coin->smartaddr,txid,vout,value,height,-1); if ( (up= LP_address_utxofind(coin,coin->smartaddr,txid,vout)) == 0 ) printf("couldnt find just added %s/%d ht.%d %.8f\n",bits256_str(str,txid),vout,height,dstr(value)); - else m++; + else + { + m++; + printf("%.8f ",dstr(value)); + } } printf("added %d from listunspents\n",m); } From e980fbff33d07af8e0773461905c60a63d9f73a4 Mon Sep 17 00:00:00 2001 From: jl777 Date: Wed, 6 Dec 2017 13:16:30 +0400 Subject: [PATCH 1567/1664] Test --- iguana/exchanges/LP_ordermatch.c | 6 +++--- iguana/exchanges/LP_utxo.c | 4 ++-- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/iguana/exchanges/LP_ordermatch.c b/iguana/exchanges/LP_ordermatch.c index a48d6fc13..ff8d15968 100644 --- a/iguana/exchanges/LP_ordermatch.c +++ b/iguana/exchanges/LP_ordermatch.c @@ -413,11 +413,11 @@ struct LP_utxoinfo *LP_address_myutxopair(struct LP_utxoinfo *butxo,int32_t iamb { if ( (m= LP_address_utxo_ptrs(coin,iambob,utxos,max,ap,coinaddr)) > 1 ) { - if ( 1 ) + if ( 0 ) { int32_t i; for (i=0; iU.value >= targetval ) + if ( utxos[i]->U.value >= targetval ) 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); } @@ -432,7 +432,7 @@ struct LP_utxoinfo *LP_address_myutxopair(struct LP_utxoinfo *butxo,int32_t iamb if ( (double)up->U.value/targetval < ratio-1 ) { - if ( 1 ) + if ( 0 ) { int32_t i; for (i=0; i Date: Wed, 6 Dec 2017 13:23:53 +0400 Subject: [PATCH 1568/1664] Test --- iguana/exchanges/LP_instantdex.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/iguana/exchanges/LP_instantdex.c b/iguana/exchanges/LP_instantdex.c index cb01b37b8..95ae264af 100644 --- a/iguana/exchanges/LP_instantdex.c +++ b/iguana/exchanges/LP_instantdex.c @@ -313,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)); + } else printf("null ap.%p or expired %ld\n",ap,time(NULL) - (timestamp-60*3600)); } return(0); } @@ -336,7 +336,7 @@ 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 %s funded %.8f weeki.%d (%s)\n",bits256_str(str,txid),destaddr,dstr(satoshis),weeki,jprint(item,0)); + char str[65]; 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 ) From b47f9bfae65b4dd2fe9eca3eb0d3a5871d53299d Mon Sep 17 00:00:00 2001 From: jl777 Date: Wed, 6 Dec 2017 13:27:16 +0400 Subject: [PATCH 1569/1664] Test --- iguana/exchanges/LP_instantdex.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/iguana/exchanges/LP_instantdex.c b/iguana/exchanges/LP_instantdex.c index 95ae264af..614be4dd7 100644 --- a/iguana/exchanges/LP_instantdex.c +++ b/iguana/exchanges/LP_instantdex.c @@ -93,7 +93,7 @@ char *LP_instantdex_deposit(struct iguana_info *coin,int32_t weeks,double amount { timestamp = (uint32_t)time(NULL); timestamp /= LP_WEEKMULT; - timestamp += weeks+1; + timestamp += weeks+2; timestamp *= LP_WEEKMULT; weeki = (timestamp - LP_FIRSTWEEKTIME) / LP_WEEKMULT; if ( weeks >= 10000 ) From f709fcc36773a2e53a92cfc7b3a76f7e599d77bd Mon Sep 17 00:00:00 2001 From: jl777 Date: Wed, 6 Dec 2017 13:36:08 +0400 Subject: [PATCH 1570/1664] Test --- iguana/exchanges/LP_instantdex.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/iguana/exchanges/LP_instantdex.c b/iguana/exchanges/LP_instantdex.c index 614be4dd7..abec20302 100644 --- a/iguana/exchanges/LP_instantdex.c +++ b/iguana/exchanges/LP_instantdex.c @@ -29,11 +29,11 @@ cJSON *LP_instantdex_txids() { char *filestr,fname[1024],afname[1024]; long fsize; cJSON *retjson=0; LP_instantdex_txidaddfname(fname,afname); - if ( (filestr= OS_filestr(&fsize,fname)) != 0 ) + if ( (filestr= OS_filestr(&fsize,afname)) != 0 ) { retjson = cJSON_Parse(filestr); free(filestr); - } else printf("couldnt open (%s)\n",fname); + } else printf("couldnt open (%s)\n",afname); return(retjson); } @@ -336,7 +336,7 @@ 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); - char str[65]; printf("%s %s funded %.8f weeki.%d (%s)\n",bits256_str(str,txid),destaddr,dstr(satoshis),weeki,jprint(item,0)); + //char str[65]; 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 ) From 5f5af675ed6439c9bae6b4e3dfbe47c686907b06 Mon Sep 17 00:00:00 2001 From: jl777 Date: Wed, 6 Dec 2017 13:44:00 +0400 Subject: [PATCH 1571/1664] Test --- iguana/exchanges/LP_instantdex.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/iguana/exchanges/LP_instantdex.c b/iguana/exchanges/LP_instantdex.c index abec20302..c859e60ea 100644 --- a/iguana/exchanges/LP_instantdex.c +++ b/iguana/exchanges/LP_instantdex.c @@ -186,7 +186,7 @@ int64_t LP_claimtx(void *ctx,struct iguana_info *coin,bits256 *claimtxidp,bits25 userdatalen = 1; utxovout = 0; memset(claimtxidp,0,sizeof(*claimtxidp)); - char str[65]; printf("satoshis %.8f %s/v%d\n",dstr(satoshis),bits256_str(str,utxotxid),utxovout); + char str[65]; printf("LP_claimtx satoshis %.8f %s/v%d\n",dstr(satoshis),bits256_str(str,utxotxid),utxovout); if ( (signedtx= basilisk_swap_bobtxspend(&signedtxid,10000,"instantdexclaim",coin->symbol,coin->wiftaddr,coin->taddr,coin->pubtype,coin->p2shtype,coin->isPoS,coin->wiftype,ctx,G.LP_privkey,0,redeemscript,redeemlen,userdata,userdatalen,utxotxid,utxovout,coin->smartaddr,G.LP_pubsecp,0,claimtime,&destamount,0,0,vinaddr,1,coin->zcash)) != 0 ) { printf("signedtx.(%s)\n",signedtx); @@ -259,7 +259,8 @@ int32_t LP_claim_submit(void *ctx,cJSON *txids,int64_t *sump,struct iguana_info } 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"); + } + printf("cant get transaction flagi.%d\n",flagi); return(flagi); } @@ -282,6 +283,7 @@ char *LP_instantdex_claim(struct iguana_info *coin) for (i=0; i Date: Wed, 6 Dec 2017 13:50:20 +0400 Subject: [PATCH 1572/1664] Test --- iguana/exchanges/LP_instantdex.c | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/iguana/exchanges/LP_instantdex.c b/iguana/exchanges/LP_instantdex.c index c859e60ea..796d090e3 100644 --- a/iguana/exchanges/LP_instantdex.c +++ b/iguana/exchanges/LP_instantdex.c @@ -204,7 +204,7 @@ int64_t LP_claimtx(void *ctx,struct iguana_info *coin,bits256 *claimtxidp,bits25 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; + 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,iter; 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 ) @@ -219,9 +219,10 @@ int32_t LP_claim_submit(void *ctx,cJSON *txids,int64_t *sump,struct iguana_info vout1 = jitem(vouts,1); weeksatoshis = LP_value_extract(vout1,0); weeki = (int32_t)(weeksatoshis % 10000); - for (j=0; j<2*168; j++) + for (iter=0; iter<2; iter++) + for (j=-168; j<=168; j++) { - if ( j >= 168 ) + if ( iter == 1 ) 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); From 1b3eea22bf75be26a5041d3d320ca9dbf522801c Mon Sep 17 00:00:00 2001 From: jl777 Date: Wed, 6 Dec 2017 13:53:17 +0400 Subject: [PATCH 1573/1664] Test --- iguana/exchanges/LP_instantdex.c | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/iguana/exchanges/LP_instantdex.c b/iguana/exchanges/LP_instantdex.c index 796d090e3..2f179b633 100644 --- a/iguana/exchanges/LP_instantdex.c +++ b/iguana/exchanges/LP_instantdex.c @@ -223,7 +223,7 @@ int32_t LP_claim_submit(void *ctx,cJSON *txids,int64_t *sump,struct iguana_info for (j=-168; j<=168; j++) { if ( iter == 1 ) - expiration = ((weeki * LP_WEEKMULTBAD + (j-168)*3600) + LP_FIRSTWEEKTIME); + expiration = ((weeki * LP_WEEKMULTBAD + j*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 ) @@ -238,7 +238,7 @@ int32_t LP_claim_submit(void *ctx,cJSON *txids,int64_t *sump,struct iguana_info 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)); + printf("iter.%d j.%d claimtime.%u vs %u, wait %d seconds to %s claim %.8f\n",iter,j,claimtime,expiration,(int32_t)expiration-claimtime,bits256_str(str,utxotxid),dstr(satoshis)); jaddnum(item,"waittime",(int32_t)expiration-claimtime); jaddi(txids,item); break; @@ -260,8 +260,7 @@ int32_t LP_claim_submit(void *ctx,cJSON *txids,int64_t *sump,struct iguana_info } else printf("vout2 dest.(%s) != %s\n",destaddr,coin->smartaddr); } else printf("numvouts %d != 3\n",numvouts); free_json(txjson); - } - printf("cant get transaction flagi.%d\n",flagi); + } else printf("cant get transaction flagi.%d\n",flagi); return(flagi); } From 280426f36ea0e01aeb039335160a3c27745424d8 Mon Sep 17 00:00:00 2001 From: jl777 Date: Wed, 6 Dec 2017 16:11:22 +0400 Subject: [PATCH 1574/1664] Test --- crypto777/iguana_OS.c | 2 +- iguana/exchanges/LP_instantdex.c | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/crypto777/iguana_OS.c b/crypto777/iguana_OS.c index 2000651a9..d08756752 100755 --- a/crypto777/iguana_OS.c +++ b/crypto777/iguana_OS.c @@ -877,7 +877,7 @@ void *OS_loadfile(char *fname,char **bufp,long *lenp,long *allocsizep) { fclose(fp); *lenp = 0; - printf("OS_loadfile null size.(%s)\n",fname); + //printf("OS_loadfile null size.(%s)\n",fname); return(0); } if ( filesize > buflen-1 ) diff --git a/iguana/exchanges/LP_instantdex.c b/iguana/exchanges/LP_instantdex.c index 2f179b633..1641da198 100644 --- a/iguana/exchanges/LP_instantdex.c +++ b/iguana/exchanges/LP_instantdex.c @@ -283,7 +283,7 @@ char *LP_instantdex_claim(struct iguana_info *coin) for (i=0; i Date: Wed, 6 Dec 2017 16:45:07 +0400 Subject: [PATCH 1575/1664] Test --- iguana/exchanges/LP_nativeDEX.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/iguana/exchanges/LP_nativeDEX.c b/iguana/exchanges/LP_nativeDEX.c index a7e11ec6c..133f81a46 100644 --- a/iguana/exchanges/LP_nativeDEX.c +++ b/iguana/exchanges/LP_nativeDEX.c @@ -618,7 +618,7 @@ void LP_coinsloop(void *_coins) continue; } nonz++; - if ( 0 && coin->lastscanht < coin->longestchain-3 ) + if ( strcmp("BTC",coins) == 0 )//&& coin->lastscanht < coin->longestchain-3 ) printf("[%s]: %s ref.%d scan.%d to %d, longest.%d\n",coins,coin->symbol,coin->firstrefht,coin->firstscanht,coin->lastscanht,coin->longestchain); for (j=0; j<100; j++) { @@ -630,7 +630,7 @@ void LP_coinsloop(void *_coins) break; } coin->lastscanht++; - if ( coin->lastscanht == coin->longestchain+1 ) + if ( coin->lastscanht == coin->longestchain+1 || strcmp("BTC",coins) == 0 ) break; } } From 55524bddf360215a81511a6af1922d3dbe75dfa5 Mon Sep 17 00:00:00 2001 From: jl777 Date: Wed, 6 Dec 2017 16:57:00 +0400 Subject: [PATCH 1576/1664] Test --- iguana/exchanges/LP_nativeDEX.c | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/iguana/exchanges/LP_nativeDEX.c b/iguana/exchanges/LP_nativeDEX.c index 133f81a46..433862ac9 100644 --- a/iguana/exchanges/LP_nativeDEX.c +++ b/iguana/exchanges/LP_nativeDEX.c @@ -500,6 +500,8 @@ void LP_coinsloop(void *_coins) } while ( 1 ) { + if ( strcmp("BTC",coins) == 0 ) + printf("BTC loop\n"); if ( strcmp("BTC",coins) == 0 ) LP_millistats_update(&LP_coinsloopBTC_stats); else if ( strcmp("KMD",coins) == 0 ) @@ -633,6 +635,8 @@ void LP_coinsloop(void *_coins) if ( coin->lastscanht == coin->longestchain+1 || strcmp("BTC",coins) == 0 ) break; } + if ( strcmp("BTC",coins) == 0 ) + printf("done [%s]: %s ref.%d scan.%d to %d, longest.%d\n",coins,coin->symbol,coin->firstrefht,coin->firstscanht,coin->lastscanht,coin->longestchain); } if ( coins == 0 ) return; From afb5698d57de0c0c948d595c563aff5ae3001c86 Mon Sep 17 00:00:00 2001 From: jl777 Date: Wed, 6 Dec 2017 16:57:58 +0400 Subject: [PATCH 1577/1664] Test --- crypto777/bitcoind_RPC.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/crypto777/bitcoind_RPC.c b/crypto777/bitcoind_RPC.c index 6bb5d3a12..f669f04ca 100755 --- a/crypto777/bitcoind_RPC.c +++ b/crypto777/bitcoind_RPC.c @@ -73,7 +73,7 @@ char *post_process_bitcoind_RPC(char *debugstr,char *command,char *rpcstr,char * char *retstr = 0; cJSON *json,*result,*error; #ifdef FROM_MARKETMAKER - usleep(3000); + //usleep(3000); #endif //printf("<<<<<<<<<<< bitcoind_RPC: %s post_process_bitcoind_RPC.%s.[%s]\n",debugstr,command,rpcstr); if ( command == 0 || rpcstr == 0 || rpcstr[0] == 0 ) From 014e63d094fb1b1dd75f465c11c2727b4a2a78d1 Mon Sep 17 00:00:00 2001 From: jl777 Date: Wed, 6 Dec 2017 17:00:09 +0400 Subject: [PATCH 1578/1664] Test --- iguana/exchanges/LP_scan.c | 1 + 1 file changed, 1 insertion(+) diff --git a/iguana/exchanges/LP_scan.c b/iguana/exchanges/LP_scan.c index 90e2f3899..850852f23 100644 --- a/iguana/exchanges/LP_scan.c +++ b/iguana/exchanges/LP_scan.c @@ -26,6 +26,7 @@ int32_t LP_blockinit(struct iguana_info *coin,int32_t height) { if ( (txs= jarray(&numtx,blockobj,"tx")) != 0 ) { + printf("LP_blockinit %s ht.%d numtx.%d\n",coin->symbol,height,numtx); for (iter=0; iter<2; iter++) { txobj = 0; From 072b6fa9023cfa01a363b5ff4a2d1ad8545c8a4d Mon Sep 17 00:00:00 2001 From: jl777 Date: Wed, 6 Dec 2017 17:16:58 +0400 Subject: [PATCH 1579/1664] Test --- iguana/exchanges/LP_nativeDEX.c | 31 +++++++++++++++++-------------- iguana/exchanges/LP_remember.c | 8 +++++--- 2 files changed, 22 insertions(+), 17 deletions(-) diff --git a/iguana/exchanges/LP_nativeDEX.c b/iguana/exchanges/LP_nativeDEX.c index 433862ac9..50114f4b6 100644 --- a/iguana/exchanges/LP_nativeDEX.c +++ b/iguana/exchanges/LP_nativeDEX.c @@ -619,24 +619,27 @@ void LP_coinsloop(void *_coins) coin->lastscanht = coin->firstscanht; continue; } - nonz++; - if ( strcmp("BTC",coins) == 0 )//&& coin->lastscanht < coin->longestchain-3 ) - printf("[%s]: %s ref.%d scan.%d to %d, longest.%d\n",coins,coin->symbol,coin->firstrefht,coin->firstscanht,coin->lastscanht,coin->longestchain); - for (j=0; j<100; j++) + if ( 0 ) { - if ( LP_blockinit(coin,coin->lastscanht) < 0 ) + nonz++; + if ( strcmp("BTC",coins) == 0 )//&& coin->lastscanht < coin->longestchain-3 ) + printf("[%s]: %s ref.%d scan.%d to %d, longest.%d\n",coins,coin->symbol,coin->firstrefht,coin->firstscanht,coin->lastscanht,coin->longestchain); + for (j=0; j<100; j++) { - static uint32_t counter; - if ( counter++ < 3 ) - printf("blockinit.%s %d error\n",coin->symbol,coin->lastscanht); - break; + if ( LP_blockinit(coin,coin->lastscanht) < 0 ) + { + static uint32_t counter; + if ( counter++ < 3 ) + printf("blockinit.%s %d error\n",coin->symbol,coin->lastscanht); + break; + } + coin->lastscanht++; + if ( coin->lastscanht == coin->longestchain+1 || strcmp("BTC",coins) == 0 ) + break; } - coin->lastscanht++; - if ( coin->lastscanht == coin->longestchain+1 || strcmp("BTC",coins) == 0 ) - break; + if ( strcmp("BTC",coins) == 0 ) + printf("done [%s]: %s ref.%d scan.%d to %d, longest.%d\n",coins,coin->symbol,coin->firstrefht,coin->firstscanht,coin->lastscanht,coin->longestchain); } - if ( strcmp("BTC",coins) == 0 ) - printf("done [%s]: %s ref.%d scan.%d to %d, longest.%d\n",coins,coin->symbol,coin->firstrefht,coin->firstscanht,coin->lastscanht,coin->longestchain); } if ( coins == 0 ) return; diff --git a/iguana/exchanges/LP_remember.c b/iguana/exchanges/LP_remember.c index e3a1eed24..bd134d140 100644 --- a/iguana/exchanges/LP_remember.c +++ b/iguana/exchanges/LP_remember.c @@ -256,9 +256,12 @@ bits256 basilisk_swap_privBn_extract(bits256 *bobrefundp,char *bobcoin,bits256 b bits256 basilisk_swap_spendupdate(int32_t iambob,char *symbol,char *spentaddr,int32_t *sentflags,bits256 *txids,int32_t utxoind,int32_t alicespent,int32_t bobspent,int32_t vout,char *aliceaddr,char *bobaddr,char *Adest,char *dest) { bits256 spendtxid,txid; char destaddr[64],str[65]; int32_t i,n,m; struct iguana_info *coin; cJSON *array,*txobj,*vins,*vin; - if ( (coin= LP_coinfind(symbol)) != 0 && coin->electrum != 0 ) + memset(&spendtxid,0,sizeof(spendtxid)); + if ( (coin= LP_coinfind(symbol)) == 0 ) + return(spendtxid); + printf("spentaddr.%s aliceaddr.%s bobaddr.%s Adest.%s Bdest.%s\n",spentaddr,aliceaddr,bobaddr,Adest,dest); + if ( coin->electrum != 0 ) { - //printf("spentaddr.%s aliceaddr.%s bobaddr.%s Adest.%s Bdest.%s\n",spentaddr,aliceaddr,bobaddr,Adest,dest); if ( (array= electrum_address_gethistory(symbol,coin->electrum,&array,spentaddr,txids[utxoind])) != 0 ) { if ( (n= cJSON_GetArraySize(array)) > 0 ) @@ -287,7 +290,6 @@ bits256 basilisk_swap_spendupdate(int32_t iambob,char *symbol,char *spentaddr,in } } txid = txids[utxoind]; - memset(&spendtxid,0,sizeof(spendtxid)); if ( bits256_nonz(txid) != 0 )//&& sentflags[utxoind] != 0 ) { destaddr[0] = 0; From 80741f7fadf679b5548e9455a39b1cf268adfac9 Mon Sep 17 00:00:00 2001 From: jl777 Date: Wed, 6 Dec 2017 17:25:26 +0400 Subject: [PATCH 1580/1664] Test --- iguana/exchanges/LP_nativeDEX.c | 2 -- 1 file changed, 2 deletions(-) diff --git a/iguana/exchanges/LP_nativeDEX.c b/iguana/exchanges/LP_nativeDEX.c index 50114f4b6..66b1e122c 100644 --- a/iguana/exchanges/LP_nativeDEX.c +++ b/iguana/exchanges/LP_nativeDEX.c @@ -500,8 +500,6 @@ void LP_coinsloop(void *_coins) } while ( 1 ) { - if ( strcmp("BTC",coins) == 0 ) - printf("BTC loop\n"); if ( strcmp("BTC",coins) == 0 ) LP_millistats_update(&LP_coinsloopBTC_stats); else if ( strcmp("KMD",coins) == 0 ) From 0bbc7d666a61e4750bdc2802f1eaba815627dda2 Mon Sep 17 00:00:00 2001 From: jl777 Date: Wed, 6 Dec 2017 17:37:00 +0400 Subject: [PATCH 1581/1664] Test --- iguana/exchanges/LP_nativeDEX.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/iguana/exchanges/LP_nativeDEX.c b/iguana/exchanges/LP_nativeDEX.c index 66b1e122c..e3875a70a 100644 --- a/iguana/exchanges/LP_nativeDEX.c +++ b/iguana/exchanges/LP_nativeDEX.c @@ -617,7 +617,7 @@ void LP_coinsloop(void *_coins) coin->lastscanht = coin->firstscanht; continue; } - if ( 0 ) + if ( 1 ) { nonz++; if ( strcmp("BTC",coins) == 0 )//&& coin->lastscanht < coin->longestchain-3 ) From f44fb1d7938edb10d13dd9b4c0628a231424baf5 Mon Sep 17 00:00:00 2001 From: jl777 Date: Wed, 6 Dec 2017 19:54:06 +0400 Subject: [PATCH 1582/1664] Test --- iguana/exchanges/LP_instantdex.c | 7 ++++++- iguana/exchanges/LP_remember.c | 2 +- 2 files changed, 7 insertions(+), 2 deletions(-) diff --git a/iguana/exchanges/LP_instantdex.c b/iguana/exchanges/LP_instantdex.c index 1641da198..113968f7f 100644 --- a/iguana/exchanges/LP_instantdex.c +++ b/iguana/exchanges/LP_instantdex.c @@ -33,7 +33,12 @@ cJSON *LP_instantdex_txids() { retjson = cJSON_Parse(filestr); free(filestr); - } else printf("couldnt open (%s)\n",afname); + } + else if ( (filestr= OS_filestr(&fsize,fname)) != 0 ) + { + retjson = cJSON_Parse(filestr); + free(filestr); + } else printf("couldnt open (%s) or (%s)\n",fname,afname); return(retjson); } diff --git a/iguana/exchanges/LP_remember.c b/iguana/exchanges/LP_remember.c index bd134d140..9a4eacd20 100644 --- a/iguana/exchanges/LP_remember.c +++ b/iguana/exchanges/LP_remember.c @@ -259,7 +259,7 @@ bits256 basilisk_swap_spendupdate(int32_t iambob,char *symbol,char *spentaddr,in memset(&spendtxid,0,sizeof(spendtxid)); if ( (coin= LP_coinfind(symbol)) == 0 ) return(spendtxid); - printf("spentaddr.%s aliceaddr.%s bobaddr.%s Adest.%s Bdest.%s\n",spentaddr,aliceaddr,bobaddr,Adest,dest); + //printf("spentaddr.%s aliceaddr.%s bobaddr.%s Adest.%s Bdest.%s\n",spentaddr,aliceaddr,bobaddr,Adest,dest); if ( coin->electrum != 0 ) { if ( (array= electrum_address_gethistory(symbol,coin->electrum,&array,spentaddr,txids[utxoind])) != 0 ) From cebcfd43cc189d140fafdf53af9f09dd4cee6474 Mon Sep 17 00:00:00 2001 From: jl777 Date: Wed, 6 Dec 2017 22:46:33 +0400 Subject: [PATCH 1583/1664] Test --- iguana/exchanges/LP_instantdex.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/iguana/exchanges/LP_instantdex.c b/iguana/exchanges/LP_instantdex.c index 113968f7f..d0564cc0b 100644 --- a/iguana/exchanges/LP_instantdex.c +++ b/iguana/exchanges/LP_instantdex.c @@ -410,7 +410,7 @@ int64_t LP_dynamictrust(bits256 pubkey,int64_t kmdvalue) swaps_kmdvalue += LP_kmdvalue(sp->Q.destcoin,sp->Q.destsatoshis); } 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)); + //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)); } @@ -420,7 +420,7 @@ int64_t LP_dynamictrust(bits256 pubkey,int64_t kmdvalue) int64_t LP_instantdex_proofcheck(char *coinaddr,cJSON *proof,int32_t num) { - uint8_t rmd160[20],addrtype; int32_t i; int64_t net = 0; char othersmartaddr[64]; struct iguana_info *coin; struct LP_address *ap = 0; + uint8_t rmd160[20],addrtype; int32_t i; char othersmartaddr[64]; struct iguana_info *coin; struct LP_address *ap = 0; if ( (coin= LP_coinfind("KMD")) != 0 ) { bitcoin_addr2rmd160(0,&addrtype,rmd160,coinaddr); @@ -431,8 +431,8 @@ int64_t LP_instantdex_proofcheck(char *coinaddr,cJSON *proof,int32_t num) 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)); + if ( ap->instantdex_credits > 0 ) + printf("validated instantdex %s.[%d] proof.(%s) credits %.8f\n",othersmartaddr,num,jprint(proof,0),dstr(ap->instantdex_credits)); } //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); From 9111b477403b448aed7f23ae35b1cd5c777ba968 Mon Sep 17 00:00:00 2001 From: jl777 Date: Thu, 7 Dec 2017 13:15:09 +0400 Subject: [PATCH 1584/1664] Make instantdex.json robust --- iguana/exchanges/LP_commands.c | 4 +- iguana/exchanges/LP_instantdex.c | 123 ++++++++++++++++++++++------- iguana/exchanges/LP_nativeDEX.c | 3 + iguana/exchanges/LP_ordermatch.c | 2 +- iguana/exchanges/LP_signatures.c | 2 +- iguana/exchanges/LP_statemachine.c | 22 ++++++ 6 files changed, 124 insertions(+), 32 deletions(-) diff --git a/iguana/exchanges/LP_commands.c b/iguana/exchanges/LP_commands.c index 160ea295f..431996de2 100644 --- a/iguana/exchanges/LP_commands.c +++ b/iguana/exchanges/LP_commands.c @@ -157,7 +157,7 @@ bot_settings(botid, newprice, newvolume)\n\ bot_status(botid)\n\ bot_stop(botid)\n\ bot_pause(botid)\n\ -instantdex_deposit(weeks, amount, broadcast=0)\n\ +instantdex_deposit(weeks, amount, broadcast=1)\n\ instantdex_claim()\n\ \"}")); //sell(base, rel, price, basevolume, timeout=10, duration=3600)\n\ @@ -208,7 +208,7 @@ instantdex_claim()\n\ { if ( jint(argjson,"weeks") <= 0 || jdouble(argjson,"amount") < 10. ) return(clonestr("{\"error\":\"instantdex_deposit needs to have weeks and amount\"}")); - else return(LP_instantdex_deposit(ptr,juint(argjson,"weeks"),jdouble(argjson,"amount"),jint(argjson,"broadcast"))); + else return(LP_instantdex_deposit(ptr,juint(argjson,"weeks"),jdouble(argjson,"amount"),jobj(argjson,"broadcast") != 0 ? jint(argjson,"broadcast") : 1)); } return(clonestr("{\"error\":\"cant find KMD\"}")); } diff --git a/iguana/exchanges/LP_instantdex.c b/iguana/exchanges/LP_instantdex.c index d0564cc0b..d06d6714a 100644 --- a/iguana/exchanges/LP_instantdex.c +++ b/iguana/exchanges/LP_instantdex.c @@ -25,16 +25,11 @@ void LP_instantdex_txidaddfname(char *fname,char *afname) sprintf(afname,"%s/instantdex_append.json",GLOBAL_DBDIR); } -cJSON *LP_instantdex_txids() +cJSON *LP_instantdex_txids(int32_t appendonly) { char *filestr,fname[1024],afname[1024]; long fsize; cJSON *retjson=0; LP_instantdex_txidaddfname(fname,afname); - if ( (filestr= OS_filestr(&fsize,afname)) != 0 ) - { - retjson = cJSON_Parse(filestr); - free(filestr); - } - else if ( (filestr= OS_filestr(&fsize,fname)) != 0 ) + if ( (filestr= OS_filestr(&fsize,appendonly != 0 ? afname : fname)) != 0 ) { retjson = cJSON_Parse(filestr); free(filestr); @@ -55,25 +50,89 @@ void LP_instantdex_filewrite(int32_t appendfile,cJSON *array) } } -void LP_instantdex_txidadd(bits256 txid) +void LP_instantdex_deposituniq(FILE *fp,bits256 txid) { - cJSON *array; int32_t i,n; - if ( (array= LP_instantdex_txids()) == 0 ) - array = cJSON_CreateArray(); - if ( (n= cJSON_GetArraySize(array)) >= 0 ) + int32_t i,n; bits256 prevtxid; + n = (int32_t)(ftell(fp) / sizeof(txid)); + for (i=0; i 0 ) + { + for (i=0; i 0 ) @@ -295,6 +353,7 @@ char *LP_instantdex_claim(struct iguana_info *coin) } free_json(array); } + firsttime = 0; if ( cJSON_GetArraySize(newarray) > 0 ) LP_instantdex_filewrite(0,newarray); free_json(newarray); @@ -315,8 +374,6 @@ int64_t LP_instantdex_credit(int32_t dispflag,char *coinaddr,int64_t satoshis,in { ap->instantdex_credits += satoshis; ap->didinstantdex = 1; - if ( strcmp(coinaddr,coin->smartaddr) == 0 ) - LP_instantdex_txidadd(txid); 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); @@ -420,7 +477,7 @@ int64_t LP_dynamictrust(bits256 pubkey,int64_t kmdvalue) int64_t LP_instantdex_proofcheck(char *coinaddr,cJSON *proof,int32_t num) { - uint8_t rmd160[20],addrtype; int32_t i; char othersmartaddr[64]; struct iguana_info *coin; struct LP_address *ap = 0; + uint8_t rmd160[20],addrtype; int32_t i,j; bits256 prevtxid,txid; char othersmartaddr[64]; struct iguana_info *coin; struct LP_address *ap = 0; if ( (coin= LP_coinfind("KMD")) != 0 ) { bitcoin_addr2rmd160(0,&addrtype,rmd160,coinaddr); @@ -429,7 +486,17 @@ int64_t LP_instantdex_proofcheck(char *coinaddr,cJSON *proof,int32_t num) { ap->instantdex_credits = 0; for (i=0; ididinstantdex = 1; if ( ap->instantdex_credits > 0 ) printf("validated instantdex %s.[%d] proof.(%s) credits %.8f\n",othersmartaddr,num,jprint(proof,0),dstr(ap->instantdex_credits)); @@ -443,7 +510,7 @@ int64_t LP_myzcredits() cJSON *proof; struct iguana_info *coin; int64_t zcredits; if ( (coin= LP_coinfind("KMD")) != 0 ) { - if ( (proof= LP_instantdex_txids()) != 0 ) + if ( (proof= LP_instantdex_txids(0)) != 0 ) { zcredits = LP_instantdex_proofcheck(coin->smartaddr,proof,cJSON_GetArraySize(proof)); free_json(proof); diff --git a/iguana/exchanges/LP_nativeDEX.c b/iguana/exchanges/LP_nativeDEX.c index e3875a70a..13dc2287c 100644 --- a/iguana/exchanges/LP_nativeDEX.c +++ b/iguana/exchanges/LP_nativeDEX.c @@ -712,7 +712,10 @@ void LP_initcoins(void *ctx,int32_t pubsock,cJSON *coins) { LP_unspents_load(coin->symbol,coin->smartaddr); if ( strcmp(coin->symbol,"KMD") == 0 ) + { LP_importaddress("KMD",BOTS_BONDADDRESS); + LP_instantdex_filescreate(); + } } if ( coin->txfee == 0 && strcmp(coin->symbol,"BTC") != 0 ) coin->txfee = LP_MIN_TXFEE; diff --git a/iguana/exchanges/LP_ordermatch.c b/iguana/exchanges/LP_ordermatch.c index ff8d15968..850a5e255 100644 --- a/iguana/exchanges/LP_ordermatch.c +++ b/iguana/exchanges/LP_ordermatch.c @@ -492,7 +492,7 @@ int32_t LP_connectstartbob(void *ctx,int32_t pubsock,char *base,char *rel,double reqjson = LP_quotejson(qp); jaddstr(reqjson,"method","connected"); jaddstr(reqjson,"pair",pairstr); - jadd(reqjson,"proof",LP_instantdex_txids()); + jadd(reqjson,"proof",LP_instantdex_txids(0)); char str[65]; printf("BOB pubsock.%d binds to %d (%s)\n",pubsock,pair,bits256_str(str,qp->desthash)); bits256 zero; memset(zero.bytes,0,sizeof(zero)); diff --git a/iguana/exchanges/LP_signatures.c b/iguana/exchanges/LP_signatures.c index 4fce8ca7f..74cf86fee 100644 --- a/iguana/exchanges/LP_signatures.c +++ b/iguana/exchanges/LP_signatures.c @@ -665,7 +665,7 @@ void LP_query(void *ctx,char *myipaddr,int32_t mypubsock,char *method,struct LP_ if ( jobj(reqjson,"timestamp") == 0 ) jaddnum(reqjson,"timestamp",time(NULL)); if ( strcmp(method,"connect") == 0 ) - jadd(reqjson,"proof",LP_instantdex_txids()); + jadd(reqjson,"proof",LP_instantdex_txids(0)); msg = jprint(reqjson,1); printf("QUERY.(%s)\n",msg); //if ( bits256_nonz(qp->srchash) == 0 || strcmp(method,"request") != 0 ) diff --git a/iguana/exchanges/LP_statemachine.c b/iguana/exchanges/LP_statemachine.c index 733530943..c8e3988a5 100644 --- a/iguana/exchanges/LP_statemachine.c +++ b/iguana/exchanges/LP_statemachine.c @@ -447,6 +447,28 @@ void issue_LP_uitem(char *destip,uint16_t destport,char *symbol,char *coinaddr,b portable_mutex_unlock(&LP_cJSONmutex); } //else printf("cJSON_unregister of unknown %p %u\n",item,item->cjsonid); }*/ + +void LP_instantdex_txidadd(bits256 txid) +{ + cJSON *array; int32_t i,n; + if ( (array= LP_instantdex_txids()) == 0 ) + array = cJSON_CreateArray(); + if ( (n= cJSON_GetArraySize(array)) >= 0 ) + { + for (i=0; i Date: Thu, 7 Dec 2017 13:18:19 +0400 Subject: [PATCH 1585/1664] Test --- iguana/exchanges/LP_instantdex.c | 11 +++++------ iguana/exchanges/LP_nativeDEX.c | 5 +++-- 2 files changed, 8 insertions(+), 8 deletions(-) diff --git a/iguana/exchanges/LP_instantdex.c b/iguana/exchanges/LP_instantdex.c index d06d6714a..0f23cb622 100644 --- a/iguana/exchanges/LP_instantdex.c +++ b/iguana/exchanges/LP_instantdex.c @@ -95,11 +95,10 @@ void LP_instantdex_filescreate() } } - void LP_instantdex_depositadd(bits256 txid) { static FILE *depositsfp; - char fname[512],coinaddr[64]; cJSON *array,*txobj; int32_t i,n,iter; + char fname[512],coinaddr[64]; bits256 prevtxid; cJSON *array,*txobj; int32_t i,n,iter; if ( depositsfp == 0 ) { sprintf(fname,"%s/deposits",GLOBAL_DBDIR), OS_compatible_path(fname); @@ -115,11 +114,11 @@ void LP_instantdex_depositadd(bits256 txid) { for (i=0; isymbol,"KMD") == 0 ) { LP_importaddress("KMD",BOTS_BONDADDRESS); - LP_instantdex_filescreate(); + memset(zero.bytes,0,sizeof(zero)); + LP_instantdex_depositadd(zero); } } if ( coin->txfee == 0 && strcmp(coin->symbol,"BTC") != 0 ) From 3fa095c3fb44261a2bd787a2d2b71dae7dc14cac Mon Sep 17 00:00:00 2001 From: jl777 Date: Thu, 7 Dec 2017 13:26:28 +0400 Subject: [PATCH 1586/1664] Test --- iguana/exchanges/LP_instantdex.c | 18 ++++++++++++++---- 1 file changed, 14 insertions(+), 4 deletions(-) diff --git a/iguana/exchanges/LP_instantdex.c b/iguana/exchanges/LP_instantdex.c index 0f23cb622..ea9d5113e 100644 --- a/iguana/exchanges/LP_instantdex.c +++ b/iguana/exchanges/LP_instantdex.c @@ -52,18 +52,23 @@ void LP_instantdex_filewrite(int32_t appendfile,cJSON *array) void LP_instantdex_deposituniq(FILE *fp,bits256 txid) { - int32_t i,n; bits256 prevtxid; + int32_t i,n; bits256 prevtxid; char str[65]; n = (int32_t)(ftell(fp) / sizeof(txid)); for (i=0; i 0 ) { for (i=0; i Date: Thu, 7 Dec 2017 13:30:46 +0400 Subject: [PATCH 1587/1664] Test --- iguana/exchanges/LP_instantdex.c | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/iguana/exchanges/LP_instantdex.c b/iguana/exchanges/LP_instantdex.c index ea9d5113e..8d4f97ce5 100644 --- a/iguana/exchanges/LP_instantdex.c +++ b/iguana/exchanges/LP_instantdex.c @@ -87,7 +87,7 @@ void LP_instantdex_filescreate() fseek(fp,sizeof(txid) * i,SEEK_SET); fread(&txid,1,sizeof(txid),fp); jaddibits256(array,txid); - if ( (txobj= LP_gettxout("KMD",coinaddr,txid,2)) != 0 ) + if ( (txobj= LP_gettxout("KMD",coinaddr,txid,0)) != 0 ) free_json(txobj); else continue; jaddibits256(newarray,txid); @@ -115,13 +115,12 @@ void LP_instantdex_depositadd(bits256 txid) { if ( (array= LP_instantdex_txids(iter)) != 0 ) { - printf("iter.%d: %s\n",iter,jprint(array,0)); if ( (n= cJSON_GetArraySize(array)) > 0 ) { for (i=0; i Date: Thu, 7 Dec 2017 13:39:15 +0400 Subject: [PATCH 1588/1664] Test --- iguana/exchanges/LP_instantdex.c | 16 +++++++--------- iguana/exchanges/LP_nativeDEX.c | 6 +----- iguana/exchanges/LP_privkey.c | 5 ++++- 3 files changed, 12 insertions(+), 15 deletions(-) diff --git a/iguana/exchanges/LP_instantdex.c b/iguana/exchanges/LP_instantdex.c index 8d4f97ce5..c8d2c08e3 100644 --- a/iguana/exchanges/LP_instantdex.c +++ b/iguana/exchanges/LP_instantdex.c @@ -71,17 +71,16 @@ void LP_instantdex_deposituniq(FILE *fp,bits256 txid) } else fseek(fp,n * sizeof(txid),SEEK_SET); } -void LP_instantdex_filescreate() +void LP_instantdex_filescreate(char *coinaddr) { - char fname[512]; FILE *fp; char coinaddr[64]; bits256 txid; int32_t i,n; cJSON *array,*newarray,*txobj; - sprintf(fname,"%s/deposits",GLOBAL_DBDIR), OS_compatible_path(fname); + char fname[512]; FILE *fp; bits256 txid; int32_t i,n; cJSON *array,*newarray,*txobj; + sprintf(fname,"%s/deposits.%s",GLOBAL_DBDIR,coinaddr), OS_compatible_path(fname); if ( (fp= fopen(fname,"rb")) != 0 ) { array = cJSON_CreateArray(); newarray = cJSON_CreateArray(); fseek(fp,0,SEEK_END); n = (int32_t)(ftell(fp) / sizeof(txid)); - bitcoin_address(coinaddr,0,60,G.LP_myrmd160,20); for (i=0; isymbol,coin->smartaddr); if ( strcmp(coin->symbol,"KMD") == 0 ) - { LP_importaddress("KMD",BOTS_BONDADDRESS); - memset(zero.bytes,0,sizeof(zero)); - LP_instantdex_depositadd(zero); - } } if ( coin->txfee == 0 && strcmp(coin->symbol,"BTC") != 0 ) coin->txfee = LP_MIN_TXFEE; diff --git a/iguana/exchanges/LP_privkey.c b/iguana/exchanges/LP_privkey.c index 5c77b4c89..0d5a515dd 100644 --- a/iguana/exchanges/LP_privkey.c +++ b/iguana/exchanges/LP_privkey.c @@ -307,7 +307,7 @@ void LP_privkey_updates(void *ctx,int32_t pubsock,char *passphrase) int32_t LP_passphrase_init(char *passphrase,char *gui) { - static void *ctx; int32_t counter; //iambob,; struct LP_utxoinfo *utxo,*tmp; + static void *ctx; char coinaddr[64]; bits256 zero; int32_t counter; //iambob,; struct LP_utxoinfo *utxo,*tmp; if ( ctx == 0 ) ctx = bitcoin_ctx(); if ( G.LP_pendingswaps != 0 ) @@ -348,6 +348,9 @@ int32_t LP_passphrase_init(char *passphrase,char *gui) safecopy(G.gui,gui,sizeof(G.gui)); G.USERPASS_COUNTER = counter; G.initializing = 0; + bitcoin_address(coinaddr,0,60,G.LP_myrmd160,20); + memset(zero.bytes,0,sizeof(zero)); + LP_instantdex_depositadd(coinaddr,zero); return(0); } From 57bc22d0a05a100f78440cc415c10b2b5a17ac2b Mon Sep 17 00:00:00 2001 From: jl777 Date: Thu, 7 Dec 2017 13:40:36 +0400 Subject: [PATCH 1589/1664] Test --- iguana/exchanges/LP_instantdex.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/iguana/exchanges/LP_instantdex.c b/iguana/exchanges/LP_instantdex.c index c8d2c08e3..6644188c7 100644 --- a/iguana/exchanges/LP_instantdex.c +++ b/iguana/exchanges/LP_instantdex.c @@ -213,7 +213,7 @@ char *LP_instantdex_deposit(struct iguana_info *coin,int32_t weeks,double amount { jaddstr(retjson,"result","success"); jaddbits256(retjson,"broadcast",sendtxid); - LP_instantdex_depositadd(txid); + LP_instantdex_depositadd(coin->smartaddr,txid); free(retstr); return(jprint(retjson,1)); } From 8d481102cc4d5e4e5e67d7985b137e5dd9049d42 Mon Sep 17 00:00:00 2001 From: jl777 Date: Thu, 7 Dec 2017 15:32:34 +0400 Subject: [PATCH 1590/1664] Test --- iguana/exchanges/LP_nativeDEX.c | 7 +---- iguana/exchanges/LP_ordermatch.c | 2 ++ iguana/exchanges/LP_remember.c | 25 +++++++-------- iguana/exchanges/LP_statemachine.c | 5 +++ iguana/exchanges/LP_transaction.c | 50 ++++++++++++++++++++++++------ 5 files changed, 60 insertions(+), 29 deletions(-) diff --git a/iguana/exchanges/LP_nativeDEX.c b/iguana/exchanges/LP_nativeDEX.c index e3875a70a..0f12bd976 100644 --- a/iguana/exchanges/LP_nativeDEX.c +++ b/iguana/exchanges/LP_nativeDEX.c @@ -617,7 +617,7 @@ void LP_coinsloop(void *_coins) coin->lastscanht = coin->firstscanht; continue; } - if ( 1 ) + if ( 0 ) { nonz++; if ( strcmp("BTC",coins) == 0 )//&& coin->lastscanht < coin->longestchain-3 ) @@ -1223,11 +1223,6 @@ void LPinit(uint16_t myport,uint16_t mypullport,uint16_t mypubport,uint16_t mybu printf("error launching LP_tradessloop for ctx.%p\n",ctx); exit(-1); } - /*if ( 0 && OS_thread_create(malloc(sizeof(pthread_t)),NULL,(void *)LP_privkeysloop,ctx) != 0 ) - { - printf("error launching LP_privkeysloop for ctx.%p\n",ctx); - exit(-1); - }*/ if ( OS_thread_create(malloc(sizeof(pthread_t)),NULL,(void *)LP_swapsloop,ctx) != 0 ) { printf("error launching LP_swapsloop for ctx.%p\n",ctx); diff --git a/iguana/exchanges/LP_ordermatch.c b/iguana/exchanges/LP_ordermatch.c index 850a5e255..3db0881a8 100644 --- a/iguana/exchanges/LP_ordermatch.c +++ b/iguana/exchanges/LP_ordermatch.c @@ -504,6 +504,7 @@ int32_t LP_connectstartbob(void *ctx,int32_t pubsock,char *base,char *rel,double } LP_reserved_msg(0,base,rel,zero,jprint(reqjson,0)); free_json(reqjson); + LP_importaddress(qp->destcoin,qp->destaddr); retval = 0; } else printf("error launching swaploop\n"); } else printf("couldnt bind to any port %s\n",pairstr); @@ -654,6 +655,7 @@ char *LP_connectedalice(struct LP_quoteinfo *qp,char *pairstr) // alice swap->N.pair = pairsock; //autxo->S.swap = swap; //swap->utxo = autxo; + LP_importaddress(qp->srccoin,qp->coinaddr); LP_aliceid(qp->tradeid,qp->aliceid,"started",qp->R.requestid,qp->R.quoteid); printf("alice pairstr.(%s) pairsock.%d pthread_t %ld\n",pairstr,pairsock,sizeof(pthread_t)); if ( OS_thread_create(malloc(sizeof(pthread_t)),NULL,(void *)LP_aliceloop,(void *)swap) == 0 ) diff --git a/iguana/exchanges/LP_remember.c b/iguana/exchanges/LP_remember.c index 9a4eacd20..b7a6ea3d1 100644 --- a/iguana/exchanges/LP_remember.c +++ b/iguana/exchanges/LP_remember.c @@ -243,6 +243,7 @@ bits256 basilisk_swap_privbob_extract(char *symbol,bits256 spendtxid,int32_t vin bits256 basilisk_swap_privBn_extract(bits256 *bobrefundp,char *bobcoin,bits256 bobdeposit,bits256 privBn) { char destaddr[64]; + destaddr[0] = 0; if ( bits256_nonz(privBn) == 0 ) { if ( bits256_nonz(bobdeposit) != 0 ) @@ -253,10 +254,11 @@ bits256 basilisk_swap_privBn_extract(bits256 *bobrefundp,char *bobcoin,bits256 b return(privBn); } -bits256 basilisk_swap_spendupdate(int32_t iambob,char *symbol,char *spentaddr,int32_t *sentflags,bits256 *txids,int32_t utxoind,int32_t alicespent,int32_t bobspent,int32_t vout,char *aliceaddr,char *bobaddr,char *Adest,char *dest) +bits256 basilisk_swap_spendupdate(int32_t iambob,char *symbol,char *spentaddr,int32_t *sentflags,bits256 *txids,int32_t utxoind,int32_t alicespent,int32_t bobspent,int32_t utxovout,char *aliceaddr,char *bobaddr,char *Adest,char *dest) { - bits256 spendtxid,txid; char destaddr[64],str[65]; int32_t i,n,m; struct iguana_info *coin; cJSON *array,*txobj,*vins,*vin; + bits256 spendtxid,txid; char destaddr[64],str[65]; int32_t i,n; struct iguana_info *coin; cJSON *array,*txobj; memset(&spendtxid,0,sizeof(spendtxid)); + destaddr[0] = 0; if ( (coin= LP_coinfind(symbol)) == 0 ) return(spendtxid); //printf("spentaddr.%s aliceaddr.%s bobaddr.%s Adest.%s Bdest.%s\n",spentaddr,aliceaddr,bobaddr,Adest,dest); @@ -272,16 +274,8 @@ bits256 basilisk_swap_spendupdate(int32_t iambob,char *symbol,char *spentaddr,in //printf("i.%d of %d: %s\n",i,n,bits256_str(str,txid)); if ( bits256_cmp(txid,txids[utxoind]) != 0 ) { - if ( (txobj= LP_gettx(symbol,txid,1)) != 0 ) - { - //printf("txobj.(%s)\n",jprint(txobj,0)); - if ( (vins= jarray(&m,txobj,"vin")) != 0 ) - { - vin = jitem(vins,0); - //printf("vin0.(%s)\n",jprint(vin,0)); - } + if ( (txobj= LP_gettx(symbol,txid,1)) != 0 ) // good side effects free_json(txobj); - } } } } @@ -289,11 +283,16 @@ bits256 basilisk_swap_spendupdate(int32_t iambob,char *symbol,char *spentaddr,in free_json(array); } } + else + { + if ( iambob != 0 ) + strcpy(destaddr,aliceaddr); + else strcpy(destaddr,bobaddr); + } txid = txids[utxoind]; if ( bits256_nonz(txid) != 0 )//&& sentflags[utxoind] != 0 ) { - destaddr[0] = 0; - spendtxid = LP_swap_spendtxid(symbol,destaddr,txid,vout); + spendtxid = LP_swap_spendtxid(symbol,destaddr,txid,utxovout); if ( bits256_nonz(spendtxid) != 0 ) { sentflags[utxoind] = 1; diff --git a/iguana/exchanges/LP_statemachine.c b/iguana/exchanges/LP_statemachine.c index c8e3988a5..3855c789f 100644 --- a/iguana/exchanges/LP_statemachine.c +++ b/iguana/exchanges/LP_statemachine.c @@ -468,6 +468,11 @@ void LP_instantdex_txidadd(bits256 txid) if ( array != 0 ) free_json(array); } +/*if ( 0 && OS_thread_create(malloc(sizeof(pthread_t)),NULL,(void *)LP_privkeysloop,ctx) != 0 ) + { + printf("error launching LP_privkeysloop for ctx.%p\n",ctx); + exit(-1); + }*/ char *issue_LP_getprices(char *destip,uint16_t destport) { diff --git a/iguana/exchanges/LP_transaction.c b/iguana/exchanges/LP_transaction.c index 9a2f8cf4a..2355e04e9 100644 --- a/iguana/exchanges/LP_transaction.c +++ b/iguana/exchanges/LP_transaction.c @@ -1638,25 +1638,55 @@ bits256 _LP_swap_spendtxid(char *symbol,char *destaddr,char *coinaddr,bits256 ut } #endif -bits256 LP_swap_spendtxid(char *symbol,char *destaddr,bits256 utxotxid,int32_t vout) +bits256 LP_swap_spendtxid(char *symbol,char *destaddr,bits256 utxotxid,int32_t utxovout) { - bits256 spendtxid; int32_t spendvin; char coinaddr[64],str[65]; cJSON *retjson; struct iguana_info *coin; + bits256 spendtxid,txid,vintxid; int32_t spendvin,i,m,n; char coinaddr[64]; cJSON *array,*vins,*vin,*txobj; struct iguana_info *coin; // listtransactions or listspents - destaddr[0] = 0; coinaddr[0] = 0; memset(&spendtxid,0,sizeof(spendtxid)); - if ( LP_spendsearch(destaddr,&spendtxid,&spendvin,symbol,utxotxid,vout) > 0 ) + if ( LP_spendsearch(destaddr,&spendtxid,&spendvin,symbol,utxotxid,utxovout) > 0 ) { //printf("spend of %s/v%d detected\n",bits256_str(str,utxotxid),vout); } - else if ( 0 && (coin= LP_coinfind(symbol)) != 0 && coin->electrum == 0 ) + else if ( (coin= LP_coinfind(symbol)) != 0 && coin->electrum == 0 ) { - if ( (retjson= LP_gettxout(symbol,coinaddr,utxotxid,vout)) == 0 ) + if ( (array= LP_listreceivedbyaddress(symbol,destaddr)) != 0 ) { - decode_hex(spendtxid.bytes,32,"deadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeef"); - printf("couldnt find spend of %s/v%d, but no gettxout\n",bits256_str(str,utxotxid),vout); - } else free_json(retjson); + if ( (n= cJSON_GetArraySize(array)) > 0 ) + { + for (i=0; iotherfee.I.locktime - (swap->I.started+1); if ( diff < 0 ) diff = -diff; - if ( diff < 10 ) + if ( diff < LP_AUTOTRADE_TIMEOUT ) printf("dexfee verified\n"); else printf("locktime mismatch in otherfee, reject %u vs %u\n",swap->otherfee.I.locktime,swap->I.started+1); return(0); From eff14be1c148b097984a7d5a6eec0330d5a172c7 Mon Sep 17 00:00:00 2001 From: jl777 Date: Thu, 7 Dec 2017 16:14:30 +0400 Subject: [PATCH 1591/1664] Test --- iguana/exchanges/LP_commands.c | 2 +- iguana/exchanges/LP_include.h | 2 +- iguana/exchanges/LP_prices.c | 13 +++++++++---- iguana/exchanges/LP_rpc.c | 4 +++- 4 files changed, 14 insertions(+), 7 deletions(-) diff --git a/iguana/exchanges/LP_commands.c b/iguana/exchanges/LP_commands.c index 431996de2..dba961871 100644 --- a/iguana/exchanges/LP_commands.c +++ b/iguana/exchanges/LP_commands.c @@ -453,7 +453,7 @@ instantdex_claim()\n\ LP_address(ptr,coinaddr); if ( strcmp(coinaddr,ptr->smartaddr) == 0 && bits256_nonz(G.LP_privkey) != 0 ) { - //LP_listunspent_issue(coin,coinaddr,2); + LP_listunspent_issue(coin,coinaddr,2,zero,zero); //LP_privkey_init(-1,ptr,G.LP_privkey,G.LP_mypub25519); } return(jprint(LP_listunspent(coin,coinaddr,zero,zero),1)); diff --git a/iguana/exchanges/LP_include.h b/iguana/exchanges/LP_include.h index 90e2ecf14..a61d8582a 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 "17667" +#define LP_BUILD_NUMBER "17701" #define LP_BARTERDEX_VERSION 1 #define LP_MAGICBITS 1 diff --git a/iguana/exchanges/LP_prices.c b/iguana/exchanges/LP_prices.c index dfc5848a8..9c8c7f204 100644 --- a/iguana/exchanges/LP_prices.c +++ b/iguana/exchanges/LP_prices.c @@ -41,9 +41,6 @@ struct LP_priceinfo double margins[LP_MAXPRICEINFOS]; double offsets[LP_MAXPRICEINFOS]; double factors[LP_MAXPRICEINFOS]; - //double maxprices[LP_MAXPRICEINFOS]; // autofill of base/rel - //double relvols[LP_MAXPRICEINFOS]; - //FILE *fps[LP_MAXPRICEINFOS]; } LP_priceinfos[LP_MAXPRICEINFOS]; int32_t LP_numpriceinfos; @@ -503,9 +500,17 @@ int32_t LP_mypriceset(int32_t *changedp,char *base,char *rel,double price) if ( base != 0 && rel != 0 && (basepp= LP_priceinfofind(base)) != 0 && (relpp= LP_priceinfofind(rel)) != 0 ) { - if ( fabs(basepp->myprices[relpp->ind] - price)/price > 0.001 ) + if ( price == 0. || fabs(basepp->myprices[relpp->ind] - price)/price > 0.001 ) *changedp = 1; basepp->myprices[relpp->ind] = price; // ask + if ( price == 0. ) + { + relpp->minprices[basepp->ind] = 0.; + relpp->fixedprices[basepp->ind] = 0.; + relpp->margins[basepp->ind] = 0.; + relpp->offsets[basepp->ind] = 0.; + relpp->factors[basepp->ind] = 0.; + } //printf("LP_mypriceset base.%s rel.%s <- price %.8f\n",base,rel,price); //relpp->myprices[basepp->ind] = (1. / price); // bid if ( (pubp= LP_pubkeyadd(G.LP_mypub25519)) != 0 ) diff --git a/iguana/exchanges/LP_rpc.c b/iguana/exchanges/LP_rpc.c index 2c0eab7e2..4a14a5d0a 100644 --- a/iguana/exchanges/LP_rpc.c +++ b/iguana/exchanges/LP_rpc.c @@ -474,7 +474,7 @@ int64_t LP_listunspent_parseitem(struct iguana_info *coin,bits256 *txidp,int32_t int32_t LP_listunspent_issue(char *symbol,char *coinaddr,int32_t fullflag,bits256 reftxid,bits256 reftxid2) { - struct iguana_info *coin; int32_t n = 0; cJSON *retjson=0; char *retstr=0; + struct iguana_info *coin; struct LP_address *ap; int32_t n = 0; cJSON *retjson=0; char *retstr=0; if ( symbol == 0 || symbol[0] == 0 ) return(0); if ( (coin= LP_coinfind(symbol)) != 0 ) @@ -489,6 +489,8 @@ int32_t LP_listunspent_issue(char *symbol,char *coinaddr,int32_t fullflag,bits25 } else { + if ( fullflag == 2 && (ap= LP_addressfind(coin,coinaddr)) != 0 ) + ap->unspenttime = 0; retjson = LP_listunspent(symbol,coinaddr,reftxid,reftxid2); coin->numutxos = cJSON_GetArraySize(retjson); if ( retjson != 0 ) From 895fd428fea9beb82e12ab82632ec19fdc579ebd Mon Sep 17 00:00:00 2001 From: jl777 Date: Thu, 7 Dec 2017 16:25:45 +0400 Subject: [PATCH 1592/1664] Test --- iguana/exchanges/LP_stats.c | 2 +- iguana/exchanges/LP_transaction.c | 3 ++- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/iguana/exchanges/LP_stats.c b/iguana/exchanges/LP_stats.c index cdbf8c936..f8fcc9fec 100644 --- a/iguana/exchanges/LP_stats.c +++ b/iguana/exchanges/LP_stats.c @@ -643,7 +643,7 @@ char *LP_gettradestatus(uint64_t aliceid,uint32_t requestid,uint32_t quoteid) //printf("gettradestatus.(%llu)\n",(long long)aliceid); if ( IAMLP != 0 ) { - if ( (sp= LP_swapstats_find(aliceid)) != 0 ) + if ( (sp= LP_swapstats_find(aliceid)) != 0 && sp->Q.satoshis != 0 && sp->Q.destsatoshis != 0 && bits256_nonz(sp->bobdeposit) != 0 ) { if ( time(NULL) > sp->lasttime+60 ) { diff --git a/iguana/exchanges/LP_transaction.c b/iguana/exchanges/LP_transaction.c index 2355e04e9..6a8117ac7 100644 --- a/iguana/exchanges/LP_transaction.c +++ b/iguana/exchanges/LP_transaction.c @@ -1669,9 +1669,10 @@ bits256 LP_swap_spendtxid(char *symbol,char *destaddr,bits256 utxotxid,int32_t u if ( bits256_cmp(vintxid,utxotxid) == 0 ) { LP_txdestaddr(destaddr,txid,0,txobj); + char str[65],str2[65],str3[65]; printf("LP_swap_spendtxid: in %s/v%d spends %s vs %s found.%d destaddr.(%s)\n",bits256_str(str,txid),utxovout,bits256_str(str2,vintxid),bits256_str(str3,utxotxid),bits256_cmp(vintxid,utxotxid) == 0,destaddr); spendtxid = txid; + break; } - char str[65],str2[65],str3[65]; printf("LP_swap_spendtxid: in %s/v%d spends %s vs %s found.%d destaddr.(%s)\n",bits256_str(str,txid),utxovout,bits256_str(str2,vintxid),bits256_str(str3,utxotxid),bits256_cmp(vintxid,utxotxid) == 0,destaddr); } } free_json(txobj); From 07e3b3e03f698b2c2f49ee02354df2dbc5d08013 Mon Sep 17 00:00:00 2001 From: jl777 Date: Thu, 7 Dec 2017 16:50:33 +0400 Subject: [PATCH 1593/1664] Test --- iguana/exchanges/LP_nativeDEX.c | 7 ++++--- iguana/exchanges/LP_transaction.c | 4 ++-- 2 files changed, 6 insertions(+), 5 deletions(-) diff --git a/iguana/exchanges/LP_nativeDEX.c b/iguana/exchanges/LP_nativeDEX.c index 0f12bd976..4aa1578c8 100644 --- a/iguana/exchanges/LP_nativeDEX.c +++ b/iguana/exchanges/LP_nativeDEX.c @@ -42,6 +42,7 @@ struct LP_millistats char name[64]; } LP_psockloop_stats,LP_reserved_msgs_stats,utxosQ_loop_stats,command_rpcloop_stats,queue_loop_stats,prices_loop_stats,LP_coinsloop_stats,LP_coinsloopBTC_stats,LP_coinsloopKMD_stats,LP_pubkeysloop_stats,LP_swapsloop_stats,LP_gcloop_stats,LP_tradesloop_stats; extern int32_t IAMLP; +char LP_methodstr[64]; void LP_millistats_update(struct LP_millistats *mp) { @@ -78,7 +79,7 @@ void LP_millistats_update(struct LP_millistats *mp) if ( mp->threshold != 0. && elapsed > mp->threshold ) { //if ( IAMLP == 0 ) - printf("%32s elapsed %10.2f millis > threshold %10.2f, ave %10.2f millis, count.%u\n",mp->name,elapsed,mp->threshold,mp->millisum/mp->count,mp->count); + printf("%32s elapsed %10.2f millis > threshold %10.2f, ave %10.2f millis, count.%u %s\n",mp->name,elapsed,mp->threshold,mp->millisum/mp->count,mp->count,LP_methodstr); } mp->lastmilli = millis; } @@ -366,7 +367,7 @@ int32_t LP_sock_check(char *typestr,void *ctx,char *myipaddr,int32_t pubsock,int //ptr = buf; methodstr[0] = 0; //printf("%s.(%s)\n",typestr,(char *)ptr); - if ( 0 ) + if ( 1 ) { cJSON *recvjson; char *mstr;//,*cstr; if ( (recvjson= cJSON_Parse((char *)ptr)) != 0 ) @@ -375,7 +376,7 @@ int32_t LP_sock_check(char *typestr,void *ctx,char *myipaddr,int32_t pubsock,int { //printf("%s RECV.(%s)\n",typestr,(char *)ptr); } - safecopy(methodstr,jstr(recvjson,"method"),sizeof(methodstr)); + safecopy(LP_methodstr,jstr(recvjson,"method"),sizeof(LP_methodstr)); free_json(recvjson); } } diff --git a/iguana/exchanges/LP_transaction.c b/iguana/exchanges/LP_transaction.c index 6a8117ac7..7afefdb9b 100644 --- a/iguana/exchanges/LP_transaction.c +++ b/iguana/exchanges/LP_transaction.c @@ -1659,9 +1659,9 @@ bits256 LP_swap_spendtxid(char *symbol,char *destaddr,bits256 utxotxid,int32_t u txid = jbits256i(array,i); if ( (txobj= LP_gettx(symbol,txid,1)) != 0 ) { - //printf("txobj.(%s)\n",jprint(txobj,0)); if ( (vins= jarray(&m,txobj,"vin")) != 0 ) { + printf("vins.(%s)\n",jprint(vins,0)); if ( utxovout < m ) { vin = jitem(vins,utxovout); @@ -1669,7 +1669,7 @@ bits256 LP_swap_spendtxid(char *symbol,char *destaddr,bits256 utxotxid,int32_t u if ( bits256_cmp(vintxid,utxotxid) == 0 ) { LP_txdestaddr(destaddr,txid,0,txobj); - char str[65],str2[65],str3[65]; printf("LP_swap_spendtxid: in %s/v%d spends %s vs %s found.%d destaddr.(%s)\n",bits256_str(str,txid),utxovout,bits256_str(str2,vintxid),bits256_str(str3,utxotxid),bits256_cmp(vintxid,utxotxid) == 0,destaddr); + char str[65],str2[65],str3[65]; printf("LP_swap_spendtxid: found %s/v%d spends %s vs %s found.%d destaddr.(%s)\n",bits256_str(str,txid),utxovout,bits256_str(str2,vintxid),bits256_str(str3,utxotxid),bits256_cmp(vintxid,utxotxid) == 0,destaddr); spendtxid = txid; break; } From 020bee03a6171dad373090ef860f325cb31e26df Mon Sep 17 00:00:00 2001 From: jl777 Date: Thu, 7 Dec 2017 17:20:43 +0400 Subject: [PATCH 1594/1664] Test --- iguana/exchanges/LP_coins.c | 9 +++++++++ iguana/exchanges/LP_commands.c | 2 +- iguana/exchanges/LP_ordermatch.c | 8 ++++++-- iguana/exchanges/LP_transaction.c | 2 +- 4 files changed, 17 insertions(+), 4 deletions(-) diff --git a/iguana/exchanges/LP_coins.c b/iguana/exchanges/LP_coins.c index 67312eb51..8c7de8da5 100644 --- a/iguana/exchanges/LP_coins.c +++ b/iguana/exchanges/LP_coins.c @@ -498,3 +498,12 @@ struct iguana_info *LP_coincreate(cJSON *item) return(0); } +void LP_otheraddress(char *destcoin,char *otheraddr,char *srccoin,char *coinaddr) +{ + uint8_t addrtype,rmd160[20]; struct iguana_info *src,*dest; + if ( (src= LP_coinfind(srccoin)) != 0 && (dest= LP_coinfind(destcoin)) != 0 ) + { + bitcoin_addr2rmd160(src->taddr,&addrtype,rmd160,coinaddr); + bitcoin_address(otheraddr,dest->taddr,dest->pubtype,rmd160,20); + } else printf("couldnt find %s or %s\n",srccoin,destcoin); +} diff --git a/iguana/exchanges/LP_commands.c b/iguana/exchanges/LP_commands.c index dba961871..ea2d7d00d 100644 --- a/iguana/exchanges/LP_commands.c +++ b/iguana/exchanges/LP_commands.c @@ -350,7 +350,7 @@ instantdex_claim()\n\ return(clonestr("{\"error\":\"couldnt set price\"}")); //else if ( LP_mypriceset(&changed,rel,base,1./price) < 0 ) // return(clonestr("{\"error\":\"couldnt set price\"}")); - else if ( jobj(argjson,"broadcast") == 0 || jint(argjson,"broadcast") != 0 ) + else if ( price == 0. || jobj(argjson,"broadcast") == 0 || jint(argjson,"broadcast") != 0 ) return(LP_pricepings(ctx,myipaddr,LP_mypubsock,base,rel,price * LP_profitratio)); else return(clonestr("{\"result\":\"success\"}")); } diff --git a/iguana/exchanges/LP_ordermatch.c b/iguana/exchanges/LP_ordermatch.c index 3db0881a8..a38fa3a7e 100644 --- a/iguana/exchanges/LP_ordermatch.c +++ b/iguana/exchanges/LP_ordermatch.c @@ -461,7 +461,7 @@ struct LP_utxoinfo *LP_address_myutxopair(struct LP_utxoinfo *butxo,int32_t iamb int32_t LP_connectstartbob(void *ctx,int32_t pubsock,char *base,char *rel,double price,struct LP_quoteinfo *qp) { - char pairstr[512]; cJSON *reqjson; bits256 privkey; int32_t pair=-1,retval = -1,DEXselector = 0; struct basilisk_swap *swap; struct iguana_info *coin; + char pairstr[512],otheraddr[64]; cJSON *reqjson; bits256 privkey; int32_t pair=-1,retval = -1,DEXselector = 0; struct basilisk_swap *swap; struct iguana_info *coin; qp->quotetime = (uint32_t)time(NULL); if ( (coin= LP_coinfind(qp->srccoin)) == 0 ) { @@ -505,6 +505,8 @@ int32_t LP_connectstartbob(void *ctx,int32_t pubsock,char *base,char *rel,double LP_reserved_msg(0,base,rel,zero,jprint(reqjson,0)); free_json(reqjson); LP_importaddress(qp->destcoin,qp->destaddr); + LP_otheraddress(qp->srccoin,otheraddr,qp->destcoin,qp->destaddr); + LP_importaddress(qp->srccoin,otheraddr); retval = 0; } else printf("error launching swaploop\n"); } else printf("couldnt bind to any port %s\n",pairstr); @@ -573,7 +575,7 @@ int32_t LP_alice_eligible(uint32_t quotetime) char *LP_connectedalice(struct LP_quoteinfo *qp,char *pairstr) // alice { - cJSON *retjson; double bid,ask,price,qprice; int32_t pairsock = -1; int32_t DEXselector = 0; struct LP_utxoinfo *autxo,A,B,*butxo; struct basilisk_swap *swap; struct iguana_info *coin; + cJSON *retjson; char otheraddr[64]; double bid,ask,price,qprice; int32_t pairsock = -1; int32_t DEXselector = 0; struct LP_utxoinfo *autxo,A,B,*butxo; struct basilisk_swap *swap; struct iguana_info *coin; /*if ( LP_quoteparse(&Q,argjson) < 0 ) { LP_aliceid(Q.tradeid,Q.aliceid,"error0",0,0); @@ -656,6 +658,8 @@ char *LP_connectedalice(struct LP_quoteinfo *qp,char *pairstr) // alice //autxo->S.swap = swap; //swap->utxo = autxo; LP_importaddress(qp->srccoin,qp->coinaddr); + LP_otheraddress(qp->destcoin,otheraddr,qp->srccoin,qp->coinaddr); + LP_importaddress(qp->srccoin,otheraddr); LP_aliceid(qp->tradeid,qp->aliceid,"started",qp->R.requestid,qp->R.quoteid); printf("alice pairstr.(%s) pairsock.%d pthread_t %ld\n",pairstr,pairsock,sizeof(pthread_t)); if ( OS_thread_create(malloc(sizeof(pthread_t)),NULL,(void *)LP_aliceloop,(void *)swap) == 0 ) diff --git a/iguana/exchanges/LP_transaction.c b/iguana/exchanges/LP_transaction.c index 7afefdb9b..a00fe0319 100644 --- a/iguana/exchanges/LP_transaction.c +++ b/iguana/exchanges/LP_transaction.c @@ -1661,7 +1661,7 @@ bits256 LP_swap_spendtxid(char *symbol,char *destaddr,bits256 utxotxid,int32_t u { if ( (vins= jarray(&m,txobj,"vin")) != 0 ) { - printf("vins.(%s)\n",jprint(vins,0)); + //printf("vins.(%s)\n",jprint(vins,0)); if ( utxovout < m ) { vin = jitem(vins,utxovout); From 4acea05dc1f4890bdbe5fc62805100c8f798919b Mon Sep 17 00:00:00 2001 From: jl777 Date: Thu, 7 Dec 2017 17:56:17 +0400 Subject: [PATCH 1595/1664] Test --- iguana/exchanges/LP_nativeDEX.c | 2 -- iguana/exchanges/LP_transaction.c | 2 +- 2 files changed, 1 insertion(+), 3 deletions(-) diff --git a/iguana/exchanges/LP_nativeDEX.c b/iguana/exchanges/LP_nativeDEX.c index 4aa1578c8..823761928 100644 --- a/iguana/exchanges/LP_nativeDEX.c +++ b/iguana/exchanges/LP_nativeDEX.c @@ -18,10 +18,8 @@ // marketmaker // // 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? // diff --git a/iguana/exchanges/LP_transaction.c b/iguana/exchanges/LP_transaction.c index a00fe0319..06fe3a5ca 100644 --- a/iguana/exchanges/LP_transaction.c +++ b/iguana/exchanges/LP_transaction.c @@ -1166,7 +1166,7 @@ int32_t LP_vins_select(void *ctx,struct iguana_info *coin,int64_t *totalp,int64_ 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,bits256 utxotxid,int32_t utxovout,uint32_t locktime) { static void *ctx; - cJSON *txobj,*item; uint8_t addrtype,rmd160[20],script[64],spendscript[256]; char *coinaddr,*rawtxbytes; bits256 txid; uint32_t timestamp; int64_t change=0,adjust=0,total,value,amount = 0; int32_t i,dustcombine,scriptlen,spendlen,suppress_pubkeys,ignore_cltverr,numvouts=0,numvins=0,numutxos=0; struct LP_address_utxo *utxos[LP_MAXVINS*16]; struct LP_address *ap; + cJSON *txobj,*item; uint8_t addrtype,rmd160[20],script[64],spendscript[256]; char *coinaddr,*rawtxbytes; bits256 txid; uint32_t timestamp; int64_t change=0,adjust=0,total,value,amount = 0; int32_t i,dustcombine,scriptlen,spendlen,suppress_pubkeys,ignore_cltverr,numvouts=0,numvins=0,numutxos=0; struct LP_address_utxo *utxos[LP_MAXVINS*256]; struct LP_address *ap; if ( ctx == 0 ) ctx = bitcoin_ctx(); *numvinsp = 0; From 04f751a3b3b6e23a2a6be7b8b88f00dfc7345b22 Mon Sep 17 00:00:00 2001 From: jl777 Date: Thu, 7 Dec 2017 18:08:30 +0400 Subject: [PATCH 1596/1664] Test --- iguana/exchanges/LP_coins.c | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/iguana/exchanges/LP_coins.c b/iguana/exchanges/LP_coins.c index 8c7de8da5..211852c11 100644 --- a/iguana/exchanges/LP_coins.c +++ b/iguana/exchanges/LP_coins.c @@ -259,6 +259,11 @@ cJSON *LP_coinjson(struct iguana_info *coin,int32_t showwif) jaddnum(item,"p2shtype",coin->p2shtype); jaddnum(item,"wiftype",coin->wiftype); jaddnum(item,"txfee",strcmp(coin->symbol,"BTC") != 0 ? coin->txfee : LP_txfeecalc(coin,0,0)); + if ( strcmp(coin->symbol,"KMD") == 0 ) + { + jaddnum(item,"zcredits",dstr(LP_myzcredits())); + jadd(item,"zdebits",LP_myzdebits()); + } return(item); } From bd151d18b2996d578c345b863c8a4cc9429b55b9 Mon Sep 17 00:00:00 2001 From: jl777 Date: Thu, 7 Dec 2017 18:16:12 +0400 Subject: [PATCH 1597/1664] Test --- iguana/exchanges/LP_nativeDEX.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/iguana/exchanges/LP_nativeDEX.c b/iguana/exchanges/LP_nativeDEX.c index 823761928..92248bbd4 100644 --- a/iguana/exchanges/LP_nativeDEX.c +++ b/iguana/exchanges/LP_nativeDEX.c @@ -711,7 +711,10 @@ void LP_initcoins(void *ctx,int32_t pubsock,cJSON *coins) { LP_unspents_load(coin->symbol,coin->smartaddr); if ( strcmp(coin->symbol,"KMD") == 0 ) + { LP_importaddress("KMD",BOTS_BONDADDRESS); + LP_dPoW_request(coin); + } } if ( coin->txfee == 0 && strcmp(coin->symbol,"BTC") != 0 ) coin->txfee = LP_MIN_TXFEE; From 2bb060511b4907e1ac6684b9b78da53f58608a1c Mon Sep 17 00:00:00 2001 From: jl777 Date: Thu, 7 Dec 2017 18:21:55 +0400 Subject: [PATCH 1598/1664] Test --- iguana/exchanges/LP_stats.c | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/iguana/exchanges/LP_stats.c b/iguana/exchanges/LP_stats.c index f8fcc9fec..a206905d5 100644 --- a/iguana/exchanges/LP_stats.c +++ b/iguana/exchanges/LP_stats.c @@ -297,6 +297,10 @@ 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 ( strcmp(bob->symbol,"BTC") == 0 ) + sp->bobneeds_dPoW = 0; + if ( strcmp(alice->symbol,"BTC") == 0 ) + sp->aliceneeds_dPoW = 0; if ( sp->bobneeds_dPoW != 0 ) { if ( bits256_nonz(sp->bobdeposit) != 0 && sp->bobdeposit_ht == 0 ) From 08b429e6ee501c036616312fb0318ab3f9a135a5 Mon Sep 17 00:00:00 2001 From: jl777 Date: Thu, 7 Dec 2017 18:27:54 +0400 Subject: [PATCH 1599/1664] test --- iguana/exchanges/LP_transaction.c | 1 + 1 file changed, 1 insertion(+) diff --git a/iguana/exchanges/LP_transaction.c b/iguana/exchanges/LP_transaction.c index 06fe3a5ca..ef3a1d89f 100644 --- a/iguana/exchanges/LP_transaction.c +++ b/iguana/exchanges/LP_transaction.c @@ -957,6 +957,7 @@ int32_t LP_vin_select(int32_t *aboveip,int64_t *abovep,int32_t *belowip,int64_t below = gap; belowi = i; } + printf("value %.8f gap %.8f abovei.%d %.8f belowi.%d %.8f\n",dstr(value),dstr(gap),abovei,dstr(above),belowi,dstr(below)); } *aboveip = abovei; *abovep = above; From 710e91190d7213050215370df59672662b46ccc9 Mon Sep 17 00:00:00 2001 From: jl777 Date: Thu, 7 Dec 2017 18:28:29 +0400 Subject: [PATCH 1600/1664] Test --- iguana/exchanges/LP_transaction.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/iguana/exchanges/LP_transaction.c b/iguana/exchanges/LP_transaction.c index ef3a1d89f..1882bc75b 100644 --- a/iguana/exchanges/LP_transaction.c +++ b/iguana/exchanges/LP_transaction.c @@ -957,7 +957,7 @@ int32_t LP_vin_select(int32_t *aboveip,int64_t *abovep,int32_t *belowip,int64_t below = gap; belowi = i; } - printf("value %.8f gap %.8f abovei.%d %.8f belowi.%d %.8f\n",dstr(value),dstr(gap),abovei,dstr(above),belowi,dstr(below)); + //printf("value %.8f gap %.8f abovei.%d %.8f belowi.%d %.8f\n",dstr(value),dstr(gap),abovei,dstr(above),belowi,dstr(below)); } *aboveip = abovei; *abovep = above; From eea27ae4e5734ae9d541181a0d8cf387af38e53c Mon Sep 17 00:00:00 2001 From: jl777 Date: Thu, 7 Dec 2017 18:29:28 +0400 Subject: [PATCH 1601/1664] Test --- iguana/exchanges/LP_transaction.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/iguana/exchanges/LP_transaction.c b/iguana/exchanges/LP_transaction.c index 1882bc75b..ef3a1d89f 100644 --- a/iguana/exchanges/LP_transaction.c +++ b/iguana/exchanges/LP_transaction.c @@ -957,7 +957,7 @@ int32_t LP_vin_select(int32_t *aboveip,int64_t *abovep,int32_t *belowip,int64_t below = gap; belowi = i; } - //printf("value %.8f gap %.8f abovei.%d %.8f belowi.%d %.8f\n",dstr(value),dstr(gap),abovei,dstr(above),belowi,dstr(below)); + printf("value %.8f gap %.8f abovei.%d %.8f belowi.%d %.8f\n",dstr(value),dstr(gap),abovei,dstr(above),belowi,dstr(below)); } *aboveip = abovei; *abovep = above; From 1367f238fa4ebe05e69dc92187525001d084ec13 Mon Sep 17 00:00:00 2001 From: jl777 Date: Thu, 7 Dec 2017 18:40:21 +0400 Subject: [PATCH 1602/1664] Test --- iguana/exchanges/LP_transaction.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/iguana/exchanges/LP_transaction.c b/iguana/exchanges/LP_transaction.c index ef3a1d89f..a4d4e1aef 100644 --- a/iguana/exchanges/LP_transaction.c +++ b/iguana/exchanges/LP_transaction.c @@ -1218,7 +1218,7 @@ char *LP_createrawtransaction(cJSON **txobjp,int32_t *numvinsp,struct iguana_inf return(0); } memset(utxos,0,sizeof(utxos)); - if ( (numutxos= LP_address_utxo_ptrs(coin,0,utxos,max,ap,coin->smartaddr)) <= 0 ) + if ( (numutxos= LP_address_utxo_ptrs(coin,0,utxos,(int32_t)(sizeof(utxos)/sizeof(*utxos)),ap,coin->smartaddr)) <= 0 ) { if ( bits256_nonz(utxotxid) == 0 ) { From a17543acecbba1ea60887369fd9850c5a7b0f4cb Mon Sep 17 00:00:00 2001 From: jl777 Date: Thu, 7 Dec 2017 18:48:14 +0400 Subject: [PATCH 1603/1664] Test --- iguana/exchanges/LP_transaction.c | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) diff --git a/iguana/exchanges/LP_transaction.c b/iguana/exchanges/LP_transaction.c index a4d4e1aef..1cd815ad7 100644 --- a/iguana/exchanges/LP_transaction.c +++ b/iguana/exchanges/LP_transaction.c @@ -951,11 +951,15 @@ int32_t LP_vin_select(int32_t *aboveip,int64_t *abovep,int32_t *belowip,int64_t above = gap; abovei = i; } - } else gap = (value - atx_value); - if ( below == 0 || gap < below ) + } + else { - below = gap; - belowi = i; + gap = (value - atx_value); + if ( below == 0 || gap < below ) + { + below = gap; + belowi = i; + } } printf("value %.8f gap %.8f abovei.%d %.8f belowi.%d %.8f\n",dstr(value),dstr(gap),abovei,dstr(above),belowi,dstr(below)); } From d6b2002ccd2ed217123e92824ac208550601b89f Mon Sep 17 00:00:00 2001 From: jl777 Date: Thu, 7 Dec 2017 18:53:16 +0400 Subject: [PATCH 1604/1664] Test --- iguana/exchanges/LP_transaction.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/iguana/exchanges/LP_transaction.c b/iguana/exchanges/LP_transaction.c index 1cd815ad7..93c8504cc 100644 --- a/iguana/exchanges/LP_transaction.c +++ b/iguana/exchanges/LP_transaction.c @@ -961,7 +961,7 @@ int32_t LP_vin_select(int32_t *aboveip,int64_t *abovep,int32_t *belowip,int64_t belowi = i; } } - printf("value %.8f gap %.8f abovei.%d %.8f belowi.%d %.8f\n",dstr(value),dstr(gap),abovei,dstr(above),belowi,dstr(below)); + //printf("value %.8f gap %.8f abovei.%d %.8f belowi.%d %.8f\n",dstr(value),dstr(gap),abovei,dstr(above),belowi,dstr(below)); } *aboveip = abovei; *abovep = above; From 9462e8335ce6ab4704e7c41a4feede413e9f1a4a Mon Sep 17 00:00:00 2001 From: jl777 Date: Thu, 7 Dec 2017 18:54:35 +0400 Subject: [PATCH 1605/1664] Test --- iguana/exchanges/LP_ordermatch.c | 1 + 1 file changed, 1 insertion(+) diff --git a/iguana/exchanges/LP_ordermatch.c b/iguana/exchanges/LP_ordermatch.c index a38fa3a7e..82822363f 100644 --- a/iguana/exchanges/LP_ordermatch.c +++ b/iguana/exchanges/LP_ordermatch.c @@ -1347,6 +1347,7 @@ char *LP_autobuy(void *ctx,char *myipaddr,int32_t mypubsock,char *base,char *rel return(clonestr("{\"error\":\"cant set ordermatch quote info\"}")); int32_t changed; LP_mypriceset(&changed,autxo->coin,base,1. / maxprice); + LP_mypriceset(&changed,base,autxo->coin,0.); return(LP_trade(ctx,myipaddr,mypubsock,&Q,maxprice,timeout,duration,tradeid,destpubkey)); } From b979e317ee576c0dcfb9d8704ff89d6af98b554c Mon Sep 17 00:00:00 2001 From: jl777 Date: Thu, 7 Dec 2017 19:05:55 +0400 Subject: [PATCH 1606/1664] Test --- iguana/exchanges/LP_instantdex.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/iguana/exchanges/LP_instantdex.c b/iguana/exchanges/LP_instantdex.c index 6644188c7..6dd6d28e1 100644 --- a/iguana/exchanges/LP_instantdex.c +++ b/iguana/exchanges/LP_instantdex.c @@ -473,7 +473,7 @@ int64_t LP_dynamictrust(bits256 pubkey,int64_t kmdvalue) swaps_kmdvalue += LP_kmdvalue(sp->Q.destcoin,sp->Q.destsatoshis); } 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)); + 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)); } From 21d9f75d7eba5be27286a1c0c56d62e05ed35fac Mon Sep 17 00:00:00 2001 From: jl777 Date: Thu, 7 Dec 2017 19:22:27 +0400 Subject: [PATCH 1607/1664] Test --- iguana/exchanges/LP_transaction.c | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) diff --git a/iguana/exchanges/LP_transaction.c b/iguana/exchanges/LP_transaction.c index 93c8504cc..5f4f107da 100644 --- a/iguana/exchanges/LP_transaction.c +++ b/iguana/exchanges/LP_transaction.c @@ -968,7 +968,16 @@ int32_t LP_vin_select(int32_t *aboveip,int64_t *abovep,int32_t *belowip,int64_t *belowip = belowi; *belowp = below; //printf("above.%d below.%d\n",abovei,belowi); - return(abovei >= 0 && above < (below>>1) ? abovei : belowi); + if ( abovei >= 0 && belowi >= 0 ) + { + if ( above < (below >> 1) ) + return(abovei); + else return(belowi); + } + else if ( abovei >= 0 ) + return(abovei); + else return(belowi); + //return(abovei >= 0 && above < (below>>1) ? abovei : belowi); } cJSON *LP_inputjson(bits256 txid,int32_t vout,char *spendscriptstr) From ec37dadb3ade6ccd29b5ee2aa2603a164769125e Mon Sep 17 00:00:00 2001 From: jl777 Date: Thu, 7 Dec 2017 19:53:52 +0400 Subject: [PATCH 1608/1664] Test --- iguana/exchanges/LP_include.h | 3 ++- iguana/exchanges/LP_instantdex.c | 39 +++++++++++++++--------------- iguana/exchanges/LP_ordermatch.c | 27 ++++----------------- iguana/exchanges/LP_statemachine.c | 16 ++++++++++++ iguana/exchanges/LP_stats.c | 2 +- 5 files changed, 44 insertions(+), 43 deletions(-) diff --git a/iguana/exchanges/LP_include.h b/iguana/exchanges/LP_include.h index a61d8582a..82b3a29ce 100644 --- a/iguana/exchanges/LP_include.h +++ b/iguana/exchanges/LP_include.h @@ -363,6 +363,7 @@ struct LP_quoteinfo { struct basilisk_request R; bits256 srchash,desthash,txid,txid2,desttxid,feetxid,privkey; + int64_t othercredits; uint64_t satoshis,txfee,destsatoshis,desttxfee,aliceid; uint32_t timestamp,quotetime,tradeid; int32_t vout,vout2,destvout,feevout,pair; @@ -537,7 +538,7 @@ int32_t LP_gettx_presence(char *symbol,bits256 expectedtxid); double LP_getestimatedrate(struct iguana_info *coin); 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); -int64_t LP_dynamictrust(bits256 pubkey,int64_t kmdvalue); +int64_t LP_dynamictrust(int64_t credits,bits256 pubkey,int64_t kmdvalue); struct LP_address *LP_addressfind(struct iguana_info *coin,char *coinaddr); int64_t LP_outpoint_amount(char *symbol,bits256 txid,int32_t vout); diff --git a/iguana/exchanges/LP_instantdex.c b/iguana/exchanges/LP_instantdex.c index 6dd6d28e1..7bf63c264 100644 --- a/iguana/exchanges/LP_instantdex.c +++ b/iguana/exchanges/LP_instantdex.c @@ -454,41 +454,41 @@ void LP_instantdex_deposits(struct iguana_info *coin) } #endif -int64_t LP_dynamictrust(bits256 pubkey,int64_t kmdvalue) +int64_t LP_dynamictrust(int64_t credits,bits256 pubkey,int64_t kmdvalue) { struct LP_pubswap *ptr,*tmp; struct LP_swapstats *sp; struct LP_pubkey_info *pubp; struct LP_address *ap; char coinaddr[64]; struct iguana_info *coin; int64_t swaps_kmdvalue = 0; if ( (coin= LP_coinfind("KMD")) != 0 && (pubp= LP_pubkeyfind(pubkey)) != 0 ) { bitcoin_address(coinaddr,coin->taddr,coin->pubtype,pubp->pubsecp,33); - if ((ap= LP_address(coin,coinaddr)) != 0 )//&& ap->instantdex_credits >= kmdvalue ) + if ( credits != 0 ) + printf("%s %s othercredits %.8f\n",coin->symbol,coinaddr,dstr(credits)); + DL_FOREACH_SAFE(pubp->bobswaps,ptr,tmp) { - DL_FOREACH_SAFE(pubp->bobswaps,ptr,tmp) - { - 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 && LP_swap_finished(sp,1) == 0 ) - swaps_kmdvalue += LP_kmdvalue(sp->Q.destcoin,sp->Q.destsatoshis); - } - 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)); + 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 && LP_swap_finished(sp,1) == 0 ) + swaps_kmdvalue += LP_kmdvalue(sp->Q.destcoin,sp->Q.destsatoshis); } + if ( credits == 0 && (ap= LP_address(coin,coinaddr)) != 0 ) + credits = ap->instantdex_credits; + if ( credits != 0 && (swaps_kmdvalue+kmdvalue) > credits ) + printf("REJECT: %s instantdex_credits %.8f vs (%.8f + current %.8f)\n",coinaddr,dstr(credits),dstr(swaps_kmdvalue),dstr(kmdvalue)); + return(credits - (swaps_kmdvalue+kmdvalue)); } return(0); } int64_t LP_instantdex_proofcheck(char *coinaddr,cJSON *proof,int32_t num) { - uint8_t rmd160[20],addrtype; int32_t i,j; bits256 prevtxid,txid; char othersmartaddr[64]; struct iguana_info *coin; struct LP_address *ap = 0; + uint8_t rmd160[20],addrtype; int64_t credits=0; int32_t i,j; bits256 prevtxid,txid; char othersmartaddr[64]; struct iguana_info *coin; struct LP_address *ap = 0; if ( (coin= LP_coinfind("KMD")) != 0 ) { 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 ) { ap->instantdex_credits = 0; for (i=0; iinstantdex_credits; ap->didinstantdex = 1; if ( ap->instantdex_credits > 0 ) printf("validated instantdex %s.[%d] proof.(%s) credits %.8f\n",othersmartaddr,num,jprint(proof,0),dstr(ap->instantdex_credits)); } //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); + return(credits); } int64_t LP_myzcredits() diff --git a/iguana/exchanges/LP_ordermatch.c b/iguana/exchanges/LP_ordermatch.c index 82822363f..5acc571a5 100644 --- a/iguana/exchanges/LP_ordermatch.c +++ b/iguana/exchanges/LP_ordermatch.c @@ -85,23 +85,6 @@ 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) -{ - uint64_t destsatoshis,satoshis; - a_value -= (desttxfee + 1); - destsatoshis = ((b_satoshis - txfee) * price); - if ( destsatoshis > a_value ) - destsatoshis = a_value; - if ( maxdestsatoshis != 0 && destsatoshis > maxdestsatoshis-desttxfee-1 ) - destsatoshis = maxdestsatoshis-desttxfee-1; - satoshis = (destsatoshis / price + 0.49) - txfee; - *destsatoshisp = destsatoshis; - *satoshisp = satoshis; - 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) { int32_t selector,spendvini; bits256 spendtxid; @@ -477,7 +460,7 @@ int32_t LP_connectstartbob(void *ctx,int32_t pubsock,char *base,char *rel,double printf("requestid.%u quoteid.%u is already in progres\n",qp->R.requestid,qp->R.quoteid); return(-1); } - if ( (swap= LP_swapinit(1,0,privkey,&qp->R,qp,LP_dynamictrust(qp->desthash,LP_kmdvalue(qp->destcoin,qp->destsatoshis)) > 0)) == 0 ) + if ( (swap= LP_swapinit(1,0,privkey,&qp->R,qp,LP_dynamictrust(qp->othercredits,qp->desthash,LP_kmdvalue(qp->destcoin,qp->destsatoshis)) > 0)) == 0 ) { printf("cant initialize swap\n"); return(-1); @@ -635,7 +618,7 @@ char *LP_connectedalice(struct LP_quoteinfo *qp,char *pairstr) // alice if ( bits256_nonz(qp->privkey) != 0 )//&& qp->quotetime >= qp->timestamp-3 ) { retjson = cJSON_CreateObject(); - if ( (swap= LP_swapinit(0,0,qp->privkey,&qp->R,qp,LP_dynamictrust(qp->srchash,LP_kmdvalue(qp->srccoin,qp->satoshis)) > 0)) == 0 ) + if ( (swap= LP_swapinit(0,0,qp->privkey,&qp->R,qp,LP_dynamictrust(qp->othercredits,qp->srchash,LP_kmdvalue(qp->srccoin,qp->satoshis)) > 0)) == 0 ) { jaddstr(retjson,"error","couldnt swapinit"); LP_availableset(qp->desttxid,qp->vout); @@ -999,7 +982,7 @@ int32_t LP_trades_bestpricecheck(void *ctx,struct LP_trade *tp) if ( (retstr= LP_quotereceived(&Q)) != 0 ) free(retstr); //LP_trades_gotreserved(ctx,&Q,&tp->Qs[LP_RESERVED]); - dynamictrust = LP_dynamictrust(Q.srchash,LP_kmdvalue(Q.srccoin,Q.satoshis)); + dynamictrust = LP_dynamictrust(Q.othercredits,Q.srchash,LP_kmdvalue(Q.srccoin,Q.satoshis)); if ( tp->bestprice == 0. ) flag = 1; else if ( qprice < tp->bestprice && pubp->slowresponse <= tp->bestresponse*1.05 ) @@ -1222,7 +1205,7 @@ int32_t LP_tradecommand(void *ctx,char *myipaddr,int32_t pubsock,cJSON *argjson, { //printf("CONNECTED.(%s)\n",jprint(argjson,0)); if ( (proof= jarray(&num,argjson,"proof")) != 0 && num > 0 ) - LP_instantdex_proofcheck(Q.coinaddr,proof,num); + Q.othercredits = LP_instantdex_proofcheck(Q.coinaddr,proof,num); if ( Qtrades == 0 ) LP_trades_gotconnected(ctx,&Q,&Q2,jstr(argjson,"pair")); else LP_tradecommandQ(&Q,jstr(argjson,"pair"),LP_CONNECTED); @@ -1258,7 +1241,7 @@ int32_t LP_tradecommand(void *ctx,char *myipaddr,int32_t pubsock,cJSON *argjson, { printf("CONNECT.(%s)\n",jprint(argjson,0)); if ( (proof= jarray(&num,argjson,"proof")) != 0 && num > 0 ) - LP_instantdex_proofcheck(Q.destaddr,proof,num); + Q.othercredits = LP_instantdex_proofcheck(Q.destaddr,proof,num); if ( Qtrades == 0 ) LP_trades_gotconnect(ctx,&Q,&Q2,jstr(argjson,"pair")); else LP_tradecommandQ(&Q,jstr(argjson,"pair"),LP_CONNECT); diff --git a/iguana/exchanges/LP_statemachine.c b/iguana/exchanges/LP_statemachine.c index 3855c789f..d467958ec 100644 --- a/iguana/exchanges/LP_statemachine.c +++ b/iguana/exchanges/LP_statemachine.c @@ -474,6 +474,22 @@ void LP_instantdex_txidadd(bits256 txid) exit(-1); }*/ +/*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); + destsatoshis = ((b_satoshis - txfee) * price); + if ( destsatoshis > a_value ) + destsatoshis = a_value; + if ( maxdestsatoshis != 0 && destsatoshis > maxdestsatoshis-desttxfee-1 ) + destsatoshis = maxdestsatoshis-desttxfee-1; + satoshis = (destsatoshis / price + 0.49) - txfee; + *destsatoshisp = destsatoshis; + *satoshisp = satoshis; + if ( satoshis > 0 ) + return((double)destsatoshis / satoshis); + else return(0.); + }*/ char *issue_LP_getprices(char *destip,uint16_t destport) { char url[512]; diff --git a/iguana/exchanges/LP_stats.c b/iguana/exchanges/LP_stats.c index a206905d5..a434cf936 100644 --- a/iguana/exchanges/LP_stats.c +++ b/iguana/exchanges/LP_stats.c @@ -760,7 +760,7 @@ cJSON *LP_statslog_disp(uint32_t starttime,uint32_t endtime,char *refgui,bits256 } HASH_ITER(hh,LP_pubkeyinfos,pubp,ptmp) { - pubp->dynamictrust = LP_dynamictrust(pubp->pubkey,0); + pubp->dynamictrust = LP_dynamictrust(0,pubp->pubkey,0); } //printf("RT.%d completed.%d\n",LP_RTcount,LP_swapscount); jadd(retjson,"swaps",array); From adde14a2b99502fde08192855aeb4264736ea49f Mon Sep 17 00:00:00 2001 From: jl777 Date: Thu, 7 Dec 2017 19:59:19 +0400 Subject: [PATCH 1609/1664] Test --- iguana/exchanges/LP_instantdex.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/iguana/exchanges/LP_instantdex.c b/iguana/exchanges/LP_instantdex.c index 7bf63c264..9de76cb8e 100644 --- a/iguana/exchanges/LP_instantdex.c +++ b/iguana/exchanges/LP_instantdex.c @@ -460,8 +460,6 @@ int64_t LP_dynamictrust(int64_t credits,bits256 pubkey,int64_t kmdvalue) if ( (coin= LP_coinfind("KMD")) != 0 && (pubp= LP_pubkeyfind(pubkey)) != 0 ) { bitcoin_address(coinaddr,coin->taddr,coin->pubtype,pubp->pubsecp,33); - if ( credits != 0 ) - printf("%s %s othercredits %.8f\n",coin->symbol,coinaddr,dstr(credits)); DL_FOREACH_SAFE(pubp->bobswaps,ptr,tmp) { if ( (sp= ptr->swap) != 0 && LP_swap_finished(sp,1) == 0 ) @@ -476,6 +474,8 @@ int64_t LP_dynamictrust(int64_t credits,bits256 pubkey,int64_t kmdvalue) credits = ap->instantdex_credits; if ( credits != 0 && (swaps_kmdvalue+kmdvalue) > credits ) printf("REJECT: %s instantdex_credits %.8f vs (%.8f + current %.8f)\n",coinaddr,dstr(credits),dstr(swaps_kmdvalue),dstr(kmdvalue)); + if ( credits != 0 ) + printf("%s %s othercredits %.8f debits %.8f + %.8f -> %.8f\n",coin->symbol,coinaddr,dstr(credits),dstr(swaps_kmdvalue),dstr(kmdvalue),dstr(credits - (swaps_kmdvalue+kmdvalue))); return(credits - (swaps_kmdvalue+kmdvalue)); } return(0); From d22d8e433938974a661864305b7db28077464dfc Mon Sep 17 00:00:00 2001 From: jl777 Date: Thu, 7 Dec 2017 20:17:30 +0400 Subject: [PATCH 1610/1664] Test --- iguana/exchanges/LP_instantdex.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/iguana/exchanges/LP_instantdex.c b/iguana/exchanges/LP_instantdex.c index 9de76cb8e..eb38c2f45 100644 --- a/iguana/exchanges/LP_instantdex.c +++ b/iguana/exchanges/LP_instantdex.c @@ -474,7 +474,7 @@ int64_t LP_dynamictrust(int64_t credits,bits256 pubkey,int64_t kmdvalue) credits = ap->instantdex_credits; if ( credits != 0 && (swaps_kmdvalue+kmdvalue) > credits ) printf("REJECT: %s instantdex_credits %.8f vs (%.8f + current %.8f)\n",coinaddr,dstr(credits),dstr(swaps_kmdvalue),dstr(kmdvalue)); - if ( credits != 0 ) + if ( 0 && credits != 0 ) printf("%s %s othercredits %.8f debits %.8f + %.8f -> %.8f\n",coin->symbol,coinaddr,dstr(credits),dstr(swaps_kmdvalue),dstr(kmdvalue),dstr(credits - (swaps_kmdvalue+kmdvalue))); return(credits - (swaps_kmdvalue+kmdvalue)); } From 716248d1144bae43b625cbae961da2fec7d831a1 Mon Sep 17 00:00:00 2001 From: jl777 Date: Thu, 7 Dec 2017 20:38:35 +0400 Subject: [PATCH 1611/1664] Test --- iguana/exchanges/LP_instantdex.c | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-) diff --git a/iguana/exchanges/LP_instantdex.c b/iguana/exchanges/LP_instantdex.c index eb38c2f45..dcb4fb3f3 100644 --- a/iguana/exchanges/LP_instantdex.c +++ b/iguana/exchanges/LP_instantdex.c @@ -88,7 +88,11 @@ void LP_instantdex_filescreate(char *coinaddr) jaddibits256(array,txid); if ( (txobj= LP_gettxout("KMD",coinaddr,txid,0)) != 0 ) free_json(txobj); - else continue; + else + { + char str[65]; printf("%s/v%d is already spent\n",bits256_str(str,txid),0); + continue; + } jaddibits256(newarray,txid); } fclose(fp); @@ -102,7 +106,7 @@ void LP_instantdex_filescreate(char *coinaddr) void LP_instantdex_depositadd(char *coinaddr,bits256 txid) { static FILE *depositsfp; - char fname[512]; bits256 prevtxid; cJSON *array,*txobj; int32_t i,n,iter; + char fname[512],str[65]; bits256 prevtxid; cJSON *array,*txobj; int32_t i,n,iter; if ( depositsfp == 0 ) { sprintf(fname,"%s/deposits.%s",GLOBAL_DBDIR,coinaddr), OS_compatible_path(fname); @@ -118,11 +122,12 @@ void LP_instantdex_depositadd(char *coinaddr,bits256 txid) for (i=0; i Date: Thu, 7 Dec 2017 20:39:25 +0400 Subject: [PATCH 1612/1664] Test --- iguana/exchanges/LP_instantdex.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/iguana/exchanges/LP_instantdex.c b/iguana/exchanges/LP_instantdex.c index dcb4fb3f3..cb5289aee 100644 --- a/iguana/exchanges/LP_instantdex.c +++ b/iguana/exchanges/LP_instantdex.c @@ -122,7 +122,7 @@ void LP_instantdex_depositadd(char *coinaddr,bits256 txid) for (i=0; i Date: Thu, 7 Dec 2017 20:46:27 +0400 Subject: [PATCH 1613/1664] Test --- iguana/exchanges/LP_instantdex.c | 1 + 1 file changed, 1 insertion(+) diff --git a/iguana/exchanges/LP_instantdex.c b/iguana/exchanges/LP_instantdex.c index cb5289aee..891304f29 100644 --- a/iguana/exchanges/LP_instantdex.c +++ b/iguana/exchanges/LP_instantdex.c @@ -131,6 +131,7 @@ void LP_instantdex_depositadd(char *coinaddr,bits256 txid) continue; } LP_instantdex_deposituniq(depositsfp,prevtxid); + fflush(depositsfp); } } free_json(array); From eff76371be0a81ad1862332bee7b93e1ef4f5a0d Mon Sep 17 00:00:00 2001 From: jl777 Date: Thu, 7 Dec 2017 21:08:22 +0400 Subject: [PATCH 1614/1664] Test --- iguana/exchanges/LP_instantdex.c | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/iguana/exchanges/LP_instantdex.c b/iguana/exchanges/LP_instantdex.c index 891304f29..e59153b6f 100644 --- a/iguana/exchanges/LP_instantdex.c +++ b/iguana/exchanges/LP_instantdex.c @@ -479,7 +479,14 @@ int64_t LP_dynamictrust(int64_t credits,bits256 pubkey,int64_t kmdvalue) if ( credits == 0 && (ap= LP_address(coin,coinaddr)) != 0 ) credits = ap->instantdex_credits; if ( credits != 0 && (swaps_kmdvalue+kmdvalue) > credits ) + { + DL_FOREACH_SAFE(pubp->aliceswaps,ptr,tmp) + { + if ( (sp= ptr->swap) != 0 && LP_swap_finished(sp,1) == 0 ) + printf("unfinished %llu r%u-r%u dest.%s %.8f -> value %.8f\n",(long long)sp->aliceid,sp->Q.R.requestid,sp->Q.R.quoteid,sp->Q.destcoin,dstr(sp->Q.destsatoshis),dstr(LP_kmdvalue(sp->Q.destcoin,sp->Q.destsatoshis))); + } printf("REJECT: %s instantdex_credits %.8f vs (%.8f + current %.8f)\n",coinaddr,dstr(credits),dstr(swaps_kmdvalue),dstr(kmdvalue)); + } if ( 0 && credits != 0 ) printf("%s %s othercredits %.8f debits %.8f + %.8f -> %.8f\n",coin->symbol,coinaddr,dstr(credits),dstr(swaps_kmdvalue),dstr(kmdvalue),dstr(credits - (swaps_kmdvalue+kmdvalue))); return(credits - (swaps_kmdvalue+kmdvalue)); From e3e3c8fdecd7c467880b0273dadcc9d2df8629a1 Mon Sep 17 00:00:00 2001 From: jl777 Date: Thu, 7 Dec 2017 22:26:16 +0400 Subject: [PATCH 1615/1664] Test --- iguana/exchanges/LP_nativeDEX.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/iguana/exchanges/LP_nativeDEX.c b/iguana/exchanges/LP_nativeDEX.c index 92248bbd4..fa0fce39d 100644 --- a/iguana/exchanges/LP_nativeDEX.c +++ b/iguana/exchanges/LP_nativeDEX.c @@ -18,6 +18,8 @@ // marketmaker // // https://github.com/bitcoin/bips/blob/master/bip-0143.mediawiki for signing BCH/BTG +// there is an issue about waiting for notarization for a swap that never starts +// use electrum in case of addr change in swap // // compress packets // portfolio to set prices from historical @@ -616,7 +618,7 @@ void LP_coinsloop(void *_coins) coin->lastscanht = coin->firstscanht; continue; } - if ( 0 ) + if ( strcmp(coin->symbol,"BTC") != 0 && strcmp(coin->symbol,"KMD") != 0 ) // SPV as backup { nonz++; if ( strcmp("BTC",coins) == 0 )//&& coin->lastscanht < coin->longestchain-3 ) From 2e9f7e89d3eb3737dbd6374a71ce93bdfb6b82b0 Mon Sep 17 00:00:00 2001 From: jl777 Date: Fri, 8 Dec 2017 10:39:24 +0400 Subject: [PATCH 1616/1664] Fix CHMEX leap second issue #36 --- crypto777/OS_time.c | 6 +++--- iguana/exchanges/LP_instantdex.c | 7 ++++++- iguana/exchanges/LP_nativeDEX.c | 1 + 3 files changed, 10 insertions(+), 4 deletions(-) diff --git a/crypto777/OS_time.c b/crypto777/OS_time.c index b5d2efc09..2a1279730 100755 --- a/crypto777/OS_time.c +++ b/crypto777/OS_time.c @@ -21,7 +21,7 @@ #define TAI_PACK 8 #define TAI_UTC_DIFF ((uint64_t)4611686018427387914ULL) -//#define UTC_ADJUST -36 +//#define UTC_ADJUST -37 #define tai_approx(t) ((double) ((t)->x)) #define tai_less(t,u) ((t)->x < (u)->x) @@ -300,7 +300,7 @@ void tai_add(struct tai *t,struct tai *u,struct tai *v) { t->x = u->x + v->x; } void tai_sub(struct tai *t,struct tai *u,struct tai *v) { t->x = u->x - v->x; } // {"leapseconds":["+1972-06-30", "+1972-12-31", "+1973-12-31", "+1974-12-31", "+1975-12-31", "+1976-12-31", "+1977-12-31", "+1982-06-30", "+1983-06-30", "+1985-06-30", "+1987-12-31", "+1989-12-31", "+1990-12-31", "+1992-06-30", "+1993-06-30", "+1994-06-30", "+1995-12-31", "+1997-06-30", "+1998-12-31", "+2005-12-31", "+2008-12-31", "+2012-06-30", "+2015-06-30"]} -char *leapseconds[] = { "+1972-06-30", "+1972-12-31", "+1973-12-31", "+1974-12-31", "+1975-12-31", "+1976-12-31", "+1977-12-31", "+1982-06-30", "+1983-06-30", "+1985-06-30", "+1987-12-31", "+1989-12-31", "+1990-12-31", "+1992-06-30", "+1993-06-30", "+1994-06-30", "+1995-12-31", "+1997-06-30", "+1998-12-31", "+2005-12-31", "+2008-12-31", "+2012-06-30", "+2015-06-30" }; +char *leapseconds[] = { "+1972-06-30", "+1972-12-31", "+1973-12-31", "+1974-12-31", "+1975-12-31", "+1976-12-31", "+1977-12-31", "+1982-06-30", "+1983-06-30", "+1985-06-30", "+1987-12-31", "+1989-12-31", "+1990-12-31", "+1992-06-30", "+1993-06-30", "+1994-06-30", "+1995-12-31", "+1997-06-30", "+1998-12-31", "+2005-12-31", "+2008-12-31", "+2012-06-30", "+2015-06-30", "+2016-12-31" }; struct tai leaptais[sizeof(leapseconds)/sizeof(*leapseconds)]; char *dayname[7] = { "Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat" } ; @@ -355,7 +355,7 @@ struct tai tai_now() { First_TAI = t, First_utc = (uint32_t)now; #ifndef DISABLE_LEAPS - UTC_ADJUST = -36; + UTC_ADJUST = -37; #endif //printf("TAINOW.%llu %03.3f UTC.%u vs %u [diff %d]\n",(long long)t.x,t.millis,First_utc,tai2utc(t),UTC_ADJUST); } diff --git a/iguana/exchanges/LP_instantdex.c b/iguana/exchanges/LP_instantdex.c index e59153b6f..f8bef39e8 100644 --- a/iguana/exchanges/LP_instantdex.c +++ b/iguana/exchanges/LP_instantdex.c @@ -480,10 +480,15 @@ int64_t LP_dynamictrust(int64_t credits,bits256 pubkey,int64_t kmdvalue) credits = ap->instantdex_credits; if ( credits != 0 && (swaps_kmdvalue+kmdvalue) > credits ) { + DL_FOREACH_SAFE(pubp->bobswaps,ptr,tmp) + { + if ( (sp= ptr->swap) != 0 && LP_swap_finished(sp,1) == 0 ) + printf("unfinished bob %llu r%u-r%u src.%s %.8f dest.%s %.8f -> price %.8f value %.8f\n",(long long)sp->aliceid,sp->Q.R.requestid,sp->Q.R.quoteid,sp->Q.srccoin,dstr(sp->Q.satoshis),sp->Q.destcoin,dstr(sp->Q.destsatoshis),(double)sp->Q.destsatoshis/(sp->Q.satoshis+1),dstr(LP_kmdvalue(sp->Q.destcoin,sp->Q.destsatoshis))); + } DL_FOREACH_SAFE(pubp->aliceswaps,ptr,tmp) { if ( (sp= ptr->swap) != 0 && LP_swap_finished(sp,1) == 0 ) - printf("unfinished %llu r%u-r%u dest.%s %.8f -> value %.8f\n",(long long)sp->aliceid,sp->Q.R.requestid,sp->Q.R.quoteid,sp->Q.destcoin,dstr(sp->Q.destsatoshis),dstr(LP_kmdvalue(sp->Q.destcoin,sp->Q.destsatoshis))); + printf("unfinished alice %llu r%u-r%u src.%s %.8f dest.%s %.8f -> price %.8f value %.8f\n",(long long)sp->aliceid,sp->Q.R.requestid,sp->Q.R.quoteid,sp->Q.srccoin,dstr(sp->Q.satoshis),sp->Q.destcoin,dstr(sp->Q.destsatoshis),(double)sp->Q.destsatoshis/(sp->Q.satoshis+1),dstr(LP_kmdvalue(sp->Q.destcoin,sp->Q.destsatoshis))); } printf("REJECT: %s instantdex_credits %.8f vs (%.8f + current %.8f)\n",coinaddr,dstr(credits),dstr(swaps_kmdvalue),dstr(kmdvalue)); } diff --git a/iguana/exchanges/LP_nativeDEX.c b/iguana/exchanges/LP_nativeDEX.c index fa0fce39d..52ba08f12 100644 --- a/iguana/exchanges/LP_nativeDEX.c +++ b/iguana/exchanges/LP_nativeDEX.c @@ -17,6 +17,7 @@ // LP_nativeDEX.c // marketmaker // +// fundvalue -> autoprice, cmc +margin -> autoprice, signals -> autoprice // https://github.com/bitcoin/bips/blob/master/bip-0143.mediawiki for signing BCH/BTG // there is an issue about waiting for notarization for a swap that never starts // use electrum in case of addr change in swap From 7b826fbf07b1394517b0c58b794303b7fe76d4f8 Mon Sep 17 00:00:00 2001 From: jl777 Date: Fri, 8 Dec 2017 14:01:43 +0400 Subject: [PATCH 1617/1664] Pending swaps --- iguana/exchanges/LP_commands.c | 6 ++--- iguana/exchanges/LP_remember.c | 44 ++++++++++++++++++++-------------- iguana/exchanges/install | 2 +- iguana/exchanges/pendingswaps | 3 +++ 4 files changed, 32 insertions(+), 23 deletions(-) create mode 100755 iguana/exchanges/pendingswaps diff --git a/iguana/exchanges/LP_commands.c b/iguana/exchanges/LP_commands.c index ea2d7d00d..bdc0060f5 100644 --- a/iguana/exchanges/LP_commands.c +++ b/iguana/exchanges/LP_commands.c @@ -119,7 +119,7 @@ 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(pending=0)\n\ swapstatus(coin, limit=10)\n\ swapstatus(base, rel, limit=10)\n\ swapstatus(requestid, quoteid)\n\ @@ -290,14 +290,12 @@ instantdex_claim()\n\ { uint32_t requestid,quoteid; if ( (requestid= juint(argjson,"requestid")) != 0 && (quoteid= juint(argjson,"quoteid")) != 0 ) - { 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,0)); + else return(basilisk_swaplist(0,0,0,jint(argjson,"pending"))); } else if ( strcmp(method,"dynamictrust") == 0 ) { diff --git a/iguana/exchanges/LP_remember.c b/iguana/exchanges/LP_remember.c index b7a6ea3d1..a64138081 100644 --- a/iguana/exchanges/LP_remember.c +++ b/iguana/exchanges/LP_remember.c @@ -880,7 +880,7 @@ 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,int32_t forceflag) +cJSON *basilisk_remember(int64_t *KMDtotals,int64_t *BTCtotals,uint32_t requestid,uint32_t quoteid,int32_t forceflag,int32_t pendingonly) { 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]; @@ -1190,10 +1190,15 @@ cJSON *basilisk_remember(int64_t *KMDtotals,int64_t *BTCtotals,uint32_t requesti for (i=0; i> 32); - q = (uint32_t)G.LP_skipstatus[i]; - if ( r == requestid && q == quoteid ) + for (i=0; i> 32); + q = (uint32_t)G.LP_skipstatus[i]; + if ( r == requestid && q == quoteid ) + { + item = cJSON_CreateObject(); + jaddstr(item,"status","realtime"); + jaddnum(item,"requestid",r); + jaddnum(item,"quoteid",q); + jaddi(array,item); + flag = 1; + break; + } } } if ( flag == 0 ) @@ -1245,7 +1253,7 @@ char *basilisk_swaplist(uint32_t origrequestid,uint32_t origquoteid,int32_t forc { if ( count < sizeof(ridqids)/sizeof(*ridqids) ) ridqids[count++] = ridqid; - if ( (item= basilisk_remember(KMDtotals,BTCtotals,requestid,quoteid,0)) != 0 ) + if ( (item= basilisk_remember(KMDtotals,BTCtotals,requestid,quoteid,0,pendingonly)) != 0 ) jaddi(array,item); } } @@ -1283,7 +1291,7 @@ 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,forceflag)) != 0 ) + if ( (item= basilisk_remember(KMDtotals,BTCtotals,requestid,quoteid,forceflag,0)) != 0 ) return(jprint(item,1)); else return(clonestr("{\"error\":\"cant find requestid-quoteid\"}")); } @@ -1373,7 +1381,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)) != 0 ) + if ( (liststr= basilisk_swaplist(0,0,0,0)) != 0 ) { //printf("swapentry.(%s)\n",liststr); if ( (retjson= cJSON_Parse(liststr)) != 0 ) diff --git a/iguana/exchanges/install b/iguana/exchanges/install index 5c8dacf99..c891b0d7f 100755 --- a/iguana/exchanges/install +++ b/iguana/exchanges/install @@ -1,5 +1,5 @@ #!/bin/bash -cp fundvalue balances dynamictrust getcoin kickstart tradesarray claim deposit10 deposit1 invreset sendrawtransaction processfiles stop millis mnzservers bot_buy bot_list bot_statuslist bot_pause bot_resume bot_sell bot_settings bot_status bot_stop guistats pubkeystats pendings coinswaps baserelswaps setpassphrase notarizations getrawtransaction parselog statsdisp m_js 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 pendingswaps fundvalue balances dynamictrust getcoin kickstart tradesarray claim deposit10 deposit1 invreset sendrawtransaction processfiles stop millis mnzservers bot_buy bot_list bot_statuslist bot_pause bot_resume bot_sell bot_settings bot_status bot_stop guistats pubkeystats pendings coinswaps baserelswaps setpassphrase notarizations getrawtransaction parselog statsdisp m_js 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 . diff --git a/iguana/exchanges/pendingswaps b/iguana/exchanges/pendingswaps new file mode 100755 index 000000000..6cd5f50dd --- /dev/null +++ b/iguana/exchanges/pendingswaps @@ -0,0 +1,3 @@ +#!/bin/bash +source userpass +curl --url "http://127.0.0.1:7783" --data "{\"userpass\":\"$userpass\",\"method\":\"swapstatus\",\"pending\":1}" From 03f9fb066779ae6a29f730ab0756656bfe283210 Mon Sep 17 00:00:00 2001 From: jl777 Date: Fri, 8 Dec 2017 14:11:09 +0400 Subject: [PATCH 1618/1664] Test --- iguana/exchanges/LP_socket.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/iguana/exchanges/LP_socket.c b/iguana/exchanges/LP_socket.c index 8cceb33b2..43e94bd21 100644 --- a/iguana/exchanges/LP_socket.c +++ b/iguana/exchanges/LP_socket.c @@ -1035,7 +1035,7 @@ void LP_dedicatedloop(void *arg) else { printf("no more electrum data when expected2\n"); - electrum_kickstart(ep); + //electrum_kickstart(ep); break; } } From f9ca420d1c3ef2ddaba14636ea0d32f897b84bf3 Mon Sep 17 00:00:00 2001 From: jl777 Date: Fri, 8 Dec 2017 14:18:21 +0400 Subject: [PATCH 1619/1664] Test --- iguana/exchanges/LP_socket.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/iguana/exchanges/LP_socket.c b/iguana/exchanges/LP_socket.c index 43e94bd21..c3fe17a4a 100644 --- a/iguana/exchanges/LP_socket.c +++ b/iguana/exchanges/LP_socket.c @@ -1034,8 +1034,10 @@ void LP_dedicatedloop(void *arg) } else { +#ifndef _WIN32 printf("no more electrum data when expected2\n"); - //electrum_kickstart(ep); + electrum_kickstart(ep); +#endif break; } } From 2e002e1680c780dd2d24d82b588df3234227a900 Mon Sep 17 00:00:00 2001 From: jl777 Date: Fri, 8 Dec 2017 14:27:44 +0400 Subject: [PATCH 1620/1664] Test --- iguana/exchanges/LP_remember.c | 2 +- iguana/exchanges/LP_scan.c | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/iguana/exchanges/LP_remember.c b/iguana/exchanges/LP_remember.c index a64138081..452b34f0e 100644 --- a/iguana/exchanges/LP_remember.c +++ b/iguana/exchanges/LP_remember.c @@ -895,7 +895,7 @@ cJSON *basilisk_remember(int64_t *KMDtotals,int64_t *BTCtotals,uint32_t requesti 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("legacy DB SWAPS.(%u %u) %llu files BOB.(%s) Alice.(%s) src.(%s) dest.(%s)\n",rswap.requestid,rswap.quoteid,(long long)rswap.aliceid,rswap.bobcoin,rswap.alicecoin,rswap.src,rswap.dest); + printf("legacy r%u-q%u DB SWAPS.(%u %u) %llu files BOB.(%s) Alice.(%s) src.(%s) dest.(%s)\n",requestid,quoteid,rswap.requestid,rswap.quoteid,(long long)rswap.aliceid,rswap.bobcoin,rswap.alicecoin,rswap.src,rswap.dest); return(cJSON_Parse("{\"error\":\"mismatched bob/alice vs src/dest coins??\"}")); } alice = LP_coinfind(rswap.alicecoin); diff --git a/iguana/exchanges/LP_scan.c b/iguana/exchanges/LP_scan.c index 850852f23..defc1b0cd 100644 --- a/iguana/exchanges/LP_scan.c +++ b/iguana/exchanges/LP_scan.c @@ -26,7 +26,7 @@ int32_t LP_blockinit(struct iguana_info *coin,int32_t height) { if ( (txs= jarray(&numtx,blockobj,"tx")) != 0 ) { - printf("LP_blockinit %s ht.%d numtx.%d\n",coin->symbol,height,numtx); + //printf("LP_blockinit %s ht.%d numtx.%d\n",coin->symbol,height,numtx); for (iter=0; iter<2; iter++) { txobj = 0; From 9553494bba5c323845e64356f9955e63c0a7b02e Mon Sep 17 00:00:00 2001 From: jl777 Date: Fri, 8 Dec 2017 14:31:07 +0400 Subject: [PATCH 1621/1664] Test --- iguana/exchanges/LP_remember.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/iguana/exchanges/LP_remember.c b/iguana/exchanges/LP_remember.c index 452b34f0e..846bc45e1 100644 --- a/iguana/exchanges/LP_remember.c +++ b/iguana/exchanges/LP_remember.c @@ -886,6 +886,8 @@ cJSON *basilisk_remember(int64_t *KMDtotals,int64_t *BTCtotals,uint32_t requesti 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 ( requestid == 0 || quoteid == 0 ) + return(cJSON_Parse("{\"error\":\"null requestid or quoteid\"}")); 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"); From c0bbaadd1f20de62e6976aef748ef2670d7175f3 Mon Sep 17 00:00:00 2001 From: jl777 Date: Fri, 8 Dec 2017 15:38:20 +0400 Subject: [PATCH 1622/1664] Test --- iguana/exchanges/LP_utxo.c | 19 ++++++++++++++++++- 1 file changed, 18 insertions(+), 1 deletion(-) diff --git a/iguana/exchanges/LP_utxo.c b/iguana/exchanges/LP_utxo.c index e948750c8..252da8769 100644 --- a/iguana/exchanges/LP_utxo.c +++ b/iguana/exchanges/LP_utxo.c @@ -622,7 +622,7 @@ cJSON *LP_address_balance(struct iguana_info *coin,char *coinaddr,int32_t electr cJSON *LP_balances(char *coinaddr) { - struct iguana_info *coin,*tmp; char address[64]; uint8_t addrtype,rmd160[20]; uint64_t balance; cJSON *array,*item,*retjson; + struct iguana_info *coin,*tmp; char address[64]; uint8_t addrtype,rmd160[20]; uint64_t balance,KMDvalue,sum = 0; cJSON *array,*item,*retjson; array = cJSON_CreateArray(); HASH_ITER(hh,LP_coins,coin,tmp) { @@ -645,6 +645,11 @@ cJSON *LP_balances(char *coinaddr) item = cJSON_CreateObject(); jaddstr(item,"coin",coin->symbol); jaddnum(item,"balance",dstr(balance)); + if ( (KMDvalue= LP_KMDvalue(coin,balance)) != 0 ) + { + jaddnum(item,"KMDvalue",dstr(balance)); + sum += KMDvalue; + } if ( coin->electrum != 0 && strcmp(coinaddr,coin->smartaddr) == 0 && strcmp(coin->symbol,"KMD") == 0 ) { jaddnum(item,"zcredits",dstr(LP_myzcredits())); @@ -662,6 +667,11 @@ cJSON *LP_balances(char *coinaddr) item = cJSON_CreateObject(); jaddstr(item,"coin",coin->symbol); jaddnum(item,"balance",dstr(balance)); + if ( (KMDvalue= LP_KMDvalue(coin,balance)) != 0 ) + { + jaddnum(item,"KMDvalue",dstr(balance)); + sum += KMDvalue; + } if ( strcmp(coin->symbol,"KMD") == 0 ) { jaddnum(item,"zcredits",dstr(LP_myzcredits())); @@ -671,6 +681,13 @@ cJSON *LP_balances(char *coinaddr) } } } + if ( sum != 0 ) + { + item = cJSON_CreateObject(); + jaddstr(item,"coin","total"); + jaddnum(item,"balance",dstr(sum)); + jaddi(array,item); + } return(array); } From 44ef1487468a14fb464d4337403c82e8e44bd77c Mon Sep 17 00:00:00 2001 From: jl777 Date: Fri, 8 Dec 2017 15:45:52 +0400 Subject: [PATCH 1623/1664] Test --- iguana/exchanges/LP_utxo.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/iguana/exchanges/LP_utxo.c b/iguana/exchanges/LP_utxo.c index 252da8769..227532b57 100644 --- a/iguana/exchanges/LP_utxo.c +++ b/iguana/exchanges/LP_utxo.c @@ -647,7 +647,7 @@ cJSON *LP_balances(char *coinaddr) jaddnum(item,"balance",dstr(balance)); if ( (KMDvalue= LP_KMDvalue(coin,balance)) != 0 ) { - jaddnum(item,"KMDvalue",dstr(balance)); + jaddnum(item,"KMDvalue",dstr(KMDvalue)); sum += KMDvalue; } if ( coin->electrum != 0 && strcmp(coinaddr,coin->smartaddr) == 0 && strcmp(coin->symbol,"KMD") == 0 ) @@ -669,7 +669,7 @@ cJSON *LP_balances(char *coinaddr) jaddnum(item,"balance",dstr(balance)); if ( (KMDvalue= LP_KMDvalue(coin,balance)) != 0 ) { - jaddnum(item,"KMDvalue",dstr(balance)); + jaddnum(item,"KMDvalue",dstr(KMDvalue)); sum += KMDvalue; } if ( strcmp(coin->symbol,"KMD") == 0 ) From 9f681777958551450fa32f353e999270eb71ff29 Mon Sep 17 00:00:00 2001 From: jl777 Date: Fri, 8 Dec 2017 16:20:55 +0400 Subject: [PATCH 1624/1664] Test --- iguana/exchanges/LP_instantdex.c | 2 +- iguana/exchanges/LP_remember.c | 42 ++++++++++++++++++++++++++++++-- 2 files changed, 41 insertions(+), 3 deletions(-) diff --git a/iguana/exchanges/LP_instantdex.c b/iguana/exchanges/LP_instantdex.c index f8bef39e8..273d1bcc3 100644 --- a/iguana/exchanges/LP_instantdex.c +++ b/iguana/exchanges/LP_instantdex.c @@ -386,7 +386,7 @@ int64_t LP_instantdex_credit(int32_t dispflag,char *coinaddr,int64_t satoshis,in { ap->instantdex_credits += satoshis; ap->didinstantdex = 1; - if ( dispflag != 0 ) + if ( 0 && 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)); diff --git a/iguana/exchanges/LP_remember.c b/iguana/exchanges/LP_remember.c index 846bc45e1..d0fd4291b 100644 --- a/iguana/exchanges/LP_remember.c +++ b/iguana/exchanges/LP_remember.c @@ -897,7 +897,7 @@ cJSON *basilisk_remember(int64_t *KMDtotals,int64_t *BTCtotals,uint32_t requesti 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("legacy r%u-q%u DB SWAPS.(%u %u) %llu files BOB.(%s) Alice.(%s) src.(%s) dest.(%s)\n",requestid,quoteid,rswap.requestid,rswap.quoteid,(long long)rswap.aliceid,rswap.bobcoin,rswap.alicecoin,rswap.src,rswap.dest); + //printf("legacy r%u-q%u DB SWAPS.(%u %u) %llu files BOB.(%s) Alice.(%s) src.(%s) dest.(%s)\n",requestid,quoteid,rswap.requestid,rswap.quoteid,(long long)rswap.aliceid,rswap.bobcoin,rswap.alicecoin,rswap.src,rswap.dest); return(cJSON_Parse("{\"error\":\"mismatched bob/alice vs src/dest coins??\"}")); } alice = LP_coinfind(rswap.alicecoin); @@ -1303,7 +1303,10 @@ extern uint32_t Alice_expiration; char *LP_recent_swaps(int32_t limit) { - char fname[512]; long fsize,offset; FILE *fp; int32_t i=0; uint32_t requestid,quoteid; cJSON *array,*item,*retjson; + char fname[512],*retstr,*base,*rel,*statusstr; long fsize,offset; FILE *fp; int32_t baseind,relind,i=0; uint32_t requestid,quoteid; cJSON *array,*item,*retjson,*subitem,*swapjson; int64_t srcamount,destamount,KMDtotals[LP_MAXPRICEINFOS],BTCtotals[LP_MAXPRICEINFOS]; double netamounts[LP_MAXPRICEINFOS]; + memset(KMDtotals,0,sizeof(KMDtotals)); + memset(BTCtotals,0,sizeof(BTCtotals)); + memset(netamounts,0,sizeof(netamounts)); if ( limit <= 0 ) limit = 3; sprintf(fname,"%s/SWAPS/list",GLOBAL_DBDIR), OS_compatible_path(fname); @@ -1322,9 +1325,33 @@ char *LP_recent_swaps(int32_t limit) { if ( fread(&requestid,1,sizeof(requestid),fp) == sizeof(requestid) && fread("eid,1,sizeof(quoteid),fp) == sizeof(quoteid) ) { + //{"expiration":1512319112,"tradeid":428338847,"requestid":2950509278,"quoteid":14828468,"iambob":0,"Bgui":"","Agui":"nogui","gui":"nogui","bob":"REVS","srcamount":0.00691857,"bobtxfee":0.00010000,"alice":"KMD","destamount":0.01250000,"alicetxfee":0.00010000,"aliceid":"8160174903500865537","sentflags":["alicespend", "bobspend", "bobpayment", "alicepayment", "bobdeposit", "myfee", "bobrefund"],"values":[0.00701857, 0.01260000, 0.00711857, 0.01270000, 0.00798339, 0, 0.00010000, 0, 0, 0, 0],"result":"success","status":"finished","finishtime":1512305767,"bobdeposit":"cf626c35cf507687eeae203429b16c5ad93abffdd3e493a731ea804f0c927dd7","alicepayment":"35563822d590f457f2c03c3169d7dfe01a642dcc24c0f4a11e7f880c1a5fcc89","bobpayment":"20bfc58829f18e551d614c799e8a6401db9e4210d9c8521d74b77cafe3e9a35f","paymentspent":"0000000000000000000000000000000000000000000000000000000000000000","Apaymentspent":"deadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeef","depositspent":"f1c2327b55efa79694585e41286b5a6d0160bad6d603fed1f3093596a701e487","method":"tradestatus","finishtime":1512305767,"gui":"nogui"} item = cJSON_CreateArray(); jaddinum(item,requestid); jaddinum(item,quoteid); + subitem = cJSON_CreateObject(); + if ( (retstr= basilisk_swapentry(requestid,quoteid,0)) != 0 ) + { + if ( (swapjson= cJSON_Parse(retstr)) != 0 ) + { + if ( (base= jstr(swapjson,"bob")) != 0 && (rel= jstr(swapjson,"alice")) != 0 && (statusstr= jstr(swapjson,"status")) != 0 && strcmp(statusstr,"finished") == 0 && (baseind= LP_priceinfoind(base)) >= 0 && (relind= LP_priceinfoind(rel)) >= 0 ) + { + srcamount = jdouble(swapjson,"srcamount"); + destamount = jdouble(swapjson,"destamount"); + if ( jint(swapjson,"iambob") != 0 ) + srcamount = -srcamount; + else destamount = -destamount; + netamounts[baseind] += srcamount; + netamounts[relind] += destamount; + jaddnum(subitem,base,srcamount); + jaddnum(subitem,rel,destamount); + jaddi(item,subitem); + } + free_json(swapjson); + } + free(retstr); + } + jaddi(array,subitem); jaddi(array,item); } else break; } else break; @@ -1334,6 +1361,17 @@ char *LP_recent_swaps(int32_t limit) retjson = cJSON_CreateObject(); jaddstr(retjson,"result","success"); jadd(retjson,"swaps",array); + array = cJSON_CreateArray(); + for (i=0; i Date: Fri, 8 Dec 2017 16:24:26 +0400 Subject: [PATCH 1625/1664] Test --- iguana/exchanges/LP_remember.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/iguana/exchanges/LP_remember.c b/iguana/exchanges/LP_remember.c index d0fd4291b..b51a8a7ff 100644 --- a/iguana/exchanges/LP_remember.c +++ b/iguana/exchanges/LP_remember.c @@ -1329,7 +1329,6 @@ char *LP_recent_swaps(int32_t limit) item = cJSON_CreateArray(); jaddinum(item,requestid); jaddinum(item,quoteid); - subitem = cJSON_CreateObject(); if ( (retstr= basilisk_swapentry(requestid,quoteid,0)) != 0 ) { if ( (swapjson= cJSON_Parse(retstr)) != 0 ) @@ -1343,6 +1342,7 @@ char *LP_recent_swaps(int32_t limit) else destamount = -destamount; netamounts[baseind] += srcamount; netamounts[relind] += destamount; + subitem = cJSON_CreateObject(); jaddnum(subitem,base,srcamount); jaddnum(subitem,rel,destamount); jaddi(item,subitem); @@ -1351,7 +1351,6 @@ char *LP_recent_swaps(int32_t limit) } free(retstr); } - jaddi(array,subitem); jaddi(array,item); } else break; } else break; From 0d94e22dbab8b2c1c08fba7d09c8f97f9ced893f Mon Sep 17 00:00:00 2001 From: jl777 Date: Fri, 8 Dec 2017 16:30:22 +0400 Subject: [PATCH 1626/1664] Test --- iguana/exchanges/LP_remember.c | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/iguana/exchanges/LP_remember.c b/iguana/exchanges/LP_remember.c index b51a8a7ff..713762d82 100644 --- a/iguana/exchanges/LP_remember.c +++ b/iguana/exchanges/LP_remember.c @@ -1325,15 +1325,18 @@ char *LP_recent_swaps(int32_t limit) { if ( fread(&requestid,1,sizeof(requestid),fp) == sizeof(requestid) && fread("eid,1,sizeof(quoteid),fp) == sizeof(quoteid) ) { - //{"expiration":1512319112,"tradeid":428338847,"requestid":2950509278,"quoteid":14828468,"iambob":0,"Bgui":"","Agui":"nogui","gui":"nogui","bob":"REVS","srcamount":0.00691857,"bobtxfee":0.00010000,"alice":"KMD","destamount":0.01250000,"alicetxfee":0.00010000,"aliceid":"8160174903500865537","sentflags":["alicespend", "bobspend", "bobpayment", "alicepayment", "bobdeposit", "myfee", "bobrefund"],"values":[0.00701857, 0.01260000, 0.00711857, 0.01270000, 0.00798339, 0, 0.00010000, 0, 0, 0, 0],"result":"success","status":"finished","finishtime":1512305767,"bobdeposit":"cf626c35cf507687eeae203429b16c5ad93abffdd3e493a731ea804f0c927dd7","alicepayment":"35563822d590f457f2c03c3169d7dfe01a642dcc24c0f4a11e7f880c1a5fcc89","bobpayment":"20bfc58829f18e551d614c799e8a6401db9e4210d9c8521d74b77cafe3e9a35f","paymentspent":"0000000000000000000000000000000000000000000000000000000000000000","Apaymentspent":"deadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeef","depositspent":"f1c2327b55efa79694585e41286b5a6d0160bad6d603fed1f3093596a701e487","method":"tradestatus","finishtime":1512305767,"gui":"nogui"} item = cJSON_CreateArray(); jaddinum(item,requestid); jaddinum(item,quoteid); if ( (retstr= basilisk_swapentry(requestid,quoteid,0)) != 0 ) { + printf("%s\n",retstr); if ( (swapjson= cJSON_Parse(retstr)) != 0 ) { - if ( (base= jstr(swapjson,"bob")) != 0 && (rel= jstr(swapjson,"alice")) != 0 && (statusstr= jstr(swapjson,"status")) != 0 && strcmp(statusstr,"finished") == 0 && (baseind= LP_priceinfoind(base)) >= 0 && (relind= LP_priceinfoind(rel)) >= 0 ) + base = jstr(swapjson,"bob"); + rel = jstr(swapjson,"alice"); + statusstr = jstr(swapjson,"status"); + if ( base != 0 && rel != 0 && statusstr != 0 && strcmp(statusstr,"finished") == 0 && (baseind= LP_priceinfoind(base)) >= 0 && (relind= LP_priceinfoind(rel)) >= 0 ) { srcamount = jdouble(swapjson,"srcamount"); destamount = jdouble(swapjson,"destamount"); @@ -1346,7 +1349,7 @@ char *LP_recent_swaps(int32_t limit) jaddnum(subitem,base,srcamount); jaddnum(subitem,rel,destamount); jaddi(item,subitem); - } + } else printf("base.%p rel.%p statusstr.%p\n",base,rel,statusstr); free_json(swapjson); } free(retstr); From 644bb0c2abf74b71e953190eccf6f718368d1ad9 Mon Sep 17 00:00:00 2001 From: jl777 Date: Fri, 8 Dec 2017 16:35:52 +0400 Subject: [PATCH 1627/1664] Test --- iguana/exchanges/LP_remember.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/iguana/exchanges/LP_remember.c b/iguana/exchanges/LP_remember.c index 713762d82..a1f1bbb87 100644 --- a/iguana/exchanges/LP_remember.c +++ b/iguana/exchanges/LP_remember.c @@ -1330,12 +1330,12 @@ char *LP_recent_swaps(int32_t limit) jaddinum(item,quoteid); if ( (retstr= basilisk_swapentry(requestid,quoteid,0)) != 0 ) { - printf("%s\n",retstr); if ( (swapjson= cJSON_Parse(retstr)) != 0 ) { base = jstr(swapjson,"bob"); rel = jstr(swapjson,"alice"); statusstr = jstr(swapjson,"status"); + baseind = relind = -1; if ( base != 0 && rel != 0 && statusstr != 0 && strcmp(statusstr,"finished") == 0 && (baseind= LP_priceinfoind(base)) >= 0 && (relind= LP_priceinfoind(rel)) >= 0 ) { srcamount = jdouble(swapjson,"srcamount"); @@ -1349,9 +1349,9 @@ char *LP_recent_swaps(int32_t limit) jaddnum(subitem,base,srcamount); jaddnum(subitem,rel,destamount); jaddi(item,subitem); - } else printf("base.%p rel.%p statusstr.%p\n",base,rel,statusstr); + } else printf("base.%p rel.%p statusstr.%p baseind.%d relind.%d\n",base,rel,statusstr,baseind,relind); free_json(swapjson); - } + } else printf("error parsing.(%s)\n",retstr); free(retstr); } jaddi(array,item); From 82ddac98ee178fbd1f362d7326ab51c82d5702ec Mon Sep 17 00:00:00 2001 From: jl777 Date: Fri, 8 Dec 2017 16:37:55 +0400 Subject: [PATCH 1628/1664] Test --- iguana/exchanges/LP_remember.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/iguana/exchanges/LP_remember.c b/iguana/exchanges/LP_remember.c index a1f1bbb87..40d0a493b 100644 --- a/iguana/exchanges/LP_remember.c +++ b/iguana/exchanges/LP_remember.c @@ -1303,7 +1303,7 @@ extern uint32_t Alice_expiration; char *LP_recent_swaps(int32_t limit) { - char fname[512],*retstr,*base,*rel,*statusstr; long fsize,offset; FILE *fp; int32_t baseind,relind,i=0; uint32_t requestid,quoteid; cJSON *array,*item,*retjson,*subitem,*swapjson; int64_t srcamount,destamount,KMDtotals[LP_MAXPRICEINFOS],BTCtotals[LP_MAXPRICEINFOS]; double netamounts[LP_MAXPRICEINFOS]; + char fname[512],*retstr,*base,*rel,*statusstr; long fsize,offset; FILE *fp; int32_t baseind,relind,i=0; uint32_t requestid,quoteid; cJSON *array,*item,*retjson,*subitem,*swapjson; int64_t KMDtotals[LP_MAXPRICEINFOS],BTCtotals[LP_MAXPRICEINFOS]; double srcamount,destamount,netamounts[LP_MAXPRICEINFOS]; memset(KMDtotals,0,sizeof(KMDtotals)); memset(BTCtotals,0,sizeof(BTCtotals)); memset(netamounts,0,sizeof(netamounts)); From f0286ad15188eaab79a91c74ed0f174548a2f866 Mon Sep 17 00:00:00 2001 From: jl777 Date: Fri, 8 Dec 2017 16:50:40 +0400 Subject: [PATCH 1629/1664] Test --- iguana/exchanges/LP_remember.c | 16 ++++++++++------ 1 file changed, 10 insertions(+), 6 deletions(-) diff --git a/iguana/exchanges/LP_remember.c b/iguana/exchanges/LP_remember.c index 40d0a493b..9b162c363 100644 --- a/iguana/exchanges/LP_remember.c +++ b/iguana/exchanges/LP_remember.c @@ -1343,12 +1343,16 @@ char *LP_recent_swaps(int32_t limit) if ( jint(swapjson,"iambob") != 0 ) srcamount = -srcamount; else destamount = -destamount; - netamounts[baseind] += srcamount; - netamounts[relind] += destamount; - subitem = cJSON_CreateObject(); - jaddnum(subitem,base,srcamount); - jaddnum(subitem,rel,destamount); - jaddi(item,subitem); + if ( srcamount != 0. && destamount != 0. ) + { + netamounts[baseind] += srcamount; + netamounts[relind] += destamount; + subitem = cJSON_CreateObject(); + jaddnum(subitem,base,srcamount); + jaddnum(subitem,rel,destamount); + jaddnum(subitem,"price",destamount/srcamount); + jaddi(item,subitem); + } } else printf("base.%p rel.%p statusstr.%p baseind.%d relind.%d\n",base,rel,statusstr,baseind,relind); free_json(swapjson); } else printf("error parsing.(%s)\n",retstr); From 8fe70f0d55c019c02f80d45f5582abd5609f5259 Mon Sep 17 00:00:00 2001 From: jl777 Date: Fri, 8 Dec 2017 19:42:10 +0400 Subject: [PATCH 1630/1664] Test --- iguana/exchanges/LP_transaction.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/iguana/exchanges/LP_transaction.c b/iguana/exchanges/LP_transaction.c index 5f4f107da..8461474ba 100644 --- a/iguana/exchanges/LP_transaction.c +++ b/iguana/exchanges/LP_transaction.c @@ -1387,7 +1387,7 @@ char *LP_withdraw(struct iguana_info *coin,cJSON *argjson) free(V); if ( vins != 0 ) { - if ( (numvins= cJSON_GetArraySize(vins)) > 0 ) + if ( completed == 0 && (numvins= cJSON_GetArraySize(vins)) > 0 ) { for (i=0; i Date: Fri, 8 Dec 2017 22:15:17 +0400 Subject: [PATCH 1631/1664] Test --- iguana/exchanges/LP_instantdex.c | 19 +++++++++++-------- 1 file changed, 11 insertions(+), 8 deletions(-) diff --git a/iguana/exchanges/LP_instantdex.c b/iguana/exchanges/LP_instantdex.c index 273d1bcc3..e744a3c0b 100644 --- a/iguana/exchanges/LP_instantdex.c +++ b/iguana/exchanges/LP_instantdex.c @@ -480,15 +480,18 @@ int64_t LP_dynamictrust(int64_t credits,bits256 pubkey,int64_t kmdvalue) credits = ap->instantdex_credits; if ( credits != 0 && (swaps_kmdvalue+kmdvalue) > credits ) { - DL_FOREACH_SAFE(pubp->bobswaps,ptr,tmp) - { - if ( (sp= ptr->swap) != 0 && LP_swap_finished(sp,1) == 0 ) - printf("unfinished bob %llu r%u-r%u src.%s %.8f dest.%s %.8f -> price %.8f value %.8f\n",(long long)sp->aliceid,sp->Q.R.requestid,sp->Q.R.quoteid,sp->Q.srccoin,dstr(sp->Q.satoshis),sp->Q.destcoin,dstr(sp->Q.destsatoshis),(double)sp->Q.destsatoshis/(sp->Q.satoshis+1),dstr(LP_kmdvalue(sp->Q.destcoin,sp->Q.destsatoshis))); - } - DL_FOREACH_SAFE(pubp->aliceswaps,ptr,tmp) + if ( 0 ) { - if ( (sp= ptr->swap) != 0 && LP_swap_finished(sp,1) == 0 ) - printf("unfinished alice %llu r%u-r%u src.%s %.8f dest.%s %.8f -> price %.8f value %.8f\n",(long long)sp->aliceid,sp->Q.R.requestid,sp->Q.R.quoteid,sp->Q.srccoin,dstr(sp->Q.satoshis),sp->Q.destcoin,dstr(sp->Q.destsatoshis),(double)sp->Q.destsatoshis/(sp->Q.satoshis+1),dstr(LP_kmdvalue(sp->Q.destcoin,sp->Q.destsatoshis))); + DL_FOREACH_SAFE(pubp->bobswaps,ptr,tmp) + { + if ( (sp= ptr->swap) != 0 && LP_swap_finished(sp,1) == 0 ) + printf("unfinished bob %llu r%u-r%u src.%s %.8f dest.%s %.8f -> price %.8f value %.8f\n",(long long)sp->aliceid,sp->Q.R.requestid,sp->Q.R.quoteid,sp->Q.srccoin,dstr(sp->Q.satoshis),sp->Q.destcoin,dstr(sp->Q.destsatoshis),(double)sp->Q.destsatoshis/(sp->Q.satoshis+1),dstr(LP_kmdvalue(sp->Q.destcoin,sp->Q.destsatoshis))); + } + DL_FOREACH_SAFE(pubp->aliceswaps,ptr,tmp) + { + if ( (sp= ptr->swap) != 0 && LP_swap_finished(sp,1) == 0 ) + printf("unfinished alice %llu r%u-r%u src.%s %.8f dest.%s %.8f -> price %.8f value %.8f\n",(long long)sp->aliceid,sp->Q.R.requestid,sp->Q.R.quoteid,sp->Q.srccoin,dstr(sp->Q.satoshis),sp->Q.destcoin,dstr(sp->Q.destsatoshis),(double)sp->Q.destsatoshis/(sp->Q.satoshis+1),dstr(LP_kmdvalue(sp->Q.destcoin,sp->Q.destsatoshis))); + } } printf("REJECT: %s instantdex_credits %.8f vs (%.8f + current %.8f)\n",coinaddr,dstr(credits),dstr(swaps_kmdvalue),dstr(kmdvalue)); } From d570ea7915227a1b2f637b1164eba57ca41fe2d5 Mon Sep 17 00:00:00 2001 From: jl777 Date: Fri, 8 Dec 2017 23:39:38 +0400 Subject: [PATCH 1632/1664] Test --- iguana/exchanges/LP_remember.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/iguana/exchanges/LP_remember.c b/iguana/exchanges/LP_remember.c index 9b162c363..389c0c8d9 100644 --- a/iguana/exchanges/LP_remember.c +++ b/iguana/exchanges/LP_remember.c @@ -1004,7 +1004,7 @@ cJSON *basilisk_remember(int64_t *KMDtotals,int64_t *BTCtotals,uint32_t requesti } if ( rswap.sentflags[BASILISK_ALICECLAIM] == 0 && rswap.sentflags[BASILISK_BOBDEPOSIT] != 0 && bits256_nonz(rswap.txids[BASILISK_BOBDEPOSIT]) != 0 && bits256_nonz(rswap.depositspent) == 0 ) { - if ( time(NULL) > rswap.expiration ) + if ( time(NULL) > rswap.expiration+777 ) { flag = 0; if ( bob->electrum == 0 ) @@ -1093,7 +1093,7 @@ cJSON *basilisk_remember(int64_t *KMDtotals,int64_t *BTCtotals,uint32_t requesti free_json(txoutobj), flag = 0; else flag = -1, rswap.paymentspent = deadtxid; } - if ( flag == 0 && time(NULL) > rswap.expiration ) + if ( flag == 0 && time(NULL) > rswap.expiration+777 ) { // bobreclaim redeemlen = basilisk_swap_bobredeemscript(0,&secretstart,redeemscript,rswap.plocktime,rswap.pubA0,rswap.pubB0,rswap.pubB1,zero,rswap.privBn,rswap.secretAm,rswap.secretAm256,rswap.secretBn,rswap.secretBn256); @@ -1122,7 +1122,7 @@ cJSON *basilisk_remember(int64_t *KMDtotals,int64_t *BTCtotals,uint32_t requesti free_json(txoutobj), flag = 0; else flag = -1, rswap.depositspent = deadtxid; } - if ( flag == 0 && (bits256_nonz(rswap.Apaymentspent) != 0 || time(NULL) > rswap.expiration) ) + if ( flag == 0 && (bits256_nonz(rswap.Apaymentspent) != 0 || time(NULL) > rswap.expiration+777) ) { 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 ) From ef16110815c95e743f5738aaa03f083f3261d4c7 Mon Sep 17 00:00:00 2001 From: jl777 Date: Sat, 9 Dec 2017 00:17:26 +0400 Subject: [PATCH 1633/1664] Test --- iguana/exchanges/LP_remember.c | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/iguana/exchanges/LP_remember.c b/iguana/exchanges/LP_remember.c index 389c0c8d9..46e0b0788 100644 --- a/iguana/exchanges/LP_remember.c +++ b/iguana/exchanges/LP_remember.c @@ -995,7 +995,7 @@ cJSON *basilisk_remember(int64_t *KMDtotals,int64_t *BTCtotals,uint32_t requesti } for (j=0; j<32; j++) rev.bytes[j] = rswap.myprivs[0].bytes[31 - j]; - if ( (rswap.txbytes[BASILISK_ALICESPEND]= basilisk_swap_bobtxspend(&signedtxid,rswap.Btxfee,"alicespend",rswap.bobcoin,bob->wiftaddr,bob->taddr,bob->pubtype,bob->p2shtype,bob->isPoS,bob->wiftype,ctx,rswap.myprivs[0],0,redeemscript,redeemlen,userdata,len,rswap.txids[BASILISK_BOBPAYMENT],0,0,rswap.pubkey33,1,rswap.expiration,&rswap.values[BASILISK_ALICESPEND],0,0,rswap.bobpaymentaddr,1,bob->zcash)) != 0 ) + if ( (rswap.txbytes[BASILISK_ALICESPEND]= basilisk_swap_bobtxspend(&signedtxid,rswap.Btxfee,"alicespend",rswap.bobcoin,bob->wiftaddr,bob->taddr,bob->pubtype,bob->p2shtype,bob->isPoS,bob->wiftype,ctx,rswap.myprivs[0],0,redeemscript,redeemlen,userdata,len,rswap.txids[BASILISK_BOBPAYMENT],0,0,rswap.pubkey33,1,rswap.expiration+777,&rswap.values[BASILISK_ALICESPEND],0,0,rswap.bobpaymentaddr,1,bob->zcash)) != 0 ) printf("alicespend.(%s)\n",rswap.txbytes[BASILISK_ALICESPEND]); } LP_txbytes_update("alicespend",rswap.bobcoin,rswap.txbytes[BASILISK_ALICESPEND],&rswap.txids[BASILISK_ALICESPEND],&rswap.paymentspent,&rswap.sentflags[BASILISK_ALICESPEND]); @@ -1025,7 +1025,7 @@ cJSON *basilisk_remember(int64_t *KMDtotals,int64_t *BTCtotals,uint32_t requesti if ( bits256_nonz(rswap.privBn) != 0 ) { len = basilisk_swapuserdata(userdata,zero,1,rswap.myprivs[0],redeemscript,redeemlen); - if ( (rswap.txbytes[BASILISK_ALICECLAIM]= basilisk_swap_bobtxspend(&signedtxid,rswap.Btxfee,"aliceclaim",rswap.bobcoin,bob->wiftaddr,bob->taddr,bob->pubtype,bob->p2shtype,bob->isPoS,bob->wiftype,ctx,rswap.myprivs[0],0,redeemscript,redeemlen,userdata,len,rswap.txids[BASILISK_BOBDEPOSIT],0,0,rswap.pubkey33,0,rswap.expiration,&rswap.values[BASILISK_ALICECLAIM],0,0,rswap.bobdepositaddr,1,bob->zcash)) != 0 ) + if ( (rswap.txbytes[BASILISK_ALICECLAIM]= basilisk_swap_bobtxspend(&signedtxid,rswap.Btxfee,"aliceclaim",rswap.bobcoin,bob->wiftaddr,bob->taddr,bob->pubtype,bob->p2shtype,bob->isPoS,bob->wiftype,ctx,rswap.myprivs[0],0,redeemscript,redeemlen,userdata,len,rswap.txids[BASILISK_BOBDEPOSIT],0,0,rswap.pubkey33,0,rswap.expiration+777,&rswap.values[BASILISK_ALICECLAIM],0,0,rswap.bobdepositaddr,1,bob->zcash)) != 0 ) printf("privBn.(%s) aliceclaim.(%s)\n",bits256_str(str,rswap.privBn),rswap.txbytes[BASILISK_ALICECLAIM]); } } @@ -1047,7 +1047,7 @@ cJSON *basilisk_remember(int64_t *KMDtotals,int64_t *BTCtotals,uint32_t requesti rswap.privBn = basilisk_swap_privBn_extract(&rswap.txids[BASILISK_BOBREFUND],rswap.bobcoin,rswap.txids[BASILISK_BOBDEPOSIT],rswap.privBn); if ( bits256_nonz(rswap.txids[BASILISK_ALICEPAYMENT]) != 0 && bits256_nonz(rswap.privAm) != 0 && bits256_nonz(rswap.privBn) != 0 ) { - if ( (rswap.txbytes[BASILISK_ALICERECLAIM]= basilisk_swap_Aspend("alicereclaim",rswap.alicecoin,rswap.Atxfee,alice->wiftaddr,alice->taddr,alice->pubtype,alice->p2shtype,alice->isPoS,alice->wiftype,ctx,rswap.privAm,rswap.privBn,rswap.txids[BASILISK_ALICEPAYMENT],0,rswap.pubkey33,rswap.expiration,&rswap.values[BASILISK_ALICERECLAIM],rswap.alicepaymentaddr,alice->zcash)) != 0 ) + if ( (rswap.txbytes[BASILISK_ALICERECLAIM]= basilisk_swap_Aspend("alicereclaim",rswap.alicecoin,rswap.Atxfee,alice->wiftaddr,alice->taddr,alice->pubtype,alice->p2shtype,alice->isPoS,alice->wiftype,ctx,rswap.privAm,rswap.privBn,rswap.txids[BASILISK_ALICEPAYMENT],0,rswap.pubkey33,rswap.expiration+777,&rswap.values[BASILISK_ALICERECLAIM],rswap.alicepaymentaddr,alice->zcash)) != 0 ) printf("privBn.(%s) alicereclaim.(%s)\n",bits256_str(str,rswap.privBn),rswap.txbytes[BASILISK_ALICERECLAIM]); } LP_txbytes_update("alicereclaim",rswap.alicecoin,rswap.txbytes[BASILISK_ALICERECLAIM],&rswap.txids[BASILISK_ALICERECLAIM],&rswap.Apaymentspent,&rswap.sentflags[BASILISK_ALICERECLAIM]); @@ -1077,7 +1077,7 @@ cJSON *basilisk_remember(int64_t *KMDtotals,int64_t *BTCtotals,uint32_t requesti } if ( bits256_nonz(rswap.privAm) != 0 && bits256_nonz(rswap.privBn) != 0 ) { - if ( (rswap.txbytes[BASILISK_BOBSPEND]= basilisk_swap_Aspend("bobspend",rswap.alicecoin,rswap.Atxfee,alice->wiftaddr,alice->taddr,alice->pubtype,alice->p2shtype,alice->isPoS,alice->wiftype,ctx,rswap.privAm,rswap.privBn,rswap.txids[BASILISK_ALICEPAYMENT],0,rswap.pubkey33,rswap.expiration,&rswap.values[BASILISK_BOBSPEND],rswap.alicepaymentaddr,alice->zcash)) != 0 ) + if ( (rswap.txbytes[BASILISK_BOBSPEND]= basilisk_swap_Aspend("bobspend",rswap.alicecoin,rswap.Atxfee,alice->wiftaddr,alice->taddr,alice->pubtype,alice->p2shtype,alice->isPoS,alice->wiftype,ctx,rswap.privAm,rswap.privBn,rswap.txids[BASILISK_ALICEPAYMENT],0,rswap.pubkey33,rswap.expiration+777,&rswap.values[BASILISK_BOBSPEND],rswap.alicepaymentaddr,alice->zcash)) != 0 ) printf("bobspend.(%s)\n",rswap.txbytes[BASILISK_BOBSPEND]); } LP_txbytes_update("bobspend",rswap.alicecoin,rswap.txbytes[BASILISK_BOBSPEND],&rswap.txids[BASILISK_BOBSPEND],&rswap.Apaymentspent,&rswap.sentflags[BASILISK_BOBSPEND]); @@ -1100,7 +1100,7 @@ cJSON *basilisk_remember(int64_t *KMDtotals,int64_t *BTCtotals,uint32_t requesti if ( redeemlen > 0 ) { len = basilisk_swapuserdata(userdata,zero,1,rswap.myprivs[1],redeemscript,redeemlen); - if ( (rswap.txbytes[BASILISK_BOBRECLAIM]= basilisk_swap_bobtxspend(&signedtxid,rswap.Btxfee,"bobrefund",rswap.bobcoin,bob->wiftaddr,bob->taddr,bob->pubtype,bob->p2shtype,bob->isPoS,bob->wiftype,ctx,rswap.myprivs[1],0,redeemscript,redeemlen,userdata,len,rswap.txids[BASILISK_BOBPAYMENT],0,0,rswap.pubkey33,0,rswap.expiration,&rswap.values[BASILISK_BOBRECLAIM],0,0,rswap.bobpaymentaddr,1,bob->zcash)) != 0 ) + if ( (rswap.txbytes[BASILISK_BOBRECLAIM]= basilisk_swap_bobtxspend(&signedtxid,rswap.Btxfee,"bobrefund",rswap.bobcoin,bob->wiftaddr,bob->taddr,bob->pubtype,bob->p2shtype,bob->isPoS,bob->wiftype,ctx,rswap.myprivs[1],0,redeemscript,redeemlen,userdata,len,rswap.txids[BASILISK_BOBPAYMENT],0,0,rswap.pubkey33,0,rswap.expiration+777,&rswap.values[BASILISK_BOBRECLAIM],0,0,rswap.bobpaymentaddr,1,bob->zcash)) != 0 ) { int32_t z; for (z=0; z<20; z++) @@ -1131,7 +1131,7 @@ cJSON *basilisk_remember(int64_t *KMDtotals,int64_t *BTCtotals,uint32_t requesti vcalc_sha256(0,rswap.secretBn256,rswap.privBn.bytes,sizeof(rswap.privBn)); redeemlen = basilisk_swap_bobredeemscript(1,&secretstart,redeemscript,rswap.dlocktime,rswap.pubA0,rswap.pubB0,rswap.pubB1,rswap.privAm,rswap.privBn,rswap.secretAm,rswap.secretAm256,rswap.secretBn,rswap.secretBn256); len = basilisk_swapuserdata(userdata,rswap.privBn,0,rswap.myprivs[0],redeemscript,redeemlen); - if ( (rswap.txbytes[BASILISK_BOBREFUND]= basilisk_swap_bobtxspend(&signedtxid,rswap.Btxfee,"bobrefund",rswap.bobcoin,bob->wiftaddr,bob->taddr,bob->pubtype,bob->p2shtype,bob->isPoS,bob->wiftype,ctx,rswap.myprivs[0],0,redeemscript,redeemlen,userdata,len,rswap.txids[BASILISK_BOBDEPOSIT],0,0,rswap.pubkey33,1,rswap.expiration,&rswap.values[BASILISK_BOBREFUND],0,0,rswap.bobdepositaddr,1,bob->zcash)) != 0 ) + if ( (rswap.txbytes[BASILISK_BOBREFUND]= basilisk_swap_bobtxspend(&signedtxid,rswap.Btxfee,"bobrefund",rswap.bobcoin,bob->wiftaddr,bob->taddr,bob->pubtype,bob->p2shtype,bob->isPoS,bob->wiftype,ctx,rswap.myprivs[0],0,redeemscript,redeemlen,userdata,len,rswap.txids[BASILISK_BOBDEPOSIT],0,0,rswap.pubkey33,1,rswap.expiration+777,&rswap.values[BASILISK_BOBREFUND],0,0,rswap.bobdepositaddr,1,bob->zcash)) != 0 ) 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]); From e984cc26db25459025b416e0fc308d4fae00930b Mon Sep 17 00:00:00 2001 From: jl777 Date: Sat, 9 Dec 2017 00:19:31 +0400 Subject: [PATCH 1634/1664] Test --- iguana/exchanges/LP_remember.c | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/iguana/exchanges/LP_remember.c b/iguana/exchanges/LP_remember.c index 46e0b0788..389c0c8d9 100644 --- a/iguana/exchanges/LP_remember.c +++ b/iguana/exchanges/LP_remember.c @@ -995,7 +995,7 @@ cJSON *basilisk_remember(int64_t *KMDtotals,int64_t *BTCtotals,uint32_t requesti } for (j=0; j<32; j++) rev.bytes[j] = rswap.myprivs[0].bytes[31 - j]; - if ( (rswap.txbytes[BASILISK_ALICESPEND]= basilisk_swap_bobtxspend(&signedtxid,rswap.Btxfee,"alicespend",rswap.bobcoin,bob->wiftaddr,bob->taddr,bob->pubtype,bob->p2shtype,bob->isPoS,bob->wiftype,ctx,rswap.myprivs[0],0,redeemscript,redeemlen,userdata,len,rswap.txids[BASILISK_BOBPAYMENT],0,0,rswap.pubkey33,1,rswap.expiration+777,&rswap.values[BASILISK_ALICESPEND],0,0,rswap.bobpaymentaddr,1,bob->zcash)) != 0 ) + if ( (rswap.txbytes[BASILISK_ALICESPEND]= basilisk_swap_bobtxspend(&signedtxid,rswap.Btxfee,"alicespend",rswap.bobcoin,bob->wiftaddr,bob->taddr,bob->pubtype,bob->p2shtype,bob->isPoS,bob->wiftype,ctx,rswap.myprivs[0],0,redeemscript,redeemlen,userdata,len,rswap.txids[BASILISK_BOBPAYMENT],0,0,rswap.pubkey33,1,rswap.expiration,&rswap.values[BASILISK_ALICESPEND],0,0,rswap.bobpaymentaddr,1,bob->zcash)) != 0 ) printf("alicespend.(%s)\n",rswap.txbytes[BASILISK_ALICESPEND]); } LP_txbytes_update("alicespend",rswap.bobcoin,rswap.txbytes[BASILISK_ALICESPEND],&rswap.txids[BASILISK_ALICESPEND],&rswap.paymentspent,&rswap.sentflags[BASILISK_ALICESPEND]); @@ -1025,7 +1025,7 @@ cJSON *basilisk_remember(int64_t *KMDtotals,int64_t *BTCtotals,uint32_t requesti if ( bits256_nonz(rswap.privBn) != 0 ) { len = basilisk_swapuserdata(userdata,zero,1,rswap.myprivs[0],redeemscript,redeemlen); - if ( (rswap.txbytes[BASILISK_ALICECLAIM]= basilisk_swap_bobtxspend(&signedtxid,rswap.Btxfee,"aliceclaim",rswap.bobcoin,bob->wiftaddr,bob->taddr,bob->pubtype,bob->p2shtype,bob->isPoS,bob->wiftype,ctx,rswap.myprivs[0],0,redeemscript,redeemlen,userdata,len,rswap.txids[BASILISK_BOBDEPOSIT],0,0,rswap.pubkey33,0,rswap.expiration+777,&rswap.values[BASILISK_ALICECLAIM],0,0,rswap.bobdepositaddr,1,bob->zcash)) != 0 ) + if ( (rswap.txbytes[BASILISK_ALICECLAIM]= basilisk_swap_bobtxspend(&signedtxid,rswap.Btxfee,"aliceclaim",rswap.bobcoin,bob->wiftaddr,bob->taddr,bob->pubtype,bob->p2shtype,bob->isPoS,bob->wiftype,ctx,rswap.myprivs[0],0,redeemscript,redeemlen,userdata,len,rswap.txids[BASILISK_BOBDEPOSIT],0,0,rswap.pubkey33,0,rswap.expiration,&rswap.values[BASILISK_ALICECLAIM],0,0,rswap.bobdepositaddr,1,bob->zcash)) != 0 ) printf("privBn.(%s) aliceclaim.(%s)\n",bits256_str(str,rswap.privBn),rswap.txbytes[BASILISK_ALICECLAIM]); } } @@ -1047,7 +1047,7 @@ cJSON *basilisk_remember(int64_t *KMDtotals,int64_t *BTCtotals,uint32_t requesti rswap.privBn = basilisk_swap_privBn_extract(&rswap.txids[BASILISK_BOBREFUND],rswap.bobcoin,rswap.txids[BASILISK_BOBDEPOSIT],rswap.privBn); if ( bits256_nonz(rswap.txids[BASILISK_ALICEPAYMENT]) != 0 && bits256_nonz(rswap.privAm) != 0 && bits256_nonz(rswap.privBn) != 0 ) { - if ( (rswap.txbytes[BASILISK_ALICERECLAIM]= basilisk_swap_Aspend("alicereclaim",rswap.alicecoin,rswap.Atxfee,alice->wiftaddr,alice->taddr,alice->pubtype,alice->p2shtype,alice->isPoS,alice->wiftype,ctx,rswap.privAm,rswap.privBn,rswap.txids[BASILISK_ALICEPAYMENT],0,rswap.pubkey33,rswap.expiration+777,&rswap.values[BASILISK_ALICERECLAIM],rswap.alicepaymentaddr,alice->zcash)) != 0 ) + if ( (rswap.txbytes[BASILISK_ALICERECLAIM]= basilisk_swap_Aspend("alicereclaim",rswap.alicecoin,rswap.Atxfee,alice->wiftaddr,alice->taddr,alice->pubtype,alice->p2shtype,alice->isPoS,alice->wiftype,ctx,rswap.privAm,rswap.privBn,rswap.txids[BASILISK_ALICEPAYMENT],0,rswap.pubkey33,rswap.expiration,&rswap.values[BASILISK_ALICERECLAIM],rswap.alicepaymentaddr,alice->zcash)) != 0 ) printf("privBn.(%s) alicereclaim.(%s)\n",bits256_str(str,rswap.privBn),rswap.txbytes[BASILISK_ALICERECLAIM]); } LP_txbytes_update("alicereclaim",rswap.alicecoin,rswap.txbytes[BASILISK_ALICERECLAIM],&rswap.txids[BASILISK_ALICERECLAIM],&rswap.Apaymentspent,&rswap.sentflags[BASILISK_ALICERECLAIM]); @@ -1077,7 +1077,7 @@ cJSON *basilisk_remember(int64_t *KMDtotals,int64_t *BTCtotals,uint32_t requesti } if ( bits256_nonz(rswap.privAm) != 0 && bits256_nonz(rswap.privBn) != 0 ) { - if ( (rswap.txbytes[BASILISK_BOBSPEND]= basilisk_swap_Aspend("bobspend",rswap.alicecoin,rswap.Atxfee,alice->wiftaddr,alice->taddr,alice->pubtype,alice->p2shtype,alice->isPoS,alice->wiftype,ctx,rswap.privAm,rswap.privBn,rswap.txids[BASILISK_ALICEPAYMENT],0,rswap.pubkey33,rswap.expiration+777,&rswap.values[BASILISK_BOBSPEND],rswap.alicepaymentaddr,alice->zcash)) != 0 ) + if ( (rswap.txbytes[BASILISK_BOBSPEND]= basilisk_swap_Aspend("bobspend",rswap.alicecoin,rswap.Atxfee,alice->wiftaddr,alice->taddr,alice->pubtype,alice->p2shtype,alice->isPoS,alice->wiftype,ctx,rswap.privAm,rswap.privBn,rswap.txids[BASILISK_ALICEPAYMENT],0,rswap.pubkey33,rswap.expiration,&rswap.values[BASILISK_BOBSPEND],rswap.alicepaymentaddr,alice->zcash)) != 0 ) printf("bobspend.(%s)\n",rswap.txbytes[BASILISK_BOBSPEND]); } LP_txbytes_update("bobspend",rswap.alicecoin,rswap.txbytes[BASILISK_BOBSPEND],&rswap.txids[BASILISK_BOBSPEND],&rswap.Apaymentspent,&rswap.sentflags[BASILISK_BOBSPEND]); @@ -1100,7 +1100,7 @@ cJSON *basilisk_remember(int64_t *KMDtotals,int64_t *BTCtotals,uint32_t requesti if ( redeemlen > 0 ) { len = basilisk_swapuserdata(userdata,zero,1,rswap.myprivs[1],redeemscript,redeemlen); - if ( (rswap.txbytes[BASILISK_BOBRECLAIM]= basilisk_swap_bobtxspend(&signedtxid,rswap.Btxfee,"bobrefund",rswap.bobcoin,bob->wiftaddr,bob->taddr,bob->pubtype,bob->p2shtype,bob->isPoS,bob->wiftype,ctx,rswap.myprivs[1],0,redeemscript,redeemlen,userdata,len,rswap.txids[BASILISK_BOBPAYMENT],0,0,rswap.pubkey33,0,rswap.expiration+777,&rswap.values[BASILISK_BOBRECLAIM],0,0,rswap.bobpaymentaddr,1,bob->zcash)) != 0 ) + if ( (rswap.txbytes[BASILISK_BOBRECLAIM]= basilisk_swap_bobtxspend(&signedtxid,rswap.Btxfee,"bobrefund",rswap.bobcoin,bob->wiftaddr,bob->taddr,bob->pubtype,bob->p2shtype,bob->isPoS,bob->wiftype,ctx,rswap.myprivs[1],0,redeemscript,redeemlen,userdata,len,rswap.txids[BASILISK_BOBPAYMENT],0,0,rswap.pubkey33,0,rswap.expiration,&rswap.values[BASILISK_BOBRECLAIM],0,0,rswap.bobpaymentaddr,1,bob->zcash)) != 0 ) { int32_t z; for (z=0; z<20; z++) @@ -1131,7 +1131,7 @@ cJSON *basilisk_remember(int64_t *KMDtotals,int64_t *BTCtotals,uint32_t requesti vcalc_sha256(0,rswap.secretBn256,rswap.privBn.bytes,sizeof(rswap.privBn)); redeemlen = basilisk_swap_bobredeemscript(1,&secretstart,redeemscript,rswap.dlocktime,rswap.pubA0,rswap.pubB0,rswap.pubB1,rswap.privAm,rswap.privBn,rswap.secretAm,rswap.secretAm256,rswap.secretBn,rswap.secretBn256); len = basilisk_swapuserdata(userdata,rswap.privBn,0,rswap.myprivs[0],redeemscript,redeemlen); - if ( (rswap.txbytes[BASILISK_BOBREFUND]= basilisk_swap_bobtxspend(&signedtxid,rswap.Btxfee,"bobrefund",rswap.bobcoin,bob->wiftaddr,bob->taddr,bob->pubtype,bob->p2shtype,bob->isPoS,bob->wiftype,ctx,rswap.myprivs[0],0,redeemscript,redeemlen,userdata,len,rswap.txids[BASILISK_BOBDEPOSIT],0,0,rswap.pubkey33,1,rswap.expiration+777,&rswap.values[BASILISK_BOBREFUND],0,0,rswap.bobdepositaddr,1,bob->zcash)) != 0 ) + if ( (rswap.txbytes[BASILISK_BOBREFUND]= basilisk_swap_bobtxspend(&signedtxid,rswap.Btxfee,"bobrefund",rswap.bobcoin,bob->wiftaddr,bob->taddr,bob->pubtype,bob->p2shtype,bob->isPoS,bob->wiftype,ctx,rswap.myprivs[0],0,redeemscript,redeemlen,userdata,len,rswap.txids[BASILISK_BOBDEPOSIT],0,0,rswap.pubkey33,1,rswap.expiration,&rswap.values[BASILISK_BOBREFUND],0,0,rswap.bobdepositaddr,1,bob->zcash)) != 0 ) 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]); From 4b5abbb4bff5efc1c298ed241ffdfde179b2a3cd Mon Sep 17 00:00:00 2001 From: jl777 Date: Sat, 9 Dec 2017 00:44:28 +0400 Subject: [PATCH 1635/1664] Test --- iguana/exchanges/LP_remember.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/iguana/exchanges/LP_remember.c b/iguana/exchanges/LP_remember.c index 389c0c8d9..013b385a6 100644 --- a/iguana/exchanges/LP_remember.c +++ b/iguana/exchanges/LP_remember.c @@ -1100,7 +1100,9 @@ cJSON *basilisk_remember(int64_t *KMDtotals,int64_t *BTCtotals,uint32_t requesti if ( redeemlen > 0 ) { len = basilisk_swapuserdata(userdata,zero,1,rswap.myprivs[1],redeemscript,redeemlen); - if ( (rswap.txbytes[BASILISK_BOBRECLAIM]= basilisk_swap_bobtxspend(&signedtxid,rswap.Btxfee,"bobrefund",rswap.bobcoin,bob->wiftaddr,bob->taddr,bob->pubtype,bob->p2shtype,bob->isPoS,bob->wiftype,ctx,rswap.myprivs[1],0,redeemscript,redeemlen,userdata,len,rswap.txids[BASILISK_BOBPAYMENT],0,0,rswap.pubkey33,0,rswap.expiration,&rswap.values[BASILISK_BOBRECLAIM],0,0,rswap.bobpaymentaddr,1,bob->zcash)) != 0 ) + uint32_t claimtime = (uint32_t)(time(NULL) - 777); + printf("claimtime %u vs expiration.%u\n",claimtime,rswap.expiration); + if ( (rswap.txbytes[BASILISK_BOBRECLAIM]= basilisk_swap_bobtxspend(&signedtxid,rswap.Btxfee,"bobrefund",rswap.bobcoin,bob->wiftaddr,bob->taddr,bob->pubtype,bob->p2shtype,bob->isPoS,bob->wiftype,ctx,rswap.myprivs[1],0,redeemscript,redeemlen,userdata,len,rswap.txids[BASILISK_BOBPAYMENT],0,0,rswap.pubkey33,0,claimtime,&rswap.values[BASILISK_BOBRECLAIM],0,0,rswap.bobpaymentaddr,1,bob->zcash)) != 0 ) { int32_t z; for (z=0; z<20; z++) From dece9786f146df5c78d9c4ec6fecf51ec2a50462 Mon Sep 17 00:00:00 2001 From: jl777 Date: Sat, 9 Dec 2017 09:30:52 +0400 Subject: [PATCH 1636/1664] Test --- iguana/exchanges/LP_nativeDEX.c | 6 +++--- iguana/exchanges/LP_remember.c | 4 +--- iguana/exchanges/LP_transaction.c | 4 ++-- 3 files changed, 6 insertions(+), 8 deletions(-) diff --git a/iguana/exchanges/LP_nativeDEX.c b/iguana/exchanges/LP_nativeDEX.c index 52ba08f12..5e320beff 100644 --- a/iguana/exchanges/LP_nativeDEX.c +++ b/iguana/exchanges/LP_nativeDEX.c @@ -19,18 +19,18 @@ // // fundvalue -> autoprice, cmc +margin -> autoprice, signals -> autoprice // https://github.com/bitcoin/bips/blob/master/bip-0143.mediawiki for signing BCH/BTG -// there is an issue about waiting for notarization for a swap that never starts -// use electrum in case of addr change in swap // // compress packets // portfolio to set prices from historical // portfolio value based on ask? // // else claim path -// swap memleak? // 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 +// use electrum in case of addr change in swap +// locktime claiming on sporadic assetchains +// there is an issue about waiting for notarization for a swap that never starts #include diff --git a/iguana/exchanges/LP_remember.c b/iguana/exchanges/LP_remember.c index 013b385a6..389c0c8d9 100644 --- a/iguana/exchanges/LP_remember.c +++ b/iguana/exchanges/LP_remember.c @@ -1100,9 +1100,7 @@ cJSON *basilisk_remember(int64_t *KMDtotals,int64_t *BTCtotals,uint32_t requesti if ( redeemlen > 0 ) { len = basilisk_swapuserdata(userdata,zero,1,rswap.myprivs[1],redeemscript,redeemlen); - uint32_t claimtime = (uint32_t)(time(NULL) - 777); - printf("claimtime %u vs expiration.%u\n",claimtime,rswap.expiration); - if ( (rswap.txbytes[BASILISK_BOBRECLAIM]= basilisk_swap_bobtxspend(&signedtxid,rswap.Btxfee,"bobrefund",rswap.bobcoin,bob->wiftaddr,bob->taddr,bob->pubtype,bob->p2shtype,bob->isPoS,bob->wiftype,ctx,rswap.myprivs[1],0,redeemscript,redeemlen,userdata,len,rswap.txids[BASILISK_BOBPAYMENT],0,0,rswap.pubkey33,0,claimtime,&rswap.values[BASILISK_BOBRECLAIM],0,0,rswap.bobpaymentaddr,1,bob->zcash)) != 0 ) + if ( (rswap.txbytes[BASILISK_BOBRECLAIM]= basilisk_swap_bobtxspend(&signedtxid,rswap.Btxfee,"bobrefund",rswap.bobcoin,bob->wiftaddr,bob->taddr,bob->pubtype,bob->p2shtype,bob->isPoS,bob->wiftype,ctx,rswap.myprivs[1],0,redeemscript,redeemlen,userdata,len,rswap.txids[BASILISK_BOBPAYMENT],0,0,rswap.pubkey33,0,rswap.expiration,&rswap.values[BASILISK_BOBRECLAIM],0,0,rswap.bobpaymentaddr,1,bob->zcash)) != 0 ) { int32_t z; for (z=0; z<20; z++) diff --git a/iguana/exchanges/LP_transaction.c b/iguana/exchanges/LP_transaction.c index 8461474ba..566d7b250 100644 --- a/iguana/exchanges/LP_transaction.c +++ b/iguana/exchanges/LP_transaction.c @@ -1660,7 +1660,7 @@ bits256 LP_swap_spendtxid(char *symbol,char *destaddr,bits256 utxotxid,int32_t u memset(&spendtxid,0,sizeof(spendtxid)); if ( LP_spendsearch(destaddr,&spendtxid,&spendvin,symbol,utxotxid,utxovout) > 0 ) { - //printf("spend of %s/v%d detected\n",bits256_str(str,utxotxid),vout); + char str[65]; printf("spend of %s/v%d detected\n",bits256_str(str,utxotxid),utxovout); } else if ( (coin= LP_coinfind(symbol)) != 0 && coin->electrum == 0 ) { @@ -1675,7 +1675,7 @@ bits256 LP_swap_spendtxid(char *symbol,char *destaddr,bits256 utxotxid,int32_t u { if ( (vins= jarray(&m,txobj,"vin")) != 0 ) { - //printf("vins.(%s)\n",jprint(vins,0)); +printf("vins.(%s)\n",jprint(vins,0)); if ( utxovout < m ) { vin = jitem(vins,utxovout); From 1c0815ab1ab01210e49e75a52c53404debe6f437 Mon Sep 17 00:00:00 2001 From: jl777 Date: Sat, 9 Dec 2017 09:37:11 +0400 Subject: [PATCH 1637/1664] Test --- iguana/exchanges/LP_remember.c | 2 ++ iguana/exchanges/LP_transaction.c | 4 ++-- 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/iguana/exchanges/LP_remember.c b/iguana/exchanges/LP_remember.c index 389c0c8d9..086528f03 100644 --- a/iguana/exchanges/LP_remember.c +++ b/iguana/exchanges/LP_remember.c @@ -375,6 +375,8 @@ int32_t basilisk_swap_isfinished(int32_t iambob,bits256 *txids,int32_t *sentflag } else if ( bits256_nonz(Apaymentspent) != 0 ) return(1); + else if ( bits256_nonz(paymentspent) != 0 && bits256_nonz(depositspent) != 0 ) + return(1); } else { diff --git a/iguana/exchanges/LP_transaction.c b/iguana/exchanges/LP_transaction.c index 566d7b250..4f458beff 100644 --- a/iguana/exchanges/LP_transaction.c +++ b/iguana/exchanges/LP_transaction.c @@ -1660,7 +1660,7 @@ bits256 LP_swap_spendtxid(char *symbol,char *destaddr,bits256 utxotxid,int32_t u memset(&spendtxid,0,sizeof(spendtxid)); if ( LP_spendsearch(destaddr,&spendtxid,&spendvin,symbol,utxotxid,utxovout) > 0 ) { - char str[65]; printf("spend of %s/v%d detected\n",bits256_str(str,utxotxid),utxovout); + //char str[65]; printf("spend of %s/v%d detected\n",bits256_str(str,utxotxid),utxovout); } else if ( (coin= LP_coinfind(symbol)) != 0 && coin->electrum == 0 ) { @@ -1675,7 +1675,7 @@ bits256 LP_swap_spendtxid(char *symbol,char *destaddr,bits256 utxotxid,int32_t u { if ( (vins= jarray(&m,txobj,"vin")) != 0 ) { -printf("vins.(%s)\n",jprint(vins,0)); +//printf("vins.(%s)\n",jprint(vins,0)); if ( utxovout < m ) { vin = jitem(vins,utxovout); From d1f30b81e9e8ab9cb0c647a81f63dcabfb3b8554 Mon Sep 17 00:00:00 2001 From: jl777 Date: Sat, 9 Dec 2017 09:40:43 +0400 Subject: [PATCH 1638/1664] Test --- iguana/exchanges/LP_remember.c | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/iguana/exchanges/LP_remember.c b/iguana/exchanges/LP_remember.c index 086528f03..447f577cb 100644 --- a/iguana/exchanges/LP_remember.c +++ b/iguana/exchanges/LP_remember.c @@ -900,7 +900,12 @@ cJSON *basilisk_remember(int64_t *KMDtotals,int64_t *BTCtotals,uint32_t requesti if ( rswap.bobcoin[0] == 0 || rswap.alicecoin[0] == 0 || strcmp(rswap.bobcoin,rswap.src) != 0 || strcmp(rswap.alicecoin,rswap.dest) != 0 ) { //printf("legacy r%u-q%u DB SWAPS.(%u %u) %llu files BOB.(%s) Alice.(%s) src.(%s) dest.(%s)\n",requestid,quoteid,rswap.requestid,rswap.quoteid,(long long)rswap.aliceid,rswap.bobcoin,rswap.alicecoin,rswap.src,rswap.dest); - return(cJSON_Parse("{\"error\":\"mismatched bob/alice vs src/dest coins??\"}")); + cJSON *retjson = cJSON_CreateObject(); + jaddstr(retjson,"error","swap never started"); + jaddnum(retjson,"requestid",requestid); + jaddnum(retjson,"quoteid",quoteid); + return(retjson); + //return(cJSON_Parse("{\"error\":\"mismatched bob/alice vs src/dest coins??\"}")); } alice = LP_coinfind(rswap.alicecoin); bob = LP_coinfind(rswap.bobcoin); From 17e0e1b89e3e4a5d25e21b4ef07149af1eb7513b Mon Sep 17 00:00:00 2001 From: jl777 Date: Sat, 9 Dec 2017 12:16:48 +0400 Subject: [PATCH 1639/1664] Test --- iguana/exchanges/LP_commands.c | 2 +- iguana/exchanges/LP_include.h | 1 + iguana/exchanges/LP_portfolio.c | 160 +++++++++++++++++++------------- iguana/exchanges/LP_remember.c | 2 +- 4 files changed, 98 insertions(+), 67 deletions(-) diff --git a/iguana/exchanges/LP_commands.c b/iguana/exchanges/LP_commands.c index bdc0060f5..dd87341eb 100644 --- a/iguana/exchanges/LP_commands.c +++ b/iguana/exchanges/LP_commands.c @@ -321,7 +321,7 @@ instantdex_claim()\n\ double price,bid,ask; if ( strcmp(method,"autoprice") == 0 ) { - if ( LP_autoprice(base,rel,argjson) < 0 ) + if ( LP_autoprice(ctx,base,rel,argjson) < 0 ) return(clonestr("{\"error\":\"couldnt set autoprice\"}")); else return(clonestr("{\"result\":\"success\"}")); } diff --git a/iguana/exchanges/LP_include.h b/iguana/exchanges/LP_include.h index 82b3a29ce..57616a77b 100644 --- a/iguana/exchanges/LP_include.h +++ b/iguana/exchanges/LP_include.h @@ -517,6 +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(); +double LP_CMCbtcprice(double *price_usdp,char *symbol); 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); diff --git a/iguana/exchanges/LP_portfolio.c b/iguana/exchanges/LP_portfolio.c index cf11dbe17..68d5d82cd 100644 --- a/iguana/exchanges/LP_portfolio.c +++ b/iguana/exchanges/LP_portfolio.c @@ -18,6 +18,14 @@ // marketmaker // + +struct LP_autoprice_ref +{ + char refbase[65],refrel[65],base[65],rel[65]; + double margin; +} LP_autorefs[100]; + +int32_t LP_autoprices,num_LP_autorefs; char LP_portfolio_base[128],LP_portfolio_rel[128]; double LP_portfolio_relvolume; @@ -201,13 +209,6 @@ char *LP_portfolio_goal(char *symbol,double goal) } else return(clonestr("{\"error\":\"cant set goal for inactive coin\"}")); } -int32_t LP_autoprices,num_LP_autorefs; - -struct LP_autoprice_ref -{ - char refbase[65],refrel[65],base[65],rel[65]; -} LP_autorefs[100]; - /*int32_t LP_autofill(char *base,char *rel,double maxprice,double totalrelvolume) { struct LP_priceinfo *basepp,*relpp; @@ -221,58 +222,6 @@ struct LP_autoprice_ref return(-1); }*/ -int32_t LP_autoprice(char *base,char *rel,cJSON *argjson) -{ - //curl --url "http://127.0.0.1:7783" --data "{\"userpass\":\"$userpass\",\"method\":\"autoprice\",\"base\":\"MNZ\",\"rel\":\"KMD\",\"offset\":0.1,\"refbase\":\"KMD\",\refrel\":\"BTC\",\"factor\":15000,\"margin\":0.01}" - struct LP_priceinfo *basepp,*relpp; int32_t i; char *refbase="",*refrel=""; double minprice,margin,offset,factor,fixedprice; - //printf("autoprice.(%s %s) %s\n",base,rel,jprint(argjson,0)); - if ( (basepp= LP_priceinfofind(base)) != 0 && (relpp= LP_priceinfofind(rel)) != 0 ) - { - if ( jobj(argjson,"minprice") != 0 ) - minprice = jdouble(argjson,"minprice"); - else minprice = 0.; - margin = jdouble(argjson,"margin"); - offset = jdouble(argjson,"offset"); - factor = jdouble(argjson,"factor"); - fixedprice = jdouble(argjson,"fixed"); - basepp->fixedprices[relpp->ind] = fixedprice; - basepp->minprices[relpp->ind] = minprice; - basepp->margins[relpp->ind] = margin; - basepp->offsets[relpp->ind] = offset; - basepp->factors[relpp->ind] = factor; - if ( fixedprice > SMALLVAL || ((refbase= jstr(argjson,"refbase")) != 0 && (refrel= jstr(argjson,"refrel")) != 0) ) - { - if ( fixedprice > SMALLVAL ) - { - refbase = base; - refrel = rel; - } - for (i=0; ifixedprices[basepp->ind],basepp->fixedprices[relpp->ind]); - LP_autopriceset(ctx,1,basepp,relpp,0.,LP_autorefs[i].refbase,LP_autorefs[i].refrel); + rel = LP_autorefs[i].rel; + base = LP_autorefs[i].base; + margin = LP_autorefs[i].margin; + printf("%s/%s for %s/%s margin %.8f\n",base,rel,LP_autorefs[i].refbase,LP_autorefs[i].refrel,margin); + if ( (price_btc= LP_CMCbtcprice(&price_usd,LP_autorefs[i].refbase)) > SMALLVAL ) + { + if ( strcmp(rel,"KMD") == 0 ) + price = price_btc / kmd_btc; + else if ( strcmp(rel,"BTC") == 0 ) + price = price_btc; + else continue; + newprice = (price * (1. + margin)); + LP_mypriceset(&changed,rel,base,newprice); + LP_pricepings(ctx,LP_myipaddr,LP_mypubsock,rel,base,newprice); + printf("price %.8f margin %.8f newprice %.8f %.8f\n",price,margin,newprice,(1. / price) * (1. + margin)); + newprice = (1. / price) * (1. + margin); + LP_mypriceset(&changed,base,rel,newprice); + LP_pricepings(ctx,LP_myipaddr,LP_mypubsock,base,rel,newprice); + } } + else + { + basepp = LP_priceinfofind(LP_autorefs[i].base); + relpp = LP_priceinfofind(LP_autorefs[i].rel); + if ( basepp != 0 && relpp != 0 ) + { + //printf("check ref-autoprice %s/%s %f %f\n",LP_autorefs[i].refbase,LP_autorefs[i].refrel,relpp->fixedprices[basepp->ind],basepp->fixedprices[relpp->ind]); + LP_autopriceset(ctx,1,basepp,relpp,0.,LP_autorefs[i].refbase,LP_autorefs[i].refrel); + } + } + } +} + +int32_t LP_autoprice(void *ctx,char *base,char *rel,cJSON *argjson) +{ + //curl --url "http://127.0.0.1:7783" --data "{\"userpass\":\"$userpass\",\"method\":\"autoprice\",\"base\":\"MNZ\",\"rel\":\"KMD\",\"offset\":0.1,\"refbase\":\"KMD\",\refrel\":\"BTC\",\"factor\":15000,\"margin\":0.01}" + struct LP_priceinfo *basepp,*relpp; int32_t i,retval = -1; char *refbase="",*refrel=""; double minprice,margin,offset,factor,fixedprice; + //printf("autoprice.(%s %s) %s\n",base,rel,jprint(argjson,0)); + if ( (basepp= LP_priceinfofind(base)) != 0 && (relpp= LP_priceinfofind(rel)) != 0 ) + { + if ( jobj(argjson,"minprice") != 0 ) + minprice = jdouble(argjson,"minprice"); + else minprice = 0.; + margin = jdouble(argjson,"margin"); + offset = jdouble(argjson,"offset"); + factor = jdouble(argjson,"factor"); + fixedprice = jdouble(argjson,"fixed"); + basepp->fixedprices[relpp->ind] = fixedprice; + basepp->minprices[relpp->ind] = minprice; + basepp->margins[relpp->ind] = margin; + basepp->offsets[relpp->ind] = offset; + basepp->factors[relpp->ind] = factor; + if ( fixedprice > SMALLVAL || ((refbase= jstr(argjson,"refbase")) != 0 && (refrel= jstr(argjson,"refrel")) != 0) ) + { + if ( fixedprice > SMALLVAL ) + { + refbase = base; + refrel = rel; + } + for (i=0; i Date: Sat, 9 Dec 2017 12:21:24 +0400 Subject: [PATCH 1640/1664] Test --- iguana/exchanges/LP_portfolio.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/iguana/exchanges/LP_portfolio.c b/iguana/exchanges/LP_portfolio.c index 68d5d82cd..2b8aae9d7 100644 --- a/iguana/exchanges/LP_portfolio.c +++ b/iguana/exchanges/LP_portfolio.c @@ -444,11 +444,11 @@ void LP_autoprice_iter(void *ctx,struct LP_priceinfo *btcpp) else continue; newprice = (price * (1. + margin)); LP_mypriceset(&changed,rel,base,newprice); - LP_pricepings(ctx,LP_myipaddr,LP_mypubsock,rel,base,newprice); + LP_pricepings(ctx,LP_myipaddr,LP_mypubsock,base,rel,newprice); printf("price %.8f margin %.8f newprice %.8f %.8f\n",price,margin,newprice,(1. / price) * (1. + margin)); newprice = (1. / price) * (1. + margin); LP_mypriceset(&changed,base,rel,newprice); - LP_pricepings(ctx,LP_myipaddr,LP_mypubsock,base,rel,newprice); + LP_pricepings(ctx,LP_myipaddr,LP_mypubsock,rel,base,newprice); } } else From f3570cba116dacf68eaf307e24cb3b3bc1e78457 Mon Sep 17 00:00:00 2001 From: jl777 Date: Sat, 9 Dec 2017 12:33:39 +0400 Subject: [PATCH 1641/1664] Test --- iguana/exchanges/LP_portfolio.c | 14 +++++++++++--- iguana/exchanges/LP_prices.c | 4 ++-- iguana/exchanges/auto_chipsbtc | 2 ++ iguana/exchanges/auto_chipskmd | 2 ++ iguana/exchanges/install | 2 +- 5 files changed, 18 insertions(+), 6 deletions(-) create mode 100755 iguana/exchanges/auto_chipsbtc create mode 100755 iguana/exchanges/auto_chipskmd diff --git a/iguana/exchanges/LP_portfolio.c b/iguana/exchanges/LP_portfolio.c index 2b8aae9d7..cea19a4bb 100644 --- a/iguana/exchanges/LP_portfolio.c +++ b/iguana/exchanges/LP_portfolio.c @@ -22,7 +22,7 @@ struct LP_autoprice_ref { char refbase[65],refrel[65],base[65],rel[65]; - double margin; + double margin,factor,offset; } LP_autorefs[100]; int32_t LP_autoprices,num_LP_autorefs; @@ -367,7 +367,7 @@ double LP_pricesparse(void *ctx,int32_t trexflag,char *retstr,struct LP_priceinf void LP_autoprice_iter(void *ctx,struct LP_priceinfo *btcpp) { - char *retstr,*base,*rel; cJSON *retjson,*bid,*ask; uint64_t bidsatoshis,asksatoshis; int32_t i,changed; double nxtkmd,price,newprice,margin,price_btc,price_usd,kmd_btc,kmd_usd; struct LP_priceinfo *kmdpp,*fiatpp,*nxtpp,*basepp,*relpp; + char *retstr,*base,*rel; cJSON *retjson,*bid,*ask; uint64_t bidsatoshis,asksatoshis; int32_t i,changed; double nxtkmd,price,factor,offset,newprice,margin,price_btc,price_usd,kmd_btc,kmd_usd; struct LP_priceinfo *kmdpp,*fiatpp,*nxtpp,*basepp,*relpp; if ( (retstr= issue_curlt("https://bittrex.com/api/v1.1/public/getmarketsummaries",LP_HTTP_TIMEOUT*10)) == 0 ) { printf("trex error getting marketsummaries\n"); @@ -434,6 +434,8 @@ void LP_autoprice_iter(void *ctx,struct LP_priceinfo *btcpp) rel = LP_autorefs[i].rel; base = LP_autorefs[i].base; margin = LP_autorefs[i].margin; + offset = LP_autorefs[i].offset; + factor = LP_autorefs[i].factor; printf("%s/%s for %s/%s margin %.8f\n",base,rel,LP_autorefs[i].refbase,LP_autorefs[i].refrel,margin); if ( (price_btc= LP_CMCbtcprice(&price_usd,LP_autorefs[i].refbase)) > SMALLVAL ) { @@ -442,6 +444,8 @@ void LP_autoprice_iter(void *ctx,struct LP_priceinfo *btcpp) else if ( strcmp(rel,"BTC") == 0 ) price = price_btc; else continue; + if ( factor > 0. ) + price = (price * factor) + offset; newprice = (price * (1. + margin)); LP_mypriceset(&changed,rel,base,newprice); LP_pricepings(ctx,LP_myipaddr,LP_mypubsock,base,rel,newprice); @@ -495,6 +499,8 @@ int32_t LP_autoprice(void *ctx,char *base,char *rel,cJSON *argjson) if ( strcmp(base,LP_autorefs[i].base) == 0 && strcmp(rel,LP_autorefs[i].rel) == 0 ) { LP_autorefs[i].margin = margin; + LP_autorefs[i].factor = factor; + LP_autorefs[i].offset = offset; safecopy(LP_autorefs[i].refbase,refbase,sizeof(LP_autorefs[i].refbase)); safecopy(LP_autorefs[i].refrel,refrel,sizeof(LP_autorefs[i].refrel)); printf("%d Update ref %s/%s for %s/%s factor %.8f offset %.8f\n",i,refbase,refrel,base,rel,factor,offset); @@ -504,6 +510,8 @@ int32_t LP_autoprice(void *ctx,char *base,char *rel,cJSON *argjson) if ( i == num_LP_autorefs && num_LP_autorefs < sizeof(LP_autorefs)/sizeof(*LP_autorefs) ) { LP_autorefs[num_LP_autorefs].margin = margin; + LP_autorefs[num_LP_autorefs].factor = factor; + LP_autorefs[num_LP_autorefs].offset = offset; safecopy(LP_autorefs[num_LP_autorefs].refbase,refbase,sizeof(LP_autorefs[num_LP_autorefs].refbase)); safecopy(LP_autorefs[num_LP_autorefs].refrel,refrel,sizeof(LP_autorefs[num_LP_autorefs].refrel)); safecopy(LP_autorefs[num_LP_autorefs].base,base,sizeof(LP_autorefs[num_LP_autorefs].base)); @@ -515,7 +523,7 @@ int32_t LP_autoprice(void *ctx,char *base,char *rel,cJSON *argjson) LP_autoprices++; retval = 0; } - LP_autoprice_iter(ctx,LP_priceinfofind("BTC")); + //LP_autoprice_iter(ctx,LP_priceinfofind("BTC")); return(retval); } diff --git a/iguana/exchanges/LP_prices.c b/iguana/exchanges/LP_prices.c index 9c8c7f204..7744ed1a6 100644 --- a/iguana/exchanges/LP_prices.c +++ b/iguana/exchanges/LP_prices.c @@ -915,8 +915,8 @@ int64_t LP_KMDvalue(struct iguana_info *coin,int64_t balance) KMDvalue = balance; else { - price = LP_price(coin->symbol,"KMD"); - KMDvalue = price * balance; + if ( (price= LP_price(coin->symbol,"KMD")) > SMALLVAL ) + KMDvalue = price * balance; } } return(KMDvalue); diff --git a/iguana/exchanges/auto_chipsbtc b/iguana/exchanges/auto_chipsbtc new file mode 100755 index 000000000..c45fffe5d --- /dev/null +++ b/iguana/exchanges/auto_chipsbtc @@ -0,0 +1,2 @@ +source userpass +curl --url "http://127.0.0.1:7783" --data "{\"userpass\":\"$userpass\",\"method\":\"autoprice\",\"base\":\"CHIPS\",\"rel\":\"BTC\",\"margin\":0.01,\"refbase\":\"chips\",\"refrel\":\"coinmarketcap\"}" diff --git a/iguana/exchanges/auto_chipskmd b/iguana/exchanges/auto_chipskmd new file mode 100755 index 000000000..10f7874c0 --- /dev/null +++ b/iguana/exchanges/auto_chipskmd @@ -0,0 +1,2 @@ +source userpass +curl --url "http://127.0.0.1:7783" --data "{\"userpass\":\"$userpass\",\"method\":\"autoprice\",\"base\":\"CHIPS\",\"rel\":\"KMD\",\"margin\":0.01,\"refbase\":\"chips\",\"refrel\":\"coinmarketcap\"}" diff --git a/iguana/exchanges/install b/iguana/exchanges/install index c891b0d7f..cbf46ca5f 100755 --- a/iguana/exchanges/install +++ b/iguana/exchanges/install @@ -1,5 +1,5 @@ #!/bin/bash -cp pendingswaps fundvalue balances dynamictrust getcoin kickstart tradesarray claim deposit10 deposit1 invreset sendrawtransaction processfiles stop millis mnzservers bot_buy bot_list bot_statuslist bot_pause bot_resume bot_sell bot_settings bot_status bot_stop guistats pubkeystats pendings coinswaps baserelswaps setpassphrase notarizations getrawtransaction parselog statsdisp m_js 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 auto_chipskmd auto_chipsbtc pendingswaps fundvalue balances dynamictrust getcoin kickstart tradesarray claim deposit10 deposit1 invreset sendrawtransaction processfiles stop millis mnzservers bot_buy bot_list bot_statuslist bot_pause bot_resume bot_sell bot_settings bot_status bot_stop guistats pubkeystats pendings coinswaps baserelswaps setpassphrase notarizations getrawtransaction parselog statsdisp m_js 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 . From 578cff2c6eb74178f327f973ecbc568c11670115 Mon Sep 17 00:00:00 2001 From: jl777 Date: Sat, 9 Dec 2017 12:41:53 +0400 Subject: [PATCH 1642/1664] Test --- iguana/exchanges/LP_nativeDEX.c | 2 +- iguana/exchanges/LP_portfolio.c | 9 ++++----- 2 files changed, 5 insertions(+), 6 deletions(-) diff --git a/iguana/exchanges/LP_nativeDEX.c b/iguana/exchanges/LP_nativeDEX.c index 5e320beff..f6fb7ded6 100644 --- a/iguana/exchanges/LP_nativeDEX.c +++ b/iguana/exchanges/LP_nativeDEX.c @@ -17,7 +17,7 @@ // LP_nativeDEX.c // marketmaker // -// fundvalue -> autoprice, cmc +margin -> autoprice, signals -> autoprice +// fundvalue -> autoprice, signals -> autoprice // https://github.com/bitcoin/bips/blob/master/bip-0143.mediawiki for signing BCH/BTG // // compress packets diff --git a/iguana/exchanges/LP_portfolio.c b/iguana/exchanges/LP_portfolio.c index cea19a4bb..3bbc44932 100644 --- a/iguana/exchanges/LP_portfolio.c +++ b/iguana/exchanges/LP_portfolio.c @@ -18,6 +18,7 @@ // marketmaker // +struct LP_portfoliotrade { double metric; char buycoin[65],sellcoin[65]; }; struct LP_autoprice_ref { @@ -436,11 +437,11 @@ void LP_autoprice_iter(void *ctx,struct LP_priceinfo *btcpp) margin = LP_autorefs[i].margin; offset = LP_autorefs[i].offset; factor = LP_autorefs[i].factor; - printf("%s/%s for %s/%s margin %.8f\n",base,rel,LP_autorefs[i].refbase,LP_autorefs[i].refrel,margin); + //printf("%s/%s for %s/%s margin %.8f\n",base,rel,LP_autorefs[i].refbase,LP_autorefs[i].refrel,margin); if ( (price_btc= LP_CMCbtcprice(&price_usd,LP_autorefs[i].refbase)) > SMALLVAL ) { if ( strcmp(rel,"KMD") == 0 ) - price = price_btc / kmd_btc; + price = kmd_btc / price_btc; else if ( strcmp(rel,"BTC") == 0 ) price = price_btc; else continue; @@ -449,7 +450,7 @@ void LP_autoprice_iter(void *ctx,struct LP_priceinfo *btcpp) newprice = (price * (1. + margin)); LP_mypriceset(&changed,rel,base,newprice); LP_pricepings(ctx,LP_myipaddr,LP_mypubsock,base,rel,newprice); - printf("price %.8f margin %.8f newprice %.8f %.8f\n",price,margin,newprice,(1. / price) * (1. + margin)); + //printf("price %.8f margin %.8f newprice %.8f %.8f\n",price,margin,newprice,(1. / price) * (1. + margin)); newprice = (1. / price) * (1. + margin); LP_mypriceset(&changed,base,rel,newprice); LP_pricepings(ctx,LP_myipaddr,LP_mypubsock,rel,base,newprice); @@ -596,8 +597,6 @@ int32_t LP_portfolio_trade(void *ctx,uint32_t *requestidp,uint32_t *quoteidp,str else return(-1); } -struct LP_portfoliotrade { double metric; char buycoin[65],sellcoin[65]; }; - int32_t LP_portfolio_order(struct LP_portfoliotrade *trades,int32_t max,cJSON *array) { int32_t i,j,m,n = 0; cJSON *item; struct LP_portfoliotrade coins[256]; From d6d1cecf6a556b02600ca50f45b3a1daa6e2041b Mon Sep 17 00:00:00 2001 From: jl777 Date: Sat, 9 Dec 2017 12:49:33 +0400 Subject: [PATCH 1643/1664] Test --- iguana/exchanges/LP_portfolio.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/iguana/exchanges/LP_portfolio.c b/iguana/exchanges/LP_portfolio.c index 3bbc44932..dd096cbe7 100644 --- a/iguana/exchanges/LP_portfolio.c +++ b/iguana/exchanges/LP_portfolio.c @@ -441,7 +441,7 @@ void LP_autoprice_iter(void *ctx,struct LP_priceinfo *btcpp) if ( (price_btc= LP_CMCbtcprice(&price_usd,LP_autorefs[i].refbase)) > SMALLVAL ) { if ( strcmp(rel,"KMD") == 0 ) - price = kmd_btc / price_btc; + price = price_btc / kmd_btc; else if ( strcmp(rel,"BTC") == 0 ) price = price_btc; else continue; From 9ed61c997c8186bfa2b15b7d34bede0a44437b1f Mon Sep 17 00:00:00 2001 From: jl777 Date: Sat, 9 Dec 2017 12:53:51 +0400 Subject: [PATCH 1644/1664] Test --- iguana/exchanges/LP_portfolio.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/iguana/exchanges/LP_portfolio.c b/iguana/exchanges/LP_portfolio.c index dd096cbe7..a47148f01 100644 --- a/iguana/exchanges/LP_portfolio.c +++ b/iguana/exchanges/LP_portfolio.c @@ -441,7 +441,7 @@ void LP_autoprice_iter(void *ctx,struct LP_priceinfo *btcpp) if ( (price_btc= LP_CMCbtcprice(&price_usd,LP_autorefs[i].refbase)) > SMALLVAL ) { if ( strcmp(rel,"KMD") == 0 ) - price = price_btc / kmd_btc; + price = kmd_btc / price_btc; else if ( strcmp(rel,"BTC") == 0 ) price = price_btc; else continue; @@ -450,7 +450,7 @@ void LP_autoprice_iter(void *ctx,struct LP_priceinfo *btcpp) newprice = (price * (1. + margin)); LP_mypriceset(&changed,rel,base,newprice); LP_pricepings(ctx,LP_myipaddr,LP_mypubsock,base,rel,newprice); - //printf("price %.8f margin %.8f newprice %.8f %.8f\n",price,margin,newprice,(1. / price) * (1. + margin)); + printf("price %.8f margin %.8f newprice %.8f %.8f\n",price,margin,newprice,(1. / price) * (1. + margin)); newprice = (1. / price) * (1. + margin); LP_mypriceset(&changed,base,rel,newprice); LP_pricepings(ctx,LP_myipaddr,LP_mypubsock,rel,base,newprice); From 2a936045e05d57a33dda8dfdad07332b8573d9a9 Mon Sep 17 00:00:00 2001 From: jl777 Date: Sat, 9 Dec 2017 12:56:52 +0400 Subject: [PATCH 1645/1664] Test --- iguana/exchanges/LP_portfolio.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/iguana/exchanges/LP_portfolio.c b/iguana/exchanges/LP_portfolio.c index a47148f01..09ce7e220 100644 --- a/iguana/exchanges/LP_portfolio.c +++ b/iguana/exchanges/LP_portfolio.c @@ -449,11 +449,11 @@ void LP_autoprice_iter(void *ctx,struct LP_priceinfo *btcpp) price = (price * factor) + offset; newprice = (price * (1. + margin)); LP_mypriceset(&changed,rel,base,newprice); - LP_pricepings(ctx,LP_myipaddr,LP_mypubsock,base,rel,newprice); + LP_pricepings(ctx,LP_myipaddr,LP_mypubsock,rel,base,newprice); printf("price %.8f margin %.8f newprice %.8f %.8f\n",price,margin,newprice,(1. / price) * (1. + margin)); newprice = (1. / price) * (1. + margin); LP_mypriceset(&changed,base,rel,newprice); - LP_pricepings(ctx,LP_myipaddr,LP_mypubsock,rel,base,newprice); + LP_pricepings(ctx,LP_myipaddr,LP_mypubsock,base,rel,newprice); } } else From 6cb8256e21f94e0b90f84d1934593db510829c7c Mon Sep 17 00:00:00 2001 From: jl777 Date: Sat, 9 Dec 2017 13:01:01 +0400 Subject: [PATCH 1646/1664] Test --- iguana/exchanges/LP_portfolio.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/iguana/exchanges/LP_portfolio.c b/iguana/exchanges/LP_portfolio.c index 09ce7e220..63cd8d45d 100644 --- a/iguana/exchanges/LP_portfolio.c +++ b/iguana/exchanges/LP_portfolio.c @@ -443,7 +443,7 @@ void LP_autoprice_iter(void *ctx,struct LP_priceinfo *btcpp) if ( strcmp(rel,"KMD") == 0 ) price = kmd_btc / price_btc; else if ( strcmp(rel,"BTC") == 0 ) - price = price_btc; + price = 1. / price_btc; else continue; if ( factor > 0. ) price = (price * factor) + offset; From 08c0aabbc4f6b4e0a668d7bb4e9b4462db1b6815 Mon Sep 17 00:00:00 2001 From: jl777 Date: Sat, 9 Dec 2017 16:06:57 +0400 Subject: [PATCH 1647/1664] Finished for alicepayment not sent and bob refund --- iguana/exchanges/LP_portfolio.c | 8 ++++++-- iguana/exchanges/LP_prices.c | 6 ++++-- iguana/exchanges/LP_remember.c | 9 +++++++-- 3 files changed, 17 insertions(+), 6 deletions(-) diff --git a/iguana/exchanges/LP_portfolio.c b/iguana/exchanges/LP_portfolio.c index 63cd8d45d..f149a5e1c 100644 --- a/iguana/exchanges/LP_portfolio.c +++ b/iguana/exchanges/LP_portfolio.c @@ -24,6 +24,7 @@ struct LP_autoprice_ref { char refbase[65],refrel[65],base[65],rel[65]; double margin,factor,offset; + cJSON *fundvalue; } LP_autorefs[100]; int32_t LP_autoprices,num_LP_autorefs; @@ -472,7 +473,7 @@ void LP_autoprice_iter(void *ctx,struct LP_priceinfo *btcpp) int32_t LP_autoprice(void *ctx,char *base,char *rel,cJSON *argjson) { //curl --url "http://127.0.0.1:7783" --data "{\"userpass\":\"$userpass\",\"method\":\"autoprice\",\"base\":\"MNZ\",\"rel\":\"KMD\",\"offset\":0.1,\"refbase\":\"KMD\",\refrel\":\"BTC\",\"factor\":15000,\"margin\":0.01}" - struct LP_priceinfo *basepp,*relpp; int32_t i,retval = -1; char *refbase="",*refrel=""; double minprice,margin,offset,factor,fixedprice; + struct LP_priceinfo *basepp,*relpp; int32_t i,isfundvalue,retval = -1; char *refbase="",*refrel=""; double minprice,margin,offset,factor,fixedprice; //printf("autoprice.(%s %s) %s\n",base,rel,jprint(argjson,0)); if ( (basepp= LP_priceinfofind(base)) != 0 && (relpp= LP_priceinfofind(rel)) != 0 ) { @@ -488,7 +489,10 @@ int32_t LP_autoprice(void *ctx,char *base,char *rel,cJSON *argjson) basepp->margins[relpp->ind] = margin; basepp->offsets[relpp->ind] = offset; basepp->factors[relpp->ind] = factor; - if ( fixedprice > SMALLVAL || ((refbase= jstr(argjson,"refbase")) != 0 && (refrel= jstr(argjson,"refrel")) != 0) ) + refbase = jstr(argjson,"refbase"); + refrel = jstr(argjson,"refrel"); + isfundvalue = jint(argjson,"fundvalue"); + if ( isfundvalue != 0 || fixedprice > SMALLVAL || (refbase != 0 && refrel != 0) ) { if ( fixedprice > SMALLVAL ) { diff --git a/iguana/exchanges/LP_prices.c b/iguana/exchanges/LP_prices.c index 7744ed1a6..98d8ee157 100644 --- a/iguana/exchanges/LP_prices.c +++ b/iguana/exchanges/LP_prices.c @@ -1140,7 +1140,7 @@ double LP_CMCbtcprice(double *price_usdp,char *symbol) cJSON *LP_fundvalue(cJSON *argjson) { - cJSON *holdings,*item,*newitem,*array,*retjson; int32_t i,iter,n; double usdprice,divisor,btcprice,balance,btcsum,KMDholdings,numKMD; struct iguana_info *coin; char *symbol,*coinaddr; int64_t fundvalue,KMDvalue = 0; + cJSON *holdings,*item,*newitem,*array,*retjson; int32_t i,iter,n,missing=0; double usdprice,divisor,btcprice,balance,btcsum,KMDholdings,numKMD; struct iguana_info *coin; char *symbol,*coinaddr; int64_t fundvalue,KMDvalue = 0; fundvalue = 0; KMDholdings = btcsum = 0.; array = cJSON_CreateArray(); @@ -1180,11 +1180,13 @@ cJSON *LP_fundvalue(cJSON *argjson) } else jaddstr(newitem,"error","no price source"); jaddi(array,newitem); - } + } else missing++; } } } retjson = cJSON_CreateObject(); + jaddstr(retjson,"result","success"); + jaddnum(retjson,"missing",missing); jadd(retjson,"holdings",array); btcprice = LP_CMCbtcprice(&usdprice,"komodo"); divisor = jdouble(argjson,"divisor"); diff --git a/iguana/exchanges/LP_remember.c b/iguana/exchanges/LP_remember.c index 18f3310e5..f8aac6b49 100644 --- a/iguana/exchanges/LP_remember.c +++ b/iguana/exchanges/LP_remember.c @@ -380,8 +380,13 @@ int32_t basilisk_swap_isfinished(int32_t iambob,bits256 *txids,int32_t *sentflag } else { - if ( bits256_nonz(txids[BASILISK_ALICEPAYMENT]) == 0 && sentflags[BASILISK_ALICEPAYMENT] == 0 ) - return(1); + if ( sentflags[BASILISK_ALICEPAYMENT] == 0 ) + { + if ( bits256_nonz(txids[BASILISK_ALICEPAYMENT]) == 0 ) + return(1); + else if ( sentflags[BASILISK_BOBPAYMENT] != 0 && sentflags[BASILISK_BOBREFUND] != 0 ) + return(1); + } else { if ( sentflags[BASILISK_ALICERECLAIM] != 0 || sentflags[BASILISK_ALICESPEND] != 0 ) From 54ebf26d6dbb6e616312d4b54e22e81c8130fdce Mon Sep 17 00:00:00 2001 From: jl777 Date: Sat, 9 Dec 2017 16:52:28 +0400 Subject: [PATCH 1648/1664] Test --- iguana/exchanges/LP_instantdex.c | 1 + iguana/exchanges/LP_portfolio.c | 7 ++++--- 2 files changed, 5 insertions(+), 3 deletions(-) diff --git a/iguana/exchanges/LP_instantdex.c b/iguana/exchanges/LP_instantdex.c index e744a3c0b..76172fdfc 100644 --- a/iguana/exchanges/LP_instantdex.c +++ b/iguana/exchanges/LP_instantdex.c @@ -509,6 +509,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); + printf("proofcheck addrtype.%d (%s) -> %s\n",addrtype,coinaddr,othersmartaddr); if ((ap= LP_address(coin,othersmartaddr)) != 0 ) { ap->instantdex_credits = 0; diff --git a/iguana/exchanges/LP_portfolio.c b/iguana/exchanges/LP_portfolio.c index f149a5e1c..d217a4116 100644 --- a/iguana/exchanges/LP_portfolio.c +++ b/iguana/exchanges/LP_portfolio.c @@ -473,7 +473,7 @@ void LP_autoprice_iter(void *ctx,struct LP_priceinfo *btcpp) int32_t LP_autoprice(void *ctx,char *base,char *rel,cJSON *argjson) { //curl --url "http://127.0.0.1:7783" --data "{\"userpass\":\"$userpass\",\"method\":\"autoprice\",\"base\":\"MNZ\",\"rel\":\"KMD\",\"offset\":0.1,\"refbase\":\"KMD\",\refrel\":\"BTC\",\"factor\":15000,\"margin\":0.01}" - struct LP_priceinfo *basepp,*relpp; int32_t i,isfundvalue,retval = -1; char *refbase="",*refrel=""; double minprice,margin,offset,factor,fixedprice; + struct LP_priceinfo *basepp,*relpp; int32_t i,retval = -1; char *fundvalue_bid,*fundvalue_ask,*refbase="",*refrel=""; double minprice,margin,offset,factor,fixedprice; //printf("autoprice.(%s %s) %s\n",base,rel,jprint(argjson,0)); if ( (basepp= LP_priceinfofind(base)) != 0 && (relpp= LP_priceinfofind(rel)) != 0 ) { @@ -491,8 +491,9 @@ int32_t LP_autoprice(void *ctx,char *base,char *rel,cJSON *argjson) basepp->factors[relpp->ind] = factor; refbase = jstr(argjson,"refbase"); refrel = jstr(argjson,"refrel"); - isfundvalue = jint(argjson,"fundvalue"); - if ( isfundvalue != 0 || fixedprice > SMALLVAL || (refbase != 0 && refrel != 0) ) + fundvalue_bid = jstr(argjson,"fundvalue_bid"); + fundvalue_ask = jstr(argjson,"fundvalue_ask"); + if ( fundvalue_bid != 0 || fundvalue_ask != 0 || fixedprice > SMALLVAL || (refbase != 0 && refrel != 0) ) { if ( fixedprice > SMALLVAL ) { From 3453615d70648ab25be9b5084f79281c528eaa26 Mon Sep 17 00:00:00 2001 From: jl777 Date: Sat, 9 Dec 2017 17:25:11 +0400 Subject: [PATCH 1649/1664] Test --- iguana/exchanges/LP_instantdex.c | 41 ++++++++++++++++++++------------ iguana/exchanges/LP_ordermatch.c | 5 ++-- iguana/exchanges/LP_portfolio.c | 13 ++++++++-- iguana/exchanges/LP_signatures.c | 7 ++++-- 4 files changed, 45 insertions(+), 21 deletions(-) diff --git a/iguana/exchanges/LP_instantdex.c b/iguana/exchanges/LP_instantdex.c index 76172fdfc..2e41e26f7 100644 --- a/iguana/exchanges/LP_instantdex.c +++ b/iguana/exchanges/LP_instantdex.c @@ -19,16 +19,24 @@ // marketmaker // -void LP_instantdex_txidaddfname(char *fname,char *afname) +void LP_instantdex_txidaddfname(char *fname,char *afname,char *coinaddr) { - sprintf(fname,"%s/instantdex.json",GLOBAL_DBDIR); - sprintf(afname,"%s/instantdex_append.json",GLOBAL_DBDIR); + if ( coinaddr == 0 || coinaddr[0] == 0 ) + { + sprintf(fname,"%s/instantdex.json",GLOBAL_DBDIR); + sprintf(afname,"%s/instantdex_append.json",GLOBAL_DBDIR); + } + else + { + sprintf(fname,"%s/instantdex_%s.json",GLOBAL_DBDIR,coinaddr); + sprintf(afname,"%s/instantdex_%s_append.json",GLOBAL_DBDIR,coinaddr); + } } -cJSON *LP_instantdex_txids(int32_t appendonly) +cJSON *LP_instantdex_txids(int32_t appendonly,char *coinaddr) { char *filestr,fname[1024],afname[1024]; long fsize; cJSON *retjson=0; - LP_instantdex_txidaddfname(fname,afname); + LP_instantdex_txidaddfname(fname,afname,coinaddr); if ( (filestr= OS_filestr(&fsize,appendonly != 0 ? afname : fname)) != 0 ) { retjson = cJSON_Parse(filestr); @@ -37,10 +45,10 @@ cJSON *LP_instantdex_txids(int32_t appendonly) return(retjson); } -void LP_instantdex_filewrite(int32_t appendfile,cJSON *array) +void LP_instantdex_filewrite(int32_t appendfile,cJSON *array,char *coinaddr) { FILE *fp; char *filestr,fname[1024],afname[1024]; - LP_instantdex_txidaddfname(fname,afname); + LP_instantdex_txidaddfname(fname,afname,coinaddr); if ( (fp= fopen(appendfile == 0 ? fname : afname,"wb")) != 0 ) { filestr = jprint(array,0); @@ -96,9 +104,9 @@ void LP_instantdex_filescreate(char *coinaddr) jaddibits256(newarray,txid); } fclose(fp); - LP_instantdex_filewrite(0,newarray); + LP_instantdex_filewrite(0,newarray,coinaddr); free_json(newarray); - LP_instantdex_filewrite(1,array); + LP_instantdex_filewrite(1,array,coinaddr); free_json(array); } } @@ -106,16 +114,19 @@ void LP_instantdex_filescreate(char *coinaddr) void LP_instantdex_depositadd(char *coinaddr,bits256 txid) { static FILE *depositsfp; - char fname[512],str[65]; bits256 prevtxid; cJSON *array,*txobj; int32_t i,n,iter; + char fname[512],str[65],*addr; bits256 prevtxid; cJSON *array,*txobj; int32_t i,n,iter; if ( depositsfp == 0 ) { sprintf(fname,"%s/deposits.%s",GLOBAL_DBDIR,coinaddr), OS_compatible_path(fname); if ( (depositsfp= fopen(fname,"rb+")) == 0 ) { depositsfp = fopen(fname,"wb+"); - for (iter=0; iter<2; iter++) + for (iter=0; iter<4; iter++) { - if ( (array= LP_instantdex_txids(iter)) != 0 ) + if ( iter < 2 ) + addr = coinaddr; + else addr = ""; + if ( (array= LP_instantdex_txids(iter&1,addr)) != 0 ) { if ( (n= cJSON_GetArraySize(array)) > 0 ) { @@ -350,7 +361,7 @@ char *LP_instantdex_claim(struct iguana_info *coin) sum = 0; txids = cJSON_CreateArray(); newarray = cJSON_CreateArray(); - if ( (array= LP_instantdex_txids(firsttime)) != 0 ) + if ( (array= LP_instantdex_txids(firsttime,coin->smartaddr)) != 0 ) { printf("claiming from.(%s)\n",jprint(array,0)); if ( (n= cJSON_GetArraySize(array)) > 0 ) @@ -367,7 +378,7 @@ char *LP_instantdex_claim(struct iguana_info *coin) } firsttime = 0; if ( cJSON_GetArraySize(newarray) > 0 ) - LP_instantdex_filewrite(0,newarray); + LP_instantdex_filewrite(0,newarray,coin->smartaddr); free_json(newarray); retjson = cJSON_CreateObject(); jaddstr(retjson,"result","success"); @@ -539,7 +550,7 @@ int64_t LP_myzcredits() cJSON *proof; struct iguana_info *coin; int64_t zcredits; if ( (coin= LP_coinfind("KMD")) != 0 ) { - if ( (proof= LP_instantdex_txids(0)) != 0 ) + if ( (proof= LP_instantdex_txids(0,coin->smartaddr)) != 0 ) { zcredits = LP_instantdex_proofcheck(coin->smartaddr,proof,cJSON_GetArraySize(proof)); free_json(proof); diff --git a/iguana/exchanges/LP_ordermatch.c b/iguana/exchanges/LP_ordermatch.c index 5acc571a5..86cb812e4 100644 --- a/iguana/exchanges/LP_ordermatch.c +++ b/iguana/exchanges/LP_ordermatch.c @@ -444,7 +444,7 @@ struct LP_utxoinfo *LP_address_myutxopair(struct LP_utxoinfo *butxo,int32_t iamb int32_t LP_connectstartbob(void *ctx,int32_t pubsock,char *base,char *rel,double price,struct LP_quoteinfo *qp) { - char pairstr[512],otheraddr[64]; cJSON *reqjson; bits256 privkey; int32_t pair=-1,retval = -1,DEXselector = 0; struct basilisk_swap *swap; struct iguana_info *coin; + char pairstr[512],otheraddr[64]; cJSON *reqjson; bits256 privkey; int32_t pair=-1,retval = -1,DEXselector = 0; struct basilisk_swap *swap; struct iguana_info *coin,*kmdcoin; qp->quotetime = (uint32_t)time(NULL); if ( (coin= LP_coinfind(qp->srccoin)) == 0 ) { @@ -475,7 +475,8 @@ int32_t LP_connectstartbob(void *ctx,int32_t pubsock,char *base,char *rel,double reqjson = LP_quotejson(qp); jaddstr(reqjson,"method","connected"); jaddstr(reqjson,"pair",pairstr); - jadd(reqjson,"proof",LP_instantdex_txids(0)); + if ( (kmdcoin= LP_coinfind("KMD")) != 0 ) + jadd(reqjson,"proof",LP_instantdex_txids(0,kmdcoin->smartaddr)); char str[65]; printf("BOB pubsock.%d binds to %d (%s)\n",pubsock,pair,bits256_str(str,qp->desthash)); bits256 zero; memset(zero.bytes,0,sizeof(zero)); diff --git a/iguana/exchanges/LP_portfolio.c b/iguana/exchanges/LP_portfolio.c index d217a4116..31511dc45 100644 --- a/iguana/exchanges/LP_portfolio.c +++ b/iguana/exchanges/LP_portfolio.c @@ -22,7 +22,7 @@ struct LP_portfoliotrade { double metric; char buycoin[65],sellcoin[65]; }; struct LP_autoprice_ref { - char refbase[65],refrel[65],base[65],rel[65]; + char refbase[65],refrel[65],base[65],rel[65],fundbid[16],fundask[16]; double margin,factor,offset; cJSON *fundvalue; } LP_autorefs[100]; @@ -473,7 +473,7 @@ void LP_autoprice_iter(void *ctx,struct LP_priceinfo *btcpp) int32_t LP_autoprice(void *ctx,char *base,char *rel,cJSON *argjson) { //curl --url "http://127.0.0.1:7783" --data "{\"userpass\":\"$userpass\",\"method\":\"autoprice\",\"base\":\"MNZ\",\"rel\":\"KMD\",\"offset\":0.1,\"refbase\":\"KMD\",\refrel\":\"BTC\",\"factor\":15000,\"margin\":0.01}" - struct LP_priceinfo *basepp,*relpp; int32_t i,retval = -1; char *fundvalue_bid,*fundvalue_ask,*refbase="",*refrel=""; double minprice,margin,offset,factor,fixedprice; + struct LP_priceinfo *basepp,*relpp; int32_t i,retval = -1; char *fundvalue_bid,*fundvalue_ask,*refbase="",*refrel=""; double minprice,margin,offset,factor,fixedprice; cJSON *fundvalue; //printf("autoprice.(%s %s) %s\n",base,rel,jprint(argjson,0)); if ( (basepp= LP_priceinfofind(base)) != 0 && (relpp= LP_priceinfofind(rel)) != 0 ) { @@ -504,6 +504,15 @@ int32_t LP_autoprice(void *ctx,char *base,char *rel,cJSON *argjson) { if ( strcmp(base,LP_autorefs[i].base) == 0 && strcmp(rel,LP_autorefs[i].rel) == 0 ) { + if ( fundvalue_bid != 0 || fundvalue_ask != 0 ) + { + fundvalue = jduplicate(argjson); + jdelete(fundvalue,"method"); + jaddstr(fundvalue,"method","fundvalue"); + LP_autorefs[i].fundvalue = fundvalue; + safecopy(LP_autorefs[i].fundbid,fundvalue_bid,sizeof(LP_autorefs[i].fundbid)); + safecopy(LP_autorefs[i].fundask,fundvalue_ask,sizeof(LP_autorefs[i].fundask)); + } LP_autorefs[i].margin = margin; LP_autorefs[i].factor = factor; LP_autorefs[i].offset = offset; diff --git a/iguana/exchanges/LP_signatures.c b/iguana/exchanges/LP_signatures.c index 74cf86fee..668551325 100644 --- a/iguana/exchanges/LP_signatures.c +++ b/iguana/exchanges/LP_signatures.c @@ -643,7 +643,7 @@ void LP_listunspent_query(char *symbol,char *coinaddr) void LP_query(void *ctx,char *myipaddr,int32_t mypubsock,char *method,struct LP_quoteinfo *qp) { - cJSON *reqjson; bits256 zero; char *msg; int32_t flag = 0; + cJSON *reqjson; bits256 zero; char *msg; struct iguana_info *coin; int32_t flag = 0; if ( strcmp(method,"request") == 0 ) { if ( LP_allocated(qp->desttxid,qp->destvout) == 0 && LP_allocated(qp->feetxid,qp->feevout) == 0 ) @@ -665,7 +665,10 @@ void LP_query(void *ctx,char *myipaddr,int32_t mypubsock,char *method,struct LP_ if ( jobj(reqjson,"timestamp") == 0 ) jaddnum(reqjson,"timestamp",time(NULL)); if ( strcmp(method,"connect") == 0 ) - jadd(reqjson,"proof",LP_instantdex_txids(0)); + { + if ( (coin= LP_coinfind("KMD")) != 0 ) + jadd(reqjson,"proof",LP_instantdex_txids(0,coin->smartaddr)); + } msg = jprint(reqjson,1); printf("QUERY.(%s)\n",msg); //if ( bits256_nonz(qp->srchash) == 0 || strcmp(method,"request") != 0 ) From ee4eb459a6632df2cc5e1742470d8500e04eeae4 Mon Sep 17 00:00:00 2001 From: jl777 Date: Sat, 9 Dec 2017 17:49:49 +0400 Subject: [PATCH 1650/1664] Test --- iguana/exchanges/LP_portfolio.c | 51 +++++++++++++++++++++++++++------ 1 file changed, 42 insertions(+), 9 deletions(-) diff --git a/iguana/exchanges/LP_portfolio.c b/iguana/exchanges/LP_portfolio.c index 31511dc45..e57bd8371 100644 --- a/iguana/exchanges/LP_portfolio.c +++ b/iguana/exchanges/LP_portfolio.c @@ -369,7 +369,7 @@ double LP_pricesparse(void *ctx,int32_t trexflag,char *retstr,struct LP_priceinf void LP_autoprice_iter(void *ctx,struct LP_priceinfo *btcpp) { - char *retstr,*base,*rel; cJSON *retjson,*bid,*ask; uint64_t bidsatoshis,asksatoshis; int32_t i,changed; double nxtkmd,price,factor,offset,newprice,margin,price_btc,price_usd,kmd_btc,kmd_usd; struct LP_priceinfo *kmdpp,*fiatpp,*nxtpp,*basepp,*relpp; + char *retstr,*base,*rel; cJSON *retjson,*bid,*ask,*fundjson,*argjson; uint64_t bidsatoshis,asksatoshis; int32_t i,changed; double nxtkmd,price,factor,offset,newprice,margin,price_btc,price_usd,kmd_btc,kmd_usd; struct LP_priceinfo *kmdpp,*fiatpp,*nxtpp,*basepp,*relpp; if ( (retstr= issue_curlt("https://bittrex.com/api/v1.1/public/getmarketsummaries",LP_HTTP_TIMEOUT*10)) == 0 ) { printf("trex error getting marketsummaries\n"); @@ -431,13 +431,37 @@ void LP_autoprice_iter(void *ctx,struct LP_priceinfo *btcpp) kmd_btc = LP_CMCbtcprice(&kmd_usd,"komodo"); for (i=0; i SMALLVAL ) + { + newprice = (1. / price) * (1. + margin); + LP_mypriceset(&changed,base,rel,newprice); + LP_pricepings(ctx,LP_myipaddr,LP_mypubsock,base,rel,newprice); + printf("fundbid %.8f margin %.8f newprice %.8f\n",price,margin,newprice); + } + if ( LP_autorefs[i].fundask[0] != 0 && (price= jdouble(fundjson,LP_autorefs[i].fundask)) > SMALLVAL ) + { + newprice = (price * (1. + margin)); + LP_mypriceset(&changed,rel,base,price); + LP_pricepings(ctx,LP_myipaddr,LP_mypubsock,rel,base,newprice); + printf("fundask %.8f margin %.8f newprice %.8f\n",price,margin,newprice); + } + } + free_json(fundjson); + } + } + else if ( strcmp(LP_autorefs[i].refrel,"coinmarketcap") == 0 ) { - rel = LP_autorefs[i].rel; - base = LP_autorefs[i].base; - margin = LP_autorefs[i].margin; - offset = LP_autorefs[i].offset; - factor = LP_autorefs[i].factor; //printf("%s/%s for %s/%s margin %.8f\n",base,rel,LP_autorefs[i].refbase,LP_autorefs[i].refrel,margin); if ( (price_btc= LP_CMCbtcprice(&price_usd,LP_autorefs[i].refbase)) > SMALLVAL ) { @@ -459,8 +483,8 @@ void LP_autoprice_iter(void *ctx,struct LP_priceinfo *btcpp) } else { - basepp = LP_priceinfofind(LP_autorefs[i].base); - relpp = LP_priceinfofind(LP_autorefs[i].rel); + basepp = LP_priceinfofind(base); + relpp = LP_priceinfofind(rel); if ( basepp != 0 && relpp != 0 ) { //printf("check ref-autoprice %s/%s %f %f\n",LP_autorefs[i].refbase,LP_autorefs[i].refrel,relpp->fixedprices[basepp->ind],basepp->fixedprices[relpp->ind]); @@ -524,6 +548,15 @@ int32_t LP_autoprice(void *ctx,char *base,char *rel,cJSON *argjson) } if ( i == num_LP_autorefs && num_LP_autorefs < sizeof(LP_autorefs)/sizeof(*LP_autorefs) ) { + if ( fundvalue_bid != 0 || fundvalue_ask != 0 ) + { + fundvalue = jduplicate(argjson); + jdelete(fundvalue,"method"); + jaddstr(fundvalue,"method","fundvalue"); + LP_autorefs[num_LP_autorefs].fundvalue = fundvalue; + safecopy(LP_autorefs[num_LP_autorefs].fundbid,fundvalue_bid,sizeof(LP_autorefs[num_LP_autorefs].fundbid)); + safecopy(LP_autorefs[num_LP_autorefs].fundask,fundvalue_ask,sizeof(LP_autorefs[num_LP_autorefs].fundask)); + } LP_autorefs[num_LP_autorefs].margin = margin; LP_autorefs[num_LP_autorefs].factor = factor; LP_autorefs[num_LP_autorefs].offset = offset; From 60c9c512283df94a6060a832db8cf292b03d4a91 Mon Sep 17 00:00:00 2001 From: jl777 Date: Sat, 9 Dec 2017 17:57:18 +0400 Subject: [PATCH 1651/1664] Test --- iguana/exchanges/LP_privkey.c | 21 +-------------------- iguana/exchanges/LP_statemachine.c | 22 ++++++++++++++++++++++ 2 files changed, 23 insertions(+), 20 deletions(-) diff --git a/iguana/exchanges/LP_privkey.c b/iguana/exchanges/LP_privkey.c index 0d5a515dd..7f519adfd 100644 --- a/iguana/exchanges/LP_privkey.c +++ b/iguana/exchanges/LP_privkey.c @@ -321,26 +321,6 @@ int32_t LP_passphrase_init(char *passphrase,char *gui) printf("waiting for G.waiting\n"); sleep(5); } - /*for (iambob=0; iambob<2; iambob++) - { - if ( G.LP_utxoinfos[iambob] != 0 ) - { - HASH_ITER(hh,G.LP_utxoinfos[iambob],utxo,tmp) - { - HASH_DELETE(hh,G.LP_utxoinfos[iambob],utxo); - //free(utxo); - } - } - if ( G.LP_utxoinfos2[iambob] != 0 ) - { - G.LP_utxoinfos2[iambob] = 0; - //HASH_ITER(hh,G.LP_utxoinfos2[iambob],utxo,tmp) - //{ - // HASH_DELETE(hh,G.LP_utxoinfos2[iambob],utxo); - // free(utxo); - //} - } - }*/ memset(&G,0,sizeof(G)); LP_privkey_updates(ctx,LP_mypubsock,passphrase); init_hexbytes_noT(G.LP_myrmd160str,G.LP_myrmd160,20); @@ -350,6 +330,7 @@ int32_t LP_passphrase_init(char *passphrase,char *gui) G.initializing = 0; bitcoin_address(coinaddr,0,60,G.LP_myrmd160,20); memset(zero.bytes,0,sizeof(zero)); + printf("passphrase init: call depositadd.(%s)\n",coinaddr); LP_instantdex_depositadd(coinaddr,zero); return(0); } diff --git a/iguana/exchanges/LP_statemachine.c b/iguana/exchanges/LP_statemachine.c index d467958ec..be1d7701d 100644 --- a/iguana/exchanges/LP_statemachine.c +++ b/iguana/exchanges/LP_statemachine.c @@ -490,6 +490,28 @@ void LP_instantdex_txidadd(bits256 txid) return((double)destsatoshis / satoshis); else return(0.); }*/ + +/*for (iambob=0; iambob<2; iambob++) + { + if ( G.LP_utxoinfos[iambob] != 0 ) + { + HASH_ITER(hh,G.LP_utxoinfos[iambob],utxo,tmp) + { + HASH_DELETE(hh,G.LP_utxoinfos[iambob],utxo); + //free(utxo); + } + } + if ( G.LP_utxoinfos2[iambob] != 0 ) + { + G.LP_utxoinfos2[iambob] = 0; + //HASH_ITER(hh,G.LP_utxoinfos2[iambob],utxo,tmp) + //{ + // HASH_DELETE(hh,G.LP_utxoinfos2[iambob],utxo); + // free(utxo); + //} + } + }*/ + char *issue_LP_getprices(char *destip,uint16_t destport) { char url[512]; From 0a97eed5d739b00196d7da2574f9b6c0bb5c8601 Mon Sep 17 00:00:00 2001 From: jl777 Date: Sat, 9 Dec 2017 18:17:06 +0400 Subject: [PATCH 1652/1664] Test --- iguana/exchanges/LP_portfolio.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/iguana/exchanges/LP_portfolio.c b/iguana/exchanges/LP_portfolio.c index e57bd8371..dd5c9de7c 100644 --- a/iguana/exchanges/LP_portfolio.c +++ b/iguana/exchanges/LP_portfolio.c @@ -445,15 +445,15 @@ void LP_autoprice_iter(void *ctx,struct LP_priceinfo *btcpp) if ( LP_autorefs[i].fundbid[0] != 0 && (price= jdouble(fundjson,LP_autorefs[i].fundbid)) > SMALLVAL ) { newprice = (1. / price) * (1. + margin); - LP_mypriceset(&changed,base,rel,newprice); - LP_pricepings(ctx,LP_myipaddr,LP_mypubsock,base,rel,newprice); + LP_mypriceset(&changed,rel,base,newprice); + LP_pricepings(ctx,LP_myipaddr,LP_mypubsock,rel,base,newprice); printf("fundbid %.8f margin %.8f newprice %.8f\n",price,margin,newprice); } if ( LP_autorefs[i].fundask[0] != 0 && (price= jdouble(fundjson,LP_autorefs[i].fundask)) > SMALLVAL ) { newprice = (price * (1. + margin)); - LP_mypriceset(&changed,rel,base,price); - LP_pricepings(ctx,LP_myipaddr,LP_mypubsock,rel,base,newprice); + LP_mypriceset(&changed,base,rel,price); + LP_pricepings(ctx,LP_myipaddr,LP_mypubsock,base,rel,newprice); printf("fundask %.8f margin %.8f newprice %.8f\n",price,margin,newprice); } } From 600def863fb9406db4879f06d52a2207cf3c0be4 Mon Sep 17 00:00:00 2001 From: jl777 Date: Sat, 9 Dec 2017 18:22:22 +0400 Subject: [PATCH 1653/1664] Test --- iguana/exchanges/LP_portfolio.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/iguana/exchanges/LP_portfolio.c b/iguana/exchanges/LP_portfolio.c index dd5c9de7c..2f6ce9f37 100644 --- a/iguana/exchanges/LP_portfolio.c +++ b/iguana/exchanges/LP_portfolio.c @@ -452,7 +452,7 @@ void LP_autoprice_iter(void *ctx,struct LP_priceinfo *btcpp) if ( LP_autorefs[i].fundask[0] != 0 && (price= jdouble(fundjson,LP_autorefs[i].fundask)) > SMALLVAL ) { newprice = (price * (1. + margin)); - LP_mypriceset(&changed,base,rel,price); + LP_mypriceset(&changed,base,rel,newprice); LP_pricepings(ctx,LP_myipaddr,LP_mypubsock,base,rel,newprice); printf("fundask %.8f margin %.8f newprice %.8f\n",price,margin,newprice); } From 5e31422486fc90800caeb1b3e2924fd6999a8f14 Mon Sep 17 00:00:00 2001 From: jl777 Date: Sat, 9 Dec 2017 18:46:46 +0400 Subject: [PATCH 1654/1664] Test --- iguana/exchanges/LP_nativeDEX.c | 3 ++- iguana/exchanges/LP_portfolio.c | 4 ++-- 2 files changed, 4 insertions(+), 3 deletions(-) diff --git a/iguana/exchanges/LP_nativeDEX.c b/iguana/exchanges/LP_nativeDEX.c index f6fb7ded6..c30d15ab9 100644 --- a/iguana/exchanges/LP_nativeDEX.c +++ b/iguana/exchanges/LP_nativeDEX.c @@ -17,7 +17,8 @@ // LP_nativeDEX.c // marketmaker // -// fundvalue -> autoprice, signals -> autoprice +// signals -> autoprice +// passphrase for deposits // https://github.com/bitcoin/bips/blob/master/bip-0143.mediawiki for signing BCH/BTG // // compress packets diff --git a/iguana/exchanges/LP_portfolio.c b/iguana/exchanges/LP_portfolio.c index 2f6ce9f37..4c1a53ca2 100644 --- a/iguana/exchanges/LP_portfolio.c +++ b/iguana/exchanges/LP_portfolio.c @@ -447,14 +447,14 @@ void LP_autoprice_iter(void *ctx,struct LP_priceinfo *btcpp) newprice = (1. / price) * (1. + margin); LP_mypriceset(&changed,rel,base,newprice); LP_pricepings(ctx,LP_myipaddr,LP_mypubsock,rel,base,newprice); - printf("fundbid %.8f margin %.8f newprice %.8f\n",price,margin,newprice); + //printf("fundbid %.8f margin %.8f newprice %.8f\n",price,margin,newprice); } if ( LP_autorefs[i].fundask[0] != 0 && (price= jdouble(fundjson,LP_autorefs[i].fundask)) > SMALLVAL ) { newprice = (price * (1. + margin)); LP_mypriceset(&changed,base,rel,newprice); LP_pricepings(ctx,LP_myipaddr,LP_mypubsock,base,rel,newprice); - printf("fundask %.8f margin %.8f newprice %.8f\n",price,margin,newprice); + //printf("fundask %.8f margin %.8f newprice %.8f\n",price,margin,newprice); } } free_json(fundjson); From 685f8240f09ae7185abb7dae44e5b96aa7d0c110 Mon Sep 17 00:00:00 2001 From: jl777 Date: Sat, 9 Dec 2017 20:39:30 +0400 Subject: [PATCH 1655/1664] Test --- iguana/exchanges/LP_commands.c | 4 +++- iguana/exchanges/LP_nativeDEX.c | 7 ++++--- iguana/exchanges/LP_privkey.c | 6 +----- 3 files changed, 8 insertions(+), 9 deletions(-) diff --git a/iguana/exchanges/LP_commands.c b/iguana/exchanges/LP_commands.c index dd87341eb..9c4b4fa2f 100644 --- a/iguana/exchanges/LP_commands.c +++ b/iguana/exchanges/LP_commands.c @@ -184,7 +184,7 @@ instantdex_claim()\n\ jdelete(argjson,"userpass"); if ( strcmp(method,"passphrase") == 0 ) { - char coinaddr[64]; + char coinaddr[64]; bits256 zero; G.USERPASS_COUNTER = 1; if ( LP_passphrase_init(jstr(argjson,"passphrase"),jstr(argjson,"gui")) < 0 ) return(clonestr("{\"error\":\"couldnt change passphrase\"}")); @@ -195,6 +195,8 @@ instantdex_claim()\n\ jaddbits256(retjson,"mypubkey",G.LP_mypub25519); bitcoin_address(coinaddr,0,60,G.LP_myrmd160,20); jaddstr(retjson,"KMD",coinaddr); + memset(zero.bytes,0,sizeof(zero)); + LP_instantdex_depositadd(coinaddr,zero); bitcoin_address(coinaddr,0,0,G.LP_myrmd160,20); jaddstr(retjson,"BTC",coinaddr); jaddstr(retjson,"NXT",G.LP_NXTaddr); diff --git a/iguana/exchanges/LP_nativeDEX.c b/iguana/exchanges/LP_nativeDEX.c index c30d15ab9..214f953dc 100644 --- a/iguana/exchanges/LP_nativeDEX.c +++ b/iguana/exchanges/LP_nativeDEX.c @@ -17,21 +17,22 @@ // LP_nativeDEX.c // marketmaker // +// ordermatch pricing error // signals -> autoprice // passphrase for deposits // https://github.com/bitcoin/bips/blob/master/bip-0143.mediawiki for signing BCH/BTG -// // compress packets // portfolio to set prices from historical // portfolio value based on ask? -// // else claim path +// +// WONTFIX: // 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 // use electrum in case of addr change in swap // locktime claiming on sporadic assetchains -// there is an issue about waiting for notarization for a swap that never starts +// there is an issue about waiting for notarization for a swap that never starts (expiration ok) #include diff --git a/iguana/exchanges/LP_privkey.c b/iguana/exchanges/LP_privkey.c index 7f519adfd..baca4e6e4 100644 --- a/iguana/exchanges/LP_privkey.c +++ b/iguana/exchanges/LP_privkey.c @@ -307,7 +307,7 @@ void LP_privkey_updates(void *ctx,int32_t pubsock,char *passphrase) int32_t LP_passphrase_init(char *passphrase,char *gui) { - static void *ctx; char coinaddr[64]; bits256 zero; int32_t counter; //iambob,; struct LP_utxoinfo *utxo,*tmp; + static void *ctx; int32_t counter; //iambob,; struct LP_utxoinfo *utxo,*tmp; if ( ctx == 0 ) ctx = bitcoin_ctx(); if ( G.LP_pendingswaps != 0 ) @@ -328,10 +328,6 @@ int32_t LP_passphrase_init(char *passphrase,char *gui) safecopy(G.gui,gui,sizeof(G.gui)); G.USERPASS_COUNTER = counter; G.initializing = 0; - bitcoin_address(coinaddr,0,60,G.LP_myrmd160,20); - memset(zero.bytes,0,sizeof(zero)); - printf("passphrase init: call depositadd.(%s)\n",coinaddr); - LP_instantdex_depositadd(coinaddr,zero); return(0); } From 1f610b501573d16c6b5f9c671698cd738ab38347 Mon Sep 17 00:00:00 2001 From: jl777 Date: Sat, 9 Dec 2017 20:46:24 +0400 Subject: [PATCH 1656/1664] Test --- iguana/exchanges/LP_nativeDEX.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/iguana/exchanges/LP_nativeDEX.c b/iguana/exchanges/LP_nativeDEX.c index 214f953dc..e8c51fa0c 100644 --- a/iguana/exchanges/LP_nativeDEX.c +++ b/iguana/exchanges/LP_nativeDEX.c @@ -1160,9 +1160,12 @@ void LPinit(uint16_t myport,uint16_t mypullport,uint16_t mypubport,uint16_t mybu exit(-1); } LP_initcoins(ctx,pubsock,coinsjson); - G.waiting = 1; LP_passphrase_init(passphrase,jstr(argjson,"gui")); + char coinaddr[64]; bits256 zero; + bitcoin_address(coinaddr,0,60,G.LP_myrmd160,20); + memset(zero.bytes,0,sizeof(zero)); + LP_instantdex_depositadd(coinaddr,zero); #ifndef FROM_JS if ( IAMLP != 0 && OS_thread_create(malloc(sizeof(pthread_t)),NULL,(void *)LP_psockloop,(void *)myipaddr) != 0 ) { From eefb5e2aa2cbe9901e4acb63b4174d25c694e5f0 Mon Sep 17 00:00:00 2001 From: jl777 Date: Sat, 9 Dec 2017 21:01:56 +0400 Subject: [PATCH 1657/1664] Test --- iguana/exchanges/LP_coins.c | 4 +++- iguana/exchanges/LP_commands.c | 4 +--- iguana/exchanges/LP_include.h | 1 + iguana/exchanges/LP_instantdex.c | 4 ++-- iguana/exchanges/LP_nativeDEX.c | 8 ++++---- 5 files changed, 11 insertions(+), 10 deletions(-) diff --git a/iguana/exchanges/LP_coins.c b/iguana/exchanges/LP_coins.c index 211852c11..b62e2b7b1 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; int32_t notarized; uint64_t balance; char wifstr[128],ipaddr[64]; uint8_t tmptype; bits256 checkkey; cJSON *item = cJSON_CreateObject(); + struct electrum_info *ep; bits256 zero; 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 ) { @@ -261,6 +261,8 @@ cJSON *LP_coinjson(struct iguana_info *coin,int32_t showwif) jaddnum(item,"txfee",strcmp(coin->symbol,"BTC") != 0 ? coin->txfee : LP_txfeecalc(coin,0,0)); if ( strcmp(coin->symbol,"KMD") == 0 ) { + memset(zero.bytes,0,sizeof(zero)); + LP_instantdex_depositadd(coin->smartaddr,zero); jaddnum(item,"zcredits",dstr(LP_myzcredits())); jadd(item,"zdebits",LP_myzdebits()); } diff --git a/iguana/exchanges/LP_commands.c b/iguana/exchanges/LP_commands.c index 9c4b4fa2f..dd87341eb 100644 --- a/iguana/exchanges/LP_commands.c +++ b/iguana/exchanges/LP_commands.c @@ -184,7 +184,7 @@ instantdex_claim()\n\ jdelete(argjson,"userpass"); if ( strcmp(method,"passphrase") == 0 ) { - char coinaddr[64]; bits256 zero; + char coinaddr[64]; G.USERPASS_COUNTER = 1; if ( LP_passphrase_init(jstr(argjson,"passphrase"),jstr(argjson,"gui")) < 0 ) return(clonestr("{\"error\":\"couldnt change passphrase\"}")); @@ -195,8 +195,6 @@ instantdex_claim()\n\ jaddbits256(retjson,"mypubkey",G.LP_mypub25519); bitcoin_address(coinaddr,0,60,G.LP_myrmd160,20); jaddstr(retjson,"KMD",coinaddr); - memset(zero.bytes,0,sizeof(zero)); - LP_instantdex_depositadd(coinaddr,zero); bitcoin_address(coinaddr,0,0,G.LP_myrmd160,20); jaddstr(retjson,"BTC",coinaddr); jaddstr(retjson,"NXT",G.LP_NXTaddr); diff --git a/iguana/exchanges/LP_include.h b/iguana/exchanges/LP_include.h index 57616a77b..cf9beab63 100644 --- a/iguana/exchanges/LP_include.h +++ b/iguana/exchanges/LP_include.h @@ -506,6 +506,7 @@ int32_t iguana_signrawtransaction(void *ctx,char *symbol,uint8_t wiftaddr,uint8_ //void LP_butxo_swapfields_set(struct LP_utxoinfo *butxo); struct LP_address_utxo *LP_address_utxofind(struct iguana_info *coin,char *coinaddr,bits256 txid,int32_t vout); int64_t LP_myzcredits(); +void LP_instantdex_depositadd(char *coinaddr,bits256 txid); int32_t LP_destaddr(char *destaddr,cJSON *item); int32_t LP_waitmempool(char *symbol,char *coinaddr,bits256 txid,int32_t vout,int32_t duration); cJSON *LP_statslog_disp(uint32_t starttime,uint32_t endtime,char *refgui,bits256 refpubkey,char *refbase,char *refrel); diff --git a/iguana/exchanges/LP_instantdex.c b/iguana/exchanges/LP_instantdex.c index 2e41e26f7..bbd84bd0e 100644 --- a/iguana/exchanges/LP_instantdex.c +++ b/iguana/exchanges/LP_instantdex.c @@ -68,7 +68,7 @@ void LP_instantdex_deposituniq(FILE *fp,bits256 txid) fread(&prevtxid,1,sizeof(prevtxid),fp); if ( bits256_cmp(prevtxid,txid) == 0 ) { - printf("%s duplicate of deposits[%d]\n",bits256_str(str,prevtxid),i); + //printf("%s duplicate of deposits[%d]\n",bits256_str(str,prevtxid),i); break; } } @@ -133,7 +133,7 @@ void LP_instantdex_depositadd(char *coinaddr,bits256 txid) for (i=0; i Date: Sat, 9 Dec 2017 21:08:10 +0400 Subject: [PATCH 1658/1664] Test --- iguana/exchanges/LP_include.h | 1 + iguana/exchanges/LP_instantdex.c | 15 ++++++--------- 2 files changed, 7 insertions(+), 9 deletions(-) diff --git a/iguana/exchanges/LP_include.h b/iguana/exchanges/LP_include.h index cf9beab63..ccddae1a5 100644 --- a/iguana/exchanges/LP_include.h +++ b/iguana/exchanges/LP_include.h @@ -507,6 +507,7 @@ int32_t iguana_signrawtransaction(void *ctx,char *symbol,uint8_t wiftaddr,uint8_ struct LP_address_utxo *LP_address_utxofind(struct iguana_info *coin,char *coinaddr,bits256 txid,int32_t vout); int64_t LP_myzcredits(); void LP_instantdex_depositadd(char *coinaddr,bits256 txid); +int64_t LP_instantdex_creditcalc(struct iguana_info *coin,int32_t dispflag,bits256 txid,char *refaddr); int32_t LP_destaddr(char *destaddr,cJSON *item); int32_t LP_waitmempool(char *symbol,char *coinaddr,bits256 txid,int32_t vout,int32_t duration); cJSON *LP_statslog_disp(uint32_t starttime,uint32_t endtime,char *refgui,bits256 refpubkey,char *refbase,char *refrel); diff --git a/iguana/exchanges/LP_instantdex.c b/iguana/exchanges/LP_instantdex.c index bbd84bd0e..32694fd0f 100644 --- a/iguana/exchanges/LP_instantdex.c +++ b/iguana/exchanges/LP_instantdex.c @@ -114,7 +114,8 @@ void LP_instantdex_filescreate(char *coinaddr) void LP_instantdex_depositadd(char *coinaddr,bits256 txid) { static FILE *depositsfp; - char fname[512],str[65],*addr; bits256 prevtxid; cJSON *array,*txobj; int32_t i,n,iter; + struct iguana_info *coin; char fname[512],*addr; bits256 prevtxid; cJSON *array; int32_t i,n,iter; + coin = LP_coinfind("KMD"); if ( depositsfp == 0 ) { sprintf(fname,"%s/deposits.%s",GLOBAL_DBDIR,coinaddr), OS_compatible_path(fname); @@ -126,7 +127,7 @@ void LP_instantdex_depositadd(char *coinaddr,bits256 txid) if ( iter < 2 ) addr = coinaddr; else addr = ""; - if ( (array= LP_instantdex_txids(iter&1,addr)) != 0 ) + if ( coin != 0 && (array= LP_instantdex_txids(iter&1,addr)) != 0 ) { if ( (n= cJSON_GetArraySize(array)) > 0 ) { @@ -134,15 +135,11 @@ void LP_instantdex_depositadd(char *coinaddr,bits256 txid) { prevtxid = jbits256i(array,i); //printf("instantdex iter.%d i.%d check %s\n",iter,i,bits256_str(str,prevtxid)); - if ( (txobj= LP_gettxout("KMD",coinaddr,prevtxid,0)) != 0 ) - free_json(txobj); - else + if ( LP_instantdex_creditcalc(coin,0,prevtxid,coinaddr) > 0 ) { - printf("null gettxout %s %s\n",coinaddr,bits256_str(str,prevtxid)); - continue; + LP_instantdex_deposituniq(depositsfp,prevtxid); + fflush(depositsfp); } - LP_instantdex_deposituniq(depositsfp,prevtxid); - fflush(depositsfp); } } free_json(array); From fff619435a172bee02015b64c1fb471b90a89b11 Mon Sep 17 00:00:00 2001 From: jl777 Date: Sat, 9 Dec 2017 21:30:54 +0400 Subject: [PATCH 1659/1664] Test --- iguana/exchanges/LP_instantdex.c | 26 ++++++++++++-------------- 1 file changed, 12 insertions(+), 14 deletions(-) diff --git a/iguana/exchanges/LP_instantdex.c b/iguana/exchanges/LP_instantdex.c index 32694fd0f..4d8002491 100644 --- a/iguana/exchanges/LP_instantdex.c +++ b/iguana/exchanges/LP_instantdex.c @@ -113,15 +113,13 @@ void LP_instantdex_filescreate(char *coinaddr) void LP_instantdex_depositadd(char *coinaddr,bits256 txid) { - static FILE *depositsfp; - struct iguana_info *coin; char fname[512],*addr; bits256 prevtxid; cJSON *array; int32_t i,n,iter; + FILE *fp; struct iguana_info *coin; char fname[512],*addr; bits256 prevtxid; cJSON *array; int32_t i,n,iter; coin = LP_coinfind("KMD"); - if ( depositsfp == 0 ) + sprintf(fname,"%s/deposits.%s",GLOBAL_DBDIR,coinaddr), OS_compatible_path(fname); + if ( (fp= fopen(fname,"rb+")) == 0 ) { - sprintf(fname,"%s/deposits.%s",GLOBAL_DBDIR,coinaddr), OS_compatible_path(fname); - if ( (depositsfp= fopen(fname,"rb+")) == 0 ) + if ( (fp= fopen(fname,"wb+")) != 0 ) { - depositsfp = fopen(fname,"wb+"); for (iter=0; iter<4; iter++) { if ( iter < 2 ) @@ -134,23 +132,23 @@ void LP_instantdex_depositadd(char *coinaddr,bits256 txid) for (i=0; i 0 ) { - LP_instantdex_deposituniq(depositsfp,prevtxid); - fflush(depositsfp); + LP_instantdex_deposituniq(fp,prevtxid); + fflush(fp); } } } free_json(array); } } - } else fseek(depositsfp,0,SEEK_END); - } - if ( depositsfp != 0 && bits256_nonz(txid) != 0 ) + } + } else fseek(fp,0,SEEK_END); + if ( fp != 0 && bits256_nonz(txid) != 0 ) { - LP_instantdex_deposituniq(depositsfp,txid); - fflush(depositsfp); + LP_instantdex_deposituniq(fp,txid); + fclose(fp); } LP_instantdex_filescreate(coinaddr); } From 8cce3577420b37cfef310ab9a8b555e09a0ff3e7 Mon Sep 17 00:00:00 2001 From: jl777 Date: Sat, 9 Dec 2017 22:11:44 +0400 Subject: [PATCH 1660/1664] Test --- iguana/exchanges/LP_coins.c | 6 +++++- iguana/exchanges/LP_include.h | 2 +- iguana/exchanges/LP_nativeDEX.c | 1 - 3 files changed, 6 insertions(+), 3 deletions(-) diff --git a/iguana/exchanges/LP_coins.c b/iguana/exchanges/LP_coins.c index b62e2b7b1..ae66c3701 100644 --- a/iguana/exchanges/LP_coins.c +++ b/iguana/exchanges/LP_coins.c @@ -262,7 +262,11 @@ cJSON *LP_coinjson(struct iguana_info *coin,int32_t showwif) if ( strcmp(coin->symbol,"KMD") == 0 ) { memset(zero.bytes,0,sizeof(zero)); - LP_instantdex_depositadd(coin->smartaddr,zero); + if ( strcmp(coin->smartaddr,coin->instantdex_address) != 0 ) + { + LP_instantdex_depositadd(coin->smartaddr,zero); + strcpy(coin->instantdex_address,coin->smartaddr); + } jaddnum(item,"zcredits",dstr(LP_myzcredits())); jadd(item,"zdebits",LP_myzdebits()); } diff --git a/iguana/exchanges/LP_include.h b/iguana/exchanges/LP_include.h index ccddae1a5..a82c40340 100644 --- a/iguana/exchanges/LP_include.h +++ b/iguana/exchanges/LP_include.h @@ -294,7 +294,7 @@ struct iguana_info 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]; + char symbol[128],smartaddr[64],userpass[1024],serverport[128],instantdex_address[64]; // portfolio double price_kmd,force,perc,goal,goalperc,relvolume,rate; void *electrum; void *ctx; diff --git a/iguana/exchanges/LP_nativeDEX.c b/iguana/exchanges/LP_nativeDEX.c index 1e67d4ac1..b3fe04ddf 100644 --- a/iguana/exchanges/LP_nativeDEX.c +++ b/iguana/exchanges/LP_nativeDEX.c @@ -19,7 +19,6 @@ // // ordermatch pricing error // signals -> autoprice -// passphrase for deposits // https://github.com/bitcoin/bips/blob/master/bip-0143.mediawiki for signing BCH/BTG // compress packets // portfolio to set prices from historical From b7b919216d0d953d7af12de9d6dd1f67f605c998 Mon Sep 17 00:00:00 2001 From: jl777 Date: Sun, 10 Dec 2017 09:18:58 +0400 Subject: [PATCH 1661/1664] Test --- iguana/exchanges/LP_instantdex.c | 2 +- iguana/exchanges/LP_nativeDEX.c | 1 - iguana/exchanges/LP_remember.c | 4 ++++ 3 files changed, 5 insertions(+), 2 deletions(-) diff --git a/iguana/exchanges/LP_instantdex.c b/iguana/exchanges/LP_instantdex.c index 4d8002491..dae35bfb6 100644 --- a/iguana/exchanges/LP_instantdex.c +++ b/iguana/exchanges/LP_instantdex.c @@ -132,7 +132,7 @@ void LP_instantdex_depositadd(char *coinaddr,bits256 txid) for (i=0; i 0 ) { LP_instantdex_deposituniq(fp,prevtxid); diff --git a/iguana/exchanges/LP_nativeDEX.c b/iguana/exchanges/LP_nativeDEX.c index b3fe04ddf..4fc1bacd4 100644 --- a/iguana/exchanges/LP_nativeDEX.c +++ b/iguana/exchanges/LP_nativeDEX.c @@ -18,7 +18,6 @@ // marketmaker // // ordermatch pricing error -// signals -> autoprice // https://github.com/bitcoin/bips/blob/master/bip-0143.mediawiki for signing BCH/BTG // compress packets // portfolio to set prices from historical diff --git a/iguana/exchanges/LP_remember.c b/iguana/exchanges/LP_remember.c index f8aac6b49..24a04a6bf 100644 --- a/iguana/exchanges/LP_remember.c +++ b/iguana/exchanges/LP_remember.c @@ -923,6 +923,8 @@ cJSON *basilisk_remember(int64_t *KMDtotals,int64_t *BTCtotals,uint32_t requesti bitcoin_address(otheraddr,alice->taddr,alice->pubtype,rswap.other33,33); destBdest = otheraddr; destAdest = rswap.Adestaddr; + if ( strcmp(alice->smartaddr,rswap.Adestaddr) != 0 ) + printf("this isnt my swap! alice.(%s vs %s)\n",alice->smartaddr,rswap.Adestaddr); } if ( (bob= LP_coinfind(rswap.bobcoin)) != 0 ) { @@ -938,6 +940,8 @@ cJSON *basilisk_remember(int64_t *KMDtotals,int64_t *BTCtotals,uint32_t requesti bitcoin_address(otheraddr,bob->taddr,bob->pubtype,rswap.other33,33); srcAdest = otheraddr; srcBdest = rswap.destaddr; + if ( strcmp(bob->smartaddr,rswap.destaddr) != 0 ) + printf("this isnt my swap! bob.(%s vs %s)\n",bob->smartaddr,rswap.destaddr); } if ( (alice= LP_coinfind(rswap.alicecoin)) != 0 ) { From ae1a4a3c6aca7088f5ec782fb4ccb240db62ae5c Mon Sep 17 00:00:00 2001 From: jl777 Date: Sun, 10 Dec 2017 09:19:27 +0400 Subject: [PATCH 1662/1664] Test --- iguana/exchanges/LP_instantdex.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/iguana/exchanges/LP_instantdex.c b/iguana/exchanges/LP_instantdex.c index dae35bfb6..4d8002491 100644 --- a/iguana/exchanges/LP_instantdex.c +++ b/iguana/exchanges/LP_instantdex.c @@ -132,7 +132,7 @@ void LP_instantdex_depositadd(char *coinaddr,bits256 txid) for (i=0; i 0 ) { LP_instantdex_deposituniq(fp,prevtxid); From 1ba599c109aebaa2aa4ae76b31ab4ea6bf89af45 Mon Sep 17 00:00:00 2001 From: jl777 Date: Sun, 10 Dec 2017 09:22:29 +0400 Subject: [PATCH 1663/1664] Test --- iguana/exchanges/LP_remember.c | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/iguana/exchanges/LP_remember.c b/iguana/exchanges/LP_remember.c index 24a04a6bf..988d47ba8 100644 --- a/iguana/exchanges/LP_remember.c +++ b/iguana/exchanges/LP_remember.c @@ -924,7 +924,14 @@ cJSON *basilisk_remember(int64_t *KMDtotals,int64_t *BTCtotals,uint32_t requesti destBdest = otheraddr; destAdest = rswap.Adestaddr; if ( strcmp(alice->smartaddr,rswap.Adestaddr) != 0 ) + { printf("this isnt my swap! alice.(%s vs %s)\n",alice->smartaddr,rswap.Adestaddr); + cJSON *retjson = cJSON_CreateObject(); + jaddstr(retjson,"error","swap for different account"); + jaddnum(retjson,"requestid",requestid); + jaddnum(retjson,"quoteid",quoteid); + return(retjson); + } } if ( (bob= LP_coinfind(rswap.bobcoin)) != 0 ) { @@ -941,7 +948,14 @@ cJSON *basilisk_remember(int64_t *KMDtotals,int64_t *BTCtotals,uint32_t requesti srcAdest = otheraddr; srcBdest = rswap.destaddr; if ( strcmp(bob->smartaddr,rswap.destaddr) != 0 ) + { printf("this isnt my swap! bob.(%s vs %s)\n",bob->smartaddr,rswap.destaddr); + cJSON *retjson = cJSON_CreateObject(); + jaddstr(retjson,"error","swap for different account"); + jaddnum(retjson,"requestid",requestid); + jaddnum(retjson,"quoteid",quoteid); + return(retjson); + } } if ( (alice= LP_coinfind(rswap.alicecoin)) != 0 ) { From 5de6f432934dea58f5488823edf514c42d2e8dcc Mon Sep 17 00:00:00 2001 From: jl777 Date: Sun, 10 Dec 2017 10:44:12 +0400 Subject: [PATCH 1664/1664] LP_tradebot_pauseall(); LP_portfolio_reset(); LP_priceinfos_clear(); --- iguana/exchanges/LP_include.h | 2 ++ iguana/exchanges/LP_portfolio.c | 33 +++++++++++++++++++++++++++++++++ iguana/exchanges/LP_prices.c | 16 +++++++++++++++- iguana/exchanges/LP_privkey.c | 3 +++ iguana/exchanges/LP_tradebots.c | 9 +++++++++ 5 files changed, 62 insertions(+), 1 deletion(-) diff --git a/iguana/exchanges/LP_include.h b/iguana/exchanges/LP_include.h index a82c40340..5c009d2cd 100644 --- a/iguana/exchanges/LP_include.h +++ b/iguana/exchanges/LP_include.h @@ -530,6 +530,8 @@ 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 fullflag); uint16_t LP_randpeer(char *destip); +void LP_tradebot_pauseall(); +void LP_portfolio_reset(); uint32_t LP_atomic_locktime(char *base,char *rel); struct LP_pubkey_info *LP_pubkeyfind(bits256 pubkey); char *issue_LP_psock(char *destip,uint16_t destport,int32_t ispaired); diff --git a/iguana/exchanges/LP_portfolio.c b/iguana/exchanges/LP_portfolio.c index 4c1a53ca2..9561bf1f3 100644 --- a/iguana/exchanges/LP_portfolio.c +++ b/iguana/exchanges/LP_portfolio.c @@ -31,6 +31,39 @@ int32_t LP_autoprices,num_LP_autorefs; char LP_portfolio_base[128],LP_portfolio_rel[128]; double LP_portfolio_relvolume; +void LP_portfolio_reset() +{ + struct iguana_info *coin,*tmp; cJSON *fundjson; int32_t i; struct LP_autoprice_ref *ptr; + for (i=0; ifundvalue) != 0 ) + { + ptr->fundvalue = 0; + free_json(fundjson); + } + } + memset(LP_autorefs,0,sizeof(LP_autorefs)); + LP_autoprices = 0; + num_LP_autorefs = 0; + strcpy(LP_portfolio_base,""); + strcpy(LP_portfolio_rel,""); + LP_portfolio_relvolume = 0.; + HASH_ITER(hh,LP_coins,coin,tmp) + { + coin->maxamount = 0; + coin->perc = 0; + coin->goal = 0; + coin->goalperc = 0; + coin->relvolume = 0; + coin->force = 0; + coin->balanceA = 0; + coin->valuesumA = 0; + coin->balanceB = 0; + coin->valuesumB = 0; + } +} + cJSON *LP_portfolio_entry(struct iguana_info *coin) { cJSON *item = cJSON_CreateObject(); diff --git a/iguana/exchanges/LP_prices.c b/iguana/exchanges/LP_prices.c index 98d8ee157..51597b46c 100644 --- a/iguana/exchanges/LP_prices.c +++ b/iguana/exchanges/LP_prices.c @@ -33,7 +33,7 @@ struct LP_priceinfo char symbol[68]; uint64_t coinbits; int32_t ind,pad; - double diagval,high[2],low[2],last[2],bid[2],ask[2]; //volume,btcvolume,prevday; // mostly bittrex info + double diagval,high[2],low[2],last[2],bid[2],ask[2]; double relvals[LP_MAXPRICEINFOS]; double myprices[LP_MAXPRICEINFOS]; double minprices[LP_MAXPRICEINFOS]; // autoprice @@ -53,6 +53,20 @@ struct LP_cacheinfo uint32_t timestamp; } *LP_cacheinfos; +void LP_priceinfos_clear() +{ + int32_t i; struct LP_priceinfo *pp; + for (i=0; imyprices,0,sizeof(pp->myprices)); + memset(pp->minprices,0,sizeof(pp->minprices)); + memset(pp->fixedprices,0,sizeof(pp->fixedprices)); + memset(pp->margins,0,sizeof(pp->margins)); + memset(pp->offsets,0,sizeof(pp->offsets)); + memset(pp->factors,0,sizeof(pp->factors)); + } +} float LP_pubkey_price(int32_t *numutxosp,int64_t *avesatoshisp,int64_t *maxsatoshisp,struct LP_pubkey_info *pubp,uint32_t baseind,uint32_t relind) { diff --git a/iguana/exchanges/LP_privkey.c b/iguana/exchanges/LP_privkey.c index baca4e6e4..db3659602 100644 --- a/iguana/exchanges/LP_privkey.c +++ b/iguana/exchanges/LP_privkey.c @@ -326,6 +326,9 @@ int32_t LP_passphrase_init(char *passphrase,char *gui) init_hexbytes_noT(G.LP_myrmd160str,G.LP_myrmd160,20); G.LP_sessionid = (uint32_t)time(NULL); safecopy(G.gui,gui,sizeof(G.gui)); + LP_tradebot_pauseall(); + LP_portfolio_reset(); + LP_priceinfos_clear(); G.USERPASS_COUNTER = counter; G.initializing = 0; return(0); diff --git a/iguana/exchanges/LP_tradebots.c b/iguana/exchanges/LP_tradebots.c index c5f0d7d6f..39526c2be 100644 --- a/iguana/exchanges/LP_tradebots.c +++ b/iguana/exchanges/LP_tradebots.c @@ -40,6 +40,15 @@ struct LP_tradebot struct LP_tradebot_trade *trades[LP_TRADEBOTS_MAXTRADES]; } *LP_tradebots; +void LP_tradebot_pauseall() +{ + struct LP_tradebot *bot,*tmp; + DL_FOREACH_SAFE(LP_tradebots,bot,tmp) + { + bot->userpause = bot->pause = (uint32_t)time(NULL); + } +} + void LP_tradebot_updatestats(struct LP_tradebot *bot,struct LP_tradebot_trade *tp) { char *swapstr,*status; int32_t flag; cJSON *swapjson;

+rV$f1l#-OZ@G? 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%0D=am7_LAP zftNu1v8*~KzJULVXb5EwZh7h}z7{QVXavJot3a1fK2GvwT3sp~isa-Jf zm5Fka9oG;At=5G!&VCUjnAW|P%y&tToe->sp6u_k(9CddIoH;3XGfFlc_RkJ3N(i} zE*YarR?|FlQQruRza-hx-lpuP2X_TQ-vCgH?=O5HGuL8o1e^3hLbj0-!`oOe* zkmEbD`Aq<@f$?Bs6Ld)v8frIQJ!Nw`hS=@i*jz?>>Yyftx~r=Oa=9z@V;c=^w36_B zv@2Y9U@~)iv!Y&o)B>FhxtF>War}_h*ZoWtgcb$)OO;W#H2uC%D_~~9(g#l3?;uPf zPWn1oNA-cMj0o`Lps8b`t)9)KWu{y95{~n5MD>wz&6gUGh#hAKF|YU%k?=uLzOo|3 zB-K%zYuCywa4G3mmlG`QKT}o4l~PqA3Z%+d%E^qXb|&7$*sY4v0n2_2ns4JZP{vPF z^Qzs4($}GkKXK|XWi0CtBb^72?P{PtE=K7deT)`iv$*=WmhZK&?`4MHESE*Zk;UpJ z+0eM@M?`3}(x(4_&J6;pDDgzVuha@?cy_ka*t}V?=rsnj*h}z5t#mmkRb1XC-Uvtu zI=YC8DCmUpQOE+4c2xsJP2U6*=956{2^_-O%@d+S1eb|?iU1+w<}t@9*F57+w|HHv z^;ft%WUCeir%=cc1+#%w!~{#tw1`T4NF~G*!er|vKb`>aC?K#U)O-TNwcS!pFa%X) zwYyt0{*(R|oF!6(o+7_*HRUVk%S8mnWwEk;L8lPtRNf5bqd8L{gVjkAvsp)gVB)G6 zDU_0kWfN%fiCc$jdG(|NiS-zD8f4T7o!41{IOms?rt&_^-i{@=D(4X#g0+%oH98Nf zK!I})0+n0Bol5O*0)mpSq>r)k0v_iMf>vSy?mtpEYYon4E&E+7wifGHV8 zgDBQYp4Vt4&uMg~>d4=y$O1$bH~}4bGa`dUF=(1V@bDYur^voj-fof~d^lO9$xo3D zPYob%lAog3^D0e#itJq~O@4}E@2fQVDYAL|82R{P$5tUJaU=g*cD9vJR{&b}0!Rbu ze$hI*zuXs>35K8ZD}4O?<1Ee3J5`{-`2_>K84mc#OZ}lRFaL^M9QNOYb?4wf7hA=C z#)+t4f&EN|iu5UnbSY5*;wz~;|ANj|6y!W~il!=e{cdeMu>Zu)2+Xq`%YFmx)Pz+% z^f8o&Mu6Gme0c`jt7(>%ynt<0;M|Jiz=$|C0zoPf7>T|L$6FD7bhZ5m-!1!3&ao=1 zzCCdqImV6ZP+pfz10nWp>Mp#t^(5}1uPy`+r2bZ7NokRlXeuqfptFK>=PA19+3$um zo!hOBElr=S>DbWp31Q8A$chN;St?NA%wj+>xY~Zw-O&^QdG?>wmCwyvv}c~3t`=t6>qy~o z)icJ!*yz|2Y|q1x6NU80IdPIPt2!|r%S-l2R>y0>_E!*Fop?~q1PPA;2sA$KG~@7B z#2)y3E8ef?r@imp3KiDG)a0Zdgq_K|-x`d}_+Z(&HTHVN|EHZBAP?+nHxRA;D5K}0 zS$c4F0HYfjom@i^uVLzsZWDZH;>9>HM~FFq=r3#gpcM(h8>KggrOq6rC`L8-fx! zrF>Ok1TY>|WHn#rGpNdFNikz~kKBA!(uO7PcuSszX^jGOU;Y2ML=!2E5{cJV?B<9(|Cod1Igcp27t(wlKJ61#68*nR=}it5SBU%;@3%oQ=Gh@HlC01RyhUE%-N zS)dIu!To=oMe*T(PiIMg1f7G@4bh&+Uw52>*JkYF)WLK!+c%2B94Im_L>d3-L^Q)c z>?_~bi_qgL=#LD+AqE#|72h44g2ymC(uK6LRnd!YBy)lzctv2DzWsS0k&zG9t)eWf zci!c$Aa;Dsr2_nFgF}pug5X^_rAW__y61RROb$TH#5RFlk!;V}ld)Kg0Ye>71E6@ zCJViyvi@uTSk+mC=xMd*rTG_#proVY`99TfX!`WmIHl%xVOJM05W2uh=H`QVqp*Fc z-tR$}{yvhz1+gUwnX0_gi(l{uHymPH6Lh5&>&xavxbwZ-`eB2YTQK3r+fzz2ebnB7 zSGR}eKs^u*w<*$d1`fdWHEHk8F- zE**eY`oZ3CztSdK#=))e+C>usYNJlX&M6J2oPuy$AJs_I?wVy!SuQ%{K9ykuu6>#M zATp>;MpA{Mww;8ww^Zi*n*oECn)(AjSg`;YQV)*ya|K0@g-;BQO#7*0r9I#$YBbun zf7MsTL!teLf?_|kHv?cye2@5v8jbdk`N0l__GcFw*&T)N_W@u`w8sS_w_fa5X1?YJ zI~3YKejwWazF>^BKZXnkA@9HPgB=R(Ul$bnk(uyVX)p2!*F|lwDCXX6rUht9UP#kbV1vW0N&)ow`X zcfl6ym-Z^U8#Y3U}PC>CB+HC-giS{r1 zi5iXeNCP#IHNlk~TylRpDq5!Q3p|{aF7eK#nYP)%cwZ(-rlm{z*Ma0w2=JbYkL{`$;_DQ@ zCEc2&K)$<$>z+^m7p+T5mYqn)HXN+*L)uf?=#sUjKUAyeb}$MrwQIFwy+O#wqhK;S_0 zb@-&!#UcE=B&)J(G2$1qm^g~TH*-PD#r(LR8zBk;bW3^y3%+j3!GMx@wZ9arAak*c z1a;u9X2th1;ZvC=wCrkDqijeuwlR*?xSG`{(|njo9Kgj!7^MwoN;jQ}OeF>-D4wa$ z1k404X1c3mzsG)({`)2B`j4W$DKmkld||HnTxfzv{&2{P)O(j`m>dnk1!9?7Q>(Smp`E>8zsm4>fne#XlgI$ZrT9YqIM_n-<4ZRNNT zLV8I0?tCq1S{xr z3C~cxTy_k*xQtbq*3Jn_U+-@mCDZk@hbAyD`H0O>VU%|9Na?LihdNWZC$iiItyKW- z5^ESz?>P2;3eu^!OPX`#szl=R zwj#qVtOmG_l1q?YLGa*r+7$BnhRzvSP7AhQj#yL!ACW8|D6&-H7uFwGWhHakj4-=x z1&HZ@aNERUVIsr~3D2li2|u0HM={f`rWSEy?5Hgm{)-+SK zTO>nU`%qL!b2>D(Ub7YQ3Cu1}P`O&X*NSWdw`Gs#btBW`Q`$y|u87ZX^A356X>x^% zl^PfavVaKZYXs2|=mXy!m#$Zvt#HxoG#O}t)@3dGY^HZa1f3RFfQ39nNz3?$-IXW> zC05AC>&?dr&sYrGs~TTN(6(1CNrCNk>j$~Cy&CX((K^rk;Q;5?%<-a78O1_$o;oxX zfc!HGa-(2ysurhzc`yw-Ju)ZgFgb8>6zM$J0c`RVqe=s4682%0w@M$<0&djbg*!Qm zwH54D8SEC7MTs4vH3QB|m=cYv$s{}-;d%+<-pDG_+n`fI2si35-MLE)R6U`VnzshN zwP?6TBaYkyta<=LTl=8C^`NARU19(qbO9OCfb9sP11x1quAR#}Dv}*IyD&{U}A+xYa?SjXDk} zmS|FGxQ!-Yp>3SHvCW(-1>tM*!fu z13$X7SYL1m@?iUaWRjucmRxHR z>lXIZ@q5Rguv!nHc`3eTbC)z3nqO`}Jwg8Ytmnym!xVi_gF0X?&HlexY9Lu;*|^|$lvs^b zQpYaaW6z;mKIUYjxk+t$4rYa#@<7u!#*R_v&AJA|-&kv$o~wGmDBW=E2>%&5hOy9X z_Z!dp|B#pXw!Km%vAz%{YBSBSsMU~s(PryTd*dKC*ESxH-L`P%Kz(se>Y88adR|`V z)%kz=@o=3lazpRQp_b?|_|g+_Wm^B|T}<3{9F!5LJHXpW`oEAl_>Ps3i-wcae+LP|MhO2_hOWzWQ$C8vQ?Yiw)>#~e#U#6o|ec4EGtx8~WZRZ}4qQ-58yyG@a zQWh$9Fqpju=@wm)dQ@_w!a|#-^W!QDimT9c$W@u@_5(HmYm}k#zFcBeQ#*9rUcP~7 zmIeHLO;`oYq^f>(i7Flla1W3Sw7HzJaD3YaU{!$S8Tsy$WVZkUc?#gGd{Bz>7?|z} zE5rgAULv=O^VWeTYiT?cQ)!VtT6eL0cJZDD&YHt&Zk*9F(~L@KwZb`(V_H%q>8 z$aF#_{s5lL=|I5&1784mY7U0Rpa>D=$9)Ut#dhP%0=#rI_Q61~ zeJ|>loKp~cG~Zg(Q=PrHa)Z4&_Cfx&S5+q`y>0EnBI2WAyS?qs`zHtHWv2%FP{`SX z^9G;5aw@5pps9*_VNG<3gwB`foj!1KU+2|)8w9H=!GbMh0ay!GflG!L6DRn2@elGL z8m|i|Muy{2%}Ip7O0q7TdbJo3+0i(}Cmz*&#IEdOyyYP_Kh5JHmK}xQwG2dps~hoM zqZS^}J|_?4HzKA4FZpP(1`(@1C3clb&>2o0~5I?eXE)LW{L>&fmwfLnw z27_^Gtw{0)kNC~(PAqEy+#Ku!uc0`dUSpHt*XPtg1@+;m`7Q>ImNoHv; z{fEC&S|ah1u)UrV7SESJQ8+#q;`fLM-7W~-rQ@RUZ)PJFy%@1Y;nZsoy1BWC&7+RR zr4{Q-!WZGV{6aY}zYgEu`^K8dfv@42k7pj9Gx3~;=L9@QjBOYp zCcbu`QMA`B)@*%=l>K zv*FaHkMS0X_Ag>+t4>~3uy}Fs*me-aa}wvjAGXgQs7YRfLAAHCH)3xLr#6C%8?01% zLTtyGR_fIwVmr@_*zMovIf_VSyUj&L03hEU0F49Cyj1$=NM()Lm%X7f z1)~jHlq!3;e|IoY34;jYzMWPQ`UgOj@wYuWF-dXO@I{q9!8MyJ*QRztsGqfaQ?H`q zZEf2rHr2+|&Ky`~m75ah=Ol109=0iWZm7SJ`}0v)qW$^V69ZzjzRT|Pko0HWt!C?P z1)bvUPY0CUmAXU8byOpEsJO2~#d#;QuS3Q8ZN6b0Dy} zp{6;+`Ix$jN=?e-E+{o4tAKuTmb|QIWc5%L?sTk4rel}Xayka{EmE2_FL_;Q7R=$f z*|d!@A;W=7GZ#awvWI)E#IjnvDRa0NA!QABA!LkUnTyHgNw6J9o{!Ob9NT0}Ok&to z&x|}7Q;n3U*$0bqkFy;<9!$rWhtsir|KJoPGZhQLB8E9!d%)?~r8C^=*z}%%)^sd^ z8f#ZVon?6OIGj=+A}^xxDWz&UM!T3!5;2R-Tr3j5U|b|VH(RV?M8YbDy*)PWX5#_q|1EVD{STM9nL>NiWuyU%ob+8qAK^y@_adI2p>1B$nNEE5NhY zrUtTct6S{dGlMt2PYW%$dLCsUoDE~uO59u8rKIFaXlKk2@06WuHMUcYq*f%M!<{;B zFcm4>i^5)%+~P*t%V1u_Oyt8U^;8e`{A+AC>q3`t|`{7G*}+M7et7(0K`o07I~NE&13PueGGZw*Of?EFb@N!r^( z(il5`(%X{uj!7etZ%6Fr-FEYvQTvhTjK2h9zrr5)^skH@-j0B9#wUQI%U>jM$&(4l z;9aj%2BY^t6rz31-AA z^MVj$_XY+3iVuFk3vXT`g#$`V@F74YCJ>9a!}dGr&$)6EwciQb`_d;-PV5>ZBhU%& zpf>MCJ2qhdQASXr$uO=*g_sn;BM+InC!H2iSx8aYq(lWh!z(Hqw)8R06_=?Z5>xk3 zj67)~E>lG$rtTe*CgL(xL}Kb2L()WCriw^ReRD{fh|5$FiK+XBq=~pp6_J?w){rz2 zm#ObiT&BLQ)4b9Wsa%F`{^v;LB@al;UW}IAbn33bd5gNxw%3`qmCg=tpBcUoG!8`i z0JQ`0cmeCqfFWqW5Hw&jBK9RuqEI8L--e_@yT6D5;FW4y>EcMdB5Xg3JYihs$pGAo z;Vc!CdL7=yE5}vaN>_*DSHjB}&Jif2A)Jdi*uqN9TXxMLH#y$>GzOiv^&EgO(k-~? zD+|}H{Pf1jfluH$63;|D9MAQ5TJT(f=j(Vb!1K^!lLP;a z=a+a^;rSk(Hatyu8u6@n0`GXP!E-sDOYnRd&pCJ^csM?C{%4lr`kql!zu@Y_tCJUI zVX(=^0vv?yylgJV1y^TBVIY}V2i|AvX$OOP&cUFJOT7_n<*eYV9-KB}2@S_zrdvtg z81~ewuw@Y7ou>;JM*QoILrVITHhgDU7!k*L*Cj)4qX`wlIa4 z+C0XL!|F_7Dz&qKFFEuz6>eZKw{SCkNrfBH_qaX>cNBd|oFrm_asxa}JCCUBZQB_D zlkJW0fK~!>Gm>{65w6_qiw8K6Y)%u0EFY$_HxLCpT5#*afveUmH=uBOvqpkM;eo)O zu)RIiKe6qlJ$NbH4k|aK`g6kO1YZ%N3b*4Xw83C?@-w+$f#~1ZnE|`k?rAzQwex69 z7}DbkQ}$Md;bj}we?)5MNA0zn(<<_#Trahs6&!`zVfeJYM07R?4+OfP#(L(#UkBfC zjh%wM8gA=@wCAI;AgCHlC0Jfy-e$*&b?2yDMND9@3!w8-&J?R~v!wK81>k7Tt1jGN zZ<=G@)dSY38O4(_f!|@}fp1P8sK_ywOdWvF0IB`rVbuRBK&n$w8 zWQx2D**Z`Qo;d3^i>P4MwBg^(tZ4v)W&_rbnqoCI&IJac7ej42rOarIpy6b+#HW` z6^-LW6!y8S8%E#cZ$UizmQHwE;uCdG#q0LPqcGOr4z{y>LGHHd^1p(qUYLl=rt%)`iI z!EkH^Ec7B>8!gnLjWWI}{dh0Zs2^+W$BlaAnXsk%(~&C#AOli z4o1O->dxoaAe2LDZ|Cjcn$!50QLW!tVN~lobVx;$4cPipcTv=S7aK+{jdD$N7j9>N z1G;n#_H6;?S_EH&W8yc}iMofY6ALl%yyPBCrb5A+mcf33sR~DKD9cLRCL04$p?Z9b zM14LpxVj4O0Se&&tV@JL)X0Sc^hwD~1u@jhjEO$UbkWM33WT&(zg@YUA~4UQGu{s_ zzZXmP*uqeqJb7H{u0iDvvwPqzOTC*7?^Df>@1sAeyeAR;QKIJii&tXmwFWBpXV|Qg zSoSmQGf6D`MYQ~V=VAZusMsKsGp&Hc%ptWFMF?0Ku^>Ustg6z;1haxOP&c9 z#ob_m1S9faMk6<*fJCcHT>MBo`WqAx8z^ZWZ@*_hn|>Bui!P`Mn1k8d(wp#Vcf(hN zK?odsB_4Hbnc_y%+%bu9Zx??tAik!sM)%10AR{GL05Aw?*KhQ#$}S8Wq4=^_QoAvr zMBkK!fVwx}#(E{bupbGp+RJ{F!o9xn=-VBG@rADkf6#?vUi?|W=bzFbIG zox{QLRs5^#$1W@R-iW>M`}UKFS-6V}JQy}#32(uOzG;ht=m}k0U>|G(-kb2e!sIlX zs*8yLn*dvIQ@qYWR7yqdKo*sOaBEfM&d3B9lE6~)D$02c3F}nCOA%tI`M!<_u3q+f zWWu&BFNK1uyBQCtnjcMowGrJN+VYBu0iw`^f%w9e@rADe?nTu8-|)N+i=#ghU%0FP zDAobxybk!+q+&ugst{cLT%Q%5jqsQ72VRRUpc{@ zG;5+irYFsQ3NE$k>^H>may3M{quz)#I@MxsH4LX-_ID~epv-1N_|VK7g2-~c%JPao z%YXqAyU%@tM-AeR;wkPE?DxXEwz5%gh# zkA0;g=$H$ut^r#OfnqTd#aF~WApWE1TM|Ih+vp6t*%`FVi@ZnT%XUNNBk@b#bmjhc zl=}<*{Qoz(|F?|XuN<@7Q=HJmuIzI?;h^LnzQ3PY*>Ax2_X`ohuR=G4A%!hQ3Pqcu zsftBC>Q+;VRa%n4Nc=}7YcIQx=&d_C`R^gL|Id=f+Hi*)~S z*bBw0M2^C7C|n3yI3CIp6$>#5$6N3z6*Yc_ppgLRlgV-(Nj^e`>IWG5!vX z@y-;+_qO#M>(we3zErgaA0quNo}b{k8PAP)zJ=#6a3aVlAEN1H512V$ z7p8fgob(~`9QXp@J?nzi;ZFRJUI(SFw=DEv8puf@%nWR5z>agw{5Xig{}#uH!7xTT zxV{lUAMS^~l%D^Z1d#N)1d3rA-5p8P+>5~m)2f(@(-|Opi9jG zFR8(H#bnLh)pj>#f==J_qAu@-e0Ra8e=h{52WS)_BU6E43*+!;#Gvr-;Cek1bYv#@ zS>H^sS*GdBdO1UlcD&q#&-Q|eaf}8sfMZQx>dmdLtS(1wtleWx{~WcZk4UWP(=UoO z{d3HWa1VvB@?o?m1oLiG9226Yqs$0H=iys#>;%phN^NJ8aDM}- zU_R%8a;#U|>nuHWA*u0)P_pusU-VV?OIAu^MP7%VZ|Dq>;NuLz>MWaOry*$#*zWYK z63f~wh+EXA#Znwx4Z9Y?1QDC1ybug24+KNBb1|$%U^d?Y+=!td;*bs52LvH(=p{Y~ z@s8l?FXkbt%HX6e?V=rsBre8<7Y6r$iyI5f>O)=%x1dU4&e@3qu+pe*M+vq+gxMw6 z8g55yIN2-%C^iFKuX>T*3zQepnoFqGy-HQ9i^e{Q&h)cPA5;BHir&B@8i!*9jwG*v z^WnXDsn>Br;!!!Jfn{k@#U+hZ#B^*Z;O-ZO;Rn<;IWUn>pz`H`jX1f181eWqpw4ad z7WPy=gSR}j%1o#pEE1F<3KR7|!GyPBkMPg~JmQs)!80(8B2wnuv4#B*hpPA~@oCY@ zZtND1Rz9vf1rKmYuiya=(FQocA>AVqKZ_gax^`-r!!t&r63>976S2%?LUP z+uU$nb`uRC!adw!Wv9*Ij?1c(Q;+(H*-f;(Zx`n!YX|$l609yhj@1KHPC~4#8&;lC z#xt@`0Jtjdf|6+}n_{UP>cAdVFb4ad`IYA~vzbVJ_dCO_f8G2cb1NEG=UxivjT)2w zNv{*%2=0ah`@*qDc*3IrCp?yNH^kX_=qKzq2XOnBufAoMH|cGV{(s5>PA z)a(fq~qv6U&aKMl9s*Zmk0Ln38Mt~|w zt8lL{jO=i$nagTYD3ejpkBWyYpQ*e>`cbrUeWWsiRk+wAJQ;=aA|Ojni%flSGS_+^ z!D*4@f!B1;`A~Lt$Y~MijK5N4-;Vl6;#F#H0RO+58-(N7m&K_7M$z3^(!CxBMi#@I zn}eecoFKr{0)uW24vZ`ogRT`=Fm8st<0kfZN79o6Rd}Z1`2?P$@Jzy!h36dyYp>7< zOYnRhPd%P<@yx|D6VIu5)b|+|->=5n7(T~%*}uHz`3S4|9&AKGpudc-rj+8_k{s8* zgk}V(J8=4`Cq)eshR|ZsG38wyv}@&Rn}uI z`&BD>YZn+=ZLh7w){)84jxEi((aH_|U&PGxfh;%`Bgu2JIMCo!=dIy){uU{J7Uxh@ z7+*yFNH};`Dr!F)!78J@A!0v?&B*0F{adij;#*kmOA$jfQDDz5cxPL1O;Bw`983dhgl z&qRr!XiXYF3qSJ?gD@q&cnqW{6f8_7W*t-coRyqaqV|(TZH&UbQTxj{MYJikV?35$ zxklPIKDcIM0@l|T(Y>%@o*%|AkL2K*4G9ZT=N8ylCC`U-pV~Pd3$cg=@GKmq!7_M0 zme~aZVi9w0k%q-;I$?VfRuN!vJD`G<+;}^8AogDFveS8fsc$^6%!{op!C6#hO7-Ut zu4C44;Z_`FCT-R+xIVHZ_Fi6aMU@x@XdS(NiamO;RJkao&(c<)MVvpZmOdL>=G(b_ zos4+PWal;}E*$Yb0y9gtZmYh!Qx3{vv``iqI%_XN=&by~xWai6LTX542wdr+b@rmj z!SGGnK6?zUawHyi|8^0y0uSsKBa(Y(^&!!0_dG3*n#p{hmA1@qIQKV|7``kAW>bHmU~uV`(;WsOi1Mo> z(P5MlMF~O{9iFD`MH>x2O4ve zhiR1zQUJx?%P$Th7p8oI;S}6n`mw zzEiZ-VlypsH*i0Pih<_ydH&&S3hL>2#2!UQQk9UE64jT6Rial{g2OA%&w6%me}Yxm z-|p=NI6wRN1j=_e&(9XUt>qgQkvbl$Ti)Hct#`MP1+oVYn^^}psag_7)jON(!*Y05 zZQX{vD97iJqqAZO!IvP%WqE)$n~RtYo)fepdvd}S+pchq7E4nQFW5w`@WCFs_l?Pc z-{ARoJU8R%z|(@~ay*OhEJv?x!Sf9~|AOZtJoE9)!!sL?wij>)&wGA$Lbd&@eFk=) z*;nR>OU`~F61=MmOJLZqBbS+A4YFw}7!(bz=|yu#%6pY!>c`x8OSF7*IQ!c<^O9%f zMD4FkL}K=Z2;usOM~TLhw@32!s3{}!Zj6?1f@xu|!wK6+aLqP5JTbyj?pnuO#i~T= zw@5kMmpaftJ^~F{-W4rhXJ1(aWSFwrFNCwZV2hwYxOSc+vFkwWbCMMs&bf5M0-ueP zzYr~9rE zvcnju*PyFxLcSgtNX&;VZ)-M7J};Xh8%68{rU0)Ye)FltoP zXl^w&jEx?&u~5w+_a-NjAQeQcbYzNCX{#-j#Hytj3}|i-x7sOf^;f5Lrk$C-reixD zijQe?6Cga~mB_okS|2y0Dn1EN$p5?6KIi5pB#1)C>HN!woAcUx?X}lhd+oLNUVH8J z5qnG6-o(tmz1y+7wQ}Qd=c2e&e(V^ya%Eb%Qb})BkEed{rcb^jWk4%8Q7Z>AU?-SK z-@^?*UE*DD>qdu=Sq6Zsqrh9%7Z~T zH~oEaZsv*L+^l2f++3~PY{R)5kDYTjzc0?sI}x0#J66s;*dV>4G`rgk^A;R4^Bxpe zj`zdAUo>gP<8FKpE)_V(*!~`rc?+rNqxbu{tf)lXJZ5%2_>clX`Mk%r_=|@%V{=m1 zywB$N;131P5jt_;7WtsepK5h~mLBh2 z6&_s{d78D@<_L2&qFcSFj6}oUH)JRpwl=ZBoL+&hWV9DI9ZAV%wKlper=(p6wk4az z^(s&I8Uv%1F<73H-OQLT&xsBdpxJ98gfP-Q$|*jv{pJh$xn^DdV>9M@BGdpTgZZn< zKuLX)eu~MZ&Yb=IRlh?Dro{O9zN*g`=s-cIP-HsHOwd|7WgEDwCMQv3w$DtTr1+{< z?9++9d1iJbqQ0suL#3-&Y$4LN{XRG#5t<3>g8Cgom+$I zJ;{w$&p28A87lP!w(5fQaaRf(`d$2}F4GaZ74mInkMM;i8(wkTsq4$02Mr_A6MG z;V}4O#G2X9QT3sJhHb34NJqj@;s{4o-8Pn}{1?Mq)&~d>vc-)~3^|XBKmKnU$hSH@ zZNm24tF~j@E*ue=us)J|)%u9Hvu4h^CG88(t|^ht2tj-sNRyG(#FRffK^pg@*S|)4 zs~O!hIhH@#ja_oqnVbSOVbfQM$Bpm4E(7m$_wBANi3j<~e!3gGIvpc-Ig_k87d2hk zQ{9+IuV<>6ERopcVJmvT$-&>v*|*y%+3(=yTf>kJHzU`Z7^0-Sj&6^hSmr0A?)$7RN|y0J68{#l4B^H{;ZU_SY+A1Fnc)uU1Dq$P|_&L^80DVa<}yqT23 zpx5AT+@Y(ghv{50^GL}JKK`;mpXp>7Xbek?!UYkJ-e0rH0yR>qbIE3`&Okg}RHZC& z_!G!7TqhM%%)T=(Lv~3a>)DLjC+j|+e#^l+zdZ2#+!#~Ce)Dsm?>9du?OW#P`1zg( zG7XokdsVXTGBpQf{HZyAl1>(V{Mos7xWN?G5g`@ed!Gq8e*#WQFf&cM=CYY&l~Tfy zvvL0XRWh;|%cIE&xt~K=or)4qyAv5o;g~1n#vbSjBHP_QJiqURoImSmX5RWt!}&9e z@}+k|4y7wp2$CyF%!5xeT?8FqLheT>f)hxEaMP)((z2Sw&q8&ZKNrVRk^0|TD6))T zDvsU)RsNo)iuN8~vfzhyR@hy@ZRhq!VHI?dOaC)*s3-7tiw`@J@xa`tTj zZo4B}D@Qp+Eb1hNIN6&^*e+>FKo#4=e9|vG@F~aR zy0-H)HC_G1Jb%Q4cISVDO^?|vktmK>mHtR)5PB*Vp=J$}mCQ0iM4=_lRXng1Dx@^) zYu;w)nYXW9YQ4FL0BP2Yy^hsEwZb0p(OB8a4QCS$%_&;%cpdxNi#jC9TaL9^lf(f# z%8!kPsR}iP+U=w++AImX6_jiw9U05n0B6}r>UDVQB?&MU*q;;@UGwvq@kBO2urqq; zc_{=^a>kXM@yv)d_G_#K3JI+Y?u4=q@AQ?!tIlF2V9IE5y^I!RsqQ)C0jmkxQVcYN zl>G*bK0Sl|zWv6FqrR(F&b#byd>`XQe}JgHIA&TzJ8`)Q28&56sn>0y@7~5Y*>^5O zD;*yWxKSq@I_|xV?`^zz{FOTE1XT((|K}brzWIO|Qh1sBXZ9H{{$=fFl)m2|C1S#+ z>}R|_7$Sa+AhiAv@z1`OvA!`FA)cUpj9*;_myR+#RQun=SM%f7o$(#zYpp2C%!PS5 zWM}gfJ|ZoT7DB7qShRslZXWKZ4RYt?j&>Sy^W6KnslGoqul!+o^Du87kvEUk*-kE74oK3-juqYTfV}j&k8pchs!5Pr(XLYtLwIH-{@CA4x+v#9!Ut71 z?jN(@5z&v7`(`kHmB{6|yOkz72n3CzR%tZj*IYP_>esS+eTdt5c+7%bz45q`>3bG1L)*{8RZ*8Yg;f5;!?AG?yn&$NPm!%rD71mnjwy$^i`q9?*1Br0(tB%a}k zp@I^yAZ6#bzF;uQh(IRTm|Xj-KgdAi&;N`5Apf06jzJ3p`TmRY2U(e)pZ05hKjHV! z{JzDniQiZF&FA+Ir}E5iA-_BLeUaad{I26Sji1{0VejfN9w1?xNy?ox2O2Ze+<9~+ z&8D?f5-!S>Ss<(CZr8LI*|THwR#cR=^lNSoSNqEHuss=vGzst{o(#;B^FX7D5Y1cw zM67Tl0C<%JfQY@gQ2<1&#hw6&*cB65+V90c^D{%#KR>Sq$zO(7$MKXu{y57oHRY$) zU1)L4^=JFVan-;0IO`ue&hiV7v;489{D6Lg^Il|h0Qo66&hm-jeq8j=JI?ZRjs5>b?px=8|7pU9gDj#)!T=l2BIj-{Q z?vAT`y4&L_zdT}34uiwd^+oUglz#Jv8}Bh=y8ng#CMU_+LMOmAnm!&R}v8z8Ckt+TcWWe$(;Zl!yfp?|@f(zxSyhiC;+VGX492{(T5+%e>kr zBv!{)7du=c-mjK6L<-X)+54;PUoCE^EllIOw87EqvW9BCJ|x$O_s~P~J^oTwcKr_( zM3aIbj?_z8^89A@SC@wEeeyD#y`N=nf+TI!0932}<7EEYUQ!qCL;I_UdHr7Cm<(Tpjg2GDgXXi+60>*xHC!=r(=1z%? zS6sZ>AA*+Vsq%h!o)pe(bDk!f9%4tzvil4o%RVO8h`l{xKNYdJM(kx11Y_15DVH5@ zJ}I~pjHdW2b9~l`&Pm=w_ey@ytno<$>93ID0up((Ka;|E( zaBPmoTpz7%2EaK0AY#jKgN~t`t*do~a>7FFLun+a@Rlt$*lnn=mz^UpCfQ4iq)?uf zJ&Zk{koSz1ekDnxwJWQ=bp(AqM^eeLq~((&t8mipsInL9dxC|yV3x=EVCPCYMO_lR z;&VE?%3G!~QRx@TwMZavJy)(_C{s#agMqy*Ai2^Bne+*@7B9Xhq0%xz43-h{e@{Wc zdKXH~Mj}-tu1v~KIFwcCnW_e*RoTl_QdNi|_BJVNnr|oPr;N}NToO8EzJ>%RN6}~FjZZeEA&N>zd*jQ zy)nW@bUP=+!Zuafk}RElnMMlp6^`RQ^fAe=90;lzj^>2in4bW-v`M4F_fVOXVLx=4 zJWlZ&R1LTx3=gT$+pG`Jurj1=77OiYCpaW8XL;FSTw%~4+%H&6@k^NGJ#nv~0G5J9 zR?z$<{$zn08>@H{Klj^PyNG=_S};ITPf|>{sQADmq}JX<)Z;IbELyu+rG)757YV9J z-*lIz6+00Fk;nYL(4x(fTDQhjefbg`tbVcDbD-W9EV%6^s_vep8g zRI^kIFn}(S3>q_2n$ISC9RW{?xHaA{??M9?eEejE6s`|kweTt_oR87k-wAzGYbc>0 zj9d#KJPa{9=dEsAzW|3-4DK2^plg znLO25vgM7G_WfqFk7YNkk!n-y@&Pz9uZB^(J^i zTMw5~xMpj;L807UmLA*}6BZ(R&2!{^jMQQ8heo))%{8&iAITf`ce3kw@%;jXRLgjW zI{ODBLeoQ2(WY7*u44p!G_|5nI0mVZ?k;*KT+zb9onhFi25@=Q4ViimTHd>ny zmdu{yEmKiJv_C2Z(Pl0cNGh&UhP_5)`;U@%CJJ1+jXYf>iBzt*8oA=!xm^*jLuE=j zo1|Fl9SXou55Yo0lxOJFq=e8B8?B3CEtT4F^@W($3TBSC?Auak*lt%%ucAOdhSbVt z?qU%e(L+)V4zx|7`(EpYqXUVImpc&$JNJw+q~vQW!@J z(t{e=B%(U~ZqT2IroJ*ZR)JD5-a5Dw(zFUHy~WzjkyF!r=-FoWb^;Jknno=1=bMjc zHb#p{vzaSo$LLwCWaoORARV#e5xZ3)a4_$Ui#k`uiP+w3mzS1{M9u&%0+K5kI4h=# zM|i5*zed8AL$1A|qfxHI1QmPfP`MC~CR)3f{HKtC_LJ=k+6cL#hO{o&3nuD>&AH(D z|DDD^hu}T-T6nCK(B0)DJ2nZ3heoMn#x7aOBUD)~kfdHy>5Wv3=uK2T$pvghi*wOk zga{=p=S)7(RElv`9gSWFb<7qv1YjVDvP|YPTHfyjq*KJZc5EnG`=_Kt%8k&;S8%>* z3ZU6R4Vo5x)lsOBJXd&%VNC=)p^s1e$@gje)gn zV1|n9pagz+sZxoDsRLQEI2!&;NhkKw+&;SBD0gp}U%qKzzJm4bRlhk6sAz*$>bI@} z`pA1kF0>;sraTQ%%f@ciwi9$t=so41m|=mXN(=~SCvCK!sru^;1DmSlV%YYzR14vG zA4`>HGxE#iAJ|fzX)M(lBzPZ|YG8|s#W^)v%Q->ic~k}k zicS3S{~$MY53Iw$K&AHRaNl}WT1yPPpt`E&leQ5AEA3~q2F9vyyQY|{1d8zuRN9uv zrO;W`L4blZcBD|P(?ZdZfl8oDP6yk8jncrZrLz?gm`RWO)Vi)7ds9+vATZ_8+B~Vu z++(#=2eVKE3)bExw(3+hQwyTC`2xI9dY^$T)#9Y3T5vQ=wY0yb8m%20D9-hP)hhhy zqePS3NRIPSOueQe`ZLv1otd-|2enjn&W1LIy?Ru|DGC$IY;YSD6Zr}4KH;CU)^xUF zLmNvu#YSb6DR%KuY*dzhj@3q0r8kg~`kOU{QH4W2nZ?{4W5B^v*=Pg|G`sjQO$j4AbMws47}pEYOO*Wv3a# z;B2|rOV2V%mYyb^q;H{)la%bRC#iP8TtQBe3ESpDdO=ye!-6!XoM>I6Y5H4>kg`|V z&|p&)ES)d#=o1;f6eJ4+F`my*JePe_%JvOaqbMn`w=g&*lM$l0L=mD)1I0=s`KEvf z>{QQyV(Y>^tEIzScD58qzoOIUZjxtM!~4cy)e2{*t$TUTgUOCx6K+@J>B} zo`St6A0P8}y<1x7Q0A znQDen-mB@0WG;HvxHj!0(&kouLc7nsSGZFxiJ7Ezwr8$q2w4 zSuerG8>0+MZC?b=LwV#8?pn16gCK3P3<@+ATE)m-Njuz+drM7wwU|dibA{~=b?gjB zPYp+JKv|*40w>RY`Yr4YLAQP9QPFLp)^-s$59J2R=rc5!uhKB1o24LTyY3Nf#vspE zA#tiE>dc#zCE70RHxTd2oJwD-h3!*`{WnO+~ zyt%iE$H=(40KI{#IPVx4=S^M^fElQk@b30wZe&s)YSzza01;JTMxRB`4o9!;tH=7q zR~Tgf`jlB_jQqdQ|8)Kda@G7_<$wCU{eLn3r}igRG+Zz9veN@EM3y)8d?vcP|D*BF z4iRPVFWUd~XV<{Cckw^X>K(s1Gt5EVk(tVE?~}9K*qviJhn6S>t1~9x724`H9xS`< zLyn$-gv-E$nvzz#J<;-o%rxTid)uqMjdHSaVt(~2JsM7NKRhHxnf=*%x^Eumap=Cgrph5rQ-~WkMWcWf za3F{7KjA12|MO7J_2qMx$y}*dau4@Ek7$~b&F38dvtIc;(*HcFX-cl+&EO0HQP8C; z=*M8lf>1fuU(*ylS|G1!%4nSrZ<;cuX~s#S!^;SxRw#$J2lKPPnxPEAy(Cs%&NidO zCvM41Q($dYdQs%2wu+4CPdB{QR*`l1caJ^LR*`et^o#S_D)RO|-wwxmkI3-P|1i*i zwUdvJk~6Fn$>7TLsR}%2#^a_#cM43dAM6;21YHWo&feECTS6Cb3s$iiKGc z`vo93hsu4n)#2?4F>eS)2Twj}=y{5?GR`j3^Hius(Ax&z-oX=>z##W^z<}I~WQH$tOsyFO5xV`0*8lyQx2C(SdRbtvgK- zSetmO=hdEQqu_xjxyr|i!x9!pZyVS6Hv^xi68NYSEMYhY??w-2ur5 z?af{O*&G61M!fO`xyxXpn;3vw>C|rn0o1Nf3S8u}h zDzg_|_rErq5tP2ci~ON)rRAiFQ%fw3iC#=2v_rE#X2|PVOW00}AE9g|3%1{y`6S+u zeVLzqSxR<1n0VCe(=HL!3XwNtU+iaJoRXbz+&pUb@DebpNY92M6+^@y zeJ_8w=OBXI^k-`@+YT}=jQGq5$(<}OPi%HEX`kYO=C$dsOiyHqywy5G0Tc?0g4}9b}B**1%3ust#`0(>eJ@U&bJO>cgL78mPQyJ`Gl- z)cUA(_U;1}-{6BkoLCxZS`e}rCpb+RIMkU_>BFJ);84?WXoyElU_P_IL+)@LW?z~- zX38V6g~Oqt-fBNdmfR6#I2;--clvdNKve)aN%$k>j;}X|IBD)?P7ZCV3lVgMQMdy> zxjJtmP(}qFY_0zKTri)lo2dJZPdi_e@hQ&l0}M|y{yIE8rr{~J*t-r-i5>HS3{Ow6 z@(mPK{<|uwKn(|~7ttMf`r$pdYV96Rr1lLo)!6^VnkrDcI(vf6ijh!wEW^{#yD|#K z^yk$HW7G*YJOf6J``{RL!UqUJiyHp{GU^2OlgMRR>hP4o+y^t^!!Y^JW1}(PewUfK z<7rXvHavAtY^8!0Rr5i%s1rPi6||`7e^y4l+wgSepNCPiJ`hF)b@7L%Ob?&P;pvSZ zD5K^El{+z&3R=|7gD@)SYx@j;j=DbcJ`ALJC$>&Oi^8G!y2-l7KUqv&vMPaV$% zhLR{@S!qfxd-b2d4;Zyz5JvT3&|k-=|AXVx8P2t=Zl)8oX!7&fED>H-;~ik}^g70) zpJfnnU5;7yi~oTKLe#&Q#ht$-$nj`qZP3XKXYb(iP=}A^c9`DA?yI_I&EJ_f!&z1J zI!HBw5M8>M%Aw*sW(O;*BeOXjc>`}o0Y%~E>Wx`3>Q7LGgJEws4@7I( z4sPMt*JC-~;85lb;Os1Fng8Y&CJw&TYcSRll1(NKh|^Cy_ukZU2gF(`igQVTd0!~F z`?HRjg83>rWXs+`jvQ8>lbt;5bXo_-E%qB9qv?7^+8rodCg*Q1%&VaIZqu4$uq7VjI@vU8abOr0$U?#niNpUO5ms8;~GK zYV5&poO5exkw+nG@xV}!)Q(gLv@xi<7o^99t&KphNo& zWL~@uXxHd0L&s#J>?5-}ooL$9cqndnA;8l9w}wl$M`GSZMHMdy<}XY8-}JjD&UlYh z1;nQ-?^%;dlcP|zEU1R2??o7NQXw$O300-}Pvq!%qyVJseM;1Arul#G(K|l+-iZpp za)Vvids_hcp?=ZG#)ZRI0Ye_BRC|FJ%1WTGtUkEbCt+btP2>)h8bgOh%x%S23 zpu5^55ATtzfH?CrH#YSxZV-o_Xw}R?5C)x82sANKt*{>j1zBg=U7$s00PFwo;CH_a zfmPU&os{D}Ln97*Pm3}X21sAxpb`~ovRQEYTUS5I42tUP!B9c7kb`nWj-;OyqsMEd#M=V|1>atsmAf2oO@gAP z<|p+6UH6&Q>wf9`OMbgV{VU~6rs3*W`QnS}%UIkwaeGf62TS!xPJG6sZzKdnTHVRS z%la=#Pkf@edQX^3;c{_-r`ULo}a)VBqNb8 zBqISr!l8L`SD3JG1!m()HwAa`5;gF)ec1Sq#xlqG@CF95@s|ET`t45({I{1FfZm-% zb^9c~uf~7-Z2Y&|+{T_%|835zZo_|jh=c!jkLz`)|8`Y+;s-<0aKH8axBWy zJl}u20_WHc)M({s@!zgc|LrkN73#lzQd5QcZ|65vsQ>oKO%>|DeM(b>`fs1wRB=V( zathH!J$2%q3H{hmY`M`2oVY7+;;z7txB@5c3Y@qraN@2gQzve9&TSfn$oNj&_*)NA ze`?>4yJ<>>eiRq(&H}`(sj}CLyJwlfE{?~cll$pl=I{!%j>wa!WK{BI_ECGI*Xvg(Zza# zd=dW2lhO(GNB^m3bx$%!DmU}mGG}#jr{`>2Yr@%tLtGqc0zY03CDxamI%>D^-rC3; zbGY}Kc--P)c({n;NKwnJoJuEQ$(RV3G=g(K<(OAXqJ(`iN6)L9lpXdqNm2G%o}GB} zFcOZ86s^(Ro0tWV*l4_CAh%8mwAPcC(@uBrE;qvQwvu-X&rUp^&AZWLluWZi`8vGy z+1(LaN<1}e?WTMT4L)ENua&f|QsdJc8~n038kS-fgy`<$XyGsc>X9kxPyv<@MRIH{H<;Lkjc2mrMtQPD2m914r9AVtrFd8PF}9EmkO zc*otJ6ofhLnLwNI)@;5yMaa-3B85Rq5ZTLU#<89ezx4I6EPH)XD+e~yzGzrWwY`Nc z!stO1i`qxBiA~n*6t!l@GX=P{SVcN)(Rf-iBSq9P?ksASPZ4WX#F9dX16c~mUdu7k zz|LN?D6V-o_=S$lUN2`vd#y#STCV?@W_#44!)!hupxm$(4l!>uaLE*6pgY#4-qL%k zY(B;wSNw89gOu;Y9+U)z0{HL@ghs?#c@!k9jTSLo*T>sNW^XELQ=(Wkp?qs+B=$7{ zO{V}uvA zMv8Wddh%MFMXdraf{0kp!j_Rlwm?GR)<1Ra{6ZK`igK0UB1ooVH)qOg$695If{Ac` zEqQ`ZeORAOn;?OoOEPJZ@zz|;v3^lppjkpua7=~2a!~k5!uA8c8uA;IcQ~=f6iX?G z8VYhjQ7Sz_St1hF4n&bQAsM_@L{h85m%MQ7n~Gg`ye-?_)LV^k>|TX#wNV|f4VwA2 z5mq4@+9qP2rm=-BC}wE~(8}QAv#MF1QJRp)vEz=l+FIlK7H>SB8%{?z5!}%$6=|yp z;W4%!MIDa18BsUO+lihF@w(WtIA=hDK)N|Je*thm{Nhcq%dWB|_jA~Xgk>v}eOKi* z43h{KO=m3wrkU7Evv2s@>-(9{dOj+~Vi12OY5$&W`u}6zzc}R5{`(hG?O%VB?eHKK6ZOn zqQ^4m5nJ|}8NH`NiPfEWWUP`d>{YY5Zja|MORzKSIeFd=?;`KBoKII1nkWIc%Ndf@ zreoR>X)!`@BZ+!mn_+jvpU*4WN+e)MdrcI}^K!Ua?GO%VK?TQGoh474f-I+1)@G7A zoXvR@=rDO6s;Sn>?J(YRh)O(D+c@pn+7gM~Et*-r4i8&$Eci89o)lMew-d2GHB<3fIHixr!qKp*U zD4Q=p+bPg;cWkZBDNd0bqV3r7D&C?1PW1uo z4_i;mSVQ{EcqTnJAWkE{waa1>Q?l1HrPb~fbuhP;{W_{zvtt7bNeIL-=4yRaBe!^6Dv`*QE{US7eqNFeR(a$bqiUr8p7Gn%Zm#&hu(gKS7FAB zLf5a3XOiDT1Ya(&xB4=RY)c=y`mAv5K9Lea@B-nhr4eKl!6YT=o6ka~y=MgUMcBJq z);bO;DpC=+IAT9Tfexdl{gTAyq9W`Yc_N0^lL$^u*xKUQn&*09TD0uAR9odo!aolmKKyO#x3Ezvu!e zMti5RQy*F~4IR>uocva!=#y+PS(oVe1yh0Ce0Z1O8nKq{#*-ruth3zYHlH>)sc1epM*HXhM z&6p#V;phmMOSotBTA;egh?q*%U^m&ekWHkR^b#5vRJjyN&epTYm!q_R3gpWP3WOfS zA=A#SmClvLIM}aE`h07h#NaVwOf*=M063qu_7Zkl2Fi6%Wk!o(o0!wiU80;qu z$~R;Z$_eR}KIF}`GC&|Gbn%;{Y8k@ZL$GTTD?yo@Nzt`qlyq_laVk$ zWdVvdD%OILAlSW0#fL)@>+pW&*K;$8L-wnV{1<)1Tp$w+b)kICy%X&-j>U8qERJiG7f=j0|B+ydqR_?AN^YlvNyNOhi<` z!%~*00eVtvzbHKGP{ckgqia-pDb>paBgDHSo7TTxhT82|T>zqi5V3p%BS+T9@1ySH z9BaEkr5~UgqDDo&^T@fKjGNHfWTbDm+8K~r(*>wdUq!l^YHT2Nfk(Qvk=XqLQ?$o+ zC!2n*1&t3Tn01gqq>EU6Kqx@IY2T6913n5g?Oi}Y%(gh$XcN@(x}xopttF6k&6sZ( zpT`Up0Ez`R+0Y0&;bOoE5j%jw)Qfyae`jwYFuc;!+D_?(PHcsuNuQKs9gwaG4}vzi zhBSvz33;KbAFsrNbj+*?@d8n&8v@%tBz#Kpmx`#_8-;X1>n%e06>WlYQX81!H$JUN~!KgMv8xhU**0!Qe(v~PM z6c88!C}H0c+13`1H;&AOWJ0~L{i0aD5Kzc2)EFmba~p(!CK&leYb|^jjwYExEuq;{ zgHlRnw5Yr3xrHNiP9j5oJGFMvG}(IeHWxOZvJ`!@sNX+I|5m!FO{EPzl}~RdVuCr% zbY2Tn(=UZ>nILJ07;*?@2ntJE7K)0c$^17fu#!C>teDQ*;;S=7-xOMJ7z=`mOC#@< zQz*%5z2vjDdWYj}nchb0K+$?xkyg7Zi}cWFH8cuSUKwO!;lQD{R~5F7xizibHg9A0 z_M%NbIhooON-;4CsZ=tN0~qZm#v)^$jvD9Vj^`UJBA0zv$xl& zxN-KA)wU?UE&geqMTNdas&Upv3de+G`j57XGTzLJO$)}Nq?2S=#VA5+t>4&bdf0BF z@uiyx`s6jT&eM`fez6-hFBD;hS-L{$LQFeXMK@MXcJkVjeK2{~Quz#96}n$=OD376 ztx<6?KcI%_F$iRDkb+R2)~<`RKV3s+>V>VTr89?@W$g?Ul>H>OF&gqBDOnN% z!pcXrucyBdVnFlaaO`fWv#~u)cf(1k(s7Ry@uC60PB!5c!wqC&wNg^4M&*T48^hi^ zA_DYvYvqb6SRb~>hbYEo#*Y^UIU$l*Xj=pxvL;5^TA}>`(jlIHDoZU7$2u7CXeYDi z)Aq|H!`mm99KR;3ks#_2R9uf$ajf;$n?yDf>NEJWpALJ6$s(2K04k%y>~&&b1cjj> z?5889iH^k~!;%G~P?$A(W<4o3EC;&0%7k*nds&{aW9S`;10}~-a^#D>F{s)~n!^Se z_Sw55*7I`0T-bV^lq`O|MM}CxF*gM3O%dyjAeVHg2*T5hRi!^>J{)V}$@r>(7V(uN zSZ}>%bxPH7aO12VMm!tk=!{a*a~O+njyxHLV;E(^9ZQ7LdP7E`jM(J>5$u-;4MCWy zng9?;v_&90Go+wUlU1gC;Ig-!EaR>HVq5R$mXktRjF|{!WRg8ovq!Ao*&8XsuZs*Q zc6u8)+LLZsOwOP&wK3RTv`X-z&`lMwv8;10_OV`1Yej~b+^4IBzHHos$jG8pV5^8d zt+z#FWHbEWWi00u*IO2P7!C*JZb~2FT^vrIM3=xs7xo1Xc5UA0G9VnFtsU3~6Wzw2 zg&rYKdi0Z7(JOOwN-P|mlvkIlbIP2t^yKdCJ9e@1D z$vhRfD=x}z?z!na`zD?W-4&xxo;mm4D}VKMo{HTS|90R08%JK4vzw<)*!J0 zFMCz40d$+W!#Shg+ySVL-0~Sf^Zi=@-AdLeO_g8ba#d61yu>M>O?PC03#Hj4~)aJe9TTZcK|!3Y4WK6D=;qr=HG!CQQjmuz)m-J z06W9nf!SDd2WDrQJAj?lH2G|R6`B_S^X~w5j(G>LbIl#Vip(9rLgo%&A2N3UJFjW- z`2fTHNw5Hze+RG&%sYU6*xUiE#M}XlbCUdO{*Ac<*o94#KLW5)^8#T09l$O!?*MkO zxdWJO?f^F4+=1C8<_=(&HckF0!0=o0G4t;LcA0qxu#cHLfK4!W0K=!p$L!ZF zcUeu7FKn9j5kJx+y}ohxV(?Qgep(WYlYj1tthGIO_p-ycvKfUZ`iIvqJ@bZ-y?xcc@I?Qxw_?n;s=H! z9b=Q!pq`&G>D}08rxG#J75BjX>PhveRL675IZ~|ICA4RT+k-mxTE$hW6xw~fesS@}RI z1moOPUGhw|^-iJ^eBDI{8+d=~85*f`8*#4DyPFav^2vI$@eg;oC2vYh%Y5_Q^)@7` zfE(3vWW^YU%?g$I{3B+k@UMTk&Y(YK=qB_i@PnMrNLTu~UT3wpv)WsWx1IM!qWr!g zX)H_=9@HzxhjKmcY0`6U=$VS9RRLifC8elbz?m_IIr)r8bE_r77fUuhX0Z z?Co{ia5Lo-2Xr53+|-l!+EPkkNuyBKz!!Ub5YuL!8^erqW6TpInj{5y%+&+q(s=3@?p-739~};>QSP+SK4eyRGyldwxqfKR5|JHcE{T$Cx{hRL(M}3`SiM%>|RLE zp(pruB!2QajzZBRuCl?Ca+yFRjPNUsh%85 z$+5Fc@YwBCZ#-RcTCKNVEU(ho?Y~G=cHp;)_4)wsy+opI+S@(e-p1y)CnOeL#3?%8 z`PVUNWGkG;=h(INv8$|btm=!2sblsL-PgsKZ{P!saH?~|4S(C(vs!9D&)dimfc4~b zR?OgY;vW?I9T2MiTwu=kVb0`RZ0c<>H-l)mPU26a1!mVYq2ldA_S+Th#1GpK;Co;& ztd&}KF!n4&#&%DAyJt!BT^V*y7rp#aOW?QI9d%U20a7XDqBLw5jPD#R?c*Cu|uS=ihyvKk3r zR$5OpnMyd=)z#jUiT})3k<5(EP46mvOz;x0Q2`qpc^*i_u3Q?9P1>9IBqdA3zxCUK zr_y=YTtnyF+l_$E_Ew2l(jMxB;tOD6=@%!j9t=R zKdiBPNd0A9nQ|GnI(&LYLyw%?6PujjtjGd8mu1V67L4cTPNF5prUkEIyAZ|oF!Z8m zstQarAq9H`jS6biIKl2?SNs3kgoJ5r&RDscB+*agxQ~6v|K~uz62!GFYlW3xT0P{bZ32!T1cF(_|M2_8!CAC zm7@`r93&8OVmj|6Tyo8=I1m*gOWcd%0FOscrk~ z!9d`(S9zT(Pg^1VLE?`G{hDOH@i?bP*(=4B_7N$C)y0G&vCCyqa4)yjvAOu)KN0HY zzJ_;ejqA-J`LtKsIk^tYXL-P%v!cgoIPY1f;r!n^4Wr7PhTKBQvX>4cBoiEoU!TX= zQDmNy5(kQU7(xkC^_8fT;>6#N>gf@E8|zKEDY5y;l!b{2q!fi;i27zg+{WxzvAsszA+_0PJKPlj)Py!Zbx|Ex4hR>~biym!@STTewS zrmwgkF;AQ!B46@c*!zTRHE?l|f0)Iz}5Q_CMR8$cSnx+KFkx7damp~ zm>u@+$dak4Nv&nuY zUOYlORzPx>GxP0u-LeUz#ngwji~YcfSRJ}E!(=(zvFXMNtV3*(@Ta&1-E){fS1u&t zZNs#{b1muam_!E&0WGQgeGIbt!_vF>>x4rea_l!C5`B*KCRYYg%p{Abg}m2*C>u)r z%F2!hq+<1O&3C?I?FAA0RbI6j+%9nJJ!EmLSJ)Z=j}6^E>{tnvD%KZdV@24;y}vuY z$_Q79V|4cG*5W`0sbltY zM)q_&P#{E;h6-6l%!W$ZVY<=6NSUk#ilnm@h@}^y$CJ>tE+oCxq!F@*n4Ac7TsS@{ zoBf*AjV(Epl-*qe`DY@5kf{dA6NzIZ2I7V^u>l2L09$FpEbPVk!WtTWM7UZ!%jO)6 z*s)X>vD}5LKF;1|i$E*wv1J$pQh{JCnkrMDB5qoOO$5}uS-*(PP$OEFQ`AgKP2gB7 z@spSDqL!r9XiF%H2LQ}6f%u=ZJp(86c*{ue6%-vQrrC!gp6mu;5J0oAra*Bis4mvE z9|0p+iZ8oh-3M1-q+&X(FQ&M`Q~e~Wxq@mEO?=;ti#(ac(_w_J`}!F7K@~8pVfW(7 zirNvlic^0QQFL5?MDcX&i|X)xsAjP8l*AMv=ucEdHlU|Lxi6BdQc=X;wm*t&pAZaN z_rZUb_BUrM$JO^q$pkZ-DHnFNj-W}jjM%r?p_hT_>iS|q>NPNwx1#srad^7U$rh$7 z41-@>KDQt+hTT$z*}MS_kt%4|A}LyF9|pf{l}sNCB_Rk33h|aveUUV**5ZYBA}gur zQT+ftgPLI3i(ZOM8XOS@+!%WC6Z#8!ls!t3iwgm?lwK5RJU#_ckBVj=Dk3FFqYzk{ z4Frm(pvWGT6<7}`XhJ5#iZG<4PhL%p^fUCmxACEMJ7K(nUfVb}M?FLeza*BiVa`Rs{5j-4%&FYD#+rlv`hr_=3Sd2%hSm`2` zs7QQZWUrrKv5(Cj%^2_z+6Bp6F|MRDg5|>ls!~IOq7el|GW2pCsY{Vd5jY&AOp+ua zv->cfG&z2`DYDs*_X5Gn2njP(G!fkt(bTW%P?F?+ZVH~6{&zaHKsce2kEZ#E5~Ox5 zfq9{Ah?_}7#Qv|h7EAmVDk?DQ>rZg&v ztu}T|LrY5%l<$617pV-Yi|i&*q^+bjb%n560AQ+#N)m-8YCSWwrFK?Q=)}xW+Xp#? zB$CMQfi#&?-0yzW!bnw{ehSloL~&{-E+CAZ37&ouHl>26C>gah`sj8)NrsQA*g^rS zs+9CQ%o9wpZe^44kyv8Q`B+k!zRF$m8&V36bfUdoWPl&eE~)rwyHD*T6^8N~VoE=L zB!=*{i|jX z^i%`Wm~C%fKJS*ms6@nutIiY+kPSx7Bd{wqg&NL+rl<CBn1PX?H6L0xqw$2T@4SlF7>l;B8eb2 zORABs36R=8RMcTaAM{MC5h@C^kD#I%IcoVxUA!N9G%BGXvh3SLf~5|~I&Zt>PLwva z13wxbrlGCs#|#+dv#23oi!5rB7mBMfD_b*z@q`&Z`rz^eny4V{j1*ge*OIB<1Gy3X zE-0yR3dW*MT1^@=fb?-zl0r6r5a}198?C`v2f9h3QVvdBjL7K?=}uedE}`rJ2sTt3 z(m_HW$R;qva8av30tpLuN#;hF=&*Ja9Ykl@2TV;Z_6^Clz&6zC{-QRpTeMnB*XcH# z5MN^_U)u=gbnxBBu{hQ!U+ry0ukwENh()X9(OYe?Kfu}(Uxmi&D%xtVvbWRCFKUsG zVQ&N8^?dHY;I%r4ogi+fBka}ElQIF}YZ_ein1+ZHu>p`hG0Vi1&xQe@7L*}jMey8M?4g~61m zxOMEQ1vyl=_yFsi3Y)tEul|&|6&>klEpY6`Ep$McQxpq(Q5+=*1!#^{G-2EpZ9RyOCEtA3=+AA>^!#2L0EeO$O z=6if%K|gH)$N;Y39-9-_;WuiePPPJB?}!hu?C-}}7KQI^!FAIxr&SrEVy^Q*kb_2# zh#}DaR;>{f4jnKat?jadAcEHBT8dO+TONvlq^MM!yzj_@_|bHd7BKs0wJ^!WUd!pB zaoV+8}JA=NrXLXGG88!ej-EX%@T3p(v?ol<39W_pjfh!xqOGfV*Ywna{Vl`-Nv-^`jKu=+-+>mavS$& z-1r-FmtkySCh4#AMa-*9Tw4Nn+6-dMH=m-2SNG zv4H;wW%A`{C0fszlIlR;9))8(Ty9cbMCN+ z{X$mwW93wYF^5~S*Dr+C>TAozc|u%V_Z*-yyM0La14&8xBLGRDC!9#}|9X`r<>Bs< zSL)8G@mAsEApQrxB%d39ak#EFTZb0CB-H5o+zKI>x4xt`-f4N8-3f2pdI^kiOWyEy zh;sxX`dZ!CRpq!1B!2WJ(vnKp8tY)<*;Tqc4av&-BAY>kc^bX@r2m+hSY0X zQef66?%`PCh`qLJ$o$hCZ7F2Jg`%AFy%EF<%4*7T zW98lIh35`4m!am8X)YP&VwuYjb4jmmOr+O8(HEBk-SCY=oiESLv*=4!2&Zw<$sIi` zH*a!Y?&z!Xa`P$*b4OPd@?6SuX(AKsd`|{(;ZV;FmU|()|IoW$YW(fa+pUxhz$aF| z9sp=uS==W?N%;)XAjTJL?=Hg+G5O?QUM(6#57n-j(42esSOiPhhf5yoh&RLNcmfAP zViby>(o8qV)*vf~#jr9Y)s7Cr&3|`h~Kz3p(r@t>!R|gBHneM^{n4$Pwku8Hks|+{WIDq-hAc zKLmHvj$iBBj&UB^nAr19YCC>=(aQt3;{$#>J|OLQo8OM7XghxHHIes}n$=iuCcX(+ zd$(!F;uh1}j<+TLgACTQ0iuGVX~*JSDgST@H8*JuH6_p2SeQ0&x%Xm@pR-3cTYxno`7|Cs1St<&_c&YZvs|Zw~`s&evc%7D zYGTo=;KU31|EX?tsPXM$@l8}+pR%P^<6tk$vGV;}R#w z$;YN%7jxI+^mj#K*q(R9k+5-P*$vmXdXw^S%EdN+Q0g+Z@%LAVJKjvI#Y;3kcST7{ z{LoPE+AMExPm8s6!Y6X>lC1z;nTa{O-a^`%>+#bkmndQhNhAQ>IaOKC1gPDiqb!|xtn>5;Mt<~5E zd)T9pULDOqBUX3c@mkkZQrFB`bGus|bJBrT8_QUYYN@H+BLx?~bQ~QtfteUmE^OMjG{%xJ#uyElPE3Yjj%H zlJUAb{U3-m}8<89*MKH=QtIAq9rTTH9 zF8>-pezD$Fd&6sE)zJ28ei_578LVqttX@J;$4U4Pe5={%X$eobHfzCC_(l&>!^LiuaJ#HM~a<`M_Gyee_)%f3*S z;#Z3li4clZ%F^>}q*BCZE~A6rmXj~+J*UFy#Q!ujT+;3Bb-c=~@Py}bW7%LQj>8sL z_^C3TxU}P~o=2}BU&$sb{vg0`Ug#d`C2-HK`#3H|dC|#v6Dm};Tf0VJ#^B9(_jW^d zws8akE|xbov}hq||AMCI+phz-+8bKqWmnI6QbYrYSx(85(a(!?e+bXSFQ(92k+f;x}IvR;0R9L7X|$BHfr*YJ#2%l_S$Q`somAMV|F~}X14&O zx-p*RG8U>*C?^3WRz+K!)yI?EUMmzXl{Q}Hy;kF0T-~_faCds{vUo|SJE5cQ z>`D>S~y=w=& z@EfFHi?%B3UlT)^Ab#!icE4@z6yc1y`1GDU_0BPAi3zp%+)8Ul1PZTjwb!<#$>|<0 zf!+8O@+;<7#;=^8>&D!?w({7QLR9h*Kd&B>FQXq_y+#M4}$lqX)Azh40Gsk!bxvba3BKK=R{fdRcj0j}2( zyKZ+Kn~DrFnTZjCj5oQ=6f;YUnd}!jMW5Dd^*bGTND{)ZL+OE^m~pb7-n) zu%EcID`=d7iA@TAiVO8$e|AE}B7R~OwQ*J5>8oM)dm;4tgTvSftoUzn* z&YEflWiDGwdNC3O3r3$v!Dvrnnvc=tijlg3myQ-yS6@up2x+AQ(bcjFmNslV8?)mNDEDFqz=!G-Zr(VpC}G)5US+{>>irCyNnubEnHDhxlf?QVmg@5_Xzopk@1Co2TIQ|sakVI=D*0fV|4x{S@yu-c^=Xe<7sGOH4dn=!^2OZ&a9%bH4EMVEhm%BXwf(e`J zE_h7LJ;^;$;KoL}6dj26_QZ(iq@V5FE{Fmtv4?(c!j6<&j>&a#O0FS^r=HbZ|0KC& z3TBCBzg7fB1{E9rkdf9^2YR_nN<_zb*XJc(?-cB6=!4NcVu`?$GAv={s~RLXk7!kG zM>oT9<@N?&bgl;oJ^{v#Dt^m~E(m+7!tx;pmm937U|- zmKOQ_IHvm-QT>P~8&B6HzIUpy2yli79ku@OY`^j#BX`L%(zsqVZHCry52B#e@)EM~>#DrO%2WKBJ$`GlW(|>K z&FV90cU^ahnn5E+@%*DjFfG$dE@&kl8|-xn}2%ziB6R5=-rYUiyg6EyTc{3bu(y z)+Q-bEfhj2(fK7Q)Jz(~YgAEnUg8%g`y~0%my#s8CEQCAl{YcUrDm{NIG&=4MDDcR zJ&H1VO~q;J-im-TFB-)(#M^KiD_x|BbXEEVaH_4g4cw`xO@un%EKjV1HzUW z!j=kQYv#m7a4jRS#mr(CCW>~T*3aroO^`}b(*_F^yHc~a*{4zyJ6-lcP4#!G8iS%A zJ^fvYpIMVa$^F%Hpk(Kw1L^cqx%cg(g1L(q@waDPY^iJajo9XGqtuN0alaEa6yQ{6nB|JZ#%5^<@=@IyIgBcFkC&P?30 z>z$qzY9$&wn~=XE8dIg|+|U}U#0JUyGSdo^3%zZLhZ*wH)H2w=x4H4~(E6e8L<$SK zavBe3)StF5QkVwE>P|-j3e)O`C%(B$OgdD<`~ri?KPEBBG?@I;yk1PwJHJHBkKKLv zwH}Hbk$dk=qSYUu>OVcZtA~0wB#9L2piC?fDWLJ>^w=KW(icbiDT;sANznm2pGVd zp+e^?JSn#Mg6-7?8cNUJJp5;mmH#*<#{0ShW6Ba#I zVT}3CZ}$QFX#@5;0s9UJ3fSuCa2jgoEhN1Ev(M(IeS=^AbG^U+^q+%k@J*f@`F)AB zZTt@LyZQP2w7=sj@8teWe(U|~xyX~W&~m>;KDE+sk+Kh)PBb=h2xv*=?*_}*)Y&oj zDMn^<5)-xu(*`%R*2GT!(-+3jEwt2>w43=E&K<~_l)F4957kpY44uU6UY96=at_DI zUGg2I3fRBAc??Elb8QJ{8RSXwtdcE3>Q~qlnH9S-y>paF`}N+mGS4(v`XQaq(9nUs z5R81-M@w&Y{@kRW@$TvCLcqPWH{F0Z3{z?Ax}KybC6nGiFus|wD>J)f=kcSTACm?Z zK9d|@GuNF}!JeC}k~Q_isv%!<{U0G=>7zrz*52(rDoRr5S?tiGN+de0_}H|eiId($ z->4E()%Do@zS{e?5wfMX^frf=61Q#bqxLih%)FOGNoFnv0Hd>k_z5fP?P~0qiL59H zQbPiyKt_5D5DLdC3K9$7=z|nRj882h{BH1nx6{D4285rHIO_=bFCZ<+DjW^|EPJ<3 z6<0I+1UaWB{`nJX;4MBGv6FL?rcwztMW{)J^JoSrkWR>*__x>hizVEA7dx_L2KhU` zd8>zIw_fT~(fLV4WO_8o-$Cg)S?GD;Fi|H=@=C*7ZaDWb0Cmj+TL@e1Jeuj_;jHMU zzww!W3JCQrK9nqe&=Nl@B|b6Kl=u-T@wcYLZiG_hC(xgHiAaaG`raBQ@fn`PNBTb> zpL_Q9!)N45VAhnZqdknEy=RON@pgM!sOu}D7ruzTlkKalJ+W?i$02I7147h!TIZ9ITL1_PFaK$Xuc~;Z26l%hSAlQLJMPtB>$?_8(4MafKBZBt*`mM z#M}a-k^OGt!mPCVixcT^)s0r_tj_4i(&-Szg#SwOTi8MMCyAl0D+FeCl3@>1s3J#S z8wEuT_Mg;|saTUU>)4*XT?DSsjj{hJk#T598rJ$NHO!;dcpJP^1o<0YA)W%}=}f85 z!ZB=v)|!i%KR)yAo-VE7ft;X*Q;)!a^SsKWPDA}VG1GKY;{mH)w(GxflhNnDL%w5E zr=!fTiMdZEKEK7+=Vh&p2Qur+5pHW?)K)Sv&@QXqrrYNa(a$lHS35Ro!n4l^gFUql!E0vV-)@!@1s-d5OjmzO{VkXOhr; zBNLuxaP%!kQ`lwx#GPM406*V{j{{GvJYwb#XMdLY!-Hi;z>l0i%!|6r#Om~6Y3dYW zTX_zBe2?2!o3h7vBVCM&{lyhB2DCo)n!@VT2UwxwDJibcQe1p z=rx#89Pv?+Z-%})jk)ww^5oAbzIG`OeK{m;B1;-wp6?X!`Ch;bqN?X~8@vB5r*3TH zfg!m|Hm!d zq1>;Fm4u;c4ATB7Fg=68LH|#^0xcTEW^1v@b}dhIuQ+q_B)+JXoc zZ5H;g*h)AwaEtJhvq*@grXhjs%N?nQtO(4a$kU|wf5S3~btGHB2v?wiwv`TypG7d6~ zE3V_XuT1H<6v|Smv}I92M#cTsxUg9ZGUWgHocq2>TG09apC8Xdlf3U;&OP_sbI*3q zMf(XNFnflqv?b;+CYDArx+a>{^RU#zd+xaROj6(I81=cdQj4wN-v2{;@F+B^E6`SF za4GA>gZr@R46ZBM{ER<_SK2?&d}#Y3XnDA|Yjm97x&4#`wC^3VO3tTS@l9x9_DK{76v?e(M68PhIU&5tufpDgU(No6BzH=FAL77YJ8`&6LGK{Du?2HZSALx=IiBCilAzx%BdJ@&ONOIme`z@hMM3SiW zk>eo$x7JVTa*e;h>@>hhC!2o=s4@QbU0h_h|G-h1M zJr9U1ZZLw5DB~*iBHoh~0FJ@%mMiPwfsqKB4eIXo2WVIO1je3Vw{YW#E`CU_W6&OY z-XL`<24lxs#jofiB|n%Del~x2f}{FXJfgF{4BgTn?8@G*-o-R}i+5n-JLzhOQOG-A zLzkNR^-S20VXy>tZnXPuPy?jziafZ-;1l`~{nB4$VA7#jLTo_z5x!vG5tkdVGsbco zjA`pan`|#a`fs!kLPXf<7O_Y74XGEIs;+El>pouf_XdN zoC(LsEI25>))~_}BG8uazIj8hMUj`!7N11-=@6GcJe`ap>TcK0cFN%5ZqI;BybL`- ziljVD;q?E9JX~t`xgQH0*)g|)Oc!5;q+ktd61ugP_T{?Id~xJUZ`pPEL56T32_E~6 zbK@h&r;`RACczxD@em(vt9+Pci4N0s!DTQ?G#Cbv=OzPLGj_B_%;u0tsm+LToFk zk0y@WtlKyTZG^@?2+q}C4P14oQO!NCo!n&3_ntTxl-0$&A1F%sZV2p8B+qYDSpXA5 zcT~-!`iTbv2sa1msG4Fu>cvMKsG}+mkA#V8P;Q(Ct4$fcYj}36zpU)EfdZIic<(zN zUv}_IAIdMiEf^iu7otH=@S>Q~V*xtyx4sEq;D5yWzZ&z!@AhZs=M8vg6G(^s{}rJR z%FlomD@5dH1c(3M-WcueU*#@eaQ&#}XgsfN_A`6e{xv>_JKS=0Wv(PkSTuP4pIz0rzY$ijVdp zmX593w^KudqHrM*X9)U+7^;@;ju!`IHXsf@xZ4&7OK8ej$K9wjAAt$jk>IME1x9!` z_`=s6+=CtXN8w8v{!a4YSyQ!q*b56ORET}yQ;`qfc&`(As~zZ<5>6|HYYkST`h8bS zKAesj!28bf;gpo5D81VI<%ccL(;HWA(9Q77K}#NN@(lS`$sJG>omI~Zi+~1xC0R$gw$pK zWCYQA33@F-k0t1_1fKK~K0}WX)DWe{ywKQrdaET>ze8nDB62PUXG0~X5r@|qZ;w#M zNn%Xm*(KjFSecHM1m1{UgZmPt(JXC9NT-d`Fa%werOrj%H-|+@;dlxlfQVcY#USx< zq?G(;0sw84k}WKZ9kF8(FbNyqm%d=(Ticru_tcZ!rKoWPov}Ld>%S*bO|gwna}m9Q zWh-I%_g1M}p49^OdG6UJ}Q~ll{Rfgd*#xerP-PGl4JM6NhvJAPx zumXke~q}!wXJio+tzNws7Onci9kzBE{)OBo2q36X{nW4f0U%H`4)R>7AmRZ z{}IJCL{EfLc+Hiz=ta%dQS}vyS)$k1v^a!%Ul#en3a5B9IbDZSFqY!AdM$d*<;b7L zkCDsJfUlH47xSmcTUYaEwY-HG;=6=D@8D07w-7DYtgh!zk+;sSU1N=~3Qb{zed9*B zM*Un9jw(8MblpNHd@jw(VBn4OjAhxrMa;R88Xy0l3- zs=j8ZLg4PS1b;dM^Lm^R-8~#t&+0ISwAuu4MA(OqQ`-mbKm2Iaz~lemjm_?Rt0UO< zy3ypWF+*}^l+cQf)!ccY5T#*7--VhO=&^@IXf&Lpb8W8lKO!_lV=iP6AWh(hZ53QC z-iRI#ZfxsXjc`KH`CuC5U_`fKZw`TD-DocI!;hVfi4k44-j3Y>8Bq(kwRmPMs!2#s zSf7}lPz^%mfBU=r+4=dED4X0RJ>d%czcnd6;br_^i~nEYe-i5V$N!o5A7xI~erwzN zDxVV81ZViUg_gX(iT>42@_s7p<;iJzu;6NYc^&QL@CnZ+k|C4_*K%X@!%Eet$~Wxe z_u>40^&0tpdhJ>iBolp3FS9Qv*h_t#3cVFuWSY02pxE7Om!fpc`0lQukD1JC{l-r6 zeedVdpu`lc{}X$*&l^g4Knm7-htx;?{Z{-(LdW=)BeUzkiMr~*iB=w+!De+eYY*A% zSl$!(I7%C|>oM4$iHu~Ffe@){ctY;3tuzjTq2@+`6MOg{`UhqbWli5f7)FyZoGsTl zOF=7|J#JJ}-|UPtZf_R8Xh0{f(K-F_$r@)%S~}q@<-_r!6WRX$PWE}3zX;6fS_`ro z>M%8!3fW9^J2u@}BeGnJTqP=PnY9(tKEK-tT$tcL9T=JlPzdq|7-}sAijc7bvi3Ap z`i358l!0<{b*bU~C}Yw<=m$IP$W~|@g{*co_>vgJPo$5Yl*FLyMc-1@Km`UM#2N+O z$7Ha{&TqJG1b#|`8Mbsf_6a=-tp)A(LOg|5;2)kJxFErwjqyBL5Od_$!dMm^&$8EJ z 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 LNcgg7@l*ad)$21;f7&QNUY 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