]> Git Repo - VerusCoin.git/blame_incremental - src/komodo_gateway.h
test
[VerusCoin.git] / src / komodo_gateway.h
... / ...
CommitLineData
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
18struct pax_transaction
19{
20 struct queueitem DL;
21 uint256 txid;
22 uint64_t komodoshis,fiatoshis;
23 uint16_t vout;
24 char symbol[4]; uint8_t rmd160[20],shortflag;
25};
26
27int32_t komodo_issued_opreturn(uint8_t *shortflagp,char *base,uint256 *txids,uint16_t *vouts,uint8_t *opretbuf,int32_t opretlen)
28{
29 int32_t i,n=0,j,len;
30 if ( opretbuf[opretlen-5] == '-' )
31 *shortflagp = 1;
32 else *shortflagp = 0;
33 for (i=0; i<4; i++)
34 base[i] = opretbuf[opretlen-4+i];
35 if ( strncmp(ASSETCHAINS_SYMBOL,base,strlen(base)) == 0 ) // shortflag
36 {
37 //printf("BASE.(%s) vs (%s)\n",base,ASSETCHAINS_SYMBOL);
38 opretbuf++, opretlen--;
39 for (n=len=0; n<opretlen/34; n++)
40 {
41 for (j=0; j<32; j++)
42 {
43 ((uint8_t *)&txids[n])[j] = opretbuf[len++];
44 //printf("%02x",((uint8_t *)&txids[n])[j]);
45 }
46 vouts[n] = opretbuf[len++];
47 vouts[n] = (opretbuf[len++] << 8) | vouts[n];
48 //printf(" issuedtxid v%d i.%d opretlen.%d\n",vouts[n],n,opretlen);
49 }
50 }
51 return(n);
52}
53
54void komodo_gateway_deposits(CMutableTransaction *txNew)
55{
56 struct pax_transaction *ptr; uint8_t *script,opret[10000],data[10000]; int32_t i,len=0,opretlen=0,numvouts=1;
57 PENDING_KOMODO_TX = 0;
58 while ( numvouts < 64 && (ptr= (struct pax_transaction *)queue_dequeue(&DepositsQ)) != 0 )
59 {
60 txNew->vout.resize(numvouts+1);
61 txNew->vout[numvouts].nValue = ptr->fiatoshis;
62 txNew->vout[numvouts].scriptPubKey.resize(25);
63 script = (uint8_t *)&txNew->vout[numvouts].scriptPubKey[0];
64 *script++ = 0x76;
65 *script++ = 0xa9;
66 *script++ = 20;
67 memcpy(script,ptr->rmd160,20), script += 20;
68 *script++ = 0x88;
69 *script++ = 0xac;
70 for (i=0; i<32; i++)
71 {
72 printf("%02x",((uint8_t *)&ptr->txid)[i]);
73 data[len++] = ((uint8_t *)&ptr->txid)[i];
74 }
75 data[len++] = ptr->vout & 0xff;
76 data[len++] = (ptr->vout >> 8) & 0xff;
77 printf(" vout.%u DEPOSIT %.8f <- paxdeposit.%s\n",ptr->vout,(double)txNew->vout[numvouts].nValue/COIN,ASSETCHAINS_SYMBOL);
78 PENDING_KOMODO_TX += ptr->fiatoshis;
79 numvouts++;
80 queue_enqueue((char *)"PENDINGS",&PendingsQ,&ptr->DL);
81 }
82 while ( (ptr= (struct pax_transaction *)queue_dequeue(&PendingsQ)) != 0 )
83 queue_enqueue((char *)"DEPOSITS",&DepositsQ,&ptr->DL);
84 if ( numvouts > 1 )
85 {
86 if ( ASSETCHAINS_SHORTFLAG != 0 )
87 data[len++] = '-';
88 for (i=0; ASSETCHAINS_SYMBOL[i]!=0; i++)
89 data[len++] = ASSETCHAINS_SYMBOL[i];
90 data[len++] = 0;
91 opretlen = komodo_opreturnscript(opret,'I',data,len);
92 txNew->vout.resize(numvouts+1);
93 txNew->vout[numvouts].nValue = 0;
94 txNew->vout[numvouts].scriptPubKey.resize(opretlen);
95 script = (uint8_t *)&txNew->vout[numvouts].scriptPubKey[0];
96 memcpy(script,opret,opretlen);
97 printf("total numvouts.%d %.8f opretlen.%d\n",numvouts,dstr(PENDING_KOMODO_TX),opretlen);
98 } else KOMODO_DEPOSIT = 0;
99}
100
101void komodo_gateway_deposit(char *coinaddr,uint64_t value,int32_t shortflag,char *symbol,uint64_t fiatoshis,uint8_t *rmd160,uint256 txid,uint16_t vout) // assetchain context
102{
103 struct pax_transaction *ptr;
104 ptr = (struct pax_transaction *)calloc(1,sizeof(*ptr));
105 ptr->komodoshis = value;
106 ptr->fiatoshis = fiatoshis;
107 memcpy(ptr->symbol,symbol,3);
108 memcpy(ptr->rmd160,rmd160,20);
109 ptr->shortflag = shortflag;
110 ptr->txid = txid;
111 ptr->vout = vout;
112 KOMODO_DEPOSIT += fiatoshis;
113 printf("ADD DEPOSIT %s %.8f -> %s TO QUEUE\n",symbol,dstr(fiatoshis),coinaddr);
114 queue_enqueue((char *)"DEPOSITS",&DepositsQ,&ptr->DL);
115}
116
117int32_t komodo_gateway_depositremove(uint256 txid,uint16_t vout) // assetchain context
118{
119 int32_t iter,i,n=0; queue_t *Q; struct pax_transaction *ptr; struct queueitem *item;
120 for (iter=0; iter<2; iter++)
121 {
122 Q = (iter == 0) ? &DepositsQ : &PendingsQ;
123 portable_mutex_lock(&Q->mutex);
124 if ( Q->list != 0 )
125 {
126 item = &ptr->DL;
127 DL_FOREACH(Q->list,item)
128 {
129 ptr = (struct pax_transaction *)item;
130 if ( memcmp(&ptr->txid,&txid,sizeof(txid)) == 0 && ptr->vout == vout )
131 {
132 if ( KOMODO_DEPOSIT >= ptr->fiatoshis )
133 KOMODO_DEPOSIT -= ptr->fiatoshis;
134 else KOMODO_DEPOSIT = 0;
135 for (i=0; i<32; i++)
136 printf("%02x",((uint8_t *)&txid)[i]);
137 printf(" v%d DELETE %.8f DEPOSIT %s %.8f\n",vout,dstr(ptr->komodoshis),ptr->symbol,dstr(ptr->fiatoshis));
138 DL_DELETE(Q->list,&ptr->DL);
139 n++;
140 free(ptr);
141 break;
142 }
143 }
144 }
145 portable_mutex_unlock(&Q->mutex);
146 }
147 if ( queue_size(&DepositsQ) == 0 && queue_size(&PendingsQ) == 0 )
148 KOMODO_DEPOSIT = PENDING_KOMODO_TX = 0;
149 return(n);
150}
151
152int32_t komodo_check_deposit(const CBlock& block) // verify above block is valid pax pricing
153{
154 int32_t i,j,n,opretlen,num,iter,matchflag,offset=1; uint256 txids[64]; uint8_t shortflag; char base[16]; uint16_t vouts[64]; uint8_t *script; queue_t *Q; struct pax_transaction *ptr; struct queueitem *item;
155 n = block.vtx[0].vout.size();
156 script = (uint8_t *)block.vtx[0].vout[n-1].scriptPubKey.data();
157 if ( n <= 2 || script[0] != 0x6a )
158 return(0);
159 offset += komodo_scriptitemlen(&opretlen,&script[offset]);
160 //printf("checkdeposit n.%d [%02x] [%c] %d vs %d\n",n,script[0],script[offset],script[offset],'I');
161 if ( script[offset] == 'I' && opretlen < block.vtx[0].vout[n-1].scriptPubKey.size() )
162 {
163 if ( (num= komodo_issued_opreturn(&shortflag,base,txids,vouts,&script[offset],opretlen)) > 0 )
164 {
165 for (i=1; i<n-1; i++)
166 {
167 for (iter=0; iter<2; iter++)
168 {
169 Q = (iter == 0) ? &DepositsQ : &PendingsQ;
170 portable_mutex_lock(&Q->mutex);
171 ptr = 0;
172 if ( Q->list != 0 )
173 {
174 item = &ptr->DL;
175 matchflag = 0;
176 DL_FOREACH(Q->list,item)
177 {
178 ptr = (struct pax_transaction *)item;
179 if ( memcmp(&ptr->txid,&txids[i-1],sizeof(txids[i-1])) == 0 && ptr->vout == vouts[i-1] )
180 {
181 if ( ptr->fiatoshis == block.vtx[0].vout[i].nValue )
182 {
183 /*for (j=0; j<32; j++)
184 printf("%02x",((uint8_t *)&ptr->txid)[j]);
185 printf(" v%d matched %.8f vout.%d ",ptr->vout,dstr(ptr->fiatoshis),i);
186 hash = block.GetHash();
187 for (j=0; j<32; j++)
188 printf("%02x",((uint8_t *)&hash)[j]);
189 printf(".blockhash\n");*/
190 matchflag = 1;
191 } else printf("error finding %.8f vout.%d\n",dstr(ptr->fiatoshis),i);
192 break;
193 }
194 }
195 }
196 portable_mutex_unlock(&Q->mutex);
197 }
198 if ( matchflag == 0 )
199 {
200 printf("couldnt find vout.[%d]\n",i);
201 return(-1);
202 }
203 }
204 }
205 //printf("opretlen.%d num.%d\n",opretlen,num);
206 }
207 return(0);
208}
209
210const char *komodo_opreturn(int32_t height,uint64_t value,uint8_t *opretbuf,int32_t opretlen,uint256 txid,uint16_t vout)
211{
212 uint8_t rmd160[20],addrtype,shortflag,pubkey33[33]; int32_t i,j,n,len,tokomodo=0; char base[4],coinaddr[64],destaddr[64]; uint256 txids[64]; uint16_t vouts[64]; int64_t fiatoshis,checktoshis; const char *typestr = "unknown";
213 for (i=0; i<opretlen; i++)
214 printf("%02x",opretbuf[i]);
215 printf(" DEPOSIT %.8f %c%s -> %s ",dstr(fiatoshis),shortflag!=0?'-':'+',base,coinaddr);
216 tokomodo = (komodo_is_issuer() == 0);
217 if ( opretbuf[0] == ((tokomodo == 0) ? 'D' : 'W') )
218 {
219 if ( opretlen == 34 )
220 {
221 memset(base,0,sizeof(base));
222 PAX_pubkey(0,&opretbuf[1],&addrtype,rmd160,base,&shortflag,&fiatoshis);
223 if ( fiatoshis < 0 )
224 fiatoshis = -fiatoshis;
225 bitcoin_address(coinaddr,addrtype,rmd160,20);
226 checktoshis = PAX_fiatdest(tokomodo,destaddr,pubkey33,coinaddr,height-1,base,fiatoshis);
227 typestr = "deposit";
228 if ( tokomodo == 0 && strncmp(ASSETCHAINS_SYMBOL,base,strlen(base)) == 0 )
229 {
230 for (i=0; i<32; i++)
231 printf("%02x",((uint8_t *)&txid)[i]);
232 printf(" <- txid.v%u ",vout);
233 for (i=0; i<33; i++)
234 printf("%02x",pubkey33[i]);
235 printf(" checkpubkey check %.8f v %.8f dest.(%s) height.%d\n",dstr(checktoshis),dstr(value),destaddr,height);
236 if ( value >= checktoshis && shortflag == ASSETCHAINS_SHORTFLAG )
237 {
238 komodo_gateway_deposit(coinaddr,value,shortflag,base,fiatoshis,rmd160,txid,vout);
239 }
240 }
241 else
242 {
243 if ( value <= checktoshis )
244 {
245
246 }
247 }
248 }
249 }
250 else if ( strncmp((char *)"KMD",(char *)&opretbuf[opretlen-4],3) != 0 )
251 {
252 if ( tokomodo == 0 && opretbuf[0] == 'I' )
253 {
254 if ( (n= komodo_issued_opreturn(&shortflag,base,txids,vouts,opretbuf,opretlen)) > 0 && shortflag == ASSETCHAINS_SHORTFLAG )
255 {
256 for (i=0; i<n; i++)
257 {
258 for (j=0; j<32; j++)
259 printf("%02x",((uint8_t *)&txids[i])[j]);
260 printf(" issuedtxid v%d i.%d of n.%d opretlen.%d\n",vouts[i],i,n,opretlen);
261 if ( komodo_gateway_depositremove(txids[i],vouts[i]) == 0 )
262 printf("%s error removing deposit\n",ASSETCHAINS_SYMBOL);
263 }
264 }
265 }
266 }
267 return(typestr);
268}
269
270void komodo_gateway_voutupdate(char *symbol,int32_t isspecial,int32_t height,int32_t txi,bits256 txid,int32_t vout,int32_t numvouts,uint64_t value,uint8_t *script,int32_t len)
271{
272 int32_t i,opretlen,offset = 0; uint256 zero,utxid; const char *typestr;
273 typestr = "unknown";
274 memcpy(&utxid,&txid,sizeof(utxid));
275 if ( 0 )//txi != 0 || vout != 0 )
276 {
277 for (i=0; i<len; i++)
278 printf("%02x",script[i]);
279 printf(" <- %s VOUTUPDATE.%d txi.%d vout.%d %.8f scriptlen.%d OP_RETURN.%d (%s) len.%d\n",symbol,height,txi,vout,dstr(value),len,script[0] == 0x6a,typestr,opretlen);
280 }
281 if ( script[offset++] == 0x6a )
282 {
283 offset += komodo_scriptitemlen(&opretlen,&script[offset]);
284 if ( isspecial != 0 && len >= offset+32*2+4 && strcmp((char *)&script[offset+32*2+4],ASSETCHAINS_SYMBOL[0]==0?"KMD":ASSETCHAINS_SYMBOL) == 0 )
285 typestr = "notarized";
286 else if ( txi == 0 && vout == 1 && opretlen == 149 )
287 {
288 typestr = "pricefeed";
289 komodo_paxpricefeed(height,&script[offset],opretlen);
290 //printf("height.%d pricefeed len.%d\n",height,opretlen);
291 }
292 else komodo_stateupdate(height,0,0,0,utxid,0,0,0,0,0,value,&script[offset],opretlen,vout);
293 }
294 else if ( numvouts > 13 )
295 typestr = "ratify";
296}
297
298int32_t komodo_gateway_tx(char *symbol,int32_t height,int32_t txi,char *txidstr,uint32_t port)
299{
300 char *retstr,params[256],*hexstr; uint8_t script[10000]; cJSON *json,*result,*vouts,*item,*sobj; int32_t vout,n,len,isspecial,retval = -1; uint64_t value; bits256 txid;
301 sprintf(params,"[\"%s\", 1]",txidstr);
302 if ( (retstr= komodo_issuemethod((char *)"getrawtransaction",params,port)) != 0 )
303 {
304 if ( (json= cJSON_Parse(retstr)) != 0 )
305 {
306 if ( (result= jobj(json,(char *)"result")) != 0 && (vouts= jarray(&n,result,(char *)"vout")) != 0 )
307 {
308 retval = 0;
309 isspecial = 0;
310 txid = jbits256(result,(char *)"txid");
311 for (vout=0; vout<n; vout++)
312 {
313 item = jitem(vouts,vout);
314 value = SATOSHIDEN * jdouble(item,(char *)"value");
315 if ( (sobj= jobj(item,(char *)"scriptPubKey")) != 0 )
316 {
317 if ( (hexstr= jstr(sobj,(char *)"hex")) != 0 )
318 {
319 len = (int32_t)strlen(hexstr) >> 1;
320 if ( vout == 0 && ((memcmp(&hexstr[2],CRYPTO777_PUBSECPSTR,66) == 0 && len == 35) || (memcmp(&hexstr[6],CRYPTO777_RMD160STR,40) == 0 && len == 25)) )
321 isspecial = 1;
322 else if ( len <= sizeof(script) )
323 {
324 decode_hex(script,len,hexstr);
325 komodo_gateway_voutupdate(symbol,isspecial,height,txi,txid,vout,n,value,script,len);
326 }
327 }
328 }
329 }
330 } else printf("error getting txids.(%s)\n",retstr);
331 free_json(json);
332 }
333 free(retstr);
334 }
335 return(retval);
336}
337
338int32_t komodo_gateway_block(char *symbol,int32_t height,uint16_t port)
339{
340 char *retstr,*retstr2,params[128],*txidstr; int32_t i,n,retval = -1; cJSON *json,*tx=0,*result=0,*result2;
341 sprintf(params,"[%d]",height);
342 if ( (retstr= komodo_issuemethod((char *)"getblockhash",params,port)) != 0 )
343 {
344 if ( (result= cJSON_Parse(retstr)) != 0 )
345 {
346 if ( (txidstr= jstr(result,(char *)"result")) != 0 && strlen(txidstr) == 64 )
347 {
348 sprintf(params,"[\"%s\"]",txidstr);
349 if ( (retstr2= komodo_issuemethod((char *)"getblock",params,port)) != 0 )
350 {
351 //printf("getblock.(%s)\n",retstr2);
352 if ( (json= cJSON_Parse(retstr2)) != 0 )
353 {
354 if ( (result2= jobj(json,(char *)"result")) != 0 && (tx= jarray(&n,result2,(char *)"tx")) != 0 )
355 {
356 for (i=0; i<n; i++)
357 if ( komodo_gateway_tx(symbol,height,i,jstri(tx,i),port) < 0 )
358 break;
359 if ( i == n )
360 retval = 0;
361 else printf("komodo_gateway_block ht.%d error i.%d vs n.%d\n",height,i,n);
362 } else printf("cant get result.%p or tx.%p\n",result,tx);
363 free_json(json);
364 } else printf("cant parse2.(%s)\n",retstr2);
365 free(retstr2);
366 } else printf("error getblock %s\n",params);
367 } else printf("strlen.%ld (%s)\n",strlen(txidstr),txidstr);
368 free_json(result);
369 } else printf("couldnt parse.(%s)\n",retstr);
370 free(retstr);
371 } else printf("error from getblockhash %d\n",height);
372 return(retval);
373}
374
375void komodo_gateway_iteration(char *symbol)
376{
377 char *retstr; int32_t i,kmdheight; cJSON *infoobj,*result; uint256 zero; uint16_t port = 7771;
378 if ( KMDHEIGHT <= 0 )
379 KMDHEIGHT = 1;
380 if ( (retstr= komodo_issuemethod((char *)"getinfo",0,port)) != 0 )
381 {
382 if ( (infoobj= cJSON_Parse(retstr)) != 0 )
383 {
384 if ( (result= jobj(infoobj,(char *)"result")) != 0 && (kmdheight= jint(result,(char *)"blocks")) != 0 )
385 {
386 for (i=0; i<1000 && KMDHEIGHT<kmdheight; i++,KMDHEIGHT++)
387 {
388 if ( (KMDHEIGHT % 100) == 0 )
389 {
390 fprintf(stderr,"%s.%d ",symbol,KMDHEIGHT);
391 memset(&zero,0,sizeof(zero));
392 komodo_stateupdate(KMDHEIGHT,0,0,0,zero,0,0,0,0,KMDHEIGHT,0,0,0,0);
393 }
394 if ( komodo_gateway_block(symbol,KMDHEIGHT,port) < 0 )
395 {
396 printf("error KMDHEIGHT %d\n",KMDHEIGHT);
397 break;
398 }
399 usleep(10000);
400 }
401 }
402 free_json(infoobj);
403 }
404 free(retstr);
405 }
406 else
407 {
408 printf("error from %s\n",symbol);
409 sleep(30);
410 }
411}
412
413#ifdef KOMODO_ISSUER
414void komodo_gateway_issuer() // from "assetchain" connectblock()
415{
416 // check for redeems
417}
418#else
419
420void komodo_gateway_redeemer() // from "KMD" connectblock()
421{
422
423}
424#endif
This page took 0.023926 seconds and 4 git commands to generate.