diff --git a/basilisk/basilisk.c b/basilisk/basilisk.c index aef368b42..64e050f41 100755 --- a/basilisk/basilisk.c +++ b/basilisk/basilisk.c @@ -514,7 +514,7 @@ void basilisk_result(struct supernet_info *myinfo,char *remoteaddr,uint32_t basi pending->numresults++; } else printf("couldnt find issued.%u\n",basilisktag); } - } else printf("null vals.(%s) or no hexmsg.%p\n",jprint(vals,0),vals); + } } void basilisk_wait(struct supernet_info *myinfo,struct iguana_info *coin) @@ -531,11 +531,74 @@ void basilisk_wait(struct supernet_info *myinfo,struct iguana_info *coin) } } -char *basilisk_respond_ping(struct supernet_info *myinfo,char *CMD,void *addr,char *remoteaddr,uint32_t basilisktag,cJSON *valsobj,uint8_t *data,int32_t datalen,bits256 hash,int32_t from_basilisk) +int32_t baslisk_relay_report(struct supernet_info *myinfo,uint8_t *data,int32_t maxlen,struct basilisk_relaystatus *reported,uint8_t pingdelay) { - char *retstr=0; - printf("PING got %d from (%s)\n",datalen,remoteaddr!=0?remoteaddr:""); - return(retstr); + if ( reported != 0 ) + { + reported->pingdelay = pingdelay; + } + return(0); +} + +int32_t basilisk_relay_ping(struct supernet_info *myinfo,uint8_t *data,int32_t maxlen,struct basilisk_relay *rp) +{ + int32_t datalen = 0; + datalen = iguana_rwnum(1,&data[datalen],sizeof(rp->ipbits),&rp->ipbits); + data[datalen++] = rp->direct.pingdelay; + return(datalen); +} + +int32_t basilisk_relay_unping(struct supernet_info *myinfo,uint8_t *data,int32_t maxlen,struct basilisk_relay *rp,int32_t i) +{ + uint8_t pingdelay; int32_t j,datalen = 0; uint32_t ipbits; + datalen = iguana_rwnum(1,&data[datalen],sizeof(ipbits),&ipbits); + pingdelay = data[datalen++]; + if ( myinfo->relays[i].ipbits != ipbits ) + printf("unping warning reported.[%d] ipbits %u != %u\n",i,myinfo->relays[i].ipbits,ipbits); + for (j=0; jnumrelays; j++) + if ( myinfo->relays[j].ipbits == ipbits ) + { + datalen += baslisk_relay_report(myinfo,&data[datalen],maxlen-datalen,&rp->reported[j],pingdelay); + return(datalen); + } + datalen += baslisk_relay_report(myinfo,&data[datalen],maxlen-datalen,0,pingdelay); + return(datalen); +} + +int32_t basilisk_relays_ping(struct supernet_info *myinfo,uint8_t *data,int32_t maxlen) +{ + int32_t i,datalen = 0; + data[datalen++] = myinfo->numrelays; + for (i=0; inumrelays; i++) + datalen += basilisk_relay_ping(myinfo,&data[datalen],maxlen - datalen,&myinfo->relays[i]); + return(datalen); +} + +void basilisk_respond_ping(struct supernet_info *myinfo,char *remoteaddr,uint8_t *data,int32_t datalen) +{ + int32_t diff,len = 0; struct basilisk_relay *rp; uint8_t numrelays; uint32_t i,ipbits,now = (uint32_t)time(NULL); + if ( remoteaddr == 0 || remoteaddr[0] == 0 || strcmp("127.0.0.1",remoteaddr) == 0 ) + ipbits = myinfo->myaddr.myipbits; + else ipbits = (uint32_t)calc_ipbits(remoteaddr); + for (i=0; inumrelays; i++) + { + rp = &myinfo->relays[i]; + rp->direct.pingdelay = 0; + if ( rp->ipbits == ipbits ) + rp->lastping = now; + if ( rp->lastping == now ) + rp->direct.pingdelay = 1; + else + { + diff = (now - rp->lastping); + if ( diff < 0xff ) + rp->direct.pingdelay = diff; + } + } + numrelays = data[len++]; + for (i=0; iRELAYID >= 0 ) + { + basilisk_respond_ping(myinfo,remoteaddr,data,datalen); + } + return; + } for (i=flag=0; iallcoins_mutex); if ( (rand() % 10) == 0 && myinfo->RELAYID >= 0 ) { - struct iguana_peer *addr; struct basilisk_relay *rp; int32_t i,j,datalen=0; uint8_t data[1024]; - data[datalen++] = myinfo->numrelays; - for (j=0; jnumrelays; j++) - data[datalen++] = myinfo->relays[j].status; + struct iguana_peer *addr; struct basilisk_relay *rp; int32_t i,datalen=0; uint8_t data[32768]; + datalen = basilisk_relays_ping(myinfo,data,sizeof(data)); for (i=0; inumrelays; i++) { rp = &myinfo->relays[i]; diff --git a/basilisk/basilisk.h b/basilisk/basilisk.h index b1d44b0ef..2d060f271 100755 --- a/basilisk/basilisk.h +++ b/basilisk/basilisk.h @@ -22,6 +22,7 @@ #define BASILISK_MINFANOUT 8 #define BASILISK_MAXFANOUT 64 #define BASILISK_DEFAULTDIFF 0x1effffff +#define BASILISK_MAXRELAYS 64 #define BASILISK_MAXFUTUREBLOCK 60 //#define BASILISK_MAXBLOCKLAG 600 @@ -45,10 +46,16 @@ struct basilisk_info struct basilisk_value values[8192]; int32_t numvalues; }; +struct basilisk_relaystatus +{ + uint8_t pingdelay; +}; + struct basilisk_relay { - bits256 pubkey; uint32_t ipbits; - uint8_t status,pubkey33[33]; + bits256 pubkey; int32_t relayid,oldrelayid; uint32_t ipbits,lastping; + uint8_t pubkey33[33]; + struct basilisk_relaystatus direct,reported[BASILISK_MAXRELAYS]; }; void basilisk_msgprocess(struct supernet_info *myinfo,void *addr,uint32_t senderipbits,char *type,uint32_t basilisktag,uint8_t *data,int32_t datalen); diff --git a/basilisk/basilisk_CMD.c b/basilisk/basilisk_CMD.c index 764b9ec42..76c02822a 100755 --- a/basilisk/basilisk_CMD.c +++ b/basilisk/basilisk_CMD.c @@ -26,7 +26,7 @@ struct iguana_peer *basilisk_ensurerelay(struct supernet_info *myinfo,struct igu addr->isrelay = 1; myinfo->RELAYID = -1; for (i=0; inumrelays; i++) - if ( myinfo->relaybits[i] == myinfo->myaddr.myipbits ) + if ( myinfo->relays[i].ipbits == myinfo->myaddr.myipbits ) { myinfo->RELAYID = i; break; @@ -38,6 +38,29 @@ struct iguana_peer *basilisk_ensurerelay(struct supernet_info *myinfo,struct igu return(addr); } +static int _decreasing_ipbits(const void *a,const void *b) +{ +#define uint32_a (*(struct basilisk_relay **)a)->ipbits +#define uint32_b (*(struct basilisk_relay **)b)->ipbits + if ( uint32_b > uint32_a ) + return(1); + else if ( uint32_b < uint32_a ) + return(-1); + return(0); +#undef uint32_a +#undef uint32_b +} + +void basilisk_relay_remap(struct supernet_info *myinfo,struct basilisk_relay *rp) +{ + int32_t i; struct basilisk_relaystatus tmp[BASILISK_MAXRELAYS]; + // need to verify this works + for (i=0; inumrelays; i++) + tmp[i] = rp->reported[i]; + for (i=0; inumrelays; i++) + rp->reported[myinfo->relays[i].relayid] = tmp[myinfo->relays[i].oldrelayid]; +} + char *basilisk_addrelay_info(struct supernet_info *myinfo,uint8_t *pubkey33,uint32_t ipbits,bits256 pubkey) { int32_t i; struct basilisk_relay *rp; struct iguana_info *btcd; @@ -60,21 +83,27 @@ char *basilisk_addrelay_info(struct supernet_info *myinfo,uint8_t *pubkey33,uint if ( i >= sizeof(myinfo->relays)/sizeof(*myinfo->relays) ) i = (rand() % (sizeof(myinfo->relays)/sizeof(*myinfo->relays))); printf("add relay[%d] <- %x\n",i,ipbits); + for (i=0; inumrelays; i++) + myinfo->relays[i].oldrelayid = i; rp = &myinfo->relays[i]; rp->ipbits = ipbits; + rp->relayid = myinfo->numrelays; basilisk_ensurerelay(myinfo,btcd,rp->ipbits); if ( myinfo->numrelays < sizeof(myinfo->relays)/sizeof(*myinfo->relays) ) myinfo->numrelays++; - for (i=0; inumrelays; i++) - memcpy(&myinfo->relaybits[i],&myinfo->relays[i].ipbits,sizeof(myinfo->relaybits[i])); - revsort32(&myinfo->relaybits[0],myinfo->numrelays,sizeof(myinfo->relaybits[0])); + qsort(&myinfo->relays,myinfo->numrelays,sizeof(myinfo->relays[0]),_decreasing_ipbits); for (i=0; inumrelays; i++) { char ipaddr[64]; - expand_ipbits(ipaddr,myinfo->relaybits[i]); + expand_ipbits(ipaddr,myinfo->relays[i].ipbits); + if ( myinfo->myaddr.myipbits == myinfo->relays[i].ipbits ) + myinfo->RELAYID = i; + myinfo->relays[i].relayid = i; printf("%s ",ipaddr); } - printf("sorted\n"); + printf("sorted MYRELAYID.%d\n",myinfo->RELAYID); + for (i=0; inumrelays; i++) + basilisk_relay_remap(myinfo,&myinfo->relays[i]); return(clonestr("{\"result\":\"relay added\"}")); } diff --git a/gecko/gecko_blocks.c b/gecko/gecko_blocks.c index db894eb49..1a356da7b 100755 --- a/gecko/gecko_blocks.c +++ b/gecko/gecko_blocks.c @@ -31,7 +31,7 @@ void gecko_txidpurge(struct iguana_info *virt,bits256 txid) } if ( virt->RELAYNODE != 0 ) { - for (i=0; imempools[i]) != 0 && (n= pool->numtx) != 0 ) { diff --git a/gecko/gecko_mempool.c b/gecko/gecko_mempool.c index d82fd1b77..97f309d8b 100755 --- a/gecko/gecko_mempool.c +++ b/gecko/gecko_mempool.c @@ -57,9 +57,9 @@ void gecko_mempool_sync(struct supernet_info *myinfo,struct iguana_info *virt,bi for (; inumrelays; i+=n) { printf("mempool_sync.%d\n",i); - if ( (addr= iguana_peerfindipbits(coin,myinfo->relaybits[i],1)) != 0 ) + if ( (addr= iguana_peerfindipbits(coin,myinfo->relays[i].ipbits,1)) != 0 ) { - if ( (otherpool= gecko_mempoolfind(myinfo,virt,&numother,myinfo->relaybits[i])) != 0 ) + if ( (otherpool= gecko_mempoolfind(myinfo,virt,&numother,myinfo->relays[i].ipbits)) != 0 ) { for (j=num=0; jnumtx; j++) { diff --git a/iguana/main.c b/iguana/main.c index 758e3abf5..c85613f17 100755 --- a/iguana/main.c +++ b/iguana/main.c @@ -2088,7 +2088,7 @@ STRING_ARG(SuperNET,myipaddr,ipaddr) strcpy(myinfo->ipaddr,ipaddr); myinfo->myaddr.myipbits = (uint32_t)calc_ipbits(ipaddr); for (i=0; inumrelays; i++) - if ( myinfo->relaybits[i] == myinfo->myaddr.myipbits ) + if ( myinfo->relays[i].ipbits == myinfo->myaddr.myipbits ) { myinfo->RELAYID = i; break; diff --git a/includes/iguana_structs.h b/includes/iguana_structs.h index d368f4339..1acecf041 100755 --- a/includes/iguana_structs.h +++ b/includes/iguana_structs.h @@ -16,8 +16,6 @@ #ifndef H_IGUANASTRUCTS_H #define H_IGUANASTRUCTS_H -#define IGUANA_MAXRELAYS 64 - struct iguana_thread { struct queueitem DL; @@ -415,7 +413,7 @@ struct iguana_info struct iguana_monitorinfo monitoring[256]; struct datachain_info dPoW; struct iguana_zblock newblock; char *newblockstr; - struct iguana_blocks blocks; void *mempool; void *mempools[IGUANA_MAXRELAYS]; + struct iguana_blocks blocks; void *mempool; void *mempools[BASILISK_MAXRELAYS]; }; struct vin_signer { bits256 privkey; char coinaddr[64]; uint8_t siglen,sig[80],rmd160[20],pubkey[66]; }; @@ -468,7 +466,7 @@ struct supernet_info portable_mutex_t allcoins_mutex,gecko_mutex,basilisk_mutex; void *ctx; struct delayedPoW_info dPoW; - uint32_t relaybits[IGUANA_MAXRELAYS]; struct basilisk_relay relays[IGUANA_MAXRELAYS]; + struct basilisk_relay relays[BASILISK_MAXRELAYS]; int32_t numrelays,RELAYID; // compatibility bits256 pangea_category,instantdex_category;