]> 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{
1bf82154 74 uint32_t kmdbtc,btcusd,cnyusd; int32_t i,n,nonz,len = 0;
0201d1a6 75 if ( data[0] == 'P' && data[5] == 35 )
76 data++;
1e81ccb7 77 len += iguana_rwnum(0,&data[len],sizeof(uint32_t),(void *)timestampp);
78 len += iguana_rwnum(0,&data[len],sizeof(uint32_t),(void *)&n);
7eca18ee 79 if ( n != 35 )
7d59e5c9 80 {
81 printf("dpow_readprices illegal n.%d\n",n);
82 return(-1);
83 }
1e81ccb7 84 len += iguana_rwnum(0,&data[len],sizeof(uint32_t),(void *)&kmdbtc); // /= 1000
85 len += iguana_rwnum(0,&data[len],sizeof(uint32_t),(void *)&btcusd); // *= 1000
86 len += iguana_rwnum(0,&data[len],sizeof(uint32_t),(void *)&cnyusd);
87 *KMDBTCp = ((double)kmdbtc / (1000000000. * 1000.));
88 *BTCUSDp = ((double)btcusd / (1000000000. / 1000.));
89 *CNYUSDp = ((double)cnyusd / 1000000000.);
1bf82154 90 for (i=nonz=0; i<n-3; i++)
1e81ccb7 91 {
1bf82154 92 if ( pvals[i] != 0 )
93 nonz++;
49df008c 94 //else if ( nonz != 0 )
95 // printf("pvals[%d] is zero\n",i);
1e81ccb7 96 len += iguana_rwnum(0,&data[len],sizeof(uint32_t),(void *)&pvals[i]);
97 //printf("%u ",pvals[i]);
98 }
1bf82154 99 if ( nonz < n-3 )
ef7b1ba6 100 {
49df008c 101 //printf("nonz.%d n.%d retval -1\n",nonz,n);
1bf82154 102 return(-1);
ef7b1ba6 103 }
1e81ccb7 104 pvals[i++] = kmdbtc;
105 pvals[i++] = btcusd;
106 pvals[i++] = cnyusd;
107 //printf("OP_RETURN prices\n");
108 return(n);
109}
110
d019c447 111int32_t komodo_pax_opreturn(uint8_t *opret,int32_t maxsize)
112{
113 static uint32_t lastcrc;
d351e231 114 FILE *fp; char fname[512]; uint32_t crc32,check,timestamp; int32_t i,n=0,retval,fsize,len=0; uint8_t data[8192];
d019c447 115#ifdef WIN32
116 sprintf(fname,"%s\\%s",GetDataDir(false).string().c_str(),(char *)"komodofeed");
117#else
118 sprintf(fname,"%s/%s",GetDataDir(false).string().c_str(),(char *)"komodofeed");
119#endif
120 if ( (fp= fopen(fname,"rb")) != 0 )
121 {
122 fseek(fp,0,SEEK_END);
123 fsize = (int32_t)ftell(fp);
124 rewind(fp);
125 if ( fsize <= maxsize-4 && fsize <= sizeof(data) && fsize > sizeof(crc32) )
126 {
127 if ( (retval= (int32_t)fread(data,1,fsize,fp)) == fsize )
128 {
129 len = iguana_rwnum(0,data,sizeof(crc32),(void *)&crc32);
130 check = calc_crc32(0,data+sizeof(crc32),(int32_t)(fsize-sizeof(crc32)));
131 if ( check == crc32 )
132 {
133 double KMDBTC,BTCUSD,CNYUSD; uint32_t pvals[128];
1bf82154 134 if ( dpow_readprices(&data[len],&timestamp,&KMDBTC,&BTCUSD,&CNYUSD,pvals) > 0 )
d019c447 135 {
d019c447 136 if ( 0 && lastcrc != crc32 )
137 {
1bf82154 138 for (i=0; i<32; i++)
139 printf("%u ",pvals[i]);
140 printf("t%u n.%d KMD %f BTC %f CNY %f (%f)\n",timestamp,n,KMDBTC,BTCUSD,CNYUSD,CNYUSD!=0?1./CNYUSD:0);
d019c447 141 }
1bf82154 142 if ( timestamp > time(NULL)-600 )
143 {
144 n = komodo_opreturnscript(opret,'P',data+sizeof(crc32),(int32_t)(fsize-sizeof(crc32)));
145 if ( 0 && lastcrc != crc32 )
146 {
147 for (i=0; i<n; i++)
148 printf("%02x",opret[i]);
149 printf(" coinbase opret[%d] crc32.%u:%u\n",n,crc32,check);
150 }
151 } //else printf("t%u too old for %u\n",timestamp,(uint32_t)time(NULL));
152 lastcrc = crc32;
153 }
d019c447 154 } else printf("crc32 %u mismatch %u\n",crc32,check);
155 } else printf("fread.%d error != fsize.%d\n",retval,fsize);
156 } else printf("fsize.%d > maxsize.%d or data[%d]\n",fsize,maxsize,(int32_t)sizeof(data));
157 fclose(fp);
158 }
159 return(n);
160}
161
1e81ccb7 162/*uint32_t PAX_val32(double val)
163 {
164 uint32_t val32 = 0; struct price_resolution price;
165 if ( (price.Pval= val*1000000000) != 0 )
166 {
167 if ( price.Pval > 0xffffffff )
168 printf("Pval overflow error %lld\n",(long long)price.Pval);
169 else val32 = (uint32_t)price.Pval;
170 }
171 return(val32);
172 }*/
173
57abdbaf 174int32_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 175{
57abdbaf 176 if ( rwflag != 0 )
177 {
178 memset(pubkey33,0,33);
179 pubkey33[0] = 0x02 | (*shortflagp != 0);
180 memcpy(&pubkey33[1],fiat,3);
181 iguana_rwnum(rwflag,&pubkey33[4],sizeof(*fiatoshisp),(void *)fiatoshisp);
182 pubkey33[12] = *addrtypep;
183 memcpy(&pubkey33[13],rmd160,20);
184 }
185 else
186 {
187 *shortflagp = (pubkey33[0] == 0x03);
188 memcpy(fiat,&pubkey33[1],4);
189 iguana_rwnum(rwflag,&pubkey33[4],sizeof(*fiatoshisp),(void *)fiatoshisp);
190 if ( *shortflagp != 0 )
191 *fiatoshisp = -(*fiatoshisp);
192 *addrtypep = pubkey33[12];
193 memcpy(rmd160,&pubkey33[13],20);
194 }
d351e231 195 return(33);
d019c447 196}
197
1e81ccb7 198double PAX_val(uint32_t pval,int32_t baseid)
199{
200 //printf("PAX_val baseid.%d pval.%u\n",baseid,pval);
201 if ( baseid >= 0 && baseid < MAX_CURRENCIES )
202 return(((double)pval / 1000000000.) / MINDENOMS[baseid]);
203 return(0.);
204}
205
206void komodo_pvals(int32_t height,uint32_t *pvals,uint8_t numpvals)
207{
5c481612 208 int32_t i,nonz; uint32_t kmdbtc,btcusd,cnyusd; double KMDBTC,BTCUSD,CNYUSD;
1e81ccb7 209 if ( numpvals >= 35 )
210 {
211 for (nonz=i=0; i<32; i++)
212 {
213 if ( pvals[i] != 0 )
214 nonz++;
215 //printf("%u ",pvals[i]);
216 }
217 if ( nonz == 32 )
218 {
219 kmdbtc = pvals[i++];
220 btcusd = pvals[i++];
221 cnyusd = pvals[i++];
5c481612 222 KMDBTC = ((double)kmdbtc / (1000000000. * 1000.));
223 BTCUSD = ((double)btcusd / (1000000000. / 1000.));
224 CNYUSD = ((double)cnyusd / 1000000000.);
1e81ccb7 225 PVALS = (uint32_t *)realloc(PVALS,(NUM_PRICES+1) * sizeof(*PVALS) * 36);
226 PVALS[36 * NUM_PRICES] = height;
227 memcpy(&PVALS[36 * NUM_PRICES + 1],pvals,sizeof(*pvals) * 35);
228 NUM_PRICES++;
5c481612 229 if ( 0 )
230 printf("OP_RETURN.%d KMD %.8f BTC %.6f CNY %.6f NUM_PRICES.%d (%llu %llu %llu)\n",height,KMDBTC,BTCUSD,CNYUSD,NUM_PRICES,(long long)kmdbtc,(long long)btcusd,(long long)cnyusd);
1e81ccb7 231 }
232 }
233}
234
235int32_t komodo_baseid(char *origbase)
236{
237 int32_t i; char base[64];
238 for (i=0; origbase[i]!=0&&i<sizeof(base); i++)
239 base[i] = toupper((int32_t)(origbase[i] & 0xff));
240 base[i] = 0;
241 for (i=0; i<=MAX_CURRENCIES; i++)
242 if ( strcmp(CURRENCIES[i],base) == 0 )
243 return(i);
244 printf("illegal base.(%s) %s\n",origbase,base);
245 return(-1);
246}
247
d019c447 248uint64_t komodo_paxcalc(uint32_t *pvals,int32_t baseid,int32_t relid,uint64_t basevolume)
a4ebaad7 249{
d351e231 250 uint32_t pvalb,pvalr,kmdbtc,btcusd; uint64_t usdvol,baseusd,usdkmd,baserel,ranked[32];
3ba8f923 251 if ( basevolume > 1000000*COIN )
2e4514ce 252 return(0);
a4ebaad7 253 if ( (pvalb= pvals[baseid]) != 0 )
254 {
255 if ( relid == MAX_CURRENCIES )
256 {
257 kmdbtc = pvals[MAX_CURRENCIES];
258 btcusd = pvals[MAX_CURRENCIES + 1];
259 if ( pvals[USD] != 0 && kmdbtc != 0 && btcusd != 0 )
260 {
261 baseusd = ((uint64_t)pvalb * 1000000000) / pvals[USD];
74fcb540 262 usdvol = komodo_paxvol(basevolume,baseusd) / MINDENOMS[baseid];
048ae852 263 usdkmd = ((uint64_t)btcusd * 1000000000) / kmdbtc;
a4ebaad7 264 //printf("base -> USD %llu, BTC %llu KMDUSD %llu\n",(long long)baseusd,(long long)btcusd,(long long)kmdusd);
048ae852 265 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 266 return(MINDENOMS[USD] * komodo_paxvol(usdvol,usdkmd));
a4ebaad7 267 }
268 }
269 else if ( baseid == relid )
270 {
56d91e9c 271 if ( baseid != MAX_CURRENCIES )
272 {
273 pax_rank(ranked,pvals);
d836ec3f 274 return(10 * ranked[baseid]); // map to percentage
56d91e9c 275 }
a4ebaad7 276 }
277 else if ( (pvalr= pvals[relid]) != 0 )
278 {
279 baserel = ((uint64_t)pvalb * 1000000000) / pvalr;
d019c447 280 return(komodo_paxvol(basevolume,baserel));
a4ebaad7 281 }
282 }
08ef004d 283 return(0);
a4ebaad7 284}
285
d019c447 286uint64_t komodo_paxprice(int32_t height,char *base,char *rel,uint64_t basevolume)
1e81ccb7 287{
c149d44c 288 int32_t baseid=-1,relid=-1,i; uint32_t *ptr;
1e81ccb7 289 if ( (baseid= komodo_baseid(base)) >= 0 && (relid= komodo_baseid(rel)) >= 0 )
290 {
291 for (i=NUM_PRICES-1; i>=0; i--)
292 {
293 ptr = &PVALS[36 * i];
294 if ( *ptr < height )
d019c447 295 return(komodo_paxcalc(&ptr[1],baseid,relid,basevolume));
1e81ccb7 296 }
297 } else printf("paxprice invalid base.%s %d, rel.%s %d\n",base,baseid,rel,relid);
298 return(0);
299}
300
d836ec3f 301int32_t komodo_paxprices(int32_t *heights,uint64_t *prices,int32_t max,char *base,char *rel)
a4ebaad7 302{
b20a5d7f 303 int32_t baseid=-1,relid=-1,i,num = 0; uint32_t *ptr;
a4ebaad7 304 if ( (baseid= komodo_baseid(base)) >= 0 && (relid= komodo_baseid(rel)) >= 0 )
305 {
306 for (i=NUM_PRICES-1; i>=0; i--)
307 {
308 ptr = &PVALS[36 * i];
56d91e9c 309 heights[num] = *ptr;
310 prices[num] = komodo_paxcalc(&ptr[1],baseid,relid,COIN);
311 num++;
312 if ( num >= max )
313 return(num);
a4ebaad7 314 }
315 }
56d91e9c 316 return(num);
a4ebaad7 317}
318
cd1fcb48 319void komodo_paxpricefeed(int32_t height,uint8_t *pricefeed,int32_t opretlen)
47e5cbc1 320{
321 double KMDBTC,BTCUSD,CNYUSD; uint32_t numpvals,timestamp,pvals[128]; uint256 zero;
322 numpvals = dpow_readprices(pricefeed,&timestamp,&KMDBTC,&BTCUSD,&CNYUSD,pvals);
323 memset(&zero,0,sizeof(zero));
30df2e00 324 komodo_stateupdate(height,0,0,0,zero,0,0,pvals,numpvals,0,0,0,0);
47e5cbc1 325 printf("komodo_paxpricefeed vout OP_RETURN.%d prices numpvals.%d opretlen.%d\n",height,numpvals,opretlen);
326}
327
d95bcb64 328uint64_t PAX_fiatdest(int32_t tokomodo,char *destaddr,uint8_t pubkey33[33],char *coinaddr,int32_t height,char *origbase,int64_t fiatoshis)
1e81ccb7 329{
7c6f8298 330 uint8_t shortflag = 0; char base[4]; int32_t i,baseid; uint8_t addrtype,rmd160[20]; uint64_t komodoshis = 0;
331 if ( (baseid= komodo_baseid(origbase)) < 0 || baseid == MAX_CURRENCIES )
d019c447 332 return(0);
3ba8f923 333 for (i=0; i<3; i++)
334 base[i] = toupper(origbase[i]);
335 base[i] = 0;
30e79ca6 336 if ( fiatoshis < 0 )
337 shortflag = 1, fiatoshis = -fiatoshis;
3ba8f923 338 komodoshis = komodo_paxprice(height,base,(char *)"KMD",(uint64_t)fiatoshis);
d019c447 339 if ( bitcoin_addr2rmd160(&addrtype,rmd160,coinaddr) == 20 )
1e81ccb7 340 {
7c6f8298 341 PAX_pubkey(1,pubkey33,&addrtype,rmd160,base,&shortflag,tokomodo != 0 ? &komodoshis : &fiatoshis);
d019c447 342 bitcoin_address(destaddr,KOMODO_PUBTYPE,pubkey33,33);
1e81ccb7 343 }
d019c447 344 return(komodoshis);
1e81ccb7 345}
This page took 0.081968 seconds and 4 git commands to generate.