You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

671 lines
27 KiB

8 years ago
/******************************************************************************
* Copyright © 2014-2017 The SuperNET Developers. *
* *
* See the AUTHORS, DEVELOPER-AGREEMENT and LICENSE files at *
* the top-level directory of this distribution for the individual copyright *
* holder information and the developer policies on copyright and licensing. *
* *
* Unless otherwise agreed in a custom licensing agreement, no part of the *
* SuperNET software, including this file may be copied, modified, propagated *
* or distributed except according to the terms contained in the LICENSE file *
* *
* Removal or modification of this copyright notice is prohibited. *
* *
******************************************************************************/
//
// LP_utxos.c
// marketmaker
//
7 years ago
int32_t LP_ismine(struct LP_utxoinfo *utxo)
{
7 years ago
if ( bits256_cmp(utxo->pubkey,LP_mypubkey) != 0 )
7 years ago
return(1);
else if ( LP_mypeer == 0 )
return(0);
7 years ago
else return(0);
}
int32_t LP_isavailable(struct LP_utxoinfo *utxo)
{
if ( utxo->T.swappending == 0 && utxo->S.swap == 0 )
7 years ago
return(1);
else return(0);
}
7 years ago
int32_t LP_isunspent(struct LP_utxoinfo *utxo)
{
7 years ago
if ( utxo->T.spentflag == 0 && LP_isavailable(utxo) > 0 )
7 years ago
return(1);
else return(0);
}
7 years ago
void LP_utxosetkey(uint8_t *key,bits256 txid,int32_t vout)
8 years ago
{
memcpy(key,txid.bytes,sizeof(txid));
memcpy(&key[sizeof(txid)],&vout,sizeof(vout));
7 years ago
}
struct LP_utxoinfo *_LP_utxofind(int32_t iambob,bits256 txid,int32_t vout)
{
struct LP_utxoinfo *utxo=0; uint8_t key[sizeof(txid) + sizeof(vout)];
LP_utxosetkey(key,txid,vout);
HASH_FIND(hh,LP_utxoinfos[iambob],key,sizeof(key),utxo);
return(utxo);
}
struct LP_utxoinfo *_LP_utxo2find(int32_t iambob,bits256 txid2,int32_t vout2)
{
struct LP_utxoinfo *utxo=0; uint8_t key2[sizeof(txid2) + sizeof(vout2)];
LP_utxosetkey(key2,txid2,vout2);
HASH_FIND(hh2,LP_utxoinfos2[iambob],key2,sizeof(key2),utxo);
return(utxo);
}
struct LP_utxoinfo *LP_utxofind(int32_t iambob,bits256 txid,int32_t vout)
{
struct LP_utxoinfo *utxo=0;
8 years ago
portable_mutex_lock(&LP_utxomutex);
7 years ago
utxo = _LP_utxofind(iambob,txid,vout);
7 years ago
portable_mutex_unlock(&LP_utxomutex);
return(utxo);
}
7 years ago
struct LP_utxoinfo *LP_utxo2find(int32_t iambob,bits256 txid2,int32_t vout2)
7 years ago
{
7 years ago
struct LP_utxoinfo *utxo=0;
portable_mutex_lock(&LP_utxomutex);
utxo = _LP_utxo2find(iambob,txid2,vout2);
portable_mutex_unlock(&LP_utxomutex);
7 years ago
return(utxo);
}
7 years ago
struct LP_utxoinfo *LP_utxofinds(int32_t iambob,bits256 txid,int32_t vout,bits256 txid2,int32_t vout2)
{
struct LP_utxoinfo *utxo;
if ( (utxo= LP_utxofind(iambob,txid,vout)) != 0 || (utxo= LP_utxofind(iambob,txid2,vout2)) != 0 || (utxo= LP_utxo2find(iambob,txid,vout)) != 0 || (utxo= LP_utxo2find(iambob,txid2,vout2)) != 0 )
return(utxo);
else return(0);
}
7 years ago
int32_t LP_utxoaddptrs(struct LP_utxoinfo *ptrs[],int32_t n,struct LP_utxoinfo *utxo)
7 years ago
{
7 years ago
int32_t i;
for (i=0; i<n; i++)
if ( ptrs[i] == utxo )
return(n);
ptrs[n++] = utxo;
return(n);
}
int32_t LP_utxocollisions(struct LP_utxoinfo *ptrs[],struct LP_utxoinfo *refutxo)
{
int32_t iambob,n = 0; struct LP_utxoinfo *utxo; struct _LP_utxoinfo u;
7 years ago
portable_mutex_lock(&LP_utxomutex);
7 years ago
for (iambob=0; iambob<=1; iambob++)
{
if ( (utxo= _LP_utxofind(iambob,refutxo->payment.txid,refutxo->payment.vout)) != 0 && utxo != refutxo )
n = LP_utxoaddptrs(ptrs,n,utxo);
if ( (utxo= _LP_utxo2find(iambob,refutxo->payment.txid,refutxo->payment.vout)) != 0 && utxo != refutxo )
n = LP_utxoaddptrs(ptrs,n,utxo);
u = (refutxo->iambob != 0) ? refutxo->deposit : refutxo->fee;
if ( (utxo= _LP_utxofind(iambob,u.txid,u.vout)) != 0 && utxo != refutxo )
n = LP_utxoaddptrs(ptrs,n,utxo);
if ( (utxo= _LP_utxo2find(iambob,u.txid,u.vout)) != 0 && utxo != refutxo )
n = LP_utxoaddptrs(ptrs,n,utxo);
}
7 years ago
portable_mutex_unlock(&LP_utxomutex);
7 years ago
if ( n > 0 )
printf("LP_utxocollisions n.%d\n",n);
return(n);
}
void _LP_availableset(struct LP_utxoinfo *utxo)
{
if ( utxo != 0 )
{
memset(&utxo->S.otherpubkey,0,sizeof(utxo->S.otherpubkey));
utxo->S.swap = 0;
utxo->T.swappending = 0;
}
}
void _LP_unavailableset(struct LP_utxoinfo *utxo,bits256 otherpubkey)
{
if ( utxo != 0 )
{
utxo->T.swappending = (uint32_t)(time(NULL) + LP_RESERVETIME);
utxo->S.otherpubkey = otherpubkey;
}
}
void LP_unavailableset(struct LP_utxoinfo *utxo,bits256 otherpubkey)
{
struct LP_utxoinfo *ptrs[8]; int32_t i,n;
memset(ptrs,0,sizeof(ptrs));
if ( (n= LP_utxocollisions(ptrs,utxo)) > 0 )
{
for (i=0; i<n; i++)
_LP_unavailableset(ptrs[i],otherpubkey);
}
char str[65]; printf("UTXO RESERVED %s/v%d collisions.%d\n",bits256_str(str,utxo->payment.txid),utxo->payment.vout,n);
_LP_unavailableset(utxo,otherpubkey);
}
void LP_availableset(struct LP_utxoinfo *utxo)
{
struct LP_utxoinfo *ptrs[8]; int32_t i,n;
memset(ptrs,0,sizeof(ptrs));
if ( (n= LP_utxocollisions(ptrs,utxo)) > 0 )
{
for (i=0; i<n; i++)
_LP_availableset(ptrs[i]);
}
char str[65]; printf("UTXO AVAIL %s/v%d collisions.%d\n",bits256_str(str,utxo->payment.txid),utxo->payment.vout,n);
_LP_availableset(utxo);
}
int32_t LP_utxopurge(int32_t allutxos)
{
struct LP_utxoinfo *utxo,*tmp; int32_t iambob,n = 0;
portable_mutex_lock(&LP_utxomutex);
for (iambob=0; iambob<=1; iambob++)
{
HASH_ITER(hh,LP_utxoinfos[iambob],utxo,tmp)
{
if ( allutxos != 0 || LP_ismine(utxo) == 0 )
{
if ( LP_isavailable(utxo) == 0 )
{
HASH_DELETE(hh,LP_utxoinfos[iambob],utxo);
free(utxo);
} else n++;
} else n++;
}
HASH_ITER(hh,LP_utxoinfos2[iambob],utxo,tmp)
{
if ( allutxos != 0 || LP_ismine(utxo) == 0 )
{
if ( LP_isavailable(utxo) == 0 )
{
HASH_DELETE(hh,LP_utxoinfos2[iambob],utxo);
free(utxo);
} else n++;
} else n++;
}
}
portable_mutex_unlock(&LP_utxomutex);
return(n);
8 years ago
}
7 years ago
cJSON *LP_inventoryjson(cJSON *item,struct LP_utxoinfo *utxo)
8 years ago
{
7 years ago
struct _LP_utxoinfo u;
8 years ago
jaddstr(item,"coin",utxo->coin);
7 years ago
jaddnum(item,"now",time(NULL));
8 years ago
jaddstr(item,"address",utxo->coinaddr);
7 years ago
jaddbits256(item,"txid",utxo->payment.txid);
jaddnum(item,"vout",utxo->payment.vout);
jadd64bits(item,"value",utxo->payment.value);
jadd64bits(item,"satoshis",utxo->S.satoshis);
u = (utxo->iambob != 0) ? utxo->deposit : utxo->fee;
if ( bits256_nonz(u.txid) != 0 )
{
jaddbits256(item,"txid2",u.txid);
jaddnum(item,"vout2",u.vout);
jadd64bits(item,"value2",u.value);
}
if ( utxo->T.swappending != 0 )
jaddnum(item,"pending",utxo->T.swappending);
if ( utxo->iambob != 0 )
{
jaddbits256(item,"srchash",LP_mypubkey);
if ( bits256_nonz(utxo->S.otherpubkey) != 0 )
jaddbits256(item,"desthash",utxo->S.otherpubkey);
}
else
{
jaddbits256(item,"desthash",LP_mypubkey);
if ( bits256_nonz(utxo->S.otherpubkey) != 0 )
jaddbits256(item,"srchash",utxo->S.otherpubkey);
}
if ( utxo->S.swap != 0 )
7 years ago
jaddstr(item,"swap","in progress");
7 years ago
if ( utxo->T.spentflag != 0 )
jaddnum(item,"spent",utxo->T.spentflag);
7 years ago
return(item);
}
cJSON *LP_utxojson(struct LP_utxoinfo *utxo)
{
cJSON *item = cJSON_CreateObject();
item = LP_inventoryjson(item,utxo);
7 years ago
jaddbits256(item,"pubkey",utxo->pubkey);
jaddnum(item,"profit",utxo->S.profitmargin);
7 years ago
jaddstr(item,"base",utxo->coin);
jaddstr(item,"script",utxo->spendscript);
8 years ago
return(item);
}
7 years ago
char *LP_utxos(int32_t iambob,struct LP_peerinfo *mypeer,char *coin,int32_t lastn)
8 years ago
{
int32_t i,firsti; struct LP_utxoinfo *utxo,*tmp; cJSON *utxosjson = cJSON_CreateArray();
i = 0;
if ( lastn >= mypeer->numutxos )
firsti = -1;
else firsti = (mypeer->numutxos - lastn);
7 years ago
HASH_ITER(hh,LP_utxoinfos[iambob],utxo,tmp)
8 years ago
{
if ( i++ < firsti )
continue;
7 years ago
if ( (coin == 0 || coin[0] == 0 || strcmp(coin,utxo->coin) == 0) && utxo->T.spentflag == 0 )//&& LP_ismine(utxo) != 0 )
8 years ago
{
jaddi(utxosjson,LP_utxojson(utxo));
}
}
return(jprint(utxosjson,1));
}
7 years ago
void LP_spentnotify(struct LP_utxoinfo *utxo,int32_t selector)
{
7 years ago
cJSON *argjson; struct _LP_utxoinfo u;
utxo->T.spentflag = (uint32_t)time(NULL);
7 years ago
if ( LP_mypeer != 0 && LP_mypeer->numutxos > 0 )
LP_mypeer->numutxos--;
7 years ago
if ( LP_mypubsock >= 0 )
{
argjson = cJSON_CreateObject();
jaddstr(argjson,"method","checktxid");
7 years ago
jaddbits256(argjson,"txid",utxo->payment.txid);
jaddnum(argjson,"vout",utxo->payment.vout);
7 years ago
if ( selector != 0 )
{
7 years ago
if ( bits256_nonz(utxo->deposit.txid) != 0 )
u = utxo->deposit;
else u = utxo->fee;
jaddbits256(argjson,"checktxid",u.txid);
jaddnum(argjson,"checkvout",u.vout);
7 years ago
}
LP_send(LP_mypubsock,jprint(argjson,1),1);
}
}
char *LP_spentcheck(cJSON *argjson)
{
7 years ago
bits256 txid,checktxid; int32_t vout,checkvout; struct LP_utxoinfo *utxo; int32_t iambob,retval = 0;
7 years ago
txid = jbits256(argjson,"txid");
vout = jint(argjson,"vout");
7 years ago
for (iambob=0; iambob<=1; iambob++)
7 years ago
{
7 years ago
if ( (utxo= LP_utxofind(iambob,txid,vout)) != 0 && utxo->T.spentflag == 0 )
7 years ago
{
7 years ago
if ( jobj(argjson,"check") == 0 )
checktxid = txid, checkvout = vout;
else
{
checktxid = jbits256(argjson,"checktxid");
checkvout = jint(argjson,"checkvout");
}
if ( LP_txvalue(utxo->coin,checktxid,checkvout) == 0 )
{
//if ( LP_mypeer != 0 && LP_mypeer->numutxos > 0 )
// LP_mypeer->numutxos--;
utxo->T.spentflag = (uint32_t)time(NULL);
retval++;
//printf("indeed txid was spent\n");
}
7 years ago
}
7 years ago
}
if ( retval > 0 )
return(clonestr("{\"result\":\"marked as spent\"}"));
return(clonestr("{\"error\":\"cant find txid to check spent status\"}"));
7 years ago
}
7 years ago
int32_t LP_iseligible(int32_t iambob,char *coin,bits256 txid,int32_t vout,uint64_t satoshis,bits256 txid2,int32_t vout2)
7 years ago
{
7 years ago
uint64_t val,val2,threshold;
7 years ago
if ( (val= LP_txvalue(coin,txid,vout)) >= satoshis )
7 years ago
{
7 years ago
threshold = (iambob != 0) ? LP_DEPOSITSATOSHIS(satoshis) : LP_DEXFEE(satoshis);
7 years ago
if ( (val2= LP_txvalue(coin,txid2,vout2)) >= threshold )
7 years ago
{
7 years ago
//printf("val %.8f and val2 %.8f vs %.8f\n",dstr(val),dstr(val2),dstr(satoshis));
7 years ago
return(1);
7 years ago
} else printf("mismatched %s txid value2 %.8f < %.8f\n",coin,dstr(val2),dstr(LP_DEPOSITSATOSHIS(satoshis)));
7 years ago
} else printf("mismatched %s txid value %.8f < %.8f\n",coin,dstr(val),dstr(satoshis));
7 years ago
return(0);
}
7 years ago
struct LP_utxoinfo *LP_addutxo(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,double profitmargin)
8 years ago
{
7 years ago
uint64_t tmpsatoshis; int32_t spendvini,selector; bits256 spendtxid; struct _LP_utxoinfo u; struct LP_utxoinfo *utxo = 0;
7 years ago
char str[65],str2[65],str3[65]; printf("iambob.%d %s %s LP_addutxo.(%.8f %.8f) %s %s\n",iambob,bits256_str(str3,pubkey),symbol,dstr(value),dstr(value2),bits256_str(str,txid),bits256_str(str2,txid2));
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 )
8 years ago
{
7 years ago
printf("malformed addutxo %d %d %d %d %d %d %d %d %d\n", symbol == 0,spendscript == 0,coinaddr == 0,bits256_nonz(txid) == 0,bits256_nonz(txid2) == 0,vout < 0,vout2 < 0,value <= 0,value2 <= 0);
8 years ago
return(0);
}
7 years ago
if ( iambob != 0 && value2 < 9 * (value >> 3) + 100000 ) // big txfee padding
tmpsatoshis = (((value2 - 100000) / 9) << 3);
7 years ago
else tmpsatoshis = value;
7 years ago
if ( LP_iseligible(iambob,symbol,txid,vout,tmpsatoshis,txid2,vout2) <= 0 )
7 years ago
{
7 years ago
printf("LP_addutxo got spent txid value %.8f, value2 %.8f, tmpsatoshis %.8f\n",dstr(value),dstr(value2),dstr(tmpsatoshis));
7 years ago
return(0);
}
7 years ago
if ( (selector= LP_mempool_vinscan(&spendtxid,&spendvini,symbol,txid,vout,txid2,vout2)) >= 0 )
{
printf("LP_addutxo selector.%d in mempool %s vini.%d",selector,bits256_str(str,spendtxid),spendvini);
return(0);
}
if ( (utxo= LP_utxofinds(iambob,txid,vout,txid2,vout2)) != 0 )
8 years ago
{
7 years ago
//printf("%.8f %.8f %.8f vs utxo.(%.8f %.8f %.8f)\n",dstr(value),dstr(value2),dstr(tmpsatoshis),dstr(utxo->value),dstr(utxo->value2),dstr(utxo->satoshis));
7 years ago
u = (utxo->iambob != 0) ? utxo->deposit : utxo->fee;
7 years ago
if ( bits256_cmp(txid,utxo->payment.txid) != 0 || bits256_cmp(txid2,u.txid) != 0 || vout != utxo->payment.vout || value != utxo->payment.value || 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 )
8 years ago
{
7 years ago
utxo->T.errors++;
7 years ago
char str[65],str2[65],str3[65],str4[65]; printf("error on subsequent utxo add.(%s v %s) %d %d %d %d %d %d %d %d %d %d %d pubkeys.(%s vs %s)\n",bits256_str(str,txid),bits256_str(str2,utxo->payment.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(str3,pubkey),bits256_str(str4,utxo->pubkey));
8 years ago
}
else if ( profitmargin != 0. )
7 years ago
utxo->S.profitmargin = profitmargin;
8 years ago
}
else
{
utxo = calloc(1,sizeof(*utxo));
7 years ago
utxo->S.profitmargin = profitmargin;
utxo->pubkey = pubkey;
7 years ago
safecopy(utxo->coin,symbol,sizeof(utxo->coin));
8 years ago
safecopy(utxo->coinaddr,coinaddr,sizeof(utxo->coinaddr));
safecopy(utxo->spendscript,spendscript,sizeof(utxo->spendscript));
7 years ago
utxo->payment.txid = txid;
utxo->payment.vout = vout;
utxo->payment.value = value;
utxo->S.satoshis = tmpsatoshis;
if ( (utxo->iambob= iambob) != 0 )
{
utxo->deposit.txid = txid2;
utxo->deposit.vout = vout2;
utxo->deposit.value = value2;
}
else
{
utxo->fee.txid = txid2;
utxo->fee.vout = vout2;
utxo->fee.value = value2;
}
LP_utxosetkey(utxo->key,txid,vout);
LP_utxosetkey(utxo->key2,txid2,vout2);
char str[65],str2[65],str3[65]; printf("iambob.%d %s %s LP_addutxo.(%.8f %.8f) %s %s\n",iambob,bits256_str(str3,utxo->pubkey),utxo->coin,dstr(value),dstr(value2),bits256_str(str,utxo->payment.txid),bits256_str(str2,txid2));
8 years ago
portable_mutex_lock(&LP_utxomutex);
7 years ago
HASH_ADD_KEYPTR(hh,LP_utxoinfos[iambob],utxo->key,sizeof(utxo->key),utxo);
if ( _LP_utxo2find(iambob,txid2,vout2) == 0 )
HASH_ADD_KEYPTR(hh2,LP_utxoinfos2[iambob],utxo->key2,sizeof(utxo->key2),utxo);
8 years ago
portable_mutex_unlock(&LP_utxomutex);
if ( mypubsock >= 0 )
LP_send(mypubsock,jprint(LP_utxojson(utxo),1),1);
}
return(utxo);
}
7 years ago
int32_t LP_utxosparse(struct LP_peerinfo *mypeer,int32_t mypubsock,char *destipaddr,uint16_t destport,char *retstr,uint32_t now)
8 years ago
{
7 years ago
struct LP_peerinfo *destpeer; uint32_t argipbits; char *argipaddr; uint16_t argport,pushport,subport; cJSON *array,*item; int32_t i,n=0; bits256 txid; struct LP_utxoinfo *utxo;
if ( IAMLP == 0 )
8 years ago
{
printf("LP_utxosparse not for clientside\n");
return(-1);
}
if ( (array= cJSON_Parse(retstr)) != 0 )
{
if ( (n= cJSON_GetArraySize(array)) > 0 )
{
for (i=0; i<n; i++)
{
item = jitem(array,i);
7 years ago
if ( (argipaddr= jstr(item,"ipaddr")) != 0 && (argport= juint(item,"port")) != 0 )
8 years ago
{
if ( (pushport= juint(item,"push")) == 0 )
pushport = argport + 1;
if ( (subport= juint(item,"sub")) == 0 )
subport = argport + 2;
argipbits = (uint32_t)calc_ipbits(argipaddr);
7 years ago
//if ( (peer= LP_peerfind(argipbits,argport)) == 0 )
// peer = LP_addpeer(mypeer,mypubsock,argipaddr,argport,pushport,subport,jdouble(item,"profit"),jint(item,"numpeers"),jint(item,"numutxos"));
8 years ago
if ( jobj(item,"txid") != 0 )
{
txid = jbits256(item,"txid");
7 years ago
//printf("parse.(%s)\n",jprint(item,0));
7 years ago
utxo = LP_addutxo(1,mypubsock,jstr(item,"coin"),txid,jint(item,"vout"),j64bits(item,"value"),jbits256(item,"txid2"),jint(item,"vout2"),j64bits(item,"value2"),jstr(item,"script"),jstr(item,"address"),jbits256(item,"pubkey"),jdouble(item,"profit"));
8 years ago
if ( utxo != 0 )
7 years ago
{
7 years ago
utxo->T.lasttime = now;
7 years ago
}
8 years ago
}
7 years ago
} // else printf("skip.(%s)\n",jprint(item,0));
8 years ago
}
7 years ago
if ( (destpeer= LP_peerfind((uint32_t)calc_ipbits(destipaddr),destport)) != 0 )
8 years ago
{
7 years ago
destpeer->numutxos = n;
}
8 years ago
}
free_json(array);
}
return(n);
}
7 years ago
void LP_utxosquery(struct LP_peerinfo *mypeer,int32_t mypubsock,char *destipaddr,uint16_t destport,char *coin,int32_t lastn,char *myipaddr,uint16_t myport,double myprofit)
8 years ago
{
7 years ago
char *retstr; struct LP_peerinfo *peer; int32_t i,firsti; uint32_t now;
7 years ago
if ( IAMLP == 0 )
8 years ago
{
printf("LP_utxosquery not for clientside\n");
return;
}
peer = LP_peerfind((uint32_t)calc_ipbits(destipaddr),destport);
7 years ago
if ( mypeer == 0 ) //(peer != 0 && peer->errors > 0) ||
8 years ago
return;
if ( coin == 0 )
coin = "";
if ( (retstr= issue_LP_getutxos(destipaddr,destport,coin,lastn,myipaddr,myport,myprofit,mypeer->numpeers,mypeer->numutxos)) != 0 )
{
now = (uint32_t)time(NULL);
7 years ago
LP_utxosparse(mypeer,mypubsock,destipaddr,destport,retstr,now);
8 years ago
free(retstr);
i = 0;
if ( lastn >= mypeer->numutxos )
firsti = -1;
else firsti = (mypeer->numutxos - lastn);
7 years ago
/*HASH_ITER(hh,LP_utxoinfos,utxo,tmp)
8 years ago
{
if ( i++ < firsti )
continue;
if ( utxo->lasttime != now && strcmp(utxo->ipaddr,"127.0.0.1") != 0 )
{
char str[65]; printf("{%s:%u %s} ",utxo->ipaddr,utxo->port,bits256_str(str,utxo->txid));
flag++;
if ( (retstr= issue_LP_notifyutxo(destipaddr,destport,utxo)) != 0 )
free(retstr);
}
}
if ( flag != 0 )
7 years ago
printf(" <- missing utxos\n");*/
8 years ago
} else if ( peer != 0 )
peer->errors++;
}
7 years ago
cJSON *LP_inventory(char *symbol,int32_t iambob)
7 years ago
{
7 years ago
struct LP_utxoinfo *utxo,*tmp; char *myipaddr; cJSON *array;
array = cJSON_CreateArray();
7 years ago
if ( LP_mypeer != 0 )
myipaddr = LP_mypeer->ipaddr;
else myipaddr = "127.0.0.1";
7 years ago
HASH_ITER(hh,LP_utxoinfos[iambob],utxo,tmp)
7 years ago
{
7 years ago
//char str[65]; printf("iterate %s\n",bits256_str(str,utxo->txid));
7 years ago
if ( LP_isunspent(utxo) != 0 && strcmp(symbol,utxo->coin) == 0 && utxo->iambob == iambob && LP_ismine(utxo) != 0 )
7 years ago
jaddi(array,LP_inventoryjson(cJSON_CreateObject(),utxo));
}
7 years ago
return(array);
7 years ago
}
8 years ago
int32_t LP_maxvalue(uint64_t *values,int32_t n)
{
int32_t i,maxi = -1; uint64_t maxval = 0;
for (i=0; i<n; i++)
if ( values[i] > maxval )
{
maxi = i;
maxval = values[i];
}
return(maxi);
}
int32_t LP_nearestvalue(uint64_t *values,int32_t n,uint64_t targetval)
{
int32_t i,mini = -1; int64_t dist; uint64_t mindist = (1 << 31);
for (i=0; i<n; i++)
{
dist = (values[i] - targetval);
if ( dist < 0 && -dist < values[i]/10 )
dist = -dist;
if ( dist >= 0 && dist < mindist )
{
mini = i;
mindist = dist;
}
}
return(mini);
}
7 years ago
uint64_t LP_privkey_init(int32_t mypubsock,struct iguana_info *coin,bits256 myprivkey,bits256 mypub,uint8_t *pubkey33)
8 years ago
{
7 years ago
char *script; struct LP_utxoinfo *utxo; cJSON *array,*item; bits256 txid,deposittxid; int32_t used,i,n,iambob,vout,depositvout; uint64_t *values=0,satoshis,depositval,targetval,value,total = 0;
8 years ago
if ( coin == 0 )
{
7 years ago
printf("coin not active\n");
8 years ago
return(0);
}
7 years ago
printf("privkey init.(%s) %s\n",coin->symbol,coin->smartaddr);
7 years ago
if ( coin->inactive == 0 && (array= LP_listunspent(coin->symbol,coin->smartaddr)) != 0 )
8 years ago
{
if ( is_cJSON_Array(array) != 0 && (n= cJSON_GetArraySize(array)) > 0 )
{
7 years ago
for (iambob=0; iambob<=1; iambob++)
8 years ago
{
7 years ago
if ( iambob == 0 )
values = calloc(n,sizeof(*values));
else memset(values,0,n * sizeof(*values));
for (i=0; i<n; i++)
8 years ago
{
item = jitem(array,i);
7 years ago
satoshis = SATOSHIDEN * jdouble(item,"amount");
values[i] = satoshis;
//printf("%.8f ",dstr(satoshis));
}
//printf("array.%d\n",n);
used = 0;
while ( used < n-1 )
{
//printf("used.%d of n.%d\n",used,n);
if ( (i= LP_maxvalue(values,n)) >= 0 )
8 years ago
{
item = jitem(array,i);
7 years ago
deposittxid = jbits256(item,"txid");
depositvout = juint(item,"vout");
script = jstr(item,"scriptPubKey");
depositval = values[i];
values[i] = 0, used++;
if ( iambob == 0 )
targetval = (depositval / 776) + 100000;
else targetval = (depositval / 9) * 8 + 100000;
//printf("i.%d %.8f target %.8f\n",i,dstr(depositval),dstr(targetval));
if ( (i= LP_nearestvalue(values,n,targetval)) >= 0 )
8 years ago
{
7 years ago
item = jitem(array,i);
txid = jbits256(item,"txid");
vout = juint(item,"vout");
if ( jstr(item,"scriptPubKey") != 0 && strcmp(script,jstr(item,"scriptPubKey")) == 0 )
8 years ago
{
7 years ago
value = values[i];
values[i] = 0, used++;
if ( iambob != 0 )
7 years ago
{
7 years ago
if ( (utxo= LP_addutxo(1,mypubsock,coin->symbol,txid,vout,value,deposittxid,depositvout,depositval,script,coin->smartaddr,mypub,LP_peerinfos[0].profitmargin)) != 0 )
{
//utxo->S.mypub = curve25519(privkey,curve25519_basepoint9());
}
7 years ago
}
7 years ago
else
7 years ago
{
7 years ago
if ( (utxo= LP_addutxo(0,mypubsock,coin->symbol,deposittxid,depositvout,depositval,txid,vout,value,script,coin->smartaddr,mypub,0)) != 0 )
{
//utxo->S.mypub = curve25519(privkey,curve25519_basepoint9());
}
7 years ago
}
7 years ago
total += value;
8 years ago
}
}
7 years ago
} else break;
}
if ( iambob == 1 )
free(values);
8 years ago
}
}
free_json(array);
}
7 years ago
//printf("privkey.%s %.8f\n",symbol,dstr(total));
8 years ago
return(total);
}
7 years ago
bits256 LP_privkeycalc(uint8_t *pubkey33,bits256 *pubkeyp,struct iguana_info *coin,char *passphrase,char *wifstr)
{
static uint32_t counter;
bits256 privkey,userpub,userpass; char tmpstr[128]; cJSON *retjson; uint8_t tmptype,rmd160[20];
if ( passphrase != 0 )
conv_NXTpassword(privkey.bytes,pubkeyp->bytes,(uint8_t *)passphrase,(int32_t)strlen(passphrase));
else privkey = iguana_wif2privkey(wifstr);
iguana_priv2pub(pubkey33,coin->smartaddr,privkey,coin->pubtype);
if ( coin->counter == 0 )
{
coin->counter++;
bitcoin_priv2wif(tmpstr,privkey,coin->wiftype);
bitcoin_addr2rmd160(&tmptype,rmd160,coin->smartaddr);
LP_privkeyadd(privkey,rmd160);
printf("%s (%s) %d wif.(%s) (%s)\n",coin->symbol,coin->smartaddr,coin->pubtype,tmpstr,passphrase);
if ( counter++ == 0 )
{
7 years ago
bitcoin_priv2wif(USERPASS_WIFSTR,privkey,0);
7 years ago
conv_NXTpassword(userpass.bytes,pubkeyp->bytes,(uint8_t *)USERPASS_WIFSTR,(int32_t)strlen(USERPASS_WIFSTR));
userpub = curve25519(userpass,curve25519_basepoint9());
printf("userpass.(%s)\n",bits256_str(USERPASS,userpub));
}
if ( coin->inactive == 0 && (retjson= LP_importprivkey(coin->symbol,tmpstr,coin->smartaddr,-1)) != 0 )
printf("importprivkey -> (%s)\n",jprint(retjson,1));
}
LP_mypubkey = *pubkeyp = curve25519(privkey,curve25519_basepoint9());
return(privkey);
}
7 years ago
void LP_privkey_updates(int32_t pubsock,char *passphrase)
8 years ago
{
7 years ago
int32_t i; struct iguana_info *coin; bits256 pubkey,privkey; uint8_t pubkey33[33];
memset(privkey.bytes,0,sizeof(privkey));
pubkey = privkey;
7 years ago
for (i=0; i<LP_numcoins; i++)
7 years ago
{
7 years ago
//printf("i.%d of %d\n",i,LP_numcoins);
7 years ago
if ( (coin= LP_coinfind(LP_coins[i].symbol)) != 0 )
{
if ( bits256_nonz(privkey) == 0 || coin->smartaddr[0] == 0 )
privkey = LP_privkeycalc(pubkey33,&pubkey,coin,passphrase,"");
if ( coin->inactive == 0 )
7 years ago
LP_privkey_init(pubsock,coin,privkey,pubkey,pubkey33);
7 years ago
}
7 years ago
}
8 years ago
}