/****************************************************************************** * Copyright © 2014-2017 The SuperNET Developers. * * * * See the AUTHORS, DEVELOPER-AGREEMENT and LICENSE files at * * the top-level directory of this distribution for the individual copyright * * holder information and the developer policies on copyright and licensing. * * * * Unless otherwise agreed in a custom licensing agreement, no part of the * * SuperNET software, including this file may be copied, modified, propagated * * or distributed except according to the terms contained in the LICENSE file * * * * Removal or modification of this copyright notice is prohibited. * * * ******************************************************************************/ // // main.c // stats // // Copyright © 2017 SuperNET. All rights reserved. // #include #include #include "OS_portable.h" #define MAX(a,b) ((a) > (b) ? (a) : (b)) #define IGUANA_URL "http://127.0.0.1:7778" #define STATS_DESTDIR "/var/www/html" #define STATS_DEST "/var/www/html/DEXstats.json" 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 }; char ASSETCHAINS_SYMBOL[16] = { "KV" }; struct komodo_state { bits256 NOTARIZED_HASH,NOTARIZED_DESTTXID; int32_t SAVEDHEIGHT,CURRENT_HEIGHT,NOTARIZED_HEIGHT; uint32_t SAVEDTIMESTAMP; uint64_t deposited,issued,withdrawn,approved,redeemed,shorted; struct notarized_checkpoint *NPOINTS; int32_t NUM_NPOINTS; struct komodo_event **Komodo_events; int32_t Komodo_numevents; uint32_t RTbufs[64][3]; uint64_t RTmask; }; struct komodo_state KOMODO_STATE; void komodo_kvupdate(int32_t height,bits256 txid,int32_t vout,uint8_t *opretbuf,int32_t opretlen,uint64_t value) { static bits256 zeroes; uint32_t flags; bits256 pubkey,refpubkey,sig; int32_t i,refvaluesize,hassig,coresize,haspubkey,height,kvheight; uint16_t keylen,valuesize,newflag = 0; uint8_t *key,*valueptr,keyvalue[10000]; iguana_rwnum(0,&opretbuf[1],sizeof(keylen),&keylen); iguana_rwnum(0,&opretbuf[3],sizeof(valuesize),&valuesize); iguana_rwnum(0,&opretbuf[5],sizeof(height),&height); iguana_rwnum(0,&opretbuf[9],sizeof(flags),&flags); key = &opretbuf[13]; if ( keylen+13 > opretlen ) { printf("komodo_kvupdate: keylen.%d + 13 > opretlen.%d\n",keylen,opretlen); return; } valueptr = &key[keylen]; coresize = (int32_t)(sizeof(flags)+sizeof(height)+sizeof(keylen)+sizeof(valuesize)+keylen+valuesize+1); if ( opretlen == coresize || opretlen == coresize+sizeof(bits256) || opretlen == coresize+2*sizeof(bits256) ) { memset(&pubkey,0,sizeof(pubkey)); memset(&sig,0,sizeof(sig)); if ( (haspubkey= (opretlen >= coresize+sizeof(bits256))) != 0 ) { for (i=0; i<32; i++) ((uint8_t *)&pubkey)[i] = opretbuf[coresize+i]; } if ( (hassig= (opretlen == coresize+sizeof(bits256)*2)) != 0 ) { for (i=0; i<32; i++) ((uint8_t *)&sig)[i] = opretbuf[coresize+sizeof(bits256)+i]; } /*if ( (refvaluesize= komodo_kvsearch((bits256 *)&refpubkey,height,&flags,&kvheight,&keyvalue[keylen],key,keylen)) >= 0 ) { if ( memcmp(&zeroes,&refpubkey,sizeof(refpubkey)) != 0 ) { if ( komodo_kvsigverify(keyvalue,keylen+refvaluesize,refpubkey,sig) < 0 ) { //printf("komodo_kvsigverify error [%d]\n",coresize-13); return; } } }*/ for (i=0; i "); for (i=0; i sp->SAVEDHEIGHT ) { sp->SAVEDHEIGHT = kmdheight; sp->SAVEDTIMESTAMP = timestamp; } if ( kmdheight > sp->CURRENT_HEIGHT ) sp->CURRENT_HEIGHT = kmdheight; } } void komodo_eventadd_kmdheight(struct komodo_state *sp,char *symbol,int32_t height,int32_t kmdheight,uint32_t timestamp) { uint32_t buf[2]; if ( kmdheight > 0 ) { buf[0] = (uint32_t)kmdheight; buf[1] = timestamp; //komodo_eventadd(sp,height,symbol,KOMODO_EVENT_KMDHEIGHT,(uint8_t *)buf,sizeof(buf)); if ( sp != 0 ) komodo_setkmdheight(sp,kmdheight,timestamp); } else { kmdheight = -kmdheight; //komodo_eventadd(sp,height,symbol,KOMODO_EVENT_REWIND,(uint8_t *)&height,sizeof(height)); //if ( sp != 0 ) // komodo_event_rewind(sp,symbol,height); } } int32_t komodo_parsestatefile(struct komodo_state *sp,FILE *fp,char *symbol,char *dest) { static int32_t errs; int32_t func,ht,notarized_height,num,matched=0; bits256 notarized_hash,notarized_desttxid; uint8_t pubkeys[64][33]; if ( (func= fgetc(fp)) != EOF ) { if ( ASSETCHAINS_SYMBOL[0] == 0 && strcmp(symbol,"KMD") == 0 ) matched = 1; else matched = (strcmp(symbol,ASSETCHAINS_SYMBOL) == 0); if ( fread(&ht,1,sizeof(ht),fp) != sizeof(ht) ) errs++; //printf("fpos.%ld func.(%d %c) ht.%d ",ftell(fp),func,func,ht); if ( func == 'P' ) { if ( (num= fgetc(fp)) <= 64 ) { if ( fread(pubkeys,33,num,fp) != num ) errs++; else { //printf("updated %d pubkeys at %s ht.%d\n",num,symbol,ht); //if ( (KOMODO_EXTERNAL_NOTARIES != 0 && matched != 0) || (strcmp(symbol,"KMD") == 0 && KOMODO_EXTERNAL_NOTARIES == 0) ) // komodo_eventadd_pubkeys(sp,symbol,ht,num,pubkeys); } } else printf("illegal num.%d\n",num); } else if ( func == 'N' ) { if ( fread(¬arized_height,1,sizeof(notarized_height),fp) != sizeof(notarized_height) ) errs++; if ( fread(¬arized_hash,1,sizeof(notarized_hash),fp) != sizeof(notarized_hash) ) errs++; if ( fread(¬arized_desttxid,1,sizeof(notarized_desttxid),fp) != sizeof(notarized_desttxid) ) errs++; //if ( matched != 0 ) global independent states -> inside *sp //komodo_eventadd_notarized(sp,symbol,ht,dest,notarized_hash,notarized_desttxid,notarized_height); } else if ( func == 'U' ) // deprecated { uint8_t n,nid; bits256 hash; uint64_t mask; n = fgetc(fp); nid = fgetc(fp); //printf("U %d %d\n",n,nid); if ( fread(&mask,1,sizeof(mask),fp) != sizeof(mask) ) errs++; if ( fread(&hash,1,sizeof(hash),fp) != sizeof(hash) ) errs++; //if ( matched != 0 ) // komodo_eventadd_utxo(sp,symbol,ht,nid,hash,mask,n); } else if ( func == 'K' ) { int32_t kheight; if ( fread(&kheight,1,sizeof(kheight),fp) != sizeof(kheight) ) errs++; //if ( matched != 0 ) global independent states -> inside *sp //printf("%s.%d load[%s] ht.%d\n",ASSETCHAINS_SYMBOL,ht,symbol,kheight); komodo_eventadd_kmdheight(sp,symbol,ht,kheight,0); } else if ( func == 'T' ) { int32_t kheight,ktimestamp; if ( fread(&kheight,1,sizeof(kheight),fp) != sizeof(kheight) ) errs++; if ( fread(&ktimestamp,1,sizeof(ktimestamp),fp) != sizeof(ktimestamp) ) errs++; //if ( matched != 0 ) global independent states -> inside *sp //printf("%s.%d load[%s] ht.%d t.%u\n",ASSETCHAINS_SYMBOL,ht,symbol,kheight,ktimestamp); komodo_eventadd_kmdheight(sp,symbol,ht,kheight,ktimestamp); } else if ( func == 'R' ) { uint16_t olen,v; uint64_t ovalue; bits256 txid; uint8_t opret[16384]; if ( fread(&txid,1,sizeof(txid),fp) != sizeof(txid) ) errs++; if ( fread(&v,1,sizeof(v),fp) != sizeof(v) ) errs++; if ( fread(&ovalue,1,sizeof(ovalue),fp) != sizeof(ovalue) ) errs++; if ( fread(&olen,1,sizeof(olen),fp) != sizeof(olen) ) errs++; if ( olen < sizeof(opret) ) { if ( fread(opret,1,olen,fp) != olen ) errs++; if ( 0 && matched != 0 ) { int32_t i; for (i=0; i global PAX } else { int32_t i; for (i=0; i global PVALS //printf("%s load[%s] prices %d\n",ASSETCHAINS_SYMBOL,symbol,ht); //komodo_eventadd_pricefeed(sp,symbol,ht,pvals,numpvals); //printf("load pvals ht.%d numpvals.%d\n",ht,numpvals); } else printf("error loading pvals[%d]\n",numpvals); } else printf("[%s] %s illegal func.(%d %c)\n",ASSETCHAINS_SYMBOL,symbol,func,func); return(func); } else return(-1); } void stats_stateupdate(char *destdir,char *statefname,int32_t maxseconds) { static long lastpos; char symbol[64],base[64],dest[64]; int32_t n; FILE *fp; uint32_t starttime; struct komodo_state *sp; starttime = (uint32_t)time(NULL); strcpy(base,"KV"); strcpy(symbol,"KV"); strcpy(dest,"KMD"); sp = &KOMODO_STATE; n = 0; if ( (fp= fopen(statefname,"rb")) != 0 && sp != 0 ) { fseek(fp,0,SEEK_END); if ( ftell(fp) > lastpos ) { fseek(fp,lastpos,SEEK_SET); while ( komodo_parsestatefile(sp,fp,symbol,dest) >= 0 && n < 1000 ) { if ( n == 999 ) { if ( time(NULL) < starttime+maxseconds ) n = 0; else break; } n++; } lastpos = ftell(fp); } fclose(fp); } } char *stats_update(char *destdir,char *statefname) { cJSON *retjson = cJSON_CreateArray(); stats_stateupdate(destdir,statefname,10); return(jprint(retjson,1)); } int main(int argc, const char * argv[]) { FILE *fp; char *filestr,*statefname; if ( argc < 2 ) statefname = "/root/.komodo/KV/komodostate"; else statefname = (char *)argv[1]; printf("DEX stats running\n"); while ( 1 ) { if ( (filestr= stats_update(STATS_DEST,statefname)) != 0 ) { printf("%u: %s\n",(uint32_t)time(NULL),filestr); if ( (fp= fopen(STATS_DEST,"wb")) != 0 ) { fwrite(filestr,1,strlen(filestr)+1,fp); fclose(fp); } free(filestr); } sleep(60); } return 0; }