// komodo functions that interact with bitcoind C++
#ifdef _WIN32
-#include <curl.h>
-#include <easy.h>
+#include <curl/curl.h>
+#include <curl/easy.h>
#else
#include <curl/curl.h>
#include <curl/easy.h>
#endif
-#define issue_curl(cmdstr) bitcoind_RPC(0,(char *)"curl",(char *)"http://127.0.0.1:7776",0,0,(char *)(cmdstr))
+#include "komodo_defs.h"
+
+int32_t komodo_notaries(uint8_t pubkeys[64][33],int32_t height,uint32_t timestamp);
+int32_t komodo_electednotary(int32_t *numnotariesp,uint8_t *pubkey33,int32_t height,uint32_t timestamp);
+
+//#define issue_curl(cmdstr) bitcoind_RPC(0,(char *)"curl",(char *)"http://127.0.0.1:7776",0,0,(char *)(cmdstr))
struct MemoryStruct { char *memory; size_t size; };
struct return_string { char *ptr; size_t len; };
curl_handle = curl_easy_init();
init_string(&s);
headers = curl_slist_append(0,"Expect:");
-
+
curl_easy_setopt(curl_handle,CURLOPT_USERAGENT,"mozilla/4.0");//"Mozilla/4.0 (compatible; )");
curl_easy_setopt(curl_handle,CURLOPT_HTTPHEADER, headers);
curl_easy_setopt(curl_handle,CURLOPT_URL, url);
bracket0 = (char *)"[";
bracket1 = (char *)"]";
}
-
+
databuf = (char *)malloc(256 + strlen(command) + strlen(params));
sprintf(databuf,"{\"id\":\"jl777\",\"method\":\"%s\",\"params\":%s%s%s}",command,bracket0,params,bracket1);
//printf("url.(%s) userpass.(%s) databuf.(%s)\n",url,userpass,databuf);
free(s.ptr);
sleep((1<<numretries));
goto try_again;
-
+
}
else
{
{
sprintf(url,(char *)"http://127.0.0.1:%u",port);
sprintf(postdata,"{\"method\":\"%s\",\"params\":%s}",method,params);
- //printf("postdata.(%s) USERPASS.(%s)\n",postdata,KMDUSERPASS);
+ //printf("[%s] (%s) postdata.(%s) params.(%s) USERPASS.(%s)\n",ASSETCHAINS_SYMBOL,url,postdata,params,KMDUSERPASS);
retstr2 = bitcoind_RPC(&retstr,(char *)"debug",url,userpass,method,params);
//retstr = curl_post(&cHandle,url,USERPASS,postdata,0,0,0,0);
}
*kmdnotarized_heightp = 0;
if ( strcmp(dest,"KMD") == 0 )
{
- port = 7771;
+ port = KMD_PORT;
userpass = KMDUSERPASS;
}
else if ( strcmp(dest,"BTC") == 0 )
printf(" notarized, ");
for (i=0; i<32; i++)
printf("%02x",((uint8_t *)&hash)[i]);
- printf(" opreturn from [%s] ht.%d\n",ASSETCHAINS_SYMBOL,height);
+ printf(" opreturn from [%s] ht.%d MISMATCHED\n",ASSETCHAINS_SYMBOL,height);
return(-1);
}
int32_t komodo_verifynotarization(char *symbol,char *dest,int32_t height,int32_t NOTARIZED_HEIGHT,uint256 NOTARIZED_HASH,uint256 NOTARIZED_DESTTXID)
{
- char params[256],*jsonstr,*hexstr; uint8_t script[8192]; int32_t n,len,retval = -1; cJSON *json,*txjson,*vouts,*vout,*skey;
+ char params[256],*jsonstr,*hexstr; uint8_t *script,_script[8192]; int32_t n,len,retval = -1; cJSON *json,*txjson,*vouts,*vout,*skey;
+ script = _script;
/*params[0] = '[';
params[1] = '"';
for (i=0; i<32; i++)
sprintf(params,"[\"%s\", 1]",NOTARIZED_DESTTXID.ToString().c_str());
if ( strcmp(symbol,ASSETCHAINS_SYMBOL[0]==0?(char *)"KMD":ASSETCHAINS_SYMBOL) != 0 )
return(0);
- //printf("[%s] src.%s dest.%s params.[%s] ht.%d notarized.%d\n",ASSETCHAINS_SYMBOL,symbol,dest,params,height,NOTARIZED_HEIGHT);
+ if ( 0 && ASSETCHAINS_SYMBOL[0] != 0 )
+ printf("[%s] src.%s dest.%s params.[%s] ht.%d notarized.%d\n",ASSETCHAINS_SYMBOL,symbol,dest,params,height,NOTARIZED_HEIGHT);
if ( strcmp(dest,"KMD") == 0 )
{
if ( KMDUSERPASS[0] != 0 )
- jsonstr = komodo_issuemethod(KMDUSERPASS,(char *)"getrawtransaction",params,7771);
- //else jsonstr = _dex_getrawtransaction();
+ {
+ if ( ASSETCHAINS_SYMBOL[0] != 0 )
+ {
+ jsonstr = komodo_issuemethod(KMDUSERPASS,(char *)"getrawtransaction",params,KMD_PORT);
+//printf("userpass.(%s) got (%s)\n",KMDUSERPASS,jsonstr);
+ }
+ }//else jsonstr = _dex_getrawtransaction();
else return(0); // need universal way to issue DEX* API, since notaries mine most blocks, this ok
}
else if ( strcmp(dest,"BTC") == 0 )
if ( (txjson= jobj(json,(char *)"result")) != 0 && (vouts= jarray(&n,txjson,(char *)"vout")) > 0 )
{
vout = jitem(vouts,n-1);
- //printf("vout.(%s)\n",jprint(vout,0));
+ if ( 0 && ASSETCHAINS_SYMBOL[0] != 0 )
+ printf("vout.(%s)\n",jprint(vout,0));
if ( (skey= jobj(vout,(char *)"scriptPubKey")) != 0 )
{
if ( (hexstr= jstr(skey,(char *)"hex")) != 0 )
{
- //printf("HEX.(%s)\n",hexstr);
+ //printf("HEX.(%s) vs hash.%s\n",hexstr,NOTARIZED_HASH.ToString().c_str());
len = strlen(hexstr) >> 1;
decode_hex(script,len,hexstr);
+ if ( script[1] == 0x4c )
+ {
+ script++;
+ len--;
+ }
+ else if ( script[1] == 0x4d )
+ {
+ script += 2;
+ len -= 2;
+ }
retval = komodo_verifynotarizedscript(height,script,len,NOTARIZED_HASH);
}
}
return(retval);
}
-uint256 komodo_getblockhash(int32_t height)
+/*uint256 komodo_getblockhash(int32_t height)
{
uint256 hash; char params[128],*hexstr,*jsonstr; cJSON *result; int32_t i; uint8_t revbuf[32];
memset(&hash,0,sizeof(hash));
sprintf(params,"[%d]",height);
- if ( (jsonstr= komodo_issuemethod(KMDUSERPASS,(char *)"getblockhash",params,7771)) != 0 )
+ if ( (jsonstr= komodo_issuemethod(KMDUSERPASS,(char *)"getblockhash",params,BITCOIND_PORT)) != 0 )
{
if ( (result= cJSON_Parse(jsonstr)) != 0 )
{
return(hash);
}
-uint256 _komodo_getblockhash(int32_t height);
+uint256 _komodo_getblockhash(int32_t height);*/
uint64_t komodo_seed(int32_t height)
{
uint64_t seed = 0;
- if ( 0 ) // problem during init time, seeds are needed for loading blockindex, so null seeds...
+ /*if ( 0 ) // problem during init time, seeds are needed for loading blockindex, so null seeds...
{
uint256 hash,zero; CBlockIndex *pindex;
memset(&hash,0,sizeof(hash));
printf(" seed.%d\n",height);
seed = arith_uint256(hash.GetHex()).GetLow64();
}
- else
+ else*/
{
seed = (height << 13) ^ (height << 2);
seed <<= 21;
return(seed);
}
-uint32_t komodo_txtime(uint256 hash)
+uint32_t komodo_txtime(uint64_t *valuep,uint256 hash,int32_t n)
{
CTransaction tx;
uint256 hashBlock;
+ *valuep = 0;
if (!GetTransaction(hash, tx,
#ifndef KOMODO_ZCASH
Params().GetConsensus(),
hashBlock, true))
{
//printf("null GetTransaction\n");
+ if ( n < tx.vout.size() )
+ *valuep = tx.vout[n].nValue;
return(tx.nLockTime);
}
return(0);
void komodo_disconnect(CBlockIndex *pindex,CBlock& block)
{
- char symbol[16],dest[16]; struct komodo_state *sp;
+ char symbol[KOMODO_ASSETCHAIN_MAXLEN],dest[KOMODO_ASSETCHAIN_MAXLEN]; struct komodo_state *sp;
+ //fprintf(stderr,"disconnect ht.%d\n",pindex->nHeight);
komodo_init(pindex->nHeight);
if ( (sp= komodo_stateptr(symbol,dest)) != 0 )
{
int32_t komodo_is_notarytx(const CTransaction& tx)
{
- uint8_t *ptr,crypto777[33];
+ uint8_t *ptr; static uint8_t crypto777[33];
if ( tx.vout.size() > 0 )
{
#ifdef KOMODO_ZCASH
#endif
if ( ptr != 0 )
{
- decode_hex(crypto777,33,(char *)CRYPTO777_PUBSECPSTR);
+ if ( crypto777[0] == 0 )
+ decode_hex(crypto777,33,(char *)CRYPTO777_PUBSECPSTR);
if ( memcmp(ptr+1,crypto777,33) == 0 )
{
//printf("found notarytx\n");
int32_t komodo_block2height(CBlock *block)
{
- int32_t i,n,height = 0; uint8_t *ptr;
+ static uint32_t match,mismatch;
+ int32_t i,n,height2=-1,height = 0; uint8_t *ptr; CBlockIndex *pindex;
+ if ( (pindex= mapBlockIndex[block->GetHash()]) != 0 )
+ {
+ height2 = (int32_t)pindex->nHeight;
+ if ( height2 >= 0 )
+ return(height2);
+ }
if ( block->vtx[0].vin.size() > 0 )
{
#ifdef KOMODO_ZCASH
//for (i=0; i<6; i++)
// printf("%02x",ptr[i]);
n = ptr[0];
- for (i=0; i<n; i++)
+ for (i=0; i<n; i++) // looks strange but this works
{
//03bb81000101(bb 187) (81 48001) (00 12288256) <- coinbase.6 ht.12288256
height += ((uint32_t)ptr[i+1] << (i*8));
}
//komodo_init(height);
}
+ if ( height != height2 )
+ {
+ fprintf(stderr,"block2height height.%d vs height2.%d, match.%d mismatch.%d\n",height,height2,match,mismatch);
+ mismatch++;
+ if ( height2 >= 0 )
+ height = height2;
+ } else match++;
return(height);
}
return(0);
}
+uint32_t komodo_chainactive_timestamp()
+{
+ if ( chainActive.Tip() != 0 )
+ return((uint32_t)chainActive.Tip()->GetBlockTime());
+ else return(0);
+}
+
CBlockIndex *komodo_chainactive(int32_t height)
{
if ( chainActive.Tip() != 0 )
CBlockIndex *ptr;
if ( height > 0 && (ptr= komodo_chainactive(height)) != 0 )
return(ptr->nTime);
- else fprintf(stderr,"komodo_heightstamp null ptr for block.%d\n",height);
+ //else fprintf(stderr,"komodo_heightstamp null ptr for block.%d\n",height);
return(0);
}
void komodo_index2pubkey33(uint8_t *pubkey33,CBlockIndex *pindex,int32_t height)
{
- CBlock block;
+ CBlock block; int32_t num,i; uint8_t pubkeys[64][33];
//komodo_init(height);
memset(pubkey33,0,33);
if ( pindex != 0 )
{
+ if ( pindex->pubkey33[0] == 2 || pindex->pubkey33[0] == 3 )
+ {
+ memcpy(pubkey33,pindex->pubkey33,33);
+ return;
+ }
if ( komodo_blockload(block,pindex) == 0 )
+ {
komodo_block2pubkey33(pubkey33,block);
+ if ( (pubkey33[0] == 2 || pubkey33[0] == 3) )
+ {
+ memcpy(pindex->pubkey33,pubkey33,33);
+ if ( (num= komodo_notaries(pubkeys,(int32_t)pindex->nHeight,(uint32_t)pindex->nTime)) > 0 )
+ {
+ pindex->notaryid = -1;
+ for (i=0; i<num; i++)
+ {
+ if ( memcmp(pubkeys[i],pubkey33,33) == 0 )
+ {
+ pindex->notaryid = i;
+ break;
+ }
+ }
+ }
+ } else pindex->notaryid = -1;
+ }
}
else
{
}
}
-void komodo_connectpindex(CBlockIndex *pindex)
+/*void komodo_connectpindex(CBlockIndex *pindex)
{
CBlock block;
if ( komodo_blockload(block,pindex) == 0 )
komodo_connectblock(pindex,block);
-}
+}*/
-int32_t komodo_notaries(uint8_t pubkeys[64][33],int32_t height);
-int32_t komodo_electednotary(uint8_t *pubkey33,int32_t height);
int8_t komodo_minerid(int32_t height,uint8_t *pubkey33)
{
- int32_t num,i; CBlockIndex *pindex; uint8_t _pubkey33[33],pubkeys[64][33];
- if ( pubkey33 == 0 && (pindex= chainActive[height]) != 0 )
+ int32_t num,i,numnotaries; CBlockIndex *pindex; uint32_t timestamp=0; uint8_t _pubkey33[33],pubkeys[64][33];
+ if ( (pindex= chainActive[height]) != 0 )
{
- if ( pubkey33 == 0 )
+ if ( (pindex->pubkey33[0] == 2 || pindex->pubkey33[0] == 3) )
{
- pubkey33 = _pubkey33;
- komodo_index2pubkey33(pubkey33,pindex,height);
+ if ( pubkey33 != 0 )
+ memcpy(pubkey33,pindex->pubkey33,33);
+ return(pindex->notaryid);
}
- if ( (num= komodo_notaries(pubkeys,height)) > 0 )
+ if ( pubkey33 != 0 )
+ komodo_index2pubkey33(pubkey33,pindex,height);
+ timestamp = pindex->GetBlockTime();
+ if ( (num= komodo_notaries(pubkeys,height,timestamp)) > 0 )
{
for (i=0; i<num; i++)
if ( memcmp(pubkeys[i],pubkey33,33) == 0 )
return(i);
}
}
- return(komodo_electednotary(pubkey33,height));
+ return(komodo_electednotary(&numnotaries,pubkey33,height,timestamp));
}
int32_t komodo_eligiblenotary(uint8_t pubkeys[66][33],int32_t *mids,int32_t *nonzpkeysp,int32_t height)
{
if ( (pindex= komodo_chainactive(height-i)) != 0 )
{
- komodo_index2pubkey33(pubkey33,pindex,height-i);
- for (j=0; j<33; j++)
- pubkeys[i][j] = pubkey33[j];
- if ( (mids[i]= komodo_minerid(height-i,pubkey33)) >= 0 )
+ if ( pindex->notaryid >= 0 && (pindex->pubkey33[0] == 2 || pindex->pubkey33[0] == 3) )
{
- //mids[i] = *(int32_t *)pubkey33;
+ memcpy(pubkeys[i],pindex->pubkey33,33);
+ mids[i] = pindex->notaryid;
(*nonzpkeysp)++;
}
+ else
+ {
+ komodo_index2pubkey33(pubkey33,pindex,height-i);
+ memcpy(pubkeys[i],pubkey33,33);
+ if ( (mids[i]= komodo_minerid(height-i,pubkey33)) >= 0 )
+ {
+ //mids[i] = *(int32_t *)pubkey33;
+ (*nonzpkeysp)++;
+ }
+ }
if ( mids[0] >= 0 && i > 0 && mids[i] == mids[0] )
duplicate++;
}
else return(0);
}
-int32_t komodo_minerids(uint8_t *minerids,int32_t height,int32_t width)
+int32_t komodo_minerids(uint8_t *minerids,int32_t height,int32_t width) // deprecate
{
- int32_t i,n=0;
+ /*int32_t i,n=0;
for (i=0; i<width; i++,n++)
{
if ( height-i <= 0 )
break;
minerids[i] = komodo_minerid(height - i,0);
}
- return(n);
+ return(n);*/
+ return(-1);
}
-int32_t komodo_is_special(int32_t height,uint8_t pubkey33[33])
+int32_t komodo_is_special(int32_t height,uint8_t pubkey33[33],uint32_t timestamp)
{
- int32_t i,notaryid=0,minerid,limit,nid; uint8_t _pubkey33[33];
+ int32_t i,notaryid=0,minerid,limit,nid; //uint8_t _pubkey33[33];
if ( height >= 225000 )
- komodo_chosennotary(¬aryid,height,_pubkey33);
+ komodo_chosennotary(¬aryid,height,pubkey33,timestamp);
if ( height >= 34000 && notaryid >= 0 )
{
if ( height < 79693 )
else limit = 66;
for (i=1; i<limit; i++)
{
- komodo_chosennotary(&nid,height-i,_pubkey33);
- if ( nid == notaryid ) //komodo_minerid(height-i,_pubkey33)
+ komodo_chosennotary(&nid,height-i,pubkey33,timestamp);
+ if ( nid == notaryid )
{
if ( (0) && notaryid > 0 )
fprintf(stderr,"ht.%d notaryid.%d already mined -i.%d nid.%d\n",height,notaryid,i,nid);
return(0);
}
+int32_t komodo_MoM(int32_t *notarized_heightp,uint256 *MoMp,uint256 *kmdtxidp,int32_t nHeight)
+{
+ int32_t depth,notarized_ht; uint256 MoM,kmdtxid;
+ depth = komodo_MoMdata(¬arized_ht,&MoM,&kmdtxid,nHeight);
+ memset(MoMp,0,sizeof(*MoMp));
+ memset(kmdtxidp,0,sizeof(*kmdtxidp));
+ *notarized_heightp = 0;
+ if ( depth > 0 && notarized_ht > 0 && nHeight > notarized_ht-depth && nHeight <= notarized_ht )
+ {
+ *MoMp = MoM;
+ *notarized_heightp = notarized_ht;
+ *kmdtxidp = kmdtxid;
+ }
+ return(depth);
+}
+
int32_t komodo_checkpoint(int32_t *notarized_heightp,int32_t nHeight,uint256 hash)
{
- int32_t notarized_height; uint256 notarized_hash,notarized_desttxid; CBlockIndex *notary; CBlockIndex *pindex;
+ int32_t notarized_height,MoMdepth; uint256 MoM,notarized_hash,notarized_desttxid; CBlockIndex *notary,*pindex;
if ( (pindex= chainActive.Tip()) == 0 )
return(-1);
notarized_height = komodo_notarizeddata(pindex->nHeight,¬arized_hash,¬arized_desttxid);
{
if ( nHeight < notarized_height )
{
- fprintf(stderr,"nHeight.%d < NOTARIZED_HEIGHT.%d\n",nHeight,notarized_height);
+ //fprintf(stderr,"[%s] nHeight.%d < NOTARIZED_HEIGHT.%d\n",ASSETCHAINS_SYMBOL,nHeight,notarized_height);
return(-1);
}
else if ( nHeight == notarized_height && memcmp(&hash,¬arized_hash,sizeof(hash)) != 0 )
{
- fprintf(stderr,"nHeight.%d == NOTARIZED_HEIGHT.%d, diff hash\n",nHeight,notarized_height);
+ fprintf(stderr,"[%s] nHeight.%d == NOTARIZED_HEIGHT.%d, diff hash\n",ASSETCHAINS_SYMBOL,nHeight,notarized_height);
return(-1);
}
- } else fprintf(stderr,"unexpected error notary_hash %s ht.%d at ht.%d\n",notarized_hash.ToString().c_str(),notarized_height,notary->nHeight);
- } else if ( notarized_height > 0 && notarized_height != 73880 && notarized_height >= 170000 )
- fprintf(stderr,"[%s] couldnt find notarized.(%s %d) ht.%d\n",ASSETCHAINS_SYMBOL,notarized_hash.ToString().c_str(),notarized_height,pindex->nHeight);
+ } 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);
+ }
+ //else if ( notarized_height > 0 && notarized_height != 73880 && notarized_height >= 170000 )
+ // fprintf(stderr,"[%s] couldnt find notarized.(%s %d) ht.%d\n",ASSETCHAINS_SYMBOL,notarized_hash.ToString().c_str(),notarized_height,pindex->nHeight);
return(0);
}
uint32_t locktime = 0;
if ( n < tx.vout.size() )
{
- if ( (pindex= mapBlockIndex[hashBlock]) != 0 && (tipindex= chainActive.Tip()) != 0 )
+ if ( (pindex= mapBlockIndex[hashBlock]) != 0 )
{
*valuep = tx.vout[n].nValue;
*txheightp = pindex->nHeight;
*txheighttimep = pindex->nTime;
- *tiptimep = tipindex->nTime;
+ if ( *tiptimep == 0 && (tipindex= chainActive.Tip()) != 0 )
+ *tiptimep = (uint32_t)tipindex->nTime;
locktime = tx.nLockTime;
//fprintf(stderr,"tx locktime.%u %.8f height.%d | tiptime.%u\n",locktime,(double)*valuep/COIN,*txheightp,*tiptimep);
}
}
uint64_t komodo_interest(int32_t txheight,uint64_t nValue,uint32_t nLockTime,uint32_t tiptime);
-uint64_t komodo_accrued_interest(int32_t *txheightp,uint32_t *locktimep,uint256 hash,int32_t n,int32_t checkheight,uint64_t checkvalue)
+
+uint64_t komodo_accrued_interest(int32_t *txheightp,uint32_t *locktimep,uint256 hash,int32_t n,int32_t checkheight,uint64_t checkvalue,int32_t tipheight)
{
- uint64_t value; uint32_t tiptime,txheighttimep;
+ uint64_t value; uint32_t tiptime=0,txheighttimep; CBlockIndex *pindex;
+ if ( (pindex= chainActive[tipheight]) != 0 )
+ tiptime = (uint32_t)pindex->nTime;
+ else fprintf(stderr,"cant find height[%d]\n",tipheight);
if ( (*locktimep= komodo_interest_args(&txheighttimep,txheightp,&tiptime,&value,hash,n)) != 0 )
{
if ( (checkvalue == 0 || value == checkvalue) && (checkheight == 0 || *txheightp == checkheight) )
{
if ( tx.nLockTime != 1477258935 || dispflag != 0 )
{
- //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);
+ 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);
}
return(-1);
}
return(0);
}
+int32_t komodo_staked(uint256 *utxotxidp,int32_t *utxovoutp,uint64_t *utxovaluep,uint8_t *utxosig)
+{
+ memset(utxotxidp,0,sizeof(*utxotxidp));
+ memset(utxovoutp,0,sizeof(*utxovoutp));
+ memset(utxovaluep,0,sizeof(*utxovaluep));
+ memset(utxosig,0,72);
+ return(72);
+}
+