diff --git a/iguana/exchanges/LP_nativeDEX.c b/iguana/exchanges/LP_nativeDEX.c index 5db9a7f24..3e1189b98 100644 --- a/iguana/exchanges/LP_nativeDEX.c +++ b/iguana/exchanges/LP_nativeDEX.c @@ -21,6 +21,7 @@ // // SPV at tx level and limit SPV proofing + // stats, fix pricearray // sign packets // dPoW security diff --git a/iguana/exchanges/LP_ordermatch.c b/iguana/exchanges/LP_ordermatch.c index 53fd437f0..943a755d6 100644 --- a/iguana/exchanges/LP_ordermatch.c +++ b/iguana/exchanges/LP_ordermatch.c @@ -441,17 +441,33 @@ int32_t LP_nanobind(void *ctx,char *pairstr) return(pairsock); } -int32_t LP_nearest_utxovalue(int32_t noSPV,struct LP_address_utxo **utxos,int32_t n,uint64_t targetval) +int32_t LP_nearest_utxovalue(struct iguana_info *coin,struct LP_address_utxo **utxos,int32_t n,uint64_t targetval) { - int32_t i,mini = -1; int64_t dist; uint64_t mindist = (1LL << 60); + int32_t i,mini = -1; struct LP_address_utxo *up; struct electrum_info *backupep=0,*ep; char str[65]; int64_t dist; uint64_t mindist = (1LL << 60); + if ( (ep= coin->electrum) != 0 ) + { + if ( (backupep= ep->prev) == 0 ) + backupep = ep; + } for (i=0; ispendheight == 0 && utxos[i]->SPV > 0)) ) + if ( (up= utxos[i]) != 0 && up->spendheight == 0 ) { - dist = (utxos[i]->U.value - targetval); + if ( coin->electrum != 0 ) + { + if (up->SPV == 0 ) + up->SPV = LP_merkleproof(coin,backupep,up->U.txid,up->U.height); + printf("%s %s: SPV.%d\n",coin->symbol,bits256_str(str,up->U.txid),up->SPV); + if ( up->SPV < 0 ) + { + printf("SPV failure for %s %s\n",coin->symbol,bits256_str(str,up->U.txid)); + continue; + } + } + dist = (up->U.value - targetval); if ( dist >= 0 && dist < mindist ) { - printf("(%.8f %.8f %.8f).%d ",dstr(utxos[i]->U.value),dstr(dist),dstr(mindist),mini); + printf("(%.8f %.8f %.8f).%d ",dstr(up->U.value),dstr(dist),dstr(mindist),mini); mini = i; mindist = dist; } @@ -484,12 +500,12 @@ struct LP_utxoinfo *LP_address_utxopair(int32_t iambob,struct LP_address_utxo ** printf("targetval %.8f vol %.8f price %.8f txfee %.8f %s\n",dstr(targetval),relvolume,price,dstr(txfee),coinaddr); } mini = -1; - if ( targetval != 0 && (mini= LP_nearest_utxovalue(coin->electrum == 0,utxos,m,targetval)) >= 0 && (double)utxos[mini]->U.value/targetval < LP_MINVOL-1 ) + if ( targetval != 0 && (mini= LP_nearest_utxovalue(coin,utxos,m,targetval)) >= 0 && (double)utxos[mini]->U.value/targetval < LP_MINVOL-1 ) { up = utxos[mini]; utxos[mini] = 0; targetval2 = (targetval / 8) * 9 + 2*txfee; - if ( (mini= LP_nearest_utxovalue(coin->electrum == 0,utxos,m,targetval2 * 1.01)) >= 0 ) + if ( (mini= LP_nearest_utxovalue(coin,utxos,m,targetval2 * 1.01)) >= 0 ) { if ( up != 0 && (up2= utxos[mini]) != 0 ) { diff --git a/iguana/exchanges/LP_utxo.c b/iguana/exchanges/LP_utxo.c index 6b5ce26ba..5916b14b9 100644 --- a/iguana/exchanges/LP_utxo.c +++ b/iguana/exchanges/LP_utxo.c @@ -302,9 +302,37 @@ bits256 validate_merkle(int32_t pos,bits256 txid,cJSON *proofarray,int32_t proof return(hash); } +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; + 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); + if ( (hdrobj= electrum_getheader(coin->symbol,ep,&hdrobj,height)) != 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\n",bits256_str(str,txid),height,jprint(merkobj,0),bits256_str(str2,roothash),bits256_str(str3,merkleroot)); + free_json(hdrobj); + } + } + free_json(merkobj); + } + return(SPV); +} + cJSON *LP_address_utxos(struct iguana_info *coin,char *coinaddr,int32_t electrumret) { - cJSON *array,*item,*merkobj,*merkles,*hdrobj; int32_t n,m; uint64_t total; struct LP_address *ap=0,*atmp; struct LP_address_utxo *up,*tmp; bits256 merkleroot,roothash; struct electrum_info *ep,*backupep=0; + cJSON *array,*item; int32_t n; uint64_t total; struct LP_address *ap=0,*atmp; struct LP_address_utxo *up,*tmp; struct electrum_info *ep,*backupep=0; array = cJSON_CreateArray(); if ( coinaddr != 0 && coinaddr[0] != 0 ) { @@ -321,30 +349,8 @@ cJSON *LP_address_utxos(struct iguana_info *coin,char *coinaddr,int32_t electrum { if ( up->spendheight <= 0 && up->U.height > 0 ) { - if ( ep != 0 && up->SPV == 0 && up->U.height > 0 ) - { - if ( (merkobj= electrum_getmerkle(coin->symbol,backupep,&merkobj,up->U.txid,up->U.height)) != 0 ) - { - char str[65],str2[65],str3[65]; - memset(roothash.bytes,0,sizeof(roothash)); - if ( (merkles= jarray(&m,merkobj,"merkle")) != 0 ) - { - roothash = validate_merkle(jint(merkobj,"pos"),up->U.txid,merkles,m); - if ( (hdrobj= electrum_getheader(coin->symbol,backupep,&hdrobj,up->U.height)) != 0 ) - { - merkleroot = jbits256(hdrobj,"merkle_root"); - if ( bits256_cmp(merkleroot,roothash) == 0 ) - { - up->SPV = up->U.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,up->U.txid),up->U.height,jprint(merkobj,0),bits256_str(str2,roothash),bits256_str(str3,merkleroot)); - free_json(hdrobj); - } - } - free_json(merkobj); - } - } + if ( backupep != 0 && up->SPV == 0 ) + up->SPV = LP_merkleproof(coin,backupep,up->U.txid,up->U.height); jaddi(array,LP_address_item(coin,up,electrumret)); n++; total += up->U.value;