]> Git Repo - VerusCoin.git/blame - src/komodo_gateway.h
test
[VerusCoin.git] / src / komodo_gateway.h
CommitLineData
9b0e1808 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
f38345e9 16// paxdeposit equivalent in reverse makes opreturn and KMD does the same in reverse
f38345e9 17
429dabb5 18struct pax_transaction
64bb0834 19{
429dabb5 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
0fc3f7d3 27int32_t komodo_issued_opreturn(uint8_t *shortflagp,char *base,uint256 *txids,uint16_t *vouts,uint8_t *opretbuf,int32_t opretlen)
63b289ad 28{
e2c35fcd 29 int32_t i,n=0,j,len;
63b289ad 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];
63b289ad 35 if ( strncmp(ASSETCHAINS_SYMBOL,base,strlen(base)) == 0 ) // shortflag
36 {
e647aac3 37 //printf("BASE.(%s) vs (%s)\n",base,ASSETCHAINS_SYMBOL);
63b289ad 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++];
e647aac3 44 //printf("%02x",((uint8_t *)&txids[n])[j]);
63b289ad 45 }
46 vouts[n] = opretbuf[len++];
47 vouts[n] = (opretbuf[len++] << 8) | vouts[n];
e647aac3 48 //printf(" issuedtxid v%d i.%d opretlen.%d\n",vouts[n],n,opretlen);
63b289ad 49 }
50 }
51 return(n);
52}
53
50824530 54void komodo_gateway_deposits(CMutableTransaction *txNew)
429dabb5 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;
63b289ad 58 while ( numvouts < 64 && (ptr= (struct pax_transaction *)queue_dequeue(&DepositsQ)) != 0 )
429dabb5 59 {
50824530 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];
429dabb5 64 *script++ = 0x76;
65 *script++ = 0xa9;
66 *script++ = 20;
b9a9c9fa 67 memcpy(script,ptr->rmd160,20), script += 20;
429dabb5 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;
2b4feae2 77 printf(" vout.%u DEPOSIT %.8f <- paxdeposit.%s\n",ptr->vout,(double)txNew->vout[numvouts].nValue/COIN,ASSETCHAINS_SYMBOL);
429dabb5 78 PENDING_KOMODO_TX += ptr->fiatoshis;
79 numvouts++;
a856c56a 80 queue_enqueue((char *)"PENDINGS",&PendingsQ,&ptr->DL);
429dabb5 81 }
2f74c54e 82 while ( (ptr= (struct pax_transaction *)queue_dequeue(&PendingsQ)) != 0 )
83 queue_enqueue((char *)"DEPOSITS",&DepositsQ,&ptr->DL);
429dabb5 84 if ( numvouts > 1 )
85 {
a5ad8f02 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;
429dabb5 91 opretlen = komodo_opreturnscript(opret,'I',data,len);
50824530 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];
429dabb5 96 memcpy(script,opret,opretlen);
e2133528 97 printf("total numvouts.%d %.8f opretlen.%d\n",numvouts,dstr(PENDING_KOMODO_TX),opretlen);
50824530 98 } else KOMODO_DEPOSIT = 0;
429dabb5 99}
100
f2ab07e1 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
429dabb5 102{
103 struct pax_transaction *ptr;
b9a9c9fa 104 ptr = (struct pax_transaction *)calloc(1,sizeof(*ptr));
429dabb5 105 ptr->komodoshis = value;
106 ptr->fiatoshis = fiatoshis;
107 memcpy(ptr->symbol,symbol,3);
19b3d41f 108 memcpy(ptr->rmd160,rmd160,20);
429dabb5 109 ptr->shortflag = shortflag;
110 ptr->txid = txid;
111 ptr->vout = vout;
112 KOMODO_DEPOSIT += fiatoshis;
f2ab07e1 113 printf("ADD DEPOSIT %s %.8f -> %s TO QUEUE\n",symbol,dstr(fiatoshis),coinaddr);
a856c56a 114 queue_enqueue((char *)"DEPOSITS",&DepositsQ,&ptr->DL);
429dabb5 115}
116
eae0d2e5 117int32_t komodo_gateway_depositremove(uint256 txid,uint16_t vout) // assetchain context
429dabb5 118{
021f8bc6 119 int32_t iter,i,n=0; queue_t *Q; struct pax_transaction *ptr; struct queueitem *item;
429dabb5 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 {
e8548bcb 126 item = &ptr->DL;
127 DL_FOREACH(Q->list,item)
429dabb5 128 {
552eb795 129 ptr = (struct pax_transaction *)item;
429dabb5 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;
021f8bc6 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));
a730c1c3 138 DL_DELETE(Q->list,&ptr->DL);
eae0d2e5 139 n++;
4c4100cc 140 free(ptr);
429dabb5 141 break;
142 }
143 }
144 }
145 portable_mutex_unlock(&Q->mutex);
146 }
cd21f5a6 147 if ( queue_size(&DepositsQ) == 0 && queue_size(&PendingsQ) == 0 )
7672a125 148 KOMODO_DEPOSIT = PENDING_KOMODO_TX = 0;
eae0d2e5 149 return(n);
429dabb5 150}
151
557d9a23 152int32_t komodo_check_deposit(const CBlock& block) // verify above block is valid pax pricing
153{
0dbbf6de 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;
557d9a23 155 n = block.vtx[0].vout.size();
156 script = (uint8_t *)block.vtx[0].vout[n-1].scriptPubKey.data();
12d47153 157 if ( n <= 2 || script[0] != 0x6a )
158 return(0);
159 offset += komodo_scriptitemlen(&opretlen,&script[offset]);
b98053e2 160 //printf("checkdeposit n.%d [%02x] [%c] %d vs %d\n",n,script[0],script[offset],script[offset],'I');
12d47153 161 if ( script[offset] == 'I' && opretlen < block.vtx[0].vout[n-1].scriptPubKey.size() )
557d9a23 162 {
12d47153 163 if ( (num= komodo_issued_opreturn(&shortflag,base,txids,vouts,&script[offset],opretlen)) > 0 )
557d9a23 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;
3eda531d 179 if ( memcmp(&ptr->txid,&txids[i-1],sizeof(txids[i-1])) == 0 && ptr->vout == vouts[i-1] )
557d9a23 180 {
181 if ( ptr->fiatoshis == block.vtx[0].vout[i].nValue )
182 {
0dbbf6de 183 /*for (j=0; j<32; j++)
65c873ea 184 printf("%02x",((uint8_t *)&ptr->txid)[j]);
16918b24 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]);
0dbbf6de 189 printf(".blockhash\n");*/
557d9a23 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 }
b98053e2 205 //printf("opretlen.%d num.%d\n",opretlen,num);
557d9a23 206 }
207 return(0);
208}
209
429dabb5 210const char *komodo_opreturn(int32_t height,uint64_t value,uint8_t *opretbuf,int32_t opretlen,uint256 txid,uint16_t vout)
211{
0fc3f7d3 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";
23d34a32 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);
8e3430ee 216 tokomodo = (komodo_is_issuer() == 0);
bbf6ba61 217 if ( opretbuf[0] == ((tokomodo == 0) ? 'D' : 'W') )
64bb0834 218 {
219 if ( opretlen == 34 )
220 {
552bdf22 221 memset(base,0,sizeof(base));
64bb0834 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);
77701fd3 226 checktoshis = PAX_fiatdest(tokomodo,destaddr,pubkey33,coinaddr,height-1,base,fiatoshis);
64bb0834 227 typestr = "deposit";
bbf6ba61 228 if ( tokomodo == 0 && strncmp(ASSETCHAINS_SYMBOL,base,strlen(base)) == 0 )
429dabb5 229 {
8e3430ee 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]);
45440ae3 235 printf(" checkpubkey check %.8f v %.8f dest.(%s) height.%d\n",dstr(checktoshis),dstr(value),destaddr,height);
4ef3572a 236 if ( value >= checktoshis && shortflag == ASSETCHAINS_SHORTFLAG )
8e3430ee 237 {
f2ab07e1 238 komodo_gateway_deposit(coinaddr,value,shortflag,base,fiatoshis,rmd160,txid,vout);
8e3430ee 239 }
429dabb5 240 }
8e3430ee 241 else
8bc1bcad 242 {
bfeb1976 243 if ( value <= checktoshis )
8e3430ee 244 {
245
246 }
8bc1bcad 247 }
64bb0834 248 }
249 }
402d5759 250 else if ( strncmp((char *)"KMD",(char *)&opretbuf[opretlen-4],3) != 0 )
429dabb5 251 {
63b289ad 252 if ( tokomodo == 0 && opretbuf[0] == 'I' )
429dabb5 253 {
a55c8425 254 if ( (n= komodo_issued_opreturn(&shortflag,base,txids,vouts,opretbuf,opretlen)) > 0 && shortflag == ASSETCHAINS_SHORTFLAG )
429dabb5 255 {
63b289ad 256 for (i=0; i<n; i++)
ec35af90 257 {
8e3430ee 258 for (j=0; j<32; j++)
021f8bc6 259 printf("%02x",((uint8_t *)&txids[i])[j]);
e2c35fcd 260 printf(" issuedtxid v%d i.%d of n.%d opretlen.%d\n",vouts[i],i,n,opretlen);
63b289ad 261 if ( komodo_gateway_depositremove(txids[i],vouts[i]) == 0 )
0dbbf6de 262 printf("%s error removing deposit\n",ASSETCHAINS_SYMBOL);
ec35af90 263 }
429dabb5 264 }
429dabb5 265 }
266 }
64bb0834 267 return(typestr);
268}
269
eae0d2e5 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)
f38345e9 271{
eae0d2e5 272 int32_t i,opretlen,offset = 0; uint256 zero,utxid; const char *typestr;
57abdbaf 273 typestr = "unknown";
eae0d2e5 274 memcpy(&utxid,&txid,sizeof(utxid));
552bdf22 275 if ( 0 )//txi != 0 || vout != 0 )
0201d1a6 276 {
277 for (i=0; i<len; i++)
278 printf("%02x",script[i]);
7127dc4e 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);
0201d1a6 280 }
64bb0834 281 if ( script[offset++] == 0x6a )
654330ab 282 {
b673d264 283 offset += komodo_scriptitemlen(&opretlen,&script[offset]);
557d9a23 284 if ( isspecial != 0 && len >= offset+32*2+4 && strcmp((char *)&script[offset+32*2+4],ASSETCHAINS_SYMBOL[0]==0?"KMD":ASSETCHAINS_SYMBOL) == 0 )
654330ab 285 typestr = "notarized";
7eca18ee 286 else if ( txi == 0 && vout == 1 && opretlen == 149 )
9b9adadc 287 {
654330ab 288 typestr = "pricefeed";
e7e817f7 289 komodo_paxpricefeed(height,&script[offset],opretlen);
0765bc71 290 //printf("height.%d pricefeed len.%d\n",height,opretlen);
9b9adadc 291 }
eae0d2e5 292 else komodo_stateupdate(height,0,0,0,utxid,0,0,0,0,0,value,&script[offset],opretlen,vout);
654330ab 293 }
294 else if ( numvouts > 13 )
295 typestr = "ratify";
f38345e9 296}
297
c59a3beb 298int32_t komodo_gateway_tx(char *symbol,int32_t height,int32_t txi,char *txidstr,uint32_t port)
c42b46db 299{
eae0d2e5 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;
f38345e9 301 sprintf(params,"[\"%s\", 1]",txidstr);
302 if ( (retstr= komodo_issuemethod((char *)"getrawtransaction",params,port)) != 0 )
c42b46db 303 {
f38345e9 304 if ( (json= cJSON_Parse(retstr)) != 0 )
c42b46db 305 {
f686d848 306 if ( (result= jobj(json,(char *)"result")) != 0 && (vouts= jarray(&n,result,(char *)"vout")) != 0 )
2c6bdd83 307 {
c59a3beb 308 retval = 0;
f38345e9 309 isspecial = 0;
aecaf4bd 310 txid = jbits256(result,(char *)"txid");
f38345e9 311 for (vout=0; vout<n; vout++)
2c6bdd83 312 {
f38345e9 313 item = jitem(vouts,vout);
1b7416b6 314 value = SATOSHIDEN * jdouble(item,(char *)"value");
315 if ( (sobj= jobj(item,(char *)"scriptPubKey")) != 0 )
2c6bdd83 316 {
1b7416b6 317 if ( (hexstr= jstr(sobj,(char *)"hex")) != 0 )
2c6bdd83 318 {
f38345e9 319 len = (int32_t)strlen(hexstr) >> 1;
844a6138 320 if ( vout == 0 && ((memcmp(&hexstr[2],CRYPTO777_PUBSECPSTR,66) == 0 && len == 35) || (memcmp(&hexstr[6],CRYPTO777_RMD160STR,40) == 0 && len == 25)) )
f38345e9 321 isspecial = 1;
bfa5b4f2 322 else if ( len <= sizeof(script) )
f38345e9 323 {
324 decode_hex(script,len,hexstr);
429dabb5 325 komodo_gateway_voutupdate(symbol,isspecial,height,txi,txid,vout,n,value,script,len);
f38345e9 326 }
2c6bdd83 327 }
328 }
2c6bdd83 329 }
4f593916 330 } else printf("error getting txids.(%s)\n",retstr);
f38345e9 331 free_json(json);
332 }
333 free(retstr);
c42b46db 334 }
c59a3beb 335 return(retval);
c42b46db 336}
337
c59a3beb 338int32_t komodo_gateway_block(char *symbol,int32_t height,uint16_t port)
9b0e1808 339{
d4c346d6 340 char *retstr,*retstr2,params[128],*txidstr; int32_t i,n,retval = -1; cJSON *json,*tx=0,*result=0,*result2;
f38345e9 341 sprintf(params,"[%d]",height);
342 if ( (retstr= komodo_issuemethod((char *)"getblockhash",params,port)) != 0 )
343 {
e14a749a 344 if ( (result= cJSON_Parse(retstr)) != 0 )
f38345e9 345 {
f686d848 346 if ( (txidstr= jstr(result,(char *)"result")) != 0 && strlen(txidstr) == 64 )
f38345e9 347 {
e14a749a 348 sprintf(params,"[\"%s\"]",txidstr);
349 if ( (retstr2= komodo_issuemethod((char *)"getblock",params,port)) != 0 )
f38345e9 350 {
f686d848 351 //printf("getblock.(%s)\n",retstr2);
e14a749a 352 if ( (json= cJSON_Parse(retstr2)) != 0 )
f38345e9 353 {
f686d848 354 if ( (result2= jobj(json,(char *)"result")) != 0 && (tx= jarray(&n,result2,(char *)"tx")) != 0 )
e14a749a 355 {
356 for (i=0; i<n; i++)
c59a3beb 357 if ( komodo_gateway_tx(symbol,height,i,jstri(tx,i),port) < 0 )
358 break;
359 if ( i == n )
360 retval = 0;
4f593916 361 else printf("komodo_gateway_block ht.%d error i.%d vs n.%d\n",height,i,n);
d4c346d6 362 } else printf("cant get result.%p or tx.%p\n",result,tx);
e14a749a 363 free_json(json);
d4c346d6 364 } else printf("cant parse2.(%s)\n",retstr2);
e14a749a 365 free(retstr2);
d4c346d6 366 } else printf("error getblock %s\n",params);
e14a749a 367 } else printf("strlen.%ld (%s)\n",strlen(txidstr),txidstr);
368 free_json(result);
d4c346d6 369 } else printf("couldnt parse.(%s)\n",retstr);
f38345e9 370 free(retstr);
d4c346d6 371 } else printf("error from getblockhash %d\n",height);
c59a3beb 372 return(retval);
9b0e1808 373}
374
f38345e9 375void komodo_gateway_iteration(char *symbol)
376{
2b84e06c 377 char *retstr; int32_t i,kmdheight; cJSON *infoobj,*result; uint256 zero; uint16_t port = 7771;
12546443 378 if ( KMDHEIGHT <= 0 )
379 KMDHEIGHT = 1;
f38345e9 380 if ( (retstr= komodo_issuemethod((char *)"getinfo",0,port)) != 0 )
381 {
382 if ( (infoobj= cJSON_Parse(retstr)) != 0 )
383 {
830fc774 384 if ( (result= jobj(infoobj,(char *)"result")) != 0 && (kmdheight= jint(result,(char *)"blocks")) != 0 )
f38345e9 385 {
d360ffce 386 for (i=0; i<1000 && KMDHEIGHT<kmdheight; i++,KMDHEIGHT++)
f38345e9 387 {
c59a3beb 388 if ( (KMDHEIGHT % 100) == 0 )
2b84e06c 389 {
d46594e2 390 fprintf(stderr,"%s.%d ",symbol,KMDHEIGHT);
2b84e06c 391 memset(&zero,0,sizeof(zero));
429dabb5 392 komodo_stateupdate(KMDHEIGHT,0,0,0,zero,0,0,0,0,KMDHEIGHT,0,0,0,0);
2b84e06c 393 }
c59a3beb 394 if ( komodo_gateway_block(symbol,KMDHEIGHT,port) < 0 )
d4c346d6 395 {
396 printf("error KMDHEIGHT %d\n",KMDHEIGHT);
c59a3beb 397 break;
d4c346d6 398 }
4563911d 399 usleep(10000);
f38345e9 400 }
401 }
402 free_json(infoobj);
403 }
f38345e9 404 free(retstr);
bb7f7473 405 }
406 else
407 {
a55c8425 408 printf("error from %s\n",symbol);
bb7f7473 409 sleep(30);
410 }
f38345e9 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()
9b0e1808 421{
422
f38345e9 423}
424#endif
This page took 0.117768 seconds and 4 git commands to generate.