]> 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;
98 FILE *fp; char fname[512]; uint32_t crc32,check,timestamp; int32_t i,n,retval,fsize,len=0; uint8_t data[8192];
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 }
134 } else printf("t%u too old for %u\n",timestamp,(uint32_t)time(NULL));
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
d019c447 156int32_t PAX_pubkey(uint8_t *pubkey33,uint8_t addrtype,uint8_t rmd160[20],char fiat[4],uint8_t shortflag,int32_t fiatunits)
157{
158 memset(pubkey33,0,33);
159 pubkey33[0] = 0x02 | (shortflag != 0);
cc87f146 160 memcpy(&pubkey33[1],fiat,3);
d019c447 161 iguana_rwnum(1,&pubkey33[4],sizeof(fiatunits),(void *)&fiatunits);
cc87f146 162 memcpy(&pubkey33[8],(char *)"PAX",4);
163 pubkey33[12] = addrtype;
164 memcpy(&pubkey33[13],rmd160,20);
d019c447 165}
166
1e81ccb7 167double PAX_val(uint32_t pval,int32_t baseid)
168{
169 //printf("PAX_val baseid.%d pval.%u\n",baseid,pval);
170 if ( baseid >= 0 && baseid < MAX_CURRENCIES )
171 return(((double)pval / 1000000000.) / MINDENOMS[baseid]);
172 return(0.);
173}
174
175void komodo_pvals(int32_t height,uint32_t *pvals,uint8_t numpvals)
176{
177 int32_t i,nonz; double KMDBTC,BTCUSD,CNYUSD; uint32_t kmdbtc,btcusd,cnyusd;
178 if ( numpvals >= 35 )
179 {
180 for (nonz=i=0; i<32; i++)
181 {
182 if ( pvals[i] != 0 )
183 nonz++;
184 //printf("%u ",pvals[i]);
185 }
186 if ( nonz == 32 )
187 {
188 kmdbtc = pvals[i++];
189 btcusd = pvals[i++];
190 cnyusd = pvals[i++];
191 KMDBTC = ((double)kmdbtc / (1000000000. * 1000.));
192 BTCUSD = ((double)btcusd / (1000000000. / 1000.));
193 CNYUSD = ((double)cnyusd / 1000000000.);
194 PVALS = (uint32_t *)realloc(PVALS,(NUM_PRICES+1) * sizeof(*PVALS) * 36);
195 PVALS[36 * NUM_PRICES] = height;
196 memcpy(&PVALS[36 * NUM_PRICES + 1],pvals,sizeof(*pvals) * 35);
197 NUM_PRICES++;
198 //printf("OP_RETURN.%d KMD %.8f BTC %.6f CNY %.6f NUM_PRICES.%d\n",height,KMDBTC,BTCUSD,CNYUSD,NUM_PRICES);
199 }
200 }
201}
202
203int32_t komodo_baseid(char *origbase)
204{
205 int32_t i; char base[64];
206 for (i=0; origbase[i]!=0&&i<sizeof(base); i++)
207 base[i] = toupper((int32_t)(origbase[i] & 0xff));
208 base[i] = 0;
209 for (i=0; i<=MAX_CURRENCIES; i++)
210 if ( strcmp(CURRENCIES[i],base) == 0 )
211 return(i);
212 printf("illegal base.(%s) %s\n",origbase,base);
213 return(-1);
214}
215
d019c447 216uint64_t komodo_paxcalc(uint32_t *pvals,int32_t baseid,int32_t relid,uint64_t basevolume)
a4ebaad7 217{
048ae852 218 uint32_t pvalb,pvalr,kmdbtc,btcusd; uint64_t usdvol,baseusd,usdkmd,baserel,sum,ranked[32]; int32_t i;
a4ebaad7 219 if ( (pvalb= pvals[baseid]) != 0 )
220 {
221 if ( relid == MAX_CURRENCIES )
222 {
223 kmdbtc = pvals[MAX_CURRENCIES];
224 btcusd = pvals[MAX_CURRENCIES + 1];
225 if ( pvals[USD] != 0 && kmdbtc != 0 && btcusd != 0 )
226 {
227 baseusd = ((uint64_t)pvalb * 1000000000) / pvals[USD];
6ea0c7db 228 usdvol = komodo_paxvol(basevolume,baseusd);
048ae852 229 usdkmd = ((uint64_t)btcusd * 1000000000) / kmdbtc;
a4ebaad7 230 //printf("base -> USD %llu, BTC %llu KMDUSD %llu\n",(long long)baseusd,(long long)btcusd,(long long)kmdusd);
048ae852 231 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);
6ea0c7db 232 return(komodo_paxvol(usdvol,usdkmd) * (MINDENOMS[USD] / MINDENOMS[baseid]));
a4ebaad7 233 }
234 }
235 else if ( baseid == relid )
236 {
56d91e9c 237 if ( baseid != MAX_CURRENCIES )
238 {
239 pax_rank(ranked,pvals);
d836ec3f 240 return(10 * ranked[baseid]); // map to percentage
56d91e9c 241 }
a4ebaad7 242 }
243 else if ( (pvalr= pvals[relid]) != 0 )
244 {
245 baserel = ((uint64_t)pvalb * 1000000000) / pvalr;
d019c447 246 return(komodo_paxvol(basevolume,baserel));
a4ebaad7 247 }
248 }
08ef004d 249 return(0);
a4ebaad7 250}
251
d019c447 252uint64_t komodo_paxprice(int32_t height,char *base,char *rel,uint64_t basevolume)
1e81ccb7 253{
aa5a494c 254 int32_t baseid=-1,relid=-1,i,ht; uint32_t *ptr;
1e81ccb7 255 if ( (baseid= komodo_baseid(base)) >= 0 && (relid= komodo_baseid(rel)) >= 0 )
256 {
257 for (i=NUM_PRICES-1; i>=0; i--)
258 {
259 ptr = &PVALS[36 * i];
260 if ( *ptr < height )
d019c447 261 return(komodo_paxcalc(&ptr[1],baseid,relid,basevolume));
1e81ccb7 262 }
263 } else printf("paxprice invalid base.%s %d, rel.%s %d\n",base,baseid,rel,relid);
264 return(0);
265}
266
d836ec3f 267int32_t komodo_paxprices(int32_t *heights,uint64_t *prices,int32_t max,char *base,char *rel)
a4ebaad7 268{
56d91e9c 269 int32_t baseid=-1,relid=-1,i,ht,num = 0; uint32_t *ptr;
a4ebaad7 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];
56d91e9c 275 heights[num] = *ptr;
276 prices[num] = komodo_paxcalc(&ptr[1],baseid,relid,COIN);
277 num++;
278 if ( num >= max )
279 return(num);
a4ebaad7 280 }
281 }
56d91e9c 282 return(num);
a4ebaad7 283}
284
d019c447 285uint64_t PAX_fiatdest(char *destaddr,uint8_t pubkey33[33],char *coinaddr,int32_t height,char *base,int32_t fiatunits)
1e81ccb7 286{
d019c447 287 uint8_t shortflag = 0; int32_t baseid,relid; uint8_t addrtype,rmd160[20]; uint64_t komodoshis = 0;
cc87f146 288 if ( strcmp(base,(char *)"KMD") == 0 || strcmp(base,(char *)"kmd") == 0 )
d019c447 289 return(0);
290 if ( fiatunits < 0 )
291 shortflag = 1, fiatunits = -fiatunits;
35199465 292 komodoshis = komodo_paxprice(height,base,(char *)"KMD",(uint64_t)fiatunits);
d019c447 293 if ( bitcoin_addr2rmd160(&addrtype,rmd160,coinaddr) == 20 )
1e81ccb7 294 {
d019c447 295 PAX_pubkey(pubkey33,addrtype,rmd160,base,shortflag,fiatunits);
296 bitcoin_address(destaddr,KOMODO_PUBTYPE,pubkey33,33);
1e81ccb7 297 }
d019c447 298 return(komodoshis);
1e81ccb7 299}
This page took 0.057808 seconds and 4 git commands to generate.