|
@ -382,85 +382,6 @@ int32_t iguana_datachain_scan(struct supernet_info *myinfo,struct iguana_info *c |
|
|
return(num); |
|
|
return(num); |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
int64_t *iguana_PoS_weights(struct supernet_info *myinfo,struct iguana_info *coin,int64_t *supplyp,int32_t *numacctsp,int32_t *nonzp,int32_t *errsp,int32_t lastheight) |
|
|
|
|
|
{ |
|
|
|
|
|
int64_t deposits,RTspend,total,supply,spent,*weights=0; uint32_t lastunspentind,unspentind,pkind; int32_t spentheight,i,neg,nonz,num=0; struct iguana_bundle *bp; struct iguana_ramchain *ramchain; struct iguana_ramchaindata *rdata; struct iguana_pkhash *refP,p; struct iguana_unspent *U; struct iguana_txid *T; uint8_t rmd160[20]; char coinaddr[64]; //struct iguana_account *A2; struct iguana_utxo *U2;
|
|
|
|
|
|
*supplyp = 0; |
|
|
|
|
|
*numacctsp = *nonzp = 0; |
|
|
|
|
|
*errsp = 1; |
|
|
|
|
|
if ( (bp= coin->bundles[lastheight / coin->chain->bundlesize]) == 0 ) |
|
|
|
|
|
return(0); |
|
|
|
|
|
if ( (rdata= bp->ramchain.H.data) == 0 ) |
|
|
|
|
|
return(0); |
|
|
|
|
|
refP = RAMCHAIN_PTR(rdata,Poffset); |
|
|
|
|
|
if ( (num= rdata->numpkinds) > 0 ) |
|
|
|
|
|
{ |
|
|
|
|
|
weights = calloc(num,sizeof(*weights)); |
|
|
|
|
|
for (pkind=1; pkind<num; pkind++) |
|
|
|
|
|
{ |
|
|
|
|
|
total = 0; |
|
|
|
|
|
memcpy(rmd160,refP[pkind].rmd160,sizeof(rmd160)); |
|
|
|
|
|
bitcoin_address(coinaddr,coin->chain->pubtype,rmd160,sizeof(rmd160)); |
|
|
|
|
|
//printf("PKIND.%d %s\n",pkind,coinaddr);
|
|
|
|
|
|
for (i=bp->hdrsi; i>=0; i--) |
|
|
|
|
|
{ |
|
|
|
|
|
if ( (bp= coin->bundles[i]) != 0 ) |
|
|
|
|
|
{ |
|
|
|
|
|
ramchain = 0; |
|
|
|
|
|
if ( iguana_pkhashfind(coin,&ramchain,&deposits,&lastunspentind,&p,rmd160,i,i) != 0 && (rdata= ramchain->H.data) != 0 ) |
|
|
|
|
|
{ |
|
|
|
|
|
spent = 0; |
|
|
|
|
|
deposits = 0; |
|
|
|
|
|
unspentind = lastunspentind; |
|
|
|
|
|
U = RAMCHAIN_PTR(rdata,Uoffset); |
|
|
|
|
|
T = RAMCHAIN_PTR(rdata,Toffset); |
|
|
|
|
|
while ( unspentind > 0 ) |
|
|
|
|
|
{ |
|
|
|
|
|
if ( iguana_spentflag(myinfo,coin,&RTspend,&spentheight,ramchain,i,unspentind,lastheight,0,1<<31,U[unspentind].value) == 0 ) |
|
|
|
|
|
deposits += U[unspentind].value; |
|
|
|
|
|
else spent += U[unspentind].value; |
|
|
|
|
|
unspentind = U[unspentind].prevunspentind; |
|
|
|
|
|
} |
|
|
|
|
|
weights[pkind] += (deposits - spent); |
|
|
|
|
|
/*if ( (A2= ramchain->A2) != 0 && p.pkind > 0 && p.pkind < rdata->numpkinds && (U2= ramchain->Uextras) != 0 )
|
|
|
|
|
|
{ |
|
|
|
|
|
T = RAMCHAIN_PTR(rdata,Toffset); |
|
|
|
|
|
U = RAMCHAIN_PTR(rdata,Uoffset); |
|
|
|
|
|
unspentind = A2[p.pkind].lastunspentind; |
|
|
|
|
|
while ( unspentind > 0 ) |
|
|
|
|
|
{ |
|
|
|
|
|
uheight = iguana_uheight(coin,ramchain->height,T,rdata->numtxids,&U[unspentind]); |
|
|
|
|
|
if ( uheight < lastheight ) |
|
|
|
|
|
spent += U[unspentind].value; |
|
|
|
|
|
unspentind = U2[unspentind].prevunspentind; |
|
|
|
|
|
} |
|
|
|
|
|
weights[pkind] -= spent; |
|
|
|
|
|
} else printf("PoS.[%d] rdata.%p or A2.%p error [%d] pkind.%d\n",pkind,rdata,A2,i,p.pkind);*/ |
|
|
|
|
|
if ( weights[pkind] != 0 ) |
|
|
|
|
|
printf("wt %.8f P.%d -> [%d] pkind.%d deposits %.8f spent %.8f\n",dstr(weights[pkind]),pkind,i,p.pkind,dstr(deposits),dstr(spent)); |
|
|
|
|
|
} |
|
|
|
|
|
} |
|
|
|
|
|
} |
|
|
|
|
|
} |
|
|
|
|
|
} |
|
|
|
|
|
nonz = neg = 0; |
|
|
|
|
|
supply = 0; |
|
|
|
|
|
for (pkind=1; pkind<num; pkind++) |
|
|
|
|
|
if ( weights[pkind] != 0 ) |
|
|
|
|
|
{ |
|
|
|
|
|
nonz++; |
|
|
|
|
|
if ( weights[pkind] < 0 ) |
|
|
|
|
|
neg++, weights[pkind] = 0; |
|
|
|
|
|
else supply += weights[pkind]; |
|
|
|
|
|
} |
|
|
|
|
|
*numacctsp = num; |
|
|
|
|
|
*errsp = neg; |
|
|
|
|
|
*nonzp = nonz; |
|
|
|
|
|
*supplyp = supply; |
|
|
|
|
|
printf("ht.%d [%d] numaddrs.%d nonz.%d neg.%d supply %.8f\n",lastheight,lastheight/coin->chain->bundlesize,num,nonz,neg,dstr(supply)); |
|
|
|
|
|
return(weights); |
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
int64_t iguana_pkhashbalance(struct supernet_info *myinfo,struct iguana_info *coin,cJSON *array,int64_t *spentp,int64_t *unspents,int32_t *nump,struct iguana_ramchain *ramchain,struct iguana_pkhash *p,uint32_t lastunspentind,uint8_t rmd160[20],char *coinaddr,uint8_t *pubkey33,int32_t hdrsi,int32_t lastheight,int32_t minconf,int32_t maxconf,char *remoteaddr) |
|
|
int64_t iguana_pkhashbalance(struct supernet_info *myinfo,struct iguana_info *coin,cJSON *array,int64_t *spentp,int64_t *unspents,int32_t *nump,struct iguana_ramchain *ramchain,struct iguana_pkhash *p,uint32_t lastunspentind,uint8_t rmd160[20],char *coinaddr,uint8_t *pubkey33,int32_t hdrsi,int32_t lastheight,int32_t minconf,int32_t maxconf,char *remoteaddr) |
|
|
{ |
|
|
{ |
|
|
struct iguana_unspent *U; struct iguana_utxo *U2; int32_t max,uheight,spentheight; uint32_t pkind=0,unspentind; int64_t spent = 0,checkval,deposits = 0; struct iguana_txid *T; struct iguana_account *A2; struct iguana_ramchaindata *rdata = 0; int64_t RTspend = 0; //struct iguana_spend *S;
|
|
|
struct iguana_unspent *U; struct iguana_utxo *U2; int32_t max,uheight,spentheight; uint32_t pkind=0,unspentind; int64_t spent = 0,checkval,deposits = 0; struct iguana_txid *T; struct iguana_account *A2; struct iguana_ramchaindata *rdata = 0; int64_t RTspend = 0; //struct iguana_spend *S;
|
|
@ -526,7 +447,7 @@ int64_t iguana_pkhashbalance(struct supernet_info *myinfo,struct iguana_info *co |
|
|
} |
|
|
} |
|
|
unspentind = U2[unspentind].prevunspentind; |
|
|
unspentind = U2[unspentind].prevunspentind; |
|
|
} |
|
|
} |
|
|
if ( llabs(spent - checkval - RTspend) > SMALLVAL ) |
|
|
if ( 0 && llabs(spent - checkval - RTspend) > SMALLVAL ) |
|
|
printf("spend %s: [%d] deposits %.8f spent %.8f check %.8f (%.8f) vs A2[%u] %.8f\n",lastheight==IGUANA_MAXHEIGHT?"checkerr":"",hdrsi,dstr(deposits),dstr(spent),dstr(checkval)+dstr(RTspend),dstr(*spentp),pkind,dstr(A2[pkind].total)); |
|
|
printf("spend %s: [%d] deposits %.8f spent %.8f check %.8f (%.8f) vs A2[%u] %.8f\n",lastheight==IGUANA_MAXHEIGHT?"checkerr":"",hdrsi,dstr(deposits),dstr(spent),dstr(checkval)+dstr(RTspend),dstr(*spentp),pkind,dstr(A2[pkind].total)); |
|
|
} |
|
|
} |
|
|
(*spentp) = spent; |
|
|
(*spentp) = spent; |
|
@ -650,17 +571,118 @@ uint8_t *iguana_rmdarray(struct supernet_info *myinfo,struct iguana_info *coin,i |
|
|
{ |
|
|
{ |
|
|
bitcoin_addr2rmd160(&addrtypes[j],&rmdarray[20 * j],coinaddr); |
|
|
bitcoin_addr2rmd160(&addrtypes[j],&rmdarray[20 * j],coinaddr); |
|
|
init_hexbytes_noT(rmdstr,&rmdarray[20 * j],20); |
|
|
init_hexbytes_noT(rmdstr,&rmdarray[20 * j],20); |
|
|
printf("(%s %s) ",coinaddr,rmdstr); |
|
|
//printf("(%s %s) ",coinaddr,rmdstr);
|
|
|
j++; |
|
|
j++; |
|
|
} |
|
|
} |
|
|
} |
|
|
} |
|
|
printf("rmdarray[%d]\n",n); |
|
|
//printf("rmdarray[%d]\n",n);
|
|
|
} |
|
|
} |
|
|
if ( flag != 0 ) |
|
|
if ( flag != 0 ) |
|
|
free_json(array); |
|
|
free_json(array); |
|
|
return(rmdarray); |
|
|
return(rmdarray); |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
int64_t *iguana_PoS_weights(struct supernet_info *myinfo,struct iguana_info *coin,struct iguana_pkhash **Ptrp,int64_t *supplyp,int32_t *numacctsp,int32_t *nonzp,int32_t *errsp,int32_t lastheight) |
|
|
|
|
|
{ |
|
|
|
|
|
int64_t balance,total,supply,*weights=0; uint32_t pkind; int32_t numrmds,minconf,neg,numunspents,nonz,num=0; struct iguana_bundle *bp; struct iguana_ramchaindata *rdata; struct iguana_pkhash *refP; uint8_t rmd160[20],*rmdarray; cJSON *array; char coinaddr[64]; //struct iguana_account *A2; struct iguana_utxo *U2;
|
|
|
|
|
|
*supplyp = 0; |
|
|
|
|
|
*numacctsp = *nonzp = 0; |
|
|
|
|
|
*errsp = 1; |
|
|
|
|
|
(*Ptrp) = 0; |
|
|
|
|
|
if ( (bp= coin->bundles[lastheight / coin->chain->bundlesize]) == 0 || bp == coin->current ) |
|
|
|
|
|
return(0); |
|
|
|
|
|
if ( (rdata= bp->ramchain.H.data) == 0 ) |
|
|
|
|
|
return(0); |
|
|
|
|
|
(*Ptrp) = refP = RAMCHAIN_PTR(rdata,Poffset); |
|
|
|
|
|
if ( (num= rdata->numpkinds) > 0 ) |
|
|
|
|
|
{ |
|
|
|
|
|
weights = calloc(num,sizeof(*weights)); |
|
|
|
|
|
minconf = coin->blocks.hwmchain.height - lastheight; |
|
|
|
|
|
for (pkind=1; pkind<num; pkind++) |
|
|
|
|
|
{ |
|
|
|
|
|
total = 0; |
|
|
|
|
|
memcpy(rmd160,refP[pkind].rmd160,sizeof(rmd160)); |
|
|
|
|
|
array = cJSON_CreateArray(); |
|
|
|
|
|
bitcoin_address(coinaddr,coin->chain->pubtype,rmd160,sizeof(rmd160)); |
|
|
|
|
|
jaddistr(array,coinaddr); |
|
|
|
|
|
//bitcoin_address(coinaddr,coin->chain->p2shtype,rmd160,sizeof(rmd160));
|
|
|
|
|
|
//jaddistr(array,coinaddr);
|
|
|
|
|
|
if ( (rmdarray= iguana_rmdarray(myinfo,coin,&numrmds,array,0)) != 0 ) |
|
|
|
|
|
{ |
|
|
|
|
|
numunspents = 0; |
|
|
|
|
|
balance = iguana_unspents(myinfo,coin,0,minconf,(1 << 30),rmdarray,numrmds,lastheight,0,&numunspents,0); |
|
|
|
|
|
free(rmdarray); |
|
|
|
|
|
weights[pkind] += balance; |
|
|
|
|
|
if ( weights[pkind] != balance ) |
|
|
|
|
|
printf("PKIND.%d %s %.8f += %.8f\n",pkind,coinaddr,dstr(weights[pkind]),dstr(balance)); |
|
|
|
|
|
} |
|
|
|
|
|
free_json(array); |
|
|
|
|
|
} |
|
|
|
|
|
} |
|
|
|
|
|
nonz = neg = 0; |
|
|
|
|
|
supply = 0; |
|
|
|
|
|
for (pkind=1; pkind<num; pkind++) |
|
|
|
|
|
if ( weights[pkind] != 0 ) |
|
|
|
|
|
{ |
|
|
|
|
|
nonz++; |
|
|
|
|
|
if ( weights[pkind] < 0 ) |
|
|
|
|
|
neg++, weights[pkind] = 0; |
|
|
|
|
|
else supply += weights[pkind]; |
|
|
|
|
|
} |
|
|
|
|
|
*numacctsp = num; |
|
|
|
|
|
*errsp = neg; |
|
|
|
|
|
*nonzp = nonz; |
|
|
|
|
|
*supplyp = supply; |
|
|
|
|
|
printf("ht.%d [%d] numaddrs.%d nonz.%d neg.%d supply %.8f\n",lastheight,lastheight/coin->chain->bundlesize,num,nonz,neg,dstr(supply)); |
|
|
|
|
|
return(weights); |
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
bits256 iguana_staker_hash2(bits256 refhash2,uint8_t *refrmd160,uint8_t *rmd160,int64_t weight) |
|
|
|
|
|
{ |
|
|
|
|
|
bits256 hash2; |
|
|
|
|
|
vcalc_sha256cat(hash2.bytes,refhash2.bytes,sizeof(refhash2),rmd160,20); |
|
|
|
|
|
return(mpz_div64(hash2,weight)); |
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
int _cmp_hashes(const void *a,const void *b) |
|
|
|
|
|
{ |
|
|
|
|
|
#define hasha (*(bits256 *)a) |
|
|
|
|
|
#define hashb (*(bits256 *)b) |
|
|
|
|
|
return(bits256_cmp(hasha,hashb)); |
|
|
|
|
|
#undef hasha |
|
|
|
|
|
#undef hashb |
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
int32_t iguana_staker_sort(struct iguana_info *coin,bits256 *hash2p,uint8_t *refrmd160,struct iguana_pkhash *refP,int64_t *weights,int32_t numweights,bits256 *sortbuf) |
|
|
|
|
|
{ |
|
|
|
|
|
int32_t i,j,n = 0; bits256 ind,refhash2 = *hash2p; |
|
|
|
|
|
memset(sortbuf,0,sizeof(*sortbuf) * 2 * numweights); |
|
|
|
|
|
for (i=0; i<numweights; i++) |
|
|
|
|
|
{ |
|
|
|
|
|
if ( weights[i] > 0 ) |
|
|
|
|
|
{ |
|
|
|
|
|
memset(&ind,0,sizeof(ind)); |
|
|
|
|
|
for (j=0; j<20; j++) |
|
|
|
|
|
ind.bytes[j] = refP[i].rmd160[j]; |
|
|
|
|
|
ind.ulongs[3] = weights[i]; |
|
|
|
|
|
ind.uints[5] = i; |
|
|
|
|
|
sortbuf[n << 1] = iguana_staker_hash2(refhash2,refrmd160,ind.bytes,weights[i]); |
|
|
|
|
|
sortbuf[(n << 1) + 1] = ind; |
|
|
|
|
|
n++; |
|
|
|
|
|
} |
|
|
|
|
|
} |
|
|
|
|
|
if ( n > 0 ) |
|
|
|
|
|
qsort(sortbuf,n,sizeof(*sortbuf)*2,_cmp_hashes); |
|
|
|
|
|
vcalc_sha256cat(hash2p->bytes,refhash2.bytes,sizeof(refhash2),sortbuf[1].bytes,20); |
|
|
|
|
|
memcpy(refrmd160,sortbuf[1].bytes,20); |
|
|
|
|
|
{ |
|
|
|
|
|
char str[65],coinaddr[64]; |
|
|
|
|
|
bitcoin_address(coinaddr,coin->chain->pubtype,refrmd160,20); |
|
|
|
|
|
printf("winner.%s %.8f: %s\n",coinaddr,dstr(sortbuf[1].ulongs[3]),bits256_str(str,sortbuf[0])); |
|
|
|
|
|
} |
|
|
|
|
|
return((int32_t)sortbuf[1].uints[5]); |
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
int32_t iguana_unspent_check(struct supernet_info *myinfo,struct iguana_info *coin,uint16_t hdrsi,uint32_t unspentind) |
|
|
int32_t iguana_unspent_check(struct supernet_info *myinfo,struct iguana_info *coin,uint16_t hdrsi,uint32_t unspentind) |
|
|
{ |
|
|
{ |
|
|
bits256 txid; int32_t vout,spentheight; |
|
|
bits256 txid; int32_t vout,spentheight; |
|
|