]> Git Repo - VerusCoin.git/blame - src/komodo.h
test
[VerusCoin.git] / src / komodo.h
CommitLineData
fcd36118 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 ******************************************************************************/
15
16#ifndef H_KOMODO_H
17#define H_KOMODO_H
18
9499e4de 19#include <stdint.h>
20#include <stdio.h>
975b2ddb 21#include <pthread.h>
d2471545 22#include "uthash.h"
9499e4de 23
6ef202b2 24#include "komodo_interest.h"
25
9499e4de 26#define KOMODO_TESTNET_EXPIRATION 60000
732fdf87 27#define KOMODO_ELECTION_GAP 1000
926d837c 28#define KOMODO_PUBKEYS_HEIGHT(height) ((int32_t)(((((height)+KOMODO_ELECTION_GAP*.5)/KOMODO_ELECTION_GAP) + 1) * KOMODO_ELECTION_GAP))
9499e4de 29
24778ada 30int32_t IS_KOMODO_NOTARY,USE_EXTERNAL_PUBKEY,NOTARIZED_HEIGHT,Num_nutxos,KOMODO_NUMNOTARIES = 64;
9499e4de 31std::string NOTARY_PUBKEY;
32uint8_t NOTARY_PUBKEY33[33];
5203fc4b 33uint256 NOTARIZED_HASH,NOTARIZED_BTCTXID;
975b2ddb 34pthread_mutex_t komodo_mutex;
d2471545 35
732fdf87 36struct nutxo_entry { UT_hash_handle hh; uint256 txhash; uint64_t voutmask; int32_t notaryid,height; } *NUTXOS;
37struct knotary_entry { UT_hash_handle hh; uint8_t pubkey[33],notaryid; };
38struct knotaries_entry { int32_t height,numnotaries; struct knotary_entry *Notaries; } Pubkeys[10000];
5203fc4b 39struct notarized_checkpoint { uint256 notarized_hash,notarized_btctxid; int32_t nHeight,notarized_height; } *NPOINTS; int32_t NUM_NPOINTS;
9499e4de 40
5cea7725 41int32_t komodo_stateupdate(int32_t height,uint8_t notarypubs[][33],uint8_t numnotaries,uint8_t notaryid,uint256 txhash,uint64_t voutmask,uint8_t numvouts,uint32_t *pvals,uint8_t numpvals);
9499e4de 42// add opreturn funcid
43// pricefeeds
44
9499e4de 45#define CRYPTO777_PUBSECPSTR "020e46e79a2a8d12b9b5d12c7a91adb4e454edfae43c0a0cb805427d2ac7613fd9"
46
13023121 47const char *Notaries[][2] =
9499e4de 48{
49 { "jl777_testA", "03b7621b44118017a16043f19b30cc8a4cfe068ac4e42417bae16ba460c80f3828" },
50 { "jl777_testB", "02ebfc784a4ba768aad88d44d1045d240d47b26e248cafaf1c5169a42d7a61d344" },
51 { "pondsea_SH", "02209073bc0943451498de57f802650311b1f12aa6deffcd893da198a544c04f36" },
52 { "crackers_EU", "0340c66cf2c41c41efb420af57867baa765e8468c12aa996bfd816e1e07e410728" },
53 { "pondsea_EU", "0225aa6f6f19e543180b31153d9e6d55d41bc7ec2ba191fd29f19a2f973544e29d" },
54 { "locomb_EU", "025c6d26649b9d397e63323d96db42a9d3caad82e1d6076970efe5056c00c0779b" },
55 { "fullmoon_AE", "0204a908350b8142698fdb6fabefc97fe0e04f537adc7522ba7a1e8f3bec003d4a" },
56 { "movecrypto_EU", "021ab53bc6cf2c46b8a5456759f9d608966eff87384c2b52c0ac4cc8dd51e9cc42" },
57 { "badass_EU", "0209d48554768dd8dada988b98aca23405057ac4b5b46838a9378b95c3e79b9b9e" },
58 { "crackers_NA", "029e1c01131974f4cd3f564cc0c00eb87a0f9721043fbc1ca60f9bd0a1f73f64a1" },
59 { "proto_EU", "03681ffdf17c8f4f0008cefb7fa0779c5e888339cdf932f0974483787a4d6747c1" },
60 { "jeezy_EU", "023cb3e593fb85c5659688528e9a4f1c4c7f19206edc7e517d20f794ba686fd6d6" },
61 { "farl4web_EU", "035caa40684ace968677dca3f09098aa02b70e533da32390a7654c626e0cf908e1" },
62 { "nxtswe_EU", "032fb104e5eaa704a38a52c126af8f67e870d70f82977e5b2f093d5c1c21ae5899" },
63 { "traderbill_EU", "03196e8de3e2e5d872f31d79d6a859c8704a2198baf0af9c7b21e29656a7eb455f" },
64 { "vanbreuk_EU", "024f3cad7601d2399c131fd070e797d9cd8533868685ddbe515daa53c2e26004c3" },
65 { "titomane_EU", "03517fcac101fed480ae4f2caf775560065957930d8c1facc83e30077e45bdd199" },
66 { "supernet_AE", "029d93ef78197dc93892d2a30e5a54865f41e0ca3ab7eb8e3dcbc59c8756b6e355" },
67 { "supernet_EU", "02061c6278b91fd4ac5cab4401100ffa3b2d5a277e8f71db23401cc071b3665546" },
68 { "supernet_NA", "033c073366152b6b01535e15dd966a3a8039169584d06e27d92a69889b720d44e1" },
69 { "yassin_EU", "033fb7231bb66484081952890d9a03f91164fb27d392d9152ec41336b71b15fbd0" },
70 { "durerus_EU", "02bcbd287670bdca2c31e5d50130adb5dea1b53198f18abeec7211825f47485d57" },
71 { "badass_SH", "026b49dd3923b78a592c1b475f208e23698d3f085c4c3b4906a59faf659fd9530b" },
72 { "badass_NA", "02afa1a9f948e1634a29dc718d218e9d150c531cfa852843a1643a02184a63c1a7" },
73 { "pondsea_NA", "031bcfdbb62268e2ff8dfffeb9ddff7fe95fca46778c77eebff9c3829dfa1bb411" },
74 { "rnr_EU", "0287aa4b73988ba26cf6565d815786caf0d2c4af704d7883d163ee89cd9977edec" },
75 { "crackers_SH", "02313d72f9a16055737e14cfc528dcd5d0ef094cfce23d0348fe974b6b1a32e5f0" },
76 { "grewal_SH", "03212a73f5d38a675ee3cdc6e82542a96c38c3d1c79d25a1ed2e42fcf6a8be4e68" },
77 { "polycryptoblock_NA", "02708dcda7c45fb54b78469673c2587bfdd126e381654819c4c23df0e00b679622" },
78 { "titomane_NA", "0387046d9745414fb58a0fa3599078af5073e10347e4657ef7259a99cb4f10ad47" },
79 { "titomane_AE", "03cda6ca5c2d02db201488a54a548dbfc10533bdc275d5ea11928e8d6ab33c2185" },
80 { "kolo_EU", "03f5c08dadffa0ffcafb8dd7ffc38c22887bd02702a6c9ac3440deddcf2837692b" },
81 { "artik_NA", "0224e31f93eff0cc30eaf0b2389fbc591085c0e122c4d11862c1729d090106c842" },
82 { "eclips_EU", "0339369c1f5a2028d44be7be6f8ec3b907fdec814f87d2dead97cab4edb71a42e9" },
d383827f 83 { "titomane_SH", "035f49d7a308dd9a209e894321f010d21b7793461b0c89d6d9231a3fe5f68d9960" },
9499e4de 84};
85
2bd54af4 86static const uint32_t crc32_tab[] = {
87 0x00000000, 0x77073096, 0xee0e612c, 0x990951ba, 0x076dc419, 0x706af48f,
88 0xe963a535, 0x9e6495a3, 0x0edb8832, 0x79dcb8a4, 0xe0d5e91e, 0x97d2d988,
89 0x09b64c2b, 0x7eb17cbd, 0xe7b82d07, 0x90bf1d91, 0x1db71064, 0x6ab020f2,
90 0xf3b97148, 0x84be41de, 0x1adad47d, 0x6ddde4eb, 0xf4d4b551, 0x83d385c7,
91 0x136c9856, 0x646ba8c0, 0xfd62f97a, 0x8a65c9ec, 0x14015c4f, 0x63066cd9,
92 0xfa0f3d63, 0x8d080df5, 0x3b6e20c8, 0x4c69105e, 0xd56041e4, 0xa2677172,
93 0x3c03e4d1, 0x4b04d447, 0xd20d85fd, 0xa50ab56b, 0x35b5a8fa, 0x42b2986c,
94 0xdbbbc9d6, 0xacbcf940, 0x32d86ce3, 0x45df5c75, 0xdcd60dcf, 0xabd13d59,
95 0x26d930ac, 0x51de003a, 0xc8d75180, 0xbfd06116, 0x21b4f4b5, 0x56b3c423,
96 0xcfba9599, 0xb8bda50f, 0x2802b89e, 0x5f058808, 0xc60cd9b2, 0xb10be924,
97 0x2f6f7c87, 0x58684c11, 0xc1611dab, 0xb6662d3d, 0x76dc4190, 0x01db7106,
98 0x98d220bc, 0xefd5102a, 0x71b18589, 0x06b6b51f, 0x9fbfe4a5, 0xe8b8d433,
99 0x7807c9a2, 0x0f00f934, 0x9609a88e, 0xe10e9818, 0x7f6a0dbb, 0x086d3d2d,
100 0x91646c97, 0xe6635c01, 0x6b6b51f4, 0x1c6c6162, 0x856530d8, 0xf262004e,
101 0x6c0695ed, 0x1b01a57b, 0x8208f4c1, 0xf50fc457, 0x65b0d9c6, 0x12b7e950,
102 0x8bbeb8ea, 0xfcb9887c, 0x62dd1ddf, 0x15da2d49, 0x8cd37cf3, 0xfbd44c65,
103 0x4db26158, 0x3ab551ce, 0xa3bc0074, 0xd4bb30e2, 0x4adfa541, 0x3dd895d7,
104 0xa4d1c46d, 0xd3d6f4fb, 0x4369e96a, 0x346ed9fc, 0xad678846, 0xda60b8d0,
105 0x44042d73, 0x33031de5, 0xaa0a4c5f, 0xdd0d7cc9, 0x5005713c, 0x270241aa,
106 0xbe0b1010, 0xc90c2086, 0x5768b525, 0x206f85b3, 0xb966d409, 0xce61e49f,
107 0x5edef90e, 0x29d9c998, 0xb0d09822, 0xc7d7a8b4, 0x59b33d17, 0x2eb40d81,
108 0xb7bd5c3b, 0xc0ba6cad, 0xedb88320, 0x9abfb3b6, 0x03b6e20c, 0x74b1d29a,
109 0xead54739, 0x9dd277af, 0x04db2615, 0x73dc1683, 0xe3630b12, 0x94643b84,
110 0x0d6d6a3e, 0x7a6a5aa8, 0xe40ecf0b, 0x9309ff9d, 0x0a00ae27, 0x7d079eb1,
111 0xf00f9344, 0x8708a3d2, 0x1e01f268, 0x6906c2fe, 0xf762575d, 0x806567cb,
112 0x196c3671, 0x6e6b06e7, 0xfed41b76, 0x89d32be0, 0x10da7a5a, 0x67dd4acc,
113 0xf9b9df6f, 0x8ebeeff9, 0x17b7be43, 0x60b08ed5, 0xd6d6a3e8, 0xa1d1937e,
114 0x38d8c2c4, 0x4fdff252, 0xd1bb67f1, 0xa6bc5767, 0x3fb506dd, 0x48b2364b,
115 0xd80d2bda, 0xaf0a1b4c, 0x36034af6, 0x41047a60, 0xdf60efc3, 0xa867df55,
116 0x316e8eef, 0x4669be79, 0xcb61b38c, 0xbc66831a, 0x256fd2a0, 0x5268e236,
117 0xcc0c7795, 0xbb0b4703, 0x220216b9, 0x5505262f, 0xc5ba3bbe, 0xb2bd0b28,
118 0x2bb45a92, 0x5cb36a04, 0xc2d7ffa7, 0xb5d0cf31, 0x2cd99e8b, 0x5bdeae1d,
119 0x9b64c2b0, 0xec63f226, 0x756aa39c, 0x026d930a, 0x9c0906a9, 0xeb0e363f,
120 0x72076785, 0x05005713, 0x95bf4a82, 0xe2b87a14, 0x7bb12bae, 0x0cb61b38,
121 0x92d28e9b, 0xe5d5be0d, 0x7cdcefb7, 0x0bdbdf21, 0x86d3d2d4, 0xf1d4e242,
122 0x68ddb3f8, 0x1fda836e, 0x81be16cd, 0xf6b9265b, 0x6fb077e1, 0x18b74777,
123 0x88085ae6, 0xff0f6a70, 0x66063bca, 0x11010b5c, 0x8f659eff, 0xf862ae69,
124 0x616bffd3, 0x166ccf45, 0xa00ae278, 0xd70dd2ee, 0x4e048354, 0x3903b3c2,
125 0xa7672661, 0xd06016f7, 0x4969474d, 0x3e6e77db, 0xaed16a4a, 0xd9d65adc,
126 0x40df0b66, 0x37d83bf0, 0xa9bcae53, 0xdebb9ec5, 0x47b2cf7f, 0x30b5ffe9,
127 0xbdbdf21c, 0xcabac28a, 0x53b39330, 0x24b4a3a6, 0xbad03605, 0xcdd70693,
128 0x54de5729, 0x23d967bf, 0xb3667a2e, 0xc4614ab8, 0x5d681b02, 0x2a6f2b94,
129 0xb40bbe37, 0xc30c8ea1, 0x5a05df1b, 0x2d02ef8d
130};
131
132uint32_t calc_crc32(uint32_t crc,const void *buf,size_t size)
133{
134 const uint8_t *p;
135
136 p = (const uint8_t *)buf;
137 crc = crc ^ ~0U;
138
139 while (size--)
140 crc = crc32_tab[(crc ^ *p++) & 0xFF] ^ (crc >> 8);
141
142 return crc ^ ~0U;
143}
5203fc4b 144
01cc012f 145int32_t iguana_rwnum(int32_t rwflag,uint8_t *serialized,int32_t len,void *endianedp)
146{
147 int32_t i; uint64_t x;
148 if ( rwflag == 0 )
149 {
150 x = 0;
151 for (i=len-1; i>=0; i--)
152 {
153 x <<= 8;
154 x |= serialized[i];
155 }
156 switch ( len )
157 {
158 case 1: *(uint8_t *)endianedp = (uint8_t)x; break;
159 case 2: *(uint16_t *)endianedp = (uint16_t)x; break;
160 case 4: *(uint32_t *)endianedp = (uint32_t)x; break;
161 case 8: *(uint64_t *)endianedp = (uint64_t)x; break;
162 }
163 }
164 else
165 {
166 x = 0;
167 switch ( len )
168 {
169 case 1: x = *(uint8_t *)endianedp; break;
170 case 2: x = *(uint16_t *)endianedp; break;
171 case 4: x = *(uint32_t *)endianedp; break;
172 case 8: x = *(uint64_t *)endianedp; break;
173 }
174 for (i=0; i<len; i++,x >>= 8)
175 serialized[i] = (uint8_t)(x & 0xff);
176 }
177 return(len);
178}
179
180int32_t iguana_rwbignum(int32_t rwflag,uint8_t *serialized,int32_t len,uint8_t *endianedp)
181{
182 int32_t i;
183 if ( rwflag == 0 )
184 {
185 for (i=0; i<len; i++)
53b58ced 186 endianedp[i] = serialized[i];
01cc012f 187 }
188 else
189 {
190 for (i=0; i<len; i++)
53b58ced 191 serialized[i] = endianedp[i];
01cc012f 192 }
193 return(len);
194}
195
65d466d3 196int32_t dpow_readprices(uint8_t *data,uint32_t *timestampp,double *KMDBTCp,double *BTCUSDp,double *CNYUSDp,uint32_t *pvals)
197{
198 uint32_t kmdbtc,btcusd,cnyusd; int32_t i,n,len = 0;
9d68c1e7 199 len += iguana_rwnum(0,&data[len],sizeof(uint32_t),(void *)timestampp);
65d466d3 200 len += iguana_rwnum(0,&data[len],sizeof(uint32_t),(void *)&n);
201 len += iguana_rwnum(0,&data[len],sizeof(uint32_t),(void *)&kmdbtc); // /= 1000
202 len += iguana_rwnum(0,&data[len],sizeof(uint32_t),(void *)&btcusd); // *= 1000
203 len += iguana_rwnum(0,&data[len],sizeof(uint32_t),(void *)&cnyusd);
204 *KMDBTCp = ((double)kmdbtc / (1000000000. * 1000.));
205 *BTCUSDp = ((double)btcusd / (1000000000. / 1000.));
206 *CNYUSDp = ((double)cnyusd / 1000000000.);
207 for (i=0; i<n-3; i++)
208 {
209 len += iguana_rwnum(0,&data[len],sizeof(uint32_t),(void *)&pvals[i]);
5cea7725 210 //printf("%u ",pvals[i]);
65d466d3 211 }
5cea7725 212 pvals[i++] = kmdbtc;
213 pvals[i++] = btcusd;
214 pvals[i++] = cnyusd;
215 //printf("OP_RETURN prices\n");
9d68c1e7 216 return(n-3);
65d466d3 217}
218
01cc012f 219int32_t _unhex(char c)
220{
221 if ( c >= '0' && c <= '9' )
222 return(c - '0');
223 else if ( c >= 'a' && c <= 'f' )
224 return(c - 'a' + 10);
225 else if ( c >= 'A' && c <= 'F' )
226 return(c - 'A' + 10);
227 return(-1);
228}
229
230int32_t is_hexstr(char *str,int32_t n)
231{
232 int32_t i;
233 if ( str == 0 || str[0] == 0 )
234 return(0);
235 for (i=0; str[i]!=0; i++)
236 {
237 if ( n > 0 && i >= n )
238 break;
239 if ( _unhex(str[i]) < 0 )
240 break;
241 }
242 if ( n == 0 )
243 return(i);
244 return(i == n);
245}
246
247int32_t unhex(char c)
248{
249 int32_t hex;
250 if ( (hex= _unhex(c)) < 0 )
251 {
252 //printf("unhex: illegal hexchar.(%c)\n",c);
253 }
254 return(hex);
255}
256
257unsigned char _decode_hex(char *hex) { return((unhex(hex[0])<<4) | unhex(hex[1])); }
258
259int32_t decode_hex(uint8_t *bytes,int32_t n,char *hex)
260{
261 int32_t adjust,i = 0;
262 //printf("decode.(%s)\n",hex);
263 if ( is_hexstr(hex,n) == 0 )
264 {
265 memset(bytes,0,n);
266 return(n);
267 }
268 if ( n == 0 || (hex[n*2+1] == 0 && hex[n*2] != 0) )
269 {
270 if ( n > 0 )
271 {
272 bytes[0] = unhex(hex[0]);
273 printf("decode_hex n.%d hex[0] (%c) -> %d hex.(%s) [n*2+1: %d] [n*2: %d %c] len.%ld\n",n,hex[0],bytes[0],hex,hex[n*2+1],hex[n*2],hex[n*2],(long)strlen(hex));
274 }
275 bytes++;
276 hex++;
277 adjust = 1;
278 } else adjust = 0;
279 if ( n > 0 )
280 {
281 for (i=0; i<n; i++)
282 bytes[i] = _decode_hex(&hex[i*2]);
283 }
284 //bytes[i] = 0;
285 return(n + adjust);
286}
287
bbe9aa6f 288int32_t komodo_threshold(int32_t height,uint64_t signedmask)
289{
290 int32_t numnotaries,i,wt = 0;
291 numnotaries = Pubkeys[height / KOMODO_ELECTION_GAP].numnotaries;
292 for (i=0; i<numnotaries; i++)
293 if ( ((1LL << i) & signedmask) != 0 )
294 wt++;
b927fb35 295 if ( wt > (numnotaries >> 1) || (wt > 7 && (signedmask & 3) != 0) )
bbe9aa6f 296 return(1); // N/2+1 || N/3 + devsig
297 else return(0);
298}
299
b927fb35 300uint32_t komodo_txtime(uint256 hash)
301{
302 CTransaction tx;
303 uint256 hashBlock;
304 if (!GetTransaction(hash, tx, hashBlock, true))
305 {
306 //printf("null GetTransaction\n");
307 return(tx.nLockTime);
308 }
b927fb35 309 return(0);
310}
311
732fdf87 312void komodo_nutxoadd(int32_t addflag,int32_t height,int32_t notaryid,uint256 txhash,uint64_t voutmask,int32_t numvouts)
313{
314 struct nutxo_entry *np;
315 if ( numvouts > 1 && notaryid < 64 ) // change to ADD_HASH() and file based
316 {
975b2ddb 317 pthread_mutex_lock(&komodo_mutex);
732fdf87 318 np = (struct nutxo_entry *)calloc(1,sizeof(*np));
319 np->height = height;
320 np->txhash = txhash;
321 np->voutmask = voutmask;
322 np->notaryid = notaryid;
323 HASH_ADD_KEYPTR(hh,NUTXOS,&np->txhash,sizeof(np->txhash),np);
dcb546ff 324 printf("Add NUTXO[%d] <- %s notaryid.%d t%u %s %llx\n",Num_nutxos,Notaries[notaryid][0],notaryid,komodo_txtime(txhash),txhash.ToString().c_str(),(long long)voutmask);
732fdf87 325 if ( addflag != 0 )
5cea7725 326 komodo_stateupdate(height,0,0,notaryid,txhash,voutmask,numvouts,0,0);
732fdf87 327 Num_nutxos++;
975b2ddb 328 pthread_mutex_unlock(&komodo_mutex);
732fdf87 329 }
330}
331
332int32_t komodo_nutxofind(int32_t height,uint256 txhash,int32_t vout) // change to HASH_FIND()
333{
334 struct nutxo_entry *np;
975b2ddb 335 pthread_mutex_lock(&komodo_mutex);
732fdf87 336 HASH_FIND(hh,NUTXOS,&txhash,sizeof(txhash),np);
975b2ddb 337 pthread_mutex_unlock(&komodo_mutex);
732fdf87 338 if ( np != 0 && ((1LL << vout) & np->voutmask) != 0 )
339 return(np->notaryid);
340 return(-1);
341}
342
343void komodo_notarysinit(int32_t height,uint8_t pubkeys[64][33],int32_t num)
344{
345 int32_t k,i,htind; struct knotary_entry *kp; struct knotaries_entry N;
346 memset(&N,0,sizeof(N));
975b2ddb 347 pthread_mutex_lock(&komodo_mutex);
732fdf87 348 for (k=0; k<num; k++)
349 {
926d837c 350 kp = (struct knotary_entry *)calloc(1,sizeof(*kp));
732fdf87 351 memcpy(kp->pubkey,pubkeys[k],33);
352 kp->notaryid = k;
353 HASH_ADD_KEYPTR(hh,N.Notaries,kp->pubkey,33,kp);
354 for (i=0; i<33; i++)
355 printf("%02x",pubkeys[k][i]);
356 printf(" notarypubs.[%d]\n",k);
357 }
358 N.numnotaries = num;
359 htind = KOMODO_PUBKEYS_HEIGHT(height) / KOMODO_ELECTION_GAP;
360 if ( htind == 1 )
361 htind = 0;
362 for (i=htind; i<sizeof(Pubkeys)/sizeof(*Pubkeys); i++)
363 {
364 Pubkeys[i] = N;
365 Pubkeys[i].height = i * KOMODO_ELECTION_GAP;
366 }
975b2ddb 367 pthread_mutex_unlock(&komodo_mutex);
732fdf87 368}
369
a5f315c7 370int32_t komodo_chosennotary(int32_t *notaryidp,int32_t height,uint8_t *pubkey33)
732fdf87 371{
372 // -1 if not notary, 0 if notary, 1 if special notary
dae9e3bb 373 struct knotary_entry *kp; int32_t numnotaries,modval = -1;
374 *notaryidp = -1;
975b2ddb 375 pthread_mutex_lock(&komodo_mutex);
732fdf87 376 HASH_FIND(hh,Pubkeys[height/KOMODO_ELECTION_GAP].Notaries,pubkey33,33,kp);
975b2ddb 377 pthread_mutex_unlock(&komodo_mutex);
732fdf87 378 if ( kp != 0 )
379 {
380 if ( (numnotaries= Pubkeys[height/KOMODO_ELECTION_GAP].numnotaries) > 0 )
381 {
dae9e3bb 382 *notaryidp = kp->notaryid;
732fdf87 383 modval = ((height % numnotaries) == kp->notaryid);
0ed83449 384 //printf("found notary.%d ht.%d modval.%d\n",kp->notaryid,height,modval);
732fdf87 385 } else printf("unexpected zero notaries at height.%d\n",height);
386 }
bbe9aa6f 387 //int32_t i; for (i=0; i<33; i++)
388 // printf("%02x",pubkey33[i]);
389 //printf(" ht.%d notary.%d special.%d\n",height,*notaryidp,modval);
732fdf87 390 return(modval);
391}
6f3bcbea 392
5203fc4b 393void komodo_notarized_update(int32_t nHeight,int32_t notarized_height,uint256 notarized_hash,uint256 notarized_btctxid)
394{
395 struct notarized_checkpoint *np;
f856c809 396 NPOINTS = (struct notarized_checkpoint *)realloc(NPOINTS,(NUM_NPOINTS+1) * sizeof(*NPOINTS));
5203fc4b 397 np = &NPOINTS[NUM_NPOINTS++];
398 memset(np,0,sizeof(*np));
399 np->nHeight = nHeight;
400 np->notarized_height = notarized_height;
401 np->notarized_hash = notarized_hash;
402 np->notarized_btctxid = notarized_btctxid;
403}
404
405int32_t komodo_notarizeddata(int32_t nHeight,uint256 *notarized_hashp,uint256 *notarized_btctxidp)
de36931b 406{
5203fc4b 407 struct notarized_checkpoint *np = 0; int32_t i;
408 if ( NUM_NPOINTS > 0 )
409 {
410 for (i=0; i<NUM_NPOINTS; i++)
411 {
412 if ( NPOINTS[i].nHeight >= nHeight )
413 break;
414 np = &NPOINTS[i];
415 }
416 }
417 if ( np != 0 )
418 {
419 *notarized_hashp = np->notarized_hash;
420 *notarized_btctxidp = np->notarized_btctxid;
421 return(np->notarized_height);
422 }
de36931b 423 memset(notarized_hashp,0,sizeof(*notarized_hashp));
424 return(-1);
425}
426
5cea7725 427void komodo_pvals(int32_t height,uint32_t *pvals,uint8_t numpvals)
bafc61f3 428{
5cea7725 429 int32_t i; double KMDBTC,BTCUSD,CNYUSD; uint32_t kmdbtc,btcusd,cnyusd;
430 if ( numpvals >= 35 )
431 {
432 for (i=0; i<32; i++)
433 printf("%u ",pvals[i]);
434 kmdbtc = pvals[i++];
435 btcusd = pvals[i++];
436 cnyusd = pvals[i++];
437 KMDBTC = ((double)kmdbtc / (1000000000. * 1000.));
438 BTCUSD = ((double)btcusd / (1000000000. / 1000.));
439 CNYUSD = ((double)cnyusd / 1000000000.);
440 printf("OP_RETURN.%d KMD %.8f BTC %.6f CNY %.6f\n",height,KMDBTC,BTCUSD,CNYUSD);
441 }
442}
443
444int32_t komodo_stateupdate(int32_t height,uint8_t notarypubs[][33],uint8_t numnotaries,uint8_t notaryid,uint256 txhash,uint64_t voutmask,uint8_t numvouts,uint32_t *pvals,uint8_t numpvals)
445{
446 static FILE *fp; static int32_t errs,didinit; char fname[512]; int32_t ht,k,i,func; uint8_t data[2048],num,pubkeys[64][33];
e402ebee 447#ifdef WIN32
448 sprintf(fname,"%s\\%s",GetDataDir(false).string().c_str(),(char *)"komodostate");
449#else
073594aa 450 sprintf(fname,"%s/%s",GetDataDir(false).string().c_str(),(char *)"komodostate");
e402ebee 451#endif
bafc61f3 452 if ( fp == 0 )
453 {
454 if ( (fp= fopen(fname,"rb+")) != 0 )
455 {
456 while ( (func= fgetc(fp)) != EOF )
457 {
c50ec0fb 458 if ( fread(&ht,1,sizeof(ht),fp) != sizeof(ht) )
459 errs++;
5203fc4b 460 //printf("func.(%d %c) ht.%d\n",func,func,ht);
bafc61f3 461 if ( func == 'P' )
462 {
463 if ( (num= fgetc(fp)) < 64 )
dd7b22ad 464 {
52ed4002 465 if ( fread(pubkeys,33,num,fp) != num )
466 errs++;
732fdf87 467 else
468 {
5203fc4b 469 printf("updated %d pubkeys at ht.%d\n",num,ht);
470 komodo_notarysinit(ht,pubkeys,num);
732fdf87 471 }
472 } else printf("illegal num.%d\n",num);
9997caa0 473 //printf("P[%d]\n",num);
bafc61f3 474 }
475 else if ( func == 'N' )
476 {
52ed4002 477 if ( fread(&NOTARIZED_HEIGHT,1,sizeof(NOTARIZED_HEIGHT),fp) != sizeof(NOTARIZED_HEIGHT) )
478 errs++;
479 if ( fread(&NOTARIZED_HASH,1,sizeof(NOTARIZED_HASH),fp) != sizeof(NOTARIZED_HASH) )
480 errs++;
5203fc4b 481 if ( fread(&NOTARIZED_BTCTXID,1,sizeof(NOTARIZED_BTCTXID),fp) != sizeof(NOTARIZED_BTCTXID) )
52ed4002 482 errs++;
81bac2f0 483 printf("load NOTARIZED %d %s\n",NOTARIZED_HEIGHT,NOTARIZED_HASH.ToString().c_str());
5203fc4b 484 komodo_notarized_update(ht,NOTARIZED_HEIGHT,NOTARIZED_HASH,NOTARIZED_BTCTXID);
bafc61f3 485 }
671187dd 486 else if ( func == 'U' )
487 {
488 uint8_t n,nid; uint256 hash; uint64_t mask;
489 n = fgetc(fp);
490 nid = fgetc(fp);
9997caa0 491 //printf("U %d %d\n",n,nid);
671187dd 492 if ( fread(&mask,1,sizeof(mask),fp) != sizeof(mask) )
493 errs++;
494 if ( fread(&hash,1,sizeof(hash),fp) != sizeof(hash) )
495 errs++;
5203fc4b 496 komodo_nutxoadd(0,ht,nid,hash,mask,n);
4355e769 497 }
498 else if ( func == 'D' )
499 {
9997caa0 500 //printf("D[%d]\n",ht);
671187dd 501 }
5cea7725 502 else if ( func == 'V' )
503 {
504 int32_t numpvals; uint32_t pvals[128];
505 numpvals = fgetc(fp);
506 if ( numpvals*sizeof(uint32_t) <= sizeof(data) && fread(pvals,sizeof(uint32_t),numpvals,fp) == numpvals )
507 {
508 komodo_pvals(ht,pvals,numpvals);
509 printf("load pvals\n");
510 }
511 }
bafc61f3 512 else printf("illegal func.(%d %c)\n",func,func);
513 }
514 } else fp = fopen(fname,"wb+");
515 printf("fname.(%s) fpos.%ld\n",fname,ftell(fp));
516 }
517 if ( fp != 0 )
518 {
4355e769 519 if ( height < 0 )
520 {
9997caa0 521 height = -height;
522 //printf("func D[%d] errs.%d\n",height,errs);
4355e769 523 fputc('D',fp);
524 if ( fwrite(&height,1,sizeof(height),fp) != sizeof(height) )
525 errs++;
526 }
9997caa0 527 else if ( notarypubs != 0 && numnotaries > 0 )
bafc61f3 528 {
9997caa0 529 //printf("func P[%d] errs.%d\n",numnotaries,errs);
bafc61f3 530 fputc('P',fp);
c50ec0fb 531 if ( fwrite(&height,1,sizeof(height),fp) != sizeof(height) )
532 errs++;
bafc61f3 533 fputc(numnotaries,fp);
52ed4002 534 if ( fwrite(notarypubs,33,numnotaries,fp) != numnotaries )
535 errs++;
bafc61f3 536 }
671187dd 537 else if ( voutmask != 0 && numvouts > 0 )
538 {
9997caa0 539 //printf("func U %d %d errs.%d hashsize.%ld\n",numvouts,notaryid,errs,sizeof(txhash));
671187dd 540 fputc('U',fp);
c50ec0fb 541 if ( fwrite(&height,1,sizeof(height),fp) != sizeof(height) )
542 errs++;
671187dd 543 fputc(numvouts,fp);
544 fputc(notaryid,fp);
545 if ( fwrite(&voutmask,1,sizeof(voutmask),fp) != sizeof(voutmask) )
546 errs++;
547 if ( fwrite(&txhash,1,sizeof(txhash),fp) != sizeof(txhash) )
548 errs++;
549 }
6dabcca4 550 else if ( height != 0 )
671187dd 551 {
9997caa0 552 //printf("func N ht.%d errs.%d\n",NOTARIZED_HEIGHT,errs);
671187dd 553 fputc('N',fp);
c50ec0fb 554 if ( fwrite(&height,1,sizeof(height),fp) != sizeof(height) )
555 errs++;
671187dd 556 if ( fwrite(&NOTARIZED_HEIGHT,1,sizeof(NOTARIZED_HEIGHT),fp) != sizeof(NOTARIZED_HEIGHT) )
557 errs++;
558 if ( fwrite(&NOTARIZED_HASH,1,sizeof(NOTARIZED_HASH),fp) != sizeof(NOTARIZED_HASH) )
559 errs++;
5203fc4b 560 if ( fwrite(&NOTARIZED_BTCTXID,1,sizeof(NOTARIZED_BTCTXID),fp) != sizeof(NOTARIZED_BTCTXID) )
671187dd 561 errs++;
5203fc4b 562 komodo_notarized_update(height,NOTARIZED_HEIGHT,NOTARIZED_HASH,NOTARIZED_BTCTXID);
671187dd 563 }
5cea7725 564 else if ( pvals != 0 && numpvals > 0 )
565 {
566 fputc('V',fp);
567 if ( fwrite(&height,1,sizeof(height),fp) != sizeof(height) )
568 errs++;
569 fputc(numpvals,fp);
570 if ( fwrite(pvals,sizeof(uint32_t),numpvals,fp) != numpvals )
571 errs++;
572 komodo_pvals(height,pvals,numpvals);
573 printf("save pvals\n");
574 }
47f47733 575 fflush(fp);
bafc61f3 576 }
577}
578
77117dbe 579void komodo_init()
580{
581 static int didinit; uint256 zero; int32_t k; uint8_t pubkeys[64][33];
582 if ( didinit == 0 )
583 {
584 didinit = 1;
585 pthread_mutex_init(&komodo_mutex,NULL);
586 decode_hex(NOTARY_PUBKEY33,33,(char *)NOTARY_PUBKEY.c_str());
587 KOMODO_NUMNOTARIES = (int32_t)(sizeof(Notaries)/sizeof(*Notaries));
588 for (k=0; k<KOMODO_NUMNOTARIES; k++)
589 {
590 if ( Notaries[k][0] == 0 || Notaries[k][1] == 0 || Notaries[k][0][0] == 0 || Notaries[k][1][0] == 0 )
591 break;
592 decode_hex(pubkeys[k],33,(char *)Notaries[k][1]);
593 }
594 komodo_notarysinit(0,pubkeys,KOMODO_NUMNOTARIES);
595 memset(&zero,0,sizeof(zero));
5cea7725 596 komodo_stateupdate(0,0,0,0,zero,0,0,0,0);
77117dbe 597 }
598}
599
1390456b 600int32_t komodo_voutupdate(int32_t notaryid,uint8_t *scriptbuf,int32_t scriptlen,int32_t height,uint256 txhash,int32_t i,int32_t j,uint64_t *voutmaskp,int32_t *specialtxp,int32_t *notarizedheightp)
601{
5cea7725 602 static uint256 zero; int32_t k,opretlen,nid,len = 0; uint256 kmdtxid,btctxid; uint8_t crypto777[33];
9c406099 603 if ( scriptlen == 35 && scriptbuf[0] == 33 && scriptbuf[34] == 0xac )
1390456b 604 {
c23dd601 605 decode_hex(crypto777,33,(char *)CRYPTO777_PUBSECPSTR);
986d3459 606 /*for (k=0; k<33; k++)
e1be360e 607 printf("%02x",crypto777[k]);
608 printf(" crypto777 ");
609 for (k=0; k<scriptlen; k++)
610 printf("%02x",scriptbuf[k]);
986d3459 611 printf(" <- script ht.%d i.%d j.%d cmp.%d\n",height,i,j,memcmp(crypto777,scriptbuf+1,33));*/
1390456b 612 if ( memcmp(crypto777,scriptbuf+1,33) == 0 )
613 {
614 *specialtxp = 1;
615 printf(">>>>>>>> ");
616 }
a5f315c7 617 else if ( komodo_chosennotary(&nid,height,scriptbuf + 1) >= 0 )
1390456b 618 {
84e843cd 619 //printf("found notary.k%d\n",k);
620 if ( notaryid < 64 )
1390456b 621 {
84e843cd 622 if ( notaryid < 0 )
623 {
a5f315c7 624 notaryid = nid;
84e843cd 625 *voutmaskp |= (1LL << j);
626 }
a5f315c7 627 else if ( notaryid != nid )
84e843cd 628 {
a5f315c7 629 printf("mismatch notaryid.%d k.%d\n",notaryid,nid);
84e843cd 630 notaryid = 64;
631 *voutmaskp = 0;
632 }
633 else *voutmaskp |= (1LL << j);
1390456b 634 }
1390456b 635 }
636 }
637 if ( j == 1 && scriptbuf[len++] == 0x6a )
638 {
639 if ( (opretlen= scriptbuf[len++]) == 0x4c )
640 opretlen = scriptbuf[len++];
641 else if ( opretlen == 0x4d )
642 {
643 opretlen = scriptbuf[len++];
644 opretlen = (opretlen << 8) + scriptbuf[len++];
645 }
646 if ( opretlen >= 32*2+4 )
647 {
6a1edfa2 648 if ( strcmp("KMD",(char *)&scriptbuf[len+32*2+4]) == 0 )
1390456b 649 {
6a1edfa2 650 len += iguana_rwbignum(0,&scriptbuf[len],32,(uint8_t *)&kmdtxid);
651 len += iguana_rwnum(0,&scriptbuf[len],4,(uint8_t *)notarizedheightp);
652 len += iguana_rwbignum(0,&scriptbuf[len],32,(uint8_t *)&btctxid);
653 //for (k=0; k<scriptlen; k++)
654 // printf("%02x",scriptbuf[k]);
655 //printf(" <- script ht.%d i.%d j.%d\n",height,i,j);
656 printf("ht.%d NOTARIZED.%d KMD.%s BTCTXID.%s (%s)\n",height,*notarizedheightp,kmdtxid.ToString().c_str(),btctxid.ToString().c_str(),(char *)&scriptbuf[len+32*2+4]);
657 if ( *notarizedheightp > NOTARIZED_HEIGHT )
658 {
6a1edfa2 659 NOTARIZED_HEIGHT = *notarizedheightp;
660 NOTARIZED_HASH = kmdtxid;
661 NOTARIZED_BTCTXID = btctxid;
5cea7725 662 komodo_stateupdate(height,0,0,0,zero,0,0,0,0);
6a1edfa2 663 }
664 }
665 else if ( i == 0 && scriptbuf[len] == 'P' )
666 {
5cea7725 667 double KMDBTC,BTCUSD,CNYUSD; uint32_t numpvals,timestamp,pvals[128];
668 numpvals = dpow_readprices(&scriptbuf[++len],&timestamp,&KMDBTC,&BTCUSD,&CNYUSD,pvals);
669 komodo_stateupdate(height,0,0,0,zero,0,0,pvals,numpvals);
b5252cb5 670 printf("vout OP_RETURN.%d prices numpvals.%d opretlen.%d\n",height,numpvals,opretlen);
1390456b 671 }
672 }
673 }
674 return(notaryid);
675}
676
651989c7 677void komodo_connectblock(CBlockIndex *pindex,CBlock& block)
50027f06 678{
bafc61f3 679 static int32_t didinit;
acb3f1d8 680 char *scriptstr,*opreturnstr; uint64_t signedmask,voutmask;
dd7b22ad 681 uint8_t scriptbuf[4096],pubkeys[64][33]; uint256 kmdtxid,btctxid,txhash;
29e69b85 682 int32_t i,j,k,numvalid,specialtx,notarizedheight,notaryid,len,numvouts,numvins,height,txn_count,flag;
77117dbe 683 komodo_init();
68916cc6 684 if ( pindex != 0 )
b501ded2 685 {
656eddcd 686 height = pindex->nHeight;
01cc012f 687 txn_count = block.vtx.size();
688 for (i=0; i<txn_count; i++)
dc64de68 689 {
352f8081 690 txhash = block.vtx[i].GetHash();
01cc012f 691 numvouts = block.vtx[i].vout.size();
352f8081 692 notaryid = -1;
1390456b 693 voutmask = specialtx = notarizedheight = 0;
01cc012f 694 for (j=0; j<numvouts; j++)
dc64de68 695 {
1390456b 696 len = block.vtx[i].vout[j].scriptPubKey.size();
697 if ( len <= sizeof(scriptbuf) )
01cc012f 698 {
1390456b 699 memcpy(scriptbuf,block.vtx[i].vout[j].scriptPubKey.data(),len);
acb3f1d8 700 notaryid = komodo_voutupdate(notaryid,scriptbuf,len,height,txhash,i,j,&voutmask,&specialtx,&notarizedheight);
a01acef4 701 if ( 0 && i > 0 )
e69a0833 702 {
703 for (k=0; k<len; k++)
704 printf("%02x",scriptbuf[k]);
a8832194 705 printf(" <- notaryid.%d ht.%d i.%d j.%d numvouts.%d numvins.%d voutmask.%llx txid.(%s)\n",notaryid,height,i,j,numvouts,numvins,(long long)voutmask,txhash.ToString().c_str());
e69a0833 706 }
01cc012f 707 }
352f8081 708 }
a5f315c7 709 if ( notaryid >= 0 && notaryid < 64 && voutmask != 0 )
97cfbf8b 710 komodo_nutxoadd(1,height,notaryid,txhash,voutmask,numvouts);
1390456b 711 signedmask = 0;
712 numvins = block.vtx[i].vin.size();
5bdebffe 713 for (j=0; j<numvins; j++)
352f8081 714 {
4355e769 715 if ( (k= komodo_nutxofind(height,block.vtx[i].vin[j].prevout.hash,block.vtx[i].vin[j].prevout.n)) >= 0 )
1390456b 716 signedmask |= (1LL << k);
21cc1d3e 717 else if ( 0 && signedmask != 0 )
bc6fd011 718 printf("signedmask.%llx but ht.%d i.%d j.%d not found (%s %d)\n",(long long)signedmask,height,i,j,block.vtx[i].vin[j].prevout.hash.ToString().c_str(),block.vtx[i].vin[j].prevout.n);
1390456b 719 }
06f0ed43 720 if ( signedmask != 0 && (notarizedheight != 0 || specialtx != 0) )
1390456b 721 {
e69a0833 722 printf("NOTARY SIGNED.%llx numvins.%d ht.%d txi.%d notaryht.%d specialtx.%d\n",(long long)signedmask,numvins,height,i,notarizedheight,specialtx);
732fdf87 723 if ( specialtx != 0 && numvouts > 2 && komodo_threshold(height,signedmask) > 0 )
84e843cd 724 {
29e69b85 725 numvalid = 0;
dd7b22ad 726 memset(pubkeys,0,sizeof(pubkeys));
84e843cd 727 for (j=1; j<numvouts; j++)
728 {
729 len = block.vtx[i].vout[j].scriptPubKey.size();
730 if ( len <= sizeof(scriptbuf) )
731 {
732 memcpy(scriptbuf,block.vtx[i].vout[j].scriptPubKey.data(),len);
733 if ( len == 35 && scriptbuf[0] == 33 && scriptbuf[34] == 0xac )
734 {
29e69b85 735 memcpy(pubkeys[numvalid++],scriptbuf+1,33);
e7f99312 736 for (k=0; k<33; k++)
84e843cd 737 printf("%02x",scriptbuf[k+1]);
738 printf(" <- new notary.[%d]\n",j-1);
739 }
740 }
741 }
29e69b85 742 if ( numvalid > 13 )
d8ce705a 743 {
744 memset(&txhash,0,sizeof(txhash));
5cea7725 745 komodo_stateupdate(height,pubkeys,numvalid,0,txhash,0,0,0,0);
d8ce705a 746 }
835c617e 747 printf("new notaries.%d newheight.%d from height.%d\n",numvouts-1,KOMODO_PUBKEYS_HEIGHT(height),height);
84e843cd 748 }
a96439f5 749 }
656eddcd 750 }
44c4fbbd 751 } else printf("komodo_connectblock: unexpected null pindex\n");
3d35aa5b 752}
753
4355e769 754void komodo_disconnect(CBlockIndex *pindex,CBlock& block)
755{
77117dbe 756 komodo_init();
9997caa0 757 //uint256 zero;
758 //printf("disconnect ht.%d\n",pindex->nHeight);
759 //memset(&zero,0,sizeof(zero));
5cea7725 760 //komodo_stateupdate(-pindex->nHeight,0,0,0,zero,0,0,0,0);
4355e769 761}
762
dfda5498 763int32_t komodo_block2height(CBlock *block)
764{
bc556d7e 765 int32_t i,n,height = 0; uint8_t *ptr = (uint8_t *)block->vtx[0].vin[0].scriptSig.data();
77117dbe 766 komodo_init();
0ebcd665 767 if ( block->vtx[0].vin[0].scriptSig.size() > 5 )
dfda5498 768 {
7b0be31f 769 //for (i=0; i<6; i++)
770 // printf("%02x",ptr[i]);
bc556d7e 771 n = ptr[0];
772 for (i=0; i<n; i++)
186dfa6f 773 {
6dabcca4 774 //03bb81000101(bb 187) (81 48001) (00 12288256) <- coinbase.6 ht.12288256
775 height += ((uint32_t)ptr[i+1] << (i*8));
7b0be31f 776 //printf("(%02x %x %d) ",ptr[i+1],((uint32_t)ptr[i+1] << (i*8)),height);
186dfa6f 777 }
7b0be31f 778 //printf(" <- coinbase.%d ht.%d\n",(int32_t)block->vtx[0].vin[0].scriptSig.size(),height);
dfda5498 779 }
780 return(height);
781}
782
f2dd868d 783void komodo_block2pubkey33(uint8_t *pubkey33,CBlock& block)
784{
dfda5498 785 uint8_t *ptr = (uint8_t *)block.vtx[0].vout[0].scriptPubKey.data();
77117dbe 786 komodo_init();
f2dd868d 787 memcpy(pubkey33,ptr+1,33);
788}
789
0d24f3ed 790void komodo_index2pubkey33(uint8_t *pubkey33,CBlockIndex *pindex,int32_t height)
9997caa0 791{
792 CBlock block;
77117dbe 793 komodo_init();
9499e4de 794 memset(pubkey33,0,33);
0d24f3ed 795 if ( pindex != 0 )
796 {
5f197aee 797 if ( ReadBlockFromDisk(block,(const CBlockIndex *)pindex) != 0 )
e778963c 798 {
0d24f3ed 799 komodo_block2pubkey33(pubkey33,block);
e778963c 800 }
0d24f3ed 801 }
802 else
803 {
804 // height -> pubkey33
732fdf87 805 //printf("extending chaintip komodo_index2pubkey33 height.%d need to get pubkey33\n",height);
0d24f3ed 806 }
9997caa0 807}
808
c62c3e41 809int32_t komodo_opreturnscript(uint8_t *script,uint8_t type,uint8_t *opret,int32_t opretlen)
c0968b8e 810{
811 int32_t offset = 0;
812 script[offset++] = 0x6a;
c62c3e41 813 opretlen++;
c0968b8e 814 if ( opretlen >= 0x4c )
815 {
816 if ( opretlen > 0xff )
817 {
818 script[offset++] = 0x4d;
819 script[offset++] = opretlen & 0xff;
820 script[offset++] = (opretlen >> 8) & 0xff;
821 }
822 else
823 {
824 script[offset++] = 0x4c;
825 script[offset++] = opretlen;
826 }
827 } else script[offset++] = opretlen;
c62c3e41 828 script[offset++] = type;
c0968b8e 829 memcpy(&script[offset],opret,opretlen);
830 return(opretlen + offset);
831}
832
7652ed92 833int32_t komodo_opreturn(uint8_t *opret,int32_t maxsize)
834{
f6326687 835 static uint32_t lastcrc;
65d466d3 836 FILE *fp; char fname[512]; uint32_t crc32,check,timestamp; int32_t i,n,retval,fsize,len=0; uint8_t data[8192];
73d79c1d 837#ifdef WIN32
838 sprintf(fname,"%s\\%s",GetDataDir(false).string().c_str(),(char *)"komodofeed");
839#else
840 sprintf(fname,"%s/%s",GetDataDir(false).string().c_str(),(char *)"komodofeed");
841#endif
842 if ( (fp= fopen(fname,"rb")) != 0 )
843 {
844 fseek(fp,0,SEEK_END);
845 fsize = (int32_t)ftell(fp);
846 rewind(fp);
4087487b 847 if ( fsize <= maxsize-4 && fsize <= sizeof(data) && fsize > sizeof(crc32) )
73d79c1d 848 {
849 if ( (retval= (int32_t)fread(data,1,fsize,fp)) == fsize )
850 {
57b8c333 851 len = iguana_rwnum(0,data,sizeof(crc32),(void *)&crc32);
73d79c1d 852 check = calc_crc32(0,data+sizeof(crc32),(int32_t)(fsize-sizeof(crc32)));
57b8c333 853 if ( check == crc32 )
854 {
15001ca1 855 double KMDBTC,BTCUSD,CNYUSD; uint32_t pvals[128];
65d466d3 856 dpow_readprices(&data[len],&timestamp,&KMDBTC,&BTCUSD,&CNYUSD,pvals);
289ad2f8 857 if ( 0 && lastcrc != crc32 )
57b8c333 858 {
65d466d3 859 for (i=0; i<32; i++)
f6326687 860 printf("%u ",pvals[i]);
f6326687 861 printf("t%u n.%d KMD %f BTC %f CNY %f (%f)\n",timestamp,n,KMDBTC,BTCUSD,CNYUSD,CNYUSD!=0?1./CNYUSD:0);
65d466d3 862 }
57b8c333 863 if ( timestamp > time(NULL)-60 )
864 {
c62c3e41 865 n = komodo_opreturnscript(opret,'P',data+sizeof(crc32),(int32_t)(fsize-sizeof(crc32)));
289ad2f8 866 if ( 0 && lastcrc != crc32 )
f6326687 867 {
868 for (i=0; i<n; i++)
869 printf("%02x",opret[i]);
870 printf(" coinbase opret[%d] crc32.%u:%u\n",n,crc32,check);
871 }
57b8c333 872 } else printf("t%u too old for %u\n",timestamp,(uint32_t)time(NULL));
e0689afa 873 lastcrc = crc32;
57b8c333 874 } else printf("crc32 %u mismatch %u\n",crc32,check);
f6326687 875 } else printf("fread.%d error != fsize.%d\n",retval,fsize);
3ab13bf3 876 } else printf("fsize.%d > maxsize.%d or data[%d]\n",fsize,maxsize,(int32_t)sizeof(data));
73d79c1d 877 fclose(fp);
878 }
c0968b8e 879 return(n);
7652ed92 880}
0f24f245 881
fcd36118 882#endif
This page took 0.221794 seconds and 4 git commands to generate.