diff --git a/crypto777/iguana_OS.c b/crypto777/iguana_OS.c index 504905ee1..9b218f130 100755 --- a/crypto777/iguana_OS.c +++ b/crypto777/iguana_OS.c @@ -297,11 +297,11 @@ void *queue_dequeue(queue_t *queue)//,int32_t offsetflag) void *queue_delete(queue_t *queue,struct queueitem *copy,int32_t copysize,int32_t freeitem) { struct allocitem *ptr; - struct queueitem *item = 0; + struct queueitem *tmp,*item = 0; lock_queue(queue); if ( queue->list != 0 ) { - DL_FOREACH(queue->list,item) + DL_FOREACH_SAFE(queue->list,item,tmp) { ptr = (void *)((long)item - sizeof(struct allocitem)); if ( item == copy || (ptr->allocsize == copysize && memcmp((void *)((long)item + sizeof(struct queueitem)),(void *)((long)item + sizeof(struct queueitem)),copysize) == 0) ) @@ -321,11 +321,11 @@ void *queue_delete(queue_t *queue,struct queueitem *copy,int32_t copysize,int32_ void *queue_free(queue_t *queue) { - struct queueitem *item = 0; + struct queueitem *tmp,*item = 0; lock_queue(queue); if ( queue->list != 0 ) { - DL_FOREACH(queue->list,item) + DL_FOREACH_SAFE(queue->list,item,tmp) { DL_DELETE(queue->list,item); myfree(item,sizeof(struct queueitem)); @@ -338,11 +338,11 @@ void *queue_free(queue_t *queue) void *queue_clone(queue_t *clone,queue_t *queue,int32_t size) { - struct queueitem *ptr,*item = 0; + struct queueitem *ptr,*tmp,*item = 0; lock_queue(queue); if ( queue->list != 0 ) { - DL_FOREACH(queue->list,item) + DL_FOREACH_SAFE(queue->list,item,tmp) { ptr = mycalloc('c',1,sizeof(*ptr)); memcpy(ptr,item,size); diff --git a/iguana/exchanges/LP_include.h b/iguana/exchanges/LP_include.h index 2a113134d..0c8eb2411 100644 --- a/iguana/exchanges/LP_include.h +++ b/iguana/exchanges/LP_include.h @@ -192,7 +192,7 @@ struct iguana_info uint8_t pubkey33[33]; }; -struct _LP_utxoinfo { bits256 txid; uint64_t value; int32_t vout; }; +struct _LP_utxoinfo { bits256 txid; uint64_t value; int32_t vout,height; }; struct LP_utxostats { uint32_t sessionid,lasttime,errors,swappending,spentflag,lastspentcheck,bestflag; }; @@ -209,7 +209,6 @@ struct LP_utxoinfo struct _LP_utxoinfo payment,deposit,fee; struct LP_utxostats T; struct LP_utxoswap S; - //struct LP_utxonetwork N; int32_t iambob,iamlp; uint8_t key[sizeof(bits256) + sizeof(int32_t)]; uint8_t key2[sizeof(bits256) + sizeof(int32_t)]; @@ -303,6 +302,7 @@ 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); +void LP_address_utxoadd(struct iguana_info *coin,char *coinaddr,bits256 txid,int32_t vout,uint64_t value,int32_t height); #endif diff --git a/iguana/exchanges/LP_nativeDEX.c b/iguana/exchanges/LP_nativeDEX.c index 15296bcd6..cc43a25d3 100644 --- a/iguana/exchanges/LP_nativeDEX.c +++ b/iguana/exchanges/LP_nativeDEX.c @@ -420,30 +420,27 @@ 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,*utmp; //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) { - if ( ap->monitor != 0 ) + DL_FOREACH_SAFE(ap->utxos,up,utmp) { - DL_FOREACH(ap->utxos,up) + if ( up->spentflag == 0 ) { - if ( up->spentflag == 0 ) - { - if ( LP_txvalue(0,coin->symbol,up->U.txid,up->U.vout) == 0 ) - up->spentflag = (uint32_t)time(NULL); - } + if ( LP_txvalue(0,coin->symbol,up->U.txid,up->U.vout) == 0 ) + up->spentflag = (uint32_t)time(NULL); } } } 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_prices.c b/iguana/exchanges/LP_prices.c index c4e011a15..eb1df8867 100644 --- a/iguana/exchanges/LP_prices.c +++ b/iguana/exchanges/LP_prices.c @@ -55,70 +55,6 @@ struct LP_pubkeyinfo uint8_t rmd160[20]; } *LP_pubkeyinfos; - -struct LP_address *_LP_addressfind(struct iguana_info *coin,char *coinaddr) -{ - struct LP_address *ap; - HASH_FIND(hh,coin->addresses,coinaddr,strlen(coinaddr),ap); - return(ap); -} - -struct LP_address *_LP_addressadd(struct iguana_info *coin,char *coinaddr) -{ - struct LP_address *ap; - ap = calloc(1,sizeof(*ap)); - safecopy(ap->coinaddr,coinaddr,sizeof(ap->coinaddr)); - HASH_ADD_KEYPTR(hh,coin->addresses,ap->coinaddr,strlen(ap->coinaddr),ap); - return(ap); -} - -struct LP_address *_LP_address(struct iguana_info *coin,char *coinaddr) -{ - struct LP_address *ap; - if ( (ap= _LP_addressfind(coin,coinaddr)) == 0 ) - ap = _LP_addressadd(coin,coinaddr); - return(ap); -} - -/*void LP_address_utxoadd(struct iguana_info *coin,char *coinaddr,bits256 txid,int32_t vout,uint64_t value) -{ - struct LP_address *ap; struct LP_address_utxo *up; - portable_mutex_lock(&coin->txmutex); - if ( (ap= _LP_address(coin,coinaddr)) != 0 ) - { - up = calloc(1,sizeof(*up)); - up->U.txid = txid; - up->U.vout = vout; - up->U.value = value; - DL_APPEND(ap->utxos,up); - } - portable_mutex_unlock(&coin->txmutex); -} - -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)); - portable_mutex_lock(&coin->txmutex); - if ( (ap= _LP_address(coin,coinaddr)) != 0 ) - { - ap->monitor = (uint32_t)time(NULL); - } - portable_mutex_unlock(&coin->txmutex); - if ( coin->electrum != 0 ) - { - if ( (retjson= electrum_address_subscribe(coin->symbol,coin->electrum,&retjson,coinaddr)) != 0 ) - { - printf("%s MONITOR.(%s) -> %s\n",coin->symbol,coinaddr,jprint(retjson,0)); - free_json(retjson); - } - } - } -}*/ - int32_t LP_pricevalid(double price) { if ( price > SMALLVAL && isnan(price) == 0 && price < SATOSHIDEN ) diff --git a/iguana/exchanges/LP_socket.c b/iguana/exchanges/LP_socket.c index 2866205a8..688a7f870 100644 --- a/iguana/exchanges/LP_socket.c +++ b/iguana/exchanges/LP_socket.c @@ -304,7 +304,7 @@ struct electrum_info *electrum_server(char *symbol,struct electrum_info *ep) return(ep); } -void electrum_process_array(struct iguana_info *coin,cJSON *array) +void electrum_process_array(struct iguana_info *coin,char *coinaddr,cJSON *array) { 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 ) @@ -333,6 +333,7 @@ void electrum_process_array(struct iguana_info *coin,cJSON *array) { 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; + LP_address_utxoadd(coin,coinaddr,txid,v,value,tx->height); } } 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)); @@ -443,7 +444,7 @@ cJSON *electrum_address_gethistory(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_history",addr,ELECTRUM_TIMEOUT); printf("history.(%s)\n",jprint(retjson,0)); - electrum_process_array(coin,retjson); + electrum_process_array(coin,addr,retjson); return(retjson); } @@ -452,7 +453,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)); - electrum_process_array(coin,retjson); + electrum_process_array(coin,addr,retjson); return(retjson); } @@ -465,7 +466,7 @@ cJSON *electrum_address_listunspent(char *symbol,struct electrum_info *ep,cJSON if ( (retjson= electrum_strarg(symbol,ep,retjsonp,"blockchain.address.listunspent",addr,ELECTRUM_TIMEOUT)) != 0 ) { printf("LISTUNSPENT.(%s)\n",jprint(retjson,0)); - electrum_process_array(coin,retjson); + electrum_process_array(coin,addr,retjson); strcpy(coin->lastunspent,addr); coin->unspenttime = (uint32_t)time(NULL); } @@ -608,7 +609,7 @@ 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 queueitem *item = 0; + cJSON *strjson,*errjson,*resultjson,*paramsjson; char *method; int32_t i,n,height; uint32_t idnum=0; struct stritem *stritem; struct queueitem *tmp,*item = 0; ep->lasttime = (uint32_t)time(NULL); if ( (strjson= cJSON_Parse(str)) != 0 ) { @@ -625,11 +626,11 @@ int32_t LP_recvfunc(struct electrum_info *ep,char *str,int32_t len) resultjson = jitem(paramsjson,i); } } - else if ( strcmp(method,"blockchain.address.subscribe") == 0 ) + /*else if ( strcmp(method,"blockchain.address.subscribe") == 0 ) never is called { printf("recv addr subscribe.(%s)\n",jprint(resultjson,0)); electrum_process_array(ep->coin,resultjson); - } + }*/ } if ( resultjson != 0 ) { @@ -644,11 +645,9 @@ int32_t LP_recvfunc(struct electrum_info *ep,char *str,int32_t len) portable_mutex_lock(&ep->pendingQ.mutex); if ( ep->pendingQ.list != 0 ) { - DL_FOREACH(ep->pendingQ.list,item) + DL_FOREACH_SAFE(ep->pendingQ.list,item,tmp) { stritem = (struct stritem *)item; - if ( *stritem->retptrp != 0 ) - continue; if ( item->type == idnum ) { //printf("matched idnum.%d result.%p\n",idnum,resultjson); @@ -660,13 +659,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); } } } @@ -708,7 +707,7 @@ void LP_dedicatedloop(void *arg) if ( ep->pendingQ.list != 0 ) { printf("list %p\n",ep->pendingQ.list); - DL_FOREACH(ep->pendingQ.list,item) + DL_FOREACH_SAFE(ep->pendingQ.list,item,tmp) { printf("item.%p\n",item); if ( item->type == 0xffffffff ) diff --git a/iguana/exchanges/LP_transaction.c b/iguana/exchanges/LP_transaction.c index 71bde88e4..86c06f84d 100644 --- a/iguana/exchanges/LP_transaction.c +++ b/iguana/exchanges/LP_transaction.c @@ -795,33 +795,13 @@ char *basilisk_swap_Aspend(char *name,char *symbol,uint64_t Atxfee,uint8_t wifta return(signedtx); } -int32_t LP_swap_txdestaddr(char *destaddr,bits256 txid,int32_t vout,cJSON *txobj) -{ - int32_t n,m,retval = -1; cJSON *vouts,*item,*addresses,*skey; char *addr; - if ( (vouts= jarray(&n,txobj,"vout")) != 0 && vout < n ) - { - item = jitem(vouts,vout); - if ( (skey= jobj(item,"scriptPubKey")) != 0 && (addresses= jarray(&m,skey,"addresses")) != 0 ) - { - item = jitem(addresses,0); - if ( (addr= jstr(item,0)) != 0 ) - { - safecopy(destaddr,addr,64); - retval = 0; - } - //printf("item.(%s) -> dest.(%s)\n",jprint(item,0),destaddr); - } - } - return(retval); -} - int32_t LP_swap_getcoinaddr(char *symbol,char *coinaddr,bits256 txid,int32_t vout) { cJSON *retjson; coinaddr[0] = 0; if ( (retjson= LP_gettx(symbol,txid)) != 0 ) { - LP_swap_txdestaddr(coinaddr,txid,vout,retjson); + LP_txdestaddr(coinaddr,txid,vout,retjson); free_json(retjson); } return(coinaddr[0] != 0); diff --git a/iguana/exchanges/LP_utxo.c b/iguana/exchanges/LP_utxo.c index 5c327dc99..79ef1d862 100644 --- a/iguana/exchanges/LP_utxo.c +++ b/iguana/exchanges/LP_utxo.c @@ -18,6 +18,16 @@ // marketmaker // +// listunspent: valid for local node, mostly valid for electrum + +// full node + electrum for external listunspent, gettxout to validate +// pruned node + electrum for external listunspent, gettxout to validate +// full node, network for external listunspent, gettxout to validate +// pruned node, network for external listunspent, gettxout to validate +// electrum only, network for gettxout + +// locally track spends, height + uint64_t LP_value_extract(cJSON *obj) { double val = 0.; uint64_t value; @@ -29,6 +39,85 @@ uint64_t LP_value_extract(cJSON *obj) return(value); } +struct LP_address *_LP_addressfind(struct iguana_info *coin,char *coinaddr) +{ + struct LP_address *ap; + HASH_FIND(hh,coin->addresses,coinaddr,strlen(coinaddr),ap); + return(ap); +} + +struct LP_address *_LP_addressadd(struct iguana_info *coin,char *coinaddr) +{ + struct LP_address *ap; + ap = calloc(1,sizeof(*ap)); + safecopy(ap->coinaddr,coinaddr,sizeof(ap->coinaddr)); + HASH_ADD_KEYPTR(hh,coin->addresses,ap->coinaddr,strlen(ap->coinaddr),ap); + return(ap); +} + +struct LP_address *_LP_address(struct iguana_info *coin,char *coinaddr) +{ + struct LP_address *ap; + if ( (ap= _LP_addressfind(coin,coinaddr)) == 0 ) + ap = _LP_addressadd(coin,coinaddr); + return(ap); +} + +void LP_address_utxoadd(struct iguana_info *coin,char *coinaddr,bits256 txid,int32_t vout,uint64_t value,int32_t height) +{ + struct LP_address *ap; struct LP_address_utxo *up,*tmp; int32_t flag; + portable_mutex_lock(&coin->txmutex); + if ( (ap= _LP_address(coin,coinaddr)) != 0 ) + { + flag = 0; + DL_FOREACH_SAFE(ap->utxos,up,tmp) + { + if ( vout == up->U.vout && bits256_cmp(up->U.txid,txid) == 0 ) + { + if ( up->U.height <= 0 && height > 0 ) + up->U.height = height; + flag = 1; + break; + } + } + if ( flag == 0 ) + { + up = calloc(1,sizeof(*up)); + up->U.txid = txid; + up->U.vout = vout; + up->U.height = height; + up->U.value = value; + DL_APPEND(ap->utxos,up); + } + } + portable_mutex_unlock(&coin->txmutex); +} + +/*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)); + portable_mutex_lock(&coin->txmutex); + if ( (ap= _LP_address(coin,coinaddr)) != 0 ) + { + ap->monitor = (uint32_t)time(NULL); + } + portable_mutex_unlock(&coin->txmutex); + if ( coin->electrum != 0 ) + { + if ( (retjson= electrum_address_subscribe(coin->symbol,coin->electrum,&retjson,coinaddr)) != 0 ) + { + printf("%s MONITOR.(%s) -> %s\n",coin->symbol,coinaddr,jprint(retjson,0)); + free_json(retjson); + } + } + } +} +*/ + void LP_utxosetkey(uint8_t *key,bits256 txid,int32_t vout) { memcpy(key,txid.bytes,sizeof(txid)); @@ -270,9 +359,33 @@ int64_t basilisk_txvalue(char *symbol,bits256 txid,int32_t vout) return(value + interest); } +int32_t LP_destaddr(char *destaddr,cJSON *item) +{ + int32_t m,retval = -1; cJSON *addresses,*skey; char *addr; + if ( (skey= jobj(item,"scriptPubKey")) != 0 && (addresses= jarray(&m,skey,"addresses")) != 0 ) + { + item = jitem(addresses,0); + if ( (addr= jstr(item,0)) != 0 ) + { + safecopy(destaddr,addr,64); + retval = 0; + } + //printf("item.(%s) -> dest.(%s)\n",jprint(item,0),destaddr); + } + return(retval); +} + +int32_t LP_txdestaddr(char *destaddr,bits256 txid,int32_t vout,cJSON *txobj) +{ + int32_t n,retval = -1; cJSON *vouts; + if ( (vouts= jarray(&n,txobj,"vout")) != 0 && vout < n ) + retval = LP_destaddr(destaddr,jitem(vouts,vout)); + return(retval); +} + 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]; + struct LP_transaction *tx; cJSON *txobj; uint64_t value; struct iguana_info *coin; char str[65],str2[65],_coinaddr[65]; if ( bits256_nonz(txid) == 0 ) return(0); if ( (coin= LP_coinfind(symbol)) == 0 || coin->inactive != 0 ) @@ -312,6 +425,9 @@ uint64_t LP_txvalue(char *coinaddr,char *symbol,bits256 txid,int32_t vout) if ( (txobj= LP_gettxout(coin->symbol,txid,vout)) != 0 ) { value = SATOSHIDEN * jdouble(txobj,"value"); + if ( coinaddr == 0 ) + coinaddr = _coinaddr; + LP_destaddr(coinaddr,txobj); 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); diff --git a/iguana/exchanges/LP_utxos.c b/iguana/exchanges/LP_utxos.c index bf985cae1..955cdaff8 100644 --- a/iguana/exchanges/LP_utxos.c +++ b/iguana/exchanges/LP_utxos.c @@ -537,11 +537,6 @@ 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 ) - { - LP_address_utxoadd(coin,coinaddr,txid,vout,value); - LP_address_utxoadd(coin,coinaddr,txid2,vout2,value2); - }*/ if ( iambob != 0 ) { if ( LP_mypeer != 0 ) @@ -715,7 +710,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,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; + char *script,destaddr[64]; struct LP_utxoinfo *utxo; cJSON *array,*item; bits256 txid,deposittxid; int32_t used,i,height,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"); @@ -732,41 +727,33 @@ uint64_t LP_privkey_init(int32_t mypubsock,struct iguana_info *coin,bits256 mypr if ( iambob == 0 ) values = calloc(n,sizeof(*values)); else memset(values,0,n * sizeof(*values)); - //if ( iambob == 0 && IAMLP != 0 ) - // continue; used = 0; for (i=0; ielectrum == 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; - } else used++; + txid = jbits256(item,"txid"); + vout = juint(item,"vout"); + value = LP_value_extract(item); + height = coin->height - jint(item,"confirmations"); } else { - //{"value":1000000,"tx_hash":"4e4f818c53486c0576693b4cd379849e5ff95538b38e4100f48884073a4e7636","tx_pos":0,"height":484877} - satoshis = j64bits(item,"value"); - 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 - { - printf("skip.(%s) coinht.%d\n",jprint(item,0),coin->height); - used++; - } + txid = jbits256(item,"tx_hash"); + vout = juint(item,"tx_pos"); + value = j64bits(item,"value"); + height = jint(item,"height"); } - //printf("%.8f ",dstr(satoshis)); + satoshis = LP_txvalue(destaddr,coin->symbol,txid,vout); + if ( satoshis != value ) + printf("unexpected privkey_init value mismatch %.8f vs %.8f (%s)\n",dstr(satoshis),dstr(value),jprint(item,0)); + if ( LP_inventory_prevent(iambob,coin->symbol,txid,vout) == 0 && height > 0 ) + { + //printf("%s\n",jprint(item,0)); + values[i] = satoshis; + LP_address_utxoadd(coin,destaddr,txid,vout,satoshis,height); + } else used++; } //printf("array.%d\n",n); while ( used < n-1 )