diff --git a/iguana/exchanges/LP_include.h b/iguana/exchanges/LP_include.h index 1e74e9507..2a113134d 100644 --- a/iguana/exchanges/LP_include.h +++ b/iguana/exchanges/LP_include.h @@ -302,6 +302,7 @@ int32_t LP_waitmempool(char *symbol,char *coinaddr,bits256 txid,int32_t duration struct LP_transaction *LP_transactionfind(struct iguana_info *coin,bits256 txid); int32_t LP_transactioninit(struct iguana_info *coin,bits256 txid,int32_t iter); int32_t LP_mempoolscan(char *symbol,bits256 searchtxid); +int32_t LP_txheight(struct iguana_info *coin,bits256 txid); #endif diff --git a/iguana/exchanges/LP_nativeDEX.c b/iguana/exchanges/LP_nativeDEX.c index 0dcb86446..15296bcd6 100644 --- a/iguana/exchanges/LP_nativeDEX.c +++ b/iguana/exchanges/LP_nativeDEX.c @@ -85,6 +85,7 @@ char *blocktrail_listtransactions(char *symbol,char *coinaddr,int32_t num,int32_ #include "LP_coins.c" #include "LP_rpc.c" #include "LP_prices.c" +#include "LP_utxo.c" #include "LP_scan.c" #include "LP_transaction.c" #include "LP_remember.c" @@ -419,11 +420,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 { - int32_t height; bits256 zero; struct LP_address *ap,*atmp; struct LP_address_utxo *up; + int32_t height; bits256 zero; //struct LP_address *ap,*atmp; struct LP_address_utxo *up; //printf("%s ref.%d scan.%d to %d, longest.%d\n",coin->symbol,coin->firstrefht,coin->firstscanht,coin->lastscanht,coin->longestchain); if ( coin->inactive != 0 || coin->electrum != 0 ) continue; - if ( time(NULL) > coin->lastmonitor+60 ) + /*if ( time(NULL) > coin->lastmonitor+60 ) { portable_mutex_lock(&coin->txmutex); HASH_ITER(hh,coin->addresses,ap,atmp) @@ -442,7 +443,7 @@ int32_t LP_mainloop_iter(void *ctx,char *myipaddr,struct LP_peerinfo *mypeer,int } portable_mutex_unlock(&coin->txmutex); coin->lastmonitor = (uint32_t)time(NULL); - } + }*/ memset(zero.bytes,0,sizeof(zero)); if ( time(NULL) > coin->lastgetinfo+LP_GETINFO_INCR ) { diff --git a/iguana/exchanges/LP_ordermatch.c b/iguana/exchanges/LP_ordermatch.c index b0a7bc083..52d4f418d 100644 --- a/iguana/exchanges/LP_ordermatch.c +++ b/iguana/exchanges/LP_ordermatch.c @@ -644,8 +644,8 @@ struct LP_utxoinfo *LP_bestutxo(double *ordermatchpricep,int64_t *bestsatoshisp, else { printf("ineligible.(%.8f %.8f)\n",price,dstr(butxo->S.satoshis)); - if ( butxo->T.spentflag == 0 ) - butxo->T.spentflag = (uint32_t)time(NULL); + //if ( butxo->T.spentflag == 0 ) + // butxo->T.spentflag = (uint32_t)time(NULL); } } else diff --git a/iguana/exchanges/LP_peers.c b/iguana/exchanges/LP_peers.c index 5e7a26cc3..806572415 100644 --- a/iguana/exchanges/LP_peers.c +++ b/iguana/exchanges/LP_peers.c @@ -57,6 +57,9 @@ 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 pushsock,subsock,timeout; char checkip[64],pushaddr[64],subaddr[64]; struct LP_peerinfo *peer = 0; + printf("addpeer (%s:%u)\n",ipaddr,port); + if ( port > 10000 ) + return(0); #ifdef LP_STRICTPEERS if ( strncmp("5.9.253",ipaddr,strlen("5.9.253")) != 0 ) return(0); diff --git a/iguana/exchanges/LP_portfolio.c b/iguana/exchanges/LP_portfolio.c index a5982444d..a3e656e70 100644 --- a/iguana/exchanges/LP_portfolio.c +++ b/iguana/exchanges/LP_portfolio.c @@ -57,9 +57,7 @@ uint64_t LP_balance(uint64_t *valuep,int32_t iambob,char *symbol,char *coinaddr) for (i=0; itxmutex); @@ -98,6 +98,7 @@ void LP_address_utxoadd(struct iguana_info *coin,char *coinaddr,bits256 txid,int void LP_address_monitor(struct LP_pubkeyinfo *pubp) { struct iguana_info *coin,*tmp; char coinaddr[64]; cJSON *retjson; struct LP_address *ap; + return; HASH_ITER(hh,LP_coins,coin,tmp) { bitcoin_address(coinaddr,coin->taddr,coin->pubtype,pubp->rmd160,sizeof(pubp->rmd160)); @@ -111,12 +112,12 @@ void LP_address_monitor(struct LP_pubkeyinfo *pubp) { if ( (retjson= electrum_address_subscribe(coin->symbol,coin->electrum,&retjson,coinaddr)) != 0 ) { - printf("%s MONITOR.(%s) -> %p\n",coin->symbol,coinaddr,retjson); + printf("%s MONITOR.(%s) -> %s\n",coin->symbol,coinaddr,jprint(retjson,0)); free_json(retjson); } } } -} +}*/ int32_t LP_pricevalid(double price) { @@ -292,7 +293,7 @@ void LP_prices_parse(cJSON *obj) printf("%02x",pubp->rmd160[i]); char str[65]; printf(" -> rmd160.(%s) for %s\n",hexstr,bits256_str(str,pubkey)); memcpy(pubp->rmd160,rmd160,sizeof(pubp->rmd160)); - LP_address_monitor(pubp); + //LP_address_monitor(pubp); } } if ( (timestamp= juint(obj,"timestamp")) > pubp->timestamp && (asks= jarray(&n,obj,"asks")) != 0 ) diff --git a/iguana/exchanges/LP_remember.c b/iguana/exchanges/LP_remember.c index 1abeca945..f8740d048 100644 --- a/iguana/exchanges/LP_remember.c +++ b/iguana/exchanges/LP_remember.c @@ -567,9 +567,7 @@ cJSON *basilisk_remember(int64_t *KMDtotals,int64_t *BTCtotals,uint32_t requesti Dredeemlen >>= 1; decode_hex(Dredeemscript,Dredeemlen,rstr); } - if ( (value= jdouble(txobj,"amount") * SATOSHIDEN) == 0 ) - value = jdouble(txobj,"value") * SATOSHIDEN; - values[i] = value; + values[i] = value = LP_value_extract(txobj); if ( (symbol= jstr(txobj,"coin")) != 0 ) { if ( i == BASILISK_ALICESPEND || i == BASILISK_BOBPAYMENT || i == BASILISK_BOBDEPOSIT || i == BASILISK_BOBREFUND || i == BASILISK_BOBRECLAIM || i == BASILISK_ALICECLAIM ) diff --git a/iguana/exchanges/LP_rpc.c b/iguana/exchanges/LP_rpc.c index 16901dae3..641d547ab 100644 --- a/iguana/exchanges/LP_rpc.c +++ b/iguana/exchanges/LP_rpc.c @@ -617,66 +617,6 @@ cJSON *LP_getblock(char *symbol,bits256 txid) return(bitcoin_json(coin,"getblock",buf)); } -int32_t LP_txheight(struct iguana_info *coin,bits256 txid) -{ - bits256 blockhash; struct LP_transaction *tx; cJSON *blockobj,*txobj; int32_t height = 0; - if ( coin == 0 ) - return(-1); - if ( coin->electrum == 0 ) - { - if ( (txobj= LP_gettx(coin->symbol,txid)) != 0 ) - { - //*timestampp = juint(txobj,"locktime"); - //*blocktimep = juint(txobj,"blocktime"); - blockhash = jbits256(txobj,"blockhash"); - if ( bits256_nonz(blockhash) != 0 && (blockobj= LP_getblock(coin->symbol,blockhash)) != 0 ) - { - height = jint(blockobj,"height"); - //printf("%s LP_txheight.%d\n",coin->symbol,height); - free_json(blockobj); - } //else printf("%s LP_txheight error (%s)\n",coin->symbol,jprint(txobj,0)); - free_json(txobj); - } - } - else - { - if ( (tx= LP_transactionfind(coin,txid)) != 0 ) - height = tx->height; - } - return(height); -} - -int32_t LP_numconfirms(char *symbol,char *coinaddr,bits256 txid,int32_t mempool) -{ - struct iguana_info *coin; int32_t ht,numconfirms = 100; - //#ifndef BASILISK_DISABLEWAITTX - cJSON *txobj; - if ( (coin= LP_coinfind(symbol)) == 0 || coin->inactive != 0 ) - return(-1); - if ( coin->electrum == 0 ) - { - numconfirms = -1; - if ( (txobj= LP_gettx(symbol,txid)) != 0 ) - { - if ( coin->electrum == 0 ) - numconfirms = jint(txobj,"confirmations"); - else numconfirms = coin->height - jint(txobj,"height"); - free_json(txobj); - } - else if ( mempool != 0 && LP_mempoolscan(symbol,txid) >= 0 ) - numconfirms = 0; - } - else - { - if ( (ht= LP_txheight(coin,txid)) > 0 && ht <= coin->height ) - numconfirms = (coin->height - ht); - else if ( mempool != 0 && LP_waitmempool(symbol,coinaddr,txid,-1) >= 0 ) - numconfirms = 0; - } - //#endif - return(numconfirms); -} - // not in electrum path uint64_t LP_txfee(char *symbol) { diff --git a/iguana/exchanges/LP_scan.c b/iguana/exchanges/LP_scan.c index 41c7308ec..ddd95f458 100644 --- a/iguana/exchanges/LP_scan.c +++ b/iguana/exchanges/LP_scan.c @@ -19,166 +19,6 @@ // -struct LP_transaction *LP_transactionfind(struct iguana_info *coin,bits256 txid) -{ - struct LP_transaction *tx; - portable_mutex_lock(&coin->txmutex); - HASH_FIND(hh,coin->transactions,txid.bytes,sizeof(txid),tx); - portable_mutex_unlock(&coin->txmutex); - return(tx); -} - -struct LP_transaction *LP_transactionadd(struct iguana_info *coin,bits256 txid,int32_t height,int32_t numvouts,int32_t numvins) -{ - 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)); - for (i=0; ioutpoints[i].spendvini = -1; - tx->height = height; - tx->numvouts = numvouts; - tx->numvins = numvins; - //tx->timestamp = timestamp; - tx->txid = txid; - 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)); - return(tx); -} - -int32_t LP_undospends(struct iguana_info *coin,int32_t lastheight) -{ - int32_t i,ht,num = 0; struct LP_transaction *tx,*tmp; - HASH_ITER(hh,coin->transactions,tx,tmp) - { - for (i=0; inumvouts; i++) - { - if ( bits256_nonz(tx->outpoints[i].spendtxid) == 0 ) - continue; - if ( (ht= tx->outpoints[i].spendheight) == 0 ) - { - tx->outpoints[i].spendheight = LP_txheight(coin,tx->outpoints[i].spendtxid); - } - if ( (ht= tx->outpoints[i].spendheight) != 0 && ht > lastheight ) - { - char str[65]; printf("clear spend %s/v%d at ht.%d > lastheight.%d\n",bits256_str(str,tx->txid),i,ht,lastheight); - tx->outpoints[i].spendheight = 0; - tx->outpoints[i].spendvini = -1; - memset(tx->outpoints[i].spendtxid.bytes,0,sizeof(bits256)); - } - } - } - return(num); -} - -uint64_t LP_txinterestvalue(uint64_t *interestp,char *destaddr,struct iguana_info *coin,bits256 txid,int32_t vout) -{ - uint64_t interest,value = 0; double val; cJSON *txobj,*sobj,*array; int32_t n=0; - *interestp = 0; - destaddr[0] = 0; - if ( (txobj= LP_gettxout(coin->symbol,txid,vout)) != 0 ) - { - // GETTXOUT.({"value":0.01200000,"txid":"6f5adfefad102e39f62a6bacb222ebace6ce5c084116c08a62cac1182729dd46","vout":1,"scriptPubkey":{"reqSigs":1,"type":"pubkey","addresses":["19Cq6MBaD8LY7trqs99ypqKAms3GcLs6J9"]}}) - if ( (val= jdouble(txobj,"amount")) < SMALLVAL ) - val = jdouble(txobj,"value"); - if ( val > SMALLVAL ) - value = (val * SATOSHIDEN + 0.0000000049); - else value = 0; - if ( value == 0 ) - { - char str[65]; printf("%s LP_txvalue.%s strange utxo.(%s) vout.%d\n",coin->symbol,bits256_str(str,txid),jprint(txobj,0),vout); - } - else if ( strcmp(coin->symbol,"KMD") == 0 ) - { - if ( (interest= jdouble(txobj,"interest")) != 0. ) - { - //printf("add interest of %.8f to %.8f\n",interest,dstr(value)); - *interestp = SATOSHIDEN * interest; - } - } - if ( (sobj= jobj(txobj,"scriptPubKey")) != 0 && (array= jarray(&n,sobj,"addresses")) != 0 ) - { - strcpy(destaddr,jstri(array,0)); - //printf("set destaddr.(%s)\n",destaddr); - if ( n > 1 ) - printf("LP_txinterestvalue warning: violation of 1 output assumption n.%d\n",n); - } else printf("LP_txinterestvalue no addresses found?\n"); - //char str[65]; printf("dest.(%s) %.8f <- %s.(%s) txobj.(%s)\n",destaddr,dstr(value),coin->symbol,bits256_str(str,txid),jprint(txobj,0)); - free_json(txobj); - } //else { char str[65]; printf("null gettxout return %s/v%d\n",bits256_str(str,txid),vout); } - return(value); -} - -int32_t LP_transactioninit(struct iguana_info *coin,bits256 txid,int32_t iter) -{ - struct LP_transaction *tx; char *address; int32_t i,n,height,numvouts,numvins,spentvout; cJSON *txobj,*vins,*vouts,*vout,*vin,*sobj,*addresses; bits256 spenttxid; char str[65]; - if ( (txobj= LP_gettx(coin->symbol,txid)) != 0 ) - { - //printf("TX.(%s)\n",jprint(txobj,0)); - if ( coin->electrum == 0 ) - height = LP_txheight(coin,txid); - else height = -1; - vins = jarray(&numvins,txobj,"vin"); - vouts = jarray(&numvouts,txobj,"vout"); - if ( iter == 0 && vouts != 0 && (tx= LP_transactionadd(coin,txid,height,numvouts,numvins)) != 0 ) - { - for (i=0; ioutpoints[i].value= SATOSHIDEN * jdouble(vout,"value")) == 0 ) - tx->outpoints[i].value = SATOSHIDEN * jdouble(vout,"amount"); - tx->outpoints[i].interest = SATOSHIDEN * jdouble(vout,"interest"); - if ( (sobj= jobj(vout,"scriptPubKey")) != 0 ) - { - if ( (addresses= jarray(&n,sobj,"addresses")) != 0 && n > 0 ) - { - if ( n > 1 ) - printf("LP_transactioninit: txid.(%s) multiple addresses.[%s]\n",bits256_str(str,txid),jprint(addresses,0)); - if ( (address= jstri(addresses,0)) != 0 && strlen(address) < sizeof(tx->outpoints[i].coinaddr) ) - { - strcpy(tx->outpoints[i].coinaddr,address); - } else if ( tx->outpoints[i].value != 0 ) - printf("LP_transactioninit: unexpected address.(%s)\n",jprint(addresses,0)); - } - //else if ( tx->outpoints[i].value != 0 ) - // printf("LP_transactioninit: pax tx ht.%d i.%d (%s) n.%d\n",height,i,jprint(vout,0),n); - } - } - } - if ( iter == 1 && vins != 0 ) - { - for (i=0; inumvouts ) - { - tx->outpoints[spentvout].spendtxid = txid; - tx->outpoints[spentvout].spendvini = i; - tx->outpoints[spentvout].spendheight = height; - //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\n",bits256_str(str,spenttxid),spentvout,tx->numvouts); - } //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); - } - } - free_json(txobj); - return(0); - } //else printf("LP_transactioninit error for %s %s\n",coin->symbol,bits256_str(str,txid)); - return(-1); -} - int32_t LP_blockinit(struct iguana_info *coin,int32_t height) { int32_t i,j,iter,numtx,checkht=-1; cJSON *blockobj,*txs; bits256 txid; struct LP_transaction *tx; @@ -560,53 +400,6 @@ char *LP_dividends(struct iguana_info *coin,int32_t height,cJSON *argjson) return(clonestr("{\"error\":\"symbol not found\"}")); } -int64_t basilisk_txvalue(char *symbol,bits256 txid,int32_t vout) -{ - char destaddr[64]; uint64_t value,interest = 0; struct iguana_info *coin; - if ( (coin= LP_coinfind(symbol)) == 0 || coin->inactive != 0 ) - return(0); - //char str[65]; printf("%s txvalue.(%s)\n",symbol,bits256_str(str,txid)); - value = LP_txinterestvalue(&interest,destaddr,coin,txid,vout); - return(value + interest); -} - -uint64_t LP_txvalue(char *coinaddr,char *symbol,bits256 txid,int32_t vout) -{ - struct LP_transaction *tx; struct iguana_info *coin; - if ( (coin= LP_coinfind(symbol)) == 0 || coin->inactive != 0 ) - return(0); - if ( coinaddr != 0 ) - coinaddr[0] = 0; - if ( (tx= LP_transactionfind(coin,txid)) == 0 ) - { - LP_transactioninit(coin,txid,0); - LP_transactioninit(coin,txid,1); - } - if ( (tx= LP_transactionfind(coin,txid)) != 0 ) - { - if ( vout < tx->numvouts ) - { - if ( bits256_nonz(tx->outpoints[vout].spendtxid) != 0 ) - { - //char str[65]; printf("%s/v%d is spent\n",bits256_str(str,txid),vout); - return(0); - } - else - { - if ( coinaddr != 0 ) - { - if ( tx->outpoints[vout].coinaddr[0] == 0 ) - LP_txinterestvalue(&tx->outpoints[vout].interest,tx->outpoints[vout].coinaddr,coin,txid,vout); - strcpy(coinaddr,tx->outpoints[vout].coinaddr); - //printf("(%s) return value %.8f + interest %.8f\n",coinaddr,dstr(tx->outpoints[vout].value),dstr(tx->outpoints[vout].interest)); - } - return(tx->outpoints[vout].value + tx->outpoints[vout].interest); - } - } else printf("vout.%d >= tx->numvouts.%d\n",vout,tx->numvouts); - } - return(0); -} - int32_t LP_spendsearch(bits256 *spendtxidp,int32_t *indp,char *symbol,bits256 searchtxid,int32_t searchvout) { struct LP_transaction *tx; struct iguana_info *coin; diff --git a/iguana/exchanges/LP_socket.c b/iguana/exchanges/LP_socket.c index 536700a3e..2866205a8 100644 --- a/iguana/exchanges/LP_socket.c +++ b/iguana/exchanges/LP_socket.c @@ -306,7 +306,7 @@ struct electrum_info *electrum_server(char *symbol,struct electrum_info *ep) void electrum_process_array(struct iguana_info *coin,cJSON *array) { - int32_t i,n; bits256 txid; cJSON *item; struct LP_transaction *tx; + int32_t i,v,n; char str[65]; uint64_t value; bits256 txid; cJSON *item; struct LP_transaction *tx; if ( array != 0 && coin != 0 && (n= cJSON_GetArraySize(array)) > 0 ) { for (i=0; iheight <= 0 ) + if ( tx != 0 ) { - tx->height = jint(item,"height"); - char str[65]; printf(">>>>>>>>>> set %s <- height %d\n",bits256_str(str,txid),tx->height); + if (tx->height <= 0 ) + { + tx->height = jint(item,"height"); + printf(">>>>>>>>>> set %s <- height %d\n",bits256_str(str,txid),tx->height); + } + if ( jobj(item,"tx_pos") != 0 && jobj(item,"value") != 0 && (v= jint(item,"tx_pos")) >= 0 && v < tx->numvouts ) + { + value = j64bits(item,"value"); + if ( tx->outpoints[v].value == 0 && value != tx->outpoints[v].value ) + { + printf(">>>>>>>>>> set %s/v%d <- %.8f vs %.8f\n",bits256_str(str,txid),v,dstr(value),dstr(tx->outpoints[v].value)); + tx->outpoints[v].value = value; + } + } + printf("v.%d numvouts.%d %.8f (%s)\n",jint(item,"tx_pos"),tx->numvouts,dstr(tx->outpoints[jint(item,"tx_pos")].value),jprint(item,0)); } } } @@ -438,7 +451,7 @@ cJSON *electrum_address_getmempool(char *symbol,struct electrum_info *ep,cJSON * { cJSON *retjson; struct iguana_info *coin = LP_coinfind(symbol); retjson = electrum_strarg(symbol,ep,retjsonp,"blockchain.address.get_mempool",addr,ELECTRUM_TIMEOUT); - //printf("MEMPOOL.(%s)\n",jprint(retjson,0)); + printf("MEMPOOL.(%s)\n",jprint(retjson,0)); electrum_process_array(coin,retjson); return(retjson); } @@ -447,7 +460,7 @@ cJSON *electrum_address_listunspent(char *symbol,struct electrum_info *ep,cJSON { cJSON *retjson=0; struct iguana_info *coin = LP_coinfind(symbol); //printf("electrum listunspent last.(%s lag %d)\n",coin->lastunspent,(int32_t)(time(NULL) - coin->unspenttime)); - if ( strcmp(coin->lastunspent,addr) != 0 || time(NULL) > coin->unspenttime+10 ) + //if ( strcmp(coin->lastunspent,addr) != 0 || time(NULL) > coin->unspenttime+10 ) { if ( (retjson= electrum_strarg(symbol,ep,retjsonp,"blockchain.address.listunspent",addr,ELECTRUM_TIMEOUT)) != 0 ) { @@ -475,7 +488,9 @@ cJSON *electrum_getchunk(char *symbol,struct electrum_info *ep,cJSON **retjsonp, cJSON *electrum_transaction(char *symbol,struct electrum_info *ep,cJSON **retjsonp,bits256 txid) { char str[65]; printf("%s TRANSACTION.(%s)\n",symbol,bits256_str(str,txid)); - return(electrum_hasharg(symbol,ep,retjsonp,"blockchain.transaction.get",txid,ELECTRUM_TIMEOUT)); + if ( bits256_nonz(txid) != 0 ) + return(electrum_hasharg(symbol,ep,retjsonp,"blockchain.transaction.get",txid,ELECTRUM_TIMEOUT)); + else return(cJSON_Parse("{\"error\":\"null txid\"}")); } cJSON *electrum_getmerkle(char *symbol,struct electrum_info *ep,cJSON **retjsonp,bits256 txid,int32_t height) @@ -598,7 +613,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 ) @@ -632,6 +647,8 @@ int32_t LP_recvfunc(struct electrum_info *ep,char *str,int32_t len) DL_FOREACH(ep->pendingQ.list,item) { stritem = (struct stritem *)item; + if ( *stritem->retptrp != 0 ) + continue; if ( item->type == idnum ) { //printf("matched idnum.%d result.%p\n",idnum,resultjson); @@ -643,13 +660,13 @@ int32_t LP_recvfunc(struct electrum_info *ep,char *str,int32_t len) } if ( stritem->expiration < ep->lasttime ) { - DL_DELETE(ep->pendingQ.list,item); + //DL_DELETE(ep->pendingQ.list,item); printf("expired (%s)\n",stritem->str); errjson = cJSON_CreateObject(); jaddnum(errjson,"id",item->type); jaddstr(errjson,"error","timeout"); *((cJSON **)stritem->retptrp) = errjson; - free(item); + //free(item); } } } diff --git a/iguana/exchanges/LP_transaction.c b/iguana/exchanges/LP_transaction.c index 3cdafe59b..71bde88e4 100644 --- a/iguana/exchanges/LP_transaction.c +++ b/iguana/exchanges/LP_transaction.c @@ -1073,7 +1073,7 @@ int32_t basilisk_bobdeposit_refund(struct basilisk_swap *swap,int32_t delay) void LP_swap_coinaddr(struct iguana_info *coin,char *coinaddr,uint64_t *valuep,uint8_t *data,int32_t datalen,int32_t v) { - cJSON *txobj,*vouts,*vout,*addresses,*item,*skey; uint8_t extraspace[32768]; bits256 signedtxid; struct iguana_msgtx msgtx; char *addr; double val; int32_t n,m,suppress_pubkeys = 0; + cJSON *txobj,*vouts,*vout,*addresses,*item,*skey; uint8_t extraspace[32768]; bits256 signedtxid; struct iguana_msgtx msgtx; char *addr; int32_t n,m,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)) != 0 ) @@ -1083,13 +1083,7 @@ void LP_swap_coinaddr(struct iguana_info *coin,char *coinaddr,uint64_t *valuep,u { vout = jitem(vouts,v); if ( valuep != 0 ) - { - *valuep = 0; - if ( (val= jdouble(vout,"value")) < SMALLVAL ) - val = jdouble(vout,"amount"); - if ( val > SMALLVAL ) - *valuep = (val * SATOSHIDEN + 0.0000000049); - } + *valuep = LP_value_extract(vout); //printf("VOUT.(%s)\n",jprint(vout,0)); if ( (skey= jobj(vout,"scriptPubKey")) != 0 && (addresses= jarray(&m,skey,"addresses")) != 0 ) { diff --git a/iguana/exchanges/LP_utxo.c b/iguana/exchanges/LP_utxo.c new file mode 100644 index 000000000..5c327dc99 --- /dev/null +++ b/iguana/exchanges/LP_utxo.c @@ -0,0 +1,436 @@ + +/****************************************************************************** + * 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_utxo.c +// marketmaker +// + +uint64_t LP_value_extract(cJSON *obj) +{ + double val = 0.; uint64_t value; + if ( (val= jdouble(obj,"amount")) < SMALLVAL ) + val = jdouble(obj,"value"); + if ( val > SMALLVAL ) + value = (val * SATOSHIDEN + 0.0000000049); + else value = 0; + return(value); +} + +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,LP_utxoinfos[iambob],key,sizeof(key),utxo); + return(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,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; + 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; + 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; + portable_mutex_lock(&coin->txmutex); + HASH_FIND(hh,coin->transactions,txid.bytes,sizeof(txid),tx); + portable_mutex_unlock(&coin->txmutex); + return(tx); +} + +struct LP_transaction *LP_transactionadd(struct iguana_info *coin,bits256 txid,int32_t height,int32_t numvouts,int32_t numvins) +{ + 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)); + for (i=0; ioutpoints[i].spendvini = -1; + tx->height = height; + tx->numvouts = numvouts; + tx->numvins = numvins; + //tx->timestamp = timestamp; + tx->txid = txid; + 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)); + return(tx); +} + +uint64_t LP_txinterestvalue(uint64_t *interestp,char *destaddr,struct iguana_info *coin,bits256 txid,int32_t vout) +{ + uint64_t interest,value = 0; cJSON *txobj,*sobj,*array; int32_t n=0; + *interestp = 0; + destaddr[0] = 0; + if ( (txobj= LP_gettxout(coin->symbol,txid,vout)) != 0 ) + { + if ( (value= LP_value_extract(txobj)) == 0 ) + { + char str[65]; printf("%s LP_txvalue.%s strange utxo.(%s) vout.%d\n",coin->symbol,bits256_str(str,txid),jprint(txobj,0),vout); + } + else if ( strcmp(coin->symbol,"KMD") == 0 ) + { + if ( (interest= jdouble(txobj,"interest")) != 0. ) + { + //printf("add interest of %.8f to %.8f\n",interest,dstr(value)); + *interestp = SATOSHIDEN * interest; + } + } + if ( (sobj= jobj(txobj,"scriptPubKey")) != 0 && (array= jarray(&n,sobj,"addresses")) != 0 ) + { + strcpy(destaddr,jstri(array,0)); + //printf("set destaddr.(%s)\n",destaddr); + if ( n > 1 ) + printf("LP_txinterestvalue warning: violation of 1 output assumption n.%d\n",n); + } else printf("LP_txinterestvalue no addresses found?\n"); + //char str[65]; printf("dest.(%s) %.8f <- %s.(%s) txobj.(%s)\n",destaddr,dstr(value),coin->symbol,bits256_str(str,txid),jprint(txobj,0)); + free_json(txobj); + } //else { char str[65]; printf("null gettxout return %s/v%d\n",bits256_str(str,txid),vout); } + return(value); +} + +int32_t LP_transactioninit(struct iguana_info *coin,bits256 txid,int32_t iter) +{ + struct LP_transaction *tx; char *address; int32_t i,n,height,numvouts,numvins,spentvout; cJSON *txobj,*vins,*vouts,*vout,*vin,*sobj,*addresses; bits256 spenttxid; char str[65]; + if ( (txobj= LP_gettx(coin->symbol,txid)) != 0 ) + { + //printf("TX.(%s)\n",jprint(txobj,0)); + if ( coin->electrum == 0 ) + height = LP_txheight(coin,txid); + else height = -1; + vins = jarray(&numvins,txobj,"vin"); + vouts = jarray(&numvouts,txobj,"vout"); + if ( iter == 0 && vouts != 0 && (tx= LP_transactionadd(coin,txid,height,numvouts,numvins)) != 0 ) + { + //printf("create txid numvouts.%d numvins.%d\n",numvouts,numvins); + for (i=0; ioutpoints[i].value = LP_value_extract(vout); + tx->outpoints[i].interest = SATOSHIDEN * jdouble(vout,"interest"); + if ( (sobj= jobj(vout,"scriptPubKey")) != 0 ) + { + if ( (addresses= jarray(&n,sobj,"addresses")) != 0 && n > 0 ) + { + if ( n > 1 ) + printf("LP_transactioninit: txid.(%s) multiple addresses.[%s]\n",bits256_str(str,txid),jprint(addresses,0)); + if ( (address= jstri(addresses,0)) != 0 && strlen(address) < sizeof(tx->outpoints[i].coinaddr) ) + { + strcpy(tx->outpoints[i].coinaddr,address); + //printf("(%s %.8f) ",address,dstr(tx->outpoints[i].value)); + } else if ( tx->outpoints[i].value != 0 ) + printf("LP_transactioninit: unexpected address.(%s)\n",jprint(addresses,0)); + } + //else if ( tx->outpoints[i].value != 0 ) + // printf("LP_transactioninit: pax tx ht.%d i.%d (%s) n.%d\n",height,i,jprint(vout,0),n); + } + } + //printf("numvouts.%d\n",numvouts); + } + if ( iter == 1 && vins != 0 ) + { + for (i=0; inumvouts ) + { + tx->outpoints[spentvout].spendtxid = txid; + tx->outpoints[spentvout].spendvini = i; + tx->outpoints[spentvout].spendheight = height; + //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\n",bits256_str(str,spenttxid),spentvout,tx->numvouts); + } //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); + } + } + free_json(txobj); + return(0); + } //else printf("LP_transactioninit error for %s %s\n",coin->symbol,bits256_str(str,txid)); + return(-1); +} + +int32_t LP_txheight(struct iguana_info *coin,bits256 txid) +{ + bits256 blockhash; struct LP_transaction *tx; cJSON *blockobj,*txobj; int32_t height = 0; + if ( coin == 0 ) + return(-1); + if ( coin->electrum == 0 ) + { + if ( (txobj= LP_gettx(coin->symbol,txid)) != 0 ) + { + //*timestampp = juint(txobj,"locktime"); + //*blocktimep = juint(txobj,"blocktime"); + blockhash = jbits256(txobj,"blockhash"); + if ( bits256_nonz(blockhash) != 0 && (blockobj= LP_getblock(coin->symbol,blockhash)) != 0 ) + { + height = jint(blockobj,"height"); + //printf("%s LP_txheight.%d\n",coin->symbol,height); + free_json(blockobj); + } //else printf("%s LP_txheight error (%s)\n",coin->symbol,jprint(txobj,0)); + free_json(txobj); + } + } + else + { + if ( (tx= LP_transactionfind(coin,txid)) != 0 ) + height = tx->height; + } + return(height); +} + +int32_t LP_numconfirms(char *symbol,char *coinaddr,bits256 txid,int32_t mempool) +{ + struct iguana_info *coin; int32_t ht,numconfirms = 100; + //#ifndef BASILISK_DISABLEWAITTX + cJSON *txobj; + if ( (coin= LP_coinfind(symbol)) == 0 || coin->inactive != 0 ) + return(-1); + if ( coin->electrum == 0 ) + { + numconfirms = -1; + if ( (txobj= LP_gettx(symbol,txid)) != 0 ) + { + if ( coin->electrum == 0 ) + numconfirms = jint(txobj,"confirmations"); + else numconfirms = coin->height - jint(txobj,"height"); + free_json(txobj); + } + else if ( mempool != 0 && LP_mempoolscan(symbol,txid) >= 0 ) + numconfirms = 0; + } + else + { + if ( (ht= LP_txheight(coin,txid)) > 0 && ht <= coin->height ) + numconfirms = (coin->height - ht); + else if ( mempool != 0 && LP_waitmempool(symbol,coinaddr,txid,-1) >= 0 ) + numconfirms = 0; + } + //#endif + return(numconfirms); +} + +int64_t basilisk_txvalue(char *symbol,bits256 txid,int32_t vout) +{ + char destaddr[64]; uint64_t value,interest = 0; struct iguana_info *coin; + if ( (coin= LP_coinfind(symbol)) == 0 || coin->inactive != 0 ) + return(0); + //char str[65]; printf("%s txvalue.(%s)\n",symbol,bits256_str(str,txid)); + value = LP_txinterestvalue(&interest,destaddr,coin,txid,vout); + return(value + interest); +} + +uint64_t LP_txvalue(char *coinaddr,char *symbol,bits256 txid,int32_t vout) +{ + struct LP_transaction *tx; cJSON *txobj; uint64_t value; struct iguana_info *coin; char str[65],str2[65]; + if ( bits256_nonz(txid) == 0 ) + return(0); + if ( (coin= LP_coinfind(symbol)) == 0 || coin->inactive != 0 ) + return(0); + if ( coinaddr != 0 ) + coinaddr[0] = 0; + if ( (tx= LP_transactionfind(coin,txid)) == 0 ) + { + LP_transactioninit(coin,txid,0); + LP_transactioninit(coin,txid,1); + tx = LP_transactionfind(coin,txid); + } + if ( tx != 0 ) + { + if ( vout < tx->numvouts ) + { + if ( bits256_nonz(tx->outpoints[vout].spendtxid) != 0 ) + { + printf("LP_txvalue %s/v%d is spent at %s\n",bits256_str(str,txid),vout,bits256_str(str2,tx->outpoints[vout].spendtxid)); + return(0); + } + else + { + if ( coinaddr != 0 ) + { + //if ( tx->outpoints[vout].coinaddr[0] == 0 ) + // tx->outpoints[vout].value = LP_txinterestvalue(&tx->outpoints[vout].interest,tx->outpoints[vout].coinaddr,coin,txid,vout); + strcpy(coinaddr,tx->outpoints[vout].coinaddr); + //printf("(%s) return value %.8f + interest %.8f\n",coinaddr,dstr(tx->outpoints[vout].value),dstr(tx->outpoints[vout].interest)); + } + return(tx->outpoints[vout].value + tx->outpoints[vout].interest); + } + } else printf("LP_txvalue vout.%d >= tx->numvouts.%d\n",vout,tx->numvouts); + } + else + { + if ( (txobj= LP_gettxout(coin->symbol,txid,vout)) != 0 ) + { + value = SATOSHIDEN * jdouble(txobj,"value"); + free_json(txobj); + printf("pruned node? LP_txvalue couldnt find %s tx %s, but gettxout %.8f\n",coin->symbol,bits256_str(str,txid),dstr(value)); + return(value); + } + printf("pruned node? LP_txvalue couldnt find %s tx %s\n",coin->symbol,bits256_str(str,txid)); + } + return(0); +} + +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) +{ + //struct LP_utxoinfo *utxo; + uint64_t val,val2=0,txfee,threshold=0; 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"); + return(-1); + } + destaddr[0] = destaddr2[0] = 0; + if ( coin != 0 && IAMLP != 0 && coin->inactive != 0 ) + bypass = 1; + if ( bypass != 0 ) + val = satoshis; + else val = LP_txvalue(destaddr,symbol,txid,vout); + txfee = LP_txfeecalc(LP_coinfind(symbol),0); + if ( val >= satoshis && val > (1+LP_MINSIZE_TXFEEMULT)*txfee ) + { + threshold = (iambob != 0) ? LP_DEPOSITSATOSHIS(satoshis) : (LP_DEXFEE(satoshis) + txfee); + if ( bypass != 0 ) + val2 = threshold; + else val2 = LP_txvalue(destaddr2,symbol,txid2,vout2); + if ( val2 >= threshold ) + { + 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; + *val2p = val2; + return(1); + } + } // else printf("no val2\n"); + } + char str[65],str2[65]; printf("spent.%d %s txid or value %.8f < %.8f or val2 %.8f < %.8f, %s/v%d %s/v%d or < 10x txfee %.8f\n",iambob,symbol,dstr(val),dstr(satoshis),dstr(val2),dstr(threshold),bits256_str(str,txid),vout,bits256_str(str2,txid2),vout2,dstr(txfee)); + /*for (iter=0; iter<2; iter++) + { + if ( (utxo= LP_utxofind(iter,txid,vout)) != 0 ) + { + //printf("iambob.%d case 00\n",iter); + if ( utxo->T.spentflag == 0 ) + utxo->T.spentflag = (uint32_t)time(NULL); + } + if ( (utxo= LP_utxo2find(iter,txid,vout)) != 0 ) + { + //printf("iambob.%d case 01\n",iter); + if ( utxo->T.spentflag == 0 ) + utxo->T.spentflag = (uint32_t)time(NULL); + } + if ( (utxo= LP_utxofind(iter,txid2,vout2)) != 0 ) + { + //printf("iambob.%d case 10\n",iter); + if ( utxo->T.spentflag == 0 ) + utxo->T.spentflag = (uint32_t)time(NULL); + } + if ( (utxo= LP_utxo2find(iter,txid2,vout2)) != 0 ) + { + //printf("iambob.%d case 11\n",iter); + if ( utxo->T.spentflag == 0 ) + utxo->T.spentflag = (uint32_t)time(NULL); + } + }*/ + *valp = val; + *val2p = val2; + return(0); +} + +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; + 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 ( tx->outpoints[vout].spendheight > 0 ) + utxo->T.spentflag = tx->outpoints[vout].spendheight; + else utxo->T.spentflag = 0; + } + 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); + return(1); + } + } + return(0); +} + +int32_t LP_undospends(struct iguana_info *coin,int32_t lastheight) +{ + int32_t i,ht,num = 0; struct LP_transaction *tx,*tmp; + HASH_ITER(hh,coin->transactions,tx,tmp) + { + for (i=0; inumvouts; i++) + { + if ( bits256_nonz(tx->outpoints[i].spendtxid) == 0 ) + continue; + if ( (ht= tx->outpoints[i].spendheight) == 0 ) + { + tx->outpoints[i].spendheight = LP_txheight(coin,tx->outpoints[i].spendtxid); + } + if ( (ht= tx->outpoints[i].spendheight) != 0 && ht > lastheight ) + { + char str[65]; printf("clear spend %s/v%d at ht.%d > lastheight.%d\n",bits256_str(str,tx->txid),i,ht,lastheight); + tx->outpoints[i].spendheight = 0; + tx->outpoints[i].spendvini = -1; + memset(tx->outpoints[i].spendtxid.bytes,0,sizeof(bits256)); + } + } + } + return(num); +} diff --git a/iguana/exchanges/LP_utxos.c b/iguana/exchanges/LP_utxos.c index ed7833e45..1ddbf750f 100644 --- a/iguana/exchanges/LP_utxos.c +++ b/iguana/exchanges/LP_utxos.c @@ -41,37 +41,6 @@ int32_t LP_isunspent(struct LP_utxoinfo *utxo) else 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,LP_utxoinfos[iambob],key,sizeof(key),utxo); - return(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,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; - portable_mutex_lock(&LP_utxomutex); - utxo = _LP_utxofind(iambob,txid,vout); - portable_mutex_unlock(&LP_utxomutex); - return(utxo); -} - 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; @@ -84,15 +53,6 @@ struct LP_utxoinfo *LP_utxopairfind(int32_t iambob,bits256 txid,int32_t vout,bit return(0); } -struct LP_utxoinfo *LP_utxo2find(int32_t iambob,bits256 txid2,int32_t vout2) -{ - struct LP_utxoinfo *utxo=0; - portable_mutex_lock(&LP_utxomutex); - utxo = _LP_utxo2find(iambob,txid2,vout2); - portable_mutex_unlock(&LP_utxomutex); - return(utxo); -} - struct LP_utxoinfo *LP_utxofinds(int32_t iambob,bits256 txid,int32_t vout,bits256 txid2,int32_t vout2) { struct LP_utxoinfo *utxo; @@ -286,70 +246,6 @@ cJSON *LP_utxojson(struct LP_utxoinfo *utxo) return(item); } -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) -{ - //struct LP_utxoinfo *utxo; - uint64_t val,val2=0,txfee,threshold=0; int32_t bypass = 0; char destaddr[64],destaddr2[64]; struct iguana_info *coin = LP_coinfind(symbol); - destaddr[0] = destaddr2[0] = 0; - if ( coin != 0 && IAMLP != 0 && coin->inactive != 0 ) - bypass = 1; - if ( bypass != 0 ) - val = satoshis; - else val = LP_txvalue(destaddr,symbol,txid,vout); - txfee = LP_txfeecalc(LP_coinfind(symbol),0); - if ( val >= satoshis && val > (1+LP_MINSIZE_TXFEEMULT)*txfee ) - { - threshold = (iambob != 0) ? LP_DEPOSITSATOSHIS(satoshis) : (LP_DEXFEE(satoshis) + txfee); - if ( bypass != 0 ) - val2 = threshold; - else val2 = LP_txvalue(destaddr2,symbol,txid2,vout2); - if ( val2 >= threshold ) - { - 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; - *val2p = val2; - return(1); - } - } // else printf("no val2\n"); - } - // char str[65],str2[65]; printf("spent.%d %s txid or value %.8f < %.8f or val2 %.8f < %.8f, %s/v%d %s/v%d or < 10x txfee %.8f\n",iambob,symbol,dstr(val),dstr(satoshis),dstr(val2),dstr(threshold),bits256_str(str,txid),vout,bits256_str(str2,txid2),vout2,dstr(txfee)); - /*for (iter=0; iter<2; iter++) - { - if ( (utxo= LP_utxofind(iter,txid,vout)) != 0 ) - { - //printf("iambob.%d case 00\n",iter); - if ( utxo->T.spentflag == 0 ) - utxo->T.spentflag = (uint32_t)time(NULL); - } - if ( (utxo= LP_utxo2find(iter,txid,vout)) != 0 ) - { - //printf("iambob.%d case 01\n",iter); - if ( utxo->T.spentflag == 0 ) - utxo->T.spentflag = (uint32_t)time(NULL); - } - if ( (utxo= LP_utxofind(iter,txid2,vout2)) != 0 ) - { - //printf("iambob.%d case 10\n",iter); - if ( utxo->T.spentflag == 0 ) - utxo->T.spentflag = (uint32_t)time(NULL); - } - if ( (utxo= LP_utxo2find(iter,txid2,vout2)) != 0 ) - { - //printf("iambob.%d case 11\n",iter); - if ( utxo->T.spentflag == 0 ) - utxo->T.spentflag = (uint32_t)time(NULL); - } - }*/ - *valp = val; - *val2p = val2; - return(0); -} - char *LP_utxos(int32_t iambob,struct LP_peerinfo *mypeer,char *symbol,int32_t lastn) { int32_t i,n,m; uint64_t val,val2; struct _LP_utxoinfo u; struct LP_utxoinfo *utxo,*tmp; cJSON *utxosjson = cJSON_CreateArray(); @@ -378,20 +274,6 @@ char *LP_utxos(int32_t iambob,struct LP_peerinfo *mypeer,char *symbol,int32_t la return(jprint(utxosjson,1)); } -int32_t LP_inventory_prevent(int32_t iambob,bits256 txid,int32_t vout) -{ - struct LP_utxoinfo *utxo; - if ( (utxo= LP_utxofind(iambob,txid,vout)) != 0 || (utxo= LP_utxo2find(iambob,txid,vout)) != 0 ) - { - //if ( utxo->T.spentflag != 0 ) - { - //char str[65]; printf("prevent adding %s/v%d to inventory\n",bits256_str(str,txid),vout); - return(1); - } - } - return(0); -} - struct LP_utxoinfo *LP_utxo_bestfit(char *symbol,uint64_t destsatoshis) { uint64_t srcvalue,srcvalue2; struct LP_utxoinfo *utxo,*tmp,*bestutxo = 0; @@ -471,7 +353,7 @@ char *LP_spentcheck(cJSON *argjson) LP_mypeer->numutxos--; utxo->T.spentflag = (uint32_t)time(NULL); retval++; - //printf("indeed txid was spent\n"); + printf("indeed txid was spent\n"); } } } @@ -598,8 +480,8 @@ struct LP_utxoinfo *LP_utxoadd(int32_t iambob,int32_t mypubsock,char *symbol,bit 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); + //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 %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(spendscript,utxo->spendscript) != 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)); @@ -655,11 +537,11 @@ struct LP_utxoinfo *LP_utxoadd(int32_t iambob,int32_t mypubsock,char *symbol,bit if ( _LP_utxo2find(iambob,txid2,vout2) == 0 ) HASH_ADD_KEYPTR(hh2,LP_utxoinfos2[iambob],utxo->key2,sizeof(utxo->key2),utxo); portable_mutex_unlock(&LP_utxomutex); - if ( 0 && coin->electrum == 0 ) + /*if ( 0 && coin->electrum == 0 ) { LP_address_utxoadd(coin,coinaddr,txid,vout,value); LP_address_utxoadd(coin,coinaddr,txid2,vout2,value2); - } + }*/ if ( iambob != 0 ) { if ( LP_mypeer != 0 ) @@ -779,21 +661,24 @@ cJSON *LP_inventory(char *symbol,int32_t iambob) else myipaddr = "127.0.0.1"; HASH_ITER(hh,LP_utxoinfos[iambob],utxo,tmp) { - //char str[65]; printf("iambob.%d iterate %s\n",iambob,bits256_str(str,LP_mypub25519)); + 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); + //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 printf("skip %s %d %d %d %d\n",bits256_str(str,utxo->pubkey),LP_isunspent(utxo) != 0,strcmp(symbol,utxo->coin) == 0,utxo->iambob == iambob,LP_ismine(utxo) > 0); + else if ( 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); } @@ -830,7 +715,7 @@ int32_t LP_nearestvalue(int32_t iambob,uint64_t *values,int32_t n,uint64_t targe uint64_t LP_privkey_init(int32_t mypubsock,struct iguana_info *coin,bits256 myprivkey,bits256 mypub) { - char *script; struct LP_utxoinfo *utxo; cJSON *array,*item; bits256 txid,deposittxid; int32_t used,i,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,n,cmpflag,iambob,vout,depositvout; uint64_t *values=0,satoshis,txfee,depositval,value,total = 0; int64_t targetval; if ( coin == 0 ) { printf("coin not active\n"); @@ -855,10 +740,11 @@ uint64_t LP_privkey_init(int32_t mypubsock,struct iguana_info *coin,bits256 mypr item = jitem(array,i); if ( coin->electrum == 0 ) { - satoshis = SATOSHIDEN * jdouble(item,"amount"); - if ( satoshis == 0 ) - satoshis = SATOSHIDEN * jdouble(item,"value"); - if ( LP_inventory_prevent(iambob,jbits256(item,"txid"),juint(item,"vout")) == 0 && jint(item,"confirmations") > 0 ) + //satoshis = SATOSHIDEN * jdouble(item,"amount"); + //if ( satoshis == 0 ) + // satoshis = SATOSHIDEN * jdouble(item,"value"); + satoshis = LP_txvalue(destaddr,coin->symbol,jbits256(item,"txid"),juint(item,"vout")); + if ( LP_inventory_prevent(iambob,coin->symbol,jbits256(item,"txid"),juint(item,"vout")) == 0 && jint(item,"confirmations") > 0 ) { //printf("%s\n",jprint(item,0)); values[i] = satoshis; @@ -868,20 +754,26 @@ uint64_t LP_privkey_init(int32_t mypubsock,struct iguana_info *coin,bits256 mypr { //{"value":1000000,"tx_hash":"4e4f818c53486c0576693b4cd379849e5ff95538b38e4100f48884073a4e7636","tx_pos":0,"height":484877} satoshis = j64bits(item,"value"); - if ( LP_inventory_prevent(iambob,jbits256(item,"tx_hash"),juint(item,"tx_pos")) == 0 && jint(item,"height") < coin->height ) + satoshis = LP_txvalue(destaddr,coin->symbol,jbits256(item,"tx_hash"),juint(item,"tx_pos")); + if ( LP_inventory_prevent(iambob,coin->symbol,jbits256(item,"tx_hash"),juint(item,"tx_pos")) == 0 && jint(item,"height") < coin->height ) { //printf("%s\n",jprint(item,0)); values[i] = satoshis; - } else used++; + } + else + { + printf("skip.(%s) coinht.%d\n",jprint(item,0),coin->height); + used++; + } } //printf("%.8f ",dstr(satoshis)); } //printf("array.%d\n",n); while ( used < n-1 ) { - //for (i=0; i= 0 ) { item = jitem(array,i); @@ -904,7 +796,7 @@ uint64_t LP_privkey_init(int32_t mypubsock,struct iguana_info *coin,bits256 mypr 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;