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
01cc012f 19int32_t iguana_rwnum(int32_t rwflag,uint8_t *serialized,int32_t len,void *endianedp)
20{
21 int32_t i; uint64_t x;
22 if ( rwflag == 0 )
23 {
24 x = 0;
25 for (i=len-1; i>=0; i--)
26 {
27 x <<= 8;
28 x |= serialized[i];
29 }
30 switch ( len )
31 {
32 case 1: *(uint8_t *)endianedp = (uint8_t)x; break;
33 case 2: *(uint16_t *)endianedp = (uint16_t)x; break;
34 case 4: *(uint32_t *)endianedp = (uint32_t)x; break;
35 case 8: *(uint64_t *)endianedp = (uint64_t)x; break;
36 }
37 }
38 else
39 {
40 x = 0;
41 switch ( len )
42 {
43 case 1: x = *(uint8_t *)endianedp; break;
44 case 2: x = *(uint16_t *)endianedp; break;
45 case 4: x = *(uint32_t *)endianedp; break;
46 case 8: x = *(uint64_t *)endianedp; break;
47 }
48 for (i=0; i<len; i++,x >>= 8)
49 serialized[i] = (uint8_t)(x & 0xff);
50 }
51 return(len);
52}
53
54int32_t iguana_rwbignum(int32_t rwflag,uint8_t *serialized,int32_t len,uint8_t *endianedp)
55{
56 int32_t i;
57 if ( rwflag == 0 )
58 {
59 for (i=0; i<len; i++)
53b58ced 60 endianedp[i] = serialized[i];
01cc012f 61 }
62 else
63 {
64 for (i=0; i<len; i++)
53b58ced 65 serialized[i] = endianedp[i];
01cc012f 66 }
67 return(len);
68}
69
70int32_t _unhex(char c)
71{
72 if ( c >= '0' && c <= '9' )
73 return(c - '0');
74 else if ( c >= 'a' && c <= 'f' )
75 return(c - 'a' + 10);
76 else if ( c >= 'A' && c <= 'F' )
77 return(c - 'A' + 10);
78 return(-1);
79}
80
81int32_t is_hexstr(char *str,int32_t n)
82{
83 int32_t i;
84 if ( str == 0 || str[0] == 0 )
85 return(0);
86 for (i=0; str[i]!=0; i++)
87 {
88 if ( n > 0 && i >= n )
89 break;
90 if ( _unhex(str[i]) < 0 )
91 break;
92 }
93 if ( n == 0 )
94 return(i);
95 return(i == n);
96}
97
98int32_t unhex(char c)
99{
100 int32_t hex;
101 if ( (hex= _unhex(c)) < 0 )
102 {
103 //printf("unhex: illegal hexchar.(%c)\n",c);
104 }
105 return(hex);
106}
107
108unsigned char _decode_hex(char *hex) { return((unhex(hex[0])<<4) | unhex(hex[1])); }
109
110int32_t decode_hex(uint8_t *bytes,int32_t n,char *hex)
111{
112 int32_t adjust,i = 0;
113 //printf("decode.(%s)\n",hex);
114 if ( is_hexstr(hex,n) == 0 )
115 {
116 memset(bytes,0,n);
117 return(n);
118 }
119 if ( n == 0 || (hex[n*2+1] == 0 && hex[n*2] != 0) )
120 {
121 if ( n > 0 )
122 {
123 bytes[0] = unhex(hex[0]);
124 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));
125 }
126 bytes++;
127 hex++;
128 adjust = 1;
129 } else adjust = 0;
130 if ( n > 0 )
131 {
132 for (i=0; i<n; i++)
133 bytes[i] = _decode_hex(&hex[i*2]);
134 }
135 //bytes[i] = 0;
136 return(n + adjust);
137}
138
93b5c955 139#include <stdint.h>
778ca57b 140#include <stdio.h>
93b5c955 141
44c4fbbd 142#define CRYPTO777_PUBSECPSTR "020e46e79a2a8d12b9b5d12c7a91adb4e454edfae43c0a0cb805427d2ac7613fd9"
143
acb1f4f1 144const char *Notaries[64][2] =
df1620e2 145{
146 { "jl777_testA", "03b7621b44118017a16043f19b30cc8a4cfe068ac4e42417bae16ba460c80f3828" },
147 { "jl777_testB", "02ebfc784a4ba768aad88d44d1045d240d47b26e248cafaf1c5169a42d7a61d344" },
148 { "pondsea_SH", "02209073bc0943451498de57f802650311b1f12aa6deffcd893da198a544c04f36" },
149 { "crackers_EU", "0340c66cf2c41c41efb420af57867baa765e8468c12aa996bfd816e1e07e410728" },
150 { "pondsea_EU", "0225aa6f6f19e543180b31153d9e6d55d41bc7ec2ba191fd29f19a2f973544e29d" },
151 { "locomb_EU", "025c6d26649b9d397e63323d96db42a9d3caad82e1d6076970efe5056c00c0779b" },
152 { "fullmoon_AE", "0204a908350b8142698fdb6fabefc97fe0e04f537adc7522ba7a1e8f3bec003d4a" },
153 { "movecrypto_EU", "021ab53bc6cf2c46b8a5456759f9d608966eff87384c2b52c0ac4cc8dd51e9cc42" },
154 { "badass_EU", "0209d48554768dd8dada988b98aca23405057ac4b5b46838a9378b95c3e79b9b9e" },
155 { "crackers_NA", "029e1c01131974f4cd3f564cc0c00eb87a0f9721043fbc1ca60f9bd0a1f73f64a1" },
156 { "proto_EU", "03681ffdf17c8f4f0008cefb7fa0779c5e888339cdf932f0974483787a4d6747c1" },
157 { "jeezy_EU", "023cb3e593fb85c5659688528e9a4f1c4c7f19206edc7e517d20f794ba686fd6d6" },
158 { "farl4web_EU", "035caa40684ace968677dca3f09098aa02b70e533da32390a7654c626e0cf908e1" },
159 { "nxtswe_EU", "032fb104e5eaa704a38a52c126af8f67e870d70f82977e5b2f093d5c1c21ae5899" },
160 { "traderbill_EU", "03196e8de3e2e5d872f31d79d6a859c8704a2198baf0af9c7b21e29656a7eb455f" },
161 { "vanbreuk_EU", "024f3cad7601d2399c131fd070e797d9cd8533868685ddbe515daa53c2e26004c3" },
162 { "titomane_EU", "03517fcac101fed480ae4f2caf775560065957930d8c1facc83e30077e45bdd199" },
163 { "supernet_AE", "029d93ef78197dc93892d2a30e5a54865f41e0ca3ab7eb8e3dcbc59c8756b6e355" },
164 { "supernet_EU", "02061c6278b91fd4ac5cab4401100ffa3b2d5a277e8f71db23401cc071b3665546" },
165 { "yassin_EU", "033fb7231bb66484081952890d9a03f91164fb27d392d9152ec41336b71b15fbd0" },
166 { "durerus_EU", "02bcbd287670bdca2c31e5d50130adb5dea1b53198f18abeec7211825f47485d57" },
167 { "badass_SH", "026b49dd3923b78a592c1b475f208e23698d3f085c4c3b4906a59faf659fd9530b" },
168 { "baddass_NA" "02afa1a9f948e1634a29dc718d218e9d150c531cfa852843a1643a02184a63c1a7" },
169 { "pondsea_NA", "031bcfdbb62268e2ff8dfffeb9ddff7fe95fca46778c77eebff9c3829dfa1bb411" },
170 { "rnr_EU", "0287aa4b73988ba26cf6565d815786caf0d2c4af704d7883d163ee89cd9977edec" },
171 { "crackers_SH", "02313d72f9a16055737e14cfc528dcd5d0ef094cfce23d0348fe974b6b1a32e5f0" },
172 { "grewal_SH", "03212a73f5d38a675ee3cdc6e82542a96c38c3d1c79d25a1ed2e42fcf6a8be4e68" },
173 { "polycryptoblock_NA", "02708dcda7c45fb54b78469673c2587bfdd126e381654819c4c23df0e00b679622" },
174 { "titomane_NA", "0387046d9745414fb58a0fa3599078af5073e10347e4657ef7259a99cb4f10ad47" },
175 { "titomane_AE", "03cda6ca5c2d02db201488a54a548dbfc10533bdc275d5ea11928e8d6ab33c2185" },
52275d67 176 { "kolo_EU", "03f5c08dadffa0ffcafb8dd7ffc38c22887bd02702a6c9ac3440deddcf2837692b" },
df1620e2 177};
178
352f8081 179int32_t IS_KOMODO_NOTARY,USE_EXTERNAL_PUBKEY,NOTARIZED_HEIGHT,Num_nutxos;
998397aa 180std::string NOTARY_PUBKEY;
f2d60864 181uint256 NOTARIZED_HASH;
352f8081 182struct nutxo_entry { uint256 txhash; uint64_t voutmask; int32_t notaryid; };
183struct nutxo_entry NUTXOS[10000];
184
b9bfc77d 185void komodo_nutxoadd(int32_t notaryid,uint256 txhash,uint64_t voutmask,int32_t numvouts)
352f8081 186{
b9bfc77d 187 if ( numvouts > 1 )
188 {
189 NUTXOS[Num_nutxos].txhash = txhash;
190 NUTXOS[Num_nutxos].voutmask = voutmask;
191 NUTXOS[Num_nutxos].notaryid = notaryid;
192 printf("Add NUTXO[%d] <- notaryid.%d %llx\n",Num_nutxos,notaryid,(long long)voutmask);
193 Num_nutxos++;
194 }
352f8081 195}
196
197int32_t komodo_nutxofind(uint256 txhash,int32_t vout)
198{
199 int32_t i;
200 for (i=0; i<Num_nutxos; i++)
201 {
202 if ( memcmp(&txhash,&NUTXOS[i].txhash,sizeof(txhash)) == 0 && ((1LL << vout) & NUTXOS[i].voutmask) != 0 )
203 return(NUTXOS[i].notaryid);
204 }
205 return(-1);
206}
50027f06 207
1390456b 208int32_t komodo_notaryfind(uint8_t *pubkey)
209{
210 int32_t k; uint8_t notarypub[33];
211 for (k=0; k<64; k++)
212 {
213 if ( Notaries[k][0] == 0 || Notaries[k][1] == 0 || Notaries[k][0][0] == 0 || Notaries[k][1][0] == 0 )
214 break;
550fcab6 215 decode_hex(notarypub,33,(char *)Notaries[k][1]);
1390456b 216 if ( memcmp(notarypub,pubkey,33) == 0 )
1390456b 217 return(k);
1390456b 218 }
219 return(-1);
220}
221
222int32_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)
223{
550fcab6 224 int32_t k,opretlen,len = 0; uint256 kmdtxid,btctxid; uint8_t crypto777[33];
9c406099 225 if ( scriptlen == 35 && scriptbuf[0] == 33 && scriptbuf[34] == 0xac )
1390456b 226 {
c23dd601 227 decode_hex(crypto777,33,(char *)CRYPTO777_PUBSECPSTR);
e1be360e 228 for (k=0; k<33; k++)
229 printf("%02x",crypto777[k]);
230 printf(" crypto777 ");
231 for (k=0; k<scriptlen; k++)
232 printf("%02x",scriptbuf[k]);
233 printf(" <- script ht.%d i.%d j.%d cmp.%d\n",height,i,j,memcmp(crypto777,scriptbuf+1,33));
1390456b 234 if ( memcmp(crypto777,scriptbuf+1,33) == 0 )
235 {
236 *specialtxp = 1;
237 printf(">>>>>>>> ");
238 }
239 else if ( (k= komodo_notaryfind(scriptbuf + 1)) >= 0 )
240 {
e1be360e 241 printf("found notary.k%d\n",k);
1390456b 242 if ( notaryid < 0 )
243 {
244 notaryid = k;
245 *voutmaskp |= (1LL << j);
246 }
247 else if ( notaryid != k )
248 printf("mismatch notaryid.%d k.%d\n",notaryid,k);
249 else *voutmaskp |= (1LL << j);
250 }
251 }
252 if ( j == 1 && scriptbuf[len++] == 0x6a )
253 {
254 if ( (opretlen= scriptbuf[len++]) == 0x4c )
255 opretlen = scriptbuf[len++];
256 else if ( opretlen == 0x4d )
257 {
258 opretlen = scriptbuf[len++];
259 opretlen = (opretlen << 8) + scriptbuf[len++];
260 }
261 if ( opretlen >= 32*2+4 )
262 {
263 len += iguana_rwbignum(0,&scriptbuf[len],32,(uint8_t *)&kmdtxid);
264 len += iguana_rwnum(0,&scriptbuf[len],4,(uint8_t *)notarizedheightp);
265 len += iguana_rwbignum(0,&scriptbuf[len],32,(uint8_t *)&btctxid);
06f0ed43 266 for (k=0; k<scriptlen; k++)
267 printf("%02x",scriptbuf[k]);
268 printf(" <- script ht.%d i.%d j.%d\n",height,i,j);
c23dd601 269 printf("ht.%d NOTARIZED.%d KMD.%s BTC.%s\n",height,*notarizedheightp,kmdtxid.ToString().c_str(),btctxid.ToString().c_str());
1390456b 270 if ( *notarizedheightp > NOTARIZED_HEIGHT )
271 {
272 NOTARIZED_HEIGHT = *notarizedheightp;
273 NOTARIZED_HASH = kmdtxid;
274 }
275 }
276 }
277 return(notaryid);
278}
279
651989c7 280void komodo_connectblock(CBlockIndex *pindex,CBlock& block)
50027f06 281{
acb3f1d8 282 char *scriptstr,*opreturnstr; uint64_t signedmask,voutmask;
550fcab6 283 uint8_t scriptbuf[4096]; uint256 kmdtxid,btctxid,txhash;
1390456b 284 int32_t i,j,k,specialtx,notarizedheight,notaryid,len,numvouts,numvins,height,txn_count,flag;
3d35aa5b 285 // update voting results and official (height, notaries[])
68916cc6 286 if ( pindex != 0 )
b501ded2 287 {
656eddcd 288 height = pindex->nHeight;
01cc012f 289 txn_count = block.vtx.size();
290 for (i=0; i<txn_count; i++)
dc64de68 291 {
352f8081 292 txhash = block.vtx[i].GetHash();
01cc012f 293 numvouts = block.vtx[i].vout.size();
352f8081 294 notaryid = -1;
1390456b 295 voutmask = specialtx = notarizedheight = 0;
01cc012f 296 for (j=0; j<numvouts; j++)
dc64de68 297 {
1390456b 298 len = block.vtx[i].vout[j].scriptPubKey.size();
299 if ( len <= sizeof(scriptbuf) )
01cc012f 300 {
1390456b 301 memcpy(scriptbuf,block.vtx[i].vout[j].scriptPubKey.data(),len);
acb3f1d8 302 notaryid = komodo_voutupdate(notaryid,scriptbuf,len,height,txhash,i,j,&voutmask,&specialtx,&notarizedheight);
01cc012f 303 }
352f8081 304 }
1390456b 305 if ( notaryid >= 0 && voutmask != 0 )
306 komodo_nutxoadd(notaryid,txhash,voutmask,numvouts);
307 signedmask = 0;
308 numvins = block.vtx[i].vin.size();
5bdebffe 309 for (j=0; j<numvins; j++)
352f8081 310 {
1390456b 311 if ( (k= komodo_nutxofind(block.vtx[i].vin[j].prevout.hash,block.vtx[i].vin[j].prevout.n)) >= 0 )
312 signedmask |= (1LL << k);
313 }
06f0ed43 314 if ( signedmask != 0 && (notarizedheight != 0 || specialtx != 0) )
1390456b 315 {
06f0ed43 316 printf("NOTARY SIGNED.%llx ht.%d txi.%d notaryht.%d specialtx.%d\n",(long long)signedmask,height,i,notarizedheight,specialtx);
a96439f5 317 }
656eddcd 318 }
44c4fbbd 319 } else printf("komodo_connectblock: unexpected null pindex\n");
3d35aa5b 320}
321
e1be360e 322int32_t komodo_blockindexcheck(CBlockIndex *pindex,uint32_t *nBitsp)
323{
324 // 1 -> valid notary block, change nBits to KOMODO_MINDIFF_NBITS
325 // -1 -> invalid, ie, prior to notarized block
326 CBlock block; int32_t i,height; char *coinbasestr;
327 if ( pindex == 0 )
328 return(0);
329 if ( ReadBlockFromDisk(block,pindex,1) == 0 )
330 return(0);
331 if ( block.vtx.size() > 0 )
332 {
333 height = pindex->nHeight;
334 coinbasestr = (char *)block.vtx[0].vout[0].scriptPubKey.ToString().c_str();
335 for (i=0; i<64; i++)
336 {
337 if ( Notaries[i][0] == 0 || Notaries[i][1] == 0 || Notaries[i][0][0] == 0 || Notaries[i][1][0] == 0 )
338 break;
339 if ( strncmp(Notaries[i][1],coinbasestr,66) == 0 )
340 {
341 //printf("Notary.[%d] %s ht.%d (%s)\n",i,Notaries[i][0],height,coinbasestr);
342 //*nBitsp = KOMODO_MINDIFF_NBITS;
343 return(1);
344 }
345 }
346 }
347 // compare against elected notary pubkeys as of height
348 return(0);
349}
350
0570045c 351int32_t komodo_is_notaryblock(CBlockHeader& blockhdr)
3d35aa5b 352{
68916cc6 353 //uint32_t nBits = 0;
354 //return(komodo_blockindexcheck(mapBlockIndex[blockhdr.GetHash()],&nBits));
355 return(0);
3d35aa5b 356}
357
0570045c 358int32_t komodo_blockhdrcheck(CBlockHeader& blockhdr,uint32_t *nBitsp)
3d35aa5b 359{
aa8b56ea 360 int32_t retval;
361 if ( (retval= komodo_is_notaryblock(blockhdr)) > 0 )
0570045c 362 *nBitsp = KOMODO_MINDIFF_NBITS;
aa8b56ea 363 return(retval);
3d35aa5b 364}
365
0570045c 366int32_t komodo_blockcheck(CBlock& block,uint32_t *nBitsp)
d27afb07 367{
c9b8b8b0 368 return(komodo_blockhdrcheck(block,nBitsp));
d27afb07 369}
fcd36118 370
371#endif
This page took 0.082643 seconds and 4 git commands to generate.