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