From c8d75a2ab590bdb82ead7de32866d22731c987d2 Mon Sep 17 00:00:00 2001 From: jl777 Date: Fri, 10 Nov 2017 18:09:14 +0200 Subject: [PATCH] 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); -} - - -