Browse Source

Cached tx for spend checks

etomic
jl777 7 years ago
parent
commit
f1eb8884c8
  1. 50
      iguana/exchanges/LP_coins.c
  2. 15
      iguana/exchanges/LP_include.h
  3. 57
      iguana/exchanges/LP_nativeDEX.c
  4. 6
      iguana/exchanges/LP_remember.c
  5. 302
      iguana/exchanges/LP_scan.c
  6. 47
      iguana/exchanges/LP_statemachine.c
  7. 20
      iguana/exchanges/LP_transaction.c
  8. 23
      iguana/exchanges/LP_utxos.c

50
iguana/exchanges/LP_coins.c

@ -173,15 +173,37 @@ cJSON *LP_coinjson(struct iguana_info *coin)
return(item);
}
static struct iguana_info *LP_coins; static int32_t LP_numcoins;
cJSON *LP_coinsjson()
{
int32_t i; cJSON *array = cJSON_CreateArray();
for (i=0; i<LP_numcoins; i++)
jaddi(array,LP_coinjson(&LP_coins[i]));
struct iguana_info *coin,*tmp; cJSON *array = cJSON_CreateArray();
HASH_ITER(hh,LP_coins,coin,tmp)
{
jaddi(array,LP_coinjson(coin));
}
return(array);
}
struct iguana_info *LP_coinsearch(char *symbol)
{
struct iguana_info *coin;
portable_mutex_lock(&LP_coinmutex);
HASH_FIND(hh,LP_coins,symbol,strlen(symbol),coin);
portable_mutex_unlock(&LP_coinmutex);
return(coin);
}
struct iguana_info *LP_coinadd(struct iguana_info *cdata)
{
struct iguana_info *coin = calloc(1,sizeof(*coin));
//printf("%s: (%s) (%s)\n",symbol,cdata.serverport,cdata.userpass);
*coin = *cdata;
portable_mutex_init(&coin->txmutex);
portable_mutex_lock(&LP_coinmutex);
HASH_ADD_KEYPTR(hh,LP_coins,coin->symbol,strlen(coin->symbol),coin);
portable_mutex_unlock(&LP_coinmutex);
return(coin);
}
int32_t LP_coininit(struct iguana_info *coin,char *symbol,char *name,char *assetname,int32_t isPoS,uint16_t port,uint8_t pubtype,uint8_t p2shtype,uint8_t wiftype,uint64_t txfee,double estimatedrate,int32_t longestchain,uint8_t taddr)
{
char *name2;
@ -203,26 +225,6 @@ int32_t LP_coininit(struct iguana_info *coin,char *symbol,char *name,char *asset
return(LP_userpass(coin->userpass,symbol,assetname,name,name2));
}
struct iguana_info *LP_coinadd(struct iguana_info *cdata)
{
struct iguana_info *coin;
//printf("%s: (%s) (%s)\n",symbol,cdata.serverport,cdata.userpass);
LP_coins = realloc(LP_coins,sizeof(*LP_coins) * (LP_numcoins+1));
coin = &LP_coins[LP_numcoins];
*coin = *cdata;
LP_numcoins++;
return(coin);
}
struct iguana_info *LP_coinsearch(char *symbol)
{
int32_t i;
for (i=0; i<LP_numcoins; i++)
if ( strcmp(LP_coins[i].symbol,symbol) == 0 )
return(&LP_coins[i]);
return(0);
}
int32_t LP_isdisabled(char *base,char *rel)
{
struct iguana_info *coin;

15
iguana/exchanges/LP_include.h

@ -29,6 +29,8 @@
#define MAINLOOP_PERSEC 10
#define MAX_PSOCK_PORT 60000
#define MIN_PSOCK_PORT 10000
#define LP_MEMPOOL_TIMEINCR 10
#define LP_GETINFO_INCR 30
#define LP_HTTP_TIMEOUT 2 // 1 is too small due to edge cases of time(NULL)
#define LP_MAXPEER_ERRORS 3
@ -157,10 +159,21 @@ struct basilisk_swapinfo
uint8_t userdata_bobrefund[256],userdata_bobrefundlen;
};
struct LP_outpoint { bits256 spendtxid; uint64_t value,interest; int32_t spendvini,spendheight; };
struct LP_transaction
{
UT_hash_handle hh;
bits256 txid; int32_t height,numvouts,numvins; uint32_t timestamp;
struct LP_outpoint outpoints[];
};
struct iguana_info
{
UT_hash_handle hh;
portable_mutex_t txmutex; struct LP_transaction *transactions;
uint64_t txfee; double estimatedrate,profitmargin;
int32_t longestchain; uint32_t counter,inactive;
int32_t longestchain,firstrefht,firstscanht,lastscanht; uint32_t counter,inactive,lastmempool,lastgetinfo;
uint8_t pubtype,p2shtype,isPoS,wiftype,taddr;
char symbol[16],smartaddr[64],userpass[1024],serverport[128];
};

57
iguana/exchanges/LP_nativeDEX.c

@ -20,13 +20,14 @@
#include <stdio.h>
#include "LP_include.h"
portable_mutex_t LP_peermutex,LP_UTXOmutex,LP_utxomutex,LP_commandmutex,LP_cachemutex,LP_swaplistmutex,LP_forwardmutex,LP_pubkeymutex,LP_networkmutex,LP_psockmutex;
portable_mutex_t LP_peermutex,LP_UTXOmutex,LP_utxomutex,LP_commandmutex,LP_cachemutex,LP_swaplistmutex,LP_forwardmutex,LP_pubkeymutex,LP_networkmutex,LP_psockmutex,LP_coinmutex;
int32_t LP_canbind;
#include "LP_network.c"
struct LP_utxoinfo *LP_utxoinfos[2],*LP_utxoinfos2[2];
struct LP_peerinfo *LP_peerinfos,*LP_mypeer;
struct LP_forwardinfo *LP_forwardinfos;
struct iguana_info *LP_coins;
char *activecoins[] = { "BTC", "KMD" };
char GLOBAL_DBDIR[] = { "DB" };
@ -192,18 +193,18 @@ int32_t LP_subsock_check(void *ctx,char *myipaddr,int32_t pubsock,int32_t sock,d
void LP_utxo_spentcheck(int32_t pubsock,struct LP_utxoinfo *utxo,double profitmargin)
{
struct _LP_utxoinfo u; char str[65],destaddr[64]; uint32_t now = (uint32_t)time(NULL);
struct _LP_utxoinfo u; char str[65]; uint32_t now = (uint32_t)time(NULL);
//printf("%s lag.%d\n",bits256_str(str,utxo->txid),now-utxo->lastspentcheck);
if ( utxo->T.spentflag == 0 && now > utxo->T.lastspentcheck+60 )
{
u = (utxo->iambob != 0) ? utxo->deposit : utxo->fee;
utxo->T.lastspentcheck = now;
if ( LP_txvalue(destaddr,utxo->coin,utxo->payment.txid,utxo->payment.vout) == 0 )
if ( LP_txvalue(0,utxo->coin,utxo->payment.txid,utxo->payment.vout) == 0 )
{
printf("txid.%s %s/v%d %.8f has been spent\n",utxo->coin,bits256_str(str,utxo->payment.txid),utxo->payment.vout,dstr(utxo->payment.value));
LP_spentnotify(utxo,0);
}
else if ( LP_txvalue(destaddr,utxo->coin,u.txid,u.vout) == 0 )
else if ( LP_txvalue(0,utxo->coin,u.txid,u.vout) == 0 )
{
printf("txid2.%s %s/v%d %.8f has been spent\n",utxo->coin,bits256_str(str,u.txid),u.vout,dstr(u.value));
LP_spentnotify(utxo,1);
@ -238,7 +239,7 @@ int32_t LP_peer_utxosquery(struct LP_peerinfo *mypeer,uint16_t myport,int32_t pu
int32_t LP_mainloop_iter(void *ctx,char *myipaddr,struct LP_peerinfo *mypeer,int32_t pubsock,char *pushaddr,uint16_t pushport,int32_t pullsock,uint16_t myport,char *passphrase,double profitmargin)
{
static uint32_t counter,lastforward,numpeers;
struct LP_utxoinfo *utxo,*utmp; char *retstr,*origipaddr; struct LP_peerinfo *peer,*tmp; uint32_t now; int32_t nonz = 0,n=0,lastn=-1;
struct LP_utxoinfo *utxo,*utmp; struct iguana_info *coin,*ctmp; char *retstr,*origipaddr; struct LP_peerinfo *peer,*tmp; uint32_t now; int32_t nonz = 0,n=0,lastn=-1;
now = (uint32_t)time(NULL);
if ( (origipaddr= myipaddr) == 0 )
origipaddr = "127.0.0.1";
@ -332,6 +333,47 @@ int32_t LP_mainloop_iter(void *ctx,char *myipaddr,struct LP_peerinfo *mypeer,int
//LP_deadman_switch = 0;
}
}
HASH_ITER(hh,LP_coins,coin,ctmp) // firstrefht,firstscanht,lastscanht
{
cJSON *obj; int32_t height; bits256 zero;
memset(zero.bytes,0,sizeof(zero));
if ( time(NULL) > coin->lastgetinfo+LP_GETINFO_INCR )
{
if ( (obj= LP_getinfo(coin->symbol)) != 0 )
{
if ( (height= jint(obj,"blocks")) > 0 )
coin->longestchain = height;
free_json(obj);
}
coin->lastgetinfo = (uint32_t)time(NULL);
}
if ( coin->firstrefht == 0 )
continue;
else if ( coin->firstscanht == 0 )
coin->lastscanht = coin->firstscanht = coin->firstrefht;
else if ( coin->firstrefht < coin->firstscanht )
{
printf("detected %s firstrefht.%d < firstscanht.%d\n",coin->symbol,coin->firstrefht,coin->firstscanht);
coin->lastscanht = coin->firstscanht = coin->firstrefht;
}
if ( coin->lastscanht == coin->longestchain )
continue;
else if ( coin->lastscanht > coin->longestchain )
{
printf("detected chain rewind lastscanht.%d vs longestchain.%d, first.%d ref.%d\n",coin->lastscanht,coin->longestchain,coin->firstscanht,coin->firstrefht);
LP_undospends(coin,coin->longestchain-1);
LP_mempoolscan(coin->symbol,zero);
coin->lastscanht = coin->longestchain - 1;
if ( coin->firstscanht < coin->lastscanht )
coin->lastscanht = coin->firstscanht;
continue;
}
printf("%s ref.%d scan.%d to %d, longest.%d\n",coin->symbol,coin->firstrefht,coin->firstscanht,coin->lastscanht,coin->longestchain);
if ( LP_blockinit(coin,coin->lastscanht) < 0 )
continue;
coin->lastscanht++;
break;
}
counter++;
return(nonz);
}
@ -401,7 +443,7 @@ void LP_initpeers(int32_t pubsock,struct LP_peerinfo *mypeer,char *myipaddr,uint
void LPinit(uint16_t myport,uint16_t mypullport,uint16_t mypubport,double profitmargin,char *passphrase,int32_t amclient,char *userhome,cJSON *argjson)
{
char *myipaddr=0; long filesize,n; int32_t timeout,pullsock=-1,pubsock=-1; struct LP_peerinfo *mypeer=0; char pushaddr[128],subaddr[128],bindaddr[128]; void *ctx = bitcoin_ctx();
char *myipaddr=0,*retstr; long filesize,n; int32_t timeout,pullsock=-1,pubsock=-1; struct LP_peerinfo *mypeer=0; char pushaddr[128],subaddr[128],bindaddr[128]; void *ctx = bitcoin_ctx();
IAMLP = !amclient;
#ifndef __linux__
if ( IAMLP != 0 )
@ -443,6 +485,7 @@ void LPinit(uint16_t myport,uint16_t mypullport,uint16_t mypubport,double profit
portable_mutex_init(&LP_networkmutex);
portable_mutex_init(&LP_forwardmutex);
portable_mutex_init(&LP_psockmutex);
portable_mutex_init(&LP_coinmutex);
portable_mutex_init(&LP_pubkeymutex);
if ( profitmargin == 0. || profitmargin == 0.01 )
{
@ -498,6 +541,8 @@ void LPinit(uint16_t myport,uint16_t mypullport,uint16_t mypubport,double profit
printf("error launching stats rpcloop for port.%u\n",myport);
exit(-1);
}
if ( (retstr= basilisk_swapentry(0,0)) != 0 )
free(retstr);
while ( 1 )
{
//fprintf(stderr,".");

6
iguana/exchanges/LP_remember.c

@ -536,7 +536,13 @@ cJSON *basilisk_remember(int64_t *KMDtotals,int64_t *BTCtotals,uint32_t requesti
}
else
{
struct iguana_info *coin; int32_t ht; uint32_t locktime,blocktime;
checktxid = jbits256(sentobj,"txid");
if ( (coin= LP_coinfind(symbol)) != 0 && (ht= LP_txheight(&locktime,&blocktime,coin,txobj)) > 0 && ht > 0 )
{
if ( coin->firstrefht == 0 || ht < coin->firstrefht )
coin->firstrefht = ht;
}
if ( bits256_nonz(checktxid) == 0 )
checktxid = jbits256(sentobj,"hash");
if ( bits256_cmp(checktxid,txid) == 0 )

302
iguana/exchanges/LP_scan.c

@ -18,154 +18,242 @@
// marketmaker
//
/*uint64_t oldLP_txvalue(char *symbol,bits256 txid,int32_t vout)
struct LP_transaction *LP_transactionfind(struct iguana_info *coin,bits256 txid)
{
uint64_t value = 0; double interest; cJSON *txobj,*vouts,*utxoobj; int32_t numvouts;
if ( (txobj= LP_gettx(symbol,txid)) != 0 )
struct LP_transaction *tx;
portable_mutex_lock(&coin->txmutex);
HASH_FIND(hh,coin->transactions,txid.bytes,sizeof(txid),tx);
portable_mutex_unlock(&coin->txmutex);
return(tx);
}
struct LP_transaction *LP_transactionadd(struct iguana_info *coin,bits256 txid,int32_t height,int32_t numvouts,int32_t numvins,uint32_t timestamp)
{
struct LP_transaction *tx; int32_t i;
if ( (tx= LP_transactionfind(coin,txid)) == 0 )
{
//char str[65]; printf("%s.(%s) txobj.(%s)\n",symbol,bits256_str(str,txid),jprint(txobj,0));
if ( (vouts= jarray(&numvouts,txobj,"vout")) != 0 && vout < numvouts )
tx = calloc(1,sizeof(*tx) + (sizeof(*tx->outpoints) * numvouts));
for (i=0; i<numvouts; i++)
tx->outpoints[i].spendvini = -1;
tx->height = height;
tx->numvouts = numvouts;
tx->numvins = numvins;
tx->timestamp = timestamp;
portable_mutex_lock(&coin->txmutex);
char str[65]; printf("%s ht.%d u.%u NEW TXID.(%s) vouts.[%d]\n",coin->symbol,tx->height,tx->timestamp,bits256_str(str,tx->txid),numvouts);
HASH_ADD_KEYPTR(hh,coin->transactions,tx->txid.bytes,sizeof(tx->txid),tx);
portable_mutex_unlock(&coin->txmutex);
} // else printf("warning adding already existing txid %s\n",bits256_str(str,tx->txid));
return(tx);
}
int32_t LP_txheight(uint32_t *timestampp,uint32_t *blocktimep,struct iguana_info *coin,cJSON *txobj)
{
bits256 blockhash; cJSON *blockobj; int32_t height = 0;
*timestampp = juint(txobj,"locktime");
*blocktimep = juint(txobj,"blocktime");
blockhash = jbits256(txobj,"blockhash");
if ( bits256_nonz(blockhash) != 0 && (blockobj= LP_getblock(coin->symbol,blockhash)) != 0 )
{
height = jint(blockobj,"height");
free_json(blockobj);
}
return(height);
}
int32_t LP_undospends(struct iguana_info *coin,int32_t lastheight)
{
int32_t i,ht,num = 0; uint32_t timestamp,blocktime; struct LP_transaction *tx,*tmp; cJSON *txobj;
HASH_ITER(hh,coin->transactions,tx,tmp)
{
for (i=0; i<tx->numvouts; i++)
{
utxoobj = jitem(vouts,vout);
if ( (value= jdouble(utxoobj,"amount")*SATOSHIDEN) == 0 && (value= jdouble(utxoobj,"value")*SATOSHIDEN) == 0 )
{
char str[65]; printf("%s LP_txvalue.%s strange utxo.(%s) vout.%d/%d\n",symbol,bits256_str(str,txid),jprint(utxoobj,0),vout,numvouts);
}
else if ( strcmp(symbol,"KMD") == 0 )
if ( bits256_nonz(tx->outpoints[i].spendtxid) == 0 )
continue;
if ( (ht= tx->outpoints[i].spendheight) == 0 )
{
if ( (utxoobj= LP_gettxout(symbol,txid,vout)) != 0 )
if ( (txobj= LP_gettx(coin->symbol,tx->outpoints[i].spendtxid)) != 0 )
{
if ( (interest= jdouble(utxoobj,"interest")) != 0. )
{
//printf("add interest of %.8f to %.8f\n",interest,dstr(value));
value += SATOSHIDEN * interest;
}
free_json(utxoobj);
tx->outpoints[i].spendheight = LP_txheight(&timestamp,&blocktime,coin,txobj);
free_json(txobj);
}
}
if ( (ht= tx->outpoints[i].spendheight) != 0 && ht > lastheight )
{
char str[65]; printf("clear spend %s/v%d at ht.%d > lastheight.%d\n",bits256_str(str,tx->txid),i,ht,lastheight);
tx->outpoints[i].spendheight = 0;
tx->outpoints[i].spendvini = -1;
memset(tx->outpoints[i].spendtxid.bytes,0,sizeof(bits256));
}
}
free_json(txobj);
}
return(value);
}*/
return(num);
}
uint64_t LP_txvalue(char *coinaddr,char *symbol,bits256 txid,int32_t vout)
uint64_t LP_txinterestvalue(uint64_t *interestp,char *destaddr,struct iguana_info *coin,bits256 txid,int32_t vout)
{
uint64_t value = 0; double interest; cJSON *txobj,*sobj,*array; int32_t n; struct iguana_info *coin;
if ( (coin= LP_coinfind(symbol)) == 0 || coin->inactive != 0 )
return(0);
coinaddr[0] = 0;
if ( (txobj= LP_gettxout(symbol,txid,vout)) != 0 )
uint64_t interest,value = 0; cJSON *txobj,*sobj,*array; int32_t n=0;
*interestp = 0;
destaddr[0] = 0;
if ( (txobj= LP_gettxout(coin->symbol,txid,vout)) != 0 )
{
if ( (value= jdouble(txobj,"amount")*SATOSHIDEN) == 0 && (value= jdouble(txobj,"value")*SATOSHIDEN) == 0 )
{
char str[65]; printf("%s LP_txvalue.%s strange utxo.(%s) vout.%d\n",symbol,bits256_str(str,txid),jprint(txobj,0),vout);
char str[65]; printf("%s LP_txvalue.%s strange utxo.(%s) vout.%d\n",coin->symbol,bits256_str(str,txid),jprint(txobj,0),vout);
}
else if ( strcmp(symbol,"KMD") == 0 )
else if ( strcmp(coin->symbol,"KMD") == 0 )
{
if ( (interest= jdouble(txobj,"interest")) != 0. )
{
//printf("add interest of %.8f to %.8f\n",interest,dstr(value));
value += SATOSHIDEN * interest;
*interestp = SATOSHIDEN * interest;
}
}
if ( (sobj= jobj(txobj,"scriptPubKey")) != 0 && (array= jarray(&n,sobj,"addresses")) != 0 )
strcpy(coinaddr,jstri(array,0));
{
strcpy(destaddr,jstri(array,0));
if ( n > 1 )
printf("LP_txinterestvalue warning: violation of 1 output assumption n.%d\n",n);
} else printf("LP_txinterestvalue no addresses found?\n");
//char str[65]; printf("%.8f <- %s.(%s) txobj.(%s)\n",dstr(value),symbol,bits256_str(str,txid),jprint(txobj,0));
free_json(txobj);
}
return(value);
}
int32_t LP_vinscan(bits256 *spendtxidp,int32_t *spendvinip,char *symbol,bits256 txid,bits256 searchtxid,int32_t searchvout,bits256 searchtxid2,int32_t searchvout2)
int32_t LP_transactioninit(struct iguana_info *coin,bits256 txid)
{
cJSON *txobj,*vins,*vin; bits256 spenttxid; struct iguana_info *coin; int32_t j,numvins,spentvout,retval = -1;
memset(spendtxidp,0,sizeof(*spendtxidp));
*spendvinip = -1;
if ( (coin= LP_coinfind(symbol)) == 0 || coin->inactive != 0 )
return(retval);
if ( (txobj= LP_gettx(symbol,txid)) != 0 )
struct LP_transaction *tx; int32_t i,height,numvouts,numvins,spentvout; uint32_t timestamp,blocktime; cJSON *txobj,*vins,*vouts,*vout,*vin; bits256 spenttxid; char str[65];
if ( (txobj=LP_gettx(coin->symbol,txid)) != 0 )
{
if ( bits256_cmp(txid,jbits256(txobj,"txid")) != 0 )
{
char str[65]; printf("txid mismatch error %s vs %s\n",bits256_str(str,txid),jprint(txobj,0));
free_json(txobj);
return(-2);
}
height = LP_txheight(&timestamp,&blocktime,coin,txobj);
if ( timestamp == 0 && height > 0 )
timestamp = blocktime;
vins = jarray(&numvins,txobj,"vin");
for (j=0; j<numvins; j++)
vouts = jarray(&numvouts,txobj,"vout");
if ( vouts != 0 && (tx= LP_transactionadd(coin,txid,height,numvouts,numvins,timestamp)) != 0 )
{
vin = jitem(vins,j);
spenttxid = jbits256(vin,"txid");
spentvout = jint(vin,"vout");
if ( spentvout == searchvout && bits256_cmp(spenttxid,searchtxid) == 0 )
for (i=0; i<numvouts; i++)
{
*spendtxidp = txid;
*spendvinip = j;
retval = 0;
break;
vout = jitem(vouts,i);
if ( (tx->outpoints[i].value= SATOSHIDEN * jdouble(vout,"value")) == 0 )
tx->outpoints[i].value = SATOSHIDEN * jdouble(vout,"amount");
tx->outpoints[i].interest = SATOSHIDEN * jdouble(vout,"interest");
}
else if ( spentvout == searchvout2 && bits256_cmp(spenttxid,searchtxid2) == 0 )
}
if ( vins != 0 )
{
for (i=0; i<numvins; i++)
{
*spendtxidp = txid;
*spendvinip = j;
retval = 1;
break;
vin = jitem(vins,i);
spenttxid = jbits256(vin,"txid");
spentvout = jint(vin,"vout");
if ( (tx= LP_transactionfind(coin,spenttxid)) != 0 )
{
if ( spentvout < tx->numvouts )
{
tx->outpoints[spentvout].spendtxid = txid;
tx->outpoints[spentvout].spendvini = i;
tx->outpoints[spentvout].spendheight = height;
} else printf("LP_transactioninint: %s spentvout.%d < numvouts.%d\n",bits256_str(str,spenttxid),spentvout,tx->numvouts);
}
}
}
free_json(txobj);
} else printf("unexpected missing txid\n"), retval = -3;
return(retval);
return(0);
} else printf("LP_transactioninit error for %s\n",bits256_str(str,txid));
return(-1);
}
int32_t LP_spendsearch(bits256 *spendtxidp,int32_t *indp,char *symbol,bits256 searchtxid,int32_t searchvout)
int32_t LP_blockinit(struct iguana_info *coin,int32_t height)
{
char destaddr[64]; struct iguana_info *coin; cJSON *blockjson,*txids,*txobj; bits256 hash,txid; int32_t h,i,j,numtxids,loadheight,errs = 0;
*indp = -1;
if ( (coin= LP_coinfind(symbol)) == 0 || coin->inactive != 0 )
return(0);
memset(spendtxidp,0,sizeof(*spendtxidp));
if ( LP_txvalue(destaddr,symbol,searchtxid,searchvout) > 0 )
return(0);
if ( (txobj= LP_gettx(symbol,searchtxid)) == 0 )
return(0);
hash = jbits256(txobj,"blockhash");
free_json(txobj);
if ( bits256_nonz(hash) == 0 )
int32_t i,numtx,checkht=-1; cJSON *blockobj,*txs; bits256 txid; struct LP_transaction *tx;
if ( (blockobj= LP_blockjson(&checkht,coin->symbol,0,height)) != 0 )
{
if ( (txs= jarray(&numtx,blockobj,"tx")) != 0 )
{
for (i=0; i<numtx; i++)
{
txid = jbits256i(txs,i);
if ( (tx= LP_transactionfind(coin,txid)) != 0 )
{
if ( tx->height == 0 )
tx->height = height;
else if ( tx->height != height )
{
printf("LP_blockinit: tx->height %d != %d\n",tx->height,height);
tx->height = height;
}
} else LP_transactioninit(coin,txid);
}
}
free_json(blockobj);
}
if ( checkht == height )
return(0);
if ( (blockjson= LP_getblock(symbol,hash)) == 0 )
else return(-1);
}
int64_t basilisk_txvalue(char *symbol,bits256 txid,int32_t vout)
{
char destaddr[64]; uint64_t value,interest = 0; struct iguana_info *coin;
if ( (coin= LP_coinfind(symbol)) == 0 || coin->inactive != 0 )
return(0);
loadheight = jint(blockjson,"height");
free_json(blockjson);
if ( loadheight <= 0 )
//char str[65]; printf("%s txvalue.(%s)\n",symbol,bits256_str(str,txid));
value = LP_txinterestvalue(&interest,destaddr,coin,txid,vout);
return(value + interest);
}
uint64_t LP_txvalue(char *coinaddr,char *symbol,bits256 txid,int32_t vout)
{
struct LP_transaction *tx; uint64_t interest = 0,value = 0; struct iguana_info *coin;
if ( (coin= LP_coinfind(symbol)) == 0 || coin->inactive != 0 )
return(0);
while ( errs == 0 && *indp < 0 )
if ( coinaddr != 0 )
coinaddr[0] = 0;
if ( (tx= LP_transactionfind(coin,txid)) != 0 )
{
//printf("search %s ht.%d\n",symbol,loadheight);
if ( (blockjson= LP_blockjson(&h,symbol,0,loadheight)) != 0 && h == loadheight )
if ( vout < tx->numvouts )
{
if ( (txids= jarray(&numtxids,blockjson,"tx")) != 0 )
if ( bits256_nonz(tx->outpoints[vout].spendtxid) != 0 )
return(0);
else
{
for (i=0; i<numtxids; i++)
if ( coinaddr != 0 && strcmp(symbol,"KMD") == 0 )
{
txid = jbits256(jitem(txids,i),0);
if ( (j= LP_vinscan(spendtxidp,indp,symbol,txid,searchtxid,searchvout,searchtxid,searchvout)) >= 0 )
break;
value = LP_txinterestvalue(&tx->outpoints[vout].interest,coinaddr,coin,txid,vout);
}
return(tx->outpoints[vout].value + tx->outpoints[vout].interest);
}
free_json(blockjson);
} else errs++;
loadheight++;
}
}
char str[65]; printf("reached %s ht.%d %s/v%d\n",symbol,loadheight,bits256_str(str,*spendtxidp),*indp);
if ( bits256_nonz(*spendtxidp) != 0 && *indp >= 0 )
return(loadheight);
else return(0);
if ( coinaddr != 0 )
value = LP_txinterestvalue(&interest,coinaddr,coin,txid,vout);
return(value + interest);
}
int32_t LP_mempoolscan(char *symbol,bits256 txid)
int32_t LP_spendsearch(bits256 *spendtxidp,int32_t *indp,char *symbol,bits256 searchtxid,int32_t searchvout)
{
int32_t i,n; cJSON *array; struct iguana_info *coin;
struct LP_transaction *tx; struct iguana_info *coin;
*indp = -1;
if ( (coin= LP_coinfind(symbol)) == 0 || coin->inactive != 0 )
return(-1);
memset(spendtxidp,0,sizeof(*spendtxidp));
if ( (tx= LP_transactionfind(coin,searchtxid)) != 0 )
{
if ( searchvout < tx->numvouts && tx->outpoints[searchvout].spendvini >= 0 )
{
*spendtxidp = tx->outpoints[searchvout].spendtxid;
*indp = tx->outpoints[searchvout].spendvini;
return(tx->outpoints[searchvout].spendheight);
}
}
return(-1);
}
int32_t LP_mempoolscan(char *symbol,bits256 searchtxid)
{
int32_t i,n; cJSON *array; bits256 txid; struct iguana_info *coin; struct LP_transaction *tx;
if ( (coin= LP_coinfind(symbol)) == 0 || coin->inactive != 0 )
return(-1);
if ( (array= LP_getmempool(symbol)) != 0 )
@ -173,11 +261,16 @@ int32_t LP_mempoolscan(char *symbol,bits256 txid)
if ( is_cJSON_Array(array) != 0 && (n= cJSON_GetArraySize(array)) > 0 )
{
for (i=0; i<n; i++)
if ( bits256_cmp(txid,jbits256i(array,i)) == 0 )
{
txid = jbits256i(array,i);
if ( (tx= LP_transactionfind(coin,txid)) == 0 )
LP_transactioninit(coin,txid);
if ( bits256_cmp(txid,searchtxid) == 0 )
{
char str[65]; printf("found %s tx.(%s) in mempool slot.%d\n",symbol,bits256_str(str,txid),i);
return(i);
}
}
}
free_json(array);
}
@ -210,31 +303,30 @@ int32_t LP_waitmempool(char *symbol,bits256 txid,int32_t duration)
{
if ( LP_mempoolscan(symbol,txid) >= 0 )
return(0);
usleep(250000);
usleep(500000);
}
return(-1);
}
int32_t LP_mempool_vinscan(bits256 *spendtxidp,int32_t *spendvinp,char *symbol,bits256 searchtxid,int32_t searchvout,bits256 searchtxid2,int32_t searchvout2)
{
int32_t i,n; cJSON *array; bits256 mempooltxid; struct iguana_info *coin;
struct iguana_info *coin; int32_t selector; cJSON *array;
if ( symbol == 0 || symbol[0] == 0 || bits256_nonz(searchtxid) == 0 || bits256_nonz(searchtxid2) == 0 )
return(-1);
if ( (coin= LP_coinfind(symbol)) == 0 || coin->inactive != 0 )
return(-1);
if ( (array= LP_getmempool(symbol)) != 0 )
if ( time(NULL) > coin->lastmempool+LP_MEMPOOL_TIMEINCR )
{
if ( is_cJSON_Array(array) != 0 && (n= cJSON_GetArraySize(array)) > 0 )
if ( (array= LP_getmempool(symbol)) != 0 )
{
for (i=0; i<n; i++)
{
mempooltxid = jbits256i(array,i);
if ( (*spendvinp= LP_vinscan(spendtxidp,spendvinp,symbol,mempooltxid,searchtxid,searchvout,searchtxid2,searchvout2)) >= 0 )
return(i);
}
free_json(array);
coin->lastmempool = (uint32_t)time(NULL);
}
}
if ( (selector= LP_spendsearch(spendtxidp,spendvinp,symbol,searchtxid,searchvout)) >= 0 )
return(selector);
else if ( (selector= LP_spendsearch(spendtxidp,spendvinp,symbol,searchtxid2,searchvout2)) >= 0 )
return(selector);
return(-1);
}

47
iguana/exchanges/LP_statemachine.c

@ -1432,4 +1432,51 @@ if ( (array= LP_tradecandidates(base)) != 0 )
LP_priceping(pubsock,utxo,"BTC",profitmargin);
else LP_priceping(pubsock,utxo,"KMD",profitmargin);
}*/
/*if ( LP_txvalue(destaddr,symbol,searchtxid,searchvout) > 0 )
return(0);
if ( (txobj= LP_gettx(symbol,searchtxid)) == 0 )
return(0);
hash = jbits256(txobj,"blockhash");
free_json(txobj);
if ( bits256_nonz(hash) == 0 )
return(0);
if ( (blockjson= LP_getblock(symbol,hash)) == 0 )
return(0);
loadheight = jint(blockjson,"height");
free_json(blockjson);
if ( loadheight <= 0 )
return(0);
while ( errs == 0 && *indp < 0 )
{
//printf("search %s ht.%d\n",symbol,loadheight);
if ( (blockjson= LP_blockjson(&h,symbol,0,loadheight)) != 0 && h == loadheight )
{
if ( (txids= jarray(&numtxids,blockjson,"tx")) != 0 )
{
for (i=0; i<numtxids; i++)
{
txid = jbits256(jitem(txids,i),0);
if ( (j= LP_vinscan(spendtxidp,indp,symbol,txid,searchtxid,searchvout,searchtxid,searchvout)) >= 0 )
break;
}
}
free_json(blockjson);
} else errs++;
loadheight++;
}
char str[65]; printf("reached %s ht.%d %s/v%d\n",symbol,loadheight,bits256_str(str,*spendtxidp),*indp);
if ( bits256_nonz(*spendtxidp) != 0 && *indp >= 0 )
return(loadheight);
else return(0);*/
/*if ( is_cJSON_Array(array) != 0 && (n= cJSON_GetArraySize(array)) > 0 )
{
for (i=0; i<n; i++)
{
mempooltxid = jbits256i(array,i);
if ( (selector= LP_vinscan(spendtxidp,spendvinp,symbol,mempooltxid,searchtxid,searchvout,searchtxid2,searchvout2)) >= 0 )
return(selector);
}
}*/

20
iguana/exchanges/LP_transaction.c

@ -13,12 +13,12 @@
* Removal or modification of this copyright notice is prohibited. *
* *
******************************************************************************/
//
// LP_transaction.c
// marketmaker
//
bits256 LP_broadcast(char *txname,char *symbol,char *txbytes,bits256 expectedtxid)
{
char *retstr; bits256 txid; cJSON *retjson,*errorobj; int32_t i,sentflag = 0;
@ -816,24 +816,6 @@ int32_t basilisk_swap_getsigscript(char *symbol,uint8_t *script,int32_t maxlen,b
return(scriptlen);
}
int64_t basilisk_txvalue(char *symbol,bits256 txid,int32_t vout)
{
cJSON *txobj,*vouts,*item; int32_t n; int64_t value = 0;
//char str[65]; printf("%s txvalue.(%s)\n",symbol,bits256_str(str,txid));
if ( (txobj= LP_gettx(symbol,txid)) != 0 )
{
//printf("txobj.(%s)\n",jprint(txobj,0));
if ( (vouts= jarray(&n,txobj,"vout")) != 0 )
{
item = jitem(vouts,vout);
if ( (value= jdouble(item,"amount") * SATOSHIDEN) == 0 )
value = jdouble(item,"value") * SATOSHIDEN;
}
free_json(txobj);
}
return(value);
}
bits256 _LP_swap_spendtxid(char *symbol,char *destaddr,char *coinaddr,bits256 utxotxid,int32_t vout)
{
char *retstr,*addr; cJSON *array,*item,*array2; int32_t i,n,m; bits256 spendtxid,txid;

23
iguana/exchanges/LP_utxos.c

@ -379,7 +379,7 @@ void LP_spentnotify(struct LP_utxoinfo *utxo,int32_t selector)
char *LP_spentcheck(cJSON *argjson)
{
char destaddr[64]; bits256 txid,checktxid; int32_t vout,checkvout; struct LP_utxoinfo *utxo; int32_t iambob,retval = 0;
bits256 txid,checktxid; int32_t vout,checkvout; struct LP_utxoinfo *utxo; int32_t iambob,retval = 0;
txid = jbits256(argjson,"txid");
vout = jint(argjson,"vout");
for (iambob=0; iambob<=1; iambob++)
@ -393,7 +393,7 @@ char *LP_spentcheck(cJSON *argjson)
checktxid = jbits256(argjson,"checktxid");
checkvout = jint(argjson,"checkvout");
}
if ( LP_txvalue(destaddr,utxo->coin,checktxid,checkvout) == 0 )
if ( LP_txvalue(0,utxo->coin,checktxid,checkvout) == 0 )
{
if ( LP_mypeer != 0 && LP_mypeer->numutxos > 0 )
LP_mypeer->numutxos--;
@ -438,7 +438,7 @@ struct LP_utxoinfo *LP_utxoadd(int32_t iambob,int32_t mypubsock,char *symbol,bit
if ( dispflag != 0 )
printf("%.8f %.8f %s iambob.%d %s utxoadd.(%.8f %.8f) %s %s\n",dstr(val),dstr(val2),coinaddr,iambob,symbol,dstr(value),dstr(value2),bits256_str(str,txid),bits256_str(str2,txid2));
dispflag = 1;
if ( 0 && (selector= LP_mempool_vinscan(&spendtxid,&spendvini,symbol,txid,vout,txid2,vout2)) >= 0 )
if ( (selector= LP_mempool_vinscan(&spendtxid,&spendvini,symbol,txid,vout,txid2,vout2)) >= 0 )
{
printf("utxoadd selector.%d in mempool %s vini.%d",selector,bits256_str(str,spendtxid),spendvini);
return(0);
@ -457,7 +457,7 @@ struct LP_utxoinfo *LP_utxoadd(int32_t iambob,int32_t mypubsock,char *symbol,bit
char str[65],str2[65],str3[65],str4[65],str5[65],str6[65];
if ( dispflag != 0 )
printf("error on subsequent utxo iambob.%d %.8f %.8f add.(%s %s) when.(%s %s) %d %d %d %d %d %d %d %d %d %d %d pubkeys.(%s vs %s)\n",iambob,dstr(val),dstr(val2),bits256_str(str,txid),bits256_str(str2,txid2),bits256_str(str3,utxo->payment.txid),bits256_str(str4,utxo->deposit.txid),bits256_cmp(txid,utxo->payment.txid) != 0,bits256_cmp(txid2,u.txid) != 0,vout != utxo->payment.vout,tmpsatoshis != utxo->S.satoshis,vout2 != u.vout,value2 != u.value,strcmp(symbol,utxo->coin) != 0,strcmp(spendscript,utxo->spendscript) != 0,strcmp(coinaddr,utxo->coinaddr) != 0,bits256_cmp(pubkey,utxo->pubkey) != 0,value != utxo->payment.value,bits256_str(str5,pubkey),bits256_str(str6,utxo->pubkey));
if ( utxo->T.spentflag != 0 || LP_txvalue(utxo->coinaddr,utxo->coin,utxo->payment.txid,utxo->payment.vout) < utxo->payment.value || LP_txvalue(utxo->coinaddr,utxo->coin,u.txid,u.vout) < u.value )
if ( utxo->T.spentflag != 0 || LP_txvalue(0,utxo->coin,utxo->payment.txid,utxo->payment.vout) < utxo->payment.value || LP_txvalue(0,utxo->coin,u.txid,u.vout) < u.value )
{
if ( utxo->T.spentflag == 0 )
utxo->T.spentflag = (uint32_t)time(NULL);
@ -777,19 +777,16 @@ bits256 LP_privkeycalc(void *ctx,uint8_t *pubkey33,bits256 *pubkeyp,struct iguan
void LP_privkey_updates(void *ctx,int32_t pubsock,char *passphrase,int32_t initonly)
{
int32_t i; struct iguana_info *coin; bits256 pubkey,privkey; uint8_t pubkey33[33];
struct iguana_info *coin,*tmp; bits256 pubkey,privkey; uint8_t pubkey33[33];
memset(privkey.bytes,0,sizeof(privkey));
pubkey = privkey;
for (i=0; i<LP_numcoins; i++)
HASH_ITER(hh,LP_coins,coin,tmp)
{
//printf("i.%d of %d\n",i,LP_numcoins);
if ( (coin= LP_coinfind(LP_coins[i].symbol)) != 0 )
{
if ( bits256_nonz(privkey) == 0 || coin->smartaddr[0] == 0 )
privkey = LP_privkeycalc(ctx,pubkey33,&pubkey,coin,passphrase,"");
if ( coin->inactive == 0 && initonly == 0 )
LP_privkey_init(pubsock,coin,privkey,pubkey,pubkey33);
}
if ( bits256_nonz(privkey) == 0 || coin->smartaddr[0] == 0 )
privkey = LP_privkeycalc(ctx,pubkey33,&pubkey,coin,passphrase,"");
if ( coin->inactive == 0 && initonly == 0 )
LP_privkey_init(pubsock,coin,privkey,pubkey,pubkey33);
}
}

Loading…
Cancel
Save