]> Git Repo - VerusCoin.git/blame - src/komodo_bitcoind.h
Add GPU miners
[VerusCoin.git] / src / komodo_bitcoind.h
CommitLineData
d019c447 1/******************************************************************************
713c2a94 2 * Copyright © 2014-2018 The SuperNET Developers. *
d019c447 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
3eea72f2 16// komodo functions that interact with bitcoind C++
17
9b0e1808 18#ifdef _WIN32
9d365796 19#include <curl/curl.h>
20#include <curl/easy.h>
9b0e1808 21#else
22#include <curl/curl.h>
23#include <curl/easy.h>
24#endif
25
5416af1d 26#include "komodo_defs.h"
27
c615ffff 28int32_t komodo_notaries(uint8_t pubkeys[64][33],int32_t height,uint32_t timestamp);
29int32_t komodo_electednotary(int32_t *numnotariesp,uint8_t *pubkey33,int32_t height,uint32_t timestamp);
30
36c733e9 31//#define issue_curl(cmdstr) bitcoind_RPC(0,(char *)"curl",(char *)"http://127.0.0.1:7776",0,0,(char *)(cmdstr))
77be6cd9 32
9b0e1808 33struct MemoryStruct { char *memory; size_t size; };
c2b50ce0 34struct return_string { char *ptr; size_t len; };
35
36// return data from the server
37#define CURL_GLOBAL_ALL (CURL_GLOBAL_SSL|CURL_GLOBAL_WIN32)
38#define CURL_GLOBAL_SSL (1<<0)
39#define CURL_GLOBAL_WIN32 (1<<1)
40
41
4ec67e74 42/************************************************************************
43 *
44 * Initialize the string handler so that it is thread safe
45 *
46 ************************************************************************/
47
48void init_string(struct return_string *s)
49{
50 s->len = 0;
51 s->ptr = (char *)calloc(1,s->len+1);
52 if ( s->ptr == NULL )
53 {
54 fprintf(stderr,"init_string malloc() failed\n");
55 exit(-1);
56 }
57 s->ptr[0] = '\0';
58}
c2b50ce0 59
4ec67e74 60/************************************************************************
61 *
62 * Use the "writer" to accumulate text until done
63 *
64 ************************************************************************/
65
66size_t accumulatebytes(void *ptr,size_t size,size_t nmemb,struct return_string *s)
67{
68 size_t new_len = s->len + size*nmemb;
69 s->ptr = (char *)realloc(s->ptr,new_len+1);
70 if ( s->ptr == NULL )
71 {
72 fprintf(stderr, "accumulate realloc() failed\n");
73 exit(-1);
74 }
75 memcpy(s->ptr+s->len,ptr,size*nmemb);
76 s->ptr[new_len] = '\0';
77 s->len = new_len;
78 return(size * nmemb);
79}
c2b50ce0 80
81/************************************************************************
82 *
83 * return the current system time in milliseconds
84 *
85 ************************************************************************/
86
87#define EXTRACT_BITCOIND_RESULT // if defined, ensures error is null and returns the "result" field
88#ifdef EXTRACT_BITCOIND_RESULT
89
90/************************************************************************
91 *
92 * perform post processing of the results
93 *
94 ************************************************************************/
95
96char *post_process_bitcoind_RPC(char *debugstr,char *command,char *rpcstr,char *params)
97{
98 long i,j,len; char *retstr = 0; cJSON *json,*result,*error;
99 //printf("<<<<<<<<<<< bitcoind_RPC: %s post_process_bitcoind_RPC.%s.[%s]\n",debugstr,command,rpcstr);
100 if ( command == 0 || rpcstr == 0 || rpcstr[0] == 0 )
101 {
102 if ( strcmp(command,"signrawtransaction") != 0 )
103 printf("<<<<<<<<<<< bitcoind_RPC: %s post_process_bitcoind_RPC.%s.[%s]\n",debugstr,command,rpcstr);
104 return(rpcstr);
105 }
106 json = cJSON_Parse(rpcstr);
107 if ( json == 0 )
108 {
109 printf("<<<<<<<<<<< bitcoind_RPC: %s post_process_bitcoind_RPC.%s can't parse.(%s) params.(%s)\n",debugstr,command,rpcstr,params);
110 free(rpcstr);
111 return(0);
112 }
113 result = cJSON_GetObjectItem(json,"result");
114 error = cJSON_GetObjectItem(json,"error");
115 if ( error != 0 && result != 0 )
116 {
117 if ( (error->type&0xff) == cJSON_NULL && (result->type&0xff) != cJSON_NULL )
118 {
119 retstr = cJSON_Print(result);
120 len = strlen(retstr);
121 if ( retstr[0] == '"' && retstr[len-1] == '"' )
122 {
123 for (i=1,j=0; i<len-1; i++,j++)
124 retstr[j] = retstr[i];
125 retstr[j] = 0;
126 }
127 }
128 else if ( (error->type&0xff) != cJSON_NULL || (result->type&0xff) != cJSON_NULL )
129 {
130 if ( strcmp(command,"signrawtransaction") != 0 )
131 printf("<<<<<<<<<<< bitcoind_RPC: %s post_process_bitcoind_RPC (%s) error.%s\n",debugstr,command,rpcstr);
132 }
133 free(rpcstr);
134 } else retstr = rpcstr;
135 free_json(json);
136 //fprintf(stderr,"<<<<<<<<<<< bitcoind_RPC: postprocess returns.(%s)\n",retstr);
137 return(retstr);
138}
139#endif
140
141/************************************************************************
142 *
143 * perform the query
144 *
145 ************************************************************************/
146
c2b50ce0 147char *bitcoind_RPC(char **retstrp,char *debugstr,char *url,char *userpass,char *command,char *params)
148{
149 static int didinit,count,count2; static double elapsedsum,elapsedsum2;
150 struct curl_slist *headers = NULL; struct return_string s; CURLcode res; CURL *curl_handle;
151 char *bracket0,*bracket1,*databuf = 0; long len; int32_t specialcase,numretries; double starttime;
152 if ( didinit == 0 )
153 {
154 didinit = 1;
155 curl_global_init(CURL_GLOBAL_ALL); //init the curl session
156 }
157 numretries = 0;
158 if ( debugstr != 0 && strcmp(debugstr,"BTCD") == 0 && command != 0 && strcmp(command,"SuperNET") == 0 )
159 specialcase = 1;
160 else specialcase = 0;
161 if ( url[0] == 0 )
162 strcpy(url,"http://127.0.0.1:7876/nxt");
163 if ( specialcase != 0 && 0 )
164 printf("<<<<<<<<<<< bitcoind_RPC: debug.(%s) url.(%s) command.(%s) params.(%s)\n",debugstr,url,command,params);
165try_again:
166 if ( retstrp != 0 )
167 *retstrp = 0;
168 starttime = OS_milliseconds();
169 curl_handle = curl_easy_init();
170 init_string(&s);
171 headers = curl_slist_append(0,"Expect:");
f796b1fb 172
173 curl_easy_setopt(curl_handle,CURLOPT_USERAGENT,"mozilla/4.0");//"Mozilla/4.0 (compatible; )");
c2b50ce0 174 curl_easy_setopt(curl_handle,CURLOPT_HTTPHEADER, headers);
175 curl_easy_setopt(curl_handle,CURLOPT_URL, url);
4ec67e74 176 curl_easy_setopt(curl_handle,CURLOPT_WRITEFUNCTION, (void *)accumulatebytes); // send all data to this function
c2b50ce0 177 curl_easy_setopt(curl_handle,CURLOPT_WRITEDATA, &s); // we pass our 's' struct to the callback
178 curl_easy_setopt(curl_handle,CURLOPT_NOSIGNAL, 1L); // supposed to fix "Alarm clock" and long jump crash
f796b1fb 179 curl_easy_setopt(curl_handle,CURLOPT_NOPROGRESS, 1L); // no progress callback
c2b50ce0 180 if ( strncmp(url,"https",5) == 0 )
181 {
182 curl_easy_setopt(curl_handle,CURLOPT_SSL_VERIFYPEER,0);
183 curl_easy_setopt(curl_handle,CURLOPT_SSL_VERIFYHOST,0);
184 }
185 if ( userpass != 0 )
186 curl_easy_setopt(curl_handle,CURLOPT_USERPWD, userpass);
187 databuf = 0;
188 if ( params != 0 )
189 {
190 if ( command != 0 && specialcase == 0 )
191 {
192 len = strlen(params);
193 if ( len > 0 && params[0] == '[' && params[len-1] == ']' ) {
194 bracket0 = bracket1 = (char *)"";
195 }
196 else
197 {
198 bracket0 = (char *)"[";
199 bracket1 = (char *)"]";
200 }
f796b1fb 201
c2b50ce0 202 databuf = (char *)malloc(256 + strlen(command) + strlen(params));
203 sprintf(databuf,"{\"id\":\"jl777\",\"method\":\"%s\",\"params\":%s%s%s}",command,bracket0,params,bracket1);
05e307ec 204 //printf("url.(%s) userpass.(%s) databuf.(%s)\n",url,userpass,databuf);
c2b50ce0 205 //
206 } //else if ( specialcase != 0 ) fprintf(stderr,"databuf.(%s)\n",params);
207 curl_easy_setopt(curl_handle,CURLOPT_POST,1L);
208 if ( databuf != 0 )
209 curl_easy_setopt(curl_handle,CURLOPT_POSTFIELDS,databuf);
210 else curl_easy_setopt(curl_handle,CURLOPT_POSTFIELDS,params);
211 }
212 //laststart = milliseconds();
213 res = curl_easy_perform(curl_handle);
214 curl_slist_free_all(headers);
215 curl_easy_cleanup(curl_handle);
216 if ( databuf != 0 ) // clean up temporary buffer
217 {
218 free(databuf);
219 databuf = 0;
220 }
221 if ( res != CURLE_OK )
222 {
223 numretries++;
224 if ( specialcase != 0 )
225 {
226 printf("<<<<<<<<<<< bitcoind_RPC.(%s): BTCD.%s timeout params.(%s) s.ptr.(%s) err.%d\n",url,command,params,s.ptr,res);
227 free(s.ptr);
228 return(0);
229 }
c59a3beb 230 else if ( numretries >= 1 )
c2b50ce0 231 {
bb7f7473 232 //printf("Maximum number of retries exceeded!\n");
c2b50ce0 233 free(s.ptr);
234 return(0);
235 }
32323ea1 236 if ( (rand() % 1000) == 0 )
237 printf( "curl_easy_perform() failed: %s %s.(%s %s), retries: %d\n",curl_easy_strerror(res),debugstr,url,command,numretries);
c2b50ce0 238 free(s.ptr);
239 sleep((1<<numretries));
240 goto try_again;
f796b1fb 241
c2b50ce0 242 }
243 else
244 {
245 if ( command != 0 && specialcase == 0 )
246 {
247 count++;
248 elapsedsum += (OS_milliseconds() - starttime);
32323ea1 249 if ( (count % 1000000) == 0)
c2b50ce0 250 printf("%d: ave %9.6f | elapsed %.3f millis | bitcoind_RPC.(%s) url.(%s)\n",count,elapsedsum/count,(OS_milliseconds() - starttime),command,url);
251 if ( retstrp != 0 )
252 {
253 *retstrp = s.ptr;
254 return(s.ptr);
255 }
256 return(post_process_bitcoind_RPC(debugstr,command,s.ptr,params));
257 }
258 else
259 {
260 if ( 0 && specialcase != 0 )
261 fprintf(stderr,"<<<<<<<<<<< bitcoind_RPC: BTCD.(%s) -> (%s)\n",params,s.ptr);
262 count2++;
263 elapsedsum2 += (OS_milliseconds() - starttime);
264 if ( (count2 % 10000) == 0)
265 printf("%d: ave %9.6f | elapsed %.3f millis | NXT calls.(%s) cmd.(%s)\n",count2,elapsedsum2/count2,(double)(OS_milliseconds() - starttime),url,command);
266 return(s.ptr);
267 }
268 }
269 printf("bitcoind_RPC: impossible case\n");
270 free(s.ptr);
271 return(0);
272}
9b0e1808 273
274static size_t WriteMemoryCallback(void *ptr,size_t size,size_t nmemb,void *data)
275{
276 size_t realsize = (size * nmemb);
277 struct MemoryStruct *mem = (struct MemoryStruct *)data;
b858fa74 278 mem->memory = (char *)((ptr != 0) ? realloc(mem->memory,mem->size + realsize + 1) : malloc(mem->size + realsize + 1));
9b0e1808 279 if ( mem->memory != 0 )
280 {
281 if ( ptr != 0 )
282 memcpy(&(mem->memory[mem->size]),ptr,realsize);
283 mem->size += realsize;
284 mem->memory[mem->size] = 0;
285 }
286 //printf("got %d bytes\n",(int32_t)(size*nmemb));
287 return(realsize);
288}
289
05d3d5ff 290char *curl_post(CURL **cHandlep,char *url,char *userpass,char *postfields,char *hdr0,char *hdr1,char *hdr2,char *hdr3)
9b0e1808 291{
292 struct MemoryStruct chunk; CURL *cHandle; long code; struct curl_slist *headers = 0;
293 if ( (cHandle= *cHandlep) == NULL )
f796b1fb 294 *cHandlep = cHandle = curl_easy_init();
9b0e1808 295 else curl_easy_reset(cHandle);
296 //#ifdef DEBUG
f796b1fb 297 //curl_easy_setopt(cHandle,CURLOPT_VERBOSE, 1);
9b0e1808 298 //#endif
f796b1fb 299 curl_easy_setopt(cHandle,CURLOPT_USERAGENT,"mozilla/4.0");//"Mozilla/4.0 (compatible; )");
300 curl_easy_setopt(cHandle,CURLOPT_SSL_VERIFYPEER,0);
301 //curl_easy_setopt(cHandle,CURLOPT_SSLVERSION,1);
302 curl_easy_setopt(cHandle,CURLOPT_URL,url);
303 curl_easy_setopt(cHandle,CURLOPT_CONNECTTIMEOUT,10);
9b0e1808 304 if ( userpass != 0 && userpass[0] != 0 )
305 curl_easy_setopt(cHandle,CURLOPT_USERPWD,userpass);
f796b1fb 306 if ( postfields != 0 && postfields[0] != 0 )
9b0e1808 307 {
308 curl_easy_setopt(cHandle,CURLOPT_POST,1);
f796b1fb 309 curl_easy_setopt(cHandle,CURLOPT_POSTFIELDS,postfields);
9b0e1808 310 }
311 if ( hdr0 != NULL && hdr0[0] != 0 )
312 {
313 //printf("HDR0.(%s) HDR1.(%s) HDR2.(%s) HDR3.(%s)\n",hdr0!=0?hdr0:"",hdr1!=0?hdr1:"",hdr2!=0?hdr2:"",hdr3!=0?hdr3:"");
314 headers = curl_slist_append(headers,hdr0);
315 if ( hdr1 != 0 && hdr1[0] != 0 )
316 headers = curl_slist_append(headers,hdr1);
317 if ( hdr2 != 0 && hdr2[0] != 0 )
318 headers = curl_slist_append(headers,hdr2);
319 if ( hdr3 != 0 && hdr3[0] != 0 )
320 headers = curl_slist_append(headers,hdr3);
321 } //headers = curl_slist_append(0,"Expect:");
322 if ( headers != 0 )
323 curl_easy_setopt(cHandle,CURLOPT_HTTPHEADER,headers);
324 //res = curl_easy_perform(cHandle);
325 memset(&chunk,0,sizeof(chunk));
326 curl_easy_setopt(cHandle,CURLOPT_WRITEFUNCTION,WriteMemoryCallback);
327 curl_easy_setopt(cHandle,CURLOPT_WRITEDATA,(void *)&chunk);
328 curl_easy_perform(cHandle);
329 curl_easy_getinfo(cHandle,CURLINFO_RESPONSE_CODE,&code);
330 if ( headers != 0 )
331 curl_slist_free_all(headers);
332 if ( code != 200 )
333 printf("(%s) server responded with code %ld (%s)\n",url,code,chunk.memory);
334 return(chunk.memory);
335}
336
0ded57c8 337char *komodo_issuemethod(char *userpass,char *method,char *params,uint16_t port)
9b0e1808 338{
50653d13 339 //static void *cHandle;
a9132082 340 char url[512],*retstr=0,*retstr2=0,postdata[8192];
365378b5 341 if ( params == 0 || params[0] == 0 )
342 params = (char *)"[]";
9b0e1808 343 if ( strlen(params) < sizeof(postdata)-128 )
344 {
3c0f5d94 345 sprintf(url,(char *)"http://127.0.0.1:%u",port);
9b0e1808 346 sprintf(postdata,"{\"method\":\"%s\",\"params\":%s}",method,params);
50653d13 347 //printf("[%s] (%s) postdata.(%s) params.(%s) USERPASS.(%s)\n",ASSETCHAINS_SYMBOL,url,postdata,params,KMDUSERPASS);
348 retstr2 = bitcoind_RPC(&retstr,(char *)"debug",url,userpass,method,params);
349 //retstr = curl_post(&cHandle,url,USERPASS,postdata,0,0,0,0);
9b0e1808 350 }
1ccb1cf0 351 return(retstr2);
9b0e1808 352}
353
0cb025c1 354int32_t notarizedtxid_height(char *dest,char *txidstr,int32_t *kmdnotarized_heightp)
b000fa04 355{
0cb025c1 356 char *jsonstr,params[256],*userpass; uint16_t port; cJSON *json,*item; int32_t height = 0,txid_height = 0,txid_confirmations = 0;
b000fa04 357 params[0] = 0;
358 *kmdnotarized_heightp = 0;
0cb025c1 359 if ( strcmp(dest,"KMD") == 0 )
b000fa04 360 {
05e307ec 361 port = KMD_PORT;
0cb025c1 362 userpass = KMDUSERPASS;
363 }
364 else if ( strcmp(dest,"BTC") == 0 )
365 {
366 port = 8332;
367 userpass = BTCUSERPASS;
368 }
369 else return(0);
370 if ( userpass[0] != 0 )
371 {
372 if ( (jsonstr= komodo_issuemethod(userpass,(char *)"getinfo",params,port)) != 0 )
b000fa04 373 {
70d83934 374 //printf("(%s)\n",jsonstr);
b000fa04 375 if ( (json= cJSON_Parse(jsonstr)) != 0 )
376 {
978ca795 377 if ( (item= jobj(json,(char *)"result")) != 0 )
033f496d 378 {
033f496d 379 height = jint(item,(char *)"blocks");
57dd4ada 380 *kmdnotarized_heightp = strcmp(dest,"KMD") == 0 ? jint(item,(char *)"notarized") : height;
033f496d 381 }
b000fa04 382 free_json(json);
383 }
384 free(jsonstr);
385 }
386 sprintf(params,"[\"%s\", 1]",txidstr);
0cb025c1 387 if ( (jsonstr= komodo_issuemethod(userpass,(char *)"getrawtransaction",params,port)) != 0 )
b000fa04 388 {
70d83934 389 //printf("(%s)\n",jsonstr);
b000fa04 390 if ( (json= cJSON_Parse(jsonstr)) != 0 )
391 {
978ca795 392 if ( (item= jobj(json,(char *)"result")) != 0 )
033f496d 393 {
394 txid_confirmations = jint(item,(char *)"confirmations");
033f496d 395 if ( txid_confirmations > 0 && height > txid_confirmations )
396 txid_height = height - txid_confirmations;
19857195 397 else txid_height = height;
094b401e 398 //printf("height.%d tconfs.%d txid_height.%d\n",height,txid_confirmations,txid_height);
033f496d 399 }
b000fa04 400 free_json(json);
401 }
402 free(jsonstr);
403 }
43cc3df6 404 }
b000fa04 405 return(txid_height);
406}
407
20a5cb84 408int32_t komodo_verifynotarizedscript(int32_t height,uint8_t *script,int32_t len,uint256 NOTARIZED_HASH)
b55c2367 409{
410 int32_t i; uint256 hash; char params[256];
411 for (i=0; i<32; i++)
ebd18944 412 ((uint8_t *)&hash)[i] = script[2+i];
d56e5945 413 if ( hash == NOTARIZED_HASH )
414 return(0);
b556919a 415 for (i=0; i<32; i++)
416 printf("%02x",((uint8_t *)&NOTARIZED_HASH)[i]);
417 printf(" notarized, ");
418 for (i=0; i<32; i++)
419 printf("%02x",((uint8_t *)&hash)[i]);
895977bf 420 printf(" opreturn from [%s] ht.%d MISMATCHED\n",ASSETCHAINS_SYMBOL,height);
b556919a 421 return(-1);
b55c2367 422}
423
424int32_t komodo_verifynotarization(char *symbol,char *dest,int32_t height,int32_t NOTARIZED_HEIGHT,uint256 NOTARIZED_HASH,uint256 NOTARIZED_DESTTXID)
425{
3da303b5 426 char params[256],*jsonstr,*hexstr; uint8_t *script,_script[8192]; int32_t n,len,retval = -1; cJSON *json,*txjson,*vouts,*vout,*skey;
427 script = _script;
c3153900 428 /*params[0] = '[';
f796b1fb 429 params[1] = '"';
430 for (i=0; i<32; i++)
431 sprintf(&params[i*2 + 2],"%02x",((uint8_t *)&NOTARIZED_DESTTXID)[31-i]);
432 strcat(params,"\", 1]");*/
c3153900 433 sprintf(params,"[\"%s\", 1]",NOTARIZED_DESTTXID.ToString().c_str());
ed937645 434 if ( strcmp(symbol,ASSETCHAINS_SYMBOL[0]==0?(char *)"KMD":ASSETCHAINS_SYMBOL) != 0 )
435 return(0);
05c1e522 436 if ( 0 && ASSETCHAINS_SYMBOL[0] != 0 )
a0b9382c 437 printf("[%s] src.%s dest.%s params.[%s] ht.%d notarized.%d\n",ASSETCHAINS_SYMBOL,symbol,dest,params,height,NOTARIZED_HEIGHT);
b55c2367 438 if ( strcmp(dest,"KMD") == 0 )
b148643e 439 {
440 if ( KMDUSERPASS[0] != 0 )
5201bb51 441 {
442 if ( ASSETCHAINS_SYMBOL[0] != 0 )
a0b9382c 443 {
05e307ec 444 jsonstr = komodo_issuemethod(KMDUSERPASS,(char *)"getrawtransaction",params,KMD_PORT);
f796b1fb 445 //printf("userpass.(%s) got (%s)\n",KMDUSERPASS,jsonstr);
a0b9382c 446 }
447 }//else jsonstr = _dex_getrawtransaction();
48d0e5df 448 else return(0); // need universal way to issue DEX* API, since notaries mine most blocks, this ok
b148643e 449 }
b55c2367 450 else if ( strcmp(dest,"BTC") == 0 )
b148643e 451 {
452 if ( BTCUSERPASS[0] != 0 )
48d0e5df 453 {
eee28662 454 //printf("BTCUSERPASS.(%s)\n",BTCUSERPASS);
b148643e 455 jsonstr = komodo_issuemethod(BTCUSERPASS,(char *)"getrawtransaction",params,8332);
48d0e5df 456 }
b148643e 457 //else jsonstr = _dex_getrawtransaction();
48d0e5df 458 else return(0);
b148643e 459 }
9674c671 460 else
461 {
462 printf("[%s] verifynotarization error unexpected dest.(%s)\n",ASSETCHAINS_SYMBOL,dest);
463 return(-1);
464 }
b55c2367 465 if ( jsonstr != 0 )
466 {
13b64fd6 467 if ( (json= cJSON_Parse(jsonstr)) != 0 )
b55c2367 468 {
fa73aa67 469 if ( (txjson= jobj(json,(char *)"result")) != 0 && (vouts= jarray(&n,txjson,(char *)"vout")) > 0 )
b55c2367 470 {
471 vout = jitem(vouts,n-1);
34c68daa 472 if ( 0 && ASSETCHAINS_SYMBOL[0] != 0 )
a0b9382c 473 printf("vout.(%s)\n",jprint(vout,0));
523a5dc7 474 if ( (skey= jobj(vout,(char *)"scriptPubKey")) != 0 )
b55c2367 475 {
523a5dc7 476 if ( (hexstr= jstr(skey,(char *)"hex")) != 0 )
b55c2367 477 {
895977bf 478 //printf("HEX.(%s) vs hash.%s\n",hexstr,NOTARIZED_HASH.ToString().c_str());
b55c2367 479 len = strlen(hexstr) >> 1;
480 decode_hex(script,len,hexstr);
279fac91 481 if ( script[1] == 0x4c )
482 {
483 script++;
484 len--;
485 }
486 else if ( script[1] == 0x4d )
487 {
488 script += 2;
489 len -= 2;
490 }
20a5cb84 491 retval = komodo_verifynotarizedscript(height,script,len,NOTARIZED_HASH);
b55c2367 492 }
493 }
494 }
495 free_json(txjson);
496 }
497 free(jsonstr);
498 }
499 return(retval);
500}
501
2934460c 502/*uint256 komodo_getblockhash(int32_t height)
f796b1fb 503 {
504 uint256 hash; char params[128],*hexstr,*jsonstr; cJSON *result; int32_t i; uint8_t revbuf[32];
505 memset(&hash,0,sizeof(hash));
506 sprintf(params,"[%d]",height);
507 if ( (jsonstr= komodo_issuemethod(KMDUSERPASS,(char *)"getblockhash",params,BITCOIND_PORT)) != 0 )
508 {
509 if ( (result= cJSON_Parse(jsonstr)) != 0 )
510 {
511 if ( (hexstr= jstr(result,(char *)"result")) != 0 )
512 {
513 if ( is_hexstr(hexstr,0) == 64 )
514 {
515 decode_hex(revbuf,32,hexstr);
516 for (i=0; i<32; i++)
517 ((uint8_t *)&hash)[i] = revbuf[31-i];
518 }
519 }
520 free_json(result);
521 }
522 printf("KMD hash.%d (%s) %x\n",height,jsonstr,*(uint32_t *)&hash);
523 free(jsonstr);
524 }
525 return(hash);
526 }
527
528 uint256 _komodo_getblockhash(int32_t height);*/
6b0e06b5 529
23256cca 530uint64_t komodo_seed(int32_t height)
531{
39b462c7 532 uint64_t seed = 0;
2934460c 533 /*if ( 0 ) // problem during init time, seeds are needed for loading blockindex, so null seeds...
f796b1fb 534 {
535 uint256 hash,zero; CBlockIndex *pindex;
536 memset(&hash,0,sizeof(hash));
537 memset(&zero,0,sizeof(zero));
538 if ( height > 10 )
539 height -= 10;
540 if ( ASSETCHAINS_SYMBOL[0] == 0 )
541 hash = _komodo_getblockhash(height);
542 if ( memcmp(&hash,&zero,sizeof(hash)) == 0 )
543 hash = komodo_getblockhash(height);
544 int32_t i;
545 for (i=0; i<32; i++)
546 printf("%02x",((uint8_t *)&hash)[i]);
547 printf(" seed.%d\n",height);
548 seed = arith_uint256(hash.GetHex()).GetLow64();
549 }
550 else*/
8aef9e40 551 {
93fb251c 552 seed = (height << 13) ^ (height << 2);
553 seed <<= 21;
8aef9e40 554 seed |= (height & 0xffffffff);
93fb251c 555 seed ^= (seed << 17) ^ (seed << 1);
8aef9e40 556 }
23256cca 557 return(seed);
558}
559
fa4d9e24 560uint32_t komodo_txtime(uint64_t *valuep,uint256 hash,int32_t n,char *destaddr)
3eea72f2 561{
8d584a9c 562 CTxDestination address; CTransaction tx; uint256 hashBlock;
ce5dd547 563 *valuep = 0;
7637aa7f 564 if (!GetTransaction(hash, tx,
565#ifndef KOMODO_ZCASH
566 Params().GetConsensus(),
567#endif
568 hashBlock, true))
3eea72f2 569 {
28d89a86 570 fprintf(stderr,"ERROR: %s/v%d locktime.%u\n",hash.ToString().c_str(),n,(uint32_t)tx.nLockTime);
2ef19f04 571 return(0);
3eea72f2 572 }
1619474e 573 //fprintf(stderr,"%s/v%d locktime.%u\n",hash.ToString().c_str(),n,(uint32_t)tx.nLockTime);
2ef19f04 574 if ( n < tx.vout.size() )
8d584a9c 575 {
2ef19f04 576 *valuep = tx.vout[n].nValue;
fa4d9e24 577 if (ExtractDestination(tx.vout[n].scriptPubKey, address))
578 strcpy(destaddr,CBitcoinAddress(address).ToString().c_str());
8d584a9c 579 }
2ef19f04 580 return(tx.nLockTime);
3eea72f2 581}
582
583void komodo_disconnect(CBlockIndex *pindex,CBlock& block)
584{
7c130297 585 char symbol[KOMODO_ASSETCHAIN_MAXLEN],dest[KOMODO_ASSETCHAIN_MAXLEN]; struct komodo_state *sp;
e0440cc3 586 //fprintf(stderr,"disconnect ht.%d\n",pindex->nHeight);
c93dc546 587 komodo_init(pindex->nHeight);
f3a1de3a 588 if ( (sp= komodo_stateptr(symbol,dest)) != 0 )
7a183152 589 {
9c432d66 590 //sp->rewinding = pindex->nHeight;
591 //fprintf(stderr,"-%d ",pindex->nHeight);
7a183152 592 } else printf("komodo_disconnect: ht.%d cant get komodo_state.(%s)\n",pindex->nHeight,ASSETCHAINS_SYMBOL);
3eea72f2 593}
594
f24b36ca 595int32_t komodo_is_notarytx(const CTransaction& tx)
596{
faf51f1a 597 uint8_t *ptr; static uint8_t crypto777[33];
0554de3c 598 if ( tx.vout.size() > 0 )
599 {
f24b36ca 600#ifdef KOMODO_ZCASH
0554de3c 601 ptr = (uint8_t *)tx.vout[0].scriptPubKey.data();
f24b36ca 602#else
0554de3c 603 ptr = (uint8_t *)&tx.vout[0].scriptPubKey[0];
f24b36ca 604#endif
0554de3c 605 if ( ptr != 0 )
303fbd20 606 {
faf51f1a 607 if ( crypto777[0] == 0 )
608 decode_hex(crypto777,33,(char *)CRYPTO777_PUBSECPSTR);
0554de3c 609 if ( memcmp(ptr+1,crypto777,33) == 0 )
610 {
611 //printf("found notarytx\n");
612 return(1);
613 }
303fbd20 614 }
f24b36ca 615 }
303fbd20 616 return(0);
f24b36ca 617}
618
3eea72f2 619int32_t komodo_block2height(CBlock *block)
620{
e1501755 621 static uint32_t match,mismatch;
c52074f2 622 int32_t i,n,height2=-1,height = 0; uint8_t *ptr; CBlockIndex *pindex;
623 if ( (pindex= mapBlockIndex[block->GetHash()]) != 0 )
8a0b06f6 624 {
c52074f2 625 height2 = (int32_t)pindex->nHeight;
8a0b06f6 626 if ( height2 >= 0 )
627 return(height2);
628 }
0554de3c 629 if ( block->vtx[0].vin.size() > 0 )
630 {
189d9dee 631#ifdef KOMODO_ZCASH
0554de3c 632 ptr = (uint8_t *)block->vtx[0].vin[0].scriptSig.data();
189d9dee 633#else
0554de3c 634 ptr = (uint8_t *)&block->vtx[0].vin[0].scriptSig[0];
189d9dee 635#endif
0554de3c 636 if ( ptr != 0 && block->vtx[0].vin[0].scriptSig.size() > 5 )
3eea72f2 637 {
0554de3c 638 //for (i=0; i<6; i++)
639 // printf("%02x",ptr[i]);
640 n = ptr[0];
643bc61b 641 for (i=0; i<n; i++) // looks strange but this works
0554de3c 642 {
643 //03bb81000101(bb 187) (81 48001) (00 12288256) <- coinbase.6 ht.12288256
644 height += ((uint32_t)ptr[i+1] << (i*8));
645 //printf("(%02x %x %d) ",ptr[i+1],((uint32_t)ptr[i+1] << (i*8)),height);
646 }
643bc61b 647 //printf(" <- coinbase.%d ht.%d\n",(int32_t)block->vtx[0].vin[0].scriptSig.size(),height);
3eea72f2 648 }
0554de3c 649 //komodo_init(height);
3eea72f2 650 }
d4cc6fc3 651 if ( height != height2 )
c52074f2 652 {
f73e64e0 653 //fprintf(stderr,"block2height height.%d vs height2.%d, match.%d mismatch.%d\n",height,height2,match,mismatch);
d4cc6fc3 654 mismatch++;
655 if ( height2 >= 0 )
f717835b 656 height = height2;
d4cc6fc3 657 } else match++;
3eea72f2 658 return(height);
659}
660
19848155 661void komodo_block2pubkey33(uint8_t *pubkey33,CBlock *block)
3eea72f2 662{
2dbf06e8 663 int32_t n;
0690e63e 664 if ( KOMODO_LOADINGBLOCKS == 0 )
665 memset(pubkey33,0xff,33);
666 else memset(pubkey33,0,33);
19848155 667 if ( block->vtx[0].vout.size() > 0 )
0554de3c 668 {
da00f2dd 669#ifdef KOMODO_ZCASH
19848155 670 uint8_t *ptr = (uint8_t *)block->vtx[0].vout[0].scriptPubKey.data();
da00f2dd 671#else
19848155 672 uint8_t *ptr = (uint8_t *)&block->vtx[0].vout[0].scriptPubKey[0];
da00f2dd 673#endif
0554de3c 674 //komodo_init(0);
19848155 675 n = block->vtx[0].vout[0].scriptPubKey.size();
0554de3c 676 if ( n == 35 )
677 memcpy(pubkey33,ptr+1,33);
678 }
3eea72f2 679}
680
d7093b33 681int32_t komodo_blockload(CBlock& block,CBlockIndex *pindex)
875cf683 682{
683 block.SetNull();
684 // Open history file to read
685 CAutoFile filein(OpenBlockFile(pindex->GetBlockPos(),true),SER_DISK,CLIENT_VERSION);
686 if (filein.IsNull())
687 return(-1);
688 // Read block
689 try { filein >> block; }
690 catch (const std::exception& e)
691 {
692 fprintf(stderr,"readblockfromdisk err B\n");
693 return(-1);
694 }
695 return(0);
696}
697
ae0bb3d3 698uint32_t komodo_chainactive_timestamp()
699{
700 if ( chainActive.Tip() != 0 )
701 return((uint32_t)chainActive.Tip()->GetBlockTime());
e34a9d43 702 else return(0);
ae0bb3d3 703}
704
7d44d3dd 705CBlockIndex *komodo_chainactive(int32_t height)
706{
5150cb47 707 if ( chainActive.Tip() != 0 )
7d44d3dd 708 {
5150cb47 709 if ( height <= chainActive.Tip()->nHeight )
710 return(chainActive[height]);
129d39b0 711 // else fprintf(stderr,"komodo_chainactive height %d > active.%d\n",height,chainActive.Tip()->nHeight);
d54aa57d 712 }
8c8a07ce 713 //fprintf(stderr,"komodo_chainactive null chainActive.Tip() height %d\n",height);
d54aa57d 714 return(0);
7d44d3dd 715}
716
717uint32_t komodo_heightstamp(int32_t height)
718{
0cb1d2da 719 CBlockIndex *ptr;
58bec1f9 720 if ( height > 0 && (ptr= komodo_chainactive(height)) != 0 )
f21afd94 721 return(ptr->nTime);
b91ef9cf 722 //else fprintf(stderr,"komodo_heightstamp null ptr for block.%d\n",height);
7d44d3dd 723 return(0);
724}
725
232506f7 726/*void komodo_pindex_init(CBlockIndex *pindex,int32_t height) gets data corrupted
141950a4 727{
5368f298 728 int32_t i,num; uint8_t pubkeys[64][33]; CBlock block;
5920762d 729 if ( pindex->didinit != 0 )
2b00bd23 730 return;
524e0280 731 //printf("pindex.%d komodo_pindex_init notary.%d from height.%d\n",pindex->nHeight,pindex->notaryid,height);
065505b7 732 if ( pindex->didinit == 0 )
141950a4 733 {
326ddd86 734 pindex->notaryid = -1;
0690e63e 735 if ( KOMODO_LOADINGBLOCKS == 0 )
1f333439 736 memset(pindex->pubkey33,0xff,33);
0690e63e 737 else memset(pindex->pubkey33,0,33);
2b00bd23 738 if ( komodo_blockload(block,pindex) == 0 )
ace61bc1 739 {
19848155 740 komodo_block2pubkey33(pindex->pubkey33,&block);
3884efe7 741 //for (i=0; i<33; i++)
742 // fprintf(stderr,"%02x",pindex->pubkey33[i]);
743 //fprintf(stderr," set pubkey at height %d/%d\n",pindex->nHeight,height);
702f7543 744 //if ( pindex->pubkey33[0] == 2 || pindex->pubkey33[0] == 3 )
232506f7 745 // pindex->didinit = (KOMODO_LOADINGBLOCKS == 0);
524e0280 746 } // else fprintf(stderr,"error loading block at %d/%d",pindex->nHeight,height);
2b00bd23 747 }
065505b7 748 if ( pindex->didinit != 0 && pindex->nHeight >= 0 && (num= komodo_notaries(pubkeys,(int32_t)pindex->nHeight,(uint32_t)pindex->nTime)) > 0 )
2b00bd23 749 {
750 for (i=0; i<num; i++)
141950a4 751 {
2b00bd23 752 if ( memcmp(pubkeys[i],pindex->pubkey33,33) == 0 )
141950a4 753 {
2b00bd23 754 pindex->notaryid = i;
755 break;
141950a4 756 }
757 }
524e0280 758 if ( 0 && i == num )
ace61bc1 759 {
760 for (i=0; i<33; i++)
761 fprintf(stderr,"%02x",pindex->pubkey33[i]);
762 fprintf(stderr," unmatched pubkey at height %d/%d\n",pindex->nHeight,height);
763 }
141950a4 764 }
232506f7 765}*/
141950a4 766
3eea72f2 767void komodo_index2pubkey33(uint8_t *pubkey33,CBlockIndex *pindex,int32_t height)
768{
232506f7 769 int32_t num,i; CBlock block;
3eea72f2 770 memset(pubkey33,0,33);
071f1be1 771 if ( pindex != 0 )
3eea72f2 772 {
232506f7 773 if ( komodo_blockload(block,pindex) == 0 )
774 komodo_block2pubkey33(pubkey33,&block);
3eea72f2 775 }
776}
777
da9fce3e 778/*int8_t komodo_minerid(int32_t height,uint8_t *destpubkey33)
4a4e912b 779{
149a4d64 780 int32_t num,i,numnotaries; CBlockIndex *pindex; uint32_t timestamp=0; uint8_t pubkey33[33],pubkeys[64][33];
3e7e3109 781 if ( (pindex= chainActive[height]) != 0 )
fc318ffe 782 {
d74896c5 783 if ( pindex->didinit != 0 )
5e0e5f85 784 {
149a4d64 785 if ( destpubkey33 != 0 )
786 memcpy(destpubkey33,pindex->pubkey33,33);
3e7e3109 787 return(pindex->notaryid);
5e0e5f85 788 }
149a4d64 789 komodo_index2pubkey33(pubkey33,pindex,height);
790 if ( destpubkey33 != 0 )
791 memcpy(destpubkey33,pindex->pubkey33,33);
792 if ( pindex->didinit != 0 )
793 return(pindex->notaryid);
5e0e5f85 794 timestamp = pindex->GetBlockTime();
eb7171f5 795 if ( (num= komodo_notaries(pubkeys,height,timestamp)) > 0 )
796 {
797 for (i=0; i<num; i++)
798 if ( memcmp(pubkeys[i],pubkey33,33) == 0 )
799 return(i);
1746e25c 800 }
dac1ef88 801 }
0f29cbd6 802 fprintf(stderr,"komodo_minerid height.%d null pindex\n",height);
8eaa7b03 803 return(komodo_electednotary(&numnotaries,pubkey33,height,timestamp));
da9fce3e 804}*/
4a4e912b 805
a30dd993 806int32_t komodo_eligiblenotary(uint8_t pubkeys[66][33],int32_t *mids,uint32_t blocktimes[66],int32_t *nonzpkeysp,int32_t height)
353af8aa 807{
178618db 808 int32_t i,j,n,duplicate; CBlock block; CBlockIndex *pindex; uint8_t notarypubs33[64][33];
353af8aa 809 memset(mids,-1,sizeof(*mids)*66);
1481a43d 810 n = komodo_notaries(notarypubs33,height,0);
353af8aa 811 for (i=duplicate=0; i<66; i++)
812 {
3c525df1 813 if ( (pindex= komodo_chainactive(height-i)) != 0 )
353af8aa 814 {
a30dd993 815 blocktimes[i] = pindex->nTime;
da9fce3e 816 if ( komodo_blockload(block,pindex) == 0 )
817 {
818 komodo_block2pubkey33(pubkeys[i],&block);
819 for (j=0; j<n; j++)
820 {
178618db 821 if ( memcmp(notarypubs33[j],pubkeys[i],33) == 0 )
da9fce3e 822 {
823 mids[i] = j;
824 (*nonzpkeysp)++;
825 break;
826 }
827 }
1481a43d 828 } else fprintf(stderr,"couldnt load block.%d\n",height);
353af8aa 829 if ( mids[0] >= 0 && i > 0 && mids[i] == mids[0] )
830 duplicate++;
3c525df1 831 }
353af8aa 832 }
f2805ceb 833 if ( i == 66 && duplicate == 0 && (height > 186233 || *nonzpkeysp > 0) )
353af8aa 834 return(1);
835 else return(0);
836}
837
df03549d 838int32_t komodo_minerids(uint8_t *minerids,int32_t height,int32_t width)
dbaf1154 839{
df03549d 840 int32_t i,j,n,nonz,numnotaries; CBlock block; CBlockIndex *pindex; uint8_t notarypubs33[64][33],pubkey33[33];
841 numnotaries = komodo_notaries(notarypubs33,height,0);
842 for (i=nonz=0; i<width; i++,n++)
843 {
844 if ( height-i <= 0 )
845 continue;
e14d2c31 846 minerids[nonz] = numnotaries;
df03549d 847 if ( (pindex= komodo_chainactive(height-width+i+1)) != 0 )
848 {
849 if ( komodo_blockload(block,pindex) == 0 )
850 {
851 komodo_block2pubkey33(pubkey33,&block);
852 for (j=0; j<numnotaries; j++)
853 {
854 if ( memcmp(notarypubs33[j],pubkey33,33) == 0 )
855 {
856 minerids[nonz++] = j;
857 break;
858 }
859 }
860 } else fprintf(stderr,"couldnt load block.%d\n",height);
861 }
862 }
863 return(nonz);
dbaf1154 864}
865
dac3c30c 866int32_t komodo_is_special(uint8_t pubkeys[66][33],int32_t mids[66],uint32_t blocktimes[66],int32_t height,uint8_t pubkey33[33],uint32_t blocktime)
4a4e912b 867{
442215b4 868 int32_t i,j,notaryid=0,minerid,limit,nid; uint8_t destpubkey33[33];
dac3c30c 869 komodo_chosennotary(&notaryid,height,pubkey33,blocktimes[0]);
cb19d181 870 if ( height >= 82000 )
82f82d3f 871 {
442215b4 872 if ( notaryid >= 0 )
82f82d3f 873 {
874 for (i=1; i<66; i++)
875 {
442215b4 876 if ( mids[i] == notaryid )
82f82d3f 877 {
3c89a023 878 if ( height > 792000 )
0f5e787b 879 {
880 for (j=0; j<66; j++)
881 fprintf(stderr,"%d ",mids[j]);
882 fprintf(stderr,"ht.%d repeat notaryid.%d in mids[%d]\n",height,notaryid,i);
861119a1 883 return(-1);
0f5e787b 884 } else break;
82f82d3f 885 }
886 }
a658d926 887 if ( blocktime != 0 && blocktimes[1] != 0 && blocktime < blocktimes[1]+57 )
3ad8d247 888 {
f7ce3004 889 //if ( height > 790000 )
890 // fprintf(stderr,"lag.%d ht.%d n.%d blocktimes[%u vs %u %u]\n",blocktime-blocktimes[1],height,notaryid,blocktime,blocktimes[0],blocktimes[1]);
26d9f4c3 891 if ( height > 807000 )
a658d926 892 return(-2);
fb64a588 893 }
894 return(1);
82f82d3f 895 } else return(0);
896 }
442215b4 897 else
4a4e912b 898 {
428a3934 899 if ( height >= 34000 && notaryid >= 0 )
4a4e912b 900 {
428a3934 901 if ( height < 79693 )
902 limit = 64;
903 else if ( height < 82000 )
904 limit = 8;
905 else limit = 66;
906 for (i=1; i<limit; i++)
66e3c532 907 {
70ebf02a 908 komodo_chosennotary(&nid,height-i,pubkey33,blocktimes[i]);
428a3934 909 if ( nid == notaryid )
910 {
79fb8179 911 //for (j=0; j<66; j++)
912 // fprintf(stderr,"%d ",mids[j]);
913 //fprintf(stderr,"ht.%d repeat mids[%d] nid.%d notaryid.%d\n",height-i,i,nid,notaryid);
428a3934 914 if ( height > 225000 )
915 return(-1);
916 }
66e3c532 917 }
428a3934 918 //fprintf(stderr,"special notaryid.%d ht.%d limit.%d\n",notaryid,height,limit);
919 return(1);
4a4e912b 920 }
4a4e912b 921 }
922 return(0);
923}
924
51dab149 925int32_t komodo_MoM(int32_t *notarized_heightp,uint256 *MoMp,uint256 *kmdtxidp,int32_t nHeight,uint256 *MoMoMp,int32_t *MoMoMoffsetp,int32_t *MoMoMdepthp,int32_t *kmdstartip,int32_t *kmdendip)
0ab5b335 926{
aa5ca001 927 int32_t depth,notarized_ht; uint256 MoM,kmdtxid;
51dab149 928 depth = komodo_MoMdata(&notarized_ht,&MoM,&kmdtxid,nHeight,MoMoMp,MoMoMoffsetp,MoMoMdepthp,kmdstartip,kmdendip);
0ab5b335 929 memset(MoMp,0,sizeof(*MoMp));
b3548b52 930 memset(kmdtxidp,0,sizeof(*kmdtxidp));
0ab5b335 931 *notarized_heightp = 0;
16ed777a 932 if ( depth > 0 && notarized_ht > 0 && nHeight > notarized_ht-depth && nHeight <= notarized_ht )
0ab5b335 933 {
934 *MoMp = MoM;
935 *notarized_heightp = notarized_ht;
aa5ca001 936 *kmdtxidp = kmdtxid;
0ab5b335 937 }
938 return(depth);
939}
940
b62d7030 941int32_t komodo_checkpoint(int32_t *notarized_heightp,int32_t nHeight,uint256 hash)
942{
c52074f2 943 int32_t notarized_height,MoMdepth; uint256 MoM,notarized_hash,notarized_desttxid; CBlockIndex *notary,*pindex;
d82623d2 944 if ( (pindex= chainActive.Tip()) == 0 )
945 return(-1);
946 notarized_height = komodo_notarizeddata(pindex->nHeight,&notarized_hash,&notarized_desttxid);
b62d7030 947 *notarized_heightp = notarized_height;
aba9ea3c 948 if ( notarized_height >= 0 && notarized_height <= pindex->nHeight && (notary= mapBlockIndex[notarized_hash]) != 0 )
b62d7030 949 {
d82623d2 950 //printf("nHeight.%d -> (%d %s)\n",pindex->Tip()->nHeight,notarized_height,notarized_hash.ToString().c_str());
b62d7030 951 if ( notary->nHeight == notarized_height ) // if notarized_hash not in chain, reorg
952 {
953 if ( nHeight < notarized_height )
954 {
2c5af2cd 955 //fprintf(stderr,"[%s] nHeight.%d < NOTARIZED_HEIGHT.%d\n",ASSETCHAINS_SYMBOL,nHeight,notarized_height);
b62d7030 956 return(-1);
957 }
958 else if ( nHeight == notarized_height && memcmp(&hash,&notarized_hash,sizeof(hash)) != 0 )
959 {
beb911ec 960 fprintf(stderr,"[%s] nHeight.%d == NOTARIZED_HEIGHT.%d, diff hash\n",ASSETCHAINS_SYMBOL,nHeight,notarized_height);
b62d7030 961 return(-1);
962 }
ccff4876 963 } //else fprintf(stderr,"[%s] unexpected error notary_hash %s ht.%d at ht.%d\n",ASSETCHAINS_SYMBOL,notarized_hash.ToString().c_str(),notarized_height,notary->nHeight);
beb911ec 964 }
dc836ee4 965 //else if ( notarized_height > 0 && notarized_height != 73880 && notarized_height >= 170000 )
966 // fprintf(stderr,"[%s] couldnt find notarized.(%s %d) ht.%d\n",ASSETCHAINS_SYMBOL,notarized_hash.ToString().c_str(),notarized_height,pindex->nHeight);
b62d7030 967 return(0);
968}
485e48ca 969
83da1e16 970uint32_t komodo_interest_args(uint32_t *txheighttimep,int32_t *txheightp,uint32_t *tiptimep,uint64_t *valuep,uint256 hash,int32_t n)
c1c95e36 971{
972 LOCK(cs_main);
973 CTransaction tx; uint256 hashBlock; CBlockIndex *pindex,*tipindex;
63c93b0c 974 *txheighttimep = *txheightp = *tiptimep = 0;
975 *valuep = 0;
c1c95e36 976 if ( !GetTransaction(hash,tx,hashBlock,true) )
977 return(0);
978 uint32_t locktime = 0;
979 if ( n < tx.vout.size() )
980 {
c60397dd 981 if ( (pindex= mapBlockIndex[hashBlock]) != 0 )
c1c95e36 982 {
983 *valuep = tx.vout[n].nValue;
984 *txheightp = pindex->nHeight;
83da1e16 985 *txheighttimep = pindex->nTime;
c60397dd 986 if ( *tiptimep == 0 && (tipindex= chainActive.Tip()) != 0 )
987 *tiptimep = (uint32_t)tipindex->nTime;
c1c95e36 988 locktime = tx.nLockTime;
1f52f946 989 //fprintf(stderr,"tx locktime.%u %.8f height.%d | tiptime.%u\n",locktime,(double)*valuep/COIN,*txheightp,*tiptimep);
c1c95e36 990 }
991 }
992 return(locktime);
993}
994
995uint64_t komodo_interest(int32_t txheight,uint64_t nValue,uint32_t nLockTime,uint32_t tiptime);
c60397dd 996
997uint64_t komodo_accrued_interest(int32_t *txheightp,uint32_t *locktimep,uint256 hash,int32_t n,int32_t checkheight,uint64_t checkvalue,int32_t tipheight)
c1c95e36 998{
c60397dd 999 uint64_t value; uint32_t tiptime=0,txheighttimep; CBlockIndex *pindex;
1000 if ( (pindex= chainActive[tipheight]) != 0 )
1001 tiptime = (uint32_t)pindex->nTime;
72070c94 1002 else fprintf(stderr,"cant find height[%d]\n",tipheight);
83da1e16 1003 if ( (*locktimep= komodo_interest_args(&txheighttimep,txheightp,&tiptime,&value,hash,n)) != 0 )
c1c95e36 1004 {
798f28c7 1005 if ( (checkvalue == 0 || value == checkvalue) && (checkheight == 0 || *txheightp == checkheight) )
1006 return(komodo_interest(*txheightp,value,*locktimep,tiptime));
c1c95e36 1007 //fprintf(stderr,"nValue %llu lock.%u:%u nTime.%u -> %llu\n",(long long)coins.vout[n].nValue,coins.nLockTime,timestamp,pindex->nTime,(long long)interest);
1c2f0c49 1008 else fprintf(stderr,"komodo_accrued_interest value mismatch %llu vs %llu or height mismatch %d vs %d\n",(long long)value,(long long)checkvalue,*txheightp,checkheight);
1009 }
c1c95e36 1010 return(0);
1011}
8a7f7063 1012
1013int32_t komodo_isrealtime(int32_t *kmdheightp)
1014{
d82623d2 1015 struct komodo_state *sp; CBlockIndex *pindex;
8a7c9241 1016 if ( (sp= komodo_stateptrget((char *)"KMD")) != 0 )
ffbc2f00 1017 *kmdheightp = sp->CURRENT_HEIGHT;
1018 else *kmdheightp = 0;
1b5b89ba 1019 if ( (pindex= chainActive.Tip()) != 0 && pindex->nHeight >= (int32_t)komodo_longestchain() )
8a7f7063 1020 return(1);
1021 else return(0);
1022}
14aa6cc0 1023
3bc88f14 1024int32_t komodo_validate_interest(const CTransaction &tx,int32_t txheight,uint32_t nTime,int32_t dispflag)
14aa6cc0 1025{
1026 uint32_t cmptime = nTime;
1027 if ( KOMODO_REWIND == 0 && ASSETCHAINS_SYMBOL[0] == 0 && (int64_t)tx.nLockTime >= LOCKTIME_THRESHOLD ) //1473793441 )
1028 {
3d02f57b 1029 if ( txheight > 246748 )
14aa6cc0 1030 {
1031 if ( txheight < 247205 )
39d28b06 1032 cmptime -= 16000;
14aa6cc0 1033 if ( (int64_t)tx.nLockTime < cmptime-3600 )
1034 {
bbaa0f9d 1035 if ( tx.nLockTime != 1477258935 || dispflag != 0 )
14aa6cc0 1036 {
c13f04b7 1037 fprintf(stderr,"komodo_validate_interest.%d reject.%d [%d] locktime %u cmp2.%u\n",dispflag,txheight,(int32_t)(tx.nLockTime - (cmptime-3600)),(uint32_t)tx.nLockTime,cmptime);
14aa6cc0 1038 }
1039 return(-1);
1040 }
948ad8f3 1041 if ( 0 && dispflag != 0 )
3bc88f14 1042 fprintf(stderr,"validateinterest.%d accept.%d [%d] locktime %u cmp2.%u\n",dispflag,(int32_t)txheight,(int32_t)(tx.nLockTime - (cmptime-3600)),(int32_t)tx.nLockTime,cmptime);
14aa6cc0 1043 }
14aa6cc0 1044 }
1045 return(0);
1046}
ec5ed2f7 1047
This page took 0.445145 seconds and 4 git commands to generate.