Пример #1
0
int32_t gecko_blocknonce_verify(struct iguana_info *virt,uint8_t *serialized,int32_t datalen,uint32_t nBits,uint32_t timestamp,uint32_t prevtimestamp)
{
    bits256 threshold,hash2;
    //printf("time.%u prev.%u\n",timestamp,prevtimestamp);
    if ( timestamp != 0 && prevtimestamp != 0 )
    {
        if ( prevtimestamp != 0 && timestamp < gecko_earliest_blocktime(virt->chain->estblocktime,prevtimestamp)  )
        {
            printf("reject timestamp prev.%u %u earliest.%u\n",prevtimestamp,timestamp,gecko_earliest_blocktime(virt->chain->estblocktime,prevtimestamp));
            return(-1);
        }
        if ( timestamp > time(NULL) + GECKO_MAXFUTUREBLOCK )
        {
            printf("reject future timestamp.%u vs %u\n",timestamp,(uint32_t)time(NULL));
            return(-1);
        }
    }
    if ( nBits >= GECKO_EASIESTDIFF )
        nBits = GECKO_EASIESTDIFF;
    threshold = bits256_from_compact(nBits);
    hash2 = iguana_calcblockhash(virt->symbol,virt->chain->hashalgo,serialized,datalen);
    if ( bits256_cmp(threshold,hash2) > 0 )
    {
        //printf("nonce worked crc.%x\n",calc_crc32(0,serialized,datalen));
        return(1);
    }
    else
    {
        char str[65],str2[65];
        printf("nonce failed crc.%x nBits.%08x %s vs %s\n",calc_crc32(0,serialized,datalen),nBits,bits256_str(str,threshold),bits256_str(str2,hash2));
    }
    return(-1);
}
Пример #2
0
uint32_t basilisk_calcnonce(struct supernet_info *myinfo,uint8_t *data,int32_t datalen,uint32_t nBits)
{
    int32_t i,numiters = 0; bits256 hash,hash2,threshold; uint32_t basilisktag;
    vcalc_sha256(0,hash.bytes,data,datalen);
    if ( nBits >= GECKO_EASIESTDIFF )
        threshold = bits256_from_compact(GECKO_EASIESTDIFF);
    else threshold = bits256_from_compact(nBits);
    for (i=0; i<numiters; i++)
    {
        //OS_randombytes((void *)hash.uints,sizeof(basilisktag));
        hash.uints[0] = rand();
        vcalc_sha256(0,hash2.bytes,hash.bytes,sizeof(hash));
        if ( bits256_cmp(threshold,hash2) > 0 )
            break;
    }
    iguana_rwnum(0,(void *)hash.uints,sizeof(basilisktag),&basilisktag);
    iguana_rwnum(1,&data[-sizeof(basilisktag)],sizeof(basilisktag),&basilisktag);
    char str[65],str2[65]; printf("found hash after numiters.%d %s vs %s basilisktag.%u\n",numiters,bits256_str(str,threshold),bits256_str(str2,hash2),basilisktag);
    return(basilisktag);
}
Пример #3
0
uint32_t gecko_nBits(struct iguana_info *virt,uint32_t *prevtimestampp,struct iguana_block *block,int32_t n)
{
    uint32_t nBits = GECKO_DEFAULTDIFF,starttime,endtime,est; struct iguana_block *prev=0; int32_t i,diff; bits256 targetval;
    *prevtimestampp = 0;
    if ( virt->chain->estblocktime == 0 )
        return(GECKO_EASIESTDIFF);
    for (i=0; i<n; i++)
    {
        if ( (prev= iguana_blockfind("geckotx",virt,block->RO.prev_block)) == 0 || prev->height == 0 )
        {
            i++;
            break;
        }
        if ( i == 0 )
        {
            *prevtimestampp = endtime = prev->RO.timestamp;
            nBits = prev->RO.bits;
        }
        starttime = prev->RO.timestamp;
        block = prev;
    }
    if ( starttime != 0 && endtime > starttime && i > 1 )
    {
        diff = (endtime - starttime);
        est = virt->chain->estblocktime * i;
        targetval = bits256_from_compact(nBits);
        if ( diff > est )
        {
            targetval = bits256_ave(targetval,bits256_ave(targetval,bits256_rshift(targetval)));
        }
        else if ( diff < est )
        {
            if ( nBits == GECKO_EASIESTDIFF )
                return(GECKO_EASIESTDIFF);
            targetval = bits256_ave(targetval,bits256_ave(targetval,bits256_lshift(targetval)));
        }
        //printf("diff.%d est.%d nBits.%08x <- %08x\n",diff,virt->chain->estblocktime * i,bits256_to_compact(targetval),nBits);
        nBits = bits256_to_compact(targetval);
    }
    if ( nBits > GECKO_EASIESTDIFF )
    {
        //printf("nBits.%08x vs easiest %08x\n",nBits,GECKO_EASIESTDIFF);
        nBits = GECKO_EASIESTDIFF;
    }
    return(nBits);
}
Пример #4
0
void gecko_miner(struct supernet_info *myinfo,struct iguana_info *btcd,struct iguana_info *virt,int32_t maxmillis,uint8_t *minerpubkey33)
{
    struct iguana_zblock newblock; uint32_t prevtimestamp,nBits; int64_t reward = 0; int32_t txn_count; char *blockstr,*space[256]; struct gecko_memtx **txptrs; void *ptr; //struct iguana_bundle *bp;
#ifndef __APPLE__
    int32_t i,gap;
    if ( virt->virtualchain == 0 || RELAYID < 0 || NUMRELAYS < 1 )
    {
        //printf("skip non-virtual chain.%s\n",virt->symbol);
        return;
    }
    if ( virt->blocks.hwmchain.height < virt->longestchain-1 )
        return;
    if ( (virt->blocks.hwmchain.height % NUMRELAYS) != RELAYID )
    {
        //if ( NUMRELAYS < 3 )
        //    return;
        gap = (int32_t)(time(NULL) - virt->blocks.hwmchain.RO.timestamp) / 60;//virt->chain->estblocktime;
        for (i=0; i<gap; i++)
        {
            if ( ((virt->blocks.hwmchain.height+i) % NUMRELAYS) == RELAYID )
                break;
        }
        if ( i == gap )
            return;
        printf("backup block generator RELAYID.%d gap.%d ht.%d i.%d num.%d\n",RELAYID,gap,virt->blocks.hwmchain.height,i,NUMRELAYS);
    }
#endif
    /*if ( virt->newblockstr != 0 )
    {
        gecko_blocksubmit(myinfo,btcd,virt,virt->newblockstr,virt->newblock.RO.hash2,virt->newblock.height);
        memset(&virt->newblock,0,sizeof(virt->newblock));
        free(virt->newblockstr);
        virt->newblockstr = 0;
        return;
    }*/
    memset(&newblock,0,sizeof(newblock));
    newblock.height = virt->blocks.hwmchain.height + 1;
    newblock.RO.prev_block = virt->blocks.hwmchain.RO.hash2;
    newblock.RO.version = GECKO_DEFAULTVERSION;
    newblock.RO.allocsize = iguana_ROallocsize(virt);
    if ( (nBits= gecko_nBits(virt,&prevtimestamp,(void *)&newblock,GECKO_DIFFITERS)) != 0 )
    {
        if ( (newblock.RO.bits= nBits) > GECKO_EASIESTDIFF )
            newblock.RO.bits = GECKO_EASIESTDIFF;
        char str[65]; printf("mine.%s %s nBits.%x ht.%d maxmillis.%d\n",virt->symbol,bits256_str(str,bits256_from_compact(newblock.RO.bits)),nBits,newblock.height,maxmillis);
        txptrs = gecko_mempool_txptrs(myinfo,virt,&reward,&txn_count,&ptr,space,(int32_t)(sizeof(space)/sizeof(*space)),newblock.height);
        //char str[65]; printf("HWM.%s %p\n",bits256_str(str,newblock.RO.prev_block),&newblock.RO.prev_block);
        if ( (blockstr= gecko_createblock(myinfo,virt->chain->estblocktime,prevtimestamp,btcd,virt->chain->isPoS,(void *)&newblock,virt->symbol,txptrs,txn_count,maxmillis,minerpubkey33,reward)) != 0 )
        {
            char str[65];
            printf("tx0.%s\n",bits256_str(str,newblock.RO.merkle_root));
            printf(">>>>>>>>>>>>>>>>> MINED %s.%x %s %u %d %.8f %d\n",virt->symbol,newblock.RO.bits,bits256_str(str,newblock.RO.hash2),newblock.RO.timestamp,newblock.height,dstr(reward),newblock.RO.txn_count);
            if ( gecko_blocksubmit(myinfo,btcd,virt,blockstr,newblock.RO.hash2,newblock.height) == 0 )
                free(blockstr);
            else
            {
                //virt->newblockstr = blockstr;
                //virt->newblock = newblock;
                free(blockstr);
            }
        } else printf("didnt find %s.block\n",virt->symbol);
        if ( txptrs != (void *)space )
            free(txptrs);
    }
}
Пример #5
0
char *gecko_blockconstruct(struct supernet_info *myinfo,struct iguana_info *virt,struct iguana_block *newblock,uint32_t *noncep,struct gecko_memtx **txptrs,int32_t txn_count,uint8_t *coinbase,int32_t coinbaselen,bits256 coinbasespend,double expiration,uint8_t *minerpubkey,int64_t blockreward)
{
    struct iguana_info *btcd; uint8_t serialized[sizeof(*newblock)],space[16384]; int32_t i,n,len,totaltxlen=0; char *coinbasestr,str[65],str2[65],*blockstr=0; bits256 *txids=0,txspace[256],threshold,hash2; struct gecko_memtx *memtx;
    if ( (btcd= iguana_coinfind("BTCD")) == 0 )
    {
        printf("basilisk needs BTCD\n");
        return(0);
    }
    if ( txn_count+2 < sizeof(space)/sizeof(*space) )
    {
        txids = txspace;
        memset(txids,0,sizeof(*txids) * (txn_count+2));
    } else txids = calloc(txn_count+2,sizeof(*txids));
    if ( txn_count > 0 )
    {
        for (i=0; i<txn_count; i++)
        {
            if ( (memtx= txptrs[i]) != 0 )
            {
                totaltxlen += memtx->datalen;
                txids[i + 1] = memtx->txid;
                printf("memtxid.%s\n",bits256_str(str,memtx->txid));
            }
        }
    }
    if ( (coinbasestr= gecko_coinbasestr(myinfo,virt,&txids[0],newblock->RO.timestamp,minerpubkey,blockreward,coinbase,coinbaselen,coinbasespend)) != 0 )
    {
        newblock->RO.merkle_root = iguana_merkle(txids,txn_count + 1);
        newblock->RO.txn_count = (txn_count + 1);
        if ( txn_count > 0 )
        {
            printf("%s %s\n",bits256_str(str,txids[0]),bits256_str(str2,txids[1]));
        }
        if ( newblock->RO.bits >= GECKO_EASIESTDIFF )
            newblock->RO.bits = GECKO_EASIESTDIFF;
        threshold = bits256_from_compact(newblock->RO.bits);
        if ( (newblock->RO.nonce= *noncep) == 0 )
        {
            struct iguana_msgblock msg;
            memset(&msg,0,sizeof(msg));
            msg.H.version = newblock->RO.version;
            msg.H.prev_block = newblock->RO.prev_block;
            msg.H.merkle_root = newblock->RO.merkle_root;
            msg.H.timestamp = newblock->RO.timestamp;
            msg.H.bits = newblock->RO.bits;
            for (i=0; i<GECKO_MAXMINERITERS; i++)
            {
                OS_randombytes((void *)noncep,sizeof(*noncep));
                msg.H.nonce = *noncep;
                //n = iguana_serialize_block(virt->chain,&hash2,serialized,newblock);
                //char str[65]; printf("nonce.%08x %s\n",newblock->RO.nonce,bits256_str(str,newblock->RO.hash2));
                len = iguana_rwblockhdr(1,virt->chain->zcash,serialized,&msg);
                hash2 = iguana_calcblockhash(virt->symbol,virt->chain->hashalgo,serialized,len);
                if ( bits256_cmp(threshold,hash2) > 0 )
                {
                    //printf("FOUND NONCE %d iterations\n",i+1);
                    newblock->RO.hash2 = hash2;
                    break;
                }
                if ( newblock->height != 0 && OS_milliseconds() > expiration )
                {
                    //printf("time limit exceeded %u %d iterations\n",virt->blocks.hwmchain.RO.timestamp,i+1);
                    free(coinbasestr);
                    if ( txids != txspace )
                        free(txids);
                    return(0);
                }
            }
        }
        newblock->RO.nonce = *noncep;
        n = iguana_serialize_block(virt->chain,&newblock->RO.hash2,serialized,newblock);
        while ( 1 && time(NULL) <= newblock->RO.timestamp + GECKO_MAXFUTUREBLOCK )
        {
            //printf("wait for block to be close enough to now: lag %ld\n",time(NULL) - newblock->RO.timestamp);
            sleep(1);
        }
        //if ( gecko_blocknonce_verify(virt,serialized,n,newblock->RO.bits,newblock->RO.timestamp,virt->blocks.hwmchain.RO.timestamp) >= 0 )
        if ( bits256_cmp(threshold,newblock->RO.hash2) > 0 )
        {
            blockstr = calloc(1,strlen(coinbasestr) + (totaltxlen+n)*2 + 1);
            init_hexbytes_noT(blockstr,serialized,n);
            printf("block.(%s) coinbase.(%s) lens.%ld\n",blockstr,coinbasestr,(strlen(blockstr)+strlen(coinbasestr))/2);
            strcat(blockstr,coinbasestr);
            len = (int32_t)strlen(blockstr);
            for (i=0; i<txn_count; i++)
            {
                if ( (memtx= txptrs[i]) != 0 )
                {
                    init_hexbytes_noT(&blockstr[len],gecko_txdata(memtx),memtx->datalen);
                    len += memtx->datalen << 1;
                    printf(" txi.%d (%s)\n",i,&blockstr[len]);
                }
            }
        } else printf("nonce failure\n");
        free(coinbasestr);
    }
    if ( txids != txspace )
        free(txids);
    return(blockstr);
}