jl777 7 years ago
parent
commit
cf29e37350
  1. 2
      iguana/exchanges/LP_include.h
  2. 42
      iguana/exchanges/LP_nativeDEX.c
  3. 65
      iguana/exchanges/LP_ordermatch.c
  4. 30
      iguana/exchanges/LP_utxo.c

2
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

42
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);

65
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; j<maxiters; j++)
/*if ( basecoin->electrum != 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; j<maxiters; j++)
{
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;
if ( (bestutxo= LP_ordermatch_iter(utxos,max,ordermatchpricep,bestsatoshisp,bestdestsatoshisp,basecoin,coinaddr,asatoshis,price,txfee,desttxfee,pubp->pubkey,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

30
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 )
{

Loading…
Cancel
Save