fcd36118 |
1 | /****************************************************************************** |
713c2a94 |
2 | * Copyright © 2014-2018 The SuperNET Developers. * |
fcd36118 |
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 |
5416af1d |
18 | #include "komodo_defs.h" |
fcd36118 |
19 | |
b71b045a |
20 | #ifdef _WIN32 |
21 | #define printf(...) |
22 | #endif |
23 | |
27bf3c5e |
24 | // Todo: |
aa114a60 |
25 | // verify: reorgs |
3ec03ada |
26 | |
26ac06c4 |
27 | #define KOMODO_ASSETCHAINS_WAITNOTARIZE |
fa8d44fc |
28 | #define KOMODO_PAXMAX (10000 * COIN) |
aa114a60 |
29 | |
9499e4de |
30 | #include <stdint.h> |
31 | #include <stdio.h> |
975b2ddb |
32 | #include <pthread.h> |
88f973c2 |
33 | #include <ctype.h> |
6d5cb6d4 |
34 | #include "uthash.h" |
35 | #include "utlist.h" |
9499e4de |
36 | |
fc318ffe |
37 | int32_t gettxout_scriptPubKey(uint8_t *scriptPubkey,int32_t maxsize,uint256 txid,int32_t n); |
f3a1de3a |
38 | void komodo_event_rewind(struct komodo_state *sp,char *symbol,int32_t height); |
875cf683 |
39 | void komodo_connectblock(CBlockIndex *pindex,CBlock& block); |
3face669 |
40 | |
fc318ffe |
41 | #include "komodo_structs.h" |
9fb37168 |
42 | #include "komodo_globals.h" |
46beb55e |
43 | #include "komodo_utils.h" |
6b5cfbb4 |
44 | #include "komodo_curve25519.h" |
1bfdde1d |
45 | |
d430a5e8 |
46 | #include "komodo_cJSON.c" |
e4e76989 |
47 | #include "komodo_bitcoind.h" |
48 | #include "komodo_interest.h" |
49 | #include "komodo_pax.h" |
50 | #include "komodo_notary.h" |
ab918767 |
51 | |
52 | int32_t komodo_parsestatefile(struct komodo_state *sp,FILE *fp,char *symbol,char *dest); |
6b5cfbb4 |
53 | #include "komodo_kv.h" |
eeaaf554 |
54 | #include "komodo_jumblr.h" |
e4e76989 |
55 | #include "komodo_gateway.h" |
56 | #include "komodo_events.h" |
713c2a94 |
57 | #include "komodo_ccdata.h" |
e4e76989 |
58 | |
c75c18fc |
59 | void komodo_currentheight_set(int32_t height) |
60 | { |
7c130297 |
61 | char symbol[KOMODO_ASSETCHAIN_MAXLEN],dest[KOMODO_ASSETCHAIN_MAXLEN]; struct komodo_state *sp; |
c75c18fc |
62 | if ( (sp= komodo_stateptr(symbol,dest)) != 0 ) |
63 | sp->CURRENT_HEIGHT = height; |
64 | } |
65 | |
66 | int32_t komodo_currentheight() |
67 | { |
7c130297 |
68 | char symbol[KOMODO_ASSETCHAIN_MAXLEN],dest[KOMODO_ASSETCHAIN_MAXLEN]; struct komodo_state *sp; |
c75c18fc |
69 | if ( (sp= komodo_stateptr(symbol,dest)) != 0 ) |
70 | return(sp->CURRENT_HEIGHT); |
71 | else return(0); |
72 | } |
73 | |
74 | int32_t komodo_parsestatefile(struct komodo_state *sp,FILE *fp,char *symbol,char *dest) |
75 | { |
76 | static int32_t errs; |
18c6cfce |
77 | int32_t func,ht,notarized_height,num,matched=0,MoMdepth; uint256 MoM,notarized_hash,notarized_desttxid; uint8_t pubkeys[64][33]; |
c75c18fc |
78 | if ( (func= fgetc(fp)) != EOF ) |
79 | { |
80 | if ( ASSETCHAINS_SYMBOL[0] == 0 && strcmp(symbol,"KMD") == 0 ) |
81 | matched = 1; |
82 | else matched = (strcmp(symbol,ASSETCHAINS_SYMBOL) == 0); |
83 | if ( fread(&ht,1,sizeof(ht),fp) != sizeof(ht) ) |
84 | errs++; |
34c68daa |
85 | if ( 0 && ASSETCHAINS_SYMBOL[0] != 0 && func != 'T' ) |
d0d61f8f |
86 | printf("[%s] matched.%d fpos.%ld func.(%d %c) ht.%d\n",ASSETCHAINS_SYMBOL,matched,ftell(fp),func,func,ht); |
c75c18fc |
87 | if ( func == 'P' ) |
88 | { |
f3a1de3a |
89 | if ( (num= fgetc(fp)) <= 64 ) |
c75c18fc |
90 | { |
91 | if ( fread(pubkeys,33,num,fp) != num ) |
92 | errs++; |
93 | else |
94 | { |
ec368288 |
95 | //printf("updated %d pubkeys at %s ht.%d\n",num,symbol,ht); |
15724d02 |
96 | if ( (KOMODO_EXTERNAL_NOTARIES != 0 && matched != 0) || (strcmp(symbol,"KMD") == 0 && KOMODO_EXTERNAL_NOTARIES == 0) ) |
c75c18fc |
97 | komodo_eventadd_pubkeys(sp,symbol,ht,num,pubkeys); |
98 | } |
99 | } else printf("illegal num.%d\n",num); |
100 | } |
18c6cfce |
101 | else if ( func == 'N' || func == 'M' ) |
c75c18fc |
102 | { |
103 | if ( fread(¬arized_height,1,sizeof(notarized_height),fp) != sizeof(notarized_height) ) |
104 | errs++; |
105 | if ( fread(¬arized_hash,1,sizeof(notarized_hash),fp) != sizeof(notarized_hash) ) |
106 | errs++; |
107 | if ( fread(¬arized_desttxid,1,sizeof(notarized_desttxid),fp) != sizeof(notarized_desttxid) ) |
108 | errs++; |
18c6cfce |
109 | if ( func == 'M' ) |
110 | { |
111 | if ( fread(&MoM,1,sizeof(MoM),fp) != sizeof(MoM) ) |
112 | errs++; |
113 | if ( fread(&MoMdepth,1,sizeof(MoMdepth),fp) != sizeof(MoMdepth) ) |
114 | errs++; |
115 | if ( 1 && ASSETCHAINS_SYMBOL[0] != 0 && sp != 0 ) |
b6e71fe9 |
116 | printf("%s load[%s.%d -> %s] NOTARIZED %d %s MoM.%s %d CCid.%u\n",ASSETCHAINS_SYMBOL,symbol,sp->NUM_NPOINTS,dest,notarized_height,notarized_hash.ToString().c_str(),MoM.ToString().c_str(),MoMdepth&0xffff,(MoMdepth>>16)&0xffff); |
18c6cfce |
117 | } |
118 | else |
119 | { |
120 | memset(&MoM,0,sizeof(MoM)); |
121 | MoMdepth = 0; |
122 | } |
1ebb14e7 |
123 | //if ( matched != 0 ) global independent states -> inside *sp |
26f6fa01 |
124 | komodo_eventadd_notarized(sp,symbol,ht,dest,notarized_hash,notarized_desttxid,notarized_height,MoM,MoMdepth); |
c75c18fc |
125 | } |
1ebb14e7 |
126 | else if ( func == 'U' ) // deprecated |
c75c18fc |
127 | { |
128 | uint8_t n,nid; uint256 hash; uint64_t mask; |
129 | n = fgetc(fp); |
130 | nid = fgetc(fp); |
131 | //printf("U %d %d\n",n,nid); |
132 | if ( fread(&mask,1,sizeof(mask),fp) != sizeof(mask) ) |
133 | errs++; |
134 | if ( fread(&hash,1,sizeof(hash),fp) != sizeof(hash) ) |
135 | errs++; |
6f3cb4d0 |
136 | //if ( matched != 0 ) |
137 | // komodo_eventadd_utxo(sp,symbol,ht,nid,hash,mask,n); |
c75c18fc |
138 | } |
139 | else if ( func == 'K' ) |
140 | { |
141 | int32_t kheight; |
142 | if ( fread(&kheight,1,sizeof(kheight),fp) != sizeof(kheight) ) |
143 | errs++; |
1ebb14e7 |
144 | //if ( matched != 0 ) global independent states -> inside *sp |
a8f4e85e |
145 | //printf("%s.%d load[%s] ht.%d\n",ASSETCHAINS_SYMBOL,ht,symbol,kheight); |
e155dbe9 |
146 | komodo_eventadd_kmdheight(sp,symbol,ht,kheight,0); |
147 | } |
148 | else if ( func == 'T' ) |
149 | { |
150 | int32_t kheight,ktimestamp; |
151 | if ( fread(&kheight,1,sizeof(kheight),fp) != sizeof(kheight) ) |
152 | errs++; |
153 | if ( fread(&ktimestamp,1,sizeof(ktimestamp),fp) != sizeof(ktimestamp) ) |
154 | errs++; |
155 | //if ( matched != 0 ) global independent states -> inside *sp |
a8f4e85e |
156 | //printf("%s.%d load[%s] ht.%d t.%u\n",ASSETCHAINS_SYMBOL,ht,symbol,kheight,ktimestamp); |
e155dbe9 |
157 | komodo_eventadd_kmdheight(sp,symbol,ht,kheight,ktimestamp); |
c75c18fc |
158 | } |
159 | else if ( func == 'R' ) |
160 | { |
ef1a9636 |
161 | uint16_t olen,v; uint64_t ovalue; uint256 txid; uint8_t opret[16384]; |
c75c18fc |
162 | if ( fread(&txid,1,sizeof(txid),fp) != sizeof(txid) ) |
163 | errs++; |
164 | if ( fread(&v,1,sizeof(v),fp) != sizeof(v) ) |
165 | errs++; |
166 | if ( fread(&ovalue,1,sizeof(ovalue),fp) != sizeof(ovalue) ) |
167 | errs++; |
168 | if ( fread(&olen,1,sizeof(olen),fp) != sizeof(olen) ) |
169 | errs++; |
170 | if ( olen < sizeof(opret) ) |
171 | { |
172 | if ( fread(opret,1,olen,fp) != olen ) |
173 | errs++; |
34c68daa |
174 | if ( 0 && ASSETCHAINS_SYMBOL[0] != 0 && matched != 0 ) |
e2a12abf |
175 | { |
176 | int32_t i; for (i=0; i<olen; i++) |
177 | printf("%02x",opret[i]); |
178 | printf(" %s.%d load[%s] opret[%c] len.%d %.8f\n",ASSETCHAINS_SYMBOL,ht,symbol,opret[0],olen,(double)ovalue/COIN); |
179 | } |
180 | komodo_eventadd_opreturn(sp,symbol,ht,txid,ovalue,v,opret,olen); // global shared state -> global PAX |
939a5a45 |
181 | } else |
182 | { |
66d02e79 |
183 | int32_t i; |
939a5a45 |
184 | for (i=0; i<olen; i++) |
185 | fgetc(fp); |
dff4ef45 |
186 | //printf("illegal olen.%u\n",olen); |
939a5a45 |
187 | } |
c75c18fc |
188 | } |
189 | else if ( func == 'D' ) |
190 | { |
191 | printf("unexpected function D[%d]\n",ht); |
192 | } |
193 | else if ( func == 'V' ) |
194 | { |
195 | int32_t numpvals; uint32_t pvals[128]; |
196 | numpvals = fgetc(fp); |
197 | if ( numpvals*sizeof(uint32_t) <= sizeof(pvals) && fread(pvals,sizeof(uint32_t),numpvals,fp) == numpvals ) |
198 | { |
1ebb14e7 |
199 | //if ( matched != 0 ) global shared state -> global PVALS |
335f2ea7 |
200 | //printf("%s load[%s] prices %d\n",ASSETCHAINS_SYMBOL,symbol,ht); |
15724d02 |
201 | komodo_eventadd_pricefeed(sp,symbol,ht,pvals,numpvals); |
c75c18fc |
202 | //printf("load pvals ht.%d numpvals.%d\n",ht,numpvals); |
203 | } else printf("error loading pvals[%d]\n",numpvals); |
528f3406 |
204 | } // else printf("[%s] %s illegal func.(%d %c)\n",ASSETCHAINS_SYMBOL,symbol,func,func); |
c75c18fc |
205 | return(func); |
206 | } else return(-1); |
207 | } |
17746e45 |
208 | |
209 | int32_t memread(void *dest,int32_t size,uint8_t *filedata,long *fposp,long datalen) |
210 | { |
211 | if ( *fposp+size <= datalen ) |
212 | { |
213 | memcpy(dest,&filedata[*fposp],size); |
214 | (*fposp) += size; |
215 | return(size); |
216 | } |
217 | return(-1); |
218 | } |
219 | |
3b40d631 |
220 | int32_t komodo_parsestatefiledata(struct komodo_state *sp,uint8_t *filedata,long *fposp,long datalen,char *symbol,char *dest) |
17746e45 |
221 | { |
222 | static int32_t errs; |
18c6cfce |
223 | int32_t func= -1,ht,notarized_height,MoMdepth,num,matched=0; uint256 MoM,notarized_hash,notarized_desttxid; uint8_t pubkeys[64][33]; long fpos = *fposp; |
17746e45 |
224 | if ( fpos < datalen ) |
225 | { |
226 | func = filedata[fpos++]; |
227 | if ( ASSETCHAINS_SYMBOL[0] == 0 && strcmp(symbol,"KMD") == 0 ) |
228 | matched = 1; |
229 | else matched = (strcmp(symbol,ASSETCHAINS_SYMBOL) == 0); |
230 | if ( memread(&ht,sizeof(ht),filedata,&fpos,datalen) != sizeof(ht) ) |
231 | errs++; |
232 | if ( func == 'P' ) |
233 | { |
234 | if ( (num= filedata[fpos++]) <= 64 ) |
235 | { |
236 | if ( memread(pubkeys,33*num,filedata,&fpos,datalen) != 33*num ) |
237 | errs++; |
238 | else |
239 | { |
240 | //printf("updated %d pubkeys at %s ht.%d\n",num,symbol,ht); |
241 | if ( (KOMODO_EXTERNAL_NOTARIES != 0 && matched != 0) || (strcmp(symbol,"KMD") == 0 && KOMODO_EXTERNAL_NOTARIES == 0) ) |
242 | komodo_eventadd_pubkeys(sp,symbol,ht,num,pubkeys); |
243 | } |
244 | } else printf("illegal num.%d\n",num); |
245 | } |
18c6cfce |
246 | else if ( func == 'N' || func == 'M' ) |
17746e45 |
247 | { |
248 | if ( memread(¬arized_height,sizeof(notarized_height),filedata,&fpos,datalen) != sizeof(notarized_height) ) |
249 | errs++; |
250 | if ( memread(¬arized_hash,sizeof(notarized_hash),filedata,&fpos,datalen) != sizeof(notarized_hash) ) |
251 | errs++; |
252 | if ( memread(¬arized_desttxid,sizeof(notarized_desttxid),filedata,&fpos,datalen) != sizeof(notarized_desttxid) ) |
253 | errs++; |
18c6cfce |
254 | if ( func == 'M' ) |
255 | { |
256 | if ( memread(&MoM,sizeof(MoM),filedata,&fpos,datalen) != sizeof(MoM) ) |
257 | errs++; |
258 | if ( memread(&MoMdepth,sizeof(MoMdepth),filedata,&fpos,datalen) != sizeof(MoMdepth) ) |
259 | errs++; |
260 | if ( 1 && ASSETCHAINS_SYMBOL[0] != 0 && sp != 0 ) |
b6e71fe9 |
261 | printf("%s load[%s.%d -> %s] NOTARIZED %d %s MoM.%s %d CCid.%u\n",ASSETCHAINS_SYMBOL,symbol,sp->NUM_NPOINTS,dest,notarized_height,notarized_hash.ToString().c_str(),MoM.ToString().c_str(),MoMdepth&0xffff,(MoMdepth>>16)&0xffff); |
18c6cfce |
262 | } |
263 | else |
264 | { |
265 | memset(&MoM,0,sizeof(MoM)); |
266 | MoMdepth = 0; |
267 | } |
26f6fa01 |
268 | komodo_eventadd_notarized(sp,symbol,ht,dest,notarized_hash,notarized_desttxid,notarized_height,MoM,MoMdepth); |
17746e45 |
269 | } |
270 | else if ( func == 'U' ) // deprecated |
271 | { |
272 | uint8_t n,nid; uint256 hash; uint64_t mask; |
273 | n = filedata[fpos++]; |
274 | nid = filedata[fpos++]; |
275 | //printf("U %d %d\n",n,nid); |
276 | if ( memread(&mask,sizeof(mask),filedata,&fpos,datalen) != sizeof(mask) ) |
277 | errs++; |
278 | if ( memread(&hash,sizeof(hash),filedata,&fpos,datalen) != sizeof(hash) ) |
279 | errs++; |
280 | } |
281 | else if ( func == 'K' ) |
282 | { |
283 | int32_t kheight; |
284 | if ( memread(&kheight,sizeof(kheight),filedata,&fpos,datalen) != sizeof(kheight) ) |
285 | errs++; |
286 | komodo_eventadd_kmdheight(sp,symbol,ht,kheight,0); |
287 | } |
288 | else if ( func == 'T' ) |
289 | { |
290 | int32_t kheight,ktimestamp; |
291 | if ( memread(&kheight,sizeof(kheight),filedata,&fpos,datalen) != sizeof(kheight) ) |
292 | errs++; |
293 | if ( memread(&ktimestamp,sizeof(ktimestamp),filedata,&fpos,datalen) != sizeof(ktimestamp) ) |
294 | errs++; |
295 | //if ( matched != 0 ) global independent states -> inside *sp |
296 | //printf("%s.%d load[%s] ht.%d t.%u\n",ASSETCHAINS_SYMBOL,ht,symbol,kheight,ktimestamp); |
297 | komodo_eventadd_kmdheight(sp,symbol,ht,kheight,ktimestamp); |
298 | } |
299 | else if ( func == 'R' ) |
300 | { |
301 | uint16_t olen,v; uint64_t ovalue; uint256 txid; uint8_t opret[16384]; |
302 | if ( memread(&txid,sizeof(txid),filedata,&fpos,datalen) != sizeof(txid) ) |
303 | errs++; |
304 | if ( memread(&v,sizeof(v),filedata,&fpos,datalen) != sizeof(v) ) |
305 | errs++; |
306 | if ( memread(&ovalue,sizeof(ovalue),filedata,&fpos,datalen) != sizeof(ovalue) ) |
307 | errs++; |
308 | if ( memread(&olen,sizeof(olen),filedata,&fpos,datalen) != sizeof(olen) ) |
309 | errs++; |
310 | if ( olen < sizeof(opret) ) |
311 | { |
312 | if ( memread(opret,olen,filedata,&fpos,datalen) != olen ) |
313 | errs++; |
4263c693 |
314 | if ( 1 && ASSETCHAINS_SYMBOL[0] != 0 && matched != 0 ) |
17746e45 |
315 | { |
316 | int32_t i; for (i=0; i<olen; i++) |
317 | printf("%02x",opret[i]); |
318 | printf(" %s.%d load[%s] opret[%c] len.%d %.8f\n",ASSETCHAINS_SYMBOL,ht,symbol,opret[0],olen,(double)ovalue/COIN); |
319 | } |
320 | komodo_eventadd_opreturn(sp,symbol,ht,txid,ovalue,v,opret,olen); // global shared state -> global PAX |
321 | } else |
322 | { |
323 | int32_t i; |
324 | for (i=0; i<olen; i++) |
325 | filedata[fpos++]; |
326 | //printf("illegal olen.%u\n",olen); |
327 | } |
328 | } |
329 | else if ( func == 'D' ) |
330 | { |
331 | printf("unexpected function D[%d]\n",ht); |
332 | } |
333 | else if ( func == 'V' ) |
334 | { |
335 | int32_t numpvals; uint32_t pvals[128]; |
336 | numpvals = filedata[fpos++]; |
337 | if ( numpvals*sizeof(uint32_t) <= sizeof(pvals) && memread(pvals,(int32_t)(sizeof(uint32_t)*numpvals),filedata,&fpos,datalen) == numpvals*sizeof(uint32_t) ) |
338 | { |
339 | //if ( matched != 0 ) global shared state -> global PVALS |
340 | //printf("%s load[%s] prices %d\n",ASSETCHAINS_SYMBOL,symbol,ht); |
341 | komodo_eventadd_pricefeed(sp,symbol,ht,pvals,numpvals); |
342 | //printf("load pvals ht.%d numpvals.%d\n",ht,numpvals); |
343 | } else printf("error loading pvals[%d]\n",numpvals); |
528f3406 |
344 | } // else printf("[%s] %s illegal func.(%d %c)\n",ASSETCHAINS_SYMBOL,symbol,func,func); |
17746e45 |
345 | *fposp = fpos; |
3b40d631 |
346 | return(func); |
347 | } |
348 | return(-1); |
17746e45 |
349 | } |
350 | |
16d589c2 |
351 | void 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,int32_t KMDheight,uint32_t KMDtimestamp,uint64_t opretvalue,uint8_t *opretbuf,uint16_t opretlen,uint16_t vout,uint256 MoM,int32_t MoMdepth) |
5cea7725 |
352 | { |
c88fa588 |
353 | static FILE *fp; static int32_t errs,didinit; static uint256 zero; |
7c130297 |
354 | struct komodo_state *sp; char fname[512],symbol[KOMODO_ASSETCHAIN_MAXLEN],dest[KOMODO_ASSETCHAIN_MAXLEN]; int32_t retval,ht,func; uint8_t num,pubkeys[64][33]; |
15d0fbd4 |
355 | if ( didinit == 0 ) |
356 | { |
357 | portable_mutex_init(&KOMODO_KV_mutex); |
fb9c3652 |
358 | portable_mutex_init(&KOMODO_CC_mutex); |
15d0fbd4 |
359 | didinit = 1; |
360 | } |
c75c18fc |
361 | if ( (sp= komodo_stateptr(symbol,dest)) == 0 ) |
15373725 |
362 | { |
363 | KOMODO_INITDONE = (uint32_t)time(NULL); |
fac8d1ff |
364 | printf("[%s] no komodo_stateptr\n",ASSETCHAINS_SYMBOL); |
c75c18fc |
365 | return; |
15373725 |
366 | } |
ca74f186 |
367 | //printf("[%s] (%s) -> (%s)\n",ASSETCHAINS_SYMBOL,symbol,dest); |
888cf827 |
368 | if ( fp == 0 ) |
369 | { |
055db9b6 |
370 | komodo_statefname(fname,ASSETCHAINS_SYMBOL,(char *)"komodostate"); |
bafc61f3 |
371 | if ( (fp= fopen(fname,"rb+")) != 0 ) |
372 | { |
f7f96087 |
373 | if ( (retval= komodo_faststateinit(sp,fname,symbol,dest)) > 0 ) |
58f293eb |
374 | fseek(fp,0,SEEK_END); |
08775bc1 |
375 | else |
376 | { |
a3a7ec85 |
377 | fprintf(stderr,"komodo_faststateinit retval.%d\n",retval); |
08775bc1 |
378 | while ( komodo_parsestatefile(sp,fp,symbol,dest) >= 0 ) |
379 | ; |
380 | } |
bafc61f3 |
381 | } else fp = fopen(fname,"wb+"); |
63c30610 |
382 | KOMODO_INITDONE = (uint32_t)time(NULL); |
bafc61f3 |
383 | } |
e98e2aec |
384 | if ( height <= 0 ) |
49df008c |
385 | { |
6458297e |
386 | //printf("early return: stateupdate height.%d\n",height); |
49df008c |
387 | return; |
388 | } |
3eea72f2 |
389 | if ( fp != 0 ) // write out funcid, height, other fields, call side effect function |
bafc61f3 |
390 | { |
2578b002 |
391 | //printf("fpos.%ld ",ftell(fp)); |
ab918767 |
392 | if ( KMDheight != 0 ) |
2b84e06c |
393 | { |
e155dbe9 |
394 | if ( KMDtimestamp != 0 ) |
395 | { |
396 | fputc('T',fp); |
397 | if ( fwrite(&height,1,sizeof(height),fp) != sizeof(height) ) |
398 | errs++; |
399 | if ( fwrite(&KMDheight,1,sizeof(KMDheight),fp) != sizeof(KMDheight) ) |
400 | errs++; |
401 | if ( fwrite(&KMDtimestamp,1,sizeof(KMDtimestamp),fp) != sizeof(KMDtimestamp) ) |
402 | errs++; |
403 | } |
404 | else |
405 | { |
406 | fputc('K',fp); |
407 | if ( fwrite(&height,1,sizeof(height),fp) != sizeof(height) ) |
408 | errs++; |
409 | if ( fwrite(&KMDheight,1,sizeof(KMDheight),fp) != sizeof(KMDheight) ) |
410 | errs++; |
411 | } |
412 | komodo_eventadd_kmdheight(sp,symbol,height,KMDheight,KMDtimestamp); |
2b84e06c |
413 | } |
01f9cb3d |
414 | else if ( opretbuf != 0 && opretlen > 0 ) |
64bb0834 |
415 | { |
01f9cb3d |
416 | uint16_t olen = opretlen; |
417 | fputc('R',fp); |
64bb0834 |
418 | if ( fwrite(&height,1,sizeof(height),fp) != sizeof(height) ) |
419 | errs++; |
429dabb5 |
420 | if ( fwrite(&txhash,1,sizeof(txhash),fp) != sizeof(txhash) ) |
421 | errs++; |
422 | if ( fwrite(&vout,1,sizeof(vout),fp) != sizeof(vout) ) |
423 | errs++; |
30df2e00 |
424 | if ( fwrite(&opretvalue,1,sizeof(opretvalue),fp) != sizeof(opretvalue) ) |
33935bd0 |
425 | errs++; |
289dc57b |
426 | if ( fwrite(&olen,1,sizeof(olen),fp) != olen ) |
427 | errs++; |
01f9cb3d |
428 | if ( fwrite(opretbuf,1,olen,fp) != olen ) |
64bb0834 |
429 | errs++; |
4263c693 |
430 | printf("create ht.%d R opret[%d] sp.%p\n",height,olen,sp); |
c75c18fc |
431 | //komodo_opreturn(height,opretvalue,opretbuf,olen,txhash,vout); |
432 | komodo_eventadd_opreturn(sp,symbol,height,txhash,opretvalue,vout,opretbuf,olen); |
01f9cb3d |
433 | } |
9997caa0 |
434 | else if ( notarypubs != 0 && numnotaries > 0 ) |
bafc61f3 |
435 | { |
f3a1de3a |
436 | printf("ht.%d func P[%d] errs.%d\n",height,numnotaries,errs); |
bafc61f3 |
437 | fputc('P',fp); |
c50ec0fb |
438 | if ( fwrite(&height,1,sizeof(height),fp) != sizeof(height) ) |
439 | errs++; |
bafc61f3 |
440 | fputc(numnotaries,fp); |
52ed4002 |
441 | if ( fwrite(notarypubs,33,numnotaries,fp) != numnotaries ) |
442 | errs++; |
c75c18fc |
443 | komodo_eventadd_pubkeys(sp,symbol,height,numnotaries,notarypubs); |
bafc61f3 |
444 | } |
671187dd |
445 | else if ( voutmask != 0 && numvouts > 0 ) |
446 | { |
2578b002 |
447 | //printf("ht.%d func U %d %d errs.%d hashsize.%ld\n",height,numvouts,notaryid,errs,sizeof(txhash)); |
671187dd |
448 | fputc('U',fp); |
c50ec0fb |
449 | if ( fwrite(&height,1,sizeof(height),fp) != sizeof(height) ) |
450 | errs++; |
671187dd |
451 | fputc(numvouts,fp); |
452 | fputc(notaryid,fp); |
453 | if ( fwrite(&voutmask,1,sizeof(voutmask),fp) != sizeof(voutmask) ) |
454 | errs++; |
455 | if ( fwrite(&txhash,1,sizeof(txhash),fp) != sizeof(txhash) ) |
456 | errs++; |
6f3cb4d0 |
457 | //komodo_eventadd_utxo(sp,symbol,height,notaryid,txhash,voutmask,numvouts); |
671187dd |
458 | } |
4a41b0b2 |
459 | else if ( pvals != 0 && numpvals > 0 ) |
460 | { |
bfa5b4f2 |
461 | int32_t i,nonz = 0; |
1bf82154 |
462 | for (i=0; i<32; i++) |
463 | if ( pvals[i] != 0 ) |
464 | nonz++; |
465 | if ( nonz >= 32 ) |
466 | { |
467 | fputc('V',fp); |
468 | if ( fwrite(&height,1,sizeof(height),fp) != sizeof(height) ) |
469 | errs++; |
470 | fputc(numpvals,fp); |
471 | if ( fwrite(pvals,sizeof(uint32_t),numpvals,fp) != numpvals ) |
472 | errs++; |
c75c18fc |
473 | komodo_eventadd_pricefeed(sp,symbol,height,pvals,numpvals); |
2578b002 |
474 | //printf("ht.%d V numpvals[%d]\n",height,numpvals); |
1bf82154 |
475 | } |
ef7a3548 |
476 | //printf("save pvals height.%d numpvals.%d\n",height,numpvals); |
4a41b0b2 |
477 | } |
6dabcca4 |
478 | else if ( height != 0 ) |
671187dd |
479 | { |
2578b002 |
480 | //printf("ht.%d func N ht.%d errs.%d\n",height,NOTARIZED_HEIGHT,errs); |
b148643e |
481 | if ( sp != 0 ) |
807200e4 |
482 | { |
b6e71fe9 |
483 | if ( sp->MoMdepth != 0 && sp->MoM != zero ) |
26f6fa01 |
484 | fputc('M',fp); |
485 | else fputc('N',fp); |
807200e4 |
486 | if ( fwrite(&height,1,sizeof(height),fp) != sizeof(height) ) |
487 | errs++; |
488 | if ( fwrite(&sp->NOTARIZED_HEIGHT,1,sizeof(sp->NOTARIZED_HEIGHT),fp) != sizeof(sp->NOTARIZED_HEIGHT) ) |
489 | errs++; |
490 | if ( fwrite(&sp->NOTARIZED_HASH,1,sizeof(sp->NOTARIZED_HASH),fp) != sizeof(sp->NOTARIZED_HASH) ) |
491 | errs++; |
492 | if ( fwrite(&sp->NOTARIZED_DESTTXID,1,sizeof(sp->NOTARIZED_DESTTXID),fp) != sizeof(sp->NOTARIZED_DESTTXID) ) |
493 | errs++; |
b6e71fe9 |
494 | if ( sp->MoMdepth != 0 && sp->MoM != zero ) |
18c6cfce |
495 | { |
496 | if ( fwrite(&sp->MoM,1,sizeof(sp->MoM),fp) != sizeof(sp->MoM) ) |
497 | errs++; |
498 | if ( fwrite(&sp->MoMdepth,1,sizeof(sp->MoMdepth),fp) != sizeof(sp->MoMdepth) ) |
499 | errs++; |
26f6fa01 |
500 | } |
501 | komodo_eventadd_notarized(sp,symbol,height,dest,sp->NOTARIZED_HASH,sp->NOTARIZED_DESTTXID,sp->NOTARIZED_HEIGHT,sp->MoM,sp->MoMdepth); |
807200e4 |
502 | } |
671187dd |
503 | } |
47f47733 |
504 | fflush(fp); |
bafc61f3 |
505 | } |
506 | } |
507 | |
c7a1d234 |
508 | int32_t komodo_validate_chain(uint256 srchash,int32_t notarized_height) |
509 | { |
cd29c830 |
510 | static int32_t last_rewind; int32_t rewindtarget; CBlockIndex *pindex; struct komodo_state *sp; char symbol[KOMODO_ASSETCHAIN_MAXLEN],dest[KOMODO_ASSETCHAIN_MAXLEN]; |
c7a1d234 |
511 | if ( (sp= komodo_stateptr(symbol,dest)) == 0 ) |
512 | return(0); |
76140489 |
513 | if ( IsInitialBlockDownload() == 0 && ((pindex= mapBlockIndex[srchash]) == 0 || pindex->nHeight != notarized_height) ) |
c7a1d234 |
514 | { |
76140489 |
515 | if ( sp->NOTARIZED_HEIGHT > 0 && sp->NOTARIZED_HEIGHT < notarized_height ) |
c7a1d234 |
516 | rewindtarget = sp->NOTARIZED_HEIGHT - 1; |
76140489 |
517 | else if ( notarized_height > 101 ) |
518 | rewindtarget = notarized_height - 101; |
c7a1d234 |
519 | else rewindtarget = 0; |
520 | if ( rewindtarget != 0 && rewindtarget > KOMODO_REWIND && rewindtarget > last_rewind ) |
521 | { |
522 | if ( last_rewind != 0 ) |
523 | { |
b8dd5290 |
524 | //KOMODO_REWIND = rewindtarget; |
76140489 |
525 | fprintf(stderr,"%s FORK detected. notarized.%d %s not in this chain! last notarization %d -> rewindtarget.%d\n",ASSETCHAINS_SYMBOL,notarized_height,srchash.ToString().c_str(),sp->NOTARIZED_HEIGHT,rewindtarget); |
c7a1d234 |
526 | } |
527 | last_rewind = rewindtarget; |
528 | } |
529 | return(0); |
530 | } else return(1); |
531 | } |
532 | |
8683bd8d |
533 | int32_t komodo_voutupdate(int32_t *isratificationp,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,uint64_t value,int32_t notarized,uint64_t signedmask,uint32_t timestamp) |
1390456b |
534 | { |
c96e160a |
535 | static uint256 zero; static FILE *signedfp; |
1bbbf487 |
536 | int32_t opretlen,nid,offset,k,MoMdepth,matched,len = 0; uint256 MoM,srchash,desttxid; uint8_t crypto777[33]; struct komodo_state *sp; char symbol[KOMODO_ASSETCHAIN_MAXLEN],dest[KOMODO_ASSETCHAIN_MAXLEN]; |
2df2f193 |
537 | if ( (sp= komodo_stateptr(symbol,dest)) == 0 ) |
538 | return(-1); |
9c406099 |
539 | if ( scriptlen == 35 && scriptbuf[0] == 33 && scriptbuf[34] == 0xac ) |
1390456b |
540 | { |
4d068367 |
541 | if ( i == 0 && j == 0 && memcmp(NOTARY_PUBKEY33,scriptbuf+1,33) == 0 && IS_KOMODO_NOTARY != 0 ) |
9152feb5 |
542 | { |
ba37a6b9 |
543 | printf("%s KOMODO_LASTMINED.%d -> %d\n",ASSETCHAINS_SYMBOL,KOMODO_LASTMINED,height); |
8ee93080 |
544 | prevKOMODO_LASTMINED = KOMODO_LASTMINED; |
9152feb5 |
545 | KOMODO_LASTMINED = height; |
546 | } |
c23dd601 |
547 | decode_hex(crypto777,33,(char *)CRYPTO777_PUBSECPSTR); |
986d3459 |
548 | /*for (k=0; k<33; k++) |
e1be360e |
549 | printf("%02x",crypto777[k]); |
550 | printf(" crypto777 "); |
551 | for (k=0; k<scriptlen; k++) |
552 | printf("%02x",scriptbuf[k]); |
986d3459 |
553 | printf(" <- script ht.%d i.%d j.%d cmp.%d\n",height,i,j,memcmp(crypto777,scriptbuf+1,33));*/ |
1390456b |
554 | if ( memcmp(crypto777,scriptbuf+1,33) == 0 ) |
555 | { |
556 | *specialtxp = 1; |
b7f942c8 |
557 | //printf(">>>>>>>> "); |
1390456b |
558 | } |
8683bd8d |
559 | else if ( komodo_chosennotary(&nid,height,scriptbuf + 1,timestamp) >= 0 ) |
1390456b |
560 | { |
84e843cd |
561 | //printf("found notary.k%d\n",k); |
562 | if ( notaryid < 64 ) |
1390456b |
563 | { |
84e843cd |
564 | if ( notaryid < 0 ) |
565 | { |
a5f315c7 |
566 | notaryid = nid; |
84e843cd |
567 | *voutmaskp |= (1LL << j); |
568 | } |
a5f315c7 |
569 | else if ( notaryid != nid ) |
84e843cd |
570 | { |
b7f942c8 |
571 | //for (i=0; i<33; i++) |
572 | // printf("%02x",scriptbuf[i+1]); |
573 | //printf(" %s mismatch notaryid.%d k.%d\n",ASSETCHAINS_SYMBOL,notaryid,nid); |
84e843cd |
574 | notaryid = 64; |
575 | *voutmaskp = 0; |
576 | } |
577 | else *voutmaskp |= (1LL << j); |
1390456b |
578 | } |
1390456b |
579 | } |
580 | } |
844a6138 |
581 | if ( scriptbuf[len++] == 0x6a ) |
1390456b |
582 | { |
eedb0249 |
583 | struct komodo_ccdata ccdata; struct komodo_ccdataMoMoM MoMoMdata; |
c7a1d234 |
584 | int32_t validated = 0,nameoffset,opoffset = 0; |
1390456b |
585 | if ( (opretlen= scriptbuf[len++]) == 0x4c ) |
586 | opretlen = scriptbuf[len++]; |
587 | else if ( opretlen == 0x4d ) |
588 | { |
589 | opretlen = scriptbuf[len++]; |
508b0d3c |
590 | opretlen += (scriptbuf[len++] << 8); |
1390456b |
591 | } |
a730ab12 |
592 | opoffset = len; |
a490f905 |
593 | matched = 0; |
594 | if ( ASSETCHAINS_SYMBOL[0] == 0 ) |
595 | { |
e621c0a3 |
596 | if ( strcmp("KMD",(char *)&scriptbuf[len+32 * 2 + 4]) == 0 ) |
a490f905 |
597 | matched = 1; |
598 | } |
599 | else |
600 | { |
93b144ac |
601 | if ( scriptbuf[len] == 'K' ) |
602 | { |
603 | fprintf(stderr,"i.%d j.%d KV OPRET len.%d %.8f\n",i,j,opretlen,dstr(value)); |
604 | komodo_stateupdate(height,0,0,0,txhash,0,0,0,0,0,0,value,&scriptbuf[len],opretlen,j,zero,0); |
605 | return(-1); |
606 | } |
835c1c02 |
607 | if ( strcmp(ASSETCHAINS_SYMBOL,(char *)&scriptbuf[len+32*2+4]) == 0 ) |
a490f905 |
608 | matched = 1; |
609 | } |
1bbbf487 |
610 | offset = 32 * (1 + matched) + 4; |
d24efb03 |
611 | nameoffset = (int32_t)strlen((char *)&scriptbuf[len+offset]); |
4a15f78e |
612 | nameoffset++; |
eedb0249 |
613 | memset(&ccdata,0,sizeof(ccdata)); |
614 | strncpy(ccdata.symbol,(char *)&scriptbuf[len+offset],sizeof(ccdata.symbol)); |
a730ab12 |
615 | if ( j == 1 && opretlen >= len+offset-opoffset ) |
1390456b |
616 | { |
d269d79e |
617 | memset(&MoMoMdata,0,sizeof(MoMoMdata)); |
90993cdb |
618 | if ( matched == 0 && bitweight(signedmask) >= KOMODO_MINRATIFY ) |
619 | notarized = 1; |
e7018d1d |
620 | if ( strcmp("PIZZA",ccdata.symbol) == 0 || strncmp("TXSCL",ccdata.symbol,5) == 0 ) |
a490f905 |
621 | notarized = 1; |
874106bf |
622 | if ( 0 && opretlen != 149 ) |
a730ab12 |
623 | printf("[%s].%d (%s) matched.%d i.%d j.%d notarized.%d %llx opretlen.%d len.%d offset.%d opoffset.%d\n",ASSETCHAINS_SYMBOL,height,ccdata.symbol,matched,i,j,notarized,(long long)signedmask,opretlen,len,offset,opoffset); |
6a933d59 |
624 | len += iguana_rwbignum(0,&scriptbuf[len],32,(uint8_t *)&srchash); |
dbaf1154 |
625 | len += iguana_rwnum(0,&scriptbuf[len],sizeof(*notarizedheightp),(uint8_t *)notarizedheightp); |
1bbbf487 |
626 | if ( matched != 0 ) |
627 | len += iguana_rwbignum(0,&scriptbuf[len],32,(uint8_t *)&desttxid); |
c7a1d234 |
628 | if ( matched != 0 ) |
629 | validated = komodo_validate_chain(srchash,*notarizedheightp); |
630 | else validated = 1; |
ae9fc2a3 |
631 | if ( notarized != 0 && validated != 0 ) |
1390456b |
632 | { |
195c2e16 |
633 | //sp->NOTARIZED_HEIGHT = *notarizedheightp; |
634 | //sp->NOTARIZED_HASH = srchash; |
635 | //sp->NOTARIZED_DESTTXID = desttxid; |
636 | memset(&MoM,0,sizeof(MoM)); |
637 | MoMdepth = 0; |
713c2a94 |
638 | len += nameoffset; |
d269d79e |
639 | ccdata.MoMdata.notarized_height = *notarizedheightp; |
640 | ccdata.MoMdata.height = height; |
641 | ccdata.MoMdata.txi = i; |
4a15f78e |
642 | //printf("nameoffset.%d len.%d + 36 %d opoffset.%d vs opretlen.%d\n",nameoffset,len,len+36,opoffset,opretlen); |
a730ab12 |
643 | if ( len+36-opoffset <= opretlen ) |
18c6cfce |
644 | { |
195c2e16 |
645 | len += iguana_rwbignum(0,&scriptbuf[len],32,(uint8_t *)&MoM); |
646 | len += iguana_rwnum(0,&scriptbuf[len],sizeof(MoMdepth),(uint8_t *)&MoMdepth); |
d269d79e |
647 | ccdata.MoMdata.MoM = MoM; |
b6e71fe9 |
648 | ccdata.MoMdata.MoMdepth = MoMdepth & 0xffff; |
835c1c02 |
649 | if ( len+sizeof(ccdata.CCid)-opoffset <= opretlen ) |
713c2a94 |
650 | { |
651 | len += iguana_rwnum(0,&scriptbuf[len],sizeof(ccdata.CCid),(uint8_t *)&ccdata.CCid); |
627aaf73 |
652 | //if ( ((MoMdepth>>16) & 0xffff) != (ccdata.CCid & 0xffff) ) |
653 | // fprintf(stderr,"%s CCid mismatch %u != %u\n",ASSETCHAINS_SYMBOL,((MoMdepth>>16) & 0xffff),(ccdata.CCid & 0xffff)); |
713c2a94 |
654 | ccdata.len = sizeof(ccdata.CCid); |
655 | if ( ASSETCHAINS_SYMBOL[0] != 0 ) |
656 | { |
657 | // MoMoM, depth, numpairs, (notarization ht, MoMoM offset) |
51dab149 |
658 | if ( len+48-opoffset <= opretlen && strcmp(ccdata.symbol,ASSETCHAINS_SYMBOL) == 0 ) |
713c2a94 |
659 | { |
51dab149 |
660 | len += iguana_rwnum(0,&scriptbuf[len],sizeof(uint32_t),(uint8_t *)&MoMoMdata.kmdstarti); |
661 | len += iguana_rwnum(0,&scriptbuf[len],sizeof(uint32_t),(uint8_t *)&MoMoMdata.kmdendi); |
090b1c9f |
662 | len += iguana_rwbignum(0,&scriptbuf[len],sizeof(MoMoMdata.MoMoM),(uint8_t *)&MoMoMdata.MoMoM); |
51dab149 |
663 | len += iguana_rwnum(0,&scriptbuf[len],sizeof(uint32_t),(uint8_t *)&MoMoMdata.MoMoMdepth); |
d269d79e |
664 | len += iguana_rwnum(0,&scriptbuf[len],sizeof(uint32_t),(uint8_t *)&MoMoMdata.numpairs); |
51dab149 |
665 | MoMoMdata.len += sizeof(MoMoMdata.MoMoM) + sizeof(uint32_t)*4; |
d269d79e |
666 | if ( len+MoMoMdata.numpairs*8-opoffset == opretlen ) |
713c2a94 |
667 | { |
d269d79e |
668 | MoMoMdata.pairs = (struct komodo_ccdatapair *)calloc(MoMoMdata.numpairs,sizeof(*MoMoMdata.pairs)); |
669 | for (k=0; k<MoMoMdata.numpairs; k++) |
713c2a94 |
670 | { |
d67bdfe9 |
671 | len += iguana_rwnum(0,&scriptbuf[len],sizeof(int32_t),(uint8_t *)&MoMoMdata.pairs[k].notarized_height); |
d269d79e |
672 | len += iguana_rwnum(0,&scriptbuf[len],sizeof(uint32_t),(uint8_t *)&MoMoMdata.pairs[k].MoMoMoffset); |
673 | MoMoMdata.len += sizeof(uint32_t) * 2; |
713c2a94 |
674 | } |
d269d79e |
675 | } else ccdata.len = MoMoMdata.len = 0; |
676 | } else ccdata.len = MoMoMdata.len = 0; |
713c2a94 |
677 | } |
678 | } |
b6e71fe9 |
679 | if ( MoM == zero || (MoMdepth&0xffff) > *notarizedheightp || (MoMdepth&0xffff) < 0 ) |
18c6cfce |
680 | { |
195c2e16 |
681 | memset(&MoM,0,sizeof(MoM)); |
682 | MoMdepth = 0; |
18c6cfce |
683 | } |
684 | else |
685 | { |
26f6fa01 |
686 | komodo_rwccdata(ASSETCHAINS_SYMBOL,1,&ccdata,&MoMoMdata); |
8fc79ac9 |
687 | if ( matched != 0 ) |
b6e71fe9 |
688 | printf("[%s] matched.%d VALID (%s) MoM.%s [%d] CCid.%u\n",ASSETCHAINS_SYMBOL,matched,ccdata.symbol,MoM.ToString().c_str(),MoMdepth&0xffff,(MoMdepth>>16)&0xffff); |
18c6cfce |
689 | } |
c0d01b7d |
690 | if ( MoMoMdata.pairs != 0 ) |
691 | free(MoMoMdata.pairs); |
713c2a94 |
692 | memset(&ccdata,0,sizeof(ccdata)); |
c0d01b7d |
693 | memset(&MoMoMdata,0,sizeof(MoMoMdata)); |
18c6cfce |
694 | } |
26f6fa01 |
695 | else if ( ASSETCHAINS_SYMBOL[0] == 0 && matched != 0 && notarized != 0 && validated != 0 ) |
696 | komodo_rwccdata((char *)"KMD",1,&ccdata,0); |
68e359a4 |
697 | if ( matched != 0 && *notarizedheightp > sp->NOTARIZED_HEIGHT && *notarizedheightp < height ) |
06d1a655 |
698 | { |
195c2e16 |
699 | sp->NOTARIZED_HEIGHT = *notarizedheightp; |
700 | sp->NOTARIZED_HASH = srchash; |
701 | sp->NOTARIZED_DESTTXID = desttxid; |
b6e71fe9 |
702 | if ( MoM != zero && (MoMdepth&0xffff) > 0 ) |
a34f39e9 |
703 | { |
704 | sp->MoM = MoM; |
705 | sp->MoMdepth = MoMdepth; |
706 | } |
195c2e16 |
707 | komodo_stateupdate(height,0,0,0,zero,0,0,0,0,0,0,0,0,0,0,sp->MoM,sp->MoMdepth); |
5c888905 |
708 | if ( ASSETCHAINS_SYMBOL[0] != 0 ) |
195c2e16 |
709 | printf("[%s] ht.%d NOTARIZED.%d %s.%s %sTXID.%s lens.(%d %d) MoM.%s %d\n",ASSETCHAINS_SYMBOL,height,*notarizedheightp,ASSETCHAINS_SYMBOL[0]==0?"KMD":ASSETCHAINS_SYMBOL,srchash.ToString().c_str(),ASSETCHAINS_SYMBOL[0]==0?"BTC":"KMD",desttxid.ToString().c_str(),opretlen,len,sp->MoM.ToString().c_str(),sp->MoMdepth); |
710 | if ( ASSETCHAINS_SYMBOL[0] == 0 ) |
dbaf1154 |
711 | { |
195c2e16 |
712 | if ( signedfp == 0 ) |
713 | { |
714 | char fname[512]; |
715 | komodo_statefname(fname,ASSETCHAINS_SYMBOL,(char *)"signedmasks"); |
716 | if ( (signedfp= fopen(fname,"rb+")) == 0 ) |
717 | signedfp = fopen(fname,"wb"); |
718 | else fseek(signedfp,0,SEEK_END); |
719 | } |
720 | if ( signedfp != 0 ) |
721 | { |
722 | fwrite(&height,1,sizeof(height),signedfp); |
723 | fwrite(&signedmask,1,sizeof(signedmask),signedfp); |
724 | fflush(signedfp); |
725 | } |
dd801e5d |
726 | if ( opretlen > len && scriptbuf[len] == 'A' ) |
727 | { |
728 | //for (i=0; i<opretlen-len; i++) |
729 | // printf("%02x",scriptbuf[len+i]); |
730 | //printf(" Found extradata.[%d] %d - %d\n",opretlen-len,opretlen,len); |
731 | komodo_stateupdate(height,0,0,0,txhash,0,0,0,0,0,0,value,&scriptbuf[len],opretlen-len+4+3+(scriptbuf[1] == 0x4d),j,zero,0); |
732 | } |
dbaf1154 |
733 | } |
06d1a655 |
734 | } |
3e34f0a6 |
735 | } else if ( opretlen != 149 && height > 600000 && matched != 0 ) |
eedb0249 |
736 | printf("%s validated.%d notarized.%d %llx reject ht.%d NOTARIZED.%d prev.%d %s.%s DESTTXID.%s len.%d opretlen.%d\n",ccdata.symbol,validated,notarized,(long long)signedmask,height,*notarizedheightp,sp->NOTARIZED_HEIGHT,ASSETCHAINS_SYMBOL[0]==0?"KMD":ASSETCHAINS_SYMBOL,srchash.ToString().c_str(),desttxid.ToString().c_str(),len,opretlen); |
1390456b |
737 | } |
1bbbf487 |
738 | else if ( matched != 0 && i == 0 && j == 1 && opretlen == 149 ) |
d42d3348 |
739 | { |
76b9b8b8 |
740 | if ( notaryid >= 0 && notaryid < 64 ) |
d42d3348 |
741 | komodo_paxpricefeed(height,&scriptbuf[len],opretlen); |
742 | } |
1bbbf487 |
743 | else if ( matched != 0 ) |
eb406ebd |
744 | { |
cd586654 |
745 | //int32_t k; for (k=0; k<scriptlen; k++) |
746 | // printf("%02x",scriptbuf[k]); |
747 | //printf(" <- script ht.%d i.%d j.%d value %.8f %s\n",height,i,j,dstr(value),ASSETCHAINS_SYMBOL); |
6dba48ec |
748 | if ( opretlen >= 32*2+4 && strcmp(ASSETCHAINS_SYMBOL[0]==0?"KMD":ASSETCHAINS_SYMBOL,(char *)&scriptbuf[len+32*2+4]) == 0 ) |
749 | { |
5a286a6f |
750 | for (k=0; k<32; k++) |
751 | if ( scriptbuf[len+k] != 0 ) |
752 | break; |
753 | if ( k == 32 ) |
6dba48ec |
754 | { |
755 | *isratificationp = 1; |
756 | printf("ISRATIFICATION (%s)\n",(char *)&scriptbuf[len+32*2+4]); |
757 | } |
758 | } |
8f3aa743 |
759 | |
c9e4d982 |
760 | if ( *isratificationp == 0 && (signedmask != 0 || (scriptbuf[len] != 'X' && scriptbuf[len] != 'A')) ) // && scriptbuf[len] != 'I') |
093f2730 |
761 | komodo_stateupdate(height,0,0,0,txhash,0,0,0,0,0,0,value,&scriptbuf[len],opretlen,j,zero,0); |
eb406ebd |
762 | } |
1390456b |
763 | } |
764 | return(notaryid); |
765 | } |
766 | |
58033467 |
767 | /*int32_t komodo_isratify(int32_t isspecial,int32_t numvalid) |
f38345e9 |
768 | { |
755ead98 |
769 | if ( isspecial != 0 && numvalid >= KOMODO_MINRATIFY ) |
f38345e9 |
770 | return(1); |
771 | else return(0); |
58033467 |
772 | }*/ |
f38345e9 |
773 | |
774 | // Special tx have vout[0] -> CRYPTO777 |
755ead98 |
775 | // with more than KOMODO_MINRATIFY pay2pubkey outputs -> ratify |
f38345e9 |
776 | // if all outputs to notary -> notary utxo |
777 | // if txi == 0 && 2 outputs and 2nd OP_RETURN, len == 32*2+4 -> notarized, 1st byte 'P' -> pricefeed |
420d7311 |
778 | // OP_RETURN: 'D' -> deposit, 'W' -> withdraw |
ab918767 |
779 | |
6f3cb4d0 |
780 | int32_t gettxout_scriptPubKey(uint8_t *scriptPubKey,int32_t maxsize,uint256 txid,int32_t n); |
781 | |
782 | int32_t komodo_notarycmp(uint8_t *scriptPubKey,int32_t scriptlen,uint8_t pubkeys[64][33],int32_t numnotaries,uint8_t rmd160[20]) |
783 | { |
784 | int32_t i; |
785 | if ( scriptlen == 25 && memcmp(&scriptPubKey[3],rmd160,20) == 0 ) |
786 | return(0); |
787 | else if ( scriptlen == 35 ) |
788 | { |
789 | for (i=0; i<numnotaries; i++) |
790 | if ( memcmp(&scriptPubKey[1],pubkeys[i],33) == 0 ) |
791 | return(i); |
792 | } |
793 | return(-1); |
794 | } |
f38345e9 |
795 | |
651989c7 |
796 | void komodo_connectblock(CBlockIndex *pindex,CBlock& block) |
50027f06 |
797 | { |
a7f0d3e4 |
798 | static int32_t hwmheight; |
7c130297 |
799 | uint64_t signedmask,voutmask; char symbol[KOMODO_ASSETCHAIN_MAXLEN],dest[KOMODO_ASSETCHAIN_MAXLEN]; struct komodo_state *sp; |
6a933d59 |
800 | uint8_t scriptbuf[10001],pubkeys[64][33],rmd160[20],scriptPubKey[35]; uint256 zero,btctxid,txhash; |
ea365a71 |
801 | int32_t i,j,k,numnotaries,notarized,scriptlen,isratification,nid,numvalid,specialtx,notarizedheight,notaryid,len,numvouts,numvins,height,txn_count; |
878d3961 |
802 | memset(&zero,0,sizeof(zero)); |
c93dc546 |
803 | komodo_init(pindex->nHeight); |
d7227bf6 |
804 | KOMODO_INITDONE = (uint32_t)time(NULL); |
ab918767 |
805 | if ( (sp= komodo_stateptr(symbol,dest)) == 0 ) |
3df53390 |
806 | { |
807 | fprintf(stderr,"unexpected null komodostateptr.[%s]\n",ASSETCHAINS_SYMBOL); |
ab918767 |
808 | return; |
3df53390 |
809 | } |
e0440cc3 |
810 | //fprintf(stderr,"%s connect.%d\n",ASSETCHAINS_SYMBOL,pindex->nHeight); |
85ef725a |
811 | numnotaries = komodo_notaries(pubkeys,pindex->nHeight,pindex->GetBlockTime()); |
6f3cb4d0 |
812 | calc_rmd160_sha256(rmd160,pubkeys[0],33); |
a7f0d3e4 |
813 | if ( pindex->nHeight > hwmheight ) |
814 | hwmheight = pindex->nHeight; |
815 | else |
816 | { |
174cae41 |
817 | if ( pindex->nHeight != hwmheight ) |
dfd07d78 |
818 | { |
174cae41 |
819 | printf("%s hwmheight.%d vs pindex->nHeight.%d t.%u reorg.%d\n",ASSETCHAINS_SYMBOL,hwmheight,pindex->nHeight,(uint32_t)pindex->nTime,hwmheight-pindex->nHeight); |
dfd07d78 |
820 | komodo_purge_ccdata((int32_t)pindex->nHeight); |
821 | hwmheight = pindex->nHeight; |
822 | } |
ab918767 |
823 | komodo_event_rewind(sp,symbol,pindex->nHeight); |
093f2730 |
824 | komodo_stateupdate(pindex->nHeight,0,0,0,zero,0,0,0,0,-pindex->nHeight,pindex->nTime,0,0,0,0,zero,0); |
a7f0d3e4 |
825 | } |
86131275 |
826 | komodo_currentheight_set(chainActive.LastTip()->nHeight); |
68916cc6 |
827 | if ( pindex != 0 ) |
b501ded2 |
828 | { |
656eddcd |
829 | height = pindex->nHeight; |
01cc012f |
830 | txn_count = block.vtx.size(); |
831 | for (i=0; i<txn_count; i++) |
dc64de68 |
832 | { |
352f8081 |
833 | txhash = block.vtx[i].GetHash(); |
01cc012f |
834 | numvouts = block.vtx[i].vout.size(); |
352f8081 |
835 | notaryid = -1; |
ea365a71 |
836 | voutmask = specialtx = notarizedheight = isratification = notarized = 0; |
517b1691 |
837 | signedmask = (height < 91400) ? 1 : 0; |
ea365a71 |
838 | numvins = block.vtx[i].vin.size(); |
839 | for (j=0; j<numvins; j++) |
840 | { |
69383c9f |
841 | if ( i == 0 && j == 0 ) |
842 | continue; |
ea365a71 |
843 | if ( (scriptlen= gettxout_scriptPubKey(scriptPubKey,sizeof(scriptPubKey),block.vtx[i].vin[j].prevout.hash,block.vtx[i].vin[j].prevout.n)) > 0 ) |
844 | { |
845 | if ( (k= komodo_notarycmp(scriptPubKey,scriptlen,pubkeys,numnotaries,rmd160)) >= 0 ) |
846 | signedmask |= (1LL << k); |
c7918614 |
847 | else if ( 0 && numvins >= 17 ) |
bb1963ca |
848 | { |
849 | int32_t k; |
850 | for (k=0; k<scriptlen; k++) |
851 | printf("%02x",scriptPubKey[k]); |
57d9cfcc |
852 | printf(" scriptPubKey doesnt match any notary vini.%d of %d\n",j,numvins); |
bb1963ca |
853 | } |
854 | } else printf("cant get scriptPubKey for ht.%d txi.%d vin.%d\n",height,i,j); |
ea365a71 |
855 | } |
e6d7eca6 |
856 | numvalid = bitweight(signedmask); |
ee5e8026 |
857 | if ( (((height < 90000 || (signedmask & 1) != 0) && numvalid >= KOMODO_MINRATIFY) || |
858 | (numvalid >= KOMODO_MINRATIFY && ASSETCHAINS_SYMBOL[0] != 0) || |
859 | numvalid > (numnotaries/5)) ) |
ea365a71 |
860 | { |
f1d6fb9b |
861 | if ( ASSETCHAINS_SYMBOL[0] != 0 ) |
862 | { |
863 | static FILE *signedfp; |
864 | if ( signedfp == 0 ) |
865 | { |
866 | char fname[512]; |
867 | komodo_statefname(fname,ASSETCHAINS_SYMBOL,(char *)"signedmasks"); |
868 | if ( (signedfp= fopen(fname,"rb+")) == 0 ) |
869 | signedfp = fopen(fname,"wb"); |
870 | else fseek(signedfp,0,SEEK_END); |
871 | } |
872 | if ( signedfp != 0 ) |
873 | { |
874 | fwrite(&height,1,sizeof(height),signedfp); |
875 | fwrite(&signedmask,1,sizeof(signedmask),signedfp); |
876 | fflush(signedfp); |
877 | } |
1132e845 |
878 | printf("[%s] ht.%d txi.%d signedmask.%llx numvins.%d numvouts.%d <<<<<<<<<<< notarized\n",ASSETCHAINS_SYMBOL,height,i,(long long)signedmask,numvins,numvouts); |
f1d6fb9b |
879 | } |
ea365a71 |
880 | notarized = 1; |
881 | } |
4d068367 |
882 | if ( IS_KOMODO_NOTARY != 0 && ASSETCHAINS_SYMBOL[0] == 0 ) |
9e5fc6d7 |
883 | printf("(tx.%d: ",i); |
01cc012f |
884 | for (j=0; j<numvouts; j++) |
dc64de68 |
885 | { |
081ab21c |
886 | /*if ( i == 0 && j == 0 ) |
6615cec9 |
887 | { |
888 | uint8_t *script = (uint8_t *)block.vtx[0].vout[numvouts-1].scriptPubKey.data(); |
889 | if ( numvouts <= 2 || script[0] != 0x6a ) |
890 | { |
891 | if ( numvouts == 2 && block.vtx[0].vout[1].nValue != 0 ) |
892 | { |
893 | fprintf(stderr,"ht.%d numvouts.%d value %.8f\n",height,numvouts,dstr(block.vtx[0].vout[1].nValue)); |
49508d3c |
894 | if ( height >= 235300 && block.vtx[0].vout[1].nValue >= 100000*COIN ) |
6615cec9 |
895 | block.vtx[0].vout[1].nValue = 0; |
896 | break; |
897 | } |
898 | } |
081ab21c |
899 | }*/ |
4d068367 |
900 | if ( IS_KOMODO_NOTARY != 0 && ASSETCHAINS_SYMBOL[0] == 0 ) |
9e5fc6d7 |
901 | printf("%.8f ",dstr(block.vtx[i].vout[j].nValue)); |
1390456b |
902 | len = block.vtx[i].vout[j].scriptPubKey.size(); |
97561034 |
903 | if ( len >= sizeof(uint32_t) && len <= sizeof(scriptbuf) ) |
01cc012f |
904 | { |
189d9dee |
905 | #ifdef KOMODO_ZCASH |
484f8777 |
906 | memcpy(scriptbuf,block.vtx[i].vout[j].scriptPubKey.data(),len); |
189d9dee |
907 | #else |
908 | memcpy(scriptbuf,(uint8_t *)&block.vtx[i].vout[j].scriptPubKey[0],len); |
909 | #endif |
86131275 |
910 | notaryid = komodo_voutupdate(&isratification,notaryid,scriptbuf,len,height,txhash,i,j,&voutmask,&specialtx,¬arizedheight,(uint64_t)block.vtx[i].vout[j].nValue,notarized,signedmask,(uint32_t)chainActive.LastTip()->GetBlockTime()); |
a01acef4 |
911 | if ( 0 && i > 0 ) |
e69a0833 |
912 | { |
913 | for (k=0; k<len; k++) |
914 | printf("%02x",scriptbuf[k]); |
a8832194 |
915 | 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 |
916 | } |
01cc012f |
917 | } |
352f8081 |
918 | } |
4d068367 |
919 | if ( IS_KOMODO_NOTARY != 0 && ASSETCHAINS_SYMBOL[0] == 0 ) |
9e5fc6d7 |
920 | printf(") "); |
05c1e522 |
921 | if ( 0 && ASSETCHAINS_SYMBOL[0] == 0 ) |
0b27cefa |
922 | printf("[%s] ht.%d txi.%d signedmask.%llx numvins.%d numvouts.%d notarized.%d special.%d isratification.%d\n",ASSETCHAINS_SYMBOL,height,i,(long long)signedmask,numvins,numvouts,notarized,specialtx,isratification); |
ea365a71 |
923 | if ( notarized != 0 && (notarizedheight != 0 || specialtx != 0) ) |
1390456b |
924 | { |
b338ea90 |
925 | if ( isratification != 0 ) |
926 | { |
927 | printf("%s NOTARY SIGNED.%llx numvins.%d ht.%d txi.%d notaryht.%d specialtx.%d\n",ASSETCHAINS_SYMBOL,(long long)signedmask,numvins,height,i,notarizedheight,specialtx); |
928 | printf("ht.%d specialtx.%d isratification.%d numvouts.%d signed.%llx numnotaries.%d\n",height,specialtx,isratification,numvouts,(long long)signedmask,numnotaries); |
929 | } |
d2a115d8 |
930 | if ( specialtx != 0 && isratification != 0 && numvouts > 2 ) |
84e843cd |
931 | { |
29e69b85 |
932 | numvalid = 0; |
dd7b22ad |
933 | memset(pubkeys,0,sizeof(pubkeys)); |
6dba48ec |
934 | for (j=1; j<numvouts-1; j++) |
84e843cd |
935 | { |
936 | len = block.vtx[i].vout[j].scriptPubKey.size(); |
0554de3c |
937 | if ( len >= sizeof(uint32_t) && len <= sizeof(scriptbuf) ) |
84e843cd |
938 | { |
189d9dee |
939 | #ifdef KOMODO_ZCASH |
484f8777 |
940 | memcpy(scriptbuf,block.vtx[i].vout[j].scriptPubKey.data(),len); |
189d9dee |
941 | #else |
942 | memcpy(scriptbuf,(uint8_t *)&block.vtx[i].vout[j].scriptPubKey[0],len); |
943 | #endif |
84e843cd |
944 | if ( len == 35 && scriptbuf[0] == 33 && scriptbuf[34] == 0xac ) |
945 | { |
29e69b85 |
946 | memcpy(pubkeys[numvalid++],scriptbuf+1,33); |
e7f99312 |
947 | for (k=0; k<33; k++) |
84e843cd |
948 | printf("%02x",scriptbuf[k+1]); |
949 | printf(" <- new notary.[%d]\n",j-1); |
950 | } |
951 | } |
952 | } |
aa114a60 |
953 | if ( ((signedmask & 1) != 0 && numvalid >= KOMODO_MINRATIFY) || bitweight(signedmask) > (numnotaries/3) ) |
d8ce705a |
954 | { |
955 | memset(&txhash,0,sizeof(txhash)); |
093f2730 |
956 | komodo_stateupdate(height,pubkeys,numvalid,0,txhash,0,0,0,0,0,0,0,0,0,0,zero,0); |
f9d034d4 |
957 | printf("RATIFIED! >>>>>>>>>> new notaries.%d newheight.%d from height.%d\n",numvalid,(((height+KOMODO_ELECTION_GAP/2)/KOMODO_ELECTION_GAP)+1)*KOMODO_ELECTION_GAP,height); |
6423c8a9 |
958 | } else printf("signedmask.%llx numvalid.%d wt.%d numnotaries.%d\n",(long long)signedmask,numvalid,bitweight(signedmask),numnotaries); |
84e843cd |
959 | } |
a96439f5 |
960 | } |
656eddcd |
961 | } |
4d068367 |
962 | if ( IS_KOMODO_NOTARY != 0 && ASSETCHAINS_SYMBOL[0] == 0 ) |
ac93bb3e |
963 | printf("%s ht.%d\n",ASSETCHAINS_SYMBOL[0] == 0 ? "KMD" : ASSETCHAINS_SYMBOL,height); |
e155dbe9 |
964 | if ( pindex->nHeight == hwmheight ) |
093f2730 |
965 | komodo_stateupdate(height,0,0,0,zero,0,0,0,0,height,(uint32_t)pindex->nTime,0,0,0,0,zero,0); |
3df53390 |
966 | } else fprintf(stderr,"komodo_connectblock: unexpected null pindex\n"); |
17899df4 |
967 | //KOMODO_INITDONE = (uint32_t)time(NULL); |
dd42fd9b |
968 | //fprintf(stderr,"%s end connect.%d\n",ASSETCHAINS_SYMBOL,pindex->nHeight); |
3d35aa5b |
969 | } |
970 | |
0f24f245 |
971 | |
fcd36118 |
972 | #endif |