]> Git Repo - VerusCoin.git/blame - src/komodo_pax.h
test
[VerusCoin.git] / src / komodo_pax.h
CommitLineData
d019c447 1/******************************************************************************
2 * Copyright © 2014-2016 The SuperNET Developers. *
3 * *
4 * See the AUTHORS, DEVELOPER-AGREEMENT and LICENSE files at *
5 * the top-level directory of this distribution for the individual copyright *
6 * holder information and the developer policies on copyright and licensing. *
7 * *
8 * Unless otherwise agreed in a custom licensing agreement, no part of the *
9 * SuperNET software, including this file may be copied, modified, propagated *
10 * or distributed except according to the terms contained in the LICENSE file *
11 * *
12 * Removal or modification of this copyright notice is prohibited. *
13 * *
14 ******************************************************************************/
1e81ccb7 15
16int32_t NUM_PRICES; uint32_t *PVALS;
17
41a4a4db 18#define USD 0
19
1e81ccb7 20#define MAX_CURRENCIES 32
21char CURRENCIES[][8] = { "USD", "EUR", "JPY", "GBP", "AUD", "CAD", "CHF", "NZD", // major currencies
22 "CNY", "RUB", "MXN", "BRL", "INR", "HKD", "TRY", "ZAR", "PLN", "NOK", "SEK", "DKK", "CZK", "HUF", "ILS", "KRW", "MYR", "PHP", "RON", "SGD", "THB", "BGN", "IDR", "HRK",
23 "KMD" };
24
a4ebaad7 25uint64_t M1SUPPLY[] = { 3317900000000, 6991604000000, 667780000000000, 1616854000000, 331000000000, 861909000000, 584629000000, 46530000000, // major currencies
05dfe053 26 45434000000000, 16827000000000, 3473357229000, 306435000000, 27139000000000, 2150641000000, 347724099000, 1469583000000, 749543000000, 1826110000000, 2400434000000, 1123925000000, 3125276000000, 13975000000000, 317657000000, 759706000000000, 354902000000, 2797061000000, 162189000000, 163745000000, 1712000000000, 39093000000, 1135490000000000, 80317000000,
a4ebaad7 27 100000000 };
28
29#define MIND 1000
30uint32_t MINDENOMS[] = { MIND, MIND, 100*MIND, MIND, MIND, MIND, MIND, MIND, // major currencies
31 10*MIND, 100*MIND, 10*MIND, MIND, 100*MIND, 10*MIND, MIND, 10*MIND, MIND, 10*MIND, 10*MIND, 10*MIND, 10*MIND, 100*MIND, MIND, 1000*MIND, MIND, 10*MIND, MIND, MIND, 10*MIND, MIND, 10000*MIND, 10*MIND, // end of currencies
3210*MIND,
1e81ccb7 33};
34
ab6984e9 35uint64_t komodo_paxvol(uint64_t volume,uint64_t price)
36{
37 if ( volume < 10000000000 )
38 return((volume * price) / 1000000000);
39 else if ( volume < (uint64_t)10 * 10000000000 )
40 return((volume * (price / 10)) / 100000000);
41 else if ( volume < (uint64_t)100 * 10000000000 )
42 return(((volume / 10) * (price / 10)) / 10000000);
43 else if ( volume < (uint64_t)1000 * 10000000000 )
44 return(((volume / 10) * (price / 100)) / 1000000);
45 else if ( volume < (uint64_t)10000 * 10000000000 )
46 return(((volume / 100) * (price / 100)) / 100000);
47 else if ( volume < (uint64_t)100000 * 10000000000 )
48 return(((volume / 100) * (price / 1000)) / 10000);
49 else if ( volume < (uint64_t)1000000 * 10000000000 )
50 return(((volume / 1000) * (price / 1000)) / 1000);
51 else if ( volume < (uint64_t)10000000 * 10000000000 )
52 return(((volume / 1000) * (price / 10000)) / 100);
53 else return(((volume / 10000) * (price / 10000)) / 10);
54}
55
a4ebaad7 56void pax_rank(uint64_t *ranked,uint32_t *pvals)
57{
58 int32_t i; uint64_t vals[32],sum = 0;
59 for (i=0; i<32; i++)
60 {
61 vals[i] = komodo_paxvol(M1SUPPLY[i] / MINDENOMS[i],pvals[i]);
62 sum += vals[i];
63 }
64 for (i=0; i<32; i++)
65 {
66 ranked[i] = (vals[i] * 1000000000) / sum;
56d91e9c 67 //printf("%.6f ",(double)ranked[i]/1000000000.);
a4ebaad7 68 }
56d91e9c 69 //printf("sum %llu\n",(long long)sum);
a4ebaad7 70};
71
1e81ccb7 72int32_t dpow_readprices(uint8_t *data,uint32_t *timestampp,double *KMDBTCp,double *BTCUSDp,double *CNYUSDp,uint32_t *pvals)
73{
74 uint32_t kmdbtc,btcusd,cnyusd; int32_t i,n,len = 0;
75 len += iguana_rwnum(0,&data[len],sizeof(uint32_t),(void *)timestampp);
76 len += iguana_rwnum(0,&data[len],sizeof(uint32_t),(void *)&n);
77 len += iguana_rwnum(0,&data[len],sizeof(uint32_t),(void *)&kmdbtc); // /= 1000
78 len += iguana_rwnum(0,&data[len],sizeof(uint32_t),(void *)&btcusd); // *= 1000
79 len += iguana_rwnum(0,&data[len],sizeof(uint32_t),(void *)&cnyusd);
80 *KMDBTCp = ((double)kmdbtc / (1000000000. * 1000.));
81 *BTCUSDp = ((double)btcusd / (1000000000. / 1000.));
82 *CNYUSDp = ((double)cnyusd / 1000000000.);
83 for (i=0; i<n-3; i++)
84 {
85 len += iguana_rwnum(0,&data[len],sizeof(uint32_t),(void *)&pvals[i]);
86 //printf("%u ",pvals[i]);
87 }
88 pvals[i++] = kmdbtc;
89 pvals[i++] = btcusd;
90 pvals[i++] = cnyusd;
91 //printf("OP_RETURN prices\n");
92 return(n);
93}
94
d019c447 95int32_t komodo_pax_opreturn(uint8_t *opret,int32_t maxsize)
96{
97 static uint32_t lastcrc;
d351e231 98 FILE *fp; char fname[512]; uint32_t crc32,check,timestamp; int32_t i,n=0,retval,fsize,len=0; uint8_t data[8192];
d019c447 99#ifdef WIN32
100 sprintf(fname,"%s\\%s",GetDataDir(false).string().c_str(),(char *)"komodofeed");
101#else
102 sprintf(fname,"%s/%s",GetDataDir(false).string().c_str(),(char *)"komodofeed");
103#endif
104 if ( (fp= fopen(fname,"rb")) != 0 )
105 {
106 fseek(fp,0,SEEK_END);
107 fsize = (int32_t)ftell(fp);
108 rewind(fp);
109 if ( fsize <= maxsize-4 && fsize <= sizeof(data) && fsize > sizeof(crc32) )
110 {
111 if ( (retval= (int32_t)fread(data,1,fsize,fp)) == fsize )
112 {
113 len = iguana_rwnum(0,data,sizeof(crc32),(void *)&crc32);
114 check = calc_crc32(0,data+sizeof(crc32),(int32_t)(fsize-sizeof(crc32)));
115 if ( check == crc32 )
116 {
117 double KMDBTC,BTCUSD,CNYUSD; uint32_t pvals[128];
118 dpow_readprices(&data[len],&timestamp,&KMDBTC,&BTCUSD,&CNYUSD,pvals);
119 if ( 0 && lastcrc != crc32 )
120 {
121 for (i=0; i<32; i++)
122 printf("%u ",pvals[i]);
123 printf("t%u n.%d KMD %f BTC %f CNY %f (%f)\n",timestamp,n,KMDBTC,BTCUSD,CNYUSD,CNYUSD!=0?1./CNYUSD:0);
124 }
125 if ( timestamp > time(NULL)-600 )
126 {
127 n = komodo_opreturnscript(opret,'P',data+sizeof(crc32),(int32_t)(fsize-sizeof(crc32)));
128 if ( 0 && lastcrc != crc32 )
129 {
130 for (i=0; i<n; i++)
131 printf("%02x",opret[i]);
132 printf(" coinbase opret[%d] crc32.%u:%u\n",n,crc32,check);
133 }
beafd76b 134 } //else printf("t%u too old for %u\n",timestamp,(uint32_t)time(NULL));
d019c447 135 lastcrc = crc32;
136 } else printf("crc32 %u mismatch %u\n",crc32,check);
137 } else printf("fread.%d error != fsize.%d\n",retval,fsize);
138 } else printf("fsize.%d > maxsize.%d or data[%d]\n",fsize,maxsize,(int32_t)sizeof(data));
139 fclose(fp);
140 }
141 return(n);
142}
143
1e81ccb7 144/*uint32_t PAX_val32(double val)
145 {
146 uint32_t val32 = 0; struct price_resolution price;
147 if ( (price.Pval= val*1000000000) != 0 )
148 {
149 if ( price.Pval > 0xffffffff )
150 printf("Pval overflow error %lld\n",(long long)price.Pval);
151 else val32 = (uint32_t)price.Pval;
152 }
153 return(val32);
154 }*/
155
57abdbaf 156int32_t PAX_pubkey(int32_t rwflag,uint8_t *pubkey33,uint8_t *addrtypep,uint8_t rmd160[20],char fiat[4],uint8_t *shortflagp,int64_t *fiatoshisp)
d019c447 157{
57abdbaf 158 if ( rwflag != 0 )
159 {
160 memset(pubkey33,0,33);
161 pubkey33[0] = 0x02 | (*shortflagp != 0);
162 memcpy(&pubkey33[1],fiat,3);
163 iguana_rwnum(rwflag,&pubkey33[4],sizeof(*fiatoshisp),(void *)fiatoshisp);
164 pubkey33[12] = *addrtypep;
165 memcpy(&pubkey33[13],rmd160,20);
166 }
167 else
168 {
169 *shortflagp = (pubkey33[0] == 0x03);
170 memcpy(fiat,&pubkey33[1],4);
171 iguana_rwnum(rwflag,&pubkey33[4],sizeof(*fiatoshisp),(void *)fiatoshisp);
172 if ( *shortflagp != 0 )
173 *fiatoshisp = -(*fiatoshisp);
174 *addrtypep = pubkey33[12];
175 memcpy(rmd160,&pubkey33[13],20);
176 }
d351e231 177 return(33);
d019c447 178}
179
1e81ccb7 180double PAX_val(uint32_t pval,int32_t baseid)
181{
182 //printf("PAX_val baseid.%d pval.%u\n",baseid,pval);
183 if ( baseid >= 0 && baseid < MAX_CURRENCIES )
184 return(((double)pval / 1000000000.) / MINDENOMS[baseid]);
185 return(0.);
186}
187
188void komodo_pvals(int32_t height,uint32_t *pvals,uint8_t numpvals)
189{
d351e231 190 int32_t i,nonz; uint32_t kmdbtc,btcusd,cnyusd; //double KMDBTC,BTCUSD,CNYUSD;
1e81ccb7 191 if ( numpvals >= 35 )
192 {
193 for (nonz=i=0; i<32; i++)
194 {
195 if ( pvals[i] != 0 )
196 nonz++;
197 //printf("%u ",pvals[i]);
198 }
199 if ( nonz == 32 )
200 {
201 kmdbtc = pvals[i++];
202 btcusd = pvals[i++];
203 cnyusd = pvals[i++];
d351e231 204 //KMDBTC = ((double)kmdbtc / (1000000000. * 1000.));
205 //BTCUSD = ((double)btcusd / (1000000000. / 1000.));
206 //CNYUSD = ((double)cnyusd / 1000000000.);
1e81ccb7 207 PVALS = (uint32_t *)realloc(PVALS,(NUM_PRICES+1) * sizeof(*PVALS) * 36);
208 PVALS[36 * NUM_PRICES] = height;
209 memcpy(&PVALS[36 * NUM_PRICES + 1],pvals,sizeof(*pvals) * 35);
210 NUM_PRICES++;
211 //printf("OP_RETURN.%d KMD %.8f BTC %.6f CNY %.6f NUM_PRICES.%d\n",height,KMDBTC,BTCUSD,CNYUSD,NUM_PRICES);
212 }
213 }
214}
215
216int32_t komodo_baseid(char *origbase)
217{
218 int32_t i; char base[64];
219 for (i=0; origbase[i]!=0&&i<sizeof(base); i++)
220 base[i] = toupper((int32_t)(origbase[i] & 0xff));
221 base[i] = 0;
222 for (i=0; i<=MAX_CURRENCIES; i++)
223 if ( strcmp(CURRENCIES[i],base) == 0 )
224 return(i);
225 printf("illegal base.(%s) %s\n",origbase,base);
226 return(-1);
227}
228
d019c447 229uint64_t komodo_paxcalc(uint32_t *pvals,int32_t baseid,int32_t relid,uint64_t basevolume)
a4ebaad7 230{
d351e231 231 uint32_t pvalb,pvalr,kmdbtc,btcusd; uint64_t usdvol,baseusd,usdkmd,baserel,ranked[32];
3ba8f923 232 if ( basevolume > 1000000*COIN )
2e4514ce 233 return(0);
a4ebaad7 234 if ( (pvalb= pvals[baseid]) != 0 )
235 {
236 if ( relid == MAX_CURRENCIES )
237 {
238 kmdbtc = pvals[MAX_CURRENCIES];
239 btcusd = pvals[MAX_CURRENCIES + 1];
240 if ( pvals[USD] != 0 && kmdbtc != 0 && btcusd != 0 )
241 {
242 baseusd = ((uint64_t)pvalb * 1000000000) / pvals[USD];
74fcb540 243 usdvol = komodo_paxvol(basevolume,baseusd) / MINDENOMS[baseid];
048ae852 244 usdkmd = ((uint64_t)btcusd * 1000000000) / kmdbtc;
a4ebaad7 245 //printf("base -> USD %llu, BTC %llu KMDUSD %llu\n",(long long)baseusd,(long long)btcusd,(long long)kmdusd);
048ae852 246 printf("usdkmd.%llu basevolume.%llu baseusd.%llu paxvol.%llu usdvol.%llu\n",(long long)usdkmd,(long long)basevolume,(long long)baseusd,(long long)komodo_paxvol(basevolume,baseusd),(long long)usdvol);
74fcb540 247 return(MINDENOMS[USD] * komodo_paxvol(usdvol,usdkmd));
a4ebaad7 248 }
249 }
250 else if ( baseid == relid )
251 {
56d91e9c 252 if ( baseid != MAX_CURRENCIES )
253 {
254 pax_rank(ranked,pvals);
d836ec3f 255 return(10 * ranked[baseid]); // map to percentage
56d91e9c 256 }
a4ebaad7 257 }
258 else if ( (pvalr= pvals[relid]) != 0 )
259 {
260 baserel = ((uint64_t)pvalb * 1000000000) / pvalr;
d019c447 261 return(komodo_paxvol(basevolume,baserel));
a4ebaad7 262 }
263 }
08ef004d 264 return(0);
a4ebaad7 265}
266
d019c447 267uint64_t komodo_paxprice(int32_t height,char *base,char *rel,uint64_t basevolume)
1e81ccb7 268{
aa5a494c 269 int32_t baseid=-1,relid=-1,i,ht; uint32_t *ptr;
1e81ccb7 270 if ( (baseid= komodo_baseid(base)) >= 0 && (relid= komodo_baseid(rel)) >= 0 )
271 {
272 for (i=NUM_PRICES-1; i>=0; i--)
273 {
274 ptr = &PVALS[36 * i];
275 if ( *ptr < height )
d019c447 276 return(komodo_paxcalc(&ptr[1],baseid,relid,basevolume));
1e81ccb7 277 }
278 } else printf("paxprice invalid base.%s %d, rel.%s %d\n",base,baseid,rel,relid);
279 return(0);
280}
281
d836ec3f 282int32_t komodo_paxprices(int32_t *heights,uint64_t *prices,int32_t max,char *base,char *rel)
a4ebaad7 283{
56d91e9c 284 int32_t baseid=-1,relid=-1,i,ht,num = 0; uint32_t *ptr;
a4ebaad7 285 if ( (baseid= komodo_baseid(base)) >= 0 && (relid= komodo_baseid(rel)) >= 0 )
286 {
287 for (i=NUM_PRICES-1; i>=0; i--)
288 {
289 ptr = &PVALS[36 * i];
56d91e9c 290 heights[num] = *ptr;
291 prices[num] = komodo_paxcalc(&ptr[1],baseid,relid,COIN);
292 num++;
293 if ( num >= max )
294 return(num);
a4ebaad7 295 }
296 }
56d91e9c 297 return(num);
a4ebaad7 298}
299
303f5c1b 300uint64_t PAX_fiatdest(char *fiatbuf,char *destaddr,uint8_t pubkey33[33],char *coinaddr,int32_t height,char *origbase,int64_t fiatoshis)
1e81ccb7 301{
d351e231 302 uint8_t shortflag = 0; char base[4]; int32_t i; uint8_t addrtype,rmd160[20]; uint64_t komodoshis = 0;
303f5c1b 303 fiatbuf[0] = 0;
cc87f146 304 if ( strcmp(base,(char *)"KMD") == 0 || strcmp(base,(char *)"kmd") == 0 )
d019c447 305 return(0);
3ba8f923 306 for (i=0; i<3; i++)
307 base[i] = toupper(origbase[i]);
308 base[i] = 0;
30e79ca6 309 if ( fiatoshis < 0 )
310 shortflag = 1, fiatoshis = -fiatoshis;
3ba8f923 311 komodoshis = komodo_paxprice(height,base,(char *)"KMD",(uint64_t)fiatoshis);
d019c447 312 if ( bitcoin_addr2rmd160(&addrtype,rmd160,coinaddr) == 20 )
1e81ccb7 313 {
303f5c1b 314 // put JSON into fiatbuf enough to replicate/validate
57abdbaf 315 PAX_pubkey(1,pubkey33,&addrtype,rmd160,base,&shortflag,&fiatoshis);
d019c447 316 bitcoin_address(destaddr,KOMODO_PUBTYPE,pubkey33,33);
1e81ccb7 317 }
d019c447 318 return(komodoshis);
1e81ccb7 319}
This page took 0.068204 seconds and 4 git commands to generate.