diff --git a/crypto777/OS_portable.h b/crypto777/OS_portable.h index 5e1833e74..011f1f6ac 100755 --- a/crypto777/OS_portable.h +++ b/crypto777/OS_portable.h @@ -98,7 +98,7 @@ struct taidate tai2date(struct tai t); int32_t taidate_str(char *s,struct taidate cd); char *taitime_str(char *s,struct taitime ct); int32_t taidate_mjd(struct taidate cd); -uint32_t tai2utime(struct tai t); +uint64_t tai2utime(struct tai t); struct tai taitime2tai(struct taitime ct); char *tai_str(char *str,struct tai t); char *utc_str(char *str,struct tai t); @@ -137,8 +137,8 @@ int32_t expand_datenum(char *date,int32_t datenum); int32_t calc_datenum(int32_t year,int32_t month,int32_t day); int32_t ecb_decrdate(int32_t *yearp,int32_t *monthp,int32_t *dayp,char *date,int32_t datenum); int32_t conv_date(int32_t *secondsp,char *buf); -uint32_t OS_conv_datenum(int32_t datenum,int32_t hour,int32_t minute,int32_t second); -int32_t OS_conv_unixtime(int32_t *secondsp,time_t timestamp); +uint64_t OS_conv_datenum(int32_t datenum,int32_t hour,int32_t minute,int32_t second); +int32_t OS_conv_unixtime(struct tai *t,int32_t *secondsp,time_t timestamp); double OS_milliseconds(); void OS_randombytes(unsigned char *x,long xlen); @@ -206,8 +206,8 @@ int32_t expand_datenum(char *date,int32_t datenum); int32_t calc_datenum(int32_t year,int32_t month,int32_t day); int32_t ecb_decrdate(int32_t *yearp,int32_t *monthp,int32_t *dayp,char *date,int32_t datenum); int32_t conv_date(int32_t *secondsp,char *buf); -uint32_t OS_conv_datenum(int32_t datenum,int32_t hour,int32_t minute,int32_t second); -int32_t OS_conv_unixtime(int32_t *secondsp,time_t timestamp); +uint64_t OS_conv_datenum(int32_t datenum,int32_t hour,int32_t minute,int32_t second); +int32_t OS_conv_unixtime(struct tai *t,int32_t *secondsp,time_t timestamp); int32_t btc_coinaddr(char *coinaddr,uint8_t addrtype,char *pubkeystr); void reverse_hexstr(char *str); int32_t init_hexbytes_noT(char *hexbytes,uint8_t *message,long len); diff --git a/crypto777/OS_time.c b/crypto777/OS_time.c index 208321f4e..edb63b67e 100755 --- a/crypto777/OS_time.c +++ b/crypto777/OS_time.c @@ -18,6 +18,8 @@ #include "OS_portable.h" #define TAI_PACK 8 +#define TAI_UTC_DIFF ((uint64_t)4611686018427387914ULL) + //#define UTC_ADJUST -36 #define tai_approx(t) ((double) ((t)->x)) #define tai_less(t,u) ((t)->x < (u)->x) @@ -27,6 +29,80 @@ static struct tai First_TAI; uint32_t First_utc; int32_t UTC_ADJUST; +#ifdef _WIN32 +struct tm *gmtime_r(const time_t *timep,struct tm *result) +{ + struct tm *p = gmtime(timep); + memset(result,0,sizeof(*result)); + if ( p != 0 ) + { + *result = *p; + p = result; + } + return(p); +} + +#include +#include // portable: uint64_t MSVC: __int64 + +// MSVC defines this in winsock2.h!? +/*typedef struct timeval { + long tv_sec; + long tv_usec; +} timeval; + +int gettimeofday(struct timeval * tp, struct timezone * tzp) +{ + // Note: some broken versions only have 8 trailing zero's, the correct epoch has 9 trailing zero's + static const uint64_t EPOCH = ((uint64_t) 116444736000000000ULL); + + SYSTEMTIME system_time; + FILETIME file_time; + uint64_t time; + + GetSystemTime( &system_time ); + SystemTimeToFileTime( &system_time, &file_time ); + time = ((uint64_t)file_time.dwLowDateTime ) ; + time += ((uint64_t)file_time.dwHighDateTime) << 32; + + tp->tv_sec = (long) ((time - EPOCH) / 10000000L); + tp->tv_usec = (long) (system_time.wMilliseconds * 1000); + return 0; +}*/ +#endif + +double OS_portable_milliseconds() +{ + struct timeval tv; double millis; + gettimeofday(&tv,NULL); + millis = ((double)tv.tv_sec * 1000. + (double)tv.tv_usec / 1000.); + //printf("tv_sec.%ld usec.%d %f\n",tv.tv_sec,tv.tv_usec,millis); + return(millis); +} + +// portable time functions + +int32_t is_DST(int32_t datenum) +{ + int32_t year,month,day; + year = datenum / 10000, month = (datenum / 100) % 100, day = (datenum % 100); + if ( month >= 4 && month <= 9 ) + return(1); + else if ( month == 3 && day >= 29 ) + return(1); + else if ( month == 10 && day < 25 ) + return(1); + return(0); +} + +struct taidate taidate_set(int32_t year,int32_t month,int32_t day) +{ + struct taidate cd; + memset(&cd,0,sizeof(cd)); + cd.year = year, cd.month = month, cd.day = day; + return(cd); +} + struct taidate taidate_frommjd(int32_t day,int32_t *pwday,int32_t *pyday) { int32_t year,month,yday; struct taidate cd; @@ -98,6 +174,15 @@ struct taidate tai2date(struct tai t) return(ct.date); } +struct taitime taitime_set(struct taidate cd,int32_t hour,int32_t minute,int32_t seconds) +{ + struct taitime ct; + memset(&ct,0,sizeof(ct)); + ct.date = cd; + ct.hour = hour, ct.minute = minute, ct.second = seconds; + return(ct); +} + /*int32_t taitime_scan(char *s,struct taitime *ct) { int32_t z,c,sign; char *t = s; @@ -177,7 +262,7 @@ char *taitime_str(char *s,struct taitime ct) s[4] = '0' + (x % 6); x /= 6; s[3] = '0' + (x % 10); x /= 10; s[2] = '0' + (x % 10); - s[len] = 0; + s[6] = 0; } return(s); } @@ -249,23 +334,26 @@ int32_t taidate_mjd(struct taidate cd) return d; } -uint32_t tai2utc(struct tai t) { t.x -= 4611686018427387914ULL; return((uint32_t)t.x); } +struct tai utc2tai(uint32_t timestamp) { struct tai t; memset(&t,0,sizeof(t)); t.x = (timestamp + TAI_UTC_DIFF); return(t); } + +uint32_t tai2utc(struct tai t) { t.x -= TAI_UTC_DIFF; return((uint32_t)t.x); } -uint32_t tai2utime(struct tai t) +uint64_t tai2utime(struct tai t) { - uint64_t mjd; struct taitime ct = tai2time(t,0,0); + uint64_t mjd; uint64_t timestamp; struct taitime ct = tai2time(t,0,0); mjd = taidate_mjd(ct.date); - return((uint32_t)(mjd * 24*3600 + ct.hour*3600 + ct.minute*60 + ct.second)); + timestamp = ((uint64_t)(mjd * 24*3600 + ct.hour*3600 + ct.minute*60 + ct.second)); + return(timestamp); } struct tai tai_now() { - struct tai t; - t.x = 4611686018427387914ULL + (uint64_t)time(NULL); + struct tai t; uint64_t now = time(NULL); + t.x = TAI_UTC_DIFF + now; t.millis = OS_milliseconds(); if ( First_TAI.x == 0 ) { - First_TAI = t, First_utc = (uint32_t)time(NULL); + First_TAI = t, First_utc = (uint32_t)now; UTC_ADJUST = -36; printf("TAINOW.%llu %03.3f UTC.%u vs %u [diff %d]\n",(long long)t.x,t.millis,First_utc,tai2utc(t),UTC_ADJUST); } @@ -387,80 +475,74 @@ char *utc_str(char *str,struct tai t) return(tai_str(str,t)); } -#ifdef ENABLE_TEST -#include -int main(int argc, const char * argv[]) +double OS_milliseconds() { - int i; char str[111],str2[111],str3[111],str4[111]; struct taitime ct; - struct tai t,start = tai_now(); - for (i=0; i<100; i++) - { - sleep(1); - t = tai_now(); - taidate_str(str2,tai2date(t)); - printf("(%s) time.%s date.%s %ld start.%ld %s %u %u\n",tai_str(str3,t),taitime_str(str,ct),str2,(long)tai2utime(t),(long)tai2utime(start),utime_str(str4,t),tai2utc(t),(uint32_t)time(NULL)); - } - // insert code here... - printf("Hello, World!\n"); - return 0; + return(OS_portable_milliseconds()); } -#endif +int32_t calc_datenum(int32_t year,int32_t month,int32_t day) +{ + return((year * 10000) + (month * 100) + day); +} -int32_t conv_date(int32_t *secondsp,char *buf); - -double OS_portable_milliseconds() +int32_t extract_datenum(int32_t *yearp,int32_t *monthp,int32_t *dayp,int32_t datenum) { - struct timeval tv; double millis; - gettimeofday(&tv,NULL); - millis = ((double)tv.tv_sec * 1000. + (double)tv.tv_usec / 1000.); - //printf("tv_sec.%ld usec.%d %f\n",tv.tv_sec,tv.tv_usec,millis); - return(millis); + *yearp = datenum / 10000, *monthp = (datenum / 100) % 100, *dayp = (datenum % 100); + if ( *yearp >= 2000 && *yearp <= 2038 && *monthp >= 1 && *monthp <= 12 && *dayp >= 1 && *dayp <= 31 ) + return(datenum); + else return(-1); } -uint32_t OS_conv_datenum(int32_t datenum,int32_t hour,int32_t minute,int32_t second) // datenum+H:M:S -> unix time +uint64_t OS_conv_datenum(int32_t datenum,int32_t hour,int32_t minute,int32_t second) // datenum+H:M:S -> unix time { + int32_t year,month,day; struct tai t; struct taitime ct; + if ( 1 ) + { + if ( extract_datenum(&year,&month,&day,datenum) > 0 ) + { + ct = taitime_set(taidate_set(year,month,day),hour,minute,second); + t = taitime2tai(ct); + return(tai2utime(t)+788250398LL - 4294967296LL); + } + return(0); + } + else + { #ifdef __PNACL - return(0); + return(0); #else - struct tm t; - memset(&t,0,sizeof(t)); - t.tm_year = (datenum / 10000) - 1900, t.tm_mon = ((datenum / 100) % 100) - 1, t.tm_mday = (datenum % 100); - t.tm_hour = hour, t.tm_min = minute, t.tm_sec = second; - return((uint32_t)timegm(&t)); + struct tm t; + memset(&t,0,sizeof(t)); + t.tm_year = (datenum / 10000) - 1900, t.tm_mon = ((datenum / 100) % 100) - 1, t.tm_mday = (datenum % 100); + t.tm_hour = hour, t.tm_min = minute, t.tm_sec = second; + return((uint32_t)timegm(&t)); #endif + } } -double OS_milliseconds() -{ - return(OS_portable_milliseconds()); -} - -int32_t OS_conv_unixtime(int32_t *secondsp,time_t timestamp) // gmtime -> datenum + number of seconds +int32_t OS_conv_unixtime(struct tai *tp,int32_t *secondsp,time_t timestamp) // gmtime -> datenum + number of seconds { - struct tm t; int32_t datenum; uint32_t checktime; char buf[64]; - t = *gmtime(×tamp); - strftime(buf, sizeof(buf), "%Y-%m-%dT%H:%M:%SZ",&t); //printf("%s\n",buf); - datenum = conv_date(secondsp,buf); - if ( (checktime= OS_conv_datenum(datenum,*secondsp/3600,(*secondsp%3600)/60,*secondsp%60)) != timestamp ) + struct tm tm,*ptr; int32_t datenum; uint32_t checktime; char buf[64]; struct tai t; struct taitime ct; + if ( 1 ) { - printf("error: timestamp.%u -> (%d + %d) -> %u\n",(uint32_t)timestamp,datenum,*secondsp,checktime); - return(-1); + *tp = t = utc2tai((uint32_t)timestamp); + ct = tai2time(t,0,0); + *secondsp = (ct.hour*3600 + ct.minute*60 + ct.second); + return(calc_datenum(ct.date.year,ct.date.month,ct.date.day)); + } + else + { + if ( (ptr= gmtime(×tamp)) != 0 ) + tm = *ptr;; + strftime(buf,sizeof(buf), "%Y-%m-%dT%H:%M:%SZ",&tm); //printf("%s\n",buf); + datenum = conv_date(secondsp,buf); + if ( (checktime= OS_conv_datenum(datenum,*secondsp/3600,(*secondsp%3600)/60,*secondsp%60)) != timestamp ) + { + printf("error: timestamp.%u -> (%d + %d) -> %u\n",(uint32_t)timestamp,datenum,*secondsp,checktime); + return(-1); + } + return(datenum); } - return(datenum); -} - -int32_t is_DST(int32_t datenum) -{ - int32_t year,month,day; - year = datenum / 10000, month = (datenum / 100) % 100, day = (datenum % 100); - if ( month >= 4 && month <= 9 ) - return(1); - else if ( month == 3 && day >= 29 ) - return(1); - else if ( month == 10 && day < 25 ) - return(1); - return(0); } int32_t conv_date(int32_t *secondsp,char *date) @@ -488,19 +570,15 @@ int32_t conv_date(int32_t *secondsp,char *date) return((year * 10000) + (month * 100) + day); } -int32_t extract_datenum(int32_t *yearp,int32_t *monthp,int32_t *dayp,int32_t datenum) +int32_t expand_datenum(char *date,int32_t datenum) { - *yearp = datenum / 10000, *monthp = (datenum / 100) % 100, *dayp = (datenum % 100); - if ( *yearp >= 2000 && *yearp <= 2038 && *monthp >= 1 && *monthp <= 12 && *dayp >= 1 && *dayp <= 31 ) - return(datenum); - else return(-1); + int32_t year,month,day; date[0] = 0; + if ( extract_datenum(&year,&month,&day,datenum) != datenum) + return(-1); + sprintf(date,"%d-%02d-%02d",year,month,day); + return(0); } -int32_t expand_datenum(char *date,int32_t datenum) { int32_t year,month,day; date[0] = 0; if ( extract_datenum(&year,&month,&day,datenum) != datenum) return(-1); sprintf(date,"%d-%02d-%02d",year,month,day); return(0); } - -int32_t calc_datenum(int32_t year,int32_t month,int32_t day) { return((year * 10000) + (month * 100) + day); } - - int32_t ecb_decrdate(int32_t *yearp,int32_t *monthp,int32_t *dayp,char *date,int32_t datenum) { static int lastday[13] = { 0, 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 }; @@ -527,3 +605,22 @@ int32_t ecb_decrdate(int32_t *yearp,int32_t *monthp,int32_t *dayp,char *date,int *yearp = year, *monthp = month, *dayp = day; return((year * 10000) + (month * 100) + day); } + +#ifdef ENABLE_TEST +#include +int main(int argc, const char * argv[]) +{ + int i; char str[111],str2[111],str3[111],str4[111]; struct taitime ct; + struct tai t,start = tai_now(); + for (i=0; i<100; i++) + { + sleep(1); + t = tai_now(); + taidate_str(str2,tai2date(t)); + printf("(%s) time.%s date.%s %ld start.%ld %s %u %u\n",tai_str(str3,t),taitime_str(str,ct),str2,(long)tai2utime(t),(long)tai2utime(start),utime_str(str4,t),tai2utc(t),(uint32_t)time(NULL)); + } + // insert code here... + printf("Hello, World!\n"); + return 0; +} +#endif diff --git a/crypto777/iguana_OS.c b/crypto777/iguana_OS.c index 40292ba4c..3bea4383a 100755 --- a/crypto777/iguana_OS.c +++ b/crypto777/iguana_OS.c @@ -259,7 +259,7 @@ void *queue_delete(queue_t *queue,struct queueitem *copy,int32_t copysize,int32_ { DL_DELETE(queue->list,item); portable_mutex_unlock(&queue->mutex); - printf("name.(%s) deleted item.%p list.%p\n",queue->name,item,queue->list); + //printf("name.(%s) deleted item.%p list.%p\n",queue->name,item,queue->list); if ( freeitem != 0 ) myfree(item,copysize); return(item); diff --git a/deprecated/obsolete.h b/deprecated/obsolete.h index 6c4c6c146..7e1d83b73 100644 --- a/deprecated/obsolete.h +++ b/deprecated/obsolete.h @@ -10168,4 +10168,21 @@ void iguana_dedicatedrecv(void *arg) } else return(0); } + + + /*char *iguana_genericjsonstr(char *jsonstr,char *remoteaddr) + { + cJSON *json; char *retjsonstr,*methodstr,*agentstr; + if ( (json= cJSON_Parse(jsonstr)) != 0 ) + { + if ( (agentstr= jstr(json,"agent")) == 0 ) + agentstr = "SuperNET"; + if ( (methodstr= jstr(json,"method")) != 0 ) + retjsonstr = iguana_agentjson(agentstr,0,methodstr,json,remoteaddr); + else retjsonstr = clonestr("{\"error\":\"no method in generic JSON\"}"); + free_json(json); + } else retjsonstr = clonestr("{\"error\":\"cant parse generic JSON\"}"); + return(retjsonstr); + }*/ + #endif diff --git a/iguana/iguana777.h b/iguana/iguana777.h index 4eb265e3e..193d47c94 100755 --- a/iguana/iguana777.h +++ b/iguana/iguana777.h @@ -19,6 +19,7 @@ //#define IGUANA_DISABLEPEERS #define IGUANA_MAXCOINS 64 +#define IGUANA_MAXDELAY_MILLIS (3600 * 1000) #define IGUANA_EXCHANGEIDLE 10 #define IGUANS_JSMILLIS 100 @@ -221,7 +222,7 @@ struct iguana_msgtx int32_t allocsize,timestamp; } __attribute__((packed)); -struct iguana_packet { struct queueitem DL; struct iguana_peer *addr; int32_t datalen,getdatablock; uint8_t serialized[]; }; +struct iguana_packet { struct queueitem DL; struct iguana_peer *addr; struct tai embargo; int32_t datalen,getdatablock; uint8_t serialized[]; }; struct msgcounts { uint32_t version,verack,getaddr,addr,inv,getdata,notfound,getblocks,getheaders,headers,tx,block,mempool,ping,pong,reject,filterload,filteradd,filterclear,merkleblock,alert; }; @@ -444,7 +445,7 @@ struct iguana_info int32_t iguana_verifypeer(struct iguana_info *coin,void *key,void *value,int32_t itemind,int32_t itemsize); int32_t iguana_peermetrics(struct iguana_info *coin); void iguana_peersloop(void *arg); -int32_t iguana_queue_send(struct iguana_info *coin,struct iguana_peer *addr,uint8_t *serialized,char *cmd,int32_t len,int32_t getdatablock,int32_t forceflag); +int32_t iguana_queue_send(struct iguana_info *coin,struct iguana_peer *addr,int32_t delay,uint8_t *serialized,char *cmd,int32_t len,int32_t getdatablock,int32_t forceflag); uint32_t iguana_ipbits2ind(struct iguana_info *coin,struct iguana_iAddr *iA,uint32_t ipbits,int32_t createflag); uint32_t iguana_rwiAddrind(struct iguana_info *coin,int32_t rwflag,struct iguana_iAddr *iA,uint32_t ind); //uint32_t iguana_rwipbits_status(struct iguana_info *coin,int32_t rwflag,uint32_t ipbits,int32_t *statusp); @@ -555,7 +556,7 @@ double dxblend(double *destp,double val,double decay); // json int32_t iguana_processjsonQ(struct iguana_info *coin); // reentrant, can be called during any idletime char *iguana_JSON(struct iguana_info *coin,char *jsonstr,char *remoteaddr); -char *SuperNET_p2p(struct iguana_info *coin,char *ipaddr,uint8_t *data,int32_t datalen); +char *SuperNET_p2p(struct iguana_info *coin,int32_t *delaymillisp,char *ipaddr,uint8_t *data,int32_t datalen); char *mbstr(char *str,double); int init_hexbytes_noT(char *hexbytes,unsigned char *message,long len); @@ -660,6 +661,6 @@ struct iguana_info *iguana_coinfind(const char *symbol); struct iguana_info *iguana_coinadd(const char *symbol); struct iguana_ramchain *iguana_bundleload(struct iguana_info *coin,struct iguana_bundle *bp); int32_t iguana_sendblockreq(struct iguana_info *coin,struct iguana_peer *addr,struct iguana_bundle *bp,int32_t bundlei,bits256 hash2,int32_t iamthreadsafe); -int32_t iguana_send_supernet(struct iguana_info *coin,struct iguana_peer *addr,char *jsonstr); +int32_t iguana_send_supernet(struct iguana_info *coin,struct iguana_peer *addr,char *jsonstr,int32_t delay); #endif diff --git a/iguana/iguana_json.c b/iguana/iguana_json.c index c66c8f2dd..7d027c75d 100755 --- a/iguana/iguana_json.c +++ b/iguana/iguana_json.c @@ -434,21 +434,6 @@ char *iguana_jsonstr(struct iguana_info *coin,char *jsonstr,char *remoteaddr) return(retjsonstr); } -/*char *iguana_genericjsonstr(char *jsonstr,char *remoteaddr) -{ - cJSON *json; char *retjsonstr,*methodstr,*agentstr; - if ( (json= cJSON_Parse(jsonstr)) != 0 ) - { - if ( (agentstr= jstr(json,"agent")) == 0 ) - agentstr = "SuperNET"; - if ( (methodstr= jstr(json,"method")) != 0 ) - retjsonstr = iguana_agentjson(agentstr,0,methodstr,json,remoteaddr); - else retjsonstr = clonestr("{\"error\":\"no method in generic JSON\"}"); - free_json(json); - } else retjsonstr = clonestr("{\"error\":\"cant parse generic JSON\"}"); - return(retjsonstr); -}*/ - int32_t iguana_processjsonQ(struct iguana_info *coin) // reentrant, can be called during any idletime { struct iguana_jsonitem *ptr; @@ -553,6 +538,29 @@ char *iguana_JSON(struct iguana_info *coin,char *jsonstr,char *remoteaddr) return(retstr); } +char *SuperNET_p2p(struct iguana_info *coin,int32_t *delaymillisp,char *ipaddr,uint8_t *data,int32_t datalen) +{ + cJSON *json,*retjson; char *retstr = 0; + if ( (json= cJSON_Parse((char *)data)) != 0 ) + { + printf("GOT >>>>>>>> SUPERNET P2P.(%s)\n",(char *)data); + if ( (retstr = iguana_JSON(coin,(char *)data,ipaddr)) != 0 ) + { + if ( (retjson= cJSON_Parse(retstr)) != 0 ) + { + if ( jobj(retjson,"result") != 0 || jobj(retjson,"error") != 0 || jobj(retjson,"method") == 0 ) + { + free(retstr); + retstr = 0; + } + free_json(retjson); + } + } + free_json(json); + } + return(retstr); +} + /*void iguana_issuejsonstrM(void *arg) { cJSON *json; int32_t fd; char *retjsonstr,*jsonstr = arg; @@ -577,6 +585,19 @@ void iguana_main(void *arg) int32_t i,len,flag; cJSON *json; uint8_t secretbuf[512]; // portable_OS_init()? mycalloc(0,0,0); + { + char str[65]; struct tai t; double startmillis; int32_t datenum,seconds; uint64_t i,checkval,timestamp,now = (uint32_t)time(NULL); + startmillis = OS_milliseconds(); + for (i=0; i<1000000; i++) + { + timestamp = now - (rand() % 100000000LL); // range -100000000LL to +500000000LL + datenum = OS_conv_unixtime(&t,&seconds,timestamp); // gmtime -> datenum + number of seconds + checkval = OS_conv_datenum(datenum,seconds/3600,(seconds/60)%60,seconds%60); // datenum+H:M:S -> unix time + if ( checkval != timestamp ) + printf("%s i.%lld timestamp.%-12llu -> (%d:%06d) -> checkval.%-12llu diff.[%lld]\n",tai_str(str,t),i,(long long)timestamp,datenum,seconds,(long long)checkval,(long long)(timestamp-checkval)); + } + printf("million tai compares in %.3f microseconds per encode/decode\n",1000. * (OS_milliseconds()-startmillis)/i); + } if ( (retstr= iguana_addagent("ramchain",ramchain_parser,"127.0.0.1",cJSON_Parse("[\"block\", \"tx\", \"txs\", \"rawtx\", \"balance\", \"totalreceived\", \"totalsent\", \"utxo\", \"status\"]"),0,0,0)) != 0 ) printf("%s\n",retstr), free(retstr); if ( (retstr= iguana_addagent("pangea",pangea_parser,"127.0.0.1",cJSON_Parse("[\"test\"]"),0,0,0)) != 0 ) diff --git a/iguana/iguana_msg.c b/iguana/iguana_msg.c index bc90c2237..d3cc152e7 100755 --- a/iguana/iguana_msg.c +++ b/iguana/iguana_msg.c @@ -120,18 +120,18 @@ int32_t iguana_rwblockhash(int32_t rwflag,uint8_t *serialized,uint32_t *nVersion } //printf("iguana_request_data.%d %s ht.%d\n",n,bits256_str(hashes[0]),iguana_height(coin,hashes[0])); addr->getdatamillis = milliseconds(); - len = iguana_queue_send(coin,addr,serialized,"getdata",len,iguana_height(coin,hashes[n-1]),forceflag); + len = iguana_queue_send(coin,addr,0,serialized,"getdata",len,iguana_height(coin,hashes[n-1]),forceflag); return(len); }*/ -int32_t iguana_send_supernet(struct iguana_info *coin,struct iguana_peer *addr,char *jsonstr) +int32_t iguana_send_supernet(struct iguana_info *coin,struct iguana_peer *addr,char *jsonstr,int32_t delaymillis) { int32_t len; uint8_t serialized[8192]; if ( addr->supernet != 0 && (len= (int32_t)strlen(jsonstr)) < sizeof(serialized)-sizeof(struct iguana_msghdr) ) { memcpy(&serialized[sizeof(struct iguana_msghdr)],jsonstr,len+1); printf("SEND.(%s) -> (%s)\n",jsonstr,addr->ipaddr); - return(iguana_queue_send(coin,addr,serialized,"SuperNET",len+1,0,1)); + return(iguana_queue_send(coin,addr,delaymillis,serialized,"SuperNET",len+1,0,1)); } else return(-1); } @@ -149,18 +149,18 @@ void iguana_gotversion(struct iguana_info *coin,struct iguana_peer *addr,struct addr->height = vers->nStartingHeight; addr->relayflag = 1; iguana_gotdata(coin,addr,addr->height); - iguana_queue_send(coin,addr,serialized,"verack",0,0,0); + iguana_queue_send(coin,addr,0,serialized,"verack",0,0,0); //iguana_send_ping(coin,addr); } else printf("nServices.%lld nonce.%llu invalid version message from.(%s)\n",(long long)vers->nServices,(long long)vers->nonce,addr->ipaddr); if ( (vers->nServices & (1<<7)) == (1<<7) ) { addr->supernet = 1; printf("send getpeers to %s\n",addr->ipaddr); - iguana_send_supernet(coin,addr,"{\"agent\":\"SuperNET\",\"method\":\"getpeers\"}"); + iguana_send_supernet(coin,addr,"{\"agent\":\"SuperNET\",\"method\":\"getpeers\"}",0); } if ( vers->nStartingHeight > coin->longestchain ) coin->longestchain = vers->nStartingHeight; - iguana_queue_send(coin,addr,serialized,"getaddr",0,0,0); + iguana_queue_send(coin,addr,0,serialized,"getaddr",0,0,0); } int32_t iguana_send_version(struct iguana_info *coin,struct iguana_peer *addr,uint64_t myservices) @@ -175,7 +175,7 @@ int32_t iguana_send_version(struct iguana_info *coin,struct iguana_peer *addr,ui msg.nStartingHeight = coin->blocks.hwmchain.height; iguana_gotdata(coin,addr,msg.nStartingHeight); len = iguana_rwversion(1,&serialized[sizeof(struct iguana_msghdr)],&msg,addr->ipaddr); - return(iguana_queue_send(coin,addr,serialized,"version",len,0,1)); + return(iguana_queue_send(coin,addr,0,serialized,"version",len,0,1)); } void iguana_gotverack(struct iguana_info *coin,struct iguana_peer *addr) @@ -185,7 +185,7 @@ void iguana_gotverack(struct iguana_info *coin,struct iguana_peer *addr) { printf("gotverack from %s\n",addr->ipaddr); addr->A.nTime = (uint32_t)time(NULL); - iguana_queue_send(coin,addr,serialized,"getaddr",0,0,0); + iguana_queue_send(coin,addr,0,serialized,"getaddr",0,0,0); } } @@ -204,8 +204,8 @@ void iguana_gotping(struct iguana_info *coin,struct iguana_peer *addr,uint64_t n 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); + iguana_queue_send(coin,addr,0,serialized,"pong",len,0,0); + iguana_queue_send(coin,addr,0,serialized,"getaddr",0,0,0); } int32_t iguana_send_ping(struct iguana_info *coin,struct iguana_peer *addr) @@ -220,8 +220,8 @@ int32_t iguana_send_ping(struct iguana_info *coin,struct iguana_peer *addr) printf("pingnonce.%llx\n",(long long)nonce); len = iguana_rwnum(1,&serialized[sizeof(struct iguana_msghdr)],sizeof(uint64_t),&nonce); if ( addr->supernet != 0 ) - iguana_send_supernet(coin,addr,"{\"agent\":\"SuperNET\",\"method\":\"getpeers\"}"); - return(iguana_queue_send(coin,addr,serialized,"ping",len,0,0)); + iguana_send_supernet(coin,addr,"{\"agent\":\"SuperNET\",\"method\":\"getpeers\"}",(rand() % 10000)); + return(iguana_queue_send(coin,addr,0,serialized,"ping",len,0,0)); } void iguana_gotpong(struct iguana_info *coin,struct iguana_peer *addr,uint64_t nonce) @@ -411,7 +411,7 @@ int32_t iguana_send_hashes(struct iguana_info *coin,char *command,struct iguana_ 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); + retval = iguana_queue_send(coin,addr,0,serialized,command,len,0,0); myfree(serialized,size); } else printf("iguana_send_hashes: unexpected n.%d\n",n); return(retval); @@ -420,7 +420,7 @@ int32_t iguana_send_hashes(struct iguana_info *coin,char *command,struct iguana_ int32_t iguana_parser(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,srvmsg,bloom,intvectors,len= -100; uint64_t nonce,x; uint32_t type; bits256 hash2; + 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 ) { @@ -433,10 +433,10 @@ int32_t iguana_parser(struct iguana_info *coin,struct iguana_peer *addr,struct O { printf("GOT.(%s) len.%d from %s\n",H->command,recvlen,addr->ipaddr); len = recvlen; - if ( (retstr= SuperNET_p2p(coin,addr->ipaddr,data,recvlen)) != 0 ) + if ( (retstr= SuperNET_p2p(coin,&delay,addr->ipaddr,data,recvlen)) != 0 ) { - iguana_send_supernet(coin,addr,retstr); - free(retstr); // dont respond immediate due to privacy + iguana_send_supernet(coin,addr,retstr,delay); + free(retstr); } } else if ( strcmp(H->command,"version") == 0 ) @@ -471,7 +471,7 @@ int32_t iguana_parser(struct iguana_info *coin,struct iguana_peer *addr,struct O iguana_gotping(coin,addr,nonce,data); addr->msgcounts.ping++; } - iguana_queue_send(coin,addr,serialized,"getaddr",0,0,0); + iguana_queue_send(coin,addr,0,serialized,"getaddr",0,0,0); } } else if ( strcmp(H->command,"pong") == 0 ) @@ -484,7 +484,7 @@ int32_t iguana_parser(struct iguana_info *coin,struct iguana_peer *addr,struct O } else printf("unexpected pong recvlen.%d\n",recvlen); if ( len == recvlen && addr != 0 ) addr->msgcounts.pong++; - iguana_queue_send(coin,addr,serialized,"getaddr",0,0,0); + iguana_queue_send(coin,addr,0,serialized,"getaddr",0,0,0); } else if ( strcmp(H->command,"addr") == 0 ) { diff --git a/iguana/iguana_peers.c b/iguana/iguana_peers.c index 15169eff3..13482f25d 100755 --- a/iguana/iguana_peers.c +++ b/iguana/iguana_peers.c @@ -384,7 +384,7 @@ int32_t iguana_send(struct iguana_info *coin,struct iguana_peer *addr,uint8_t *s return(len); } -int32_t iguana_queue_send(struct iguana_info *coin,struct iguana_peer *addr,uint8_t *serialized,char *cmd,int32_t len,int32_t getdatablock,int32_t forceflag) +int32_t iguana_queue_send(struct iguana_info *coin,struct iguana_peer *addr,int32_t delay,uint8_t *serialized,char *cmd,int32_t len,int32_t getdatablock,int32_t forceflag) { struct iguana_packet *packet; int32_t datalen; if ( addr == 0 ) @@ -401,6 +401,12 @@ int32_t iguana_queue_send(struct iguana_info *coin,struct iguana_peer *addr,uint packet = mycalloc('S',1,sizeof(struct iguana_packet) + datalen); packet->datalen = datalen; packet->addr = addr; + if ( delay != 0 ) + { + if ( delay > IGUANA_MAXDELAY_MILLIS ) + delay = IGUANA_MAXDELAY_MILLIS; + packet->embargo = tai_now(); + } memcpy(packet->serialized,serialized,datalen); //printf("%p queue send.(%s) %d to (%s) %x\n",packet,serialized+4,datalen,addr->ipaddr,addr->ipbits); queue_enqueue("sendQ",&addr->sendQ,&packet->DL,0); @@ -732,12 +738,14 @@ int32_t iguana_pollsendQ(struct iguana_info *coin,struct iguana_peer *addr) printf("unexpected getdata for %s\n",addr->ipaddr); myfree(packet,sizeof(*packet) + packet->datalen); } - else + else if ( packet->embargo.x == 0 ) { + iguana_send(coin,addr,packet->serialized,packet->datalen); myfree(packet,sizeof(*packet) + packet->datalen); return(1); } + else queue_enqueue("embargo",&addr->sendQ,&packet->DL,0); } return(0); } @@ -890,7 +898,7 @@ void iguana_dedicatedloop(struct iguana_info *coin,struct iguana_peer *addr) 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); + iguana_queue_send(coin,addr,0,serialized,"getaddr",0,0,0); //printf("after send version\n"); run = 0; while ( addr->usock >= 0 && addr->dead == 0 && coin->peers.shuttingdown == 0 ) diff --git a/iguana/iguana_rpc.c b/iguana/iguana_rpc.c index be2633eba..266ee1d55 100755 --- a/iguana/iguana_rpc.c +++ b/iguana/iguana_rpc.c @@ -498,15 +498,3 @@ char *ramchain_parser(struct iguana_agent *agent,struct iguana_info *coin,char * } return(ramchain_coinparser(coin,method,json)); } - -char *SuperNET_p2p(struct iguana_info *coin,char *ipaddr,uint8_t *data,int32_t datalen) -{ - cJSON *json; char *retstr = 0; - if ( (json= cJSON_Parse((char *)data)) != 0 ) - { - printf("GOT >>>>>>>> SUPERNET P2P.(%s)\n",(char *)data); - retstr = iguana_JSON(coin,(char *)data,ipaddr); - free_json(json); - } - return(retstr); -} diff --git a/iguana/main.c b/iguana/main.c index 632684375..3cb3240ad 100644 --- a/iguana/main.c +++ b/iguana/main.c @@ -47,9 +47,9 @@ void *iguana(void *arg) #else arg = 0;//"{\"coins\":[{\"name\":\"BTCD\",\"maxpeers\":128,\"initialheight\":400000,\"services\":1,\"peers\":[\"127.0.0.1\"]}]}"; #endif + PostMessage("iguana start.(%s)\n",(char *)arg); while ( initflag == 0 ) sleep(1); - PostMessage("iguana start.(%s)\n",(char *)arg); iguana_main(arg); return(0); }