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