uint32_t iguana_possible_peer(struct iguana_info *coin,char *ipaddr) { char checkaddr[64]; uint32_t ipbits,ind,now = (uint32_t)time(NULL); int32_t i; struct iguana_iAddr iA; struct iguana_kvitem item; if ( ipaddr != 0 ) { //printf("Q possible peer.(%s)\n",ipaddr); queue_enqueue("possibleQ",&coin->possibleQ,queueitem(ipaddr),1); return((uint32_t)time(NULL)); } else if ( (ipaddr= queue_dequeue(&coin->possibleQ,1)) == 0 ) return((uint32_t)time(NULL)); #ifdef IGUANA_DISABLEPEERS if ( strcmp(ipaddr,"127.0.0.1") != 0 ) { free_queueitem(ipaddr); return((uint32_t)time(NULL)); } #endif //printf("possible peer.(%s)\n",ipaddr); for (i=0; i<coin->MAXPEERS; i++) if ( strcmp(ipaddr,coin->peers.active[i].ipaddr) == 0 ) { free_queueitem(ipaddr); return((uint32_t)time(NULL)); } if ( strncmp("0.0.0",ipaddr,5) != 0 && strcmp("0.0.255.255",ipaddr) != 0 && strcmp("1.0.0.0",ipaddr) != 0 ) { if ( (ipbits= (uint32_t)calc_ipbits(ipaddr)) != 0 ) { expand_ipbits(checkaddr,ipbits); if ( strcmp(checkaddr,ipaddr) == 0 ) { if ( (ind= iguana_ipbits2ind(coin,&iA,ipbits,1)) > 0 && iA.status != IGUANA_PEER_CONNECTING && iA.status != IGUANA_PEER_READY ) { if ( (iA.lastconnect == 0 || iA.lastkilled == 0) || (iA.numconnects > 0 && iA.lastconnect > (now - IGUANA_RECENTPEER)) || iA.lastkilled < now-600 ) { iA.status = IGUANA_PEER_ELIGIBLE; if ( iguana_rwiAddrind(coin,1,&iA,ind) == 0 ) printf("error updating status for (%s)\n",ipaddr); else if ( coin->peers.numconnected < coin->MAXPEERS ) { memset(&item,0,sizeof(item)); item.hh.itemind = ind; iguana_kvconnectiterator(coin,coin->iAddrs,&item,0,&iA.ipbits,&iA,sizeof(iA)); } } } } else printf("reject ipaddr.(%s)\n",ipaddr); } } free_queueitem(ipaddr); return((uint32_t)time(NULL)); }
void idle() { char *jsonstr,*str; cJSON *json; int32_t n = 0; uint32_t nonce; while ( INSTANTDEX.readyflag == 0 ) sleep(1); while ( 1 ) { if ( n == 0 ) msleep(1000); n = 0; if ( (jsonstr= queue_dequeue(&InstantDEXQ,1)) != 0 ) { if ( (json= cJSON_Parse(jsonstr)) != 0 ) { //printf("Dequeued InstantDEX.(%s)\n",jsonstr); //fprintf(stderr,"dequeued\n"); if ( (str= busdata_sync(&nonce,jsonstr,"allnodes",0)) != 0 ) { //fprintf(stderr,"busdata.(%s)\n",str); free(str); } free_json(json); n++; } else printf("error parsing (%s) from InstantDEXQ\n",jsonstr); free_queueitem(jsonstr); } } }
int32_t iguana_pollQs(struct iguana_info *coin,struct iguana_peer *addr) { uint8_t serialized[sizeof(struct iguana_msghdr) + sizeof(uint32_t)*32 + sizeof(bits256)]; char *hashstr=0,hexstr[65]; bits256 hash2; int32_t height=-1,datalen,flag = 0; struct iguana_blockreq *req=0; if ( iguana_needhdrs(coin) != 0 && addr->pendhdrs == 0 && (hashstr= queue_dequeue(&coin->hdrsQ,1)) != 0 ) { if ( (datalen= iguana_gethdrs(coin,serialized,coin->chain->gethdrsmsg,hashstr)) > 0 ) { decode_hex(hash2.bytes,sizeof(hash2),hashstr); //printf("%s request hdr.(%s) %d pend.%d\n",addr->ipaddr,hashstr,iguana_itemheight(coin,hash2),addr->pendhdrs); iguana_send(coin,addr,serialized,datalen); addr->pendhdrs++; flag++; } else printf("datalen.%d from gethdrs\n",datalen); free_queueitem(hashstr); hashstr = 0; } if ( ((req= queue_dequeue(&coin->priorityQ,0)) != 0 || (req= queue_dequeue(&coin->blocksQ,0)) != 0) ) { hash2 = req->hash2; height = iguana_hash2height(coin,hash2); if ( req->height >= 0 && height != req->height ) { printf("blocksQ ht.%d vs %d dequeued.(%s) for %s\n",req->height,height,bits256_str(hash2),addr->ipaddr); myfree(req,sizeof(*req)); return(0); } if ( height >= 0 && (height < coin->blocks.recvblocks || iguana_blockptr(coin,height) != 0) ) { printf("skip.%d vs recvblocks.%d %p\n",height,coin->blocks.recvblocks,iguana_blockptr(coin,height)); myfree(req,sizeof(*req)); } else { init_hexbytes_noT(hexstr,hash2.bytes,sizeof(hash2)); if ( (datalen= iguana_getdata(coin,serialized,MSG_BLOCK,hexstr)) > 0 ) { //printf("%s %s REQ BLOCK.%d\n",addr->ipaddr,hexstr,iguana_blockheight(coin,hash2)); iguana_send(coin,addr,serialized,datalen); //if ( height >= 0 ) // iguana_setwaitstart(coin,height); addr->pendblocks++; addr->pendtime = (uint32_t)time(NULL); flag++; myfree(req,sizeof(*req)); } else printf("error constructing request %s.%d\n",hexstr,height); } } return(flag); }
// seems a bit wastefull to do all the two iter queueing/dequeuing with threadlock overhead // however, there is assumed to be plenty of CPU time relative to actual blockchain events // also this method allows for adding of parallel threads without worry int32_t process_pingpong_queue(struct pingpong_queue *ppq,void *argptr) { int32_t iter,retval,freeflag = 0; void *ptr; //printf("%p process_pingpong_queue.%s %d %d\n",ppq,ppq->name,queue_size(&ppq->pingpong[0]),queue_size(&ppq->pingpong[1])); for (iter=0; iter<2; iter++) { while ( (ptr= queue_dequeue(&ppq->pingpong[iter],ppq->offset)) != 0 ) { if ( Debuglevel > 2 ) printf("%s pingpong[%d].%p action.%p\n",ppq->name,iter,ptr,ppq->action); retval = (*ppq->action)(&ptr,argptr); if ( retval == 0 ) queue_enqueue(ppq->name,&ppq->pingpong[iter ^ 1],ptr); else if ( ptr != 0 ) { if ( retval < 0 ) { if ( Debuglevel > 0 ) printf("%s iter.%d errorqueue %p vs %p\n",ppq->name,iter,ppq->errorqueue,&ppq->pingpong[0]); if ( ppq->errorqueue == &ppq->pingpong[0] ) queue_enqueue(ppq->name,&ppq->pingpong[iter ^ 1],ptr); else if ( ppq->errorqueue != 0 ) queue_enqueue(ppq->name,ppq->errorqueue,ptr); else freeflag = 1; } else if ( ppq->destqueue != 0 ) { if ( Debuglevel > 0 ) printf("%s iter.%d destqueue %p vs %p\n",ppq->name,iter,ppq->destqueue,&ppq->pingpong[0]); if ( ppq->destqueue == &ppq->pingpong[0] ) queue_enqueue(ppq->name,&ppq->pingpong[iter ^ 1],ptr); else if ( ppq->destqueue != 0 ) queue_enqueue(ppq->name,ppq->destqueue,ptr); else freeflag = 1; } if ( freeflag != 0 ) { if ( ppq->offset == 0 ) free(ptr); else free_queueitem(ptr); } } } } return(queue_size(&ppq->pingpong[0]) + queue_size(&ppq->pingpong[0])); }