struct pax_transaction
{
- struct queueitem DL;
+ UT_hash_handle hh;
uint256 txid;
uint64_t komodoshis,fiatoshis;
+ int32_t mark;
uint16_t vout;
- char symbol[4]; uint8_t rmd160[20],shortflag;
-};
+ char symbol[16]; uint8_t rmd160[20],shortflag;
+} *PAX;
-void komodo_gateway_deposits(CMutableTransaction& txNew)
+void 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
{
- struct pax_transaction *ptr; uint8_t *script,opret[10000],data[10000]; int32_t i,len=0,opretlen=0,numvouts=1;
+ struct pax_transaction *pax;
+ pax = (struct pax_transaction *)calloc(1,sizeof(*pax));
+ strcpy(pax->coinaddr,coinaddr);
+ pax->komodoshis = value;
+ pax->shortflag = shortflag;
+ strcpy(pax->symbol,symbol);
+ pax->fiatoshis = fiatoshis;
+ memcpy(pax->rmd160,rmd160,20);
+ pax->txid = txid;
+ pax->vout = vout;
+ printf("ADD DEPOSIT %s %.8f -> %s TO PAX\n",symbol,dstr(fiatoshis),coinaddr);
+ pthread_mutex_lock(&komodo_mutex);
+ HASH_ADD_KEYPTR(hh,PAX,&pax->txid,sizeof(pax->txid),pax);
+ pthread_mutex_unlock(&komodo_mutex);
+ KOMODO_DEPOSIT += fiatoshis;
+}
+
+struct pax_transaction *komodo_paxfind(struct pax_transaction *space,uint256 txid,uint16_t vout)
+{
+ struct pax_transaction *pax;
+ pthread_mutex_lock(&komodo_mutex);
+ HASH_FIND(hh,PAX,&txid,sizeof(txid),pax);
+ if ( pax != 0 )
+ memcpy(space,pax,sizeof(*pax));
+ pthread_mutex_unlock(&komodo_mutex);
+ return(pax);
+}
+
+struct pax_transaction *komodo_paxmark(struct pax_transaction *space,uint256 txid,uint16_t vout,int32_t mark)
+{
+ struct pax_transaction *pax;
+ pthread_mutex_lock(&komodo_mutex);
+ HASH_FIND(hh,PAX,&txid,sizeof(txid),pax);
+ if ( pax != 0 )
+ {
+ pax->marked = mark;
+ memcpy(space,pax,sizeof(*pax));
+ }
+ pthread_mutex_unlock(&komodo_mutex);
+ return(pax);
+}
+
+int32_t komodo_issued_opreturn(uint8_t *shortflagp,char *base,uint256 *txids,uint16_t *vouts,uint8_t *opretbuf,int32_t opretlen)
+{
+ int32_t i,n=0,j,len;
+ if ( opretbuf[opretlen-5] == '-' )
+ *shortflagp = 1;
+ else *shortflagp = 0;
+ for (i=0; i<4; i++)
+ base[i] = opretbuf[opretlen-4+i];
+ if ( strncmp(ASSETCHAINS_SYMBOL,base,strlen(base)) == 0 ) // shortflag
+ {
+ //printf("BASE.(%s) vs (%s)\n",base,ASSETCHAINS_SYMBOL);
+ opretbuf++, opretlen--;
+ for (n=len=0; n<opretlen/34; n++)
+ {
+ for (j=0; j<32; j++)
+ {
+ ((uint8_t *)&txids[n])[j] = opretbuf[len++];
+ //printf("%02x",((uint8_t *)&txids[n])[j]);
+ }
+ vouts[n] = opretbuf[len++];
+ vouts[n] = (opretbuf[len++] << 8) | vouts[n];
+ //printf(" issuedtxid v%d i.%d opretlen.%d\n",vouts[n],n,opretlen);
+ }
+ }
+ return(n);
+}
+
+void komodo_gateway_deposits(CMutableTransaction *txNew)
+{
+ struct pax_transaction *pax,*tmp; uint8_t *script,opret[10000],data[10000]; int32_t i,len=0,opretlen=0,numvouts=1;
PENDING_KOMODO_TX = 0;
- while ( (ptr= (struct pax_transaction *)queue_dequeue(&DepositsQ)) != 0 )
+ HASH_ITER(hh,PAX,ptr,tmp)
{
- txNew.vout.resize(numvouts+1);
- txNew.vout[numvouts].nValue = ptr->fiatoshis;
- txNew.vout[numvouts].scriptPubKey.resize(25);
- script = (uint8_t *)&txNew.vout[numvouts].scriptPubKey[0];
+ if ( pax->mark != 0 )
+ continue;
+ txNew->vout.resize(numvouts+1);
+ txNew->vout[numvouts].nValue = ptr->fiatoshis;
+ txNew->vout[numvouts].scriptPubKey.resize(25);
+ script = (uint8_t *)&txNew->vout[numvouts].scriptPubKey[0];
*script++ = 0x76;
*script++ = 0xa9;
*script++ = 20;
}
data[len++] = ptr->vout & 0xff;
data[len++] = (ptr->vout >> 8) & 0xff;
- printf(" vout.%u DEPOSIT %.8f\n",ptr->vout,(double)KOMODO_DEPOSIT/COIN);
+ printf(" vout.%u DEPOSIT %.8f <- paxdeposit.%s\n",ptr->vout,(double)txNew->vout[numvouts].nValue/COIN,ASSETCHAINS_SYMBOL);
PENDING_KOMODO_TX += ptr->fiatoshis;
- numvouts++;
- queue_enqueue((char *)"PENDINGS",&PendingsQ,&ptr->DL);
+ if ( numvouts++ >= 64 )
+ break;
}
if ( numvouts > 1 )
{
+ if ( ASSETCHAINS_SHORTFLAG != 0 )
+ data[len++] = '-';
+ for (i=0; ASSETCHAINS_SYMBOL[i]!=0; i++)
+ data[len++] = ASSETCHAINS_SYMBOL[i];
+ data[len++] = 0;
opretlen = komodo_opreturnscript(opret,'I',data,len);
- txNew.vout.resize(numvouts+1);
- txNew.vout[numvouts].nValue = 0;
- txNew.vout[numvouts].scriptPubKey.resize(opretlen);
- script = (uint8_t *)&txNew.vout[numvouts].scriptPubKey[0];
+ txNew->vout.resize(numvouts+1);
+ txNew->vout[numvouts].nValue = 0;
+ txNew->vout[numvouts].scriptPubKey.resize(opretlen);
+ script = (uint8_t *)&txNew->vout[numvouts].scriptPubKey[0];
memcpy(script,opret,opretlen);
- }
- printf("total numvouts.%d %.8f\n",numvouts,dstr(PENDING_KOMODO_TX));
-}
-
-void komodo_gateway_deposit(uint64_t value,int32_t shortflag,char *symbol,uint64_t fiatoshis,uint8_t *rmd160,uint256 txid,uint16_t vout) // assetchain context
-{
- struct pax_transaction *ptr;
- ptr = (struct pax_transaction *)calloc(1,sizeof(*ptr));
- ptr->komodoshis = value;
- ptr->fiatoshis = fiatoshis;
- memcpy(ptr->symbol,symbol,3);
- memcpy(ptr->rmd160,rmd160,20);
- ptr->shortflag = shortflag;
- ptr->txid = txid;
- ptr->vout = vout;
- KOMODO_DEPOSIT += fiatoshis;
- queue_enqueue((char *)"DEPOSITS",&DepositsQ,&ptr->DL);
+ printf("total numvouts.%d %.8f opretlen.%d\n",numvouts,dstr(PENDING_KOMODO_TX),opretlen);
+ } else KOMODO_DEPOSIT = 0;
}
-int32_t komodo_gateway_depositremove(uint256 txid,uint16_t vout) // assetchain context
+int32_t komodo_check_deposit(int32_t height,const CBlock& block) // verify above block is valid pax pricing
{
- int32_t iter,n=0; queue_t *Q; struct pax_transaction *ptr; struct queueitem *item;
- for (iter=0; iter<2; iter++)
+ int32_t i,j,n,opretlen,offset=1; uint256 hash,txids[64]; uint8_t shortflag; char base[16]; uint16_t vouts[64]; uint8_t *script; struct pax_transaction *pax,space;
+ n = block.vtx[0].vout.size();
+ script = (uint8_t *)block.vtx[0].vout[n-1].scriptPubKey.data();
+ if ( n <= 2 || script[0] != 0x6a )
+ return(0);
+ offset += komodo_scriptitemlen(&opretlen,&script[offset]);
+ //printf("checkdeposit n.%d [%02x] [%c] %d vs %d\n",n,script[0],script[offset],script[offset],'I');
+ if ( script[offset] == 'I' && opretlen < block.vtx[0].vout[n-1].scriptPubKey.size() )
{
- Q = (iter == 0) ? &DepositsQ : &PendingsQ;
- portable_mutex_lock(&Q->mutex);
- if ( Q->list != 0 )
+ if ( (num= komodo_issued_opreturn(&shortflag,base,txids,vouts,&script[offset],opretlen)) > 0 )
{
- item = &ptr->DL;
- DL_FOREACH(Q->list,item)
+ for (i=1; i<n-1; i++)
{
- ptr = (struct pax_transaction *)item;
- if ( memcmp(&ptr->txid,&txid,sizeof(txid)) == 0 && ptr->vout == vout )
- {
- if ( KOMODO_DEPOSIT >= ptr->fiatoshis )
- KOMODO_DEPOSIT -= ptr->fiatoshis;
- else KOMODO_DEPOSIT = 0;
- printf("DELETE %.8f DEPOSIT %s %.8f\n",dstr(ptr->komodoshis),ptr->symbol,dstr(ptr->fiatoshis));
- DL_DELETE(Q->list,&ptr->DL);
- n++;
- free(ptr);
+ if ( (pax= komodo_paxfind(&space,txids[i-1],vouts[i-1])) == 0 || ptr->fiatoshis != block.vtx[0].vout[i].nValue )
break;
- }
+ }
+ if ( i != n-1 )
+ {
+ hash = block.GetHash();
+ for (j=0; j<32; j++)
+ printf("%02x",((uint8_t *)&hash)[j]);
+ printf(" ht.%d blockhash couldnt find vout.[%d]\n",height,i);
+ //return(-1);
}
}
- portable_mutex_unlock(&Q->mutex);
+ //printf("opretlen.%d num.%d\n",opretlen,num);
}
- return(n);
+ return(0);
}
const char *komodo_opreturn(int32_t height,uint64_t value,uint8_t *opretbuf,int32_t opretlen,uint256 txid,uint16_t vout)
{
- uint8_t rmd160[20],addrtype,shortflag,pubkey33[33]; int32_t i,j,len,tokomodo=0; char base[4],coinaddr[64],destaddr[64]; int64_t fiatoshis,checktoshis; const char *typestr = "unknown";
- //printf("komodo_opreturn[%c]: ht.%d %.8f opretlen.%d\n",opretbuf[0],height,dstr(value),opretlen);
-#ifdef KOMODO_ISSUER
- tokomodo = 1;
-#endif
- if ( opretbuf[0] == ((tokomodo != 0) ? 'D' : 'W') )
+ uint8_t rmd160[20],addrtype,shortflag,pubkey33[33]; int32_t i,j,n,len,tokomodo=0; char base[4],coinaddr[64],destaddr[64]; struct pax_transaction space; uint256 txids[64]; uint16_t vouts[64]; int64_t fiatoshis,checktoshis; const char *typestr = "unknown";
+ tokomodo = (komodo_is_issuer() == 0);
+ //for (i=0; i<opretlen; i++)
+ // printf("%02x",opretbuf[i]);
+ //printf(" DEPOSIT.[%c] tokomodo.%d %.8f %c%s -> %s ",opretbuf[0],tokomodo,dstr(fiatoshis),shortflag!=0?'-':'+',base,coinaddr);
+ if ( opretbuf[0] == ((tokomodo == 0) ? 'D' : 'W') )
{
if ( opretlen == 34 )
{
if ( fiatoshis < 0 )
fiatoshis = -fiatoshis;
bitcoin_address(coinaddr,addrtype,rmd160,20);
- checktoshis = PAX_fiatdest(tokomodo,destaddr,pubkey33,coinaddr,height,base,fiatoshis);
- for (i=0; i<opretlen; i++)
- printf("%02x",opretbuf[i]);
- printf(" DEPOSIT %.8f %c%s -> %s ",dstr(fiatoshis),shortflag!=0?'-':'+',base,coinaddr);
- for (i=0; i<32; i++)
- printf("%02x",((uint8_t *)&txid)[i]);
- printf(" <- txid.v%u ",vout);
- for (i=0; i<33; i++)
- printf("%02x",pubkey33[i]);
- printf(" checkpubkey check %.8f v %.8f dest.(%s)\n",dstr(checktoshis),dstr(value),destaddr);
+ checktoshis = PAX_fiatdest(tokomodo,destaddr,pubkey33,coinaddr,height-1,base,fiatoshis);
typestr = "deposit";
-#ifdef KOMODO_ISSUER
- if ( strncmp(KOMODO_SOURCE,base,strlen(base)) == 0 && value >= (9999*checktoshis)/10000 && shortflag == ASSETCHAINS_SHORTFLAG )
+ if ( tokomodo == 0 && strncmp(ASSETCHAINS_SYMBOL,base,strlen(base)) == 0 )
{
- komodo_gateway_deposit(value,shortflag,base,fiatoshis,rmd160,txid,vout);
+ for (i=0; i<32; i++)
+ printf("%02x",((uint8_t *)&txid)[i]);
+ printf(" <- txid.v%u ",vout);
+ for (i=0; i<33; i++)
+ printf("%02x",pubkey33[i]);
+ printf(" checkpubkey check %.8f v %.8f dest.(%s) height.%d\n",dstr(checktoshis),dstr(value),destaddr,height);
+ if ( value >= checktoshis && shortflag == ASSETCHAINS_SHORTFLAG )
+ {
+ komodo_gateway_deposit(coinaddr,value,shortflag,base,fiatoshis,rmd160,txid,vout);
+ }
}
-#else
- if ( tokomodo != 0 && value <= (10000*checktoshis)/9999 )
+ else
{
-
+ if ( value <= checktoshis )
+ {
+
+ }
}
-#endif
}
}
- else if ( opretbuf[0] == 'I' )
+ else if ( strncmp((char *)"KMD",(char *)&opretbuf[opretlen-4],3) != 0 )
{
- uint256 issuedtxid; uint16_t issuedvout;
- opretbuf++, opretlen--;
- for (i=len=0; i<opretlen/34; i++)
+ if ( tokomodo == 0 && opretbuf[0] == 'I' )
{
- for (j=0; j<32; j++)
+ if ( (n= komodo_issued_opreturn(&shortflag,base,txids,vouts,opretbuf,opretlen)) > 0 && shortflag == ASSETCHAINS_SHORTFLAG )
{
- ((uint8_t *)&issuedtxid)[j] = opretbuf[len++];
- printf("%02x",((uint8_t *)&issuedtxid)[j]);
+ for (i=0; i<n; i++)
+ {
+ for (j=0; j<32; j++)
+ printf("%02x",((uint8_t *)&txids[i])[j]);
+ printf(" issuedtxid v%d i.%d of n.%d opretlen.%d\n",vouts[i],i,n,opretlen);
+ if ( komodo_paxmark(&space,txids[i],vouts[i],height) == 0 )
+ printf("%s error removing deposit\n",ASSETCHAINS_SYMBOL);
+ }
}
- issuedvout = opretbuf[len++];
- issuedvout = (vout << 8) | opretbuf[len++];
- printf(" issuedtxid v%d i.%d opretlen.%d\n",issuedvout,i,opretlen);
- if ( komodo_gateway_depositremove(issuedtxid,issuedvout) == 0 )
- printf("error removing deposit\n");
}
}
return(typestr);
if ( script[offset++] == 0x6a )
{
offset += komodo_scriptitemlen(&opretlen,&script[offset]);
- if ( isspecial != 0 && len >= offset+32*2+4 && strcmp((char *)&script[offset+32*2+4],"KMD") == 0 )
+ if ( isspecial != 0 && len >= offset+32*2+4 && strcmp((char *)&script[offset+32*2+4],ASSETCHAINS_SYMBOL[0]==0?"KMD":ASSETCHAINS_SYMBOL) == 0 )
typestr = "notarized";
else if ( txi == 0 && vout == 1 && opretlen == 149 )
{
{
retval = 0;
isspecial = 0;
+ txid = jbits256(result,(char *)"txid");
for (vout=0; vout<n; vout++)
{
item = jitem(vouts,vout);
- txid = jbits256(item,(char *)"txid");
value = SATOSHIDEN * jdouble(item,(char *)"value");
if ( (sobj= jobj(item,(char *)"scriptPubKey")) != 0 )
{
if ( (hexstr= jstr(sobj,(char *)"hex")) != 0 )
{
len = (int32_t)strlen(hexstr) >> 1;
- if ( 0 && len != 74 )
- printf("ht.%d txi.%d vout.%d/%d %s script (%d %d)\n",height,txi,vout,n,hexstr,memcmp(&hexstr[2],CRYPTO777_PUBSECPSTR,66),memcmp(&hexstr[6],CRYPTO777_RMD160STR,40));
if ( vout == 0 && ((memcmp(&hexstr[2],CRYPTO777_PUBSECPSTR,66) == 0 && len == 35) || (memcmp(&hexstr[6],CRYPTO777_RMD160STR,40) == 0 && len == 25)) )
isspecial = 1;
else if ( len <= sizeof(script) )
}
}
}
- }
+ } else printf("error getting txids.(%s)\n",retstr);
free_json(json);
}
free(retstr);
int32_t komodo_gateway_block(char *symbol,int32_t height,uint16_t port)
{
- char *retstr,*retstr2,params[128],*txidstr; int32_t i,n,retval = -1; cJSON *json,*tx,*result,*result2;
+ char *retstr,*retstr2,params[128],*txidstr; int32_t i,n,retval = -1; cJSON *json,*tx=0,*result=0,*result2;
sprintf(params,"[%d]",height);
if ( (retstr= komodo_issuemethod((char *)"getblockhash",params,port)) != 0 )
{
break;
if ( i == n )
retval = 0;
- else printf("error i.%d vs n.%d\n",i,n);
- }
+ else printf("komodo_gateway_block ht.%d error i.%d vs n.%d\n",height,i,n);
+ } else printf("cant get result.%p or tx.%p\n",result,tx);
free_json(json);
- }
+ } else printf("cant parse2.(%s)\n",retstr2);
free(retstr2);
- }
+ } else printf("error getblock %s\n",params);
} else printf("strlen.%ld (%s)\n",strlen(txidstr),txidstr);
free_json(result);
- }
+ } else printf("couldnt parse.(%s)\n",retstr);
free(retstr);
- }
+ } else printf("error from getblockhash %d\n",height);
return(retval);
}
char *retstr; int32_t i,kmdheight; cJSON *infoobj,*result; uint256 zero; uint16_t port = 7771;
if ( KMDHEIGHT <= 0 )
KMDHEIGHT = 1;
+ KOMODO_REALTIME = 0;
if ( (retstr= komodo_issuemethod((char *)"getinfo",0,port)) != 0 )
{
if ( (infoobj= cJSON_Parse(retstr)) != 0 )
{
for (i=0; i<1000 && KMDHEIGHT<kmdheight; i++,KMDHEIGHT++)
{
- //printf("KMDHEIGHT %d\n",KMDHEIGHT);
if ( (KMDHEIGHT % 100) == 0 )
{
fprintf(stderr,"%s.%d ",symbol,KMDHEIGHT);
komodo_stateupdate(KMDHEIGHT,0,0,0,zero,0,0,0,0,KMDHEIGHT,0,0,0,0);
}
if ( komodo_gateway_block(symbol,KMDHEIGHT,port) < 0 )
+ {
+ printf("error KMDHEIGHT %d\n",KMDHEIGHT);
break;
+ }
usleep(10000);
}
+ if ( KMDHEIGHT >= kmdheight )
+ KOMODO_REALTIME = (uint32_t)time(NULL);
}
free_json(infoobj);
}
}
else
{
- //printf("error from %s\n",symbol);
+ printf("error from %s\n",symbol);
sleep(30);
}
}
-
-#ifdef KOMODO_ISSUER
-void komodo_gateway_issuer() // from "assetchain" connectblock()
-{
- // check for redeems
-}
-#else
-
-void komodo_gateway_redeemer() // from "KMD" connectblock()
-{
-
-}
-#endif