Browse Source

test

release/v0.1
jl777 9 years ago
parent
commit
8b02600f44
  1. 33
      basilisk/basilisk.c
  2. 254
      basilisk/basilisk_bitcoin.c
  3. 2
      iguana/iguana777.h
  4. 36
      iguana/iguana_payments.c
  5. 43
      iguana/iguana_unspents.c
  6. 4
      iguana/iguana_wallet.c
  7. 2
      iguana/tests/history
  8. 1
      includes/iguana_apideclares.h
  9. 2
      includes/iguana_funcs.h
  10. 5
      includes/iguana_structs.h

33
basilisk/basilisk.c

@ -308,9 +308,11 @@ struct basilisk_item *basilisk_issueremote(struct supernet_info *myinfo,struct i
strcpy(pending->CMD,CMD); strcpy(pending->CMD,CMD);
while ( OS_milliseconds() < pending->expiration ) while ( OS_milliseconds() < pending->expiration )
{ {
//if ( (retstr= basilisk_iscomplete(ptr)) != 0 ) if ( pending->numresults >= pending->numrequired )//|| (retstr= pending->retstr) != 0 )
if ( pending->numresults >= pending->numrequired || (retstr= pending->retstr) != 0 ) {
//printf("numresults.%d vs numrequired.%d\n",pending->numresults,pending->numrequired);
break; break;
}
usleep(10000); usleep(10000);
} }
if ( (retarray= pending->retarray) != 0 ) if ( (retarray= pending->retarray) != 0 )
@ -329,7 +331,8 @@ struct basilisk_item *basilisk_issueremote(struct supernet_info *myinfo,struct i
struct basilisk_item *basilisk_requestservice(struct supernet_info *myinfo,struct iguana_peer *addr,char *CMD,int32_t blockflag,cJSON *valsobj,bits256 hash,uint8_t *data,int32_t datalen,uint32_t nBits) struct basilisk_item *basilisk_requestservice(struct supernet_info *myinfo,struct iguana_peer *addr,char *CMD,int32_t blockflag,cJSON *valsobj,bits256 hash,uint8_t *data,int32_t datalen,uint32_t nBits)
{ {
int32_t minresults,timeoutmillis,numsent,delaymillis,encryptflag,fanout; struct basilisk_item *ptr; char buf[4096],*symbol,*str = 0; struct iguana_info *virt; int32_t numrequired,timeoutmillis,numsent,delaymillis,encryptflag,fanout; struct basilisk_item *ptr; char buf[4096],*symbol,*str = 0; struct iguana_info *virt;
//printf("request.(%s)\n",jprint(valsobj,0));
basilisk_addhexstr(&str,valsobj,buf,sizeof(buf),data,datalen); basilisk_addhexstr(&str,valsobj,buf,sizeof(buf),data,datalen);
if ( bits256_cmp(hash,GENESIS_PUBKEY) != 0 && bits256_nonz(hash) != 0 ) if ( bits256_cmp(hash,GENESIS_PUBKEY) != 0 && bits256_nonz(hash) != 0 )
{ {
@ -337,8 +340,8 @@ struct basilisk_item *basilisk_requestservice(struct supernet_info *myinfo,struc
jdelete(valsobj,"hash"); jdelete(valsobj,"hash");
jaddbits256(valsobj,"hash",hash); jaddbits256(valsobj,"hash",hash);
} }
if ( (minresults= jint(valsobj,"minresults")) <= 0 ) if ( (numrequired= jint(valsobj,"numrequired")) <= 0 )
minresults = 1; numrequired = 1;
if ( (timeoutmillis= jint(valsobj,"timeout")) == 0 ) if ( (timeoutmillis= jint(valsobj,"timeout")) == 0 )
timeoutmillis = BASILISK_TIMEOUT; timeoutmillis = BASILISK_TIMEOUT;
if ( jobj(valsobj,"fanout") == 0 ) if ( jobj(valsobj,"fanout") == 0 )
@ -357,7 +360,7 @@ struct basilisk_item *basilisk_requestservice(struct supernet_info *myinfo,struc
symbol = "BTCD"; symbol = "BTCD";
encryptflag = jint(valsobj,"encrypt"); encryptflag = jint(valsobj,"encrypt");
delaymillis = jint(valsobj,"delay"); delaymillis = jint(valsobj,"delay");
ptr = basilisk_issueremote(myinfo,addr,&numsent,CMD,symbol,blockflag,valsobj,fanout,minresults,0,timeoutmillis,0,0,encryptflag,delaymillis,nBits); ptr = basilisk_issueremote(myinfo,addr,&numsent,CMD,symbol,blockflag,valsobj,fanout,numrequired,0,timeoutmillis,0,0,encryptflag,delaymillis,nBits);
return(ptr); return(ptr);
} }
@ -863,7 +866,7 @@ void basilisk_requests_poll(struct supernet_info *myinfo)
void basilisks_loop(void *arg) void basilisks_loop(void *arg)
{ {
struct iguana_info *virt,*tmpcoin,*btcd; struct basilisk_message *msg,*tmpmsg; struct basilisk_item *tmp,*pending; uint32_t now; int32_t iter,maxmillis,flag=0; struct supernet_info *myinfo = arg; struct iguana_info *virt,*tmpcoin,*coin,*btcd; struct basilisk_message *msg,*tmpmsg; struct basilisk_item *tmp,*pending; uint32_t now; int32_t i,iter,maxmillis,flag=0; struct supernet_info *myinfo = arg;
iter = 0; iter = 0;
while ( 1 ) while ( 1 )
{ {
@ -896,10 +899,17 @@ void basilisks_loop(void *arg)
if ( (rand() % 100) == 0 && myinfo->RELAYID >= 0 ) if ( (rand() % 100) == 0 && myinfo->RELAYID >= 0 )
basilisk_ping_send(myinfo,btcd); basilisk_ping_send(myinfo,btcd);
} }
//fprintf(stderr,"i "); HASH_ITER(hh,myinfo->allcoins,coin,tmpcoin)
//for (i=0; i<IGUANA_MAXCOINS; i++) {
// if ( (coin= Coins[i]) != 0 && coin->RELAYNODE == 0 && coin->VALIDATENODE == 0 && coin->active != 0 && coin->chain->userpass[0] != 0 && coin->MAXPEERS == 1 ) if ( coin->RELAYNODE == 0 && coin->VALIDATENODE == 0 )
// basilisk_bitcoinscan(coin,blockspace,&RAWMEM); {
for (i=0; i<BASILISK_MAXRELAYS; i++)
if ( coin->relay_RTheights[i] != 0 )
break;
if ( i == BASILISK_MAXRELAYS || (time(NULL) % 60) == 0 )
basilisk_unspents_update(myinfo,coin);
}
}
if ( (myinfo->RELAYID >= 0 || time(NULL) < myinfo->DEXactive) ) if ( (myinfo->RELAYID >= 0 || time(NULL) < myinfo->DEXactive) )
basilisk_requests_poll(myinfo); basilisk_requests_poll(myinfo);
now = (uint32_t)time(NULL); now = (uint32_t)time(NULL);
@ -923,6 +933,7 @@ void basilisks_loop(void *arg)
void basilisks_init(struct supernet_info *myinfo) void basilisks_init(struct supernet_info *myinfo)
{ {
iguana_initQ(&myinfo->msgQ,"messageQ"); iguana_initQ(&myinfo->msgQ,"messageQ");
portable_mutex_init(&myinfo->bu_mutex);
portable_mutex_init(&myinfo->allcoins_mutex); portable_mutex_init(&myinfo->allcoins_mutex);
portable_mutex_init(&myinfo->basilisk_mutex); portable_mutex_init(&myinfo->basilisk_mutex);
portable_mutex_init(&myinfo->DEX_mutex); portable_mutex_init(&myinfo->DEX_mutex);

254
basilisk/basilisk_bitcoin.c

@ -783,32 +783,6 @@ cJSON *BTC_makeclaimfunc(struct supernet_info *myinfo,struct exchange_info *exch
#include "../includes/iguana_apidefs.h" #include "../includes/iguana_apidefs.h"
#include "../includes/iguana_apideclares.h" #include "../includes/iguana_apideclares.h"
HASH_ARRAY_STRING(basilisk,balances,hash,vals,hexstr)
{
char *retstr=0,*symbol; uint32_t basilisktag; struct basilisk_item *ptr,Lptr; int32_t timeoutmillis;
if ( coin == 0 )
{
if ( (symbol= jstr(vals,"symbol")) != 0 || (symbol= jstr(vals,"coin")) != 0 )
coin = iguana_coinfind(symbol);
}
if ( coin != 0 && vals != 0 )
{
if ( jobj(vals,"addresses") == 0 )
jadd(vals,"addresses",iguana_getaddressesbyaccount(myinfo,coin,"*"));
if ( (basilisktag= juint(vals,"basilisktag")) == 0 )
basilisktag = rand();
if ( (timeoutmillis= juint(vals,"timeout")) <= 0 )
timeoutmillis = BASILISK_TIMEOUT;
if ( coin->RELAYNODE != 0 && (ptr= basilisk_bitcoinbalances(&Lptr,myinfo,coin,remoteaddr,basilisktag,timeoutmillis,vals)) != 0 )
{
retstr = ptr->retstr, ptr->retstr = 0;
ptr->finished = (uint32_t)time(NULL);
return(retstr);
}
}
return(basilisk_standardservice("BAL",myinfo,0,hash,vals,hexstr,1));
}
HASH_ARRAY_STRING(basilisk,value,hash,vals,hexstr) HASH_ARRAY_STRING(basilisk,value,hash,vals,hexstr)
{ {
char *retstr=0,*symbol; uint32_t basilisktag; struct basilisk_item *ptr,Lptr; int32_t timeoutmillis; char *retstr=0,*symbol; uint32_t basilisktag; struct basilisk_item *ptr,Lptr; int32_t timeoutmillis;
@ -817,6 +791,8 @@ HASH_ARRAY_STRING(basilisk,value,hash,vals,hexstr)
if ( (symbol= jstr(vals,"symbol")) != 0 || (symbol= jstr(vals,"coin")) != 0 ) if ( (symbol= jstr(vals,"symbol")) != 0 || (symbol= jstr(vals,"coin")) != 0 )
coin = iguana_coinfind(symbol); coin = iguana_coinfind(symbol);
} }
if ( jobj(vals,"fanout") == 0 )
jaddnum(vals,"fanout",8);
if ( coin != 0 ) if ( coin != 0 )
{ {
if ( (basilisktag= juint(vals,"basilisktag")) == 0 ) if ( (basilisktag= juint(vals,"basilisktag")) == 0 )
@ -841,6 +817,8 @@ HASH_ARRAY_STRING(basilisk,rawtx,hash,vals,hexstr)
if ( (symbol= jstr(vals,"symbol")) != 0 || (symbol= jstr(vals,"coin")) != 0 ) if ( (symbol= jstr(vals,"symbol")) != 0 || (symbol= jstr(vals,"coin")) != 0 )
coin = iguana_coinfind(symbol); coin = iguana_coinfind(symbol);
} }
if ( jobj(vals,"fanout") == 0 )
jaddnum(vals,"fanout",8);
if ( coin != 0 ) if ( coin != 0 )
{ {
if ( juint(vals,"burn") == 0 ) if ( juint(vals,"burn") == 0 )
@ -887,4 +865,228 @@ HASH_ARRAY_STRING(basilisk,rawtx,hash,vals,hexstr)
} }
return(retstr); return(retstr);
} }
HASH_ARRAY_STRING(basilisk,balances,hash,vals,hexstr)
{
char *retstr=0,*symbol; uint32_t basilisktag; struct basilisk_item *ptr,Lptr; int32_t timeoutmillis;
if ( vals == 0 )
return(clonestr("{\"error\":\"need vals object\"}"));
if ( coin == 0 )
{
if ( (symbol= jstr(vals,"symbol")) != 0 || (symbol= jstr(vals,"coin")) != 0 )
coin = iguana_coinfind(symbol);
}
if ( jobj(vals,"fanout") == 0 )
jaddnum(vals,"fanout",8);
if ( jobj(vals,"numrequired") == 0 )
jaddnum(vals,"numrequired",myinfo->numrelays);
//printf("vals.(%s)\n",jprint(vals,0));
if ( coin != 0 )
{
if ( jobj(vals,"addresses") == 0 )
jadd(vals,"addresses",iguana_getaddressesbyaccount(myinfo,coin,"*"));
if ( (basilisktag= juint(vals,"basilisktag")) == 0 )
basilisktag = rand();
if ( (timeoutmillis= juint(vals,"timeout")) <= 0 )
timeoutmillis = BASILISK_TIMEOUT;
if ( (coin->RELAYNODE != 0 || coin->VALIDATENODE != 0) && (ptr= basilisk_bitcoinbalances(&Lptr,myinfo,coin,remoteaddr,basilisktag,timeoutmillis,vals)) != 0 )
{
retstr = ptr->retstr, ptr->retstr = 0;
ptr->finished = (uint32_t)time(NULL);
return(retstr);
}
}
return(basilisk_standardservice("BAL",myinfo,0,hash,vals,hexstr,1));
}
HASH_ARRAY_STRING(basilisk,history,hash,vals,hexstr)
{
struct basilisk_unspent *bu; int32_t i; int64_t total = 0; struct iguana_waccount *wacct,*tmp; struct iguana_waddress *waddr,*tmp2; char coinaddr[64],*symbol; cJSON *retjson,*array,*item,*details;
if ( vals == 0 )
return(clonestr("{\"error\":\"need vals object\"}"));
if ( coin == 0 )
{
if ( (symbol= jstr(vals,"symbol")) != 0 || (symbol= jstr(vals,"coin")) != 0 )
coin = iguana_coinfind(symbol);
}
array = cJSON_CreateArray();
portable_mutex_lock(&myinfo->bu_mutex);
HASH_ITER(hh,myinfo->wallet,wacct,tmp)
{
HASH_ITER(hh,wacct->waddr,waddr,tmp2)
{
for (i=0; i<waddr->numunspents; i++)
{
bu = &waddr->unspents[i];
if ( strcmp(bu->symbol,coin->symbol) == 0 )
{
bitcoin_address(coinaddr,coin->chain->pubtype,waddr->rmd160,sizeof(waddr->rmd160));
item = cJSON_CreateObject();
jaddstr(item,"address",coinaddr);
jaddnum(item,"amount",dstr(bu->value));
jaddnum(item,"numseconds",time(NULL) - bu->timestamp);
details = cJSON_CreateObject();
jaddbits256(details,"txid",bu->txid);
jaddnum(details,"vout",bu->vout);
jaddnum(details,"height",bu->height);
if ( bu->spentheight != 0 )
jaddnum(details,"spentheight",bu->spentheight);
else total += bu->value;
jaddnum(details,"relays",bitweight(bu->relaymask));
jadd(item,"details",details);
jaddi(array,item);
}
}
//printf("%s numunspents.%d\n",waddr->coinaddr,waddr->numunspents);
}
}
portable_mutex_unlock(&myinfo->bu_mutex);
retjson = cJSON_CreateObject();
jaddstr(retjson,"result","success");
jadd(retjson,"history",array);
jaddstr(retjson,"coin",coin->symbol);
jaddnum(retjson,"balance",dstr(total));
return(jprint(retjson,1));
}
#include "../includes/iguana_apiundefs.h" #include "../includes/iguana_apiundefs.h"
int32_t basilisk_unspentfind(struct supernet_info *myinfo,struct iguana_info *coin,bits256 *txidp,int32_t *voutp,uint8_t *spendscript,int16_t hdrsi,uint32_t unspentind,int64_t value)
{
struct basilisk_unspent *bu; int32_t i,spendlen; struct iguana_waccount *wacct,*tmp; struct iguana_waddress *waddr,*tmp2;
memset(txidp,0,sizeof(*txidp));
*voutp = -1;
portable_mutex_lock(&myinfo->bu_mutex);
HASH_ITER(hh,myinfo->wallet,wacct,tmp)
{
HASH_ITER(hh,wacct->waddr,waddr,tmp2)
{
for (i=0; i<waddr->numunspents; i++)
{
bu = &waddr->unspents[i];
if ( bu->hdrsi == hdrsi && bu->unspentind == unspentind && bu->value == value )
{
*txidp = bu->txid;
*voutp = bu->vout;
memcpy(spendscript,bu->script,bu->spendlen);
spendlen = bu->spendlen;
portable_mutex_unlock(&myinfo->bu_mutex);
return(spendlen);
}
}
}
}
portable_mutex_unlock(&myinfo->bu_mutex);
return(-1);
}
void basilisk_unspent_update(struct supernet_info *myinfo,struct iguana_info *coin,cJSON *item,int32_t spentheight,int32_t relayid,int32_t RTheight)
{
//{"txid":"4814dc8a357f93f16271eb43806a69416ec41ab1956b128d170402b0a1b37c7f","vout":2,"address":"RSyKVKNxrSDc1Vwvh4guYb9ZDEpvMFz2rm","scriptPubKey":"76a914c210f6711e98fe9971757ede2b2dcb0507f3f25e88ac","amount":9.99920000,"timestamp":1466684518,"height":1160306,"confirmations":22528,"checkind":1157,"spent":{"hdrsi":2320,"pkind":168,"unspentind":1157,"prevunspentind":0,"satoshis":"999920000","txidind":619,"vout":2,"type":2,"fileid":0,"scriptpos":0,"scriptlen":25},"spentheight":1161800,"dest":{"error":"couldnt find spent info"}}
int32_t i,n,already_spent=0; struct basilisk_unspent bu,bu2; char *address,*script; struct iguana_waccount *wacct; struct iguana_waddress *waddr;
if ( (address= jstr(item,"address")) != 0 && (script= jstr(item,"scriptPubKey")) != 0 && (waddr= iguana_waddresssearch(myinfo,&wacct,address)) != 0 )
{
if ( relayid >= 64 )
relayid = 0;
memset(&bu,0,sizeof(bu));
bu.spendlen = (int32_t)strlen(script) >> 1;
if ( bu.spendlen > sizeof(bu.script) )
{
printf("spendscript too big.%d\n",bu.spendlen);
return;
}
strcpy(bu.symbol,coin->symbol);
bu.txid = jbits256(item,"txid");
bu.vout = jint(item,"vout");
bu.value = jdouble(item,"amount") * SATOSHIDEN;
bu.height = jint(item,"height");
bu.hdrsi = (bu.height / coin->chain->bundlesize);
bu.unspentind = juint(item,"checkind");
bu.timestamp = juint(item,"timestamp");
decode_hex(bu.script,bu.spendlen,script);
n = waddr->numunspents;
for (i=0; i<n; i++)
{
bu2 = waddr->unspents[i];
bu2.status = 0;
bu2.RTheight = bu2.spentheight = 0;
bu2.relaymask = 0;
if ( memcmp(&bu,&bu2,sizeof(bu)) == 0 )
{
if ( waddr->unspents[i].RTheight > RTheight )
RTheight = waddr->unspents[i].RTheight;
already_spent = waddr->unspents[i].spentheight;
bu.relaymask = waddr->unspents[i].relaymask;
break;
}
}
bu.RTheight = RTheight;
bu.relaymask |= ((uint64_t)1 << relayid);
//printf("relayid.%d -> %llx wt.%d\n",relayid,(long long)bu.relaymask,bitweight(bu.relaymask));
if ( spentheight != 0 )
already_spent = spentheight;
if ( (bu.spentheight= already_spent) != 0 )
bu.status = 1;
if ( i == n )
{
if ( i >= waddr->maxunspents )
{
waddr->maxunspents += 16;
waddr->unspents = realloc(waddr->unspents,sizeof(*waddr->unspents) * waddr->maxunspents);
printf("allocate max.%d for %s\n",waddr->maxunspents,waddr->coinaddr);
}
waddr->numunspents++;
printf("new unspent.%s %d script.%p [%d]\n",waddr->coinaddr,waddr->numunspents,bu.script,bu.spendlen);
}
waddr->unspents[i] = bu;
}
}
void basilisk_unspents_update(struct supernet_info *myinfo,struct iguana_info *coin)
{
char *retstr; cJSON *retarray,*vals,*relayjson,*unspents,*spends; int32_t oldest,i,j,n,num,RTheight,relayid;
if ( coin->RELAYNODE == 0 && coin->VALIDATENODE == 0 )
{
vals = cJSON_CreateObject();
for (i=oldest=0; i<BASILISK_MAXRELAYS; i++)
if ( (RTheight= coin->relay_RTheights[i]) != 0 && (oldest == 0 || RTheight < oldest) )
oldest = RTheight;
jaddnum(vals,"firstheight",oldest);
jaddnum(vals,"history",3);
if ( (retstr= basilisk_balances(myinfo,coin,0,0,GENESIS_PUBKEY,vals,"")) != 0 )
{
//printf("GOT.(%s)\n",retstr);
portable_mutex_lock(&myinfo->bu_mutex);
if ( (retarray= cJSON_Parse(retstr)) != 0 && (n= cJSON_GetArraySize(retarray)) > 0 )
{
if ( jobj(retarray,"error") == 0 )
{
for (i=0; i<n; i++)
{
relayjson = jitem(retarray,i);
RTheight = jint(relayjson,"RTheight");
if ( (relayid= basilisk_relayid(myinfo,(uint32_t)calc_ipbits(jstr(relayjson,"relay")))) < BASILISK_MAXRELAYS )
{
coin->relay_RTheights[relayid] = RTheight;
}
//printf("relayid.%d RT.%d\n",relayid,RTheight);
if ( (unspents= jarray(&num,relayjson,"unspents")) != 0 )
{
for (j=0; j<num; j++)
basilisk_unspent_update(myinfo,coin,jitem(unspents,j),0,relayid,RTheight);
}
if ( (spends= jarray(&num,relayjson,"spends")) != 0 )
{
for (j=0; j<num; j++)
basilisk_unspent_update(myinfo,coin,jitem(spends,j),jint(jitem(spends,j),"spentheight"),relayid,RTheight);
}
}
}
}
if ( retarray != 0 )
free_json(retarray);
free(retstr);
portable_mutex_unlock(&myinfo->bu_mutex);
}
free_json(vals);
}
}

2
iguana/iguana777.h

@ -52,7 +52,7 @@ struct supernet_info
struct exchange_info *tradingexchanges[SUPERNET_MAXEXCHANGES]; int32_t numexchanges; struct exchange_info *tradingexchanges[SUPERNET_MAXEXCHANGES]; int32_t numexchanges;
struct iguana_waccount *wallet; struct iguana_waccount *wallet;
struct iguana_info *allcoins; int32_t allcoins_being_added,allcoins_numvirts; struct iguana_info *allcoins; int32_t allcoins_being_added,allcoins_numvirts;
portable_mutex_t allcoins_mutex,gecko_mutex,basilisk_mutex,DEX_mutex,DEX_reqmutex,DEX_swapmutex; portable_mutex_t bu_mutex,allcoins_mutex,gecko_mutex,basilisk_mutex,DEX_mutex,DEX_reqmutex,DEX_swapmutex;
struct queueitem *DEX_quotes; struct queueitem *DEX_quotes;
struct basilisk_swap *swaps[256]; int32_t numswaps; struct basilisk_swap *swaps[256]; int32_t numswaps;
struct basilisk_message *messagetable; portable_mutex_t messagemutex; queue_t msgQ; struct basilisk_message *messagetable; portable_mutex_t messagemutex; queue_t msgQ;

36
iguana/iguana_payments.c

@ -200,9 +200,21 @@ int32_t iguana_bestunspent(struct iguana_info *coin,int32_t *aboveip,int64_t *ab
return(abovei >= 0 ? abovei : belowi); return(abovei >= 0 ? abovei : belowi);
} }
cJSON *iguana_inputjson(bits256 txid,int32_t vout,uint8_t *spendscript,int32_t spendlen)
{
char hexstr[IGUANA_MAXSCRIPTSIZE*2 + 1]; cJSON *sobj,*item = cJSON_CreateObject();
jaddbits256(item,"txid",txid);
jaddnum(item,"vout",vout);
sobj = cJSON_CreateObject();
init_hexbytes_noT(hexstr,spendscript,spendlen);
jaddstr(sobj,"hex",hexstr);
jadd(item,"scriptPubKey",sobj);
return(item);
}
cJSON *iguana_inputsjson(struct supernet_info *myinfo,struct iguana_info *coin,int64_t *totalp,uint64_t amount,int64_t *unspents,int32_t num) cJSON *iguana_inputsjson(struct supernet_info *myinfo,struct iguana_info *coin,int64_t *totalp,uint64_t amount,int64_t *unspents,int32_t num)
{ {
cJSON *item,*vins,*sobj; uint8_t spendscript[IGUANA_MAXSCRIPTSIZE]; struct iguana_txid *T; struct iguana_unspent *U,*u; struct iguana_bundle *bp; struct iguana_ramchain *ramchain; char coinaddr[64],hexstr[IGUANA_MAXSCRIPTSIZE*2+1]; int32_t height,abovei,belowi,i,spendlen,ind,hdrsi; uint32_t txidind,unspentind; struct iguana_ramchaindata *rdata; int64_t value,above,below,total = 0; int64_t remains = amount; cJSON *vins; uint8_t spendscript[IGUANA_MAXSCRIPTSIZE]; struct iguana_txid *T; struct iguana_unspent *U,*u; struct iguana_bundle *bp; struct iguana_ramchain *ramchain; char coinaddr[64]; int32_t vout,height,abovei,belowi,i,spendlen,ind,hdrsi; uint32_t txidind,unspentind; struct iguana_ramchaindata *rdata; bits256 txid; int64_t value,above,below,total = 0; int64_t remains = amount;
*totalp = 0; *totalp = 0;
vins = cJSON_CreateArray(); vins = cJSON_CreateArray();
for (i=0; i<num; i++) for (i=0; i<num; i++)
@ -221,6 +233,19 @@ cJSON *iguana_inputsjson(struct supernet_info *myinfo,struct iguana_info *coin,i
unspentind = (uint32_t)unspents[(ind << 1)]; unspentind = (uint32_t)unspents[(ind << 1)];
value = unspents[(ind << 1) + 1]; value = unspents[(ind << 1) + 1];
unspents[(ind << 1) + 1] = -1; unspents[(ind << 1) + 1] = -1;
if ( coin->RELAYNODE == 0 && coin->VALIDATENODE == 0 )
{
if ( (spendlen= basilisk_unspentfind(myinfo,coin,&txid,&vout,spendscript,hdrsi,unspentind,value)) > 0 )
{
jaddi(vins,iguana_inputjson(txid,vout,spendscript,spendlen));
total += value;
remains -= value;
//printf("%s value %.8f -> remains %.8f\n",coinaddr,dstr(value),dstr(remains));
if ( remains <= 0 )
break;
}
continue;
}
if ( (bp= coin->bundles[hdrsi]) == 0 ) if ( (bp= coin->bundles[hdrsi]) == 0 )
{ {
printf("no bundle.[%d]\n",hdrsi); printf("no bundle.[%d]\n",hdrsi);
@ -239,14 +264,7 @@ cJSON *iguana_inputsjson(struct supernet_info *myinfo,struct iguana_info *coin,i
{ {
if ( iguana_unspentindfind(coin,coinaddr,spendscript,&spendlen,&amount,&height,T[txidind].txid,u->vout,coin->bundlescount-1,0) == unspentind && spendlen > 0 ) if ( iguana_unspentindfind(coin,coinaddr,spendscript,&spendlen,&amount,&height,T[txidind].txid,u->vout,coin->bundlescount-1,0) == unspentind && spendlen > 0 )
{ {
item = cJSON_CreateObject(); jaddi(vins,iguana_inputjson(T[txidind].txid,u->vout,spendscript,spendlen));
jaddbits256(item,"txid",T[txidind].txid);
jaddnum(item,"vout",u->vout);
sobj = cJSON_CreateObject();
init_hexbytes_noT(hexstr,spendscript,spendlen);
jaddstr(sobj,"hex",hexstr);
jadd(item,"scriptPubKey",sobj);
jaddi(vins,item);
total += value; total += value;
remains -= value; remains -= value;
//printf("%s value %.8f -> remains %.8f\n",coinaddr,dstr(value),dstr(remains)); //printf("%s value %.8f -> remains %.8f\n",coinaddr,dstr(value),dstr(remains));

43
iguana/iguana_unspents.c

@ -506,7 +506,7 @@ uint8_t *iguana_rmdarray(struct supernet_info *myinfo,struct iguana_info *coin,i
int32_t iguana_unspentslists(struct supernet_info *myinfo,struct iguana_info *coin,int64_t *totalp,int64_t *unspents,int32_t max,int64_t required,int32_t minconf,cJSON *addresses,char *remoteaddr) int32_t iguana_unspentslists(struct supernet_info *myinfo,struct iguana_info *coin,int64_t *totalp,int64_t *unspents,int32_t max,int64_t required,int32_t minconf,cJSON *addresses,char *remoteaddr)
{ {
int64_t remains,total,sum = 0; int32_t i,n,numunspents,numaddrs; uint8_t addrtype,pubkey[65],rmd160[20]; char *coinaddr; int64_t total,sum = 0; int32_t i,n,numunspents,numaddrs; uint8_t addrtype,pubkey[65],rmd160[20]; char *coinaddr; struct iguana_waddress *waddr; struct iguana_waccount *wacct; struct basilisk_unspent *bu;
*totalp = 0; *totalp = 0;
if ( (numaddrs= cJSON_GetArraySize(addresses)) == 0 ) if ( (numaddrs= cJSON_GetArraySize(addresses)) == 0 )
{ {
@ -514,7 +514,7 @@ int32_t iguana_unspentslists(struct supernet_info *myinfo,struct iguana_info *co
return(0); return(0);
} }
memset(pubkey,0,sizeof(pubkey)); memset(pubkey,0,sizeof(pubkey));
remains = required * 1.1 + coin->txfee; //remains = required * 1.1 + coin->txfee;
for (i=numunspents=0; i<numaddrs; i++) for (i=numunspents=0; i<numaddrs; i++)
{ {
if ( (coinaddr= jstri(addresses,i)) != 0 ) if ( (coinaddr= jstri(addresses,i)) != 0 )
@ -522,17 +522,38 @@ int32_t iguana_unspentslists(struct supernet_info *myinfo,struct iguana_info *co
//printf("i.%d coinaddr.(%s) minconf.%d longest.%d diff.%d\n",i,coinaddr,minconf,coin->longestchain,coin->blocks.hwmchain.height - minconf); //printf("i.%d coinaddr.(%s) minconf.%d longest.%d diff.%d\n",i,coinaddr,minconf,coin->longestchain,coin->blocks.hwmchain.height - minconf);
total = 0; total = 0;
n = 0; n = 0;
bitcoin_addr2rmd160(&addrtype,rmd160,coinaddr); if ( coin->RELAYNODE != 0 || coin->VALIDATENODE != 0 )
iguana_pkhasharray(myinfo,coin,0,minconf,coin->longestchain,&total,0,coin->bundlescount,rmd160,coinaddr,pubkey,coin->blocks.hwmchain.height - minconf,unspents,&n,max-1000,remoteaddr);
//printf("n.%d max.%d total %.8f\n",n,max,dstr(total));
if ( n > 0 )
{ {
sum += total; bitcoin_addr2rmd160(&addrtype,rmd160,coinaddr);
unspents += (n << 1); iguana_pkhasharray(myinfo,coin,0,minconf,coin->longestchain,&total,0,coin->bundlescount,rmd160,coinaddr,pubkey,coin->blocks.hwmchain.height - minconf,unspents,&n,max-1000,remoteaddr);
numunspents += n; if ( n > 0 )
if ( numunspents > max ) {
break; sum += total;
unspents += (n << 1);
numunspents += n;
}
}
else
{
if ( (waddr= iguana_waddresssearch(myinfo,&wacct,coinaddr)) != 0 )
{
for (i=0; i<waddr->numunspents; i++)
{
bu = &waddr->unspents[i];
if ( bu->status == 0 )
{
unspents[0] = ((uint64_t)bu->hdrsi << 32) | bu->unspentind;
unspents[1] = bu->value;
sum += bu->value;
unspents++;
numunspents++;
}
}
}
} }
if ( numunspents > max )
break;
//printf("n.%d max.%d total %.8f\n",n,max,dstr(total));
} }
} }
*totalp = sum; *totalp = sum;

4
iguana/iguana_wallet.c

@ -687,9 +687,10 @@ uint8_t iguana_waddrvalidate(struct supernet_info *myinfo,struct iguana_info *co
cJSON *iguana_walletiterate(struct supernet_info *myinfo,struct iguana_info *coin,int32_t flag,cJSON *array,int32_t *goodp,int32_t *badp,int32_t *errors) cJSON *iguana_walletiterate(struct supernet_info *myinfo,struct iguana_info *coin,int32_t flag,cJSON *array,int32_t *goodp,int32_t *badp,int32_t *errors)
{ {
struct iguana_waccount *wacct,*tmp; struct iguana_waddress *waddr=0,*tmp2; uint8_t errorflags; int32_t i,good=0,bad=0,_errors[8]; cJSON *item; char coinaddr[64]; struct iguana_waccount *wacct,*tmp; struct iguana_waddress *waddr=0,*tmp2; uint8_t errorflags; int32_t i,good=0,bad=0,_errors[8]; cJSON *item; char coinaddr[64];
if ( errors == 0 ) if ( errors == 0 )
errors = _errors; errors = _errors;
portable_mutex_lock(&myinfo->bu_mutex);
HASH_ITER(hh,myinfo->wallet,wacct,tmp) HASH_ITER(hh,myinfo->wallet,wacct,tmp)
{ {
HASH_ITER(hh,wacct->waddr,waddr,tmp2) HASH_ITER(hh,wacct->waddr,waddr,tmp2)
@ -732,6 +733,7 @@ cJSON *iguana_walletiterate(struct supernet_info *myinfo,struct iguana_info *coi
myfree(wacct,sizeof(*wacct)); myfree(wacct,sizeof(*wacct));
} }
} }
portable_mutex_unlock(&myinfo->bu_mutex);
if ( goodp != 0 ) if ( goodp != 0 )
*goodp = good; *goodp = good;
if ( badp != 0 ) if ( badp != 0 )

2
iguana/tests/history

@ -1 +1 @@
curl --url "http://127.0.0.1:7778" --data "{\"timeout\":20000,\"agent\":\"basilisk\",\"method\":\"balances\",\"vals\":{\"minconf\":1,\"history\":3}}" curl --url "http://127.0.0.1:7778" --data "{\"timeout\":20000,\"agent\":\"basilisk\",\"method\":\"history\",\"vals\":{\"coin\":\"BTCD\"}}"

1
includes/iguana_apideclares.h

@ -24,6 +24,7 @@ TWO_INTS(InstantDEX,accept,requestid,quoteid);
TWO_INTS(InstantDEX,swapstatus,requestid,quoteid); TWO_INTS(InstantDEX,swapstatus,requestid,quoteid);
HASH_ARRAY_STRING(basilisk,genesis_opreturn,hash,vals,hexstr); HASH_ARRAY_STRING(basilisk,genesis_opreturn,hash,vals,hexstr);
HASH_ARRAY_STRING(basilisk,history,hash,vals,hexstr);
HASH_ARRAY_STRING(basilisk,balances,hash,vals,hexstr); HASH_ARRAY_STRING(basilisk,balances,hash,vals,hexstr);
HASH_ARRAY_STRING(basilisk,value,hash,vals,hexstr); HASH_ARRAY_STRING(basilisk,value,hash,vals,hexstr);

2
includes/iguana_funcs.h

@ -413,10 +413,12 @@ int32_t iguana_voutscript(struct iguana_info *coin,struct iguana_bundle *bp,uint
cJSON *iguana_unspentjson(struct supernet_info *myinfo,struct iguana_info *coin,int32_t hdrsi,uint32_t unspentind,struct iguana_txid *T,struct iguana_unspent *up,uint8_t rmd160[20],char *coinaddr,uint8_t *pubkey33,int32_t spentheight,char *remoteaddr); cJSON *iguana_unspentjson(struct supernet_info *myinfo,struct iguana_info *coin,int32_t hdrsi,uint32_t unspentind,struct iguana_txid *T,struct iguana_unspent *up,uint8_t rmd160[20],char *coinaddr,uint8_t *pubkey33,int32_t spentheight,char *remoteaddr);
int32_t bitcoin_standardspend(uint8_t *script,int32_t n,uint8_t rmd160[20]); int32_t bitcoin_standardspend(uint8_t *script,int32_t n,uint8_t rmd160[20]);
struct iguana_waddress *iguana_waddresssearch(struct supernet_info *myinfo,struct iguana_waccount **wacctp,char *coinaddr); struct iguana_waddress *iguana_waddresssearch(struct supernet_info *myinfo,struct iguana_waccount **wacctp,char *coinaddr);
int32_t basilisk_unspentfind(struct supernet_info *myinfo,struct iguana_info *coin,bits256 *txidp,int32_t *voutp,uint8_t *spendscript,int16_t hdrsi,uint32_t unspentind,int64_t value);
int64_t iguana_addressreceived(struct supernet_info *myinfo,struct iguana_info *coin,cJSON *json,char *remoteaddr,cJSON *txids,cJSON *vouts,cJSON *unspents,cJSON *spends,char *coinaddr,int32_t minconf,int32_t firstheight); int64_t iguana_addressreceived(struct supernet_info *myinfo,struct iguana_info *coin,cJSON *json,char *remoteaddr,cJSON *txids,cJSON *vouts,cJSON *unspents,cJSON *spends,char *coinaddr,int32_t minconf,int32_t firstheight);
cJSON *iguana_walletjson(struct supernet_info *myinfo); cJSON *iguana_walletjson(struct supernet_info *myinfo);
int32_t iguana_payloadupdate(struct supernet_info *myinfo,struct iguana_info *coin,char *retstr,struct iguana_waddress *waddr,char *account); int32_t iguana_payloadupdate(struct supernet_info *myinfo,struct iguana_info *coin,char *retstr,struct iguana_waddress *waddr,char *account);
int32_t bitcoin_MofNspendscript(uint8_t p2sh_rmd160[20],uint8_t *script,int32_t n,const struct vin_info *vp); int32_t bitcoin_MofNspendscript(uint8_t p2sh_rmd160[20],uint8_t *script,int32_t n,const struct vin_info *vp);
void basilisk_unspents_update(struct supernet_info *myinfo,struct iguana_info *coin);
struct iguana_txid *iguana_blocktx(struct iguana_info *coin,struct iguana_txid *tx,struct iguana_block *block,int32_t i); struct iguana_txid *iguana_blocktx(struct iguana_info *coin,struct iguana_txid *tx,struct iguana_block *block,int32_t i);
cJSON *iguana_p2shjson(struct supernet_info *myinfo,struct iguana_info *coin,cJSON *retjson,struct iguana_waddress *waddr); cJSON *iguana_p2shjson(struct supernet_info *myinfo,struct iguana_info *coin,cJSON *retjson,struct iguana_waddress *waddr);
char *setaccount(struct supernet_info *myinfo,struct iguana_info *coin,struct iguana_waddress **waddrp,char *account,char *coinaddr,char *redeemScript); char *setaccount(struct supernet_info *myinfo,struct iguana_info *coin,struct iguana_waddress **waddrp,char *account,char *coinaddr,char *redeemScript);

5
includes/iguana_structs.h

@ -364,7 +364,9 @@ struct iguana_bundlereq
struct iguana_bitmap { int32_t width,height,amplitude; char name[52]; uint8_t data[IGUANA_WIDTH*IGUANA_HEIGHT*3]; }; struct iguana_bitmap { int32_t width,height,amplitude; char name[52]; uint8_t data[IGUANA_WIDTH*IGUANA_HEIGHT*3]; };
struct iguana_waddress { UT_hash_handle hh; uint64_t balance,*unspents; uint32_t maxunspents,numunspents; uint16_t scriptlen; uint8_t rmd160[20],pubkey[33],wiftype,addrtype; bits256 privkey; char symbol[8],coinaddr[36],wifstr[54]; uint8_t redeemScript[]; }; struct basilisk_unspent { bits256 txid; uint64_t value,relaymask; uint32_t unspentind,timestamp; int32_t RTheight,height,spentheight; int16_t status,hdrsi,vout,spendlen; char symbol[16]; uint8_t script[256]; };
struct iguana_waddress { UT_hash_handle hh; struct basilisk_unspent *unspents; uint64_t balance; uint32_t maxunspents,numunspents; uint16_t scriptlen; uint8_t rmd160[20],pubkey[33],wiftype,addrtype; bits256 privkey; char symbol[8],coinaddr[36],wifstr[54]; uint8_t redeemScript[]; };
struct iguana_waccount { UT_hash_handle hh; char account[128]; struct iguana_waddress *waddr,*current; }; struct iguana_waccount { UT_hash_handle hh; char account[128]; struct iguana_waddress *waddr,*current; };
struct iguana_wallet { UT_hash_handle hh; struct iguana_waccount *wacct; }; struct iguana_wallet { UT_hash_handle hh; struct iguana_waccount *wacct; };
@ -413,6 +415,7 @@ struct iguana_info
struct iguana_monitorinfo monitoring[256]; struct iguana_monitorinfo monitoring[256];
struct datachain_info dPoW; struct datachain_info dPoW;
struct iguana_zblock newblock; char *newblockstr; struct iguana_zblock newblock; char *newblockstr;
int32_t relay_RTheights[BASILISK_MAXRELAYS];
struct iguana_blocks blocks; void *mempool; void *mempools[BASILISK_MAXRELAYS]; struct iguana_blocks blocks; void *mempool; void *mempools[BASILISK_MAXRELAYS];
}; };

Loading…
Cancel
Save