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