diff --git a/iguana/exchanges/LP_include.h b/iguana/exchanges/LP_include.h index f66db99ff..7849e40d9 100644 --- a/iguana/exchanges/LP_include.h +++ b/iguana/exchanges/LP_include.h @@ -44,7 +44,7 @@ #define LP_PEERGOOD_ERRORDECAY 0.9 #define LP_SWAPSTEP_TIMEOUT 30 -#define LP_AUTOTRADE_TIMEOUT 15 +#define LP_AUTOTRADE_TIMEOUT 10 #define LP_MIN_TXFEE 10000 #define LP_MINVOL 20 #define LP_MINCLIENTVOL 50 diff --git a/iguana/exchanges/LP_nativeDEX.c b/iguana/exchanges/LP_nativeDEX.c index f683c22cb..a03d9f858 100644 --- a/iguana/exchanges/LP_nativeDEX.c +++ b/iguana/exchanges/LP_nativeDEX.c @@ -18,6 +18,10 @@ // LP_nativeDEX.c // marketmaker // +// variable timeout based on number of electrums in swap +// listunspent on each new block or 30 seconds if doing swap +// reject swap response from bob? +// // electrum swaps efficiency // process stats.log local file -> map of realtime activity! // select oldest utxo first @@ -397,7 +401,7 @@ int32_t LP_utxos_sync(struct LP_peerinfo *peer) return(0); HASH_ITER(hh,LP_coins,coin,ctmp) { - if ( IAMLP == 0 && coin->inactive != 0 )//|| (coin->electrum != 0 && coin->obooktime == 0) ) + if ( IAMLP == 0 && coin->inactive != 0 ) continue; if ( coin->smartaddr[0] == 0 ) continue; @@ -512,7 +516,7 @@ int32_t LP_utxos_sync(struct LP_peerinfo *peer) void LP_coinsloop(void *_coins) { - struct iguana_info *coin,*ctmp; bits256 zero; int32_t j,nonz; char *coins = _coins; + struct LP_address *ap=0,*atmp; struct LP_address_utxo *up,*tmp; struct iguana_info *coin,*ctmp; char str[65]; struct electrum_info *ep,*backupep=0; bits256 zero; int32_t oldht,j,nonz; char *coins = _coins; while ( 1 ) { nonz = 0; @@ -531,8 +535,37 @@ void LP_coinsloop(void *_coins) memset(&zero,0,sizeof(zero)); if ( coin->inactive != 0 ) continue; - if ( coin->electrum != 0 ) + if ( (ep= coin->electrum) != 0 ) + { + if ( (backupep= ep->prev) == 0 ) + backupep = ep; + HASH_ITER(hh,coin->addresses,ap,atmp) + { + DL_FOREACH_SAFE(ap->utxos,up,tmp) + { + if ( up->SPV == 0 ) + { + nonz++; + up->SPV = LP_merkleproof(coin,backupep,up->U.txid,up->U.height); + if ( up->SPV > 0 ) + printf("%s %s: SPV.%d\n",coin->symbol,bits256_str(str,up->U.txid),up->SPV); + } + else if ( up->SPV == -1 ) + { + nonz++; + printf("SPV failure for %s %s\n",coin->symbol,bits256_str(str,up->U.txid)); + 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); + 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); + } + } + } continue; + } if ( coin->firstrefht == 0 ) continue; else if ( coin->firstscanht == 0 ) @@ -557,6 +590,7 @@ void LP_coinsloop(void *_coins) coin->lastscanht = coin->firstscanht; continue; } + nonz++; //if ( (coin->lastscanht % 1000) == 0 ) printf("[%s]: %s ref.%d scan.%d to %d, longest.%d\n",coins,coin->symbol,coin->firstrefht,coin->firstscanht,coin->lastscanht,coin->longestchain); for (j=0; j<100; j++) @@ -570,8 +604,6 @@ void LP_coinsloop(void *_coins) if ( coin->lastscanht == coin->longestchain+1 ) break; } - nonz++; - continue; } if ( nonz == 0 ) usleep(1000); diff --git a/iguana/exchanges/LP_ordermatch.c b/iguana/exchanges/LP_ordermatch.c index 93b8f7e75..9899bf9bc 100644 --- a/iguana/exchanges/LP_ordermatch.c +++ b/iguana/exchanges/LP_ordermatch.c @@ -200,7 +200,7 @@ int32_t LP_nanobind(void *ctx,char *pairstr) int32_t LP_nearest_utxovalue(struct iguana_info *coin,char *coinaddr,struct LP_address_utxo **utxos,int32_t n,uint64_t targetval) { - int32_t i,oldht,mini = -1; struct LP_address_utxo *up; struct electrum_info *backupep=0,*ep; char str[65]; int64_t dist; uint64_t mindist = (1LL << 60); + int32_t i,mini = -1; struct LP_address_utxo *up; struct electrum_info *backupep=0,*ep; int64_t dist; uint64_t mindist = (1LL << 60); if ( (ep= coin->electrum) != 0 ) { if ( (backupep= ep->prev) == 0 ) @@ -215,25 +215,6 @@ int32_t LP_nearest_utxovalue(struct iguana_info *coin,char *coinaddr,struct LP_a //printf("nearest i.%d target %.8f val %.8f dist %.8f mindist %.8f mini.%d spent.%d\n",i,dstr(targetval),dstr(up->U.value),dstr(dist),dstr(mindist),mini,up->spendheight); if ( up->spendheight <= 0 ) { - if ( coin->electrum != 0 ) - { - if ( up->SPV == 0 || up->SPV == -1 ) - up->SPV = LP_merkleproof(coin,backupep,up->U.txid,up->U.height); - if ( up->SPV == 0 || up->SPV == -1 ) - { - printf("SPV failure for %s %s\n",coin->symbol,bits256_str(str,up->U.txid)); - if ( up->SPV == -1 ) - { - oldht = up->U.height; - LP_txheight_check(coin,coinaddr,up); - if ( oldht != up->U.height ) - up->SPV = LP_merkleproof(coin,backupep,up->U.txid,up->U.height); - if ( up->SPV < 0 ) - up->SPV = -2; - } - continue; - } //else printf("%s %s: SPV.%d\n",coin->symbol,bits256_str(str,up->U.txid),up->SPV); - } if ( (coin->electrum == 0 || up->SPV > 0) && dist >= 0 && dist < mindist ) { //printf("(%.8f %.8f %.8f).%d ",dstr(up->U.value),dstr(dist),dstr(mindist),mini); @@ -800,20 +781,30 @@ struct LP_utxoinfo *LP_buyutxo(double *ordermatchpricep,int64_t *bestsatoshisp,i if ( bits256_cmp(pubkey,G.LP_mypub25519) != 0 && (pubp= LP_pubkeyadd(pubkey)) != 0 ) { bitcoin_address(coinaddr,basecoin->taddr,basecoin->pubtype,pubp->rmd160,sizeof(pubp->rmd160)); - LP_listunspent_query(base,coinaddr); - LP_listunspent_both(base,coinaddr,1); asatoshis = autxo->S.satoshis; - for (j=0; jelectrum != 0 ) + { + price *= 1.01; + *ordermatchpricep = price; + *bestsatoshisp = LP_basesatoshis(dstr(asatoshis),price,txfee,desttxfee); + *bestdestsatoshisp = asatoshis; + } + else*/ { - if ( (bestutxo= LP_ordermatch_iter(utxos,max,ordermatchpricep,bestsatoshisp,bestdestsatoshisp,basecoin,coinaddr,asatoshis,price,txfee,desttxfee,pubp->pubkey,gui)) != 0 ) + LP_listunspent_query(base,coinaddr); + LP_listunspent_both(base,coinaddr,1); + for (j=0; jpubkey,gui)) != 0 ) + { + printf("j.%d/%d ordermatch %.8f best satoshis %.8f destsatoshis %.8f txfees (%.8f %.8f)\n",j,maxiters,price,dstr(*bestsatoshisp),dstr(*bestdestsatoshisp),dstr(txfee),dstr(desttxfee)); + break; + } + asatoshis = (asatoshis / 64) * 63; } - asatoshis = (asatoshis / 64) * 63; + if ( j < maxiters ) + break; } - if ( j < maxiters ) - break; } else printf("self trading or blacklisted peer\n"); } else @@ -838,7 +829,11 @@ struct LP_utxoinfo *LP_buyutxo(double *ordermatchpricep,int64_t *bestsatoshisp,i char *LP_autobuy(void *ctx,char *myipaddr,int32_t mypubsock,char *base,char *rel,double maxprice,double relvolume,int32_t timeout,int32_t duration,char *gui,uint32_t nonce) { - uint64_t desttxfee,txfee; uint32_t lastnonce; int32_t i,maxiters,numpubs = 0; int64_t bestsatoshis=0,destsatoshis,bestdestsatoshis=0; struct LP_utxoinfo *autxo,*bestutxo = 0; double qprice,ordermatchprice=0.; struct LP_quoteinfo Q; bits256 pubkeys[100]; + uint64_t desttxfee,txfee; uint32_t lastnonce; int32_t i,maxiters,numpubs = 0; int64_t bestsatoshis=0,destsatoshis,bestdestsatoshis=0; struct iguana_info *basecoin,*relcoin; struct LP_utxoinfo *autxo,*bestutxo = 0; double qprice,ordermatchprice=0.; struct LP_quoteinfo Q; bits256 pubkeys[100]; + basecoin = LP_coinfind(base); + relcoin = LP_coinfind(rel); + if ( basecoin == 0 || basecoin->inactive != 0 || relcoin == 0 || relcoin->inactive != 0 ) + return(clonestr("{\"error\":\"base or rel not found or inactive\"}")); if ( LP_aliceonly(base) > 0 ) return(clonestr("{\"error\":\"GAME can only be alice coin\"}")); printf("LP_autobuy %s/%s price %.8f vol %.8f nonce %u\n",base,rel,maxprice,relvolume,nonce); @@ -852,6 +847,16 @@ char *LP_autobuy(void *ctx,char *myipaddr,int32_t mypubsock,char *base,char *rel duration = LP_ORDERBOOK_DURATION; if ( timeout <= 0 ) timeout = LP_AUTOTRADE_TIMEOUT; + if ( basecoin->electrum != 0 && relcoin->electrum != 0 ) + { + if ( timeout < 3*LP_AUTOTRADE_TIMEOUT ) + timeout = 3*LP_AUTOTRADE_TIMEOUT; + } + else if ( basecoin->electrum != 0 || relcoin->electrum != 0 ) + { + if ( timeout < 2*LP_AUTOTRADE_TIMEOUT ) + timeout = 2*LP_AUTOTRADE_TIMEOUT; + } if ( time(NULL) < Alice_expiration ) return(clonestr("{\"error\":\"only one pending request at a time\"}")); else diff --git a/iguana/exchanges/LP_utxo.c b/iguana/exchanges/LP_utxo.c index 027544a6d..998d12ce1 100644 --- a/iguana/exchanges/LP_utxo.c +++ b/iguana/exchanges/LP_utxo.c @@ -18,19 +18,6 @@ // 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 - -// handle spurious errors -// handle invalid data - -//REJECT KMD ccee27b53b52ca61bbc9fdc7de5feb0a12c14d4d92639414d372f002cc3d092f/v0 value.468169379 vs 468169380 ({"bestblock":"080400d4216c02d100004fd2f4f3505ddb507b643785e02703d3412feba39fb1","confirmations":2356,"value":4.68169380,"scriptPubKey":{"asm":"0224e31f93eff0cc30eaf0b2389fbc591085c0e122c4d11862c1729d090106c842 OP_CHECKSIG","hex":"210224e31f93eff0cc30eaf0b2389fbc591085c0e122c4d11862c1729d090106c842ac","reqSigs":1,"type":"pubkey","addresses":["RFssbc211PJdVy1bvcvAG5X2N4ovPAoy5o"]},"version":1,"coinbase":true}) - uint64_t LP_value_extract(cJSON *obj,int32_t addinterest) { double val = 0.; uint64_t value = 0; int32_t electrumflag; @@ -208,12 +195,8 @@ int32_t LP_address_utxoadd(struct iguana_info *coin,char *coinaddr,bits256 txid, if ( vout == up->U.vout && bits256_cmp(up->U.txid,txid) == 0 ) { flag = 1; - if ( height > 0 && up->U.height != height && up->SPV <= 0 ) - { - if ( up->U.height > 0 ) - printf("%s SPV.%d update %s/v%d up->U.height %d <- %d\n",coin->symbol,up->SPV,bits256_str(str,up->U.txid),up->U.vout,up->U.height,height); + if ( height > 0 && up->U.height != height ) up->U.height = height, flag |= 2; - } if ( spendheight > 0 && up->spendheight != spendheight ) up->spendheight = spendheight, flag |= 4; if ( up->U.value == 0 && up->U.value != value ) @@ -240,9 +223,9 @@ int32_t LP_address_utxoadd(struct iguana_info *coin,char *coinaddr,bits256 txid, up->spendheight = spendheight; portable_mutex_lock(&coin->addrmutex); DL_APPEND(ap->utxos,up); - portable_mutex_unlock(&coin->addrmutex); + portable_mutex_unlock(&coin->addrmutex); retval = 1; - //if ( 0 && height > 0 && strcmp("REVS",coin->symbol) == 0 ) + if ( 0 && height > 0 && strcmp("REVS",coin->symbol) == 0 ) printf("ADD UTXO >> %s %s %s/v%d ht.%d %.8f\n",coin->symbol,coinaddr,bits256_str(str,txid),vout,height,dstr(value)); } } // else printf("cant get ap %s %s\n",coin->symbol,coinaddr); @@ -354,15 +337,10 @@ int32_t LP_merkleproof(struct iguana_info *coin,struct electrum_info *ep,bits256 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; 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; cJSON *txobj; array = cJSON_CreateArray(); if ( coinaddr != 0 && coinaddr[0] != 0 ) { - if ( (ep= coin->electrum) != 0 ) - { - if ( (backupep= ep->prev) == 0 ) - backupep = ep; - } //portable_mutex_lock(&coin->addrmutex); if ( (ap= _LP_addressfind(coin,coinaddr)) != 0 ) {