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