int32_t iguana_unspentindfind(struct iguana_info *coin,char *coinaddr,uint8_t *spendscript,int32_t *spendlenp,uint64_t *valuep,int32_t *heightp,bits256 txid,int32_t vout,int32_t lasthdrsi)
{
    struct iguana_txid *tp,TX; struct iguana_pkhash *P; struct iguana_unspent *U; struct iguana_bundle *bp; struct iguana_ramchaindata *rdata; int64_t RTspend; int32_t pkind,hdrsi,firstvout,spentheight,unspentind = -1;
    if ( valuep != 0 )
        *valuep = 0;
    if ( coinaddr != 0 )
        coinaddr[0] = 0;
    if ( coin->fastfind != 0 && (firstvout= iguana_txidfastfind(coin,heightp,txid,lasthdrsi)) >= 0 )
        unspentind = (firstvout + vout);
    else if ( (tp= iguana_txidfind(coin,heightp,&TX,txid,lasthdrsi)) != 0 )
        unspentind = (tp->firstvout + vout);
    if ( coinaddr != 0 && unspentind > 0 && (hdrsi= *heightp/coin->chain->bundlesize) >= 0 && hdrsi < coin->bundlescount && (bp= coin->bundles[hdrsi]) != 0 && (rdata= bp->ramchain.H.data) != 0 && unspentind < rdata->numunspents )
    {
        U = RAMCHAIN_PTR(rdata,Uoffset);
        P = RAMCHAIN_PTR(rdata,Poffset);
        //U = (void *)(long)((long)rdata + rdata->Uoffset);
        //P = (void *)(long)((long)rdata + rdata->Poffset);
        pkind = U[unspentind].pkind;
        if ( pkind > 0 && pkind < rdata->numpkinds )
        {
            RTspend = 0;
            if ( iguana_spentflag(coin,&RTspend,&spentheight,bp == coin->current ? &coin->RTramchain : &bp->ramchain,bp->hdrsi,unspentind,0,1,coin->longestchain,U[unspentind].value) == 0 )
            {
                if ( valuep != 0 )
                    *valuep = U[unspentind].value;
                bitcoin_address(coinaddr,iguana_addrtype(coin,U[unspentind].type),P[pkind].rmd160,sizeof(P[pkind].rmd160));
                if ( spendscript != 0 && spendlenp != 0 )
                    *spendlenp = iguana_voutscript(coin,bp,spendscript,0,&U[unspentind],&P[pkind],1);
            }
        }
    }
    return(unspentind);
}
Example #2
0
int32_t iguana_vinset(struct iguana_info *coin,uint8_t *scriptspace,int32_t height,struct iguana_msgvin *vin,struct iguana_txid *tx,int32_t i)
{
    struct iguana_spend *s,*S; uint32_t spendind,unspentind; bits256 *X; struct iguana_bundle *bp;
    struct iguana_ramchaindata *rdata=0; struct iguana_txid *T; char fname[1024]; int32_t scriptlen,err = 0; struct iguana_ramchain *ramchain;
    memset(vin,0,sizeof(*vin));
    if ( height >= 0 && height < coin->chain->bundlesize*coin->bundlescount && (bp= coin->bundles[height / coin->chain->bundlesize]) != 0 )
    {
        ramchain = &bp->ramchain;//(bp == coin->current) ? &coin->RTramchain : &bp->ramchain;
        if ( ((rdata= ramchain->H.data) != 0 || ((bp == coin->current && (rdata= ramchain->H.data) != 0))) && i < tx->numvins )
        //if ( (rdata= ramchain->H.data) != 0 && i < rdata->numspends )
        {
            S = RAMCHAIN_PTR(rdata,Soffset);
            X = RAMCHAIN_PTR(rdata,Xoffset);
            T = RAMCHAIN_PTR(rdata,Toffset);
            spendind = (tx->firstvin + i);
            s = &S[spendind];
            vin->sequence = s->sequenceid;
            vin->prev_vout = s->prevout;
            if ( s->prevout < 0 )
                ;
            if ( s->scriptpos != 0 && s->scriptlen > 0 )
            {
                iguana_vinsfname(coin,bp->ramchain.from_ro,fname,s->fileid);
                if ( (scriptlen= iguana_scriptdata(coin,scriptspace,coin->vinptrs[s->fileid],fname,s->scriptpos,s->scriptlen)) != s->scriptlen )
                    printf("err.%d getting %d bytes from fileid.%u[%u] %s for s%d\n",err,(int32_t)s->scriptlen,(uint32_t)s->scriptpos,(uint32_t)s->fileid,fname,spendind);
            }
            vin->scriptlen = s->scriptlen;
            vin->vinscript = scriptspace;
            iguana_ramchain_spendtxid(coin,&unspentind,&vin->prev_hash,T,rdata->numtxids,X,rdata->numexternaltxids,s);
        } else printf("null rdata.%p error height.%d i.%d\n",rdata,height,i);
    } else printf("error getting rdata.%p height.%d\n",rdata,height);
    if ( err != 0 )
        return(-err);
    else return(vin->scriptlen);
}
Example #3
0
int32_t iguana_voutset(struct iguana_info *coin,uint8_t *scriptspace,char *asmstr,int32_t height,struct iguana_msgvout *vout,struct iguana_txid *tx,int32_t i)
{
    struct iguana_ramchaindata *rdata=0; uint32_t unspentind,scriptlen = 0; struct iguana_bundle *bp;
    struct iguana_unspent *u,*U; struct iguana_pkhash *P; struct iguana_ramchain *ramchain=0; int32_t err = 0;
    memset(vout,0,sizeof(*vout));
    if ( height >= 0 && height < coin->chain->bundlesize*coin->bundlescount && (bp= coin->bundles[height / coin->chain->bundlesize]) != 0  )
    {
        ramchain = &bp->ramchain;//(bp == coin->current) ? &coin->RTramchain : &bp->ramchain;
        if ( ((rdata= ramchain->H.data) != 0 || ((bp == coin->current && (rdata= ramchain->H.data) != 0))) && i < tx->numvouts )
        {
            U = RAMCHAIN_PTR(rdata,Uoffset);
            P = RAMCHAIN_PTR(rdata,Poffset);
            //U = (void *)(long)((long)rdata + rdata->Uoffset);
            //P = (void *)(long)((long)rdata + rdata->Poffset);
            unspentind = (tx->firstvout + i);
            u = &U[unspentind];
            if ( u->vout != i || u->hdrsi != height / coin->chain->bundlesize ) //u->txidind != tx->txidind ||
            {
                static uint32_t counter;
                if ( counter++ < 3 )
                    printf("%s.[%d].%d iguana_voutset: vout mismatch t%d u%u || %d vs %d, type.%d scriptpos.%d scriptlen.%d\n",coin->symbol,height/coin->chain->bundlesize,u->hdrsi,u->txidind,unspentind,u->vout,i,u->type,u->scriptpos,u->scriptlen);
                return(-1);
            }
            vout->value = u->value;
            vout->pk_script = scriptspace;
            scriptlen = iguana_voutscript(coin,bp,scriptspace,asmstr,u,&P[u->pkind],i);
        } else printf("iguana_voutset unexpected path [%d] rdata.%p i.%d %d\n",bp->hdrsi,rdata,i,tx->numvouts);
    } else printf("vout error getting rdata.%p height.%d\n",rdata,height);
    vout->pk_scriptlen = scriptlen;
    if ( err != 0 )
        return(-err);
    else return(scriptlen);
}
struct iguana_pkhash *iguana_pkhashfind(struct iguana_info *coin,struct iguana_ramchain **ramchainp,int64_t *depositsp,uint32_t *lastunspentindp,struct iguana_pkhash *p,uint8_t rmd160[20],int32_t firsti,int32_t endi)
{
    uint8_t *PKbits; struct iguana_pkhash *P; uint32_t pkind,numpkinds,i; struct iguana_bundle *bp; struct iguana_ramchain *ramchain; struct iguana_ramchaindata *rdata; struct iguana_account *ACCTS;
    *depositsp = 0;
    *ramchainp = 0;
    *lastunspentindp = 0;
    for (i=firsti; i<coin->bundlescount&&i<=endi; i++)
    {
        if ( (bp= coin->bundles[i]) != 0 )
        {
            if ( 0 && coin->RTramchain_busy != 0 )
            {
                printf("iguana_pkhashfind: unexpected access when RTramchain_busy\n");
                return(0);
            }
            ramchain = (bp != coin->current) ? &bp->ramchain : &coin->RTramchain;
            if ( (rdata= ramchain->H.data) != 0 )
            {
                numpkinds = rdata->numpkinds;
                PKbits = RAMCHAIN_PTR(rdata,PKoffset);
                P = RAMCHAIN_PTR(rdata,Poffset);
                //PKbits = (void *)(long)((long)rdata + rdata->PKoffset);
                //P = (void *)(long)((long)rdata + rdata->Poffset);
                if ( bp == coin->current )
                    ACCTS = ramchain->A;
                else ACCTS = RAMCHAIN_PTR(rdata,Aoffset);
                //ACCTS = (void *)(long)((long)rdata + rdata->Aoffset);
                if ( (pkind= iguana_sparseaddpk(PKbits,rdata->pksparsebits,rdata->numpksparse,rmd160,P,0,ramchain)) > 0 && pkind < numpkinds )
                {
                    *ramchainp = ramchain;
                    *depositsp = ACCTS[pkind].total;
                    *lastunspentindp = ACCTS[pkind].lastunspentind;
                    //printf("[%d] return pkind.%u of %u P.%p %.8f last.%u ACCTS.%p %p\n",i,pkind,numpkinds,P,dstr(*depositsp),*lastunspentindp,ACCTS,ramchain->A);
                    if ( P != 0 )
                        *p = P[pkind];
                    return(p);
                }
                else if ( pkind != 0 )
                    printf("[%d] not found pkind.%d vs num.%d RT.%d rdata.%p\n",i,pkind,rdata->numpkinds,bp->isRT,rdata);
            } else printf("%s.[%d] error null rdata isRT.%d\n",coin->symbol,i,bp->isRT);
        }
    }
    return(0);
}
Example #5
0
int32_t iguana_alloctxbits(struct iguana_info *coin,struct iguana_ramchain *ramchain)
{
    static int64_t total; struct iguana_ramchaindata *rdata;
    if ( 0 && ramchain->txbits == 0 && (rdata= ramchain->H.data) != 0 )
    {
        int32_t tlen; uint8_t *TXbits;
        TXbits = RAMCHAIN_PTR(rdata,TXoffset);
        //TXbits = (uint8_t *)((long)rdata + rdata->TXoffset);
        tlen = (int32_t)hconv_bitlen(rdata->numtxsparse * rdata->txsparsebits);
        ramchain->txbits = calloc(1,tlen);
        memcpy(ramchain->txbits,TXbits,tlen);
        total += tlen;
        char str[65]; printf("%s alloc.[%d] txbits.%p[%d] total %s\n",coin->symbol,rdata->height/coin->chain->bundlesize,ramchain->txbits,tlen,mbstr(str,total));
        return(tlen);
    }
    return(-1);
}
Example #6
0
int32_t iguana_alloccacheT(struct iguana_info *coin,struct iguana_ramchain *ramchain)
{
    static int64_t total; struct iguana_ramchaindata *rdata;
    if ( ramchain->cacheT == 0 && (rdata= ramchain->H.data) != 0 )
    {
        int32_t i,tlen; struct iguana_txid *T;
        T = RAMCHAIN_PTR(rdata,Toffset);
        //T = (void *)((long)rdata + rdata->Toffset);
        tlen = sizeof(*T) * rdata->numtxids;
        if ( (ramchain->cacheT= calloc(1,tlen)) != 0 )
        {
            //memcpy(ramchain->cacheT,T,tlen);
            for (i=0; i<rdata->numtxids; i++)
                ramchain->cacheT[i] = T[i];
        } else ramchain->cacheT = T;
        total += tlen;
        char str[65]; printf("alloc.[%d] cacheT.%p[%d] total %s\n",rdata->height/coin->chain->bundlesize,ramchain->cacheT,tlen,mbstr(str,total));
        return(tlen);
    }
    return(-1);
}
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)
{
    struct iguana_unspent *U; struct iguana_utxo *U2; struct iguana_spend *S; 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;
    max = *nump;
    *spentp = *nump = 0;
    if ( 0 && coin->RTramchain_busy != 0 )
    {
        printf("iguana_pkhashbalance: unexpected access when RTramchain_busy\n");
        return(0);
    }
    if ( ramchain->Uextras == 0 || (rdata= ramchain->H.data) == 0 )
    {
        printf("iguana_pkhashbalance: unexpected null spents.%p or rdata.%p\n",ramchain->Uextras,rdata);
        return(0);
    }
    unspentind = lastunspentind;
    U = RAMCHAIN_PTR(rdata,Uoffset);
    T = RAMCHAIN_PTR(rdata,Toffset);
    //U = (void *)(long)((long)rdata + rdata->Uoffset);
    //T = (void *)(long)((long)rdata + rdata->Toffset);
    RTspend = 0;
    if ( lastheight == 0 )
        lastheight = IGUANA_MAXHEIGHT;
    while ( unspentind > 0 )
    {
        uheight = iguana_uheight(coin,ramchain->height,T,rdata->numtxids,&U[unspentind]);
        if ( lastheight <= 0 || uheight < lastheight )
        {
            deposits += U[unspentind].value;
            if ( iguana_spentflag(coin,&RTspend,&spentheight,ramchain,hdrsi,unspentind,lastheight,minconf,maxconf,U[unspentind].value) == 0 )
            {
                if ( *nump < max && unspents != 0 )
                {
                    unspents[*nump << 1] = ((uint64_t)hdrsi << 32) | unspentind;
                    unspents[(*nump << 1) + 1] = U[unspentind].value;
                }
                //printf("%.8f ",dstr(U[unspentind].value));
                (*nump)++;
                if ( array != 0 )
                    jaddi(array,iguana_unspentjson(myinfo,coin,hdrsi,unspentind,T,&U[unspentind],rmd160,coinaddr,pubkey33));
            }
            else
            {
                //printf("-%.8f ",dstr(U[unspentind].value));
                spent += U[unspentind].value;
            }
            if ( p->pkind != U[unspentind].pkind )
                printf("warning: [%d] p->pkind.%u vs U->pkind.%u for u%d\n",hdrsi,p->pkind,U[unspentind].pkind,unspentind);
        }
        pkind = p->pkind;
        unspentind = U[unspentind].prevunspentind;
    }
    if ( lastheight > 0 && (A2= ramchain->A2) != 0 && (U2= ramchain->Uextras) != 0 )
    {
        S = RAMCHAIN_PTR(rdata,Soffset);
        //S = (void *)(long)((long)rdata + rdata->Soffset);
        unspentind = A2[pkind].lastunspentind;
        checkval = 0;
        while ( unspentind > 0 )
        {
            uheight = iguana_uheight(coin,ramchain->height,T,rdata->numtxids,&U[unspentind]);
            if ( uheight < lastheight )
            {
                checkval += U[unspentind].value;
                //printf("u%u %.8f spentflag.%d prev.%u fromheight.%d\n",unspentind,dstr(U[unspentind].value),U2[unspentind].spentflag,U2[unspentind].prevunspentind,U2[unspentind].fromheight);
            }
            unspentind = U2[unspentind].prevunspentind;
        }
        if ( 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));
    }
    (*spentp) = spent;
    //printf("(%s) spent %.8f, RTspent %.8f deposits %.8f\n",coinaddr,dstr(spent),dstr(RTspend),dstr(deposits));
    return(deposits - spent);
}