示例#1
0
int32_t iguana_peergetrequest(struct iguana_info *coin,struct iguana_peer *addr,uint8_t *data,int32_t recvlen,int32_t getblock)
{
    int32_t i,reqvers,len,n,flag = 0;
    bits256 hash2;
    if ( getblock != 0 )
        addr->msgcounts.getblocks++;
    else addr->msgcounts.getheaders++;
    len = iguana_rwnum(0,&data[0],sizeof(uint32_t),&reqvers);
    len += iguana_rwvarint32(0,&data[len],(uint32_t *)&n);
    for (i=0; i<n&&len<=recvlen-sizeof(bits256)*2; i++)
    {
        len += iguana_rwbignum(0,&data[len],sizeof(bits256),hash2.bytes);
        if ( bits256_nonz(hash2) == 0 )
            break;
        if ( flag == 0 )
        {
            if ( getblock != 0 && iguana_peerblockrequest(coin,addr->blockspace,IGUANA_MAXPACKETSIZE,addr,hash2,0) > 0 )
                flag = 1;
            else if ( getblock == 0 && iguana_peerhdrrequest(coin,addr->blockspace,IGUANA_MAXPACKETSIZE,addr,hash2) > 0 )
                flag = 1;
        }
    }
    len += iguana_rwbignum(0,&data[len],sizeof(bits256),hash2.bytes);
    //for (i=0; i<69; i++)
    //    printf("%02x ",data[i]);
    //printf("version.%d num blocks.%d recvlen.%d len.%d\n",reqvers,n,recvlen,len);
    return(len);
}
示例#2
0
int32_t iguana_rwtx(int32_t rwflag,struct OS_memspace *mem,uint8_t *serialized,struct iguana_msgtx *msg,int32_t maxsize,bits256 *txidp,int32_t hastimestamp,int32_t isvpncoin)
{
    int32_t i,len = 0; uint8_t *txstart = serialized; char txidstr[65];
    len += iguana_rwnum(rwflag,&serialized[len],sizeof(msg->version),&msg->version);
    if ( hastimestamp != 0 )
        len += iguana_rwnum(rwflag,&serialized[len],sizeof(msg->timestamp),&msg->timestamp);
    len += iguana_rwvarint32(rwflag,&serialized[len],&msg->tx_in);
    //printf("version.%d ",msg->version);
    if ( msg->tx_in > 0 && msg->tx_out*100 < maxsize )
    {
        if ( rwflag == 0 )
            msg->vins = iguana_memalloc(mem,msg->tx_in * sizeof(*msg->vins),1);
        for (i=0; i<msg->tx_in; i++)
            len += iguana_rwvin(rwflag,mem,&serialized[len],&msg->vins[i]);
        //printf("numvins.%d\n",msg->tx_in);
    }
    else
    {
        printf("invalid tx_in.%d\n",msg->tx_in);
        return(-1);
    }
    len += iguana_rwvarint32(rwflag,&serialized[len],&msg->tx_out);
    if ( msg->tx_out > 0 && msg->tx_out*32 < maxsize )
    {
        //printf("numvouts.%d ",msg->tx_out);
        if ( rwflag == 0 )
            msg->vouts = iguana_memalloc(mem,msg->tx_out * sizeof(*msg->vouts),1);
        for (i=0; i<msg->tx_out; i++)
            len += iguana_rwvout(rwflag,mem,&serialized[len],&msg->vouts[i]);
    }
    else
    {
        printf("invalid tx_out.%d\n",msg->tx_out);
        return(-1);
    }
    len += iguana_rwnum(rwflag,&serialized[len],sizeof(msg->lock_time),&msg->lock_time);
    if ( isvpncoin != 0 )
    {
        uint16_t ddosflag=0;
        len += iguana_rwnum(rwflag,&serialized[len],sizeof(ddosflag),&ddosflag);
        for (; serialized[len]!=0&&len<maxsize; len++) // eat null terminated string
            ;
    }
    *txidp = bits256_doublesha256(txidstr,txstart,len);
    msg->allocsize = len;
    return(len);
}
示例#3
0
int32_t iguana_rwtx(int32_t rwflag,uint8_t *serialized,struct iguana_msgtx *msg,int32_t maxsize,bits256 *txidp,int32_t height,int32_t hastimestamp)
{
    int32_t i,len = 0; uint8_t *txstart = serialized; char txidstr[65]; uint32_t timestamp;
    len += iguana_rwnum(rwflag,&serialized[len],sizeof(msg->version),&msg->version);
    if ( hastimestamp != 0 )
        len += iguana_rwnum(rwflag,&serialized[len],sizeof(timestamp),&timestamp);
    len += iguana_rwvarint32(rwflag,&serialized[len],&msg->tx_in);
    //printf("version.%d ",msg->version);
    if ( msg->tx_in > 0 && msg->tx_out*100 < maxsize )
    {
        if ( rwflag == 0 )
            msg->vins = mycalloc('v',msg->tx_in,sizeof(*msg->vins));
        for (i=0; i<msg->tx_in; i++)
            len += iguana_rwvin(rwflag,&serialized[len],&msg->vins[i]);
        //printf("numvins.%d\n",msg->tx_in);
    }
    else
    {
        printf("invalid tx_in.%d\n",msg->tx_in);
        return(-1);
    }
    len += iguana_rwvarint32(rwflag,&serialized[len],&msg->tx_out);
    if ( msg->tx_out > 0 && msg->tx_out*32 < maxsize )
    {
        //printf("numvouts.%d ",msg->tx_out);
        if ( rwflag == 0 )
            msg->vouts = mycalloc('v',msg->tx_out,sizeof(*msg->vouts));
        for (i=0; i<msg->tx_out; i++)
            len += iguana_rwvout(rwflag,&serialized[len],&msg->vouts[i]);
    }
    else
    {
        printf("invalid tx_out.%d\n",msg->tx_out);
        return(-1);
    }
    len += iguana_rwnum(rwflag,&serialized[len],sizeof(msg->lock_time),&msg->lock_time);
    *txidp = bits256_doublesha256(txidstr,txstart,len);
    //printf("txid.(%s) len.%d\n",bits256_str(*txidp),len);
    msg->allocsize = len;
    Tx_allocated++, Tx_allocsize += len;
    if ( ((Tx_allocated + Tx_freed) % 10000000) == 0 )
        printf("h.%u len.%d (%llu - %llu) %lld (%llu - %llu)\n",height,len,(long long)Tx_allocated,(long long)Tx_freed,(long long)(Tx_allocated - Tx_freed),(long long)Tx_allocsize,(long long)Tx_freesize);
    return(len);
}
示例#4
0
int32_t iguana_getdata(struct iguana_info *coin,uint8_t *serialized,int32_t type,char *hashstr)
{
    uint32_t len,i,n=1; bits256 hash2;
    decode_hex(hash2.bytes,sizeof(hash2),hashstr);
    len = iguana_rwvarint32(1,&serialized[sizeof(struct iguana_msghdr)],(uint32_t *)&n);
    for (i=0; i<n; i++)
    {
        len += iguana_rwnum(1,&serialized[sizeof(struct iguana_msghdr) + len],sizeof(uint32_t),&type);
        len += iguana_rwbignum(1,&serialized[sizeof(struct iguana_msghdr) + len],sizeof(bits256),hash2.bytes);
    }
    return(iguana_sethdr((void *)serialized,coin->chain->netmagic,"getdata",&serialized[sizeof(struct iguana_msghdr)],len));
}
示例#5
0
int32_t iguana_gethdrs(struct iguana_info *coin,uint8_t *serialized,char *cmd,char *hashstr)
{
    uint32_t len,n; bits256 hash2;
    decode_hex(hash2.bytes,sizeof(hash2),hashstr);
    n = 0;
    len = iguana_rwnum(1,&serialized[sizeof(struct iguana_msghdr)],sizeof(uint32_t),&n);
    n++;
    len += iguana_rwvarint32(1,&serialized[sizeof(struct iguana_msghdr) + len],(uint32_t *)&n);
    len += iguana_rwbignum(1,&serialized[sizeof(struct iguana_msghdr) + len],sizeof(bits256),hash2.bytes);
    len += iguana_rwbignum(1,&serialized[sizeof(struct iguana_msghdr) + len],sizeof(bits256),(uint8_t *)bits256_zero.bytes);
    return(iguana_sethdr((void *)serialized,coin->chain->netmagic,cmd,&serialized[sizeof(struct iguana_msghdr)],len));
}
示例#6
0
int32_t iguana_rwvout(int32_t rwflag,uint8_t *serialized,struct iguana_msgvout *msg)
{
    int32_t len = 0;
    len += iguana_rwnum(rwflag,&serialized[len],sizeof(msg->value),&msg->value);
    len += iguana_rwvarint32(rwflag,&serialized[len],&msg->pk_scriptlen);
    if ( rwflag == 0 )
        msg->pk_script = mycalloc('s',1,msg->pk_scriptlen);
    len += iguana_rwmem(rwflag,&serialized[len],msg->pk_scriptlen,msg->pk_script);
    //printf("(%.8f scriptlen.%d) ",dstr(msg->value),msg->pk_scriptlen);
    //int i; for (i=0; i<msg->pk_scriptlen; i++)
    //    printf("%02x",msg->pk_script[i]);
    //printf("\n");
    return(len);
}
示例#7
0
int32_t iguana_coinbase(int32_t isPoS,uint32_t txversion,uint8_t *serialized,uint32_t timestamp,bits256 prev_hash,uint8_t *coinbasescript,uint32_t coinbaselen,uint8_t *minerpayment,uint32_t minerpaymentlen,int64_t blockreward,bits256 *txidp)
{
    int32_t len = 0,rwflag=1; uint32_t prev_vout,sequence,lock_time; char txidstr[65]; struct iguana_msgtx msg;
    memset(&msg,0,sizeof(msg));
    msg.tx_out = (blockreward > 0) ? 1 : 0;
    msg.tx_in = 1;
    sequence = prev_vout = -1;
    lock_time = 0;
    msg.version = txversion;
    msg.timestamp = timestamp;
    len += iguana_rwnum(rwflag,&serialized[len],sizeof(msg.version),&msg.version);
    if ( isPoS != 0 )
        len += iguana_rwnum(rwflag,&serialized[len],sizeof(msg.timestamp),&msg.timestamp);
    {
        len += iguana_rwvarint32(rwflag,&serialized[len],&msg.tx_in);
        // tx_in times
        len += iguana_rwbignum(rwflag,&serialized[len],sizeof(prev_hash),prev_hash.bytes);
        len += iguana_rwnum(rwflag,&serialized[len],sizeof(prev_vout),&prev_vout);
        len += iguana_rwvarint32(rwflag,&serialized[len],&coinbaselen);
        len += iguana_rwmem(rwflag,&serialized[len],coinbaselen,coinbasescript);
        len += iguana_rwnum(rwflag,&serialized[len],sizeof(sequence),&sequence);
    }
    {
        len += iguana_rwvarint32(rwflag,&serialized[len],&msg.tx_out);
        // tx_out times
        if ( msg.tx_out > 0 )
        {
            len += iguana_rwnum(rwflag,&serialized[len],sizeof(blockreward),&blockreward);
            len += iguana_rwvarint32(rwflag,&serialized[len],&minerpaymentlen);
            len += iguana_rwmem(rwflag,&serialized[len],minerpaymentlen,minerpayment);
        }
    }
    len += iguana_rwnum(rwflag,&serialized[len],sizeof(lock_time),&lock_time);
    *txidp = bits256_doublesha256(txidstr,serialized,len);
    return(len);
}
示例#8
0
int32_t iguana_rwblockhash(int32_t rwflag,uint8_t *serialized,uint32_t *nVersionp,uint32_t *varintp,bits256 *hashes,bits256 *stophash)
{
    int32_t i,len = 0;
    len += iguana_rwnum(rwflag,&serialized[len],sizeof(*nVersionp),nVersionp);
    len += iguana_rwvarint32(rwflag,&serialized[len],varintp);
    if ( *varintp < IGUANA_MAXLOCATORS-1 )
    {
        for (i=0; i<*varintp; i++)
            len += iguana_rwbignum(rwflag,&serialized[len],sizeof(hashes[i]),hashes[i].bytes);
        len += iguana_rwbignum(rwflag,&serialized[len],sizeof(*stophash),stophash->bytes);
        //for (i=0; i<len; i++)
        //    printf("%02x ",serialized[i]);
        //printf("rwblockhash len.%d\n",len);
    } else printf("iguana_rwblockhash: illegal varint.%d\n",*varintp);
    return(len);
}
示例#9
0
// two passes to check data size
int32_t iguana_rwvin(int32_t rwflag,uint8_t *serialized,struct iguana_msgvin *msg)
{
    int32_t len = 0;
    len += iguana_rwbignum(rwflag,&serialized[len],sizeof(msg->prev_hash),msg->prev_hash.bytes);
    len += iguana_rwnum(rwflag,&serialized[len],sizeof(msg->prev_vout),&msg->prev_vout);
    //printf("vin.(%s) %d\n",bits256_str(msg->prev_hash),msg->prev_vout);
    len += iguana_rwvarint32(rwflag,&serialized[len],&msg->scriptlen);
    if ( rwflag == 0 )
        msg->script = mycalloc('s',1,msg->scriptlen);
    len += iguana_rwmem(rwflag,&serialized[len],msg->scriptlen,msg->script);
    len += iguana_rwnum(rwflag,&serialized[len],sizeof(msg->sequence),&msg->sequence);
    //int i; for (i=0; i<msg->scriptlen; i++)
   // printf("%02x ",msg->script[i]);
    //printf(" inscriptlen.%d, prevhash.%llx prev_vout.%d | ",msg->scriptlen,(long long)msg->prev_hash.txid,msg->prev_vout);
    return(len);
}
示例#10
0
int32_t iguana_rwvin(int32_t rwflag,struct OS_memspace *mem,uint8_t *serialized,struct iguana_msgvin *msg)
{
    int32_t len = 0;
    len += iguana_rwbignum(rwflag,&serialized[len],sizeof(msg->prev_hash),msg->prev_hash.bytes);
    len += iguana_rwnum(rwflag,&serialized[len],sizeof(msg->prev_vout),&msg->prev_vout);
    len += iguana_rwvarint32(rwflag,&serialized[len],&msg->scriptlen);
    if ( rwflag == 0 )
        msg->script = iguana_memalloc(mem,msg->scriptlen,1);
    len += iguana_rwmem(rwflag,&serialized[len],msg->scriptlen,msg->script);
    len += iguana_rwnum(rwflag,&serialized[len],sizeof(msg->sequence),&msg->sequence);
    //char str[65]; printf("MSGvin.(%s/v%d) script[%d]\n",bits256_str(str,msg->prev_hash),msg->prev_vout,msg->scriptlen);
    //int i; for (i=0; i<msg->scriptlen; i++)
    // printf("%02x ",msg->script[i]);
    //printf(" inscriptlen.%d, prevhash.%llx prev_vout.%d | ",msg->scriptlen,(long long)msg->prev_hash.txid,msg->prev_vout);
    return(len);
}
示例#11
0
int32_t iguana_parser(struct iguana_info *coin,struct iguana_peer *addr,struct iguana_msghdr *H,uint8_t *data,int32_t datalen)
{
    int32_t height,i,retval,srvmsg,bloom,intvectors,len= -100; uint64_t nonce,x;
    uint32_t type,firsttxidind,firstvout,firstvin; bits256 hash2; double PoW;
    bloom = intvectors = srvmsg = -1;
    if ( addr != 0 )
    {
        addr->lastcontact = (uint32_t)time(NULL);
        strcpy(addr->lastcommand,H->command);
    }
    retval = 0;
    //printf("%s parse.(%s)\n",addr->ipaddr,H->command);
    if ( strcmp(H->command,"version") == 0 )
    {
        struct iguana_msgversion recvmv;
        if ( addr != 0 )
        {
            len = iguana_rwversion(0,data,&recvmv,addr->ipaddr);
            if ( len == datalen )
                iguana_gotversion(coin,addr,&recvmv);
            //printf("deser.(%s) len.%d datalen.%d\n",recvmv.H.command,len,datalen);
            addr->msgcounts.version++;
        }
    }
    else if ( strcmp(H->command,"verack") == 0 )
    {
        if ( addr != 0 )
        {
            iguana_gotverack(coin,addr);
            addr->msgcounts.verack++;
        }
        len = 0;
    }
    else if ( strcmp(H->command,"ping") == 0 )
    {
        if ( datalen == sizeof(uint64_t) && addr != 0 )
        {
            len = iguana_rwnum(0,data,sizeof(uint64_t),&nonce);
            if ( addr != 0 )
            {
                //printf("%u got nonce.%llx from %s\n",(uint32_t)time(NULL),(long long)nonce,addr->ipaddr);
                iguana_gotping(coin,addr,nonce,data);
                addr->msgcounts.ping++;
            }
        }
    }
    else if ( strcmp(H->command,"pong") == 0 )
    {
        len = 0;
        if ( datalen == sizeof(uint64_t) )
        {
            len = iguana_rwnum(0,data,sizeof(uint64_t),&nonce);
            iguana_gotpong(coin,addr,nonce);
        } else printf("unexpected pong datalen.%d\n",datalen);
        if ( len == datalen && addr != 0 )
            addr->msgcounts.pong++;
    }
    else if ( strcmp(H->command,"addr") == 0 )
    {
        struct iguana_msgaddress A;
        len = iguana_rwvarint(0,data,&x);
        for (i=0; i<x; i++)
        {
            memset(&A,0,sizeof(A));
            if ( addr != 0 )
                len += iguana_rwaddr(0,&data[len],&A,(int32_t)addr->protover);
            iguana_gotaddr(coin,addr,&A);
        }
        if ( len == datalen && addr != 0 )
        {
            addr->lastgotaddr = (uint32_t)time(NULL);
            addr->msgcounts.addr++;
        }
        //printf("%s -> addr datalen.%d num.%d\n",addr->ipaddr,datalen,(int32_t)x);
    }
    else if ( strcmp(H->command,"headers") == 0 )
    {
        struct iguana_msgblock msg; struct iguana_block *blocks; uint32_t n;
        len = iguana_rwvarint32(0,data,&n);
        if ( n <= IGUANA_MAXINV )
        {
            blocks = mycalloc('i',1,sizeof(*blocks) * n);
            height = -1;
            for (i=0; i<n; i++)
            {
                len += iguana_rwblock(0,&hash2,&data[len],&msg);
                if ( i == 0 )
                    height = iguana_setchainvars(coin,&firsttxidind,&firstvout,&firstvin,&PoW,hash2,msg.H.bits,msg.H.prev_block,msg.txn_count);
                iguana_convblock(&blocks[i],&msg,hash2,height,firsttxidind,firstvout,firstvin,PoW);
                if ( firsttxidind > 0 )
                {
                    height++;
                    firsttxidind += blocks[i].txn_count;
                    PoW += PoW_from_compact(blocks[i].bits,coin->chain->unitval);
                }
            }
            //printf("GOT HEADERS n.%d len.%d\n",n,len);
            iguana_gotheadersM(coin,addr,blocks,n);
            //myfree(blocks,sizeof(*blocks) * n);
            if ( len == datalen && addr != 0 )
                addr->msgcounts.headers++;
        } else printf("got unexpected n.%d for headers\n",n);
    }
    else if ( strcmp(H->command,"tx") == 0 )
    {
        struct iguana_msgtx *tx;
        tx = mycalloc('u',1,sizeof(*tx));
        len = iguana_rwtx(0,data,tx,datalen,&tx->txid,-1,coin->chain->hastimestamp);
        if ( len == datalen && addr != 0 )
        {
            iguana_gotunconfirmedM(coin,addr,tx,data,datalen);
            printf("tx datalen.%d\n",datalen);
            addr->msgcounts.tx++;
        }
    }
    else if ( strcmp(H->command,"block") == 0 )
    {
        struct iguana_block *block; struct iguana_msgtx *tx; uint8_t extra[256];
        block = mycalloc('b',1,sizeof(*block));
        memset(extra,0,sizeof(extra));
        tx = iguana_gentxarray(coin,&len,block,data,datalen,extra);
        if ( len == datalen )
        {
            if ( addr != 0 )
            {
                if ( len == datalen )
                    addr->msgcounts.block++;
                //addr->OV.reqrecv += datalen;
                //printf("%s gotblock.%d datalen.%d last.[%02x]\n",addr->ipaddr,block->height,datalen,data[len-1]);
            }
            iguana_gotblockM(coin,addr,block,tx,block->txn_count,data,datalen,extra);
        } else printf("parse error block txn_count.%d, len.%d vs datalen.%d\n",block->txn_count,len,datalen);
        //if ( tx != 0 )
        //    iguana_freetx(tx,block->txn_count);
        //myfree(block,sizeof(*block));
    }
    else if ( strcmp(H->command,"reject") == 0 )
    {
        for (i=0; i<datalen; i++)
            printf("%02x ",data[i]);
        printf("reject.(%s) datalen.%d\n",data+1,datalen);
        len = datalen;
        if ( len == datalen && addr != 0 )
            addr->msgcounts.reject++;
    }
    else if ( strcmp(H->command,"alert") == 0 )
    {
        for (i=0; i<datalen; i++)
            printf("%02x ",data[i]);
        printf("alert.(%s)\n",data+1);
        len = datalen;
        if ( len == datalen && addr != 0 )
            addr->msgcounts.alert++;
    }
    else if ( addr != 0 )
    {
        if ( strcmp(H->command,"inv") == 0 )
            intvectors = 'I', addr->msgcounts.inv++;
        else if ( strcmp(H->command,"notfound") == 0 ) // for servers
            intvectors = 'N', addr->msgcounts.notfound++;
        else if ( strcmp(H->command,"getdata") == 0 ) // for servers
            intvectors = srvmsg = 'D', addr->msgcounts.getdata++;
        else if ( strcmp(H->command,"getblocks") == 0 ) // for servers
            srvmsg = 'B', addr->msgcounts.getblocks++;
        else if ( strcmp(H->command,"getheaders") == 0 ) // for servers
            srvmsg = 'H', addr->msgcounts.getheaders++;
        else if ( strcmp(H->command,"getaddr") == 0 ) // for servers
            srvmsg = 'A', addr->msgcounts.getaddr++;
        else if ( strcmp(H->command,"mempool") == 0 ) // for servers
            srvmsg = 'M', addr->msgcounts.mempool++;
        else if ( strcmp(H->command,"filterload") == 0 ) // for bloom
            bloom = 'L', addr->msgcounts.filterload++;
        else if ( strcmp(H->command,"filteradd") == 0 ) // for bloom
            bloom = 'A', addr->msgcounts.filteradd++;
        else if ( strcmp(H->command,"filterclear") == 0 ) // for bloom
            bloom = 'C', addr->msgcounts.filterclear++;
        else if ( strcmp(H->command,"merkleblock") == 0 ) // for bloom
            bloom = 'M', addr->msgcounts.merkleblock++;
    }
    if ( bloom >= 0 || srvmsg >= 0 )
        len = datalen; // just mark as valid
    if ( intvectors >= 0 )
    {
        bits256 *txids=0,*blockhashes=0,hash; int32_t n,m;
        len = n = m = 0;
        len += iguana_rwvarint(0,&data[len],&x);
        for (i=0; i<x; i++)
        {
            len += iguana_rwnum(0,&data[len],sizeof(uint32_t),&type);
            len += iguana_rwbignum(0,&data[len],sizeof(bits256),hash.bytes);
            if ( type == MSG_TX )
            {
                if ( txids == 0 )
                    txids = mycalloc('t',(int32_t)x,sizeof(*txids));
                txids[m++] = hash;
                if ( (rand() % 1000) == 0 && i == x-1 )
                    printf("%s iv.%c %d of %d: tx.%llx len.%d\n",addr->ipaddr,intvectors,i,(int32_t)x,(long long)hash.txid,len);
            }
            else if ( type == MSG_BLOCK )
            {
                if ( blockhashes == 0 )
                    blockhashes = mycalloc('f',(int32_t)x,sizeof(*blockhashes));
                blockhashes[n++] = hash;
                //init_hexbytes_noT(hashstr,hash.bytes,sizeof(hash));
                //queue_enqueue("blocksQ",&coin->blocksQ,queueitem(hashstr),1);
                //if ( i == x-2 )
                //    queue_enqueue("hdrsQ",&coin->hdrsQ,queueitem(hashstr),1);
                //printf("iv.%d %d of %d: block.%llx len.%d %s\n",intvectors,i,(int32_t)x,(long long)hash.txid,len,bits256_str(hash));
            }
            else if ( type == MSG_FILTERED_BLOCK )
                printf("iv.%d %d of %d: merkle.%llx\n",intvectors,i,(int32_t)x,(long long)hash.txid);
            else printf("what type is %d\n",type);
        }
        if ( intvectors == 'I' )
        {
            if ( n > 0 )
            {
                if ( n != x )
                {
                    //printf("n.%d != x.%d -> realloc blockhashes\n",n,(int32_t)x);
                    blockhashes = myrealloc('f',blockhashes,(int32_t)(x*sizeof(*blockhashes)),n*sizeof(*blockhashes));
                } // else printf("n.%d == x.%d\n",n,(int32_t)x);
                iguana_gotblockhashesM(coin,addr,blockhashes,n), blockhashes = 0;
            }
            if ( m > 0 )
            {
                if ( m != x )
                    txids = myrealloc('t',txids,(int32_t)(x*sizeof(*txids)),m*sizeof(*txids));
                iguana_gottxidsM(coin,addr,txids,m), txids = 0;
            }
        }
        if ( txids != 0 )
            myfree(txids,sizeof(*txids) * x);
        if ( blockhashes != 0 )
            myfree(blockhashes,sizeof(*blockhashes) * x);
        //printf("intvectors.%c datalen.%d\n",intvectors,datalen);
    }
    if ( len != datalen && len != datalen-1 )
    {
        //printf("error.(%s) (%s): len.%d != datalen.%d\n",H->command,addr->ipaddr,len,datalen);
        //for (i=0; i<len; i++)
        //    printf("%02x",data[i]);
        if ( strcmp(H->command,"addr") != 0 )
            printf("%s.%s len mismatch %d != %d\n",addr!=0?addr->ipaddr:"local",H->command,len,datalen);
    }
    else if ( len == datalen-1 )
    {
        printf("extra byte.[%02x] command.%s len.%d datalen.%d\n",data[datalen-1],H->command,len,datalen);
        //retval = -1;
    }
    return(retval);
}
示例#12
0
int32_t iguana_msgparser(struct iguana_info *coin,struct iguana_peer *addr,struct OS_memspace *rawmem,struct OS_memspace *txmem,struct OS_memspace *hashmem,struct iguana_msghdr *H,uint8_t *data,int32_t recvlen)
{
    uint8_t serialized[512]; char *retstr;
    int32_t i,retval,delay,srvmsg,bloom,intvectors,len= -100; uint64_t nonce,x; uint32_t type; bits256 hash2;
    bloom = intvectors = srvmsg = -1;
    if ( addr != 0 )
    {
        addr->lastcontact = (uint32_t)time(NULL);
        strcpy(addr->lastcommand,H->command);
    }
    retval = 0;
    //printf("iguana_msgparser %s parse.(%s)\n",addr->ipaddr,H->command);
    if ( strncmp(H->command,"SuperNET",strlen("SuperNET")) == 0 )
    {
        addr->supernet = 1;
        addr->msgcounts.verack++;
        len = recvlen;
        if ( (retstr= SuperNET_p2p(coin,addr,&delay,addr->ipaddr,data,recvlen,H->command[strlen("SuperNET")]=='b')) != 0 )
        {
            iguana_send_supernet(coin,addr,retstr,delay);
            free(retstr);
        }
        //printf("GOT.(%s) [%s] len.%d from %s -> (%s)\n",H->command,data,recvlen,addr->ipaddr,retstr==0?"null":retstr);
    }
    else if ( strcmp(H->command,"version") == 0 )
    {
        struct iguana_msgversion recvmv;
        if ( addr != 0 )
        {
            len = iguana_rwversion(0,data,&recvmv,addr->ipaddr,recvlen);
            if ( len <= recvlen )
                iguana_gotversion(coin,addr,&recvmv);
            //printf("deser.(%s) len.%d recvlen.%d\n",recvmv.H.command,len,recvlen);
            addr->msgcounts.version++;
        }
    }
    else if ( strcmp(H->command,"verack") == 0 )
    {
        if ( addr != 0 )
        {
            iguana_gotverack(coin,addr);
            addr->msgcounts.verack++;
        }
        len = 0;
    }
    else if ( strcmp(H->command,"ConnectTo") == 0 )
    {
        iguana_queue_send(coin,addr,0,serialized,"getaddr",0,0,0);
        len = 6;
    }
    else if ( strcmp(H->command,"ping") == 0 )
    {
        if ( recvlen == sizeof(uint64_t) && addr != 0 )
        {
            len = iguana_rwnum(0,data,sizeof(uint64_t),&nonce);
            if ( addr != 0 )
            {
                //printf("%u got nonce.%llx from %s\n",(uint32_t)time(NULL),(long long)nonce,addr->ipaddr);
                iguana_gotping(coin,addr,nonce,data);
                addr->msgcounts.ping++;
            }
            iguana_queue_send(coin,addr,0,serialized,"getaddr",0,0,0);
        }
    }
    else if ( strcmp(H->command,"pong") == 0 )
    {
        len = 0;
        if ( recvlen == sizeof(uint64_t) )
        {
            len = iguana_rwnum(0,data,sizeof(uint64_t),&nonce);
            iguana_gotpong(coin,addr,nonce);
        } else printf("unexpected pong recvlen.%d\n",recvlen);
        if ( len == recvlen && addr != 0 )
            addr->msgcounts.pong++;
        iguana_queue_send(coin,addr,0,serialized,"getaddr",0,0,0);
    }
    else if ( strcmp(H->command,"addr") == 0 )
    {
        struct iguana_msgaddress A;
        len = iguana_rwvarint(0,data,&x);
        for (i=0; i<x; i++)
        {
            memset(&A,0,sizeof(A));
            if ( addr != 0 )
                len += iguana_rwaddr(0,&data[len],&A,(int32_t)addr->protover);
            iguana_gotaddr(coin,addr,&A);
        }
        if ( len == recvlen && addr != 0 )
        {
            addr->lastgotaddr = (uint32_t)time(NULL);
            addr->msgcounts.addr++;
        }
        //printf("%s -> addr recvlen.%d num.%d\n",addr->ipaddr,recvlen,(int32_t)x);
    }
    else if ( strcmp(H->command,"headers") == 0 )
    {
        struct iguana_msgblock msg; struct iguana_block *blocks; uint32_t n;
        len = iguana_rwvarint32(0,data,&n);
        if ( n <= IGUANA_MAXINV )
        {
            blocks = mycalloc('i',1,sizeof(*blocks) * n);
            for (i=0; i<n; i++)
            {
                len += iguana_rwblock(0,&hash2,&data[len],&msg);
                iguana_blockconv(&blocks[i],&msg,hash2,-1);
            }
            iguana_gotheadersM(coin,addr,blocks,n);
            //myfree(blocks,sizeof(*blocks) * n);
            if ( len == recvlen && addr != 0 )
                addr->msgcounts.headers++;
        } else printf("got unexpected n.%d for headers\n",n);
        //printf("GOT HEADERS n.%d len.%d\n",n,len);
    }
    else if ( strcmp(H->command,"tx") == 0 )
    {
        struct iguana_msgtx *tx;
        iguana_memreset(rawmem);
        tx = iguana_memalloc(rawmem,sizeof(*tx),1);//mycalloc('u',1,sizeof(*tx));
        len = iguana_rwtx(0,rawmem,data,tx,recvlen,&tx->txid,coin->chain->hastimestamp,strcmp(coin->symbol,"VPN")==0);
        iguana_gotunconfirmedM(coin,addr,tx,data,recvlen);
        printf("tx recvlen.%d vs len.%d\n",recvlen,len);
        addr->msgcounts.tx++;
    }
    else if ( strcmp(H->command,"block") == 0 )
    {
        struct iguana_txblock txdata;
        if ( addr != 0 )
            addr->msgcounts.block++;
        iguana_memreset(rawmem), iguana_memreset(txmem);//, iguana_memreset(hashmem);
        memset(&txdata,0,sizeof(txdata));
        if ( (len= iguana_gentxarray(coin,rawmem,&txdata,&len,data,recvlen)) == recvlen )
            iguana_gotblockM(coin,addr,&txdata,rawmem->ptr,H,data,recvlen);
        else printf("parse error block txn_count.%d, len.%d vs recvlen.%d\n",txdata.block.RO.txn_count,len,recvlen);
    }
    else if ( strcmp(H->command,"reject") == 0 )
    {
        for (i=0; i<recvlen; i++)
            printf("%02x ",data[i]);
        printf("reject.(%s) recvlen.%d\n",data+1,recvlen);
        len = recvlen;
        if ( len == recvlen && addr != 0 )
            addr->msgcounts.reject++;
    }
    else if ( strcmp(H->command,"alert") == 0 )
    {
        for (i=0; i<recvlen; i++)
            printf("%02x ",data[i]);
        printf("alert.(%s)\n",data+1);
        len = recvlen;
        if ( len == recvlen && addr != 0 )
            addr->msgcounts.alert++;
    }
    else if ( addr != 0 )
    {
        if ( strcmp(H->command,"inv") == 0 )
            intvectors = 'I', addr->msgcounts.inv++;
        else if ( strcmp(H->command,"notfound") == 0 ) // for servers
            intvectors = 'N', addr->msgcounts.notfound++;
        else if ( strcmp(H->command,"getdata") == 0 ) // for servers
        {
            intvectors = srvmsg = 'D', addr->msgcounts.getdata++;
        }
        else if ( strcmp(H->command,"getblocks") == 0 ) // for servers
        {
            srvmsg = 'B', addr->msgcounts.getblocks++;
        }
        else if ( strcmp(H->command,"getheaders") == 0 ) // for servers
        {
            srvmsg = 'H', addr->msgcounts.getheaders++;
        }
        else if ( strcmp(H->command,"getaddr") == 0 )
        {
            srvmsg = 'A', addr->msgcounts.getaddr++;
        }
        else if ( strcmp(H->command,"mempool") == 0 )
            srvmsg = 'M', addr->msgcounts.mempool++;
        else if ( strcmp(H->command,"filterload") == 0 ) // for bloom
            bloom = 'L', addr->msgcounts.filterload++;
        else if ( strcmp(H->command,"filteradd") == 0 ) // for bloom
            bloom = 'A', addr->msgcounts.filteradd++;
        else if ( strcmp(H->command,"filterclear") == 0 ) // for bloom
            bloom = 'C', addr->msgcounts.filterclear++;
        else if ( strcmp(H->command,"merkleblock") == 0 ) // for bloom
            bloom = 'M', addr->msgcounts.merkleblock++;
    }
    if ( bloom >= 0 || srvmsg >= 0 )
        len = recvlen; // just mark as valid
    if ( intvectors >= 0 )
    {
        bits256 *txids=0,*blockhashes=0,hash; int32_t n,m;
        len = n = m = 0;
        len += iguana_rwvarint(0,&data[len],&x);
        for (i=0; i<x; i++)
        {
            len += iguana_rwnum(0,&data[len],sizeof(uint32_t),&type);
            len += iguana_rwbignum(0,&data[len],sizeof(bits256),hash.bytes);
            if ( type == MSG_TX )
            {
                if ( txids == 0 )
                    txids = mycalloc('t',(int32_t)x+1,sizeof(*txids));
                txids[m++] = hash;
                if ( (rand() % 1000) == 0 && i == x-1 )
                    printf("%s iv.%c %d of %d: tx.%llx len.%d\n",addr->ipaddr,intvectors,i,(int32_t)x,(long long)hash.txid,len);
            }
            else if ( type == MSG_BLOCK )
            {
                if ( blockhashes == 0 )
                {
                    blockhashes = mycalloc('f',(int32_t)x+1,sizeof(*blockhashes));
                    n = 1;
                }
                blockhashes[n++] = hash;
            }
            else if ( type == MSG_FILTERED_BLOCK )
                printf("iv.%d %d of %d: merkle.%llx\n",intvectors,i,(int32_t)x,(long long)hash.txid);
            else printf("what type is %d\n",type);
        }
        if ( intvectors == 'I' )
        {
            if ( n > 0 )
            {
                if ( n != x+1 )
                {
                    printf("n.%d != x.%d -> realloc blockhashes\n",n,(int32_t)x+1);
                    blockhashes = myrealloc('f',blockhashes,(int32_t)((x+1)*sizeof(*blockhashes)),n*sizeof(*blockhashes));
                } // else printf("n.%d == x.%d\n",n,(int32_t)x);
                if ( 1 )
                    iguana_gotblockhashesM(coin,addr,blockhashes,n), blockhashes = 0;
                else iguana_send_hashes(coin,"getblocks",addr,blockhashes[0],&blockhashes[1],n);
            }
            if ( m > 0 )
            {
                if ( m != x )
                    txids = myrealloc('t',txids,(int32_t)((x+1)*sizeof(*txids)),(m+1)*sizeof(*txids));
                iguana_gottxidsM(coin,addr,txids,m), txids = 0;
            }
        }
        if ( txids != 0 )
            myfree(txids,sizeof(*txids) * (x+1));
        if ( blockhashes != 0 )
            myfree(blockhashes,sizeof(*blockhashes) * (x+1));
        //printf("intvectors.%c recvlen.%d\n",intvectors,recvlen);
    }
    if ( len != recvlen && len != recvlen-1 && len != recvlen-2 )
    {
        //printf("error.(%s) (%s): len.%d != recvlen.%d\n",H->command,addr->ipaddr,len,recvlen);
        //for (i=0; i<len; i++)
        //    printf("%02x",data[i]);
        if ( strcmp(H->command,"addr") != 0 )
            printf("%s.%s len mismatch %d != %d\n",addr!=0?addr->ipaddr:"local",H->command,len,recvlen);
    }
    else if ( len != recvlen )
    {
        printf("%s extra byte.[%02x] command.%s len.%d recvlen.%d\n",addr->ipaddr,data[recvlen-1],H->command,len,recvlen);
        //retval = -1;
    }
    return(retval);
}
示例#13
0
cJSON *iguana_blockjson(struct supernet_info *myinfo,struct iguana_info *coin,struct iguana_block *block,int32_t txidsflag)
{
    char str[65],hexstr[1024]; int32_t i,len,size; struct iguana_txid *tx,T; struct iguana_msgzblock zmsg; struct iguana_msgblock *msg = (void *)&zmsg; struct iguana_zblock *zblock;
    bits256 hash2,nexthash2; uint8_t serialized[1024]; cJSON *array,*json = cJSON_CreateObject();
    jaddstr(json,"result","success");
    jaddstr(json,"hash",bits256_str(str,block->RO.hash2));
    jaddnum(json,"height",block->height);
    //jaddnum(json,"ipbits",block->fpipbits);
    jaddstr(json,"merkleroot",bits256_str(str,block->RO.merkle_root));
    jaddstr(json,"previousblockhash",bits256_str(str,block->RO.prev_block));
    if ( block->height > 0 )
    {
        nexthash2 = iguana_blockhash(coin,block->height+1);
        if ( bits256_nonz(nexthash2) != 0 )
            jaddstr(json,"nextblockhash",bits256_str(str,nexthash2));
    }
    jaddnum(json,"timestamp",block->RO.timestamp);
    jaddstr(json,"utc",utc_str(str,block->RO.timestamp));
    jaddnum(json,"nonce",block->RO.nonce);
    jaddnum(json,"version",block->RO.version);
    jaddnum(json,"numvouts",block->RO.numvouts);
    jaddnum(json,"numvins",block->RO.numvins);
    jaddnum(json,"recvlen",block->RO.recvlen);
    jaddnum(json,"hdrsi",block->hdrsi);
    jaddnum(json,"difficulty",PoW_from_compact(block->RO.bits,coin->chain->unitval));
    jaddnum(json,"bundlei",block->bundlei);
    jaddnum(json,"mainchain",block->mainchain);
    jaddnum(json,"valid",block->valid);
    jaddnum(json,"txn_count",block->RO.txn_count);
    
    jaddnum(json,"nBits",block->RO.bits);
    serialized[0] = ((uint8_t *)&block->RO.bits)[3];
    serialized[1] = ((uint8_t *)&block->RO.bits)[2];
    serialized[2] = ((uint8_t *)&block->RO.bits)[1];
    serialized[3] = ((uint8_t *)&block->RO.bits)[0];
    init_hexbytes_noT(hexstr,serialized,sizeof(uint32_t));
    jaddstr(json,"nBitshex",hexstr);
    if ( block->RO.allocsize == sizeof(struct iguana_zblock) )
    {
        zblock = (void *)block;
        memset(&zmsg,0,sizeof(zmsg));
        zmsg.zH.version = zblock->RO.version;
        zmsg.zH.merkle_root = zblock->RO.merkle_root;
        zmsg.zH.timestamp = zblock->RO.timestamp;
        zmsg.zH.bits = zblock->RO.bits;
        zmsg.zH.bignonce = zblock->zRO.bignonce;
        if ( iguana_rwvarint32(1,zmsg.zH.var_numelements,&zblock->zRO.numelements) != sizeof(zmsg.zH.var_numelements) )
            printf("unexpected varint size for zmsg.zH.numelements <- %d\n",zblock->zRO.numelements);
        for (i=0; i<ZCASH_SOLUTION_ELEMENTS; i++)
            zmsg.zH.solution[i] = zblock->zRO.solution[i];
        zmsg.txn_count = 0;//block->RO.txn_count;
        len = iguana_rwblock(myinfo,coin->symbol,coin->chain->zcash,coin->chain->auxpow,coin->chain->hashalgo,1,&hash2,serialized,&zmsg,IGUANA_MAXPACKETSIZE*2);
    }
    else
    {
        memset(msg,0,sizeof(&msg));
        msg->H.version = block->RO.version;
        msg->H.prev_block = block->RO.prev_block;
        msg->H.merkle_root = block->RO.merkle_root;
        msg->H.timestamp = block->RO.timestamp;
        msg->H.bits = block->RO.bits;
        msg->H.nonce = block->RO.nonce;
        msg->txn_count = 0;//block->RO.txn_count;
        len = iguana_rwblock(myinfo,coin->symbol,coin->chain->zcash,coin->chain->auxpow,coin->chain->hashalgo,1,&hash2,serialized,&zmsg,IGUANA_MAXPACKETSIZE*2);
    }
    init_hexbytes_noT(hexstr,serialized,len);
    jaddstr(json,"blockheader",hexstr);
    if ( txidsflag != 0 )
    {
        array = cJSON_CreateArray();
        for (i=0; i<block->RO.txn_count; i++)
        {
            if ( (tx= iguana_blocktx(coin,&T,block,i)) != 0 )
                jaddistr(array,bits256_str(str,tx->txid));
        }
        jadd(json,"tx",array);
        //printf("add txids[%d]\n",block->txn_count);
    }
    if ( (size= iguana_peerblockrequest(myinfo,coin,coin->blockspace,coin->blockspacesize,0,block->RO.hash2,0)) < 0 )
        jaddstr(json,"error","couldnt generate raw bytes for block");
    else jaddnum(json,"size",size);
    return(json);
}
示例#14
0
int32_t iguana_ramtxbytes(struct iguana_info *coin,uint8_t *serialized,int32_t maxlen,bits256 *txidp,struct iguana_txid *tx,int32_t height,struct iguana_msgvin *vins,struct iguana_msgvout *vouts,int32_t validatesigs)
{
    int32_t i,rwflag=1,len = 0; char asmstr[512],txidstr[65];
    uint32_t numvins,numvouts,version,locktime,timestamp=0; struct iguana_msgvin vin; struct iguana_msgvout vout; uint8_t space[IGUANA_MAXSCRIPTSIZE];
    if ( rwflag != 0 )
    {
        version = tx->version;
        locktime = tx->locktime;
        timestamp = tx->timestamp;
        numvins = tx->numvins;
        numvouts = tx->numvouts;
    }
    len += iguana_rwnum(rwflag,&serialized[len],sizeof(version),&version);
    if ( coin->chain->isPoS != 0 )
        len += iguana_rwnum(rwflag,&serialized[len],sizeof(timestamp),&timestamp);
    len += iguana_rwvarint32(rwflag,&serialized[len],&numvins);
    memset(&vin,0,sizeof(vin));
    for (i=0; i<numvins; i++)
    {
        if ( vins == 0 )
        {
            if ( iguana_vinset(coin,space,height,&vin,tx,i) < 0 )
            {
                printf("iguana_ramtxbytes vinset error %d of %d\n",i,numvins);
                return(0);
            }
        } else vin = vins[i];
        len += iguana_rwvin(rwflag,coin,0,&serialized[len],&vin,i);
        if ( len > maxlen )
            break;
    }
    if ( len > maxlen )
    {
        printf("len.%d > maxlen.%d\n",len,maxlen);
        return(0);
    }
    len += iguana_rwvarint32(rwflag,&serialized[len],&numvouts);
    for (i=0; i<numvouts; i++)
    {
        if ( vouts == 0 )
        {
            if ( iguana_voutset(coin,space,asmstr,height,&vout,tx,i) < 0 )
            {
                static uint32_t counter;
                if ( counter++ < 10 )
                    printf("iguana_ramtxbytes voutset error %d of %d\n",i,numvouts);
                return(0);
            }
        } else vout = vouts[i];
        len += iguana_rwvout(rwflag,0,&serialized[len],&vout);
        if ( len > maxlen )
            break;
    }
    if ( len > maxlen )
    {
        printf("len.%d > maxlenB.%d\n",len,maxlen);
        return(0);
    }
    len += iguana_rwnum(rwflag,&serialized[len],sizeof(locktime),&locktime);
    if ( rwflag == 0 )
    {
        tx->version = version;
        tx->timestamp = timestamp;
        tx->numvins = numvins;
        tx->numvouts = numvouts;
        tx->locktime = locktime;
    }
    *txidp = bits256_doublesha256(txidstr,serialized,len);
    if ( memcmp(txidp,tx->txid.bytes,sizeof(*txidp)) != 0 )
    {
        for (i=0; i<len; i++)
            printf("%02x",serialized[i]);
        char str[65],str2[65]; printf("\nrw.%d numvins.%d numvouts.%d error generating txbytes txid %s vs %s\n",rwflag,numvins,numvouts,bits256_str(str,*txidp),bits256_str(str2,tx->txid));
        return(-1);
    }
    return(len);
}