Test
[VerusCoin.git] / src / komodo_pax.h
CommitLineData
d019c447 1/******************************************************************************
37fed603 2 * Copyright © 2014-2017 The SuperNET Developers. *
d019c447 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
41a4a4db 16#define USD 0
dd39b6bf 17#define EUR 1
18#define JPY 2
19#define GBP 3
20#define AUD 4
21#define CAD 5
22#define CHF 6
23#define NZD 7
24
25#define CNY 8
26#define RUB 9
27#define MXN 10
28#define BRL 11
29#define INR 12
30#define HKD 13
31#define TRY 14
32#define ZAR 15
33
34#define PLN 16
35#define NOK 17
36#define SEK 18
37#define DKK 19
38#define CZK 20
39#define HUF 21
40#define ILS 22
41#define KRW 23
42
43#define MYR 24
44#define PHP 25
45#define RON 26
46#define SGD 27
47#define THB 28
48#define BGN 29
49#define IDR 30
50#define HRK 31
41a4a4db 51
1e81ccb7 52#define MAX_CURRENCIES 32
18d9697a 53extern char CURRENCIES[][8];
1e81ccb7 54
a4ebaad7 55uint64_t M1SUPPLY[] = { 3317900000000, 6991604000000, 667780000000000, 1616854000000, 331000000000, 861909000000, 584629000000, 46530000000, // major currencies
05dfe053 56 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 57 100000000 };
58
59#define MIND 1000
60uint32_t MINDENOMS[] = { MIND, MIND, 100*MIND, MIND, MIND, MIND, MIND, MIND, // major currencies
61 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
6210*MIND,
1e81ccb7 63};
64
2e9292fe 65int32_t Peggy_inds[539] = {289, 404, 50, 490, 59, 208, 87, 508, 366, 288, 13, 38, 159, 440, 120, 480, 361, 104, 534, 195, 300, 362, 489, 108, 143, 220, 131, 244, 133, 473, 315, 439, 210, 456, 219, 352, 153, 444, 397, 491, 286, 479, 519, 384, 126, 369, 155, 427, 373, 360, 135, 297, 256, 506, 322, 425, 501, 251, 75, 18, 420, 537, 443, 438, 407, 145, 173, 78, 340, 240, 422, 160, 329, 32, 127, 128, 415, 495, 372, 522, 60, 238, 129, 364, 471, 140, 171, 215, 378, 292, 432, 526, 252, 389, 459, 350, 233, 408, 433, 51, 423, 19, 62, 115, 211, 22, 247, 197, 530, 7, 492, 5, 53, 318, 313, 283, 169, 464, 224, 282, 514, 385, 228, 175, 494, 237, 446, 105, 150, 338, 346, 510, 6, 348, 89, 63, 536, 442, 414, 209, 216, 227, 380, 72, 319, 259, 305, 334, 236, 103, 400, 176, 267, 355, 429, 134, 257, 527, 111, 287, 386, 15, 392, 535, 405, 23, 447, 399, 291, 112, 74, 36, 435, 434, 330, 520, 335, 201, 478, 17, 162, 483, 33, 130, 436, 395, 93, 298, 498, 511, 66, 487, 218, 65, 309, 419, 48, 214, 377, 409, 462, 139, 349, 4, 513, 497, 394, 170, 307, 241, 185, 454, 29, 367, 465, 194, 398, 301, 229, 212, 477, 303, 39, 524, 451, 116, 532, 30, 344, 85, 186, 202, 517, 531, 515, 230, 331, 466, 147, 426, 234, 304, 64, 100, 416, 336, 199, 383, 200, 166, 258, 95, 188, 246, 136, 90, 68, 45, 312, 354, 184, 314, 518, 326, 401, 269, 217, 512, 81, 88, 272, 14, 413, 328, 393, 198, 226, 381, 161, 474, 353, 337, 294, 295, 302, 505, 137, 207, 249, 46, 98, 27, 458, 482, 262, 253, 71, 25, 0, 40, 525, 122, 341, 107, 80, 165, 243, 168, 250, 375, 151, 503, 124, 52, 343, 371, 206, 178, 528, 232, 424, 163, 273, 191, 149, 493, 177, 144, 193, 388, 1, 412, 265, 457, 255, 475, 223, 41, 430, 76, 102, 132, 96, 97, 316, 472, 213, 263, 3, 317, 324, 274, 396, 486, 254, 205, 285, 101, 21, 279, 58, 467, 271, 92, 538, 516, 235, 332, 117, 500, 529, 113, 445, 390, 358, 79, 34, 488, 245, 83, 509, 203, 476, 496, 347, 280, 12, 84, 485, 323, 452, 10, 146, 391, 293, 86, 94, 523, 299, 91, 164, 363, 402, 110, 321, 181, 138, 192, 469, 351, 276, 308, 277, 428, 182, 260, 55, 152, 157, 382, 121, 507, 225, 61, 431, 31, 106, 327, 154, 16, 49, 499, 73, 70, 449, 460, 187, 24, 248, 311, 275, 158, 387, 125, 67, 284, 35, 463, 190, 179, 266, 376, 221, 42, 26, 290, 357, 268, 43, 167, 99, 374, 242, 156, 239, 403, 339, 183, 320, 180, 306, 379, 441, 20, 481, 141, 77, 484, 69, 410, 502, 172, 417, 118, 461, 261, 47, 333, 450, 296, 453, 368, 359, 437, 421, 264, 504, 281, 270, 114, 278, 56, 406, 448, 411, 521, 418, 470, 123, 455, 148, 356, 468, 109, 204, 533, 365, 8, 345, 174, 370, 28, 57, 11, 2, 231, 310, 196, 119, 82, 325, 44, 342, 37, 189, 142, 222, 9, 54, };
66
67uint64_t peggy_smooth_coeffs[sizeof(Peggy_inds)/sizeof(*Peggy_inds)] = // numprimes.13
68{
69 962714545, 962506087, 962158759, 961672710, 961048151, 960285354, 959384649, 958346426, 957171134, // x.8
70 955859283, 954411438, 952828225, 951110328, 949258485, 947273493, 945156207, 942907532, 940528434, // x.17
71 938019929, 935383089, 932619036, 929728945, 926714044, 923575608, 920314964, 916933485, 913432593, // x.26
72 909813756, 906078486, 902228342, 898264923, 894189872, 890004874, 885711650, 881311964, 876807614, // x.35
73 872200436, 867492300, 862685110, 857780804, 852781347, 847688737, 842505000, 837232189, 831872382, // x.44
74 826427681, 820900212, 815292123, 809605581, 803842772, 798005901, 792097186, 786118864, 780073180, // x.53
75 773962395, 767788778, 761554609, 755262175, 748913768, 742511686, 736058231, 729555707, 723006417, // x.62
76 716412665, 709776755, 703100984, 696387648, 689639036, 682857428, 676045100, 669204315, 662337327, // x.71
77 655446378, 648533696, 641601496, 634651978, 627687325, 620709702, 613721256, 606724115, 599720386, // x.80
78 592712154, 585701482, 578690411, 571680955, 564675105, 557674825, 550682053, 543698699, 536726645, // x.89
79 529767743, 522823816, 515896658, 508988029, 502099660, 495233249, 488390461, 481572928, 474782249, // x.98
80 468019988, 461287675, 454586804, 447918836, 441285195, 434687268, 428126409, 421603932, 415121117, // x.107
81 408679208, 402279408, 395922888, 389610779, 383344175, 377124134, 370951677, 364827785, 358753406, // x.116
82 352729449, 346756785, 340836251, 334968645, 329154729, 323395230, 317690838, 312042206, 306449955, // x.125
83 300914667, 295436891, 290017141, 284655897, 279353604, 274110676, 268927490, 263804394, 258741701, // x.134
84 253739694, 248798623, 243918709, 239100140, 234343077, 229647649, 225013957, 220442073, 215932043, // x.143
85 211483883, 207097585, 202773112, 198510404, 194309373, 190169909, 186091877, 182075118, 178119452, // x.152
86 174224676, 170390565, 166616873, 162903335, 159249664, 155655556, 152120688, 148644718, 145227287, // x.161
87 141868021, 138566528, 135322401, 132135218, 129004542, 125929924, 122910901, 119946997, 117037723, // x.170
88 114182582, 111381062, 108632643, 105936795, 103292978, 100700645, 98159238, 95668194, 93226942, // x.179
89 90834903, 88491495, 86196126, 83948203, 81747126, 79592292, 77483092, 75418916, 73399150, // x.188
90 71423178, 69490383, 67600142, 65751837, 63944844, 62178541, 60452305, 58765515, 57117547, // x.197
91 55507781, 53935597, 52400377, 50901505, 49438366, 48010349, 46616844, 45257246, 43930951, // x.206
92 42637360, 41375878, 40145912, 38946876, 37778185, 36639262, 35529533, 34448428, 33395384, // x.215
93 32369842, 31371249, 30399057, 29452725, 28531717, 27635503, 26763558, 25915365, 25090413, // x.224
94 24288196, 23508216, 22749980, 22013003, 21296806, 20600917, 19924870, 19268206, 18630475, // x.233
95 18011231, 17410035, 16826458, 16260073, 15710466, 15177224, 14659944, 14158231, 13671694, // x.242
96 13199950, 12742625, 12299348, 11869759, 11453500, 11050225, 10659590, 10281262, 9914910, // x.251
97 9560213, 9216856, 8884529, 8562931, 8251764, 7950739, 7659571, 7377984, 7105706, // x.260
98 6842471, 6588020, 6342099, 6104460, 5874861, 5653066, 5438844, 5231969, 5032221, // x.269
99 4839386, 4653254, 4473620, 4300287, 4133059, 3971747, 3816167, 3666139, 3521488, // x.278
100 3382043, 3247640, 3118115, 2993313, 2873079, 2757266, 2645728, 2538325, 2434919, // x.287
101 2335380, 2239575, 2147382, 2058677, 1973342, 1891262, 1812325, 1736424, 1663453, // x.296
102 1593311, 1525898, 1461118, 1398879, 1339091, 1281666, 1226519, 1173569, 1122736, // x.305
103 1073944, 1027117, 982185, 939076, 897725, 858065, 820033, 783568, 748612, // x.314
104 715108, 682999, 652233, 622759, 594527, 567488, 541597, 516808, 493079, // x.323
105 470368, 448635, 427841, 407948, 388921, 370725, 353326, 336692, 320792, // x.332
106 305596, 291075, 277202, 263950, 251292, 239204, 227663, 216646, 206130, // x.341
107 196094, 186517, 177381, 168667, 160356, 152430, 144874, 137671, 130806, // x.350
108 124264, 118031, 112093, 106437, 101050, 95921, 91039, 86391, 81968, // x.359
109 77759, 73755, 69945, 66322, 62877, 59602, 56488, 53528, 50716, // x.368
110 48043, 45505, 43093, 40803, 38629, 36564, 34604, 32745, 30980, // x.377
111 29305, 27717, 26211, 24782, 23428, 22144, 20927, 19774, 18681, // x.386
112 17646, 16665, 15737, 14857, 14025, 13237, 12491, 11786, 11118, // x.395
113 10487, 9890, 9325, 8791, 8287, 7810, 7359, 6933, 6531, // x.404
114 6151, 5792, 5453, 5133, 4831, 4547, 4278, 4024, 3785, // x.413
115 3560, 3347, 3147, 2958, 2779, 2612, 2454, 2305, 2164, // x.422
116 2032, 1908, 1791, 1681, 1577, 1480, 1388, 1302, 1221, // x.431
117 1145, 1073, 1006, 942, 883, 827, 775, 725, 679, // x.440
118 636, 595, 557, 521, 487, 456, 426, 399, 373, // x.449
119 348, 325, 304, 284, 265, 248, 231, 216, 202, // x.458
120 188, 175, 164, 153, 142, 133, 124, 115, 107, // x.467
121 100, 93, 87, 81, 75, 70, 65, 61, 56, // x.476
122 53, 49, 45, 42, 39, 36, 34, 31, 29, // x.485
123 27, 25, 23, 22, 20, 19, 17, 16, 15, // x.494
124 14, 13, 12, 11, 10, 9, 9, 8, 7, // x.503
125 7, 6, 6, 5, 5, 5, 4, 4, 4, // x.512
126 3, 3, 3, 3, 2, 2, 2, 2, 2, // x.521
127 2, 2, 1, 1, 1, 1, 1, 1, 1, // x.530
128 1, 1, 1, 1, 1, 1, 0, 0, // isum 100000000000
129};
130
5334d5ad 131uint64_t komodo_maxallowed(int32_t baseid)
132{
dff4ef45 133 uint64_t mult,val = COIN * (uint64_t)10000;
5334d5ad 134 if ( baseid < 0 || baseid >= 32 )
135 return(0);
136 if ( baseid < 10 )
dff4ef45 137 val *= 4;
5334d5ad 138 mult = MINDENOMS[baseid] / MIND;
139 return(mult * val);
140}
141
ab6984e9 142uint64_t komodo_paxvol(uint64_t volume,uint64_t price)
143{
144 if ( volume < 10000000000 )
145 return((volume * price) / 1000000000);
146 else if ( volume < (uint64_t)10 * 10000000000 )
147 return((volume * (price / 10)) / 100000000);
148 else if ( volume < (uint64_t)100 * 10000000000 )
149 return(((volume / 10) * (price / 10)) / 10000000);
150 else if ( volume < (uint64_t)1000 * 10000000000 )
151 return(((volume / 10) * (price / 100)) / 1000000);
152 else if ( volume < (uint64_t)10000 * 10000000000 )
153 return(((volume / 100) * (price / 100)) / 100000);
154 else if ( volume < (uint64_t)100000 * 10000000000 )
155 return(((volume / 100) * (price / 1000)) / 10000);
156 else if ( volume < (uint64_t)1000000 * 10000000000 )
157 return(((volume / 1000) * (price / 1000)) / 1000);
158 else if ( volume < (uint64_t)10000000 * 10000000000 )
159 return(((volume / 1000) * (price / 10000)) / 100);
160 else return(((volume / 10000) * (price / 10000)) / 10);
161}
162
a4ebaad7 163void pax_rank(uint64_t *ranked,uint32_t *pvals)
164{
165 int32_t i; uint64_t vals[32],sum = 0;
166 for (i=0; i<32; i++)
167 {
168 vals[i] = komodo_paxvol(M1SUPPLY[i] / MINDENOMS[i],pvals[i]);
169 sum += vals[i];
170 }
171 for (i=0; i<32; i++)
172 {
173 ranked[i] = (vals[i] * 1000000000) / sum;
56d91e9c 174 //printf("%.6f ",(double)ranked[i]/1000000000.);
a4ebaad7 175 }
56d91e9c 176 //printf("sum %llu\n",(long long)sum);
a4ebaad7 177};
178
1e81ccb7 179int32_t dpow_readprices(uint8_t *data,uint32_t *timestampp,double *KMDBTCp,double *BTCUSDp,double *CNYUSDp,uint32_t *pvals)
180{
1bf82154 181 uint32_t kmdbtc,btcusd,cnyusd; int32_t i,n,nonz,len = 0;
0201d1a6 182 if ( data[0] == 'P' && data[5] == 35 )
183 data++;
1e81ccb7 184 len += iguana_rwnum(0,&data[len],sizeof(uint32_t),(void *)timestampp);
185 len += iguana_rwnum(0,&data[len],sizeof(uint32_t),(void *)&n);
7eca18ee 186 if ( n != 35 )
7d59e5c9 187 {
188 printf("dpow_readprices illegal n.%d\n",n);
189 return(-1);
190 }
1e81ccb7 191 len += iguana_rwnum(0,&data[len],sizeof(uint32_t),(void *)&kmdbtc); // /= 1000
192 len += iguana_rwnum(0,&data[len],sizeof(uint32_t),(void *)&btcusd); // *= 1000
193 len += iguana_rwnum(0,&data[len],sizeof(uint32_t),(void *)&cnyusd);
194 *KMDBTCp = ((double)kmdbtc / (1000000000. * 1000.));
195 *BTCUSDp = ((double)btcusd / (1000000000. / 1000.));
196 *CNYUSDp = ((double)cnyusd / 1000000000.);
1bf82154 197 for (i=nonz=0; i<n-3; i++)
1e81ccb7 198 {
1bf82154 199 if ( pvals[i] != 0 )
200 nonz++;
49df008c 201 //else if ( nonz != 0 )
202 // printf("pvals[%d] is zero\n",i);
1e81ccb7 203 len += iguana_rwnum(0,&data[len],sizeof(uint32_t),(void *)&pvals[i]);
204 //printf("%u ",pvals[i]);
205 }
32f7d394 206 /*if ( nonz < n-3 )
ef7b1ba6 207 {
49df008c 208 //printf("nonz.%d n.%d retval -1\n",nonz,n);
1bf82154 209 return(-1);
32f7d394 210 }*/
1e81ccb7 211 pvals[i++] = kmdbtc;
212 pvals[i++] = btcusd;
213 pvals[i++] = cnyusd;
214 //printf("OP_RETURN prices\n");
215 return(n);
216}
217
d019c447 218int32_t komodo_pax_opreturn(uint8_t *opret,int32_t maxsize)
219{
220 static uint32_t lastcrc;
d351e231 221 FILE *fp; char fname[512]; uint32_t crc32,check,timestamp; int32_t i,n=0,retval,fsize,len=0; uint8_t data[8192];
d019c447 222#ifdef WIN32
223 sprintf(fname,"%s\\%s",GetDataDir(false).string().c_str(),(char *)"komodofeed");
224#else
225 sprintf(fname,"%s/%s",GetDataDir(false).string().c_str(),(char *)"komodofeed");
226#endif
227 if ( (fp= fopen(fname,"rb")) != 0 )
228 {
229 fseek(fp,0,SEEK_END);
230 fsize = (int32_t)ftell(fp);
231 rewind(fp);
232 if ( fsize <= maxsize-4 && fsize <= sizeof(data) && fsize > sizeof(crc32) )
233 {
234 if ( (retval= (int32_t)fread(data,1,fsize,fp)) == fsize )
235 {
236 len = iguana_rwnum(0,data,sizeof(crc32),(void *)&crc32);
237 check = calc_crc32(0,data+sizeof(crc32),(int32_t)(fsize-sizeof(crc32)));
238 if ( check == crc32 )
239 {
240 double KMDBTC,BTCUSD,CNYUSD; uint32_t pvals[128];
1bf82154 241 if ( dpow_readprices(&data[len],&timestamp,&KMDBTC,&BTCUSD,&CNYUSD,pvals) > 0 )
d019c447 242 {
d019c447 243 if ( 0 && lastcrc != crc32 )
244 {
1bf82154 245 for (i=0; i<32; i++)
246 printf("%u ",pvals[i]);
247 printf("t%u n.%d KMD %f BTC %f CNY %f (%f)\n",timestamp,n,KMDBTC,BTCUSD,CNYUSD,CNYUSD!=0?1./CNYUSD:0);
d019c447 248 }
1bf82154 249 if ( timestamp > time(NULL)-600 )
250 {
251 n = komodo_opreturnscript(opret,'P',data+sizeof(crc32),(int32_t)(fsize-sizeof(crc32)));
252 if ( 0 && lastcrc != crc32 )
253 {
254 for (i=0; i<n; i++)
255 printf("%02x",opret[i]);
256 printf(" coinbase opret[%d] crc32.%u:%u\n",n,crc32,check);
257 }
258 } //else printf("t%u too old for %u\n",timestamp,(uint32_t)time(NULL));
259 lastcrc = crc32;
260 }
d019c447 261 } else printf("crc32 %u mismatch %u\n",crc32,check);
262 } else printf("fread.%d error != fsize.%d\n",retval,fsize);
263 } else printf("fsize.%d > maxsize.%d or data[%d]\n",fsize,maxsize,(int32_t)sizeof(data));
264 fclose(fp);
265 }
266 return(n);
267}
268
1e81ccb7 269/*uint32_t PAX_val32(double val)
270 {
271 uint32_t val32 = 0; struct price_resolution price;
272 if ( (price.Pval= val*1000000000) != 0 )
273 {
274 if ( price.Pval > 0xffffffff )
275 printf("Pval overflow error %lld\n",(long long)price.Pval);
276 else val32 = (uint32_t)price.Pval;
277 }
278 return(val32);
279 }*/
280
57abdbaf 281int32_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 282{
57abdbaf 283 if ( rwflag != 0 )
284 {
285 memset(pubkey33,0,33);
286 pubkey33[0] = 0x02 | (*shortflagp != 0);
287 memcpy(&pubkey33[1],fiat,3);
288 iguana_rwnum(rwflag,&pubkey33[4],sizeof(*fiatoshisp),(void *)fiatoshisp);
289 pubkey33[12] = *addrtypep;
290 memcpy(&pubkey33[13],rmd160,20);
291 }
292 else
293 {
294 *shortflagp = (pubkey33[0] == 0x03);
4d272ae4 295 memcpy(fiat,&pubkey33[1],3);
4d272ae4 296 fiat[3] = 0;
57abdbaf 297 iguana_rwnum(rwflag,&pubkey33[4],sizeof(*fiatoshisp),(void *)fiatoshisp);
298 if ( *shortflagp != 0 )
299 *fiatoshisp = -(*fiatoshisp);
300 *addrtypep = pubkey33[12];
301 memcpy(rmd160,&pubkey33[13],20);
302 }
d351e231 303 return(33);
d019c447 304}
305
1e81ccb7 306double PAX_val(uint32_t pval,int32_t baseid)
307{
308 //printf("PAX_val baseid.%d pval.%u\n",baseid,pval);
309 if ( baseid >= 0 && baseid < MAX_CURRENCIES )
310 return(((double)pval / 1000000000.) / MINDENOMS[baseid]);
311 return(0.);
312}
313
314void komodo_pvals(int32_t height,uint32_t *pvals,uint8_t numpvals)
315{
5c481612 316 int32_t i,nonz; uint32_t kmdbtc,btcusd,cnyusd; double KMDBTC,BTCUSD,CNYUSD;
1e81ccb7 317 if ( numpvals >= 35 )
318 {
319 for (nonz=i=0; i<32; i++)
320 {
321 if ( pvals[i] != 0 )
322 nonz++;
323 //printf("%u ",pvals[i]);
324 }
325 if ( nonz == 32 )
326 {
327 kmdbtc = pvals[i++];
328 btcusd = pvals[i++];
329 cnyusd = pvals[i++];
5c481612 330 KMDBTC = ((double)kmdbtc / (1000000000. * 1000.));
331 BTCUSD = ((double)btcusd / (1000000000. / 1000.));
332 CNYUSD = ((double)cnyusd / 1000000000.);
f42f9288 333 portable_mutex_lock(&komodo_mutex);
1e81ccb7 334 PVALS = (uint32_t *)realloc(PVALS,(NUM_PRICES+1) * sizeof(*PVALS) * 36);
335 PVALS[36 * NUM_PRICES] = height;
336 memcpy(&PVALS[36 * NUM_PRICES + 1],pvals,sizeof(*pvals) * 35);
337 NUM_PRICES++;
f42f9288 338 portable_mutex_unlock(&komodo_mutex);
5c481612 339 if ( 0 )
340 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 341 }
342 }
343}
344
a6cd9b28 345uint64_t komodo_paxcorrelation(uint64_t *votes,int32_t numvotes,uint64_t seed)
a4ebaad7 346{
295e677f 347 int32_t i,j,k,ind,zeroes,wt,nonz; int64_t delta; uint64_t lastprice,tolerance,den,densum,sum=0;
348 for (sum=i=zeroes=nonz=0; i<numvotes; i++)
349 {
350 if ( votes[i] == 0 )
351 zeroes++;
352 else sum += votes[i], nonz++;
353 }
8ea67f05 354 if ( nonz < (numvotes >> 2) )
7851554d 355 return(0);
295e677f 356 sum /= nonz;
357 lastprice = sum;
358 for (i=0; i<numvotes; i++)
359 {
360 if ( votes[i] == 0 )
361 votes[i] = lastprice;
362 else lastprice = votes[i];
363 }
b5d53e71 364 tolerance = sum / 50;
295e677f 365 for (k=0; k<numvotes; k++)
366 {
367 ind = Peggy_inds[(k + seed) % numvotes];
368 i = (int32_t)(ind % numvotes);
369 wt = 0;
370 if ( votes[i] != 0 )
371 {
372 for (j=0; j<numvotes; j++)
373 {
374 if ( votes[j] != 0 )
375 {
376 if ( (delta= (votes[i] - votes[j])) < 0 )
377 delta = -delta;
e2ca75ae 378 if ( delta <= tolerance )
379 {
380 wt++;
381 if ( wt > (numvotes >> 1) )
382 break;
383 }
295e677f 384 }
385 }
386 }
387 if ( wt > (numvotes >> 1) )
388 {
389 ind = i;
390 for (densum=sum=j=0; j<numvotes; j++)
391 {
392 den = peggy_smooth_coeffs[j];
393 densum += den;
394 sum += (den * votes[(ind + j) % numvotes]);
2e16695c 395 //printf("(%llu/%llu %.8f) ",(long long)sum,(long long)densum,(double)sum/densum);
295e677f 396 }
8ea67f05 397 if ( densum != 0 )
398 sum /= densum;
e2ca75ae 399 //sum = (sum * basevolume);
400 //printf("paxprice seed.%llx sum %.8f densum %.8f\n",(long long)seed,dstr(sum),dstr(densum));
295e677f 401 break;
e2ca75ae 402 }
295e677f 403 }
404 return(sum);
405}
406
5b5af603 407uint64_t komodo_paxcalc(int32_t height,uint32_t *pvals,int32_t baseid,int32_t relid,uint64_t basevolume,uint64_t refkmdbtc,uint64_t refbtcusd)
295e677f 408{
d829a5f5 409 uint32_t pvalb,pvalr; uint64_t price,kmdbtc,btcusd,usdvol,baseusd,usdkmd,baserel,ranked[32];
ac606ad4 410 if ( basevolume > KOMODO_PAXMAX )
97865d36 411 {
412 printf("paxcalc overflow %.8f\n",dstr(basevolume));
2e4514ce 413 return(0);
97865d36 414 }
a4ebaad7 415 if ( (pvalb= pvals[baseid]) != 0 )
416 {
417 if ( relid == MAX_CURRENCIES )
418 {
d2f213b8 419 if ( height < 236000 )
420 {
421 if ( kmdbtc == 0 )
422 kmdbtc = pvals[MAX_CURRENCIES];
423 if ( btcusd == 0 )
424 btcusd = pvals[MAX_CURRENCIES + 1];
425 }
426 else
427 {
428 if ( (kmdbtc= pvals[MAX_CURRENCIES]) == 0 )
429 kmdbtc = refkmdbtc;
430 if ( (btcusd= pvals[MAX_CURRENCIES + 1]) == 0 )
431 btcusd = refbtcusd;
432 }
5fe8a65f 433 if ( kmdbtc < 25000000 )
434 kmdbtc = 25000000;
a4ebaad7 435 if ( pvals[USD] != 0 && kmdbtc != 0 && btcusd != 0 )
436 {
b0c7fb04 437 baseusd = (((uint64_t)pvalb * 1000000000) / pvals[USD]);
445e9606 438 usdvol = komodo_paxvol(basevolume,baseusd);
414bd08b 439 usdkmd = ((uint64_t)kmdbtc * 1000000000) / btcusd;
e2ca75ae 440 if ( height >= 236000-10 )
7b9c2935 441 {
442 usdkmd = ((uint64_t)kmdbtc * btcusd) / 1000000000;
e2ca75ae 443 if ( height > 380000 && baseid == USD )
7b9c2935 444 price = usdkmd;
e2ca75ae 445 else price = ((uint64_t)10000000000 * MINDENOMS[USD] / MINDENOMS[baseid]) / komodo_paxvol(usdvol,usdkmd);
7a9a3ddc 446 //fprintf(stderr,"ht.%d kmdbtc.%llu btcusd.%llu base -> USD %llu, usdkmd %llu usdvol %llu -> %llu\n",height,(long long)kmdbtc,(long long)btcusd,(long long)baseusd,(long long)usdkmd,(long long)usdvol,(long long)(MINDENOMS[USD] * komodo_paxvol(usdvol,usdkmd) / (MINDENOMS[baseid]/100)));
0ce1e753 447 //fprintf(stderr,"usdkmd.%llu basevolume.%llu baseusd.%llu paxvol.%llu usdvol.%llu -> %llu %llu\n",(long long)usdkmd,(long long)basevolume,(long long)baseusd,(long long)komodo_paxvol(basevolume,baseusd),(long long)usdvol,(long long)(MINDENOMS[USD] * komodo_paxvol(usdvol,usdkmd) / (MINDENOMS[baseid]/100)),(long long)price);
1049be8e 448 //fprintf(stderr,"usdkmd.%llu basevolume.%llu baseusd.%llu paxvol.%llu usdvol.%llu -> %llu\n",(long long)usdkmd,(long long)basevolume,(long long)baseusd,(long long)komodo_paxvol(basevolume,baseusd),(long long)usdvol,(long long)(MINDENOMS[USD] * komodo_paxvol(usdvol,usdkmd) / (MINDENOMS[baseid]/100)));
5ab5e9ff 449 } else price = (MINDENOMS[USD] * komodo_paxvol(usdvol,usdkmd) / (MINDENOMS[baseid]/100));
6bb5b220 450 return(price);
ee0744d2 451 } //else printf("zero val in KMD conv %llu %llu %llu\n",(long long)pvals[USD],(long long)kmdbtc,(long long)btcusd);
a4ebaad7 452 }
453 else if ( baseid == relid )
454 {
56d91e9c 455 if ( baseid != MAX_CURRENCIES )
456 {
457 pax_rank(ranked,pvals);
9ef47e29 458 //printf("%s M1 percentage %.8f\n",CURRENCIES[baseid],dstr(10 * ranked[baseid]));
5d299045 459 return(10 * ranked[baseid]); // scaled percentage of M1 total
97865d36 460 } else return(basevolume);
a4ebaad7 461 }
462 else if ( (pvalr= pvals[relid]) != 0 )
463 {
464 baserel = ((uint64_t)pvalb * 1000000000) / pvalr;
4077bfb0 465 //printf("baserel.%lld %lld %lld %.8f %.8f\n",(long long)baserel,(long long)MINDENOMS[baseid],(long long)MINDENOMS[relid],dstr(MINDENOMS[baseid]/MINDENOMS[relid]),dstr(MINDENOMS[relid]/MINDENOMS[baseid]));
b6f95ae6 466 if ( MINDENOMS[baseid] > MINDENOMS[relid] )
fde4e779 467 basevolume /= (MINDENOMS[baseid] / MINDENOMS[relid]);
b6f95ae6 468 else if ( MINDENOMS[baseid] < MINDENOMS[relid] )
fde4e779 469 basevolume *= (MINDENOMS[relid] / MINDENOMS[baseid]);
1a6bc62c 470 return(komodo_paxvol(basevolume,baserel));
a4ebaad7 471 }
97865d36 472 else printf("null pval for %s\n",CURRENCIES[relid]);
473 } else printf("null pval for %s\n",CURRENCIES[baseid]);
08ef004d 474 return(0);
a4ebaad7 475}
476
295e677f 477uint64_t _komodo_paxprice(uint64_t *kmdbtcp,uint64_t *btcusdp,int32_t height,char *base,char *rel,uint64_t basevolume,uint64_t kmdbtc,uint64_t btcusd)
1e81ccb7 478{
c149d44c 479 int32_t baseid=-1,relid=-1,i; uint32_t *ptr;
4307bd89 480 if ( height > 10 )
481 height -= 10;
1e81ccb7 482 if ( (baseid= komodo_baseid(base)) >= 0 && (relid= komodo_baseid(rel)) >= 0 )
483 {
bba30a43 484 //portable_mutex_lock(&komodo_mutex);
1e81ccb7 485 for (i=NUM_PRICES-1; i>=0; i--)
486 {
487 ptr = &PVALS[36 * i];
488 if ( *ptr < height )
295e677f 489 {
9e838b49 490 if ( kmdbtcp != 0 && btcusdp != 0 )
491 {
717b0c4e 492 *kmdbtcp = ptr[MAX_CURRENCIES + 1] / 539;
493 *btcusdp = ptr[MAX_CURRENCIES + 2] / 539;
9e838b49 494 }
bba30a43 495 //portable_mutex_unlock(&komodo_mutex);
295e677f 496 if ( kmdbtc != 0 && btcusd != 0 )
d5f0a866 497 return(komodo_paxcalc(height,&ptr[1],baseid,relid,basevolume,kmdbtc,btcusd));
295e677f 498 else return(0);
499 }
1e81ccb7 500 }
bba30a43 501 //portable_mutex_unlock(&komodo_mutex);
72da1eea 502 } //else printf("paxprice invalid base.%s %d, rel.%s %d\n",base,baseid,rel,relid);
1e81ccb7 503 return(0);
504}
505
e08169c4 506int32_t komodo_kmdbtcusd(int32_t rwflag,uint64_t *kmdbtcp,uint64_t *btcusdp,int32_t height)
507{
703cc8c9 508 static uint64_t *KMDBTCS,*BTCUSDS; static int32_t maxheight = 0; int32_t incr = 10000;
e08169c4 509 if ( height >= maxheight )
510 {
d854fae2 511 //printf("height.%d maxheight.%d incr.%d\n",height,maxheight,incr);
bfadcf9c 512 if ( height >= maxheight+incr )
513 incr = (height - (maxheight+incr) + 1000);
c9da2420 514 KMDBTCS = (uint64_t *)realloc(KMDBTCS,((incr + maxheight) * sizeof(*KMDBTCS)));
e08169c4 515 memset(&KMDBTCS[maxheight],0,(incr * sizeof(*KMDBTCS)));
c9da2420 516 BTCUSDS = (uint64_t *)realloc(BTCUSDS,((incr + maxheight) * sizeof(*BTCUSDS)));
e08169c4 517 memset(&BTCUSDS[maxheight],0,(incr * sizeof(*BTCUSDS)));
518 maxheight += incr;
519 }
520 if ( rwflag == 0 )
521 {
522 *kmdbtcp = KMDBTCS[height];
523 *btcusdp = BTCUSDS[height];
524 }
525 else
526 {
527 KMDBTCS[height] = *kmdbtcp;
528 BTCUSDS[height] = *btcusdp;
529 }
530 if ( *kmdbtcp != 0 && *btcusdp != 0 )
531 return(0);
532 else return(-1);
533}
534
5b5af603 535uint64_t _komodo_paxpriceB(uint64_t seed,int32_t height,char *base,char *rel,uint64_t basevolume)
2e9292fe 536{
c72ee808 537 int32_t i,j,k,ind,zeroes,numvotes,wt,nonz; int64_t delta; uint64_t lastprice,tolerance,den,densum,sum=0,votes[sizeof(Peggy_inds)/sizeof(*Peggy_inds)],btcusds[sizeof(Peggy_inds)/sizeof(*Peggy_inds)],kmdbtcs[sizeof(Peggy_inds)/sizeof(*Peggy_inds)],kmdbtc,btcusd;
ac606ad4 538 if ( basevolume > KOMODO_PAXMAX )
77af0879 539 {
540 printf("komodo_paxprice overflow %.8f\n",dstr(basevolume));
541 return(0);
542 }
b0c7fb04 543 if ( strcmp(base,"KMD") == 0 || strcmp(base,"kmd") == 0 )
544 {
545 printf("kmd cannot be base currency\n");
546 return(0);
547 }
2e9292fe 548 numvotes = (int32_t)(sizeof(Peggy_inds)/sizeof(*Peggy_inds));
549 memset(votes,0,sizeof(votes));
fa7d97db 550 //if ( komodo_kmdbtcusd(0,&kmdbtc,&btcusd,height) < 0 ) crashes when via passthru GUI use
a6cd9b28 551 {
e08169c4 552 memset(btcusds,0,sizeof(btcusds));
553 memset(kmdbtcs,0,sizeof(kmdbtcs));
554 for (i=0; i<numvotes; i++)
555 {
4350833c 556 _komodo_paxprice(&kmdbtcs[numvotes-1-i],&btcusds[numvotes-1-i],height-i,base,rel,100000,0,0);
e2ca75ae 557 //printf("(%llu %llu) ",(long long)kmdbtcs[numvotes-1-i],(long long)btcusds[numvotes-1-i]);
e08169c4 558 }
5765eedb 559 kmdbtc = komodo_paxcorrelation(kmdbtcs,numvotes,seed) * 539;
560 btcusd = komodo_paxcorrelation(btcusds,numvotes,seed) * 539;
9f9d5114 561 //komodo_kmdbtcusd(1,&kmdbtc,&btcusd,height);
a6cd9b28 562 }
295e677f 563 for (i=nonz=0; i<numvotes; i++)
68f2120f 564 {
4350833c 565 if ( (votes[numvotes-1-i]= _komodo_paxprice(0,0,height-i,base,rel,100000,kmdbtc,btcusd)) == 0 )
9fd7459c 566 zeroes++;
331b7eed 567 else
568 {
569 nonz++;
570 sum += votes[numvotes-1-i];
4130f3a0 571 //if ( (i % 10) == 0 )
e2ca75ae 572 // fprintf(stderr,"[%llu] ",(long long)votes[numvotes-1-i]);
331b7eed 573 }
68f2120f 574 }
e2ca75ae 575 //fprintf(stderr,"kmdbtc %llu btcusd %llu ",(long long)kmdbtc,(long long)btcusd);
576 //fprintf(stderr,"komodo_paxprice nonz.%d of numvotes.%d seed.%llu %.8f\n",nonz,numvotes,(long long)seed,nonz!=0?dstr(1000. * (double)sum/nonz):0);
9fd7459c 577 if ( nonz <= (numvotes >> 1) )
b75c9445 578 {
9fd7459c 579 return(0);
b75c9445 580 }
4350833c 581 return(komodo_paxcorrelation(votes,numvotes,seed) * basevolume / 100000);
2e9292fe 582}
583
5b5af603 584uint64_t komodo_paxpriceB(uint64_t seed,int32_t height,char *base,char *rel,uint64_t basevolume)
d4487f05 585{
586 uint64_t baseusd,basekmd,usdkmd; int32_t baseid = komodo_baseid(base);
587 if ( height >= 236000 && strcmp(rel,"kmd") == 0 )
588 {
589 usdkmd = _komodo_paxpriceB(seed,height,(char *)"USD",(char *)"KMD",SATOSHIDEN);
590 if ( strcmp("usd",base) == 0 )
5484ec26 591 return(komodo_paxvol(basevolume,usdkmd) * 10);
d4487f05 592 baseusd = _komodo_paxpriceB(seed,height,base,(char *)"USD",SATOSHIDEN);
593 basekmd = (komodo_paxvol(basevolume,baseusd) * usdkmd) / 10000000;
594 //if ( strcmp("KMD",base) == 0 )
595 // printf("baseusd.%llu usdkmd.%llu %llu\n",(long long)baseusd,(long long)usdkmd,(long long)basekmd);
596 return(basekmd);
597 } else return(_komodo_paxpriceB(seed,height,base,rel,basevolume));
598}
599
e2ca75ae 600/*uint64_t komodo_paxpriceB(uint64_t seed,int32_t height,char *base,char *rel,uint64_t basevolume)
601{
602 uint64_t baseusd,basekmd,usdkmd; int32_t baseid = komodo_baseid(base);
603 //if ( strcmp(rel,"KMD") != 0 || baseid < 0 || MINDENOMS[baseid] == MINDENOMS[USD] )
604 // return(_komodo_paxpriceB(seed,height,base,rel,basevolume));
605 //else
606 {
607 baseusd = _komodo_paxpriceB(seed,height,base,(char *)"USD",SATOSHIDEN);
608 usdkmd = _komodo_paxpriceB(seed,height,(char *)"USD",(char *)"KMD",SATOSHIDEN);
609 basekmd = (komodo_paxvol(basevolume,baseusd) * usdkmd) / 10000000;
610 if ( strcmp("KMD",base) == 0 )
611 printf("baseusd.%llu usdkmd.%llu %llu\n",(long long)baseusd,(long long)usdkmd,(long long)basekmd);
612 return(basekmd);
613 }
614}*/
615
eea23236 616uint64_t komodo_paxprice(uint64_t *seedp,int32_t height,char *base,char *rel,uint64_t basevolume)
617{
acd6ccf4 618 int32_t i,nonz=0; int64_t diff; uint64_t price,seed,sum = 0;
df96c294 619 if ( ASSETCHAINS_SYMBOL[0] == 0 && chainActive.Tip() != 0 && height > chainActive.Tip()->nHeight )
620 {
796bbf8a 621 if ( height < 100000000 )
e2ca75ae 622 printf("height.%d vs tip.%d\n",height,chainActive.Tip()->nHeight);
10854282 623 return(0);
df96c294 624 }
b9f308cf 625 *seedp = komodo_seed(height);
bba30a43 626 portable_mutex_lock(&komodo_mutex);
93139074 627 for (i=0; i<17; i++)
eea23236 628 {
b9f308cf 629 if ( (price= komodo_paxpriceB(*seedp,height-i,base,rel,basevolume)) != 0 )
eea23236 630 {
631 sum += price;
632 nonz++;
e2ca75ae 633 if ( 0 && i == 1 && nonz == 2 )
e8bd824b 634 {
395fae6b 635 diff = (((int64_t)price - (sum >> 1)) * 10000);
e8bd824b 636 if ( diff < 0 )
637 diff = -diff;
395fae6b 638 diff /= price;
6b9b9aca 639 printf("(%llu %llu %lld).%lld ",(long long)price,(long long)(sum>>1),(long long)(((int64_t)price - (sum >> 1)) * 10000),(long long)diff);
640 if ( diff < 33 )
e8bd824b 641 break;
e8bd824b 642 }
93139074 643 else if ( 0 && i == 3 && nonz == 4 )
e8bd824b 644 {
395fae6b 645 diff = (((int64_t)price - (sum >> 2)) * 10000);
e8bd824b 646 if ( diff < 0 )
647 diff = -diff;
395fae6b 648 diff /= price;
6b9b9aca 649 printf("(%llu %llu %lld).%lld ",(long long)price,(long long)(sum>>2),(long long) (((int64_t)price - (sum >> 2)) * 10000),(long long)diff);
650 if ( diff < 20 )
e8bd824b 651 break;
e2ca75ae 652 }
eea23236 653 }
ce3302c9 654 if ( height < 165000 || height > 236000 )
fa7d97db 655 break;
eea23236 656 }
bba30a43 657 portable_mutex_unlock(&komodo_mutex);
eea23236 658 if ( nonz != 0 )
659 sum /= nonz;
e2ca75ae 660 //printf("-> %lld %s/%s i.%d ht.%d\n",(long long)sum,base,rel,i,height);
eea23236 661 return(sum);
662}
663
d836ec3f 664int32_t komodo_paxprices(int32_t *heights,uint64_t *prices,int32_t max,char *base,char *rel)
a4ebaad7 665{
b20a5d7f 666 int32_t baseid=-1,relid=-1,i,num = 0; uint32_t *ptr;
a4ebaad7 667 if ( (baseid= komodo_baseid(base)) >= 0 && (relid= komodo_baseid(rel)) >= 0 )
668 {
669 for (i=NUM_PRICES-1; i>=0; i--)
670 {
671 ptr = &PVALS[36 * i];
56d91e9c 672 heights[num] = *ptr;
d5f0a866 673 prices[num] = komodo_paxcalc(*ptr,&ptr[1],baseid,relid,COIN,0,0);
56d91e9c 674 num++;
675 if ( num >= max )
676 return(num);
a4ebaad7 677 }
678 }
56d91e9c 679 return(num);
a4ebaad7 680}
681
cd1fcb48 682void komodo_paxpricefeed(int32_t height,uint8_t *pricefeed,int32_t opretlen)
47e5cbc1 683{
684 double KMDBTC,BTCUSD,CNYUSD; uint32_t numpvals,timestamp,pvals[128]; uint256 zero;
685 numpvals = dpow_readprices(pricefeed,&timestamp,&KMDBTC,&BTCUSD,&CNYUSD,pvals);
686 memset(&zero,0,sizeof(zero));
e155dbe9 687 komodo_stateupdate(height,0,0,0,zero,0,0,pvals,numpvals,0,0,0,0,0,0);
0765bc71 688 //printf("komodo_paxpricefeed vout OP_RETURN.%d prices numpvals.%d opretlen.%d\n",height,numpvals,opretlen);
47e5cbc1 689}
690
0bda6249 691uint64_t PAX_fiatdest(uint64_t *seedp,int32_t tokomodo,char *destaddr,uint8_t pubkey33[33],char *coinaddr,int32_t height,char *origbase,int64_t fiatoshis)
1e81ccb7 692{
fe965b1c 693 uint8_t shortflag = 0; char base[4]; int32_t i,baseid; uint8_t addrtype,rmd160[20]; int64_t komodoshis = 0;
df96c294 694 *seedp = komodo_seed(height);
7c6f8298 695 if ( (baseid= komodo_baseid(origbase)) < 0 || baseid == MAX_CURRENCIES )
c3fa7fad 696 {
106a1d04 697 if ( 0 && origbase[0] != 0 )
e4bef239 698 printf("[%s] PAX_fiatdest illegal base.(%s)\n",ASSETCHAINS_SYMBOL,origbase);
d019c447 699 return(0);
c3fa7fad 700 }
3ba8f923 701 for (i=0; i<3; i++)
702 base[i] = toupper(origbase[i]);
703 base[i] = 0;
30e79ca6 704 if ( fiatoshis < 0 )
705 shortflag = 1, fiatoshis = -fiatoshis;
0bda6249 706 komodoshis = komodo_paxprice(seedp,height,base,(char *)"KMD",(uint64_t)fiatoshis);
8b4d7f27 707 //printf("PAX_fiatdest ht.%d price %s %.8f -> KMD %.8f seed.%llx\n",height,base,(double)fiatoshis/COIN,(double)komodoshis/COIN,(long long)*seedp);
d019c447 708 if ( bitcoin_addr2rmd160(&addrtype,rmd160,coinaddr) == 20 )
1e81ccb7 709 {
7c6f8298 710 PAX_pubkey(1,pubkey33,&addrtype,rmd160,base,&shortflag,tokomodo != 0 ? &komodoshis : &fiatoshis);
d019c447 711 bitcoin_address(destaddr,KOMODO_PUBTYPE,pubkey33,33);
1e81ccb7 712 }
d019c447 713 return(komodoshis);
1e81ccb7 714}
This page took 0.360158 seconds and 4 git commands to generate.