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