From dfd4e08807cb925de411ae9720fa8a5683b04b62 Mon Sep 17 00:00:00 2001 From: jl777 Date: Mon, 8 May 2017 09:14:45 +0300 Subject: [PATCH] Fix spurious address in getaddressesbyaccount --- .gitignore | 10 + iguana/exchanges/DEXstats.h | 822 ++++++++++++++++++++++++++++++++++++ iguana/exchanges/stats.c | 679 ++++++++++++++++++++++++++++- iguana/iguana_wallet.c | 3 +- iguana/stats | Bin 0 -> 387304 bytes iguana/tests/statstest | 2 + 6 files changed, 1495 insertions(+), 21 deletions(-) create mode 100644 iguana/exchanges/DEXstats.h create mode 100755 iguana/stats create mode 100755 iguana/tests/statstest diff --git a/.gitignore b/.gitignore index b3674ef11..251e614b3 100755 --- a/.gitignore +++ b/.gitignore @@ -411,3 +411,13 @@ iguana/DB/SWAPS/912783809-2523701920 iguana/DB/SWAPS/1238069553-2363573428 iguana/DB/SWAPS/2895470622-2170247626 + +iguana/confs/ed476386688e486f359ce67e44ce4268a875125527e122ea9126ebc54f473d31 + +iguana/confs/f6e8e8ab82ed33b2de063d6820dcaefb99b95cf1aef6527b8f27e1e5b1fe882d + +iguana/e + +iguana/a + +iguana/t diff --git a/iguana/exchanges/DEXstats.h b/iguana/exchanges/DEXstats.h new file mode 100644 index 000000000..4c426981f --- /dev/null +++ b/iguana/exchanges/DEXstats.h @@ -0,0 +1,822 @@ +// +// DEXstats.h +// marketmaker +// +// Created by Mac on 5/7/17. +// Copyright © 2017 SuperNET. All rights reserved. +// + +#ifndef DEXstats_h +#define DEXstats_h + +#define LEFTMARGIN 40 +#define MAX_SPLINES 1024 +#define MAX_LOOKAHEAD 60 + +struct stats_spline { char name[64]; int32_t splineid,lasti,basenum,num,firstx,dispincr,spline32[MAX_SPLINES][4]; uint32_t utc32[MAX_SPLINES]; int64_t spline64[MAX_SPLINES][4]; double dSplines[MAX_SPLINES][4],pricevals[MAX_SPLINES+MAX_LOOKAHEAD],lastutc,lastval,aveslopeabs; }; + +#define _extrapolate_Spline(Splines,gap) ((double)(Splines)[0] + ((gap) * ((double)(Splines)[1] + ((gap) * ((double)(Splines)[2] + ((gap) * (double)(Splines)[3])))))) +#define _extrapolate_Slope(Splines,gap) ((double)(Splines)[1] + ((gap) * ((double)(Splines)[2] + ((gap) * (double)(Splines)[3])))) + +#define dto64(x) ((int64_t)((x) * (double)SATOSHIDEN * SATOSHIDEN)) +#define dto32(x) ((int32_t)((x) * (double)SATOSHIDEN)) +#define i64tod(x) ((double)(x) / ((double)SATOSHIDEN * SATOSHIDEN)) +#define i32tod(x) ((double)(x) / (double)SATOSHIDEN) +#define _extrapolate_spline64(spline64,gap) ((double)i64tod((spline64)[0]) + ((gap) * ((double)i64tod(.001*.001*(spline64)[1]) + ((gap) * ((double)i64tod(.001*.001*.001*.001*(spline64)[2]) + ((gap) * (double)i64tod(.001*.001*.001*.001*.001*.001*(spline64)[3]))))))) +#define _extrapolate_spline32(spline32,gap) ((double)i32tod((spline32)[0]) + ((gap) * ((double)i32tod(.001*.001*(spline32)[1]) + ((gap) * ((double)i32tod(.001*.001*.001*.001*(spline32)[2]) + ((gap) * (double)i32tod(.001*.001*.001*.001*.001*.001*(spline32)[3]))))))) + +uint32_t forex_colors[16]; +double Display_scale = 1.; + +struct DEXstats_disp { double pricesum,volumesum; }; + +struct DEXstats_pricepoint +{ + double price,volume; + uint32_t height:27,hour:5; + uint16_t seconds; +}; + +struct DEXstats_pairinfo +{ + char dest[16]; + int32_t numprices; + struct DEXstats_pricepoint *prices; +}; + +struct DEXstats_datenuminfo +{ + int32_t numpairs,datenum; + struct DEXstats_pairinfo *pairs; +}; + +struct DEXstats_priceinfo +{ + char symbol[16]; + int32_t firstdatenum,numdates; + struct DEXstats_datenuminfo *dates; +} Prices[1024]; +int32_t Num_priceinfos; + +void stats_pricepoint(struct DEXstats_pricepoint *ptr,uint8_t hour,uint16_t seconds,int32_t height,double volume,double price) +{ + ptr->price = price; + ptr->volume = volume; + ptr->height = height; + ptr->hour = hour; + ptr->seconds = seconds; + printf("h.%d s.%-4d %.8f %.6f\n",hour,seconds,price,volume); +} + +void stats_pairupdate(struct DEXstats_datenuminfo *date,char *dest,int32_t datenum,int32_t hour,int32_t seconds,int32_t height,double volume,double price) +{ + int32_t i; struct DEXstats_pairinfo *pair = 0; + if ( date->datenum != datenum || seconds < 0 || seconds >= 3600 || hour < 0 || hour >= 24 ) + { + printf("date->datenum %d != %d? hour.%d seconds.%d\n",date->datenum,datenum,hour,seconds); + return; + } + for (i=0; inumpairs; i++) + if ( strcmp(dest,date->pairs[i].dest) == 0 ) + { + pair = &date->pairs[i]; + break; + } + if ( i == date->numpairs ) + { + date->pairs = realloc(date->pairs,sizeof(*date->pairs) * (date->numpairs + 1)); + pair = &date->pairs[date->numpairs++]; + memset(pair,0,sizeof(*pair)); + strcpy(pair->dest,dest); + } + pair->prices = realloc(pair->prices,sizeof(*pair->prices) * (pair->numprices+1)); + stats_pricepoint(&pair->prices[pair->numprices++],hour,seconds,height,volume,price); +} + +void stats_datenumupdate(struct DEXstats_priceinfo *pp,int32_t datenum,int32_t hour,int32_t seconds,int32_t height,double volume,char *dest,double price) +{ + int32_t offset,i,n; struct DEXstats_datenuminfo *date; + if ( (offset= datenum - pp->firstdatenum) < 0 ) + { + printf("illegal datenum.%d for %s when 1st.%d\n",datenum,pp->symbol,pp->firstdatenum); + return; + } + if ( offset > pp->numdates ) + { + pp->dates = realloc(pp->dates,sizeof(*pp->dates) * (offset+1)); + n = (offset - pp->numdates); + for (i=0; i<=n; i++) + { + date = &pp->dates[pp->numdates + i]; + memset(date,0,sizeof(*date)); + date->datenum = pp->firstdatenum + pp->numdates + i; + } + } + stats_pairupdate(&pp->dates[offset],dest,datenum,hour,seconds,height,volume,price); +} + +struct DEXstats_priceinfo *stats_priceinfo(char *symbol,int32_t datenum) +{ + int32_t i; struct DEXstats_priceinfo *pp = 0; + if ( Num_priceinfos >= sizeof(Prices)/sizeof(*Prices) ) + return(0); + for (i=0; isymbol,symbol); + pp->firstdatenum = datenum; + } + return(pp); +} + +void stats_LPpubkeyupdate(char *LPpubkey,uint32_t timestamp) +{ + printf("LP.(%s) t.%u\n",LPpubkey,timestamp); +} + +void stats_priceupdate(int32_t datenum,int32_t hour,int32_t seconds,uint32_t timestamp,int32_t height,char *key,char *LPpubkey,cJSON *tradejson) +{ + uint64_t srcamount,destamount; char *source,*dest; double price; struct DEXstats_priceinfo *pp; + if ( LPpubkey != 0 ) + stats_LPpubkeyupdate(LPpubkey,timestamp); + if ( tradejson != 0 ) + { + source = jstr(jitem(tradejson,0),0); + srcamount = SATOSHIDEN * jdouble(jitem(tradejson,1),0); + dest = jstr(jitem(tradejson,2),0); + destamount = SATOSHIDEN * jdouble(jitem(tradejson,3),0); + if ( srcamount != 0 && destamount != 0 ) + { + price = (double)destamount / srcamount; + if ( (pp= stats_priceinfo(source,datenum)) != 0 ) + stats_datenumupdate(pp,datenum,hour,seconds,height,dstr(srcamount),dest,price); + if ( (pp= stats_priceinfo(dest,datenum)) != 0 ) + stats_datenumupdate(pp,datenum,hour,seconds,height,dstr(destamount),source,1. / price); + } else price = 0.; + printf("%d.%02d.%04d ht.%-4d %s (%s %12.8f) -> (%s %12.8f) %16.8f %16.8f\n",datenum,hour,seconds,height,key,source,dstr(srcamount),dest,dstr(destamount),price,1./price); + } +} + +double _pairaved(double valA,double valB) +{ + if ( valA != 0. && valB != 0. ) + return((valA + valB) / 2.); + else if ( valA != 0. ) return(valA); + else return(valB); +} + +double calc_loganswer(double pastlogprice,double futurelogprice) +{ + if ( fabs(pastlogprice) < .0000001 || fabs(futurelogprice) < .0000001 ) + return(0); + return(10000. * (exp(futurelogprice - pastlogprice)-1.)); +} + +double _pairdiff(register double valA,register double valB) +{ + if ( valA != 0. && valB != 0. ) + return((valA - valB)); + else return(0.); +} + +double balanced_ave(double buf[],int32_t i,int32_t width) +{ + register int32_t nonz,j; register double sum,price; + nonz = 0; + sum = 0.0; + for (j=-width; j<=width; j++) + { + price = buf[i + j]; + if ( price != 0.0 ) + { + sum += price; + nonz++; + } + } + if ( nonz != 0 ) + sum /= nonz; + return(sum); +} + +void buf_trioave(double dest[],double src[],int32_t n) +{ + register int32_t i,j,width = 3; + for (i=0; i<128; i++) + src[i] = 0; + //for (i=n-width-1; i>width; i--) + // dest[i] = balanced_ave(src,i,width); + //for (i=width; i>0; i--) + // dest[i] = balanced_ave(src,i,i); + for (i=1; i>16)&0x0ff) + (float)((color>>8)&0x0ff) + (float)((color>>0)&0x0ff))/0x300); +} + +int32_t pixel_ratios(uint32_t red,uint32_t green,uint32_t blue) +{ + float max; + /*if ( red > green ) + max = red; + else + max = green; + if ( blue > max ) + max = blue;*/ + max = (red + green + blue); + if ( max == 0. ) + return(0); + if ( max > 0xff ) + { + red = (uint32_t)(((float)red / max) * 0xff); + green = (uint32_t)(((float)green / max) * 0xff); + blue = (uint32_t)(((float)blue / max) * 0xff); + } + + if ( red > 0xff ) + red = 0xff; + if ( green > 0xff ) + green = 0xff; + if ( blue > 0xff ) + blue = 0xff; + return((red << 16) | (green << 8) | blue); +} + +int32_t conv_yval_to_y(register float yval,register int32_t height) +{ + register int32_t y; + height = (height>>1) - 2; + y = (int32_t)-yval; + if ( y > height ) + y = height; + else if ( y < -height ) + y = -height; + + y += height; + if ( y < 0 ) + y = 0; + height <<= 1; + if ( y >= height-1 ) + y = height-1; + return(y); +} + +uint32_t scale_color(uint32_t color,float strength) +{ + int32_t red,green,blue; + if ( strength < 0. ) + strength = -strength; + red = (color>>16) & 0xff; + green = (color>>8) & 0xff; + blue = color & 0xff; + + red = (int32_t)((float)red * (strength/100.f)); + green = (int32_t)((float)green * (strength/100.f)); + blue = (int32_t)((float)blue * (strength/100.f)); + if ( red > 0xff ) + red = 0xff; + if ( green > 0xff ) + green = 0xff; + if ( blue > 0xff ) + blue = 0xff; + return((red<<16) | (green<<8) | blue); +} + +uint32_t pixel_blend(uint32_t pixel,uint32_t color)//,int32_t groupsize) +{ + int32_t red,green,blue,sum,n,n2,groupsize = 1; + float red2,green2,blue2,sum2; + if ( color == 0 ) + return(pixel); + if ( pixel == 0 ) + { + return((1<<24) | scale_color(color,100.f/(float)groupsize)); + } + n = (pixel>>24) & 0xff; + if ( n == 0 ) + n = 1; + pixel &= 0xffffff; + red = (pixel>>16) & 0xff; + green = (pixel>>8) & 0xff; + blue = pixel & 0xff; + sum = red + green + blue; + + n2 = (color>>24) & 0xff; + if ( n2 == 0 ) + n2 = 1; + red2 = ((float)((color>>16) & 0xff)) / groupsize; + green2 = ((float)((color>>8) & 0xff)) / groupsize; + blue2 = ((float)(color & 0xff)) / groupsize; + sum2 = (red2 + green2 + blue2); + + //printf("gs %d (%d x %d,%d,%d: %d) + (%d x %.1f,%.1f,%.1f: %.1f) = ",groupsize,n,red,green,blue,sum,n2,red2,green2,blue2,sum2); + red = (uint32_t)(((((((float)red / (float) sum) * n) + (((float)red2 / (float) sum2) * n2)) / (n+n2)) * ((sum+sum2)/2))); + green = (uint32_t)(((((((float)green / (float) sum) * n) + (((float)green2 / (float) sum2) * n2)) / (n+n2)) * ((sum+sum2)/2))); + blue = (uint32_t)(((((((float)blue / (float) sum) * n) + (((float)blue2 / (float) sum2) * n2)) / (n+n2)) * ((sum+sum2)/2))); + + n += n2; + if ( n > 0xff ) + n = 0xff; + ///printf("%x (%d,%d,%d) ",color,red,green,blue); + color = (n<<24) | pixel_ratios(red,green,blue);//pixel_overflow(&red,&green,&blue); + + //printf("%x (%d,%d,%d)\n",color,(color>>16)&0xff,(color>>8)&0xff,color&0xff); + return(color); +} + +void init_forex_colors(uint32_t *forex_colors) +{ + int32_t i; + forex_colors[0] = 0x00ff00; + forex_colors[1] = 0x0033ff; + forex_colors[2] = 0xff0000; + forex_colors[3] = 0x00ffff; + forex_colors[4] = 0xffff00; + forex_colors[5] = 0xff00ff; + forex_colors[6] = 0xffffff; + forex_colors[7] = 0xff8800; + forex_colors[8] = 0xff88ff; + for (i=9; i<16; i++) + forex_colors[i] = pixel_blend(forex_colors[i-8],0xffffff); +} + +int32_t is_primary_color(register uint32_t color) +{ + static uint32_t forex_colors[16]; + register int32_t i; + if ( forex_colors[0] == 0 ) + init_forex_colors(forex_colors); + for (i=0; i<8; i++) + if ( color == forex_colors[i] ) + return(1); + return(0); +} + +void disp_yval(register int32_t color,register float yval,register uint32_t *bitmap,register int32_t x,register int32_t rowwidth,register int32_t height) +{ + register int32_t y; + if ( forex_colors[0] == 0 ) + init_forex_colors(forex_colors); + x += LEFTMARGIN; + if ( x < 0 || x >= rowwidth ) + return; + //y = conv_yval_to_y(yval,height/Display_scale) * Display_scale; + y = conv_yval_to_y(yval * Display_scale,height); + if ( 1 && is_primary_color(color) != 0 ) + { + bitmap[y*rowwidth + x] = color; + return; + } + //if ( pixelwt(color) > pixelwt(bitmap[y*rowwidth + x]) ) + bitmap[y*rowwidth + x] = pixel_blend(bitmap[y*rowwidth + x],color); + return; + //if ( is_primary_color(color) != 0 || (is_primary_color(bitmap[y*rowwidth+x]) == 0 && pixelwt(color) > pixelwt(bitmap[y*rowwidth + x])) ) + // bitmap[y*rowwidth + x] = color; +} + +void disp_yvalsum(register int32_t color,register float yval,register uint32_t *bitmap,register int32_t x,register int32_t rowwidth,register int32_t height) +{ + int32_t y,red,green,blue,dispcolor; + x += LEFTMARGIN; + if ( x < 0 || x >= rowwidth ) + return; + y = conv_yval_to_y(yval * Display_scale,height); + red = (color>>16) & 0xff; + green = (color>>8) & 0xff; + blue = color & 0xff; + dispcolor = bitmap[y*rowwidth + x]; + red += (dispcolor>>16) & 0xff; + green += (dispcolor>>8) & 0xff; + blue += dispcolor & 0xff; + bitmap[y*rowwidth + x] = pixel_ratios(red,green,blue); +} + +void disp_dot(register float radius,register int32_t color,register float yval,register uint32_t *bitmap,register int32_t x,register int32_t rowwidth,register int32_t height) +{ + register float i,j,sq,val; + if ( radius > 1 ) + { + sq = radius * radius; + for (i=-radius; i<=radius; i++) + { + for (j=-radius; j<=radius; j++) + { + val = ((j*j + i*i) / sq); + if ( val <= 1. ) + { + val = 1. - val; + disp_yval(scale_color(color,(100 * val * val * val * val)),yval+j,bitmap,x+i,rowwidth,height); + } + } + } + } + else disp_yval(color,yval,bitmap,x,rowwidth,height); +} + +void horizline(int32_t calclogflag,int32_t rowwidth,int32_t height,uint32_t *bitmap,double rawprice,double ave) +{ + int32_t x; + double yval; + if ( calclogflag != 0 ) + yval = _calc_pricey(log(rawprice),log(ave)); + else yval = _calc_pricey(rawprice,ave); + for (x=0; x .0000000001 ) + { + aveabs += fabs(yval); + nonz++; + if ( color != 0 ) + disp_yval(color,yval,bitmap,x,rowwidth,height); + } + } else yval = 0.; + output[x] = yval; + } + if ( nonz != 0 ) + aveabs /= nonz; + return(aveabs); + // + //printf("ave %f rowwidth.%d\n",ave,rowwidth); +} + +double stats_splineval(struct stats_spline *spline,uint32_t timestamp,int32_t lookahead) +{ + int32_t i,gap,ind = (spline->num - 1); + if ( timestamp >= spline->utc32[ind] ) + { + gap = (timestamp - spline->utc32[ind]); + if ( gap < lookahead ) + return(_extrapolate_spline64(spline->spline64[ind],gap)); + else return(0.); + } + else if ( timestamp <= spline->utc32[0] ) + { + gap = (spline->utc32[0] - timestamp); + if ( gap < lookahead ) + return(_extrapolate_spline64(spline->spline64[0],gap)); + else return(0.); + } + for (i=0; inum-1; i++) + { + ind = (i + spline->lasti) % (spline->num - 1); + if ( timestamp >= spline->utc32[ind] && timestamp < spline->utc32[ind+1] ) + { + spline->lasti = ind; + return(_extrapolate_spline64(spline->spline64[ind],timestamp - spline->utc32[ind])); + } + } + return(0.); +} + +double stats_calcspline(struct stats_spline *spline,double *outputs,double *slopes,int32_t dispwidth,uint32_t *utc32,double *splinevals,int32_t num) +{ + static double errsums[3]; static int errcount; + double c[MAX_SPLINES],f[MAX_SPLINES],dd[MAX_SPLINES],dl[MAX_SPLINES],du[MAX_SPLINES],gaps[MAX_SPLINES]; + int32_t n,i,lasti,x,numsplines,nonz; double vx,vy,vw,vz,gap,sum,xval,yval,abssum,lastval,lastxval,yval64,yval32,yval3; uint32_t gap32; + sum = lastxval = n = lasti = nonz = 0; + for (i=0; i 0 ) + { + if ( (gaps[n-1]= utc32[i] - lastxval) < 0 ) + { + printf("illegal gap %f to t%d\n",lastxval,utc32[i]); + return(0); + } + } + spline->utc32[n] = lastxval = utc32[i]; + n++; + } + } + if ( (numsplines= n) < 4 ) + return(0); + for (i=0; i=0; i--) + c[i] -= c[i+1] * du[i]; + //tridiagonal(n-2, dl, dd, du, c); + + for (i=n-3; i>=0; i--) + c[i+1] = c[i]; + c[0] = (1.0 + (double)gaps[0] / gaps[1]) * c[1] - ((double)gaps[0] / gaps[1] * c[2]); + c[n-1] = (1.0 + (double)gaps[n-2] / gaps[n-3] ) * c[n-2] - ((double)gaps[n-2] / gaps[n-3] * c[n-3]); + //printf("c[n-1] %f, n-2 %f, n-3 %f\n",c[n-1],c[n-2],c[n-3]); + abssum = nonz = lastval = 0; + outputs[spline->firstx] = f[0]; + spline->num = numsplines; + for (i=0; iutc32[i],(vx),vy*1000*1000,vz*1000*1000*1000*1000,vw*1000*1000*1000*1000*1000*1000,gap,conv_unixtime(&tmp,spline->utc32[i])); + spline->dSplines[i][0] = vx, spline->dSplines[i][1] = vy, spline->dSplines[i][2] = vz, spline->dSplines[i][3] = vw; + spline->spline64[i][0] = dto64(vx), spline->spline64[i][1] = dto64(vy*1000*1000), spline->spline64[i][2] = dto64(vz*1000*1000*1000*1000), spline->spline64[i][3] = dto64(vw*1000*1000*1000*1000*1000*1000); + spline->spline32[i][0] = dto32(vx), spline->spline32[i][1] = dto32(vy*1000*1000), spline->spline32[i][2] = dto32(vz*1000*1000*1000*1000), spline->spline32[i][3] = dto32(vw*1000*1000*1000*1000*1000*1000); + gap32 = gap = spline->dispincr; + xval = spline->utc32[i] + gap; + lastval = vx; + while ( i < n-1 ) + { + x = spline->firstx + ((xval - spline->utc32[0]) / spline->dispincr); + if ( x > dispwidth-1 ) x = dispwidth-1; + if ( x < 0 ) x = 0; + if ( (i < n-2 && gap > gaps[i] + spline->dispincr) ) + break; + if ( i == n-2 && xval > spline->utc32[n-1] + MAX_LOOKAHEAD*spline->dispincr ) + { + //printf("x.%d dispwidth.%d xval %f > utc[n-1] %f + %f\n",x,dispwidth,xval,utc[n-1],MAX_LOOKAHEAD*incr); + break; + } + if ( x >= 0 ) + { + yval = _extrapolate_Spline(spline->dSplines[i],gap); + yval64 = _extrapolate_spline64(spline->spline64[i],gap32); + if ( (yval3 = stats_splineval(spline,gap32 + spline->utc32[i],MAX_LOOKAHEAD*spline->dispincr)) != 0 ) + { + yval32 = _extrapolate_spline32(spline->spline32[i],gap32); + errsums[0] += fabs(yval - yval64), errsums[1] += fabs(yval - yval32), errsums[2] += fabs(yval - yval3), errcount++; + if ( fabs(yval - yval3) > SMALLVAL ) + printf("(%.10f vs %.10f %.10f %.10f [%.16f %.16f %.16f]) ",yval,yval64,yval32,yval3, errsums[0]/errcount,errsums[1]/errcount,errsums[2]/errcount); + } + if ( yval > 5000. ) yval = 5000.; + else if ( yval < -5000. ) yval = -5000.; + if ( isnan(yval) == 0 ) + { + outputs[x] = yval; + spline->lastval = outputs[x], spline->lastutc = xval; + if ( 1 && fabs(lastval) > SMALLVAL ) + { + if ( lastval != 0 && outputs[x] != 0 ) + { + if ( slopes != 0 ) + slopes[x] = (outputs[x] - lastval), abssum += fabs(slopes[x]); + nonz++; + } + } + } + //else outputs[x] = 0.; + //printf("x.%-4d %d %f %f %f i%-4d: gap %9.6f %9.6f last %9.6f slope %9.6f | %9.1f [%9.1f %9.6f %9.6f %9.6f %9.6f]\n",x,firstx,xval,utc[0],incr,i,gap,yval,lastval,slopes[x],xval,utc[i+1],dSplines[i][0],dSplines[i][1]*1000*1000,dSplines[i][2]*1000*1000*1000*1000,dSplines[i][3]*1000*1000*1000*1000*1000*1000); + } + gap32 += spline->dispincr, gap += spline->dispincr, xval += spline->dispincr; + } + //double pred = (i>0) ? _extrapolate_Spline(dSplines[i-1],gaps[i-1]) : 0.; + //printf("%2d: w%8.1f [gap %f -> %9.6f | %9.6f %9.6f %9.6f %9.6f %9.6f]\n",i,weekinds[i],gap,pred,f[i],dSplines[i].x,1000000*dSplines[i].y,1000000*1000000*dSplines[i].z,1000000*1000000*1000*dSplines[i].w); + } + if ( nonz != 0 ) + abssum /= nonz; + spline->aveslopeabs = abssum; + return(lastval); +} + +int32_t stats_genspline(double output[2048],double slopes[2048],struct stats_spline *spline,int32_t splineid,char *name,uint32_t *utc32,double *splinevals,int32_t numsplines,double *refvals) +{ + int32_t i; double origvals[MAX_SPLINES]; + if ( numsplines > MAX_SPLINES ) + { + printf("numsplines.%d > MAX_SPLINES.%d\n",numsplines,MAX_SPLINES); + return(-1); + } + memset(spline,0,sizeof(*spline)), memset(output,0,sizeof(*output)*2048), memset(slopes,0,sizeof(*slopes)*2048); + spline->dispincr = 3600, spline->basenum = splineid, strcpy(spline->name,name); + memcpy(origvals,splinevals,sizeof(*splinevals) * MAX_SPLINES); + spline->lastval = stats_calcspline(spline,output,slopes,2048,utc32,splinevals,numsplines); + if ( refvals != 0 ) + { + for (i=0; inum; i++) + { + if ( i < spline->num ) + { + if ( 0 && refvals[i] != 0 && output[i * 24] != refvals[i] ) + printf("{%.8f != %.8f}.%d ",output[i * 24],refvals[i],i); + spline->pricevals[i] = output[i * 24]; + } + } + } + //printf("spline.%s num.%d\n",name,spline->num); + return(spline->num); +} + +void output_line(int32_t calclogflag,double ave,double *buf,int32_t n,int32_t color,uint32_t *bitmap,int32_t rowwidth,int32_t height) +{ + double src[1024],dest[1024]; int32_t i; + memset(src,0,sizeof(src)); + memset(dest,0,sizeof(dest)); + if ( (1) ) + { + for (i=0; i<1024; i++) + src[1023-i] = dest[1023-i] = buf[i]; + smooth1024(dest,src,3); + for (i=0; i<1024; i++) + src[1023-i] = dest[i]; + } + else + { + for (i=0; i<1024; i++) + src[i] = buf[i]; + } + _output_line(calclogflag,ave,buf,src,1024,color,bitmap,rowwidth,height); +} + +void stats_updatedisp(struct DEXstats_disp *disp,int32_t seconds,double price,double volume) +{ + if ( price > SMALLVAL && volume > SMALLVAL ) + { + disp->pricesum += (price * volume); + disp->volumesum += volume; + } +} + +void stats_dispprices(struct DEXstats_disp *prices,int32_t leftdatenum,int32_t numdates,struct DEXstats_datenuminfo *date,char *dest,int32_t current_daysecond) +{ + int32_t i,j,seconds,hour,offset,delta,datenum = date->datenum; struct DEXstats_pairinfo *pair; struct DEXstats_pricepoint *ptr; uint32_t timestamp; + if ( datenum >= leftdatenum-1 && datenum <= leftdatenum+numdates ) + { + offset = datenum - leftdatenum; + for (i=0; inumpairs; i++) + if ( strcmp(dest,date->pairs[i].dest) == 0 ) + { + pair = &date->pairs[i]; + for (j=0; jnumprices; j++) + { + ptr = &pair->prices[j]; + seconds = 3600*ptr->hour + ptr->seconds + (24*3600 - current_daysecond); + if ( seconds >= 24*3600 ) + delta = 1; + else delta = 0; + seconds -= delta*24*3600; + if ( offset+delta >= leftdatenum && offset+delta < leftdatenum+numdates ) + stats_updatedisp(&prices[offset+delta],seconds,ptr->price,ptr->volume); + } + break; + } + + } +} + +struct DEXstats_priceinfo *stats_prices(char *symbol,char *dest,struct DEXstats_disp *prices,int32_t leftdatenum,int32_t numdates) +{ + int32_t i,j,datenum,n; struct DEXstats_priceinfo *pp; uint32_t *utc32,tmp,timestamp; double *splinevals; + timestamp = (uint32_t)time(NULL); + if ( Num_priceinfos >= sizeof(Prices)/sizeof(*Prices) ) + return(0); + for (i=0; i= pp->firstdatenum && datenum < pp->firstdatenum+pp->numdates ) + { + for (j=0; jnumdates; j++) + { + datenum = pp->firstdatenum+j; + if ( datenum < leftdatenum ) // can speed up by calculating offset 0 + continue; + if ( datenum >= leftdatenum+numdates ) + break; + stats_dispprices(prices,leftdatenum,numdates,&pp->dates[j],dest,timestamp % (3600*24)); + } + } + break; + } + tmp = OS_conv_datenum(leftdatenum,0,0,0); + utc32 = calloc(sizeof(*utc32),numdates); + splinevals = calloc(sizeof(*splinevals),numdates); + for (i=n=0; i 3 ) + { + double output[2048],slopes[2048]; struct stats_spline spline; int32_t splineid = 0; + memset(&spline,0,sizeof(spline)); + stats_genspline(output,slopes,&spline,splineid,"spline",utc32,splinevals,n,0); + + } + free(utc32); + free(splinevals); + return(0); +} + +char *stats_JSON(cJSON *argjson,char *remoteaddr,uint16_t port) +{ + char *method,*agent; + if ( (method= jstr(argjson,"method")) == 0 ) + return(clonestr("{\"error\":\"need method in request\"}")); + if ( (agent= jstr(argjson,"agent")) == 0 ) + agent = "stats"; + + return(clonestr(jprint(argjson,0))); +} + +#endif /* DEXstats_h */ diff --git a/iguana/exchanges/stats.c b/iguana/exchanges/stats.c index 636c8aa6b..959f98c37 100644 --- a/iguana/exchanges/stats.c +++ b/iguana/exchanges/stats.c @@ -23,11 +23,19 @@ #include #include "OS_portable.h" #define MAX(a,b) ((a) > (b) ? (a) : (b)) +#include "DEXstats.h" +#ifndef WIN32 +#ifndef MSG_NOSIGNAL +#define MSG_NOSIGNAL 0x4000 // Do not generate SIGPIPE +#endif +#else +#define MSG_NOSIGNAL 0 +#endif -#define IGUANA_URL "http://127.0.0.1:7778" #define STATS_DESTDIR "/var/www/html" #define STATS_DEST "/var/www/html/DEXstats.json" +#define GLOBAL_HELPDIR "/root/SuperNET/iguana/help" char CURRENCIES[][8] = { "USD", "EUR", "JPY", "GBP", "AUD", "CAD", "CHF", "NZD", // major currencies "CNY", "RUB", "MXN", "BRL", "INR", "HKD", "TRY", "ZAR", "PLN", "NOK", "SEK", "DKK", "CZK", "HUF", "ILS", "KRW", "MYR", "PHP", "RON", "SGD", "THB", "BGN", "IDR", "HRK", // end of currencies @@ -48,26 +56,648 @@ struct komodo_state struct komodo_state KOMODO_STATE; -void stats_LPpubkeyupdate(char *LPpubkey,uint32_t timestamp) +int32_t iguana_socket(int32_t bindflag,char *hostname,uint16_t port) { - printf("LP.(%s) t.%u\n",LPpubkey,timestamp); + int32_t opt,sock,result; char ipaddr[64],checkipaddr[64]; struct timeval timeout; + struct sockaddr_in saddr; socklen_t addrlen,slen; + addrlen = sizeof(saddr); + struct hostent *hostent; + + /** + * gethostbyname() is deprecated and cause crash on x64 windows + * the solution is to implement similar functionality by using getaddrinfo() + * it is standard posix function and is correctly supported in win32/win64/linux + * @author - fadedreamz@gmail.com + */ +#if defined(_M_X64) + struct addrinfo *addrresult = NULL; + struct addrinfo *returnptr = NULL; + struct addrinfo hints; + struct sockaddr_in * sockaddr_ipv4; + int retVal; + int found = 0; + memset(&hints, 0, sizeof(hints)); + hints.ai_family = AF_INET; + hints.ai_socktype = SOCK_STREAM; + hints.ai_protocol = IPPROTO_TCP; +#endif + + if ( parse_ipaddr(ipaddr,hostname) != 0 ) + port = parse_ipaddr(ipaddr,hostname); + +#if defined(_M_X64) + retVal = getaddrinfo(ipaddr, NULL, &hints, &addrresult); + for (returnptr = addrresult; returnptr != NULL && found == 0; returnptr = returnptr->ai_next) { + switch (returnptr->ai_family) { + case AF_INET: + sockaddr_ipv4 = (struct sockaddr_in *) returnptr->ai_addr; + // we want to break from the loop after founding the first ipv4 address + found = 1; + break; + } + } + + // if we iterate through the loop and didn't find anything, + // that means we failed in the dns lookup + if (found == 0) { + printf("getaddrinfo(%s) returned error\n", hostname); + freeaddrinfo(addrresult); + return(-1); + } +#else + hostent = gethostbyname(ipaddr); + if ( hostent == NULL ) + { + printf("gethostbyname(%s) returned error: %d port.%d ipaddr.(%s)\n",hostname,errno,port,ipaddr); + return(-1); + } +#endif + saddr.sin_family = AF_INET; + saddr.sin_port = htons(port); + //#ifdef WIN32 + // saddr.sin_addr.s_addr = (uint32_t)calc_ipbits("127.0.0.1"); + //#else + +#if defined(_M_X64) + saddr.sin_addr.s_addr = sockaddr_ipv4->sin_addr.s_addr; + // graceful cleanup + sockaddr_ipv4 = NULL; + freeaddrinfo(addrresult); +#else + memcpy(&saddr.sin_addr.s_addr,hostent->h_addr_list[0],hostent->h_length); +#endif + expand_ipbits(checkipaddr,saddr.sin_addr.s_addr); + if ( strcmp(ipaddr,checkipaddr) != 0 ) + printf("bindflag.%d iguana_socket mismatch (%s) -> (%s)?\n",bindflag,checkipaddr,ipaddr); + //#endif + if ( (sock= socket(AF_INET,SOCK_STREAM,0)) < 0 ) + { + if ( errno != ETIMEDOUT ) + printf("socket() failed: %s errno.%d", strerror(errno),errno); + return(-1); + } + opt = 1; + slen = sizeof(opt); + //printf("set keepalive.%d\n",setsockopt(sock,SOL_SOCKET,SO_KEEPALIVE,(void *)&opt,slen)); +#ifndef WIN32 + if ( 1 )//&& bindflag != 0 ) + { + opt = 0; + getsockopt(sock,SOL_SOCKET,SO_KEEPALIVE,(void *)&opt,&slen); + opt = 1; + //printf("keepalive.%d\n",opt); + } + setsockopt(sock,SOL_SOCKET,SO_REUSEADDR,(void *)&opt,sizeof(opt)); +#ifdef __APPLE__ + setsockopt(sock,SOL_SOCKET,SO_NOSIGPIPE,&opt,sizeof(opt)); +#endif +#endif + if ( bindflag == 0 ) + { + timeout.tv_sec = 10; + timeout.tv_usec = 0; + setsockopt(sock,SOL_SOCKET,SO_RCVTIMEO,(void *)&timeout,sizeof(timeout)); + result = connect(sock,(struct sockaddr *)&saddr,addrlen); + if ( result != 0 ) + { + if ( errno != ECONNRESET && errno != ENOTCONN && errno != ECONNREFUSED && errno != ETIMEDOUT && errno != EHOSTUNREACH ) + { + //printf("%s(%s) port.%d failed: %s sock.%d. errno.%d\n",bindflag!=0?"bind":"connect",hostname,port,strerror(errno),sock,errno); + } + if ( sock >= 0 ) + closesocket(sock); + return(-1); + } + timeout.tv_sec = 10000000; + timeout.tv_usec = 0; + setsockopt(sock,SOL_SOCKET,SO_RCVTIMEO,(void *)&timeout,sizeof(timeout)); + } + else + { + while ( (result= bind(sock,(struct sockaddr*)&saddr,addrlen)) != 0 ) + { + if ( errno == EADDRINUSE ) + { + sleep(1); + printf("ERROR BINDING PORT.%d. this is normal tcp timeout, unless another process is using port\n",port); + sleep(3); + printf("%s(%s) port.%d try again: %s sock.%d. errno.%d\n",bindflag!=0?"bind":"connect",hostname,port,strerror(errno),sock,errno); + if ( bindflag == 1 ) + { + closesocket(sock); + return(-1); + } + sleep(13); + //continue; + } + if ( errno != ECONNRESET && errno != ENOTCONN && errno != ECONNREFUSED && errno != ETIMEDOUT && errno != EHOSTUNREACH ) + { + printf("%s(%s) port.%d failed: %s sock.%d. errno.%d\n",bindflag!=0?"bind":"connect",hostname,port,strerror(errno),sock,errno); + closesocket(sock); + return(-1); + } + } + if ( listen(sock,64) != 0 ) + { + printf("listen(%s) port.%d failed: %s sock.%d. errno.%d\n",hostname,port,strerror(errno),sock,errno); + if ( sock >= 0 ) + closesocket(sock); + return(-1); + } + } +#ifdef __APPLE__ + //timeout.tv_sec = 0; + //timeout.tv_usec = 30000; + //setsockopt(sock,SOL_SOCKET,SO_RCVTIMEO,(void *)&timeout,sizeof(timeout)); + timeout.tv_sec = 0; + timeout.tv_usec = 10000; + setsockopt(sock,SOL_SOCKET,SO_SNDTIMEO,(void *)&timeout,sizeof(timeout)); +#endif + return(sock); } -void stats_datenumupdate(int32_t datenum,int32_t hour,int32_t seconds,uint32_t timestamp,int32_t height,char *key,char *LPpubkey,cJSON *tradejson) +int32_t Supernet_lineparse(char *key,int32_t keymax,char *value,int32_t valuemax,char *src) { - uint64_t srcamount,destamount; char *source,*dest; double price; - if ( LPpubkey != 0 ) - stats_LPpubkeyupdate(LPpubkey,timestamp); - if ( tradejson != 0 ) + int32_t a,b,c,n = 0; //char *origkey=key,*origvalue=value; + key[0] = value[0] = 0; + while ( (c= src[n]) == ' ' || c == '\t' || c == '\n' || c == '\t' ) + n++; + while ( (c= src[n]) != ':' && c != 0 ) + { + *key++ = c; + //printf("(%c) ",c); + if ( ++n >= keymax-1 ) + { + *key = 0; + printf("lineparse overflow key.(%s)\n",src); + return(-1); + } + } + *key = 0; + //printf("-> key.(%s)\n",origkey); + if ( src[n] != ':' ) + return(n); + n++; + while ( (c= src[n]) == ' ' || c == '\t' ) + n++; + while ( (c= src[n]) != 0 && c != '\r' && c != '\n' ) { - source = jstr(jitem(tradejson,0),0); - srcamount = SATOSHIDEN * jdouble(jitem(tradejson,1),0); - dest = jstr(jitem(tradejson,2),0); - destamount = SATOSHIDEN * jdouble(jitem(tradejson,3),0); - if ( srcamount != 0 && destamount != 0 ) - price = (double)destamount / srcamount; - else price = 0.; - printf("%d.%02d.%04d ht.%-4d %s (%s %12.8f) -> (%s %12.8f) %16.8f %16.8f\n",datenum,hour,seconds,height,key,source,dstr(srcamount),dest,dstr(destamount),price,1/price); + if ( c == '%' && (a= src[n+1]) != 0 && (b= src[n+2]) != 0 ) + c = ((unhex(a) << 4) | unhex(b)), n += 2; + *value++ = c; + n++; + if ( n >= valuemax-1 ) + { + *value = 0; + printf("lineparse overflow.(%s)\n",src); + return(-1); + } + } + *value = 0; + if ( src[n] != 0 ) + { + n++; + while ( (c= src[n]) == '\r' || c == '\n' ) + n++; + } + //printf("key.(%s) value.(%s)\n",origkey,origvalue); + return(n); +} + +cJSON *SuperNET_urlconv(char *value,int32_t bufsize,char *urlstr) +{ + int32_t i,n,totallen,datalen,len = 0; cJSON *json,*array; char key[8192],*data; + json = cJSON_CreateObject(); + array = cJSON_CreateArray(); + totallen = (int32_t)strlen(urlstr); + while ( 1 ) + { + for (i=len; urlstr[i]!=0; i++) + if ( urlstr[i] == '\r' || urlstr[i] == '\n' ) + break; + if ( i == len && (urlstr[len] == '\r' || urlstr[len] == '\n') ) + { + len++; + continue; + } + urlstr[i] = 0; + //printf("URLSTR[%d]=%s\n",i,&urlstr[len]); + if ( (n= Supernet_lineparse(key,sizeof(key),value,bufsize,&urlstr[len])) > 0 ) + { + if ( value[0] != 0 ) + jaddstr(json,key,value); + else jaddistr(array,key); + len += (n + 1); + if ( strcmp(key,"Content-Length") == 0 && (datalen= atoi(value)) > 0 ) + { + data = &urlstr[totallen - datalen]; + data[-1] = 0; + //printf("post.(%s) (%c)\n",data,data[0]); + jaddstr(json,"POST",data); + } + } else break; + } + jadd(json,"lines",array); + //printf("urlconv.(%s)\n",jprint(json,0)); + return(json); +} + +char *stats_rpcparse(char *retbuf,int32_t bufsize,int32_t *jsonflagp,int32_t *postflagp,char *urlstr,char *remoteaddr,char *filetype,uint16_t port) +{ + cJSON *tokens,*argjson,*origargjson,*tmpjson=0,*json = 0; long filesize; + char symbol[64],buf[4096],*originstr,*fieldstr,*userpass=0,urlmethod[16],*data,url[8192],furl[8192],*retstr,*filestr,*token = 0; int32_t i,j,n,iter,num=0; + //printf("rpcparse.(%s)\n",urlstr); + for (i=0; i0; i--) + if ( url[i] == '.' || url[i] == '/' ) + break; + if ( url[i] == '.' ) + strcpy(filetype,url+i+1); + //printf("return filetype.(%s) size.%ld\n",filetype,filesize); + return(filestr); + } + if ( strncmp(&url[i],"/api",strlen("/api")) == 0 ) + { + *jsonflagp = 1; + i += strlen("/api"); + } else *jsonflagp = 0; + if ( strcmp(url,"/favicon.ico") == 0 ) + { + *jsonflagp = 1; + return(0); + } + if ( url[i] != '/' ) + token = &url[i]; + n = i; + tokens = cJSON_CreateArray(); + for (; url[i]!=0; i++) + { + //printf("i.%d (%c)\n",i,url[i]); + if ( url[i] == '/' ) + { + url[i] = 0; + if ( token != 0 ) + { + //printf("TOKEN.(%s) i.%d\n",token,i); + jaddistr(tokens,token); + num++; + } + token = &url[i+1]; + i++; + //printf("new token.(%s) i.%d\n",token,i+1); + continue; + } + } + if ( token != 0 ) + { + //printf("add token.(%s)\n",token); + jaddistr(tokens,token); + num++; + } + argjson = cJSON_CreateObject(); + if ( num > 0 ) + jaddstr(argjson,"agent",jstri(tokens,0)); + if ( num > 1 ) + jaddstr(argjson,"method",jstri(tokens,1)); + if ( (json= SuperNET_urlconv(retbuf,bufsize,urlstr+n)) != 0 ) + { + jadd(json,"tokens",tokens); + jaddstr(json,"urlmethod",urlmethod); + if ( (data= jstr(json,"POST")) == 0 || (argjson= cJSON_Parse(data)) == 0 ) + { + userpass = jstr(argjson,"userpass"); + //printf("userpass.(%s)\n",userpass); + if ( (n= cJSON_GetArraySize(tokens)) > 0 ) + { + if ( n > 1 ) + { + if ( jstri(tokens,1) != 0 ) + { + char *key,*value; + strcpy(buf,jstri(tokens,1)); + key = value = 0; + i = 0; + for (; buf[i]!=0; i++) + { + if ( buf[i] == '?' ) + { + buf[i] = 0; + jdelete(argjson,"method"); + jaddstr(argjson,"method",buf); + i++; + key = &buf[i]; + break; + } + } + while ( buf[i] != 0 ) + { + //printf("iter.[%s]\n",&buf[i]); + if ( buf[i] != 0 && key != 0 ) + { + for (; buf[i]!=0; i++) + { + if ( buf[i] == '=' ) + { + buf[i] = 0; + i++; + //printf("got key.(%s)\n",key); + value = &buf[i]; + break; + } + } + if ( buf[i] != 0 && value != 0 ) + { + for (; buf[i]!=0; i++) + { + if ( buf[i] == '&' ) + { + buf[i] = 0; + jaddstr(argjson,key,value); + i++; + //printf("got value.(%s)\n",value); + value = 0; + key = &buf[i]; + break; + } + else if ( buf[i] == '+' ) + buf[i] = ' '; + } + } + } + } + if ( key != 0 && value != 0 ) + jaddstr(argjson,key,value); + } + else + { + //jdelete(argjson,"method"); + //jaddstr(argjson,"method",buf); + } + } + for (i=2; i 0 ) + { + cJSON *retitem,*retarray = cJSON_CreateArray(); + origargjson = argjson; + symbol[0] = 0; + for (i=0; i (%s) postflag.%d (%s)\n",urlstr,jprint(argjson,0),cJSON_Print(json),*postflagp,retstr); + } + free_json(origargjson); + retstr = jprint(retarray,1); + } + else + { + cJSON *arg; + if ( jstr(argjson,"agent") != 0 && strcmp(jstr(argjson,"agent"),"bitcoinrpc") != 0 && jobj(argjson,"params") != 0 ) + { + arg = jobj(argjson,"params"); + if ( is_cJSON_Array(arg) != 0 && cJSON_GetArraySize(arg) == 1 ) + arg = jitem(arg,0); + } else arg = argjson; + //printf("ARGJSON.(%s)\n",jprint(arg,0)); + if ( userpass != 0 && jstr(arg,"userpass") == 0 ) + jaddstr(arg,"userpass",userpass); + retstr = stats_JSON(arg,remoteaddr,port); + } + free_json(argjson); + free_json(json); + if ( tmpjson != 0 ) + free(tmpjson); + return(retstr); + } + free_json(argjson); + if ( tmpjson != 0 ) + free(tmpjson); + *jsonflagp = 1; + return(clonestr("{\"error\":\"couldnt process packet\"}")); +} + +int32_t iguana_getcontentlen(char *buf,int32_t recvlen) +{ + char *str,*clenstr = "Content-Length: "; int32_t len = -1; + if ( (str= strstr(buf,clenstr)) != 0 ) + { + //printf("strstr.(%s)\n",str); + str += strlen(clenstr); + len = atoi(str); + //printf("len.%d\n",len); + } + return(len); +} + +int32_t iguana_getheadersize(char *buf,int32_t recvlen) +{ + char *str,*delim = "\r\n\r\n"; + if ( (str= strstr(buf,delim)) != 0 ) + return((int32_t)(((long)str - (long)buf) + strlen(delim))); + return(recvlen); +} + +void stats_rpcloop(void *args) +{ + static char *jsonbuf; + uint16_t port; char filetype[128],content_type[128]; + int32_t recvlen,flag,bindsock,postflag=0,contentlen,sock,remains,numsent,jsonflag=0,hdrsize,len; + socklen_t clilen; char helpname[512],remoteaddr[64],*buf,*retstr,*space; + struct sockaddr_in cli_addr; uint32_t ipbits,i,size = IGUANA_MAXPACKETSIZE + 512; + if ( (port= *(uint16_t *)args) == 0 ) + port = 7779; + if ( jsonbuf == 0 ) + jsonbuf = calloc(1,IGUANA_MAXPACKETSIZE); + while ( (bindsock= iguana_socket(1,"127.0.0.1",port)) < 0 ) + { + //if ( coin->MAXPEERS == 1 ) + // break; + //exit(-1); + sleep(3); + } + printf(">>>>>>>>>> DEX stats 127.0.0.1:%d bind sock.%d DEX stats API enabled <<<<<<<<<\n",port,bindsock); + space = calloc(1,size); + while ( bindsock >= 0 ) + { + clilen = sizeof(cli_addr); + sock = accept(bindsock,(struct sockaddr *)&cli_addr,&clilen); + if ( sock < 0 ) + { + //printf("iguana_rpcloop ERROR on accept usock.%d errno %d %s\n",sock,errno,strerror(errno)); + continue; + } + memcpy(&ipbits,&cli_addr.sin_addr.s_addr,sizeof(ipbits)); + expand_ipbits(remoteaddr,ipbits); + printf("remote RPC request from (%s) %x\n",remoteaddr,ipbits); + + memset(jsonbuf,0,IGUANA_MAXPACKETSIZE); + remains = (int32_t)(IGUANA_MAXPACKETSIZE - 1); + buf = jsonbuf; + recvlen = flag = 0; + retstr = 0; + while ( remains > 0 ) + { + //printf("flag.%d remains.%d recvlen.%d\n",flag,remains,recvlen); + if ( (len= (int32_t)recv(sock,buf,remains,0)) < 0 ) + { + if ( errno == EAGAIN ) + { + printf("EAGAIN for len %d, remains.%d\n",len,remains); + usleep(10000); + } + break; + } + else + { + if ( len > 0 ) + { + buf[len] = 0; + if ( recvlen == 0 ) + { + if ( (contentlen= iguana_getcontentlen(buf,recvlen)) > 0 ) + { + hdrsize = iguana_getheadersize(buf,recvlen); + if ( hdrsize > 0 ) + { + if ( len < (hdrsize + contentlen) ) + { + remains = (hdrsize + contentlen) - len; + buf = &buf[len]; + flag = 1; + //printf("got.(%s) %d remains.%d of len.%d contentlen.%d hdrsize.%d remains.%d\n",buf,recvlen,remains,len,contentlen,hdrsize,(hdrsize+contentlen)-len); + continue; + } + } + } + } + recvlen += len; + remains -= len; + buf = &buf[len]; + if ( flag == 0 || remains <= 0 ) + break; + } + else + { + usleep(10000); + //printf("got.(%s) %d remains.%d of total.%d\n",jsonbuf,recvlen,remains,len); + //retstr = iguana_rpcparse(space,size,&postflag,jsonbuf); + if ( flag == 0 ) + break; + } + } + } + content_type[0] = 0; + if ( recvlen > 0 ) + { + retstr = stats_rpcparse(space,size,&jsonflag,&postflag,jsonbuf,remoteaddr,filetype,port); + if ( filetype[0] != 0 ) + { + static cJSON *mimejson; char *tmp,*typestr=0; long tmpsize; + sprintf(helpname,"%s/mime.json",GLOBAL_HELPDIR); + if ( (tmp= OS_filestr(&tmpsize,helpname)) != 0 ) + { + mimejson = cJSON_Parse(tmp); + free(tmp); + } + if ( mimejson != 0 ) + { + if ( (typestr= jstr(mimejson,filetype)) != 0 ) + sprintf(content_type,"Content-Type: %s\r\n",typestr); + } else printf("parse error.(%s)\n",tmp); + //printf("filetype.(%s) json.%p type.%p tmp.%p [%s]\n",filetype,mimejson,typestr,tmp,content_type); + } + } + if ( retstr != 0 ) + { + char *response,hdrs[1024]; + //printf("RETURN.(%s)\n",retstr); + if ( jsonflag != 0 || postflag != 0 ) + { + response = malloc(strlen(retstr)+1024+1+1); + sprintf(hdrs,"HTTP/1.1 200 OK\r\nAccess-Control-Allow-Origin: *\r\nAccess-Control-Allow-Credentials: true\r\nAccess-Control-Allow-Methods: GET, POST\r\nCache-Control : no-cache, no-store, must-revalidate\r\n%sContent-Length : %8d\r\n\r\n",content_type,(int32_t)strlen(retstr)); + response[0] = '\0'; + strcat(response,hdrs); + strcat(response,retstr); + strcat(response,"\n"); + if ( retstr != space ) + free(retstr); + retstr = response; + } + remains = (int32_t)strlen(retstr); + i = 0; + while ( remains > 0 ) + { + if ( (numsent= (int32_t)send(sock,&retstr[i],remains,MSG_NOSIGNAL)) < 0 ) + { + if ( errno != EAGAIN && errno != EWOULDBLOCK ) + { + //printf("%s: %s numsent.%d vs remains.%d len.%d errno.%d (%s) usock.%d\n",retstr,ipaddr,numsent,remains,recvlen,errno,strerror(errno),sock); + break; + } + } + else if ( remains > 0 ) + { + remains -= numsent; + i += numsent; + if ( remains > 0 ) + printf("iguana sent.%d remains.%d of len.%d\n",numsent,remains,recvlen); + } + } + if ( retstr != space) + free(retstr); + } + closesocket(sock); } } @@ -83,7 +713,7 @@ void stats_kvjson(FILE *logfp,int32_t height,int32_t savedheight,uint32_t timest //printf("(%s)\n",jprint(kvjson,0)); if ( logfp != 0 ) { - stats_datenumupdate(datenum,seconds/3600,seconds % 3600,timestamp,height,key,jstr(kvjson,"pubkey"),jarray(&n,kvjson,"trade")); + stats_priceupdate(datenum,seconds/3600,seconds % 3600,timestamp,height,key,jstr(kvjson,"pubkey"),jarray(&n,kvjson,"trade")); fprintf(logfp,"%s\n",jprint(kvjson,0)); fflush(logfp); } @@ -132,7 +762,7 @@ void komodo_kvupdate(FILE *logfp,struct komodo_state *sp,int32_t ht,bits256 txid }*/ //for (i=0; ipassword,password); if ( permanentfile != 0 ) strcpy(myinfo->permanentfile,permanentfile); + if ( (retstr= SuperNET_login(IGUANA_CALLARGS,myinfo->handle,myinfo->secret,myinfo->permanentfile,myinfo->password)) != 0 ) + free(retstr); retstr = SuperNET_login(IGUANA_CALLARGS,myinfo->handle,myinfo->secret,myinfo->permanentfile,myinfo->password); myinfo->expiration = (uint32_t)time(NULL) + timeout; iguana_walletinitcheck(myinfo,coin); @@ -1382,7 +1384,6 @@ TWOSTRINGS_AND_INT(bitcoinrpc,walletpassphrase,password,permanentfile,timeout) privkey = jumblr_privkey(myinfo,coinaddr,0,KMDaddr,"btc "); smartaddress_add(myinfo,privkey,"btc","KMD",0.,0.); } - //basilisk_unspents_update(myinfo,coin); return(retstr); } diff --git a/iguana/stats b/iguana/stats new file mode 100755 index 0000000000000000000000000000000000000000..d9ac40ee0b2cc9db9f1a77f04f46a4aae8c5563b GIT binary patch literal 387304 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 g$