Example #1
0
int32_t iguana_peerhdrrequest(struct iguana_info *coin,uint8_t *serialized,int32_t maxsize,struct iguana_peer *addr,bits256 hash2)
{
    int32_t len=0,i,flag=0,height,n,hdrsi,bundlei,bundlesize,firstvout,retval=-1;
    struct iguana_block *block;
    struct iguana_bundle *bp;
    if ( (firstvout= iguana_unspentindfind(coin,0,0,0,0,&height,hash2,0,coin->bundlescount-1,0)) != 0 )
    {
        bundlesize = coin->chain->bundlesize;
        hdrsi = (height / bundlesize);
        bundlei = height - (hdrsi * bundlesize);
        if ( hdrsi >= 0 && hdrsi < bundlesize && bundlei >= 0 && bundlei < bundlesize && (bp= coin->bundles[hdrsi]) != 0 )
        {
            for (i=0; i<coin->chain->bundlesize; i++)
            {
                if ( (block= bp->blocks[i]) != 0 )
                {
                    if ( (n= iguana_headerget(coin,&serialized[len],maxsize-len,block)) < 0 )
                    {
                        printf("%s error getting header ht.%d\n",coin->symbol,block->height);
                        continue;
                    }
                    len += n;
                } else printf("cant find block at ht.%d\n",height+i);
            }
        }
        if ( flag != 0 )
            retval = iguana_queue_send(addr,0,serialized,"headers",len);
        //printf("hdrs request retval.%d len.%d\n",retval,len);
    } //else printf("couldnt find header\n");
    return(retval);
}
Example #2
0
int32_t iguana_send_ConnectTo(struct iguana_info *coin,struct iguana_peer *addr)
{
  	int32_t len; uint32_t r; uint16_t port = 1920; uint8_t serialized[sizeof(struct iguana_msghdr) + 6];
    r = rand();
    len = iguana_rwnum(1,&serialized[sizeof(struct iguana_msghdr)],sizeof(uint32_t),&r);
    len += iguana_rwnum(1,&serialized[sizeof(struct iguana_msghdr)+len],sizeof(port),&port);
    return(iguana_queue_send(coin,addr,0,serialized,"ConnectTo",len,0,0));
}
Example #3
0
void iguana_gotping(struct iguana_info *coin,struct iguana_peer *addr,uint64_t nonce,uint8_t *data)
{
    int32_t len; uint8_t serialized[sizeof(struct iguana_msghdr) + sizeof(nonce)];
    len = iguana_rwnum(1,&serialized[sizeof(struct iguana_msghdr)],sizeof(uint64_t),&nonce);
    if ( memcmp(data,&serialized[sizeof(struct iguana_msghdr)],sizeof(nonce)) != 0 )
        printf("ping ser error %llx != %llx\n",(long long)nonce,*(long long *)data);
    iguana_queue_send(coin,addr,serialized,"pong",len,0,0);
    //iguana_queue_send(coin,addr,serialized,"getaddr",0,0,0);
}
Example #4
0
void iguana_dedicatedloop(struct iguana_info *coin,struct iguana_peer *addr)
{
    struct pollfd fds; uint8_t *buf,serialized[64]; int32_t bufsize,flag,timeout = coin->MAXPEERS/64+1;
    printf("start dedicatedloop.%s\n",addr->ipaddr);
    bufsize = IGUANA_MAXPACKETSIZE;
    buf = mycalloc('r',1,bufsize);
    //printf("send version myservices.%llu\n",(long long)coin->myservices);
    iguana_send_version(coin,addr,coin->myservices);
    iguana_queue_send(coin,addr,serialized,"getaddr",0,0,0);
    //printf("after send version\n");
    while ( addr->usock >= 0 && addr->dead == 0 && coin->peers.shuttingdown == 0 )
    {
        flag = 0;
        memset(&fds,0,sizeof(fds));
        fds.fd = addr->usock;
        fds.events |= POLLOUT;
        if (  poll(&fds,1,timeout) > 0 )
            flag += iguana_pollsendQ(coin,addr);
        if ( flag == 0 )
        {
            memset(&fds,0,sizeof(fds));
            fds.fd = addr->usock;
            fds.events |= POLLIN;
            if ( poll(&fds,1,timeout) > 0 )
                flag += iguana_pollrecv(coin,addr,buf,bufsize);
            if ( flag == 0 )
            {
                if ( time(NULL) > addr->pendtime+30 )
                {
                    if ( addr->pendblocks > 0 )
                        addr->pendblocks--;
                    if ( addr->pendhdrs > 0 )
                        addr->pendhdrs--;
                    addr->pendtime = 0;
                }
                if ( addr->pendblocks < IGUANA_MAXPENDING )
                {
                    //if ( ((int64_t)coin->R.RSPACE.openfiles * coin->R.RSPACE.size) < coin->MAXRECVCACHE )
                    {
                        memset(&fds,0,sizeof(fds));
                        fds.fd = addr->usock;
                        fds.events |= POLLOUT;
                        if ( poll(&fds,1,timeout) > 0 )
                            flag += iguana_pollQs(coin,addr);
                    }
                    //else printf("%s > %llu coin->IGUANA_MAXRECVCACHE\n",mbstr((int64_t)coin->R.RSPACE.openfiles * coin->R.RSPACE.size),(long long)coin->MAXRECVCACHE);
                }
            }
            if ( flag == 0 )//&& iguana_processjsonQ(coin) == 0 )
                usleep(20000);//+ 100000*(coin->blocks.hwmheight > (long)coin->longestchain-coin->minconfirms*2));
        }
    }
    iguana_iAkill(coin,addr,addr->dead != 0);
    printf("finish dedicatedloop.%s\n",addr->ipaddr);
    myfree(buf,bufsize);
    coin->peers.numconnected--;
}
Example #5
0
void iguana_gotversion(struct iguana_info *coin,struct iguana_peer *addr,struct iguana_msgversion *vers)
{
    uint8_t serialized[sizeof(struct iguana_msghdr)];
    //printf("gotversion from %s\n",addr->ipaddr);
    if ( (vers->nServices & NODE_NETWORK) == 0 )
        printf("other node.(%s) doesnt relay\n",addr->ipaddr);
    else if ( (vers->nServices & NODE_NETWORK) != 0 )//&& vers->nonce != coin->instance_nonce )
    {
        addr->protover = (vers->nVersion < PROTOCOL_VERSION) ? vers->nVersion : PROTOCOL_VERSION;
        addr->relayflag = vers->relayflag;
        addr->height = vers->nStartingHeight;
        addr->relayflag = 1;
        iguana_gotdata(coin,addr,addr->height,bits256_zero);
        iguana_queue_send(coin,addr,serialized,"verack",0,0,0);
        //iguana_send_ping(coin,addr);
    } else printf("nServices.%llx nonce.%llu invalid version message from.(%s)\n",(long long)vers->nServices,(long long)vers->nonce,addr->ipaddr);
    if ( vers->nStartingHeight > coin->longestchain )
        coin->longestchain = vers->nStartingHeight;
    iguana_queue_send(coin,addr,serialized,"getaddr",0,0,0);
}
Example #6
0
void iguana_gotversion(struct iguana_info *coin,struct iguana_peer *addr,struct iguana_msgversion *vers)
{
    uint8_t serialized[sizeof(struct iguana_msghdr)];
    printf("gotversion from %s: starting height.%d services.%llx proto.%d\n",addr->ipaddr,vers->nStartingHeight,(long long)vers->nServices,vers->nVersion);
    if ( (vers->nServices & NODE_NETWORK) != 0 )//&& vers->nonce != coin->instance_nonce )
    {
        addr->protover = (vers->nVersion < PROTOCOL_VERSION) ? vers->nVersion : PROTOCOL_VERSION;
        addr->relayflag = vers->relayflag;
        addr->height = vers->nStartingHeight;
        addr->relayflag = 1;
        iguana_gotdata(coin,addr,addr->height);
        iguana_queue_send(coin,addr,0,serialized,"verack",0,0,0);
        //iguana_send_ping(coin,addr);
    }
    if ( (vers->nServices & (1<<7)) == (1<<7) )
        addr->supernet = 1;
    else printf("nServices.%lld nonce.%llu non-relay node.(%s) supernet.%d\n",(long long)vers->nServices,(long long)vers->nonce,addr->ipaddr,addr->supernet);
    if ( vers->nStartingHeight > coin->longestchain )
        coin->longestchain = vers->nStartingHeight;
    iguana_queue_send(coin,addr,0,serialized,"getaddr",0,0,0);
}
Example #7
0
int32_t iguana_send_ping(struct iguana_info *coin,struct iguana_peer *addr)
{
  	int32_t len; uint64_t nonce; uint8_t serialized[sizeof(struct iguana_msghdr) + sizeof(nonce)];
    if ( (nonce= addr->pingnonce) == 0 )
    {
        randombytes((uint8_t *)&nonce,sizeof(nonce));
        addr->pingnonce = nonce;
        addr->pingtime = (uint32_t)time(NULL);
    }
    printf("pingnonce.%llx\n",(long long)nonce);
    len = iguana_rwnum(1,&serialized[sizeof(struct iguana_msghdr)],sizeof(uint64_t),&nonce);
    return(iguana_queue_send(coin,addr,serialized,"ping",len,0,0));
}
Example #8
0
void iguana_gotping(struct iguana_info *coin,struct iguana_peer *addr,uint64_t nonce,uint8_t *data)
{
    int32_t len; uint8_t serialized[sizeof(struct iguana_msghdr) + sizeof(nonce)];
    len = iguana_rwnum(1,&serialized[sizeof(struct iguana_msghdr)],sizeof(uint64_t),&nonce);
    if ( memcmp(data,&serialized[sizeof(struct iguana_msghdr)],sizeof(nonce)) != 0 )
        printf("ping ser error %llx != %llx\n",(long long)nonce,*(long long *)data);
    iguana_queue_send(coin,addr,0,serialized,"pong",len,0,0);
    if ( addr->supernet != 0 )
    {
        printf("send getpeers to %s\n",addr->ipaddr);
        iguana_send_supernet(coin,addr,SUPERNET_GETPEERSTR,0);
    }
}
Example #9
0
int32_t iguana_send_VPNversion(struct iguana_info *coin,struct iguana_peer *addr,uint64_t myservices)
{
  	int32_t len; struct iguana_VPNversion msg; uint8_t serialized[sizeof(struct iguana_msghdr)+sizeof(msg)];
    memset(&msg,0,sizeof(msg));
	msg.nVersion = PROTOCOL_VERSION;
	msg.nServices = myservices;
	msg.nTime = (int64_t)time(NULL);
	msg.nonce = 0;//coin->instance_nonce;
	sprintf(msg.strSubVer,"/Satoshi:0.11.99/");
	msg.nStartingHeight = coin->blocks.hwmchain.height;
    len = iguana_rwversion(1,&serialized[sizeof(struct iguana_msghdr)],(void *)&msg,addr->ipaddr,117);
    return(iguana_queue_send(coin,addr,0,serialized,"version",len,0,1));
}
Example #10
0
int32_t iguana_send_hashes(struct iguana_info *coin,char *command,struct iguana_peer *addr,bits256 stophash,bits256 *hashes,int32_t n)
{
  	uint32_t len,nVersion,varint; int32_t retval = -1; uint8_t *serialized; long size;
    size = sizeof(struct iguana_msghdr) + sizeof(uint64_t) + 1 + sizeof(bits256)*(n+1);
    if ( (varint= n) <= IGUANA_MAXINV )
    {
        serialized = mycalloc('h',1,size);
        nVersion = 0;
        len = iguana_rwblockhash(1,&serialized[sizeof(struct iguana_msghdr)],&nVersion,&varint,hashes,&stophash);
        //printf("%s send_hashes.%d %s height.%d\n",addr->ipaddr,n,bits256_str(hashes[0]),iguana_height(coin,hashes[0]));
        retval = iguana_queue_send(coin,addr,serialized,command,len,0,0);
        myfree(serialized,size);
    } else printf("iguana_send_hashes: unexpected n.%d\n",n);
    return(retval);
}
Example #11
0
void iguana_gotverack(struct iguana_info *coin,struct iguana_peer *addr)
{
    uint8_t serialized[sizeof(struct iguana_msghdr)];
    if ( addr != 0 )
    {
        printf("gotverack from %s\n",addr->ipaddr);
        addr->A.nTime = (uint32_t)time(NULL);
        iguana_queue_send(coin,addr,0,serialized,"getaddr",0,0,0);
        if ( addr->supernet != 0 )
        {
            printf("send getpeers to %s\n",addr->ipaddr);
            iguana_send_supernet(coin,addr,SUPERNET_GETPEERSTR,0);
        }
    }
}
Example #12
0
int32_t gecko_blocksubmit(struct supernet_info *myinfo,struct iguana_info *btcd,struct iguana_info *virt,char *blockstr,bits256 hash2,int32_t height)
{
    uint8_t *data,space[16384],*allocptr=0; int32_t i,len,numranked=0; struct iguana_peers *peers; struct iguana_peer *addr;
    //printf("submit.(%s)\n",blockstr);
    if ( (peers= virt->peers) == 0 || (numranked= peers->numranked) <= 0 )
    {
        if ( basilisk_blocksubmit(myinfo,btcd,virt,0,blockstr,hash2,height) < 0 )//(NUMRELAYS >> 1) )
            return(-1);
    }
    else // physical node for geckochain
    {
        if ( (data= get_dataptr(sizeof(struct iguana_msghdr),&allocptr,&len,space,sizeof(space),blockstr)) != 0 )
        {
            for (i=0; i<numranked; i++)
            {
                if ( (addr= peers->ranked[i]) != 0 && addr->usock >= 0 && addr->supernet != 0 )
                    iguana_queue_send(addr,0,data,"block",len);
            }
        }
        if ( allocptr != 0 )
            free(allocptr);
    }
    return(0);
}
Example #13
0
int32_t iguana_process_msgrequestQ(struct supernet_info *myinfo,struct iguana_info *coin)
{
    struct iguana_peermsgrequest *msg;
    int32_t height,len,flag = 0;
    bits256 checktxid;
    struct iguana_txid *tx,T;
    struct iguana_peer *addr;
    if ( (msg= queue_dequeue(&coin->msgrequestQ,0)) != 0 )
    {
        flag = 1;
        if ( msg->addr != 0 )
        {
            //char str[65]; printf("send type.%d %s -> (%s)\n",msg->type,bits256_str(str,msg->hash2),msg->addr->ipaddr);
            if ( msg->type == MSG_BLOCK )
            {
                if ( coin->RELAYNODE != 0 || coin->VALIDATENODE != 0 )
                {
                    if ( (addr= msg->addr) != 0 && (len= iguana_peerblockrequest(coin,coin->blockspace,(int32_t)(coin->blockspacesize - sizeof(struct iguana_msghdr)),0,msg->hash2,0)) > 0 )
                    {
                        //char str[65]; printf("msg Sendlen.%d block %s to %s\n",len,bits256_str(str,msg->hash2),addr->ipaddr);
                        iguana_queue_send(addr,0,coin->blockspace,"block",len);
                    }
                }
            }
            else if ( msg->type == MSG_TX )
            {
                if ( coin->RELAYNODE != 0 || coin->VALIDATENODE )
                {
                    if ( (tx= iguana_txidfind(coin,&height,&T,msg->hash2,coin->bundlescount-1)) != 0 )
                    {
                        if ( (len= iguana_ramtxbytes(coin,&coin->blockspace[sizeof(struct iguana_msghdr)],coin->blockspacesize,&checktxid,tx,height,0,0,0)) > 0 )
                        {
                            char str[65],str2[65];
                            if ( bits256_cmp(msg->hash2,checktxid) == 0 )
                                iguana_queue_send(msg->addr,0,coin->blockspace,"block",len);
                            else printf("checktxid mismatch (%s) != (%s)\n",bits256_str(str,msg->hash2),bits256_str(str2,checktxid));
                        }
                    }
                }
            }
            else if ( msg->type == MSG_FILTERED_BLOCK )
            {

            }
            else if ( msg->type == MSG_BUNDLE_HEADERS )
            {

            }
            else if ( msg->type == MSG_BUNDLE )
            {

            }
            /*else if ( msg->type == MSG_QUOTE )
            {
                if ( (len= instantdex_quoterequest(myinfo,coin,&coin->blockspace[sizeof(struct iguana_msghdr)],coin->blockspacesize,msg->addr,msg->hash2)) > 0 )
                {
                    //iguana_sethdr((void *)coin->blockspace,coin->chain->netmagic,"quote",&coin->blockspace[sizeof(struct iguana_msghdr)],len);
                    //iguana_msgparser(coin,msg->addr,0,0,0,(void *)coin->blockspace,&coin->blockspace[sizeof(struct iguana_msghdr)],len);
                    iguana_queue_send(msg->addr,0,coin->blockspace,"quote",len);
                }
            }*/
        }
        free(msg);
    }
    return(flag);
}
Example #14
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);
}
Example #15
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);
}