예제 #1
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);
}
예제 #2
0
int32_t iguana_peerblockrequest(struct supernet_info *myinfo,struct iguana_info *coin,uint8_t *blockspace,int32_t max,struct iguana_peer *addr,bits256 hash2,int32_t validatesigs)
{
#if defined(_M_X64)
	/*
	* because we have no choice but to access the memory address
	* we need 64bit to correctly hold 64bit memory address, thus changing
	* to uint64_t instead of long in win x64
	* @author - [email protected]
	*/
	struct iguana_txid *tx, T; bits256 checktxid; int32_t i, len, total, bundlei = -2; struct iguana_block *block; struct iguana_msgzblock zmsgB; bits256 *tree, checkhash2, merkle_root; struct iguana_bundle *bp = 0; uint64_t tmp; char str[65]; struct iguana_ramchaindata *rdata;
#else
    struct iguana_txid *tx,T; bits256 checktxid; int32_t i,len,total,bundlei=-2; struct iguana_block *block; struct iguana_msgzblock zmsgB; bits256 *tree,checkhash2,merkle_root; struct iguana_bundle *bp=0; long tmp; char str[65]; struct iguana_ramchaindata *rdata;
#endif
    if ( (bp= iguana_bundlefind(coin,&bp,&bundlei,hash2)) != 0 && bundlei >= 0 && bundlei < bp->n )
    {
        if ( (rdata= bp->ramchain.H.data) == 0 )//&& bp == coin->current )
        {
            //printf("iguana_peerblockrequest no ramchain data [%d] use RTcache\n",bp->hdrsi);
            //rdata = coin->RTramchain.H.data;
            return(-1);
        }
        if ( (block= bp->blocks[bundlei]) != 0 && rdata != 0 )
        {
            iguana_blockunconv(coin->chain->zcash,coin->chain->auxpow,&zmsgB,(void *)block,0);
            zmsgB.txn_count = block->RO.txn_count;
            total = iguana_rwblock(myinfo,coin->symbol,coin->chain->zcash,coin->chain->auxpow,coin->chain->hashalgo,1,&checkhash2,&blockspace[sizeof(struct iguana_msghdr) + 0],&zmsgB,max);
            if ( bits256_cmp(checkhash2,block->RO.hash2) != 0 )
            {
                //static int counter;
                //if ( counter++ < 100 )
                    printf("iguana_peerblockrequest: blockhash mismatch ht.%d\n",bp->bundleheight+bundlei);
                return(-1);
            }
            for (i=0; i<block->RO.txn_count; i++)
            {
                if ( (tx= iguana_blocktx(coin,&T,block,i)) != 0 )
                {
                    //printf("ht.%d [%d:%d] txi.%d i.%d o.%d %s\n",block->height,block->hdrsi,block->bundlei,i,tx->numvins,tx->numvouts,bits256_str(str,tx->txid));
                    if ( (len= iguana_ramtxbytes(coin,&blockspace[sizeof(struct iguana_msghdr) + total],max - total,&checktxid,tx,block->height,0,0,validatesigs)) > 0 )//&& bits256_cmp(checktxid,T.txid) == 0 )
                        total += len;
                    else
                    {
                        static uint32_t counter;
                        char str[65],str2[65];
                        if ( counter++ < 100 )
                        {
                            for (i=0; i<len; i++)
                                printf("%02x",blockspace[sizeof(struct iguana_msghdr)+i]);
                            printf(" len.%d error getting txi.%d [%d:%d] cmp.%s %s\n",len,i,bp->hdrsi,bundlei,bits256_str(str,checktxid),bits256_str(str2,T.txid));
                        }
                        break;
                    }
                }
                else
                {
                    printf("%s null tx error getting txi.%d [%d:%d]\n",coin->symbol,i,bp->hdrsi,bundlei);
                    break;
                }
            }
            if ( i == block->RO.txn_count )
            {
#if defined(_M_X64)
				/*
				* because we have no choice but to access the memory address
				* we need 64bit to correctly hold 64bit memory address, thus changing
				* to uint64_t instead of long in win x64
				* @author - [email protected]
				*/
				tmp = (uint64_t)&blockspace[sizeof(struct iguana_msghdr) + total + sizeof(bits256)];
#else
                tmp = (long)&blockspace[sizeof(struct iguana_msghdr) + total + sizeof(bits256)];
#endif
                tmp &= ~(sizeof(bits256) - 1);
                tree = (void *)tmp;
                for (i=0; i<block->RO.txn_count; i++)
                {
                    if ( (tx= iguana_blocktx(coin,&T,block,i)) != 0 )
                        tree[i] = T.txid;
                    else break;
                }
                if ( i == block->RO.txn_count )
                {
                    merkle_root = iguana_merkle(tree,block->RO.txn_count);
                    if ( bits256_cmp(merkle_root,block->RO.merkle_root) == 0 )
                    {
                        if ( addr != 0 && addr->lastsent != block->height )
                        {
                            addr->lastsent = block->height;
                            printf("Sendlen.%d block.%d %s to %s\n",total,block->height,bits256_str(str,block->RO.hash2),addr->ipaddr);
                            if ( 0 )
                            {
                                struct iguana_txblock txdata; int32_t checklen; static struct OS_memspace RAWMEM;
                                if ( RAWMEM.ptr == 0 )
                                    iguana_meminit(&RAWMEM,addr->ipaddr,0,IGUANA_MAXPACKETSIZE * 2,0);
                                else iguana_memreset(&RAWMEM);
                                memset(&txdata,0,sizeof(txdata));
                                int32_t i;
                                for (i=0; i<total; i++)
                                {
                                    if ( i == 81 )
                                        printf(" ");
                                    printf("%02x",blockspace[i + sizeof(struct iguana_msghdr)]);
                                }
                                printf(" blocksize.%d\n",total);
                                for (i=0; i<16; i++)
                                    printf("%02x",blockspace[i + sizeof(struct iguana_msghdr)+81]);
                                printf(" txhdr\n");
                                if ( (checklen= iguana_gentxarray(myinfo,coin,&RAWMEM,&txdata,&checklen,&blockspace[sizeof(struct iguana_msghdr)],total)) != total && checklen != total-1 )
                                    printf("Error reconstructing txarray checklen.%d total.%d\n",checklen,total);
                            }
                            return(iguana_queue_send(addr,0,blockspace,"block",total));
                        }
                        else
                        {
                            //printf("validated.[%d:%d] len.%d\n",bp->hdrsi,bundlei,total);
                            return(total);
                        }
                    } else printf("iguana_peerblockrequest: %s error %s merkle cmp tx.[%d] for ht.%d\n",coin->symbol,bits256_str(str,block->RO.hash2),i,bp->bundleheight+bundlei);
                } else printf("iguana_peerblockrequest: error merkle verify tx.[%d] for ht.%d\n",i,bp->bundleheight+bundlei);
            }
            else
            {
                static uint32_t counter;
                if ( counter++ < 10 )
                    printf("%s iguana_peerblockrequest: error getting tx.[%d] for ht.%d block.%p main.%d ht.%d\n",coin->symbol,i,bp->bundleheight+bundlei,block,block!=0?block->mainchain:-1,block!=0?block->height:-1);
            }
        }
        else
        {
            if ( coin->virtualchain != 0 )
                ;
            /*if ( block != 0 )
                printf("iguana_peerblockrequest: block.%p ht.%d mainchain.%d [%d:%d] from %s bp.%p rdata.%p\n",block,block->height,block->mainchain,bp->hdrsi,bundlei,addr!=0?addr->ipaddr:"local",bp,bp!=0?rdata:0);
            else printf("iguana_peerblockrequest: block.%p [%d:%d]\n",block,bp->hdrsi,bundlei);*/
        }
    } //else printf("iguana_peerblockrequest: cant find %s\n",bits256_str(str,hash2));
    return(-1);
}