diff --git a/iguana/exchanges/LP_commands.c b/iguana/exchanges/LP_commands.c index b76100e93..754dd6d3d 100644 --- a/iguana/exchanges/LP_commands.c +++ b/iguana/exchanges/LP_commands.c @@ -351,6 +351,8 @@ dividends(coin, height, )\n\ return(LP_numutxos()); else if ( strcmp(method,"postprice") == 0 ) retstr = LP_postedprice(argjson); + else if ( strcmp(method,"postutxos") == 0 ) + retstr = LP_postedutxos(argjson); else if ( strcmp(method,"encrypted") == 0 ) retstr = clonestr("{\"result\":\"success\"}"); else if ( strcmp(method,"getprices") == 0 ) @@ -388,6 +390,12 @@ dividends(coin, height, )\n\ return(clonestr("{\"error\":\"you are running an obsolete version, update\"}")); else if ( strcmp(method,"lookup") == 0 ) return(clonestr("{\"error\":\"you are running an obsolete version, update\"}")); + else if ( strcmp(method,"listunspent") == 0 ) + { + if ( (ptr= LP_coinsearch(jstr(argjson,"coin"))) != 0 ) + return(jprint(LP_address_utxos(ptr,jstr(argjson,"address"),1),1)); + else return(clonestr("{\"error\":\"cant find coind\"}")); + } if ( strcmp(method,"broadcast") == 0 ) { bits256 zero; char *cipherstr; int32_t cipherlen; uint8_t cipher[LP_ENCRYPTED_MAXSIZE]; diff --git a/iguana/exchanges/LP_nativeDEX.c b/iguana/exchanges/LP_nativeDEX.c index 9bc79a954..fb492573f 100644 --- a/iguana/exchanges/LP_nativeDEX.c +++ b/iguana/exchanges/LP_nativeDEX.c @@ -325,6 +325,7 @@ void command_rpcloop(void *myipaddr) int32_t LP_mainloop_iter(void *ctx,char *myipaddr,struct LP_peerinfo *mypeer,int32_t pubsock,char *pushaddr,uint16_t myport,char *passphrase) { + int32_t enable_utxos = 0; static uint32_t counter,numpeers,lastresync; //lastforward struct LP_utxoinfo *utxo,*utmp; cJSON *retjson; struct iguana_info *coin,*ctmp; char *retstr,*origipaddr; struct LP_peerinfo *peer,*tmp,*mostpeer; uint32_t id,now; int32_t mostutxos,nonz = 0,n=0,num,lastn=-1; now = (uint32_t)time(NULL); @@ -332,7 +333,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"; - //if ( LP_canbind == 0 ) printf("counter.%d canbind.%d peers\n",counter,LP_canbind); numpeers = LP_numpeers(); mostutxos = 0; mostpeer = 0; @@ -357,7 +357,7 @@ int32_t LP_mainloop_iter(void *ctx,char *myipaddr,struct LP_peerinfo *mypeer,int // printf("%s num.%d vs %d\n",peer->ipaddr,peer->numpeers,numpeers); if ( strcmp(peer->ipaddr,myipaddr) != 0 ) LP_peersquery(mypeer,pubsock,peer->ipaddr,peer->port,myipaddr,myport); - if ( IAMLP != 0 && LP_mypeer != 0 && strcmp(peer->ipaddr,myipaddr) != 0 ) + if ( enable_utxos && IAMLP != 0 && LP_mypeer != 0 && strcmp(peer->ipaddr,myipaddr) != 0 ) { if ( (retstr= issue_LP_numutxos(peer->ipaddr,peer->port,LP_mypeer->ipaddr,LP_mypeer->port,LP_mypeer->numpeers,LP_mypeer->numutxos)) != 0 ) { @@ -379,7 +379,7 @@ int32_t LP_mainloop_iter(void *ctx,char *myipaddr,struct LP_peerinfo *mypeer,int } if ( peer->diduquery == 0 ) { - if ( lastn != n || n < 20 ) + if ( enable_utxos && (lastn != n || n < 20) ) { lastn = n; n = LP_peer_utxosquery(mypeer,myport,pubsock,peer,now,60,100); @@ -394,14 +394,14 @@ int32_t LP_mainloop_iter(void *ctx,char *myipaddr,struct LP_peerinfo *mypeer,int } } //printf("numutxos vs mine.%d\n",LP_mypeer != 0 ? LP_mypeer->numutxos : -1); - if ( LP_mypeer != 0 && mostpeer != 0 && ((LP_mypeer->numutxos < mostutxos && time(NULL) > lastresync+10) || time(NULL) > lastresync+60) ) + if ( enable_utxos && LP_mypeer != 0 && mostpeer != 0 && ((LP_mypeer->numutxos < mostutxos && time(NULL) > lastresync+10) || time(NULL) > lastresync+60) ) { //printf("myutxos.%d most.%d %s\n",LP_mypeer->numutxos,mostutxos,mostpeer->ipaddr); LP_peer_utxosquery(LP_mypeer,myport,pubsock,mostpeer,now,60,(mostutxos-LP_mypeer->numutxos) * 2); lastresync = (uint32_t)time(NULL); //LP_peer_pricesquery(mostpeer->ipaddr,mostpeer->port); } - if ( (counter % 6000) == 10 ) + if ( enable_utxos && (counter % 6000) == 10 ) { LP_myutxo_updates(ctx,pubsock,passphrase); HASH_ITER(hh,LP_utxoinfos[0],utxo,utmp) @@ -422,25 +422,35 @@ int32_t LP_mainloop_iter(void *ctx,char *myipaddr,struct LP_peerinfo *mypeer,int { 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 ) + if ( coin->inactive != 0 ) continue; if ( time(NULL) > coin->lastmonitor+60 ) { portable_mutex_lock(&coin->txmutex); HASH_ITER(hh,coin->addresses,ap,atmp) { - DL_FOREACH_SAFE(ap->utxos,up,utmp) + if ( coin->electrum == 0 ) { - if ( up->spendheight <= 0 ) + DL_FOREACH_SAFE(ap->utxos,up,utmp) { - if ( LP_txvalue(0,coin->symbol,up->U.txid,up->U.vout) == 0 ) - up->spendheight = 1; + if ( up->spendheight <= 0 ) + { + if ( LP_txvalue(0,coin->symbol,up->U.txid,up->U.vout) == 0 ) + up->spendheight = 1; + } } } + else + { + if ( (retjson= electrum_address_listunspent(coin->symbol,coin->electrum,&retjson,ap->coinaddr)) != 0 ) + free_json(retjson); + } } portable_mutex_unlock(&coin->txmutex); coin->lastmonitor = (uint32_t)time(NULL); } + if ( coin->electrum != 0 ) + continue; memset(zero.bytes,0,sizeof(zero)); if ( time(NULL) > coin->lastgetinfo+LP_GETINFO_INCR ) { @@ -450,16 +460,6 @@ int32_t LP_mainloop_iter(void *ctx,char *myipaddr,struct LP_peerinfo *mypeer,int if ( 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); - /*if ( (obj= LP_getinfo(coin->symbol)) != 0 ) - { - if ( (height= jint(obj,"blocks")) > coin->longestchain ) - { - coin->longestchain = height; - if ( 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); - free_json(obj); - } else printf("error getting info.%s\n",coin->symbol);*/ coin->lastgetinfo = (uint32_t)time(NULL); } if ( coin->firstrefht == 0 ) diff --git a/iguana/exchanges/LP_utxo.c b/iguana/exchanges/LP_utxo.c index b8926cf4d..e47c2768e 100644 --- a/iguana/exchanges/LP_utxo.c +++ b/iguana/exchanges/LP_utxo.c @@ -87,6 +87,15 @@ struct LP_address *_LP_address(struct iguana_info *coin,char *coinaddr) return(ap); } +struct LP_address *LP_addressfind(struct iguana_info *coin,char *coinaddr) +{ + struct LP_address *ap; + portable_mutex_lock(&coin->txmutex); + ap = _LP_addressfind(coin,coinaddr); + portable_mutex_unlock(&coin->txmutex); + return(ap); +} + void LP_address_utxoadd(struct iguana_info *coin,char *coinaddr,bits256 txid,int32_t vout,uint64_t value,int32_t height,int32_t spendheight) { struct LP_address *ap; struct LP_address_utxo *up,*tmp; int32_t flag; @@ -145,19 +154,88 @@ cJSON *LP_address_utxos(struct iguana_info *coin,char *coinaddr,int32_t electrum { cJSON *array; struct LP_address *ap; struct LP_address_utxo *up,*tmp; array = cJSON_CreateArray(); - portable_mutex_lock(&coin->txmutex); - if ( (ap= _LP_addressfind(coin,coinaddr)) != 0 ) + if ( coinaddr != 0 && coinaddr[0] != 0 ) { - DL_FOREACH_SAFE(ap->utxos,up,tmp) + portable_mutex_lock(&coin->txmutex); + if ( (ap= _LP_addressfind(coin,coinaddr)) != 0 ) { - if ( up->spendheight <= 0 ) - jaddi(array,LP_address_item(coin,up,electrumret)); + DL_FOREACH_SAFE(ap->utxos,up,tmp) + { + if ( up->spendheight <= 0 ) + jaddi(array,LP_address_item(coin,up,electrumret)); + } } + portable_mutex_unlock(&coin->txmutex); } - portable_mutex_unlock(&coin->txmutex); return(array); } +void LP_postutxos(int32_t pubsock,char *symbol) +{ + bits256 zero; char *msg; struct iguana_info *coin; cJSON *array,*reqjson = cJSON_CreateObject(); + if ( (coin= LP_coinfind(symbol)) != 0 && (array= LP_address_utxos(coin,coin->smartaddr,1)) != 0 ) + { + if ( cJSON_GetArraySize(array) == 0 ) + free_json(array); + else + { + memset(zero.bytes,0,sizeof(zero)); + jaddstr(reqjson,"method","postutxos"); + jaddstr(reqjson,"coin",symbol); + jaddstr(reqjson,"coinaddr",coin->smartaddr); + jadd(reqjson,"utxos",array); + msg = jprint(reqjson,1); + printf("post (%s)\n",msg); + LP_broadcast_message(pubsock,symbol,symbol,zero,msg); + } + } +} + +char *LP_postedutxos(cJSON *argjson) +{ + int32_t i,n,v,ht,errs,height; uint64_t value,val; cJSON *array,*item,*txobj; bits256 txid; char str[65],*symbol,*coinaddr; struct LP_address *ap; struct iguana_info *coin; + if ( (coinaddr= jstr(argjson,"coinaddr")) != 0 && (symbol= jstr(argjson,"coin")) != 0 && (coin= LP_coinfind(symbol)) != 0 ) // addsig + { + printf("posted.(%s)\n",jprint(argjson,0)); + if ( coin->electrum == 0 || (ap= LP_addressfind(coin,coinaddr)) != 0 ) + { + if ( (array= jarray(&n,argjson,"utxos")) != 0 ) + { + for (i=0; ielectrum == 0 && (txobj= LP_gettxout(symbol,txid,v)) != 0 ) + { + value = LP_value_extract(txobj,0); + if ( value != val ) + { + printf("%s %s/v%d value.%llu vs %llu\n",symbol,bits256_str(str,txid),v,(long long)value,(long long)val); + errs++; + } + ht = coin->height - jint(txobj,"confirmations"); + if ( ht != height ) + { + printf("%s %s/v%d ht.%d vs %d\n",symbol,bits256_str(str,txid),v,ht,height); + errs++; + } + free_json(txobj); + } + if ( errs == 0 ) + LP_address_utxoadd(coin,coinaddr,txid,v,val,height,-1); + } + } + } + else if ( (array= electrum_address_listunspent(symbol,coin->electrum,&array,coinaddr)) != 0 ) + free_json(array); + } + return(clonestr("{\"result\":\"success\"}")); +} + /*void LP_address_monitor(struct LP_pubkeyinfo *pubp) { struct iguana_info *coin,*tmp; char coinaddr[64]; cJSON *retjson; struct LP_address *ap; diff --git a/iguana/exchanges/LP_utxos.c b/iguana/exchanges/LP_utxos.c index 01843bd29..124e813d4 100644 --- a/iguana/exchanges/LP_utxos.c +++ b/iguana/exchanges/LP_utxos.c @@ -249,6 +249,7 @@ cJSON *LP_utxojson(struct LP_utxoinfo *utxo) 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(); + printf("deprecated! LP_utxos\n"); //n = mypeer != 0 ? mypeer->numutxos : 0; if ( lastn <= 0 ) lastn = LP_PROPAGATION_SLACK * 2; @@ -365,32 +366,12 @@ char *LP_spentcheck(cJSON *argjson) void LP_utxo_clientpublish(struct LP_utxoinfo *utxo) { bits256 zero; char *msg; - if ( LP_isunspent(utxo) > 0 ) + if ( 0 && LP_isunspent(utxo) > 0 ) { memset(zero.bytes,0,sizeof(zero)); msg = jprint(LP_utxojson(utxo),1); LP_broadcast_message(LP_mypubsock,utxo->coin,"",zero,msg); } - /*struct LP_peerinfo *peer,*tmp; cJSON *retjson; char *retstr; int32_t n = 0; - HASH_ITER(hh,LP_peerinfos,peer,tmp) - { - if ( (retstr= issue_LP_notifyutxo(peer->ipaddr,peer->port,utxo)) != 0 ) - { - if ( (retjson= cJSON_Parse(retstr)) != 0 ) - { - if ( jobj(retjson,"error") == 0 ) - { - utxo->T.lasttime = (uint32_t)time(NULL); - n++; - } - free_json(retjson); - } - free(retstr); - } - //if ( utxo->T.lasttime != 0 ) - // return(0); - } - return(n);*/ } struct LP_utxoinfo *LP_utxoadd(int32_t iambob,int32_t mypubsock,char *symbol,bits256 txid,int32_t vout,int64_t value,bits256 txid2,int32_t vout2,int64_t value2,char *spendscript,char *coinaddr,bits256 pubkey,char *gui,uint32_t sessionid) @@ -419,27 +400,6 @@ struct LP_utxoinfo *LP_utxoadd(int32_t iambob,int32_t mypubsock,char *symbol,bit printf("trying to add Alice utxo when not mine? %s/v%d\n",bits256_str(str,txid),vout); return(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); - } - numconfirms = -1; - if ( (txobj= LP_gettx(symbol,txid2)) != 0 ) - { - if ( coin->electrum == 0 ) - numconfirms = jint(txobj,"confirmations"); - else numconfirms = coin->height - jint(txobj,"height"); - free_json(txobj); - } - if ( numconfirms <= 0 ) - { - printf("LP_utxoadd reject2 numconfirms.%d\n",numconfirms); - return(0); - }*/ if ( coin->inactive == 0 ) { if ( LP_iseligible(&val,&val2,iambob,symbol,txid,vout,tmpsatoshis,txid2,vout2) <= 0 ) @@ -612,6 +572,8 @@ int32_t LP_utxosparse(char *destipaddr,uint16_t destport,char *retstr,uint32_t n int32_t LP_utxosquery(struct LP_peerinfo *mypeer,int32_t mypubsock,char *destipaddr,uint16_t destport,char *coin,int32_t lastn,char *myipaddr,uint16_t myport,int32_t maxentries) { char *retstr; struct LP_peerinfo *peer; uint32_t now; int32_t retval = -1; + printf("deprecated LP_utxosquery\n"); + return(-1); peer = LP_peerfind((uint32_t)calc_ipbits(destipaddr),destport); if ( coin == 0 ) coin = ""; @@ -841,6 +803,7 @@ uint64_t LP_privkey_init(int32_t mypubsock,struct iguana_info *coin,bits256 mypr } } free_json(array); + LP_postutxos(mypubsock,coin->symbol); } //printf("privkey.%s %.8f\n",symbol,dstr(total)); return(total);