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