Browse Source

Merge pull request #364 from jl777/spvdex

Spvdex
etomic
jl777 7 years ago
committed by GitHub
parent
commit
690051a8bd
  1. 1
      iguana/exchanges/LP_coins.c
  2. 13
      iguana/exchanges/LP_include.h
  3. 4
      iguana/exchanges/LP_ordermatch.c
  4. 4
      iguana/exchanges/LP_remember.c
  5. 345
      iguana/exchanges/LP_rpc.c
  6. 123
      iguana/exchanges/LP_scan.c
  7. 92
      iguana/exchanges/LP_socket.c
  8. 22
      iguana/exchanges/LP_swap.c
  9. 106
      iguana/exchanges/LP_transaction.c
  10. 55
      iguana/exchanges/LP_utxos.c

1
iguana/exchanges/LP_coins.c

@ -265,6 +265,7 @@ int32_t LP_coininit(struct iguana_info *coin,char *symbol,char *name,char *asset
coin->wiftype = wiftype;
coin->inactive = (uint32_t)time(NULL);
coin->bussock = LP_coinbus(busport);
coin->ctx = bitcoin_ctx();
if ( strcmp(symbol,"KMD") == 0 || (assetname != 0 && assetname[0] != 0) )
name2 = 0;
else name2 = name;

13
iguana/exchanges/LP_include.h

@ -172,7 +172,7 @@ struct LP_outpoint { bits256 spendtxid; uint64_t value,interest; int32_t spendvi
struct LP_transaction
{
UT_hash_handle hh;
bits256 txid; int32_t height,numvouts,numvins; uint32_t timestamp;
bits256 txid; int32_t height,numvouts,numvins; //uint32_t timestamp;
struct LP_outpoint outpoints[];
};
@ -182,12 +182,12 @@ struct iguana_info
portable_mutex_t txmutex; struct LP_transaction *transactions; struct LP_address *addresses;
uint64_t txfee;
int32_t longestchain,firstrefht,firstscanht,lastscanht,bussock,height; uint16_t busport;
uint32_t counter,inactive,lastmempool,lastgetinfo,ratetime,heighttime,lastmonitor;
uint32_t counter,inactive,lastmempool,lastgetinfo,ratetime,heighttime,lastmonitor,unspenttime;
uint8_t pubtype,p2shtype,isPoS,wiftype,wiftaddr,taddr,noimportprivkey_flag;
char symbol[16],smartaddr[64],userpass[1024],serverport[128];
char symbol[16],smartaddr[64],userpass[1024],serverport[128],lastunspent[64];
// portfolio
double price_kmd,force,perc,goal,goalperc,relvolume,rate;
void *electrum;
void *electrum; void *ctx;
uint64_t maxamount,kmd_equiv,balanceA,balanceB,valuesumA,valuesumB;
uint8_t pubkey33[33];
};
@ -297,6 +297,11 @@ int32_t LP_crc32find(int32_t *duplicatep,int32_t ind,uint32_t crc32);
char *LP_pricepings(void *ctx,char *myipaddr,int32_t pubsock,char *base,char *rel,double price);
uint64_t LP_txfeecalc(struct iguana_info *coin,uint64_t txfee);
struct LP_address *_LP_address(struct iguana_info *coin,char *coinaddr);
int32_t iguana_signrawtransaction(void *ctx,char *symbol,uint8_t wiftaddr,uint8_t taddr,uint8_t pubtype,uint8_t p2shtype,uint8_t isPoS,int32_t height,struct iguana_msgtx *msgtx,char **signedtxp,bits256 *signedtxidp,struct vin_info *V,int32_t numinputs,char *rawtx,cJSON *vins,cJSON *privkeysjson);
int32_t LP_waitmempool(char *symbol,char *coinaddr,bits256 txid,int32_t duration);
struct LP_transaction *LP_transactionfind(struct iguana_info *coin,bits256 txid);
int32_t LP_transactioninit(struct iguana_info *coin,bits256 txid,int32_t iter);
int32_t LP_mempoolscan(char *symbol,bits256 searchtxid);
#endif

4
iguana/exchanges/LP_ordermatch.c

@ -244,12 +244,12 @@ char *LP_postedprice(cJSON *argjson)
int32_t LP_quote_checkmempool(struct LP_quoteinfo *qp)
{
int32_t selector,spendvini; bits256 spendtxid;
if ( (selector= LP_mempool_vinscan(&spendtxid,&spendvini,qp->srccoin,qp->txid,qp->vout,qp->txid2,qp->vout2)) >= 0 )
if ( (selector= LP_mempool_vinscan(&spendtxid,&spendvini,qp->srccoin,qp->coinaddr,qp->txid,qp->vout,qp->txid2,qp->vout2)) >= 0 )
{
char str[65]; printf("LP_tradecommand selector.%d in mempool %s vini.%d",selector,bits256_str(str,spendtxid),spendvini);
return(-1);
}
if ( (selector= LP_mempool_vinscan(&spendtxid,&spendvini,qp->destcoin,qp->desttxid,qp->destvout,qp->feetxid,qp->feevout)) >= 0 )
if ( (selector= LP_mempool_vinscan(&spendtxid,&spendvini,qp->destcoin,qp->destaddr,qp->desttxid,qp->destvout,qp->feetxid,qp->feevout)) >= 0 )
{
char str[65]; printf("LP_tradecommand dest selector.%d in mempool %s vini.%d",selector,bits256_str(str,spendtxid),spendvini);
return(-1);

4
iguana/exchanges/LP_remember.c

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

345
iguana/exchanges/LP_rpc.c

@ -212,12 +212,14 @@ int32_t LP_getheight(struct iguana_info *coin)
return(height);
}
cJSON *LP_getmempool(char *symbol)
cJSON *LP_getmempool(char *symbol,char *coinaddr)
{
struct iguana_info *coin = LP_coinfind(symbol);
if ( coin == 0 )
return(cJSON_Parse("{\"error\":\"no coin\"}"));
return(bitcoin_json(coin,"getrawmempool","[]"));
cJSON *array; struct iguana_info *coin = LP_coinfind(symbol);
if ( coin == 0 || (coin->electrum != 0 && coinaddr == 0) )
return(cJSON_Parse("{\"error\":\"no native coin\"}"));
if ( coin->electrum == 0 )
return(bitcoin_json(coin,"getrawmempool","[]"));
else return(electrum_address_getmempool(symbol,coin->electrum,&array,coinaddr));
}
cJSON *LP_paxprice(char *fiat)
@ -324,7 +326,7 @@ cJSON *LP_gettxout(char *symbol,bits256 txid,int32_t vout)
"coinbase": false
}*/
if ( value != j64bits(item,"value") )
printf("value %llu != %llu\n",(long long)value,(long long)j64bits(item,"value"));
printf("LP_gettxout: value %llu != %llu\n",(long long)value,(long long)j64bits(item,"value"));
jaddnum(retjson,"value",dstr(value));
jaddbits256(retjson,"txid",t);
jaddnum(retjson,"vout",v);
@ -334,7 +336,7 @@ cJSON *LP_gettxout(char *symbol,bits256 txid,int32_t vout)
jaddnum(sobj,"reqSigs",1);
jaddstr(sobj,"type","pubkey");
jadd(sobj,"addresses",addresses);
jadd(retjson,"scriptPubkey",sobj);
jadd(retjson,"scriptPubKey",sobj);
printf("GETTXOUT.(%s)\n",jprint(retjson,0));
break;
}
@ -349,67 +351,20 @@ cJSON *LP_gettxout(char *symbol,bits256 txid,int32_t vout)
}
}
cJSON *LP_getblock(char *symbol,bits256 txid)
{
char buf[128],str[65]; struct iguana_info *coin = LP_coinfind(symbol);
if ( coin == 0 )
return(cJSON_Parse("{\"error\":\"no coin\"}"));
sprintf(buf,"[\"%s\"]",bits256_str(str,txid));
return(bitcoin_json(coin,"getblock",buf));
}
int32_t LP_txheight(uint32_t *timestampp,uint32_t *blocktimep,struct iguana_info *coin,bits256 txid)
{
bits256 blockhash; cJSON *blockobj,*txobj; int32_t height = 0;
if ( coin == 0 )
return(-1);
if ( (txobj= LP_gettx(coin->symbol,txid)) != 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");
//printf("%s LP_txheight.%d\n",coin->symbol,height);
free_json(blockobj);
} //else printf("%s LP_txheight error (%s)\n",coin->symbol,jprint(txobj,0));
free_json(txobj);
}
return(height);
}
cJSON *LP_getblockhashstr(char *symbol,char *blockhashstr)
{
char buf[128]; struct iguana_info *coin = LP_coinfind(symbol);
if ( coin == 0 )
return(cJSON_Parse("{\"error\":\"no coin\"}"));
sprintf(buf,"[\"%s\"]",blockhashstr);
return(bitcoin_json(coin,"getblock",buf));
}
cJSON *LP_listunspent(char *symbol,char *coinaddr)
{
char buf[128]; cJSON *retjson; struct iguana_info *coin = LP_coinfind(symbol);
if ( coin == 0 )
//printf("LP_listunspent.(%s %s)\n",symbol,coinaddr);
if ( coin == 0 || coin->inactive != 0 )
return(cJSON_Parse("{\"error\":\"no coin\"}"));
if ( coin->electrum == 0 )
{
sprintf(buf,"[0, 99999999, [\"%s\"]]",coinaddr);
return(bitcoin_json(coin,"listunspent",buf));
}
else
{
sprintf(buf,"[\"%s\"]",coinaddr);
if ( (retjson= bitcoin_json(coin,"blockchain.address.listunspent",buf)) != 0 )
{
//printf("LISTUNSPENT.(%s)\n",jprint(retjson,0));
}
return(retjson);
}
} else return(electrum_address_listunspent(symbol,coin->electrum,&retjson,coinaddr));
}
cJSON *LP_listtransactions(char *symbol,char *coinaddr,int32_t count,int32_t skip)
/*cJSON *LP_listtransactions(char *symbol,char *coinaddr,int32_t count,int32_t skip)
{
char buf[128]; struct iguana_info *coin = LP_coinfind(symbol);
if ( coin == 0 )
@ -418,7 +373,7 @@ cJSON *LP_listtransactions(char *symbol,char *coinaddr,int32_t count,int32_t ski
count = 100;
sprintf(buf,"[\"%s\", %d, %d, true]",coinaddr,count,skip);
return(bitcoin_json(coin,"listtransactions",buf));
}
}*/
cJSON *LP_validateaddress(char *symbol,char *address)
{
@ -493,33 +448,36 @@ int32_t LP_importaddress(char *symbol,char *address)
return(-2);
if ( coin->electrum != 0 )
{
if ( (retjson= electrum_address_subscribe(symbol,0,&retjson,address)) != 0 )
if ( (retjson= electrum_address_subscribe(symbol,coin->electrum,&retjson,address)) != 0 )
{
printf("importaddress.(%s) -> %s\n",address,jprint(retjson,0));
free_json(retjson);
}
return(0);
}
if ( (validatejson= LP_validateaddress(symbol,address)) != 0 )
else
{
if ( (isvalid= is_cJSON_True(jobj(validatejson,"isvalid")) != 0) != 0 )
if ( (validatejson= LP_validateaddress(symbol,address)) != 0 )
{
if ( is_cJSON_True(jobj(validatejson,"iswatchonly")) != 0 || is_cJSON_True(jobj(validatejson,"ismine")) != 0 )
doneflag = 1;
if ( (isvalid= is_cJSON_True(jobj(validatejson,"isvalid")) != 0) != 0 )
{
if ( is_cJSON_True(jobj(validatejson,"iswatchonly")) != 0 || is_cJSON_True(jobj(validatejson,"ismine")) != 0 )
doneflag = 1;
}
free_json(validatejson);
}
free_json(validatejson);
if ( isvalid == 0 )
return(-1);
if ( doneflag != 0 )
return(0); // success
sprintf(buf,"[\"%s\", \"%s\", false]",address,address);
if ( (retstr= bitcoind_passthru(symbol,coin->serverport,coin->userpass,"importaddress",buf)) != 0 )
{
//printf("importaddress.(%s %s) -> (%s)\n",symbol,address,retstr);
free(retstr);
} //else printf("importaddress.(%s %s)\n",symbol,address);
return(1);
}
if ( isvalid == 0 )
return(-1);
if ( doneflag != 0 )
return(0); // success
sprintf(buf,"[\"%s\", \"%s\", false]",address,address);
if ( (retstr= bitcoind_passthru(symbol,coin->serverport,coin->userpass,"importaddress",buf)) != 0 )
{
//printf("importaddress.(%s %s) -> (%s)\n",symbol,address,retstr);
free(retstr);
} //else printf("importaddress.(%s %s)\n",symbol,address);
return(1);
}
double LP_getestimatedrate(struct iguana_info *coin)
@ -550,71 +508,43 @@ double LP_getestimatedrate(struct iguana_info *coin)
return(SATOSHIDEN * rate);
}
uint64_t LP_txfee(char *symbol)
{
uint64_t txfee = 0;
if ( strcmp(symbol,"BTC") != 0 )
txfee = LP_MIN_TXFEE;
return(txfee);
}
char *LP_blockhashstr(char *symbol,int32_t height)
char *LP_sendrawtransaction(char *symbol,char *signedtx)
{
cJSON *array; char *paramstr,*retstr; struct iguana_info *coin = LP_coinfind(symbol);
cJSON *array; char *paramstr,*tmpstr,*retstr=0; int32_t n; cJSON *retjson; struct iguana_info *coin;
coin = LP_coinfind(symbol);
if ( coin == 0 )
return(0);
array = cJSON_CreateArray();
jaddinum(array,height);
paramstr = jprint(array,1);
retstr = bitcoind_passthru(symbol,coin->serverport,coin->userpass,"getblockhash",paramstr);
free(paramstr);
return(retstr);
}
cJSON *LP_blockjson(int32_t *heightp,char *symbol,char *blockhashstr,int32_t height)
{
cJSON *json = 0; int32_t flag = 0;
if ( blockhashstr == 0 )
blockhashstr = LP_blockhashstr(symbol,height), flag = 1;
if ( blockhashstr != 0 )
if ( coin->electrum == 0 )
{
if ( (json= LP_getblockhashstr(symbol,blockhashstr)) != 0 )
array = cJSON_CreateArray();
jaddistr(array,signedtx);
paramstr = jprint(array,1);
retstr = bitcoind_passthru(symbol,coin->serverport,coin->userpass,"sendrawtransaction",paramstr);
//printf(">>>>>>>>>>> %s dpow_sendrawtransaction.(%s) -> (%s)\n",coin->symbol,paramstr,retstr);
free(paramstr);
}
else
{
if ( (retjson= electrum_sendrawtransaction(symbol,coin->electrum,&retjson,signedtx)) != 0 )
{
if ( *heightp != 0 )
retstr = jprint(retjson,1);
printf("electrum sendrawtx.(%s) -> %s\n",signedtx,retstr);
n = (int32_t)strlen(retstr);
if ( retstr[0] == '"' && retstr[n-1] == '"' )
{
*heightp = juint(json,"height");
if ( height >= 0 && *heightp != height )
{
printf("unexpected height %d vs %d for %s (%s)\n",*heightp,height,blockhashstr,jprint(json,0));
*heightp = -1;
free_json(json);
json = 0;
}
retstr[n-1] = 0;
tmpstr = clonestr(retstr+1);
free(retstr);
retstr = tmpstr;
}
}
if ( flag != 0 && blockhashstr != 0 )
free(blockhashstr);
}
return(json);
}
char *LP_sendrawtransaction(char *symbol,char *signedtx)
{
cJSON *array; char *paramstr,*retstr; struct iguana_info *coin = LP_coinfind(symbol);
if ( coin == 0 )
return(0);
array = cJSON_CreateArray();
jaddistr(array,signedtx);
paramstr = jprint(array,1);
retstr = bitcoind_passthru(symbol,coin->serverport,coin->userpass,"sendrawtransaction",paramstr);
//printf(">>>>>>>>>>> %s dpow_sendrawtransaction.(%s) -> (%s)\n",coin->symbol,paramstr,retstr);
free(paramstr);
return(retstr);
}
char *LP_signrawtx(char *symbol,bits256 *signedtxidp,int32_t *completedp,cJSON *vins,char *rawtx,cJSON *privkeys,struct vin_info *V)
{
cJSON *array,*json; int32_t len; uint8_t *data; char *paramstr,*retstr,*hexstr,*signedtx=0; struct iguana_info *coin = LP_coinfind(symbol);
cJSON *array,*json,*retjson; int32_t len; uint8_t *data; char str[65],*paramstr,*retstr,*hexstr,*signedtx=0; struct iguana_msgtx msgtx; struct iguana_info *coin = LP_coinfind(symbol);
memset(signedtxidp,0,sizeof(*signedtxidp));
*completedp = 0;
if ( coin == 0 )
@ -622,6 +552,32 @@ char *LP_signrawtx(char *symbol,bits256 *signedtxidp,int32_t *completedp,cJSON *
printf("LP_signrawtx cant find coin.(%s)\n",symbol);
return(0);
}
//int32_t iguana_signrawtransaction(void *ctx,char *symbol,uint8_t wiftaddr,uint8_t taddr,uint8_t pubtype,uint8_t p2shtype,uint8_t isPoS,int32_t height,struct iguana_msgtx *msgtx,char **signedtxp,bits256 *signedtxidp,struct vin_info *V,int32_t numinputs,char *rawtx,cJSON *vins,cJSON *privkeysjson)
memset(&msgtx,0,sizeof(msgtx));
signedtx = 0;
memset(signedtxidp,0,sizeof(*signedtxidp));
//printf("locktime.%u sequenceid.%x rawtx.(%s) vins.(%s)\n",locktime,sequenceid,rawtxbytes,jprint(vins,0));
if ( (*completedp= iguana_signrawtransaction(coin->ctx,symbol,coin->wiftaddr,coin->taddr,coin->pubtype,coin->p2shtype,coin->isPoS,1000000,&msgtx,&signedtx,signedtxidp,V,16,rawtx,vins,privkeys)) < 0 )
//if ( (signedtx= LP_signrawtx(symbol,signedtxidp,&completed,vins,rawtxbytes,privkeys,V)) == 0 )
printf("couldnt sign transaction.%s %s\n",rawtx,bits256_str(str,*signedtxidp));
else if ( *completedp == 0 )
{
printf("incomplete signing %s (%s)\n",rawtx,jprint(vins,0));
if ( signedtx != 0 )
free(signedtx), signedtx = 0;
} else printf("basilisk_swap_bobtxspend %s -> %s\n",rawtx,bits256_str(str,*signedtxidp));
if ( signedtx == 0 )
{
retjson = cJSON_CreateObject();
jaddstr(retjson,"error","couldnt sign tx");
jaddstr(retjson,"coin",coin->symbol);
jaddstr(retjson,"rawtx",rawtx);
jadd(retjson,"vins",vins);
jadd(retjson,"privkeys",privkeys);
return(jprint(retjson,1));
}
return(signedtx);
array = cJSON_CreateArray();
jaddistr(array,rawtx);
jaddi(array,jduplicate(vins));
@ -643,7 +599,7 @@ char *LP_signrawtx(char *symbol,bits256 *signedtxidp,int32_t *completedp,cJSON *
*signedtxidp = bits256_doublesha256(0,data,len >> 1);
}
//else
printf("%s signrawtransaction.(%s) params.(%s)\n",coin->symbol,retstr,paramstr);
printf("%s signrawtransaction.(%s) params.(%s)\n",coin->symbol,retstr,paramstr);
free_json(json);
}
free(retstr);
@ -651,3 +607,136 @@ char *LP_signrawtx(char *symbol,bits256 *signedtxidp,int32_t *completedp,cJSON *
free(paramstr);
return(signedtx);
}
cJSON *LP_getblock(char *symbol,bits256 txid)
{
char buf[128],str[65]; struct iguana_info *coin = LP_coinfind(symbol);
if ( coin == 0 || coin->electrum != 0 )
return(cJSON_Parse("{\"error\":\"no native coin\"}"));
sprintf(buf,"[\"%s\"]",bits256_str(str,txid));
return(bitcoin_json(coin,"getblock",buf));
}
int32_t LP_txheight(struct iguana_info *coin,bits256 txid)
{
bits256 blockhash; struct LP_transaction *tx; cJSON *blockobj,*txobj; int32_t height = 0;
if ( coin == 0 )
return(-1);
if ( coin->electrum == 0 )
{
if ( (txobj= LP_gettx(coin->symbol,txid)) != 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");
//printf("%s LP_txheight.%d\n",coin->symbol,height);
free_json(blockobj);
} //else printf("%s LP_txheight error (%s)\n",coin->symbol,jprint(txobj,0));
free_json(txobj);
}
}
else
{
if ( (tx= LP_transactionfind(coin,txid)) != 0 )
height = tx->height;
}
return(height);
}
int32_t LP_numconfirms(char *symbol,char *coinaddr,bits256 txid,int32_t mempool)
{
struct iguana_info *coin; int32_t ht,numconfirms = 100;
//#ifndef BASILISK_DISABLEWAITTX
cJSON *txobj;
if ( (coin= LP_coinfind(symbol)) == 0 || coin->inactive != 0 )
return(-1);
if ( coin->electrum == 0 )
{
numconfirms = -1;
if ( (txobj= LP_gettx(symbol,txid)) != 0 )
{
if ( coin->electrum == 0 )
numconfirms = jint(txobj,"confirmations");
else numconfirms = coin->height - jint(txobj,"height");
free_json(txobj);
}
else if ( mempool != 0 && LP_mempoolscan(symbol,txid) >= 0 )
numconfirms = 0;
}
else
{
if ( (ht= LP_txheight(coin,txid)) > 0 && ht <= coin->height )
numconfirms = (coin->height - ht);
else if ( mempool != 0 && LP_waitmempool(symbol,coinaddr,txid,-1) >= 0 )
numconfirms = 0;
}
//#endif
return(numconfirms);
}
// not in electrum path
uint64_t LP_txfee(char *symbol)
{
uint64_t txfee = 0;
if ( strcmp(symbol,"BTC") != 0 )
txfee = LP_MIN_TXFEE;
return(txfee);
}
char *LP_blockhashstr(char *symbol,int32_t height)
{
cJSON *array; char *paramstr,*retstr; struct iguana_info *coin = LP_coinfind(symbol);
if ( coin == 0 || coin->electrum != 0 )
return(0);
array = cJSON_CreateArray();
jaddinum(array,height);
paramstr = jprint(array,1);
retstr = bitcoind_passthru(symbol,coin->serverport,coin->userpass,"getblockhash",paramstr);
free(paramstr);
return(retstr);
}
cJSON *LP_getblockhashstr(char *symbol,char *blockhashstr)
{
char buf[128]; struct iguana_info *coin = LP_coinfind(symbol);
if ( coin == 0 || coin->electrum != 0 )
return(cJSON_Parse("{\"error\":\"no native coin daemon\"}"));
sprintf(buf,"[\"%s\"]",blockhashstr);
return(bitcoin_json(coin,"getblock",buf));
}
cJSON *LP_blockjson(int32_t *heightp,char *symbol,char *blockhashstr,int32_t height)
{
cJSON *json = 0; int32_t flag = 0; struct iguana_info *coin = LP_coinfind(symbol);
if ( coin == 0 || coin->electrum != 0 )
{
printf("unexpected electrum path for %s\n",symbol);
return(0);
}
if ( blockhashstr == 0 )
blockhashstr = LP_blockhashstr(symbol,height), flag = 1;
if ( blockhashstr != 0 )
{
if ( (json= LP_getblockhashstr(symbol,blockhashstr)) != 0 )
{
if ( *heightp != 0 )
{
*heightp = juint(json,"height");
if ( height >= 0 && *heightp != height )
{
printf("unexpected height %d vs %d for %s (%s)\n",*heightp,height,blockhashstr,jprint(json,0));
*heightp = -1;
free_json(json);
json = 0;
}
}
}
if ( flag != 0 && blockhashstr != 0 )
free(blockhashstr);
}
return(json);
}

123
iguana/exchanges/LP_scan.c

@ -28,7 +28,7 @@ struct LP_transaction *LP_transactionfind(struct iguana_info *coin,bits256 txid)
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 *LP_transactionadd(struct iguana_info *coin,bits256 txid,int32_t height,int32_t numvouts,int32_t numvins)
{
struct LP_transaction *tx; int32_t i;
if ( (tx= LP_transactionfind(coin,txid)) == 0 )
@ -42,7 +42,7 @@ struct LP_transaction *LP_transactionadd(struct iguana_info *coin,bits256 txid,i
tx->height = height;
tx->numvouts = numvouts;
tx->numvins = numvins;
tx->timestamp = timestamp;
//tx->timestamp = timestamp;
tx->txid = txid;
portable_mutex_lock(&coin->txmutex);
HASH_ADD_KEYPTR(hh,coin->transactions,tx->txid.bytes,sizeof(tx->txid),tx);
@ -53,7 +53,7 @@ struct LP_transaction *LP_transactionadd(struct iguana_info *coin,bits256 txid,i
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;
int32_t i,ht,num = 0; struct LP_transaction *tx,*tmp;
HASH_ITER(hh,coin->transactions,tx,tmp)
{
for (i=0; i<tx->numvouts; i++)
@ -62,7 +62,7 @@ int32_t LP_undospends(struct iguana_info *coin,int32_t lastheight)
continue;
if ( (ht= tx->outpoints[i].spendheight) == 0 )
{
tx->outpoints[i].spendheight = LP_txheight(&timestamp,&blocktime,coin,tx->outpoints[i].spendtxid);
tx->outpoints[i].spendheight = LP_txheight(coin,tx->outpoints[i].spendtxid);
}
if ( (ht= tx->outpoints[i].spendheight) != 0 && ht > lastheight )
{
@ -78,12 +78,18 @@ int32_t LP_undospends(struct iguana_info *coin,int32_t lastheight)
uint64_t LP_txinterestvalue(uint64_t *interestp,char *destaddr,struct iguana_info *coin,bits256 txid,int32_t vout)
{
uint64_t interest,value = 0; cJSON *txobj,*sobj,*array; int32_t n=0;
uint64_t interest,value = 0; double val; 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 )
// GETTXOUT.({"value":0.01200000,"txid":"6f5adfefad102e39f62a6bacb222ebace6ce5c084116c08a62cac1182729dd46","vout":1,"scriptPubkey":{"reqSigs":1,"type":"pubkey","addresses":["19Cq6MBaD8LY7trqs99ypqKAms3GcLs6J9"]}})
if ( (val= jdouble(txobj,"amount")) < SMALLVAL )
val = jdouble(txobj,"value");
if ( val > SMALLVAL )
value = (val * SATOSHIDEN + 0.0000000049);
else value = 0;
if ( value == 0 )
{
char str[65]; printf("%s LP_txvalue.%s strange utxo.(%s) vout.%d\n",coin->symbol,bits256_str(str,txid),jprint(txobj,0),vout);
}
@ -98,6 +104,7 @@ uint64_t LP_txinterestvalue(uint64_t *interestp,char *destaddr,struct iguana_inf
if ( (sobj= jobj(txobj,"scriptPubKey")) != 0 && (array= jarray(&n,sobj,"addresses")) != 0 )
{
strcpy(destaddr,jstri(array,0));
//printf("set destaddr.(%s)\n",destaddr);
if ( n > 1 )
printf("LP_txinterestvalue warning: violation of 1 output assumption n.%d\n",n);
} else printf("LP_txinterestvalue no addresses found?\n");
@ -109,16 +116,16 @@ uint64_t LP_txinterestvalue(uint64_t *interestp,char *destaddr,struct iguana_inf
int32_t LP_transactioninit(struct iguana_info *coin,bits256 txid,int32_t iter)
{
struct LP_transaction *tx; char *address; int32_t i,n,height,numvouts,numvins,spentvout; uint32_t timestamp,blocktime; cJSON *txobj,*vins,*vouts,*vout,*vin,*sobj,*addresses; bits256 spenttxid; char str[65];
struct LP_transaction *tx; char *address; int32_t i,n,height,numvouts,numvins,spentvout; cJSON *txobj,*vins,*vouts,*vout,*vin,*sobj,*addresses; bits256 spenttxid; char str[65];
if ( (txobj= LP_gettx(coin->symbol,txid)) != 0 )
{
//printf("TX.(%s)\n",jprint(txobj,0));
height = LP_txheight(&timestamp,&blocktime,coin,txid);
if ( timestamp == 0 && height > 0 )
timestamp = blocktime;
if ( coin->electrum == 0 )
height = LP_txheight(coin,txid);
else height = -1;
vins = jarray(&numvins,txobj,"vin");
vouts = jarray(&numvouts,txobj,"vout");
if ( iter == 0 && vouts != 0 && (tx= LP_transactionadd(coin,txid,height,numvouts,numvins,timestamp)) != 0 )
if ( iter == 0 && vouts != 0 && (tx= LP_transactionadd(coin,txid,height,numvouts,numvins)) != 0 )
{
for (i=0; i<numvouts; i++)
{
@ -565,11 +572,16 @@ int64_t basilisk_txvalue(char *symbol,bits256 txid,int32_t vout)
uint64_t LP_txvalue(char *coinaddr,char *symbol,bits256 txid,int32_t vout)
{
struct LP_transaction *tx; char _coinaddr[64]; uint64_t interest = 0,value = 0; struct iguana_info *coin;
struct LP_transaction *tx; struct iguana_info *coin;
if ( (coin= LP_coinfind(symbol)) == 0 || coin->inactive != 0 )
return(0);
if ( coinaddr != 0 )
coinaddr[0] = 0;
if ( (tx= LP_transactionfind(coin,txid)) == 0 )
{
LP_transactioninit(coin,txid,0);
LP_transactioninit(coin,txid,1);
}
if ( (tx= LP_transactionfind(coin,txid)) != 0 )
{
if ( vout < tx->numvouts )
@ -582,22 +594,17 @@ uint64_t LP_txvalue(char *coinaddr,char *symbol,bits256 txid,int32_t vout)
else
{
if ( coinaddr != 0 )
value = LP_txinterestvalue(&tx->outpoints[vout].interest,coinaddr,coin,txid,vout);
//printf("return value %.8f + interest %.8f\n",dstr(tx->outpoints[vout].value),dstr(tx->outpoints[vout].interest));
{
if ( tx->outpoints[vout].coinaddr[0] == 0 )
LP_txinterestvalue(&tx->outpoints[vout].interest,tx->outpoints[vout].coinaddr,coin,txid,vout);
strcpy(coinaddr,tx->outpoints[vout].coinaddr);
//printf("(%s) return value %.8f + interest %.8f\n",coinaddr,dstr(tx->outpoints[vout].value),dstr(tx->outpoints[vout].interest));
}
return(tx->outpoints[vout].value + tx->outpoints[vout].interest);
}
} else printf("vout.%d >= tx->numvouts.%d\n",vout,tx->numvouts);
}
if ( tx == 0 )
{
LP_transactioninit(coin,txid,0);
LP_transactioninit(coin,txid,1);
}
if ( coinaddr == 0 )
coinaddr = _coinaddr;
value = LP_txinterestvalue(&interest,coinaddr,coin,txid,vout);
//printf("coinaddr.(%s) value %.8f interest %.8f\n",coinaddr,dstr(value),dstr(interest));
return(value + interest);
return(0);
}
int32_t LP_spendsearch(bits256 *spendtxidp,int32_t *indp,char *symbol,bits256 searchtxid,int32_t searchvout)
@ -622,9 +629,9 @@ int32_t LP_spendsearch(bits256 *spendtxidp,int32_t *indp,char *symbol,bits256 se
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 )
if ( (coin= LP_coinfind(symbol)) == 0 || coin->inactive != 0 || coin->electrum != 0 )
return(-1);
if ( (array= LP_getmempool(symbol)) != 0 )
if ( (array= LP_getmempool(symbol,0)) != 0 )
{
if ( is_cJSON_Array(array) != 0 && (n= cJSON_GetArraySize(array)) > 0 )
{
@ -648,40 +655,52 @@ int32_t LP_mempoolscan(char *symbol,bits256 searchtxid)
return(-1);
}
int32_t LP_numconfirms(struct basilisk_swap *swap,struct basilisk_rawtx *rawtx,int32_t mempool)
int32_t LP_waitmempool(char *symbol,char *coinaddr,bits256 txid,int32_t duration)
{
struct iguana_info *coin; int32_t numconfirms = 100;
//#ifndef BASILISK_DISABLEWAITTX
cJSON *txobj;
if ( (coin= LP_coinfind(rawtx->coin->symbol)) == 0 || coin->inactive != 0 )
struct iguana_info *coin; struct LP_transaction *tx; cJSON *array,*item; uint32_t expiration,i,n;
if ( (coin= LP_coinfind(symbol)) == 0 || coin->inactive != 0 )
return(-1);
numconfirms = -1;
if ( (txobj= LP_gettx(rawtx->coin->symbol,rawtx->I.signedtxid)) != 0 )
expiration = (uint32_t)time(NULL) + duration;
while ( 1 )
{
if ( coin->electrum == 0 )
numconfirms = jint(txobj,"confirmations");
else numconfirms = coin->height - jint(txobj,"height");
free_json(txobj);
}
else if ( mempool != 0 && LP_mempoolscan(rawtx->coin->symbol,rawtx->I.signedtxid) >= 0 )
numconfirms = 0;
//#endif
return(numconfirms);
}
int32_t LP_waitmempool(char *symbol,bits256 txid,int32_t duration)
{
uint32_t expiration = (uint32_t)time(NULL) + duration;
while ( time(NULL) < expiration )
{
if ( LP_mempoolscan(symbol,txid) >= 0 )
return(0);
{
if ( LP_mempoolscan(symbol,txid) >= 0 )
return(0);
}
else
{
if ( (tx= LP_transactionfind(coin,txid)) != 0 && tx->height >= 0 )
{
char str[65]; printf("LP_waitmempool found %s %s\n",symbol,bits256_str(str,txid));
return(tx->height);
}
if ( (array= electrum_address_getmempool(symbol,coin->electrum,&array,coinaddr)) != 0 )
{
if ( (n= cJSON_GetArraySize(array)) > 0 )
{
for (i=0; i<n; i++)
{
item = jitem(array,i);
if ( bits256_cmp(txid,jbits256(item,"tx_hash")) == 0 )
{
free(array);
char str[65]; printf("found %s %s in mempool\n",symbol,bits256_str(str,txid));
return(0);
}
}
}
free(array);
}
}
if ( time(NULL) < expiration )
break;
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 LP_mempool_vinscan(bits256 *spendtxidp,int32_t *spendvinp,char *symbol,char *coinaddr,bits256 searchtxid,int32_t searchvout,bits256 searchtxid2,int32_t searchvout2)
{
struct iguana_info *coin; int32_t selector; cJSON *array;
if ( symbol == 0 || symbol[0] == 0 || bits256_nonz(searchtxid) == 0 || bits256_nonz(searchtxid2) == 0 )
@ -690,7 +709,7 @@ int32_t LP_mempool_vinscan(bits256 *spendtxidp,int32_t *spendvinp,char *symbol,b
return(-1);
if ( time(NULL) > coin->lastmempool+LP_MEMPOOL_TIMEINCR )
{
if ( (array= LP_getmempool(symbol)) != 0 )
if ( (array= LP_getmempool(symbol,coinaddr)) != 0 )
{
free_json(array);
coin->lastmempool = (uint32_t)time(NULL);

92
iguana/exchanges/LP_socket.c

@ -244,6 +244,7 @@ struct electrum_info
{
queue_t sendQ,pendingQ;
int32_t bufsize,sock,*heightp;
struct iguana_info *coin;
uint32_t stratumid,lasttime,pending,*heighttimep;
char ipaddr[64],symbol[16];
uint16_t port;
@ -303,6 +304,30 @@ struct electrum_info *electrum_server(char *symbol,struct electrum_info *ep)
return(ep);
}
void electrum_process_array(struct iguana_info *coin,cJSON *array)
{
int32_t i,n; bits256 txid; cJSON *item; struct LP_transaction *tx;
if ( array != 0 && coin != 0 && (n= cJSON_GetArraySize(array)) > 0 )
{
for (i=0; i<n; i++)
{
item = jitem(array,i);
txid = jbits256(item,"tx_hash");
if ( (tx= LP_transactionfind(coin,txid)) == 0 )
{
LP_transactioninit(coin,txid,0);
LP_transactioninit(coin,txid,1);
tx = LP_transactionfind(coin,txid);
}
if ( tx != 0 && tx->height <= 0 )
{
tx->height = jint(item,"height");
char str[65]; printf(">>>>>>>>>> set %s <- height %d\n",bits256_str(str,txid),tx->height);
}
}
}
}
cJSON *electrum_submit(char *symbol,struct electrum_info *ep,cJSON **retjsonp,char *method,char *params,int32_t timeout)
{
// queue id and string and callback
@ -390,11 +415,55 @@ cJSON *electrum_script_getmempool(char *symbol,struct electrum_info *ep,cJSON **
cJSON *electrum_script_listunspent(char *symbol,struct electrum_info *ep,cJSON **retjsonp,char *script) { return(electrum_strarg(symbol,ep,retjsonp,"blockchain.scripthash.listunspent",script,ELECTRUM_TIMEOUT)); }
cJSON *electrum_script_subscribe(char *symbol,struct electrum_info *ep,cJSON **retjsonp,char *script) { return(electrum_strarg(symbol,ep,retjsonp,"blockchain.scripthash.subscribe",script,ELECTRUM_TIMEOUT)); }
cJSON *electrum_address_subscribe(char *symbol,struct electrum_info *ep,cJSON **retjsonp,char *addr) { return(electrum_strarg(symbol,ep,retjsonp,"blockchain.address.subscribe",addr,ELECTRUM_TIMEOUT)); }
cJSON *electrum_address_gethistory(char *symbol,struct electrum_info *ep,cJSON **retjsonp,char *addr) { return(electrum_strarg(symbol,ep,retjsonp,"blockchain.address.get_history",addr,ELECTRUM_TIMEOUT)); }
cJSON *electrum_address_getmempool(char *symbol,struct electrum_info *ep,cJSON **retjsonp,char *addr) { return(electrum_strarg(symbol,ep,retjsonp,"blockchain.address.get_mempool",addr,ELECTRUM_TIMEOUT)); }
cJSON *electrum_address_getbalance(char *symbol,struct electrum_info *ep,cJSON **retjsonp,char *addr) { return(electrum_strarg(symbol,ep,retjsonp,"blockchain.address.get_balance",addr,ELECTRUM_TIMEOUT)); }
cJSON *electrum_address_listunspent(char *symbol,struct electrum_info *ep,cJSON **retjsonp,char *addr) { return(electrum_strarg(symbol,ep,retjsonp,"blockchain.address.listunspent",addr,ELECTRUM_TIMEOUT)); }
cJSON *electrum_address_subscribe(char *symbol,struct electrum_info *ep,cJSON **retjsonp,char *addr)
{
cJSON *retjson;
if ( (retjson= electrum_strarg(symbol,ep,retjsonp,"blockchain.address.subscribe",addr,ELECTRUM_TIMEOUT)) != 0 )
{
printf("subscribe.(%s)\n",jprint(retjson,0));
}
return(retjson);
}
cJSON *electrum_address_gethistory(char *symbol,struct electrum_info *ep,cJSON **retjsonp,char *addr)
{
cJSON *retjson; struct iguana_info *coin = LP_coinfind(symbol);
retjson = electrum_strarg(symbol,ep,retjsonp,"blockchain.address.get_history",addr,ELECTRUM_TIMEOUT);
printf("history.(%s)\n",jprint(retjson,0));
electrum_process_array(coin,retjson);
return(retjson);
}
cJSON *electrum_address_getmempool(char *symbol,struct electrum_info *ep,cJSON **retjsonp,char *addr)
{
cJSON *retjson; struct iguana_info *coin = LP_coinfind(symbol);
retjson = electrum_strarg(symbol,ep,retjsonp,"blockchain.address.get_mempool",addr,ELECTRUM_TIMEOUT);
//printf("MEMPOOL.(%s)\n",jprint(retjson,0));
electrum_process_array(coin,retjson);
return(retjson);
}
cJSON *electrum_address_listunspent(char *symbol,struct electrum_info *ep,cJSON **retjsonp,char *addr)
{
cJSON *retjson=0; struct iguana_info *coin = LP_coinfind(symbol);
//printf("electrum listunspent last.(%s lag %d)\n",coin->lastunspent,(int32_t)(time(NULL) - coin->unspenttime));
if ( strcmp(coin->lastunspent,addr) != 0 || time(NULL) > coin->unspenttime+10 )
{
if ( (retjson= electrum_strarg(symbol,ep,retjsonp,"blockchain.address.listunspent",addr,ELECTRUM_TIMEOUT)) != 0 )
{
printf("LISTUNSPENT.(%s)\n",jprint(retjson,0));
electrum_process_array(coin,retjson);
strcpy(coin->lastunspent,addr);
coin->unspenttime = (uint32_t)time(NULL);
}
}
return(retjson);
}
cJSON *electrum_address_getbalance(char *symbol,struct electrum_info *ep,cJSON **retjsonp,char *addr)
{
return(electrum_strarg(symbol,ep,retjsonp,"blockchain.address.get_balance",addr,ELECTRUM_TIMEOUT));
}
cJSON *electrum_addpeer(char *symbol,struct electrum_info *ep,cJSON **retjsonp,char *endpoint) { return(electrum_strarg(symbol,ep,retjsonp,"server.add_peer",endpoint,ELECTRUM_TIMEOUT)); }
cJSON *electrum_sendrawtransaction(char *symbol,struct electrum_info *ep,cJSON **retjsonp,char *rawtx) { return(electrum_strarg(symbol,ep,retjsonp,"blockchain.transaction.broadcast",rawtx,ELECTRUM_TIMEOUT)); }
@ -402,7 +471,12 @@ cJSON *electrum_sendrawtransaction(char *symbol,struct electrum_info *ep,cJSON *
cJSON *electrum_estimatefee(char *symbol,struct electrum_info *ep,cJSON **retjsonp,int32_t numblocks) { return(electrum_intarg(symbol,ep,retjsonp,"blockchain.estimatefee",numblocks,ELECTRUM_TIMEOUT)); }
cJSON *electrum_getheader(char *symbol,struct electrum_info *ep,cJSON **retjsonp,int32_t n) { return(electrum_intarg(symbol,ep,retjsonp,"blockchain.block.get_header",n,ELECTRUM_TIMEOUT)); }
cJSON *electrum_getchunk(char *symbol,struct electrum_info *ep,cJSON **retjsonp,int32_t n) { return(electrum_intarg(symbol,ep,retjsonp,"blockchain.block.get_chunk",n,ELECTRUM_TIMEOUT)); }
cJSON *electrum_transaction(char *symbol,struct electrum_info *ep,cJSON **retjsonp,bits256 txid) { return(electrum_hasharg(symbol,ep,retjsonp,"blockchain.transaction.get",txid,ELECTRUM_TIMEOUT)); }
cJSON *electrum_transaction(char *symbol,struct electrum_info *ep,cJSON **retjsonp,bits256 txid)
{
char str[65]; printf("%s TRANSACTION.(%s)\n",symbol,bits256_str(str,txid));
return(electrum_hasharg(symbol,ep,retjsonp,"blockchain.transaction.get",txid,ELECTRUM_TIMEOUT));
}
cJSON *electrum_getmerkle(char *symbol,struct electrum_info *ep,cJSON **retjsonp,bits256 txid,int32_t height)
{
@ -502,6 +576,7 @@ struct electrum_info *LP_electrum_info(int32_t *alreadyp,char *symbol,char *ipad
safecopy(ep->ipaddr,ipaddr,sizeof(ep->ipaddr));
ep->port = port;
ep->bufsize = bufsize;
ep->coin = LP_coinfind(symbol);
ep->lasttime = (uint32_t)time(NULL);
sprintf(name,"%s_%s_%u_electrum_sendQ",symbol,ipaddr,port);
queue_enqueue(name,&ep->sendQ,queueitem(str));
@ -535,6 +610,11 @@ int32_t LP_recvfunc(struct electrum_info *ep,char *str,int32_t len)
resultjson = jitem(paramsjson,i);
}
}
else if ( strcmp(method,"blockchain.address.subscribe") == 0 )
{
printf("recv addr subscribe.(%s)\n",jprint(resultjson,0));
electrum_process_array(ep->coin,resultjson);
}
}
if ( resultjson != 0 )
{

22
iguana/exchanges/LP_swap.c

@ -635,9 +635,9 @@ uint32_t LP_swapdata_rawtxsend(int32_t pairsock,struct basilisk_swap *swap,uint3
if ( suppress_swapsend == 0 )
{
retval = LP_swapsend(pairsock,swap,msgbits,sendbuf,sendlen,nextbits,rawtx->I.crcs);
if ( LP_waitmempool(rawtx->coin->symbol,rawtx->I.signedtxid,LP_SWAPSTEP_TIMEOUT) < 0 )
if ( LP_waitmempool(rawtx->coin->symbol,rawtx->I.destaddr,rawtx->I.signedtxid,LP_SWAPSTEP_TIMEOUT*10) < 0 )
{
char str[65]; printf("failed to find %s %s in the mempool?\n",rawtx->name,bits256_str(str,rawtx->I.actualtxid));
char str[65]; printf("failed to find %s %s %s in the mempool?\n",rawtx->name,rawtx->I.destaddr,bits256_str(str,rawtx->I.actualtxid));
retval = -1;
}
return(retval);
@ -716,11 +716,11 @@ void LP_bobloop(void *_swap)
basilisk_bobdeposit_refund(swap,swap->I.putduration);
//printf("depositlen.%d\n",swap->bobdeposit.I.datalen);
LP_swapsfp_update(&swap->I.req);
if ( LP_waitfor(swap->N.pair,swap,LP_SWAPSTEP_TIMEOUT*3,LP_verify_otherfee) < 0 )
if ( LP_waitfor(swap->N.pair,swap,LP_SWAPSTEP_TIMEOUT*10,LP_verify_otherfee) < 0 )
printf("error waiting for alicefee\n");
else if ( LP_swapdata_rawtxsend(swap->N.pair,swap,0x200,data,maxlen,&swap->bobdeposit,0x100,0) == 0 )
printf("error sending bobdeposit\n");
else if ( LP_waitfor(swap->N.pair,swap,LP_SWAPSTEP_TIMEOUT*3,LP_verify_alicepayment) < 0 )
else if ( LP_waitfor(swap->N.pair,swap,LP_SWAPSTEP_TIMEOUT*10,LP_verify_alicepayment) < 0 )
printf("error waiting for alicepayment\n");
else
{
@ -731,7 +731,7 @@ void LP_bobloop(void *_swap)
if ( strcmp(swap->alicecoin.symbol,"BTC") == 0 )
m = 0;
else m = 1;
while ( (n= LP_numconfirms(swap,&swap->alicepayment,1)) < m ) // sync with alice
while ( (n= LP_numconfirms(swap->alicecoin.symbol,swap->alicepayment.I.destaddr,swap->alicepayment.I.signedtxid,1)) < m ) // sync with alice
{
char str[65];printf("%d waiting for alicepayment to be confirmed.%d %s %s\n",n,1,swap->alicecoin.symbol,bits256_str(str,swap->alicepayment.I.signedtxid));
sleep(3);
@ -775,7 +775,7 @@ void LP_aliceloop(void *_swap)
LP_swapsfp_update(&swap->I.req);
if ( LP_swapdata_rawtxsend(swap->N.pair,swap,0x80,data,maxlen,&swap->myfee,0x40,0) == 0 )
printf("error sending alicefee\n");
else if ( LP_waitfor(swap->N.pair,swap,LP_SWAPSTEP_TIMEOUT*3,LP_verify_bobdeposit) < 0 )
else if ( LP_waitfor(swap->N.pair,swap,LP_SWAPSTEP_TIMEOUT*10,LP_verify_bobdeposit) < 0 )
printf("error waiting for bobdeposit\n");
else if ( LP_swapdata_rawtxsend(swap->N.pair,swap,0x1000,data,maxlen,&swap->alicepayment,0x800,0) == 0 )
printf("error sending alicepayment\n");
@ -784,24 +784,24 @@ void LP_aliceloop(void *_swap)
if ( strcmp(swap->alicecoin.symbol,"BTC") == 0 )
m = 0;
else m = 1;
while ( (n= LP_numconfirms(swap,&swap->alicepayment,1)) < m )
while ( (n= LP_numconfirms(swap->alicecoin.symbol,swap->alicepayment.I.destaddr,swap->alicepayment.I.signedtxid,1)) < m )
{
char str[65];printf("%d waiting for alicepayment to be confirmed.%d %s %s\n",n,1,swap->alicecoin.symbol,bits256_str(str,swap->alicepayment.I.signedtxid));
sleep(LP_SWAPSTEP_TIMEOUT);
sleep(10);
}
swap->sentflag = 1;
if ( LP_waitfor(swap->N.pair,swap,LP_SWAPSTEP_TIMEOUT*3,LP_verify_bobpayment) < 0 )
if ( LP_waitfor(swap->N.pair,swap,LP_SWAPSTEP_TIMEOUT*10,LP_verify_bobpayment) < 0 )
printf("error waiting for bobpayment\n");
else
{
while ( (n= LP_numconfirms(swap,&swap->bobpayment,1)) < swap->I.bobconfirms )
while ( (n= LP_numconfirms(swap->bobcoin.symbol,swap->bobpayment.I.destaddr,swap->bobpayment.I.signedtxid,1)) < swap->I.bobconfirms )
{
char str[65];printf("%d waiting for bobpayment to be confirmed.%d %s %s\n",n,swap->I.bobconfirms,swap->bobcoin.symbol,bits256_str(str,swap->bobpayment.I.signedtxid));
sleep(LP_SWAPSTEP_TIMEOUT);
}
if ( LP_swapdata_rawtxsend(swap->N.pair,swap,0x20000,data,maxlen,&swap->alicespend,0x40000,0) == 0 )
printf("error sending alicespend\n");
while ( (n= LP_numconfirms(swap,&swap->alicespend,1)) < swap->I.aliceconfirms )
while ( (n= LP_numconfirms(swap->alicecoin.symbol,swap->alicespend.I.destaddr,swap->alicespend.I.signedtxid,1)) < swap->I.aliceconfirms )
{
char str[65];printf("%d waiting for alicespend to be confirmed.%d %s %s\n",n,swap->I.aliceconfirms,swap->bobcoin.symbol,bits256_str(str,swap->alicespend.I.signedtxid));
sleep(LP_SWAPSTEP_TIMEOUT);

106
iguana/exchanges/LP_transaction.c

@ -904,7 +904,7 @@ bits256 _LP_swap_spendtxid(char *symbol,char *destaddr,char *coinaddr,bits256 ut
bits256 LP_swap_spendtxid(char *symbol,char *destaddr,bits256 utxotxid,int32_t vout)
{
bits256 spendtxid,txid; char *catstr,*addr; cJSON *array,*item,*item2,*txobj,*vins; int32_t i,n,m,spendvin; char coinaddr[64],str[65];
bits256 spendtxid; int32_t spendvin; char coinaddr[64],str[65];
// listtransactions or listspents
destaddr[0] = 0;
coinaddr[0] = 0;
@ -913,95 +913,6 @@ bits256 LP_swap_spendtxid(char *symbol,char *destaddr,bits256 utxotxid,int32_t v
printf("spend of %s/v%d detected\n",bits256_str(str,utxotxid),vout);
return(spendtxid);
//char str[65]; printf("swap %s spendtxid.(%s)\n",symbol,bits256_str(str,utxotxid));
if ( (0) && strcmp("BTC",symbol) == 0 )
{
//[{"type":"sent","confirmations":379,"height":275311,"timestamp":1492084664,"txid":"8703c5517bc57db38134058370a14e99b8e662b99ccefa2061dea311bbd02b8b","vout":0,"amount":117.50945263,"spendtxid":"cf2509e076fbb9b22514923df916b7aacb1391dce9c7e1460b74947077b12510","vin":0,"paid":{"type":"paid","txid":"cf2509e076fbb9b22514923df916b7aacb1391dce9c7e1460b74947077b12510","height":275663,"timestamp":1492106024,"vouts":[{"RUDpN6PEBsE7ZFbGjUxk1W3QVsxnjBLYw6":117.50935263}]}}]
/*LP_swap_getcoinaddr(symbol,coinaddr,utxotxid,vout);
if ( coinaddr[0] != 0 )
spendtxid = _LP_swap_spendtxid(symbol,destaddr,coinaddr,utxotxid,vout);*/
}
else
{
if ( (array= LP_listtransactions(symbol,destaddr,1000,0)) != 0 )
{
if ( (n= cJSON_GetArraySize(array)) > 0 )
{
for (i=0; i<n; i++)
{
if ( (item= jitem(array,i)) == 0 )
continue;
txid = jbits256(item,"txid");
if ( vout == juint(item,"vout") && bits256_cmp(txid,utxotxid) == 0 && (addr= jstr(item,"address")) != 0 )
{
if ( (catstr= jstr(item,"category")) != 0 )
{
if (strcmp(catstr,"send") == 0 )
{
strncpy(destaddr,addr,63);
//printf("(%s) <- (%s) item.%d.[%s]\n",destaddr,coinaddr,i,jprint(item,0));
if ( coinaddr[0] != 0 )
break;
}
if (strcmp(catstr,"receive") == 0 )
{
strncpy(coinaddr,addr,63);
//printf("receive dest.(%s) <- (%s)\n",destaddr,coinaddr);
if ( destaddr[0] != 0 )
break;
}
}
}
}
}
free_json(array);
}
if ( destaddr[0] != 0 )
{
if ( (array= LP_listtransactions(symbol,destaddr,1000,0)) != 0 )
{
if ( (n= cJSON_GetArraySize(array)) > 0 )
{
for (i=0; i<n; i++)
{
if ( (item= jitem(array,i)) == 0 )
continue;
if ( (catstr= jstr(item,"category")) != 0 && strcmp(catstr,"send") == 0 )
{
txid = jbits256(item,"txid");
if ( (txobj= LP_gettx(symbol,txid)) != 0 )
{
if ( (vins= jarray(&m,txobj,"vin")) != 0 && m > jint(item,"vout") )
{
item2 = jitem(vins,jint(item,"vout"));
if ( bits256_cmp(utxotxid,jbits256(item2,"txid")) == 0 && vout == jint(item2,"vout") )
{
spendtxid = txid;
break;
}
}
}
}
}
if ( i == n )
printf("dpowlist: native couldnt find spendtxid for %s\n",bits256_str(str,utxotxid));
}
free_json(array);
}
if ( bits256_nonz(spendtxid) != 0 )
return(spendtxid);
}
/*if ( iguana_isnotarychain(symbol) >= 0 )
{
LP_swap_getcoinaddr(symbol,coinaddr,utxotxid,vout);
printf("fallback use DEX for native (%s) (%s)\n",coinaddr,bits256_str(str,utxotxid));
if ( coinaddr[0] != 0 )
{
spendtxid = _LP_swap_spendtxid(symbol,destaddr,coinaddr,utxotxid,vout);
printf("spendtxid.(%s)\n",bits256_str(str,spendtxid));
}
}*/
}
return(spendtxid);
}
int32_t basilisk_swap_bobredeemscript(int32_t depositflag,int32_t *secretstartp,uint8_t *redeemscript,uint32_t locktime,bits256 pubA0,bits256 pubB0,bits256 pubB1,bits256 privAm,bits256 privBn,uint8_t *secretAm,uint8_t *secretAm256,uint8_t *secretBn,uint8_t *secretBn256)
@ -1162,7 +1073,7 @@ int32_t basilisk_bobdeposit_refund(struct basilisk_swap *swap,int32_t delay)
void LP_swap_coinaddr(struct iguana_info *coin,char *coinaddr,uint64_t *valuep,uint8_t *data,int32_t datalen,int32_t v)
{
cJSON *txobj,*vouts,*vout,*addresses,*item,*skey; uint8_t extraspace[32768]; bits256 signedtxid; struct iguana_msgtx msgtx; char *addr; int32_t n,m,suppress_pubkeys = 0;
cJSON *txobj,*vouts,*vout,*addresses,*item,*skey; uint8_t extraspace[32768]; bits256 signedtxid; struct iguana_msgtx msgtx; char *addr; double val; int32_t n,m,suppress_pubkeys = 0;
if ( valuep != 0 )
*valuep = 0;
if ( (txobj= bitcoin_data2json(coin->taddr,coin->pubtype,coin->p2shtype,coin->isPoS,coin->longestchain,&signedtxid,&msgtx,extraspace,sizeof(extraspace),data,datalen,0,suppress_pubkeys)) != 0 )
@ -1173,8 +1084,11 @@ void LP_swap_coinaddr(struct iguana_info *coin,char *coinaddr,uint64_t *valuep,u
vout = jitem(vouts,v);
if ( valuep != 0 )
{
if ( (*valuep= SATOSHIDEN * jdouble(vout,"value")) == 0 )
*valuep= SATOSHIDEN * jdouble(vout,"amount");
*valuep = 0;
if ( (val= jdouble(vout,"value")) < SMALLVAL )
val = jdouble(vout,"amount");
if ( val > SMALLVAL )
*valuep = (val * SATOSHIDEN + 0.0000000049);
}
//printf("VOUT.(%s)\n",jprint(vout,0));
if ( (skey= jobj(vout,"scriptPubKey")) != 0 && (addresses= jarray(&m,skey,"addresses")) != 0 )
@ -1424,7 +1338,7 @@ int32_t LP_verify_bobdeposit(struct basilisk_swap *swap,uint8_t *data,int32_t da
printf("%02x",swap->aliceclaim.txbytes[i]);
printf(" <- aliceclaim\n");*/
//basilisk_txlog(swap,&swap->aliceclaim,swap->I.putduration+swap->I.callduration);
return(LP_waitmempool(swap->bobcoin.symbol,swap->bobdeposit.I.signedtxid,10));
return(LP_waitmempool(swap->bobcoin.symbol,swap->bobdeposit.I.destaddr,swap->bobdeposit.I.signedtxid,10));
} else printf("error signing aliceclaim suppress.%d vin.(%s)\n",swap->aliceclaim.I.suppress_pubkeys,swap->bobdeposit.I.destaddr);
}
printf("error with bobdeposit\n");
@ -1442,7 +1356,7 @@ int32_t LP_verify_alicepayment(struct basilisk_swap *swap,uint8_t *data,int32_t
if ( bits256_nonz(swap->alicepayment.I.signedtxid) != 0 )
swap->aliceunconf = 1;
basilisk_dontforget_update(swap,&swap->alicepayment);
return(LP_waitmempool(swap->alicecoin.symbol,swap->alicepayment.I.signedtxid,10));
return(LP_waitmempool(swap->alicecoin.symbol,swap->alicepayment.I.destaddr,swap->alicepayment.I.signedtxid,10));
//printf("import alicepayment address.(%s)\n",swap->alicepayment.p2shaddr);
//LP_importaddress(swap->alicecoin.symbol,swap->alicepayment.p2shaddr);
return(0);
@ -1489,7 +1403,7 @@ int32_t LP_verify_bobpayment(struct basilisk_swap *swap,uint8_t *data,int32_t da
printf("%02x",swap->alicespend.txbytes[i]);
printf(" <- alicespend\n\n");*/
swap->I.alicespent = 1;
return(LP_waitmempool(swap->bobcoin.symbol,swap->bobpayment.I.signedtxid,10));
return(LP_waitmempool(swap->bobcoin.symbol,swap->bobpayment.I.destaddr,swap->bobpayment.I.signedtxid,10));
} else printf("error signing aliceclaim suppress.%d vin.(%s)\n",swap->alicespend.I.suppress_pubkeys,swap->bobpayment.I.destaddr);
}
printf("error validating bobpayment\n");

55
iguana/exchanges/LP_utxos.c

@ -291,7 +291,7 @@ int32_t LP_iseligible(uint64_t *valp,uint64_t *val2p,int32_t iambob,char *symbol
//struct LP_utxoinfo *utxo;
uint64_t val,val2=0,txfee,threshold=0; int32_t bypass = 0; char destaddr[64],destaddr2[64]; struct iguana_info *coin = LP_coinfind(symbol);
destaddr[0] = destaddr2[0] = 0;
if ( coin != 0 && ((IAMLP != 0 && coin->inactive != 0) || coin->electrum != 0) )
if ( coin != 0 && IAMLP != 0 && coin->inactive != 0 )
bypass = 1;
if ( bypass != 0 )
val = satoshis;
@ -513,7 +513,7 @@ void LP_utxo_clientpublish(struct LP_utxoinfo *utxo)
struct LP_utxoinfo *LP_utxoadd(int32_t iambob,int32_t mypubsock,char *symbol,bits256 txid,int32_t vout,int64_t value,bits256 txid2,int32_t vout2,int64_t value2,char *spendscript,char *coinaddr,bits256 pubkey,char *gui,uint32_t sessionid)
{
uint64_t val,val2=0,tmpsatoshis,txfee; cJSON *txobj; int32_t spendvini,numconfirms,selector; bits256 spendtxid; struct iguana_info *coin; struct _LP_utxoinfo u; struct LP_utxoinfo *utxo = 0;
uint64_t val,val2=0,tmpsatoshis,txfee; int32_t spendvini,numconfirms,selector; bits256 spendtxid; struct iguana_info *coin; struct _LP_utxoinfo u; struct LP_utxoinfo *utxo = 0;
if ( symbol == 0 || symbol[0] == 0 || spendscript == 0 || spendscript[0] == 0 || coinaddr == 0 || coinaddr[0] == 0 || bits256_nonz(txid) == 0 || bits256_nonz(txid2) == 0 || vout < 0 || vout2 < 0 || value <= 0 || value2 <= 0 || sessionid == 0 )
{
printf("session.%u malformed addutxo %d %d %d %d %d %d %d %d %d\n",sessionid,symbol == 0,spendscript == 0,coinaddr == 0,bits256_nonz(txid) == 0,bits256_nonz(txid2) == 0,vout < 0,vout2 < 0,value <= 0,value2 <= 0);
@ -537,12 +537,7 @@ struct LP_utxoinfo *LP_utxoadd(int32_t iambob,int32_t mypubsock,char *symbol,bit
printf("trying to add Alice utxo when not mine? %s/v%d\n",bits256_str(str,txid),vout);
return(0);
}
if ( LP_iseligible(&val,&val2,iambob,symbol,txid,vout,tmpsatoshis,txid2,vout2) <= 0 )
{
printf("iambob.%d utxoadd %s inactive.%u got ineligible txid value %.8f:%.8f, value2 %.8f:%.8f, tmpsatoshis %.8f\n",iambob,symbol,coin->inactive,dstr(value),dstr(val),dstr(value2),dstr(val2),dstr(tmpsatoshis));
return(0);
}
numconfirms = -1;
/*numconfirms = -1;
if ( (txobj= LP_gettx(symbol,txid)) != 0 )
{
if ( coin->electrum == 0 )
@ -550,11 +545,6 @@ struct LP_utxoinfo *LP_utxoadd(int32_t iambob,int32_t mypubsock,char *symbol,bit
else numconfirms = coin->height - jint(txobj,"height");
free_json(txobj);
}
if ( numconfirms <= 0 )
{
printf("LP_utxoadd reject numconfirms.%d\n",numconfirms);
return(0);
}
numconfirms = -1;
if ( (txobj= LP_gettx(symbol,txid2)) != 0 )
{
@ -567,6 +557,29 @@ struct LP_utxoinfo *LP_utxoadd(int32_t iambob,int32_t mypubsock,char *symbol,bit
{
printf("LP_utxoadd reject2 numconfirms.%d\n",numconfirms);
return(0);
}*/
if ( coin->inactive == 0 )
{
if ( LP_iseligible(&val,&val2,iambob,symbol,txid,vout,tmpsatoshis,txid2,vout2) <= 0 )
{
printf("iambob.%d utxoadd %s inactive.%u got ineligible txid value %.8f:%.8f, value2 %.8f:%.8f, tmpsatoshis %.8f\n",iambob,symbol,coin->inactive,dstr(value),dstr(val),dstr(value2),dstr(val2),dstr(tmpsatoshis));
return(0);
}
if ( (numconfirms= LP_numconfirms(symbol,coinaddr,txid,0)) <= 0 )
{
printf("LP_utxoadd reject numconfirms.%d %s.%s\n",numconfirms,symbol,bits256_str(str,txid));
return(0);
}
if ( (numconfirms= LP_numconfirms(symbol,coinaddr,txid2,0)) <= 0 )
{
printf("LP_utxoadd reject2 numconfirms.%d\n",numconfirms);
return(0);
}
}
else
{
val = value;
val2 = value2;
}
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));
@ -631,7 +644,7 @@ struct LP_utxoinfo *LP_utxoadd(int32_t iambob,int32_t mypubsock,char *symbol,bit
if ( LP_ismine(utxo) > 0 )
utxo->T.sessionid = LP_sessionid;
else utxo->T.sessionid = sessionid;
if ( (selector= LP_mempool_vinscan(&spendtxid,&spendvini,symbol,txid,vout,txid2,vout2)) >= 0 )
if ( coin->inactive == 0 && (selector= LP_mempool_vinscan(&spendtxid,&spendvini,symbol,coinaddr,txid,vout,txid2,vout2)) >= 0 )
{
printf("utxoadd selector.%d spent in mempool %s vini.%d",selector,bits256_str(str,spendtxid),spendvini);
utxo->T.spentflag = (uint32_t)time(NULL);
@ -866,9 +879,9 @@ uint64_t LP_privkey_init(int32_t mypubsock,struct iguana_info *coin,bits256 mypr
//printf("array.%d\n",n);
while ( used < n-1 )
{
for (i=0; i<n; i++)
printf("%.8f ",dstr(values[i]));
printf("used.%d of n.%d\n",used,n);
//for (i=0; i<n; i++)
// printf("%.8f ",dstr(values[i]));
//printf("used.%d of n.%d\n",used,n);
if ( (i= LP_maxvalue(values,n)) >= 0 )
{
item = jitem(array,i);
@ -891,7 +904,7 @@ uint64_t LP_privkey_init(int32_t mypubsock,struct iguana_info *coin,bits256 mypr
else targetval = (depositval / 9) * 8 + 2*txfee;
if ( targetval < txfee*2 )
targetval = txfee*2;
printf("iambob.%d i.%d deposit %.8f min %.8f target %.8f\n",iambob,i,dstr(depositval),dstr((1+LP_MINSIZE_TXFEEMULT)*txfee),dstr(targetval));
//printf("iambob.%d i.%d deposit %.8f min %.8f target %.8f\n",iambob,i,dstr(depositval),dstr((1+LP_MINSIZE_TXFEEMULT)*txfee),dstr(targetval));
if ( depositval < (1+LP_MINSIZE_TXFEEMULT)*txfee )
continue;
i = -1;
@ -904,7 +917,7 @@ uint64_t LP_privkey_init(int32_t mypubsock,struct iguana_info *coin,bits256 mypr
}
if ( i >= 0 || (i= LP_nearestvalue(iambob,values,n,targetval)) >= 0 )
{
printf("iambob.%d i.%d %.8f target %.8f\n",iambob,i,dstr(depositval),dstr(targetval));
//printf("iambob.%d i.%d %.8f target %.8f\n",iambob,i,dstr(depositval),dstr(targetval));
item = jitem(array,i);
cmpflag = 0;
if ( coin->electrum == 0 )
@ -933,7 +946,7 @@ uint64_t LP_privkey_init(int32_t mypubsock,struct iguana_info *coin,bits256 mypr
}
else
{
printf("call utxoadd\n");
//printf("call utxoadd\n");
if ( (utxo= LP_utxoadd(0,mypubsock,coin->symbol,deposittxid,depositvout,depositval,txid,vout,value,script,coin->smartaddr,mypub,LP_gui,LP_sessionid)) != 0 )
{
}
@ -1041,7 +1054,7 @@ bits256 LP_privkeycalc(void *ctx,uint8_t *pubkey33,bits256 *pubkeyp,struct iguan
userpub = curve25519(userpass,curve25519_basepoint9());
printf("userpass.(%s)\n",bits256_str(USERPASS,userpub));
}
if ( (retjson= LP_importprivkey(coin->symbol,tmpstr,coin->smartaddr,-1)) != 0 )
if ( coin->electrum == 0 && (retjson= LP_importprivkey(coin->symbol,tmpstr,coin->smartaddr,-1)) != 0 )
{
if ( jobj(retjson,"error") != 0 )
{

Loading…
Cancel
Save