]> Git Repo - VerusCoin.git/blob - src/komodo_gateway.h
test
[VerusCoin.git] / src / komodo_gateway.h
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 // paxdeposit equivalent in reverse makes opreturn and KMD does the same in reverse
17
18 struct pax_transaction *komodo_paxfind(struct pax_transaction *space,uint256 txid,uint16_t vout)
19 {
20     struct pax_transaction *pax;
21     pthread_mutex_lock(&komodo_mutex);
22     HASH_FIND(hh,PAX,&txid,sizeof(txid),pax);
23     if ( pax != 0 )
24         memcpy(space,pax,sizeof(*pax));
25     pthread_mutex_unlock(&komodo_mutex);
26     return(pax);
27 }
28
29 struct pax_transaction *komodo_paxmark(int32_t height,struct pax_transaction *space,uint256 txid,uint16_t vout,int32_t mark)
30 {
31     struct pax_transaction *pax;
32     pthread_mutex_lock(&komodo_mutex);
33     HASH_FIND(hh,PAX,&txid,sizeof(txid),pax);
34     if ( pax == 0 )
35     {
36         pax = (struct pax_transaction *)calloc(1,sizeof(*pax));
37         pax->txid = txid;
38         pax->vout = vout;
39         HASH_ADD_KEYPTR(hh,PAX,&pax->txid,sizeof(pax->txid),pax);
40         //printf("ht.%d create pax.%p mark.%d\n",height,pax,mark);
41     }
42     if ( pax != 0 )
43     {
44         pax->marked = mark;
45         //int32_t i; for (i=0; i<32; i++)
46         //    printf("%02x",((uint8_t *)&txid)[i]);
47         //printf(" paxmark.ht %d vout%d\n",mark,vout);
48         memcpy(space,pax,sizeof(*pax));
49     }
50     pthread_mutex_unlock(&komodo_mutex);
51     return(pax);
52 }
53
54 void komodo_gateway_deposit(char *coinaddr,uint64_t value,char *symbol,uint64_t fiatoshis,uint8_t *rmd160,uint256 txid,uint16_t vout,int32_t height,int32_t otherheight) // assetchain context
55 {
56     struct pax_transaction *pax; int32_t addflag = 0; struct komodo_state *sp; char str[16],dest[16];
57     sp = komodo_stateptr(str,dest);
58     pthread_mutex_lock(&komodo_mutex);
59     HASH_FIND(hh,PAX,&txid,sizeof(txid),pax);
60     if ( pax == 0 )
61     {
62         pax = (struct pax_transaction *)calloc(1,sizeof(*pax));
63         pax->txid = txid;
64         pax->vout = vout;
65         HASH_ADD_KEYPTR(hh,PAX,&pax->txid,sizeof(pax->txid),pax);
66         addflag = 1;
67         if ( ASSETCHAINS_SYMBOL[0] == 0 )
68         {
69             int32_t i; for (i=0; i<32; i++)
70                 printf("%02x",((uint8_t *)&txid)[i]);
71             printf(" v.%d [%s] kht.%d ht.%d create pax.%p\n",vout,ASSETCHAINS_SYMBOL,height,otherheight,pax);
72         }
73     }
74     pthread_mutex_unlock(&komodo_mutex);
75     if ( coinaddr != 0 )
76     {
77         strcpy(pax->coinaddr,coinaddr);
78         pax->komodoshis = value;
79         strcpy(pax->symbol,symbol);
80         pax->fiatoshis = fiatoshis;
81         memcpy(pax->rmd160,rmd160,20);
82         pax->height = height;
83         pax->otherheight = sp->CURRENT_HEIGHT;//otherheight;
84         if ( pax->marked == 0 )
85         {
86             if ( addflag != 0 )
87                 printf("[%s] addflag.%d ADD DEPOSIT %s %.8f -> %s TO PAX ht.%d otherht.%d total %.8f\n",ASSETCHAINS_SYMBOL,addflag,symbol,dstr(fiatoshis),coinaddr,height,otherheight,dstr(komodo_paxtotal()));
88         }
89         //else printf("%p MARKED.%d DEPOSIT %s %.8f -> %s TO PAX ht.%d otherht.%d\n",pax,pax->marked,symbol,dstr(fiatoshis),coinaddr,height,otherheight);
90     }
91     else
92     {
93         pax->marked = height;
94         printf("pax.%p MARK DEPOSIT ht.%d other.%d\n",pax,height,otherheight);
95     }
96 }
97
98 int32_t komodo_issued_opreturn(char *base,uint256 *txids,uint16_t *vouts,int64_t *values,int32_t *kmdheights,int32_t *otherheights,int8_t *baseids,uint8_t *opretbuf,int32_t opretlen,int32_t iskomodo)
99 {
100     int32_t i,n=0,j,len;
101     for (i=0; i<4; i++)
102         base[i] = opretbuf[opretlen-4+i];
103     if ( ASSETCHAINS_SYMBOL[0] == 0 || strncmp(ASSETCHAINS_SYMBOL,base,strlen(base)) == 0 )
104     {
105         opretbuf++, opretlen--;
106         for (n=len=0; n<opretlen/34; n++)
107         {
108             for (j=0; j<32; j++)
109             {
110                 ((uint8_t *)&txids[n])[j] = opretbuf[len++];
111                 //printf("%02x",((uint8_t *)&txids[n])[j]);
112             }
113             vouts[n] = opretbuf[len++];
114             vouts[n] = (opretbuf[len++] << 8) | vouts[n];
115             //printf(" issuedtxid v%d i.%d opretlen.%d\n",vouts[n],n,opretlen);
116             if ( iskomodo != 0 )
117             {
118                 uint64_t fiatoshis; int32_t height,otherheight; char symbol[16];
119                 len += iguana_rwnum(0,&opretbuf[len],sizeof(fiatoshis),&fiatoshis);
120                 len += iguana_rwnum(0,&opretbuf[len],sizeof(height),&height);
121                 len += iguana_rwnum(0,&opretbuf[len],sizeof(otherheight),&otherheight);
122                 for (i=0; opretbuf[len+i]!=0&&i<3; i++)
123                     symbol[i] = opretbuf[len+i];
124                 symbol[i] = 0;
125                 if ( values != 0 && kmdheights != 0 && otherheights != 0 && baseids != 0 )
126                 {
127                     values[i] = fiatoshis;
128                     kmdheights[i] = height;
129                     otherheights[i] = otherheight;
130                     baseids[i] = komodo_baseid(symbol);
131                 }
132                 printf(">>>>>>> iskomodo X: (%s) fiat %.8f kmdheight.%d other.%d\n",symbol,dstr(fiatoshis),height,otherheight);
133             }
134         }
135     }
136     return(n);
137 }
138
139 uint64_t komodo_paxtotal()
140 {
141     struct pax_transaction *pax,*tmp; int32_t ht; uint64_t total = 0;
142     if ( komodo_isrealtime(&ht) == 0 )
143         return(0);
144     HASH_ITER(hh,PAX,pax,tmp)
145     {
146         //printf("pax.%s marked.%d %.8f -> %.8f\n",pax->symbol,pax->marked,dstr(pax->komodoshis),dstr(pax->fiatoshis));
147         if ( pax->marked == 0 )
148         {
149             if ( komodo_is_issuer() != 0 )
150                 total += pax->fiatoshis;
151             else total += pax->komodoshis;
152         }
153     }
154     //printf("paxtotal %.8f\n",dstr(total));
155     return(total);
156 }
157
158 int32_t komodo_gateway_deposits(CMutableTransaction *txNew,char *base,int32_t tokomodo)
159 {
160     struct pax_transaction *pax,*tmp; char symbol[16],dest[16]; uint8_t *script,opcode,opret[10000],data[10000]; int32_t i,baseid,ht,len=0,opretlen=0,numvouts=1; struct komodo_state *sp; uint64_t mask;
161     sp = komodo_stateptr(symbol,dest);
162     strcpy(symbol,base);
163     PENDING_KOMODO_TX = 0;
164     if ( tokomodo == 0 )
165     {
166         opcode = 'I';
167         if ( komodo_isrealtime(&ht) == 0 )
168             return(0);
169     }
170     else opcode = 'X';
171     HASH_ITER(hh,PAX,pax,tmp)
172     {
173         //printf("pax.%s marked.%d %.8f -> %.8f\n",pax->symbol,pax->marked,dstr(pax->komodoshis),dstr(pax->fiatoshis));
174         if ( pax->marked != 0 || strcmp(pax->symbol,symbol) != 0 )
175             continue;
176         //if ( ASSETCHAINS_SYMBOL[0] != 0 )
177             printf("pax.%s marked.%d %.8f -> %.8f\n",ASSETCHAINS_SYMBOL,pax->marked,dstr(pax->komodoshis),dstr(pax->fiatoshis));
178         txNew->vout.resize(numvouts+1);
179         txNew->vout[numvouts].nValue = (opcode == 'I') ? pax->fiatoshis : pax->komodoshis;
180         txNew->vout[numvouts].scriptPubKey.resize(25);
181         script = (uint8_t *)&txNew->vout[numvouts].scriptPubKey[0];
182         *script++ = 0x76;
183         *script++ = 0xa9;
184         *script++ = 20;
185         memcpy(script,pax->rmd160,20), script += 20;
186         *script++ = 0x88;
187         *script++ = 0xac;
188         for (i=0; i<32; i++)
189         {
190             //printf("%02x",((uint8_t *)&pax->txid)[i]);
191             data[len++] = ((uint8_t *)&pax->txid)[i];
192         }
193         data[len++] = pax->vout & 0xff;
194         data[len++] = (pax->vout >> 8) & 0xff;
195         if ( tokomodo == 0 )
196             PENDING_KOMODO_TX += pax->fiatoshis;
197         else
198         {
199             //[{"prev_hash":"5d5c9a49489b558de9e84f991f996dedaae6b9d0f157f82b2fec64662476d5cf","prev_vout":2,"EUR":0.10000000,"fiat":"EUR","kmdheight":57930,"height":153,"KMD":0.78329000,"address":"RDhEGYScNQYetCyG75Kf8Fg61UWPdwc1C5","rmd160":"306c507eea639e7220b3069ed9f49f3bc97eaca1"}]
200             len += iguana_rwnum(1,&data[len],sizeof(pax->fiatoshis),&pax->fiatoshis);
201             len += iguana_rwnum(1,&data[len],sizeof(pax->height),&pax->height);
202             len += iguana_rwnum(1,&data[len],sizeof(pax->otherheight),&pax->otherheight);
203             for (i=0; pax->symbol[i]!=0&&i<3; i++) // must be 3 letter currency
204                 data[len++] = pax->symbol[i];
205             data[len++] = 0;
206             PENDING_KOMODO_TX += pax->komodoshis;
207             printf(" vout.%u DEPOSIT %.8f <- pax.%s pending %.8f | ",pax->vout,(double)txNew->vout[numvouts].nValue/COIN,symbol,dstr(PENDING_KOMODO_TX));
208         }
209         if ( numvouts++ >= 64 )
210             break;
211     }
212     if ( numvouts > 1 )
213     {
214         if ( tokomodo != 0 )
215             strcpy(symbol,(char *)"KMD");
216         for (i=0; symbol[i]!=0; i++)
217             data[len++] = symbol[i];
218         data[len++] = 0;
219         opretlen = komodo_opreturnscript(opret,opcode,data,len);
220         txNew->vout.resize(numvouts+1);
221         txNew->vout[numvouts].nValue = 0;
222         txNew->vout[numvouts].scriptPubKey.resize(opretlen);
223         script = (uint8_t *)&txNew->vout[numvouts].scriptPubKey[0];
224         memcpy(script,opret,opretlen);
225         printf("MINER deposits.%d (%s) vouts.%d %.8f opretlen.%d\n",tokomodo,ASSETCHAINS_SYMBOL,numvouts,dstr(PENDING_KOMODO_TX),opretlen);
226         return(1);
227     }
228     return(0);
229 }
230
231 int32_t komodo_check_deposit(int32_t height,const CBlock& block) // verify above block is valid pax pricing
232 {
233     int32_t i,j,n,num,opretlen,offset=1,errs=0,matched=0,kmdheights[64],otherheights[64]; uint256 hash,txids[64]; char symbol[16],base[16]; uint16_t vouts[64]; int8_t baseids[64]; uint8_t *script,opcode; int64_t values[64]; struct pax_transaction *pax,space;
234     memset(baseids,0xff,sizeof(baseids));
235     memset(values,0,sizeof(values));
236     memset(kmdheights,0,sizeof(kmdheights));
237     memset(otherheights,0,sizeof(otherheights));
238     n = block.vtx[0].vout.size();
239     script = (uint8_t *)block.vtx[0].vout[n-1].scriptPubKey.data();
240     if ( n <= 2 || script[0] != 0x6a )
241         return(0);
242     offset += komodo_scriptitemlen(&opretlen,&script[offset]);
243     if ( ASSETCHAINS_SYMBOL[0] == 0 )
244     {
245         //for (i=0; i<opretlen; i++)
246         //    printf("%02x",script[i]);
247         //printf(" height.%d checkdeposit n.%d [%02x] [%c] %d vs %d\n",height,n,script[0],script[offset],script[offset],'X');
248         opcode = 'X';
249         strcpy(symbol,"KMD");
250     }
251     else
252     {
253         strcpy(symbol,ASSETCHAINS_SYMBOL);
254         opcode = 'I';
255     }
256     if ( script[offset] == opcode && opretlen < block.vtx[0].vout[n-1].scriptPubKey.size() )
257     {
258         if ( (num= komodo_issued_opreturn(base,txids,vouts,values,kmdheights,otherheights,baseids,&script[offset],opretlen,opcode == 'X')) > 0 )
259         {
260             for (i=1; i<n-1; i++)
261             {
262                 if ( (pax= komodo_paxfind(&space,txids[i-1],vouts[i-1])) != 0 )
263                 {
264                     if ( ((opcode == 'I' && pax->fiatoshis == block.vtx[0].vout[i].nValue) || (opcode == 'X' && pax->komodoshis == block.vtx[0].vout[i].nValue)) )
265                     {
266                         if ( pax->marked != 0 )
267                             errs++;
268                         else matched++;
269                         if ( 0 && opcode == 'X' )
270                             printf("errs.%d i.%d match %.8f == %.8f\n",errs,i,dstr(pax != 0 ? pax->fiatoshis:-1),dstr(block.vtx[0].vout[i].nValue));
271                     }
272                     else
273                     {
274                         hash = block.GetHash();
275                         if ( opcode == 'X' )
276                         {
277                             for (j=0; j<32; j++)
278                                 printf("%02x",((uint8_t *)&hash)[j]);
279                             printf(" ht.%d blockhash X couldnt find vout.[%d]\n",height,i);
280                             // validate amount! via fiat chain
281                         }
282                     }
283                 }
284                 else
285                 {
286                     if  ( opcode == 'X' )
287                     {
288                         matched++;
289                         for (j=0; j<32; j++)
290                             printf("%02x",((uint8_t *)&txids[i-1])[j]);
291                         printf(" cant paxfind X txid\n");
292                         // validate amount! via fiat chain
293                     } else if ( opcode == 'I' )
294                         matched++;
295                 }
296                 komodo_paxmark(height,&space,txids[i-1],vouts[i-1],height);
297             }
298             if ( matched != num )
299             {
300                 // can easily happen depending on order of loading
301                 if ( height > 60000 )
302                     printf("WARNING: ht.%d (%c) matched.%d vs num.%d\n",height,opcode,matched,num);
303             }
304         }
305         //printf("opretlen.%d num.%d\n",opretlen,num);
306     }
307     return(0);
308 }
309
310 const char *komodo_opreturn(int32_t height,uint64_t value,uint8_t *opretbuf,int32_t opretlen,uint256 txid,uint16_t vout)
311 {
312     uint8_t rmd160[20],addrtype,shortflag,pubkey33[33]; int32_t i,j,n,len,tokomodo,kmdheight,otherheights[64],kmdheights[64]; int8_t baseids[64]; char base[4],coinaddr[64],destaddr[64]; struct pax_transaction space; uint256 txids[64]; uint16_t vouts[64]; uint64_t seed; int64_t fiatoshis,checktoshis,values[64]; struct pax_transaction *pax;
313     const char *typestr = "unknown";
314     memset(baseids,0xff,sizeof(baseids));
315     memset(values,0,sizeof(values));
316     memset(kmdheights,0,sizeof(kmdheights));
317     memset(otherheights,0,sizeof(otherheights));
318     tokomodo = (komodo_is_issuer() == 0);
319     if ( 0 && ASSETCHAINS_SYMBOL[0] != 0 )
320     {
321         for (i=0; i<opretlen; i++)
322             printf("%02x",opretbuf[i]);
323         printf(" opret[%c] else path tokomodo.%d ht.%d\n",opretbuf[0],tokomodo,height);
324     }
325     if ( opretbuf[0] == 'D' )
326     {
327         if ( opretlen == 38 ) // any KMD tx
328         {
329             iguana_rwnum(0,&opretbuf[34],sizeof(kmdheight),&kmdheight);
330             memset(base,0,sizeof(base));
331             PAX_pubkey(0,&opretbuf[1],&addrtype,rmd160,base,&shortflag,&fiatoshis);
332             bitcoin_address(coinaddr,addrtype,rmd160,20);
333             checktoshis = PAX_fiatdest(&seed,tokomodo,destaddr,pubkey33,coinaddr,kmdheight,base,fiatoshis);
334             typestr = "deposit";
335             printf("%s kmdheight.%d vs height.%d check %.8f vs %.8f tokomodo.%d %d seed.%llx\n",ASSETCHAINS_SYMBOL,kmdheight,height,dstr(checktoshis),dstr(value),komodo_is_issuer(),strncmp(ASSETCHAINS_SYMBOL,base,strlen(base)) == 0,(long long)seed);
336             if ( kmdheight <= height )
337             {
338                 if ( tokomodo == 0 && strncmp(ASSETCHAINS_SYMBOL,base,strlen(base)) == 0 )
339                 {
340                     for (i=0; i<32; i++)
341                         printf("%02x",((uint8_t *)&txid)[i]);
342                     printf(" <- txid.v%u ",vout);
343                     for (i=0; i<33; i++)
344                         printf("%02x",pubkey33[i]);
345                     printf(" checkpubkey check %.8f v %.8f dest.(%s) kmdheight.%d height.%d\n",dstr(checktoshis),dstr(value),destaddr,kmdheight,height);
346                     if ( value == checktoshis )//value >= checktoshis || (seed == 0 && diff < .01) )
347                     {
348                         if ( komodo_paxfind(&space,txid,vout) == 0 )
349                         {
350                             komodo_gateway_deposit(coinaddr,value,base,fiatoshis,rmd160,txid,vout,kmdheight,height);
351                         } else printf("duplicate deposit\n");
352                     }
353                 }
354             }
355         }
356     }
357     else if ( strncmp((char *)"KMD",(char *)&opretbuf[opretlen-4],3) != 0 || opretlen == 38 )
358     {
359         if ( tokomodo == 0 && opretbuf[0] == 'I' ) // assetchain coinbase
360         {
361             if ( (n= komodo_issued_opreturn(base,txids,vouts,values,kmdheights,otherheights,baseids,opretbuf,opretlen,0)) > 0 )
362             {
363                 for (i=0; i<n; i++)
364                 {
365                     if ( komodo_paxmark(height,&space,txids[i],vouts[i],height) == 0 )
366                         komodo_gateway_deposit(0,0,0,0,0,txids[i],vouts[i],height,0);
367                 }
368             }
369         }
370         else if ( tokomodo != 0 && opretbuf[0] == 'W' && opretlen >= 38 )
371         {
372             iguana_rwnum(0,&opretbuf[34],sizeof(kmdheight),&kmdheight);
373             memset(base,0,sizeof(base));
374             PAX_pubkey(0,&opretbuf[1],&addrtype,rmd160,base,&shortflag,&fiatoshis);
375             bitcoin_address(coinaddr,addrtype,rmd160,20);
376             checktoshis = PAX_fiatdest(&seed,tokomodo,destaddr,pubkey33,coinaddr,kmdheight,base,fiatoshis);
377             typestr = "withdraw";
378             printf("%s kmdheight.%d vs height.%d check %.8f vs %.8f tokomodo.%d %d seed.%llx\n",ASSETCHAINS_SYMBOL,kmdheight,height,dstr(checktoshis),dstr(value),komodo_is_issuer(),strncmp(ASSETCHAINS_SYMBOL,base,strlen(base)) == 0,(long long)seed);
379             if ( komodo_paxmark(height,&space,txid,vout,kmdheight) == 0 )
380             {
381                 if ( (pax= komodo_paxfind(&space,txids[i],vouts[i])) != 0 )
382                 {
383                     
384                 }
385                 printf("notarize %s %.8f kmd.%d other.%d\n",ASSETCHAINS_SYMBOL,dstr(value),kmdheight,height);
386                 //komodo_gateway_deposit(0,0,0,0,0,txids[i],vouts[i],height,0);
387             }
388         }
389     }
390     return(typestr);
391 }
392
393 void komodo_passport_iteration()
394 {
395     static long lastpos[34]; static char userpass[33][1024];
396     FILE *fp; int32_t baseid,isrealtime,refid,blocks,longest; struct komodo_state *sp,*refsp; char *retstr,fname[512],*base,symbol[16],dest[16]; uint32_t buf[3]; cJSON *infoobj,*result; uint64_t RTmask = 0;
397     refsp = komodo_stateptr(symbol,dest);
398     if ( ASSETCHAINS_SYMBOL[0] == 0 )
399         refid = 33;
400     else refid = komodo_baseid(ASSETCHAINS_SYMBOL)+1; // illegal base -> baseid.-1 -> 0
401     //printf("PASSPORT %s refid.%d\n",ASSETCHAINS_SYMBOL,refid);
402     for (baseid=0; baseid<=32; baseid++)
403     {
404         sp = 0;
405         isrealtime = 0;
406         base = (char *)CURRENCIES[baseid];
407         if ( baseid+1 != refid )
408         {
409             komodo_statefname(fname,baseid<32?base:(char *)"",(char *)"komodostate");
410             komodo_nameset(symbol,dest,base);
411             //port = komodo_port(base,10,&magic) + 1;
412             if ( (fp= fopen(fname,"rb")) != 0 && (sp= komodo_stateptrget(symbol)) != 0 )
413             {
414                 //printf("refid.%d %s fname.(%s) base.%s\n",refid,symbol,fname,base);
415                 fseek(fp,0,SEEK_END);
416                 if ( ftell(fp) > lastpos[baseid] )
417                 {
418                     fseek(fp,lastpos[baseid],SEEK_SET);
419                     while ( komodo_parsestatefile(sp,fp,symbol,dest) >= 0 )
420                         ;
421                     lastpos[baseid] = ftell(fp);
422                     //printf("from.(%s) lastpos[%s] %ld\n",ASSETCHAINS_SYMBOL,CURRENCIES[baseid],lastpos[baseid]);
423                 } //else fprintf(stderr,"%s.%ld ",CURRENCIES[baseid],ftell(fp));
424                 fclose(fp);
425             }
426             komodo_statefname(fname,baseid<32?base:(char *)"",(char *)"realtime");
427             if ( (fp= fopen(fname,"rb")) != 0 )
428             {
429                 if ( fread(buf,1,sizeof(buf),fp) == sizeof(buf) )
430                 {
431                     sp->CURRENT_HEIGHT = buf[0];
432                     if ( buf[0] != 0 && buf[0] == buf[1] && buf[2] > time(NULL)-60 )
433                     {
434                         isrealtime = 1;
435                         RTmask |= (1LL << baseid);
436                         memcpy(refsp->RTbufs[baseid+1],buf,sizeof(refsp->RTbufs[baseid+1]));
437                     } //else fprintf(stderr,"%s not RT\n",base);
438                 } //else fprintf(stderr,"%s size error RT\n",base);
439                 fclose(fp);
440             } else fprintf(stderr,"%s open error RT\n",base);
441         }
442         else
443         {
444             komodo_statefname(fname,baseid<32?base:(char *)"",(char *)"realtime");
445             if ( (fp= fopen(fname,"wb")) != 0 )
446             {
447                 buf[0] = (uint32_t)chainActive.Tip()->nHeight;
448                 buf[1] = (uint32_t)komodo_longestchain();
449                 if ( buf[0] != 0 && buf[0] == buf[1] )
450                 {
451                     buf[2] = (uint32_t)time(NULL);
452                     RTmask |= (1LL << baseid) | 1;
453                     memcpy(refsp->RTbufs[baseid+1],buf,sizeof(refsp->RTbufs[baseid+1]));
454                     if ( refid != 0 )
455                         memcpy(refsp->RTbufs[0],buf,sizeof(refsp->RTbufs[0]));
456                 }
457                 if ( fwrite(buf,1,sizeof(buf),fp) != sizeof(buf) )
458                     fprintf(stderr,"[%s] %s error writing realtime\n",ASSETCHAINS_SYMBOL,base);
459                 fclose(fp);
460             } else fprintf(stderr,"%s create error RT\n",base);
461         }
462         if ( sp != 0 && isrealtime == 0 )
463             refsp->RTbufs[0][2] = 0;
464     }
465     refsp->RTmask = RTmask;
466 }
467
This page took 0.049863 seconds and 4 git commands to generate.