|
|
|
/******************************************************************************
|
|
|
|
* Copyright © 2014-2016 The SuperNET Developers. *
|
|
|
|
* *
|
|
|
|
* See the AUTHORS, DEVELOPER-AGREEMENT and LICENSE files at *
|
|
|
|
* the top-level directory of this distribution for the individual copyright *
|
|
|
|
* holder information and the developer policies on copyright and licensing. *
|
|
|
|
* *
|
|
|
|
* Unless otherwise agreed in a custom licensing agreement, no part of the *
|
|
|
|
* SuperNET software, including this file may be copied, modified, propagated *
|
|
|
|
* or distributed except according to the terms contained in the LICENSE file *
|
|
|
|
* *
|
|
|
|
* Removal or modification of this copyright notice is prohibited. *
|
|
|
|
* *
|
|
|
|
******************************************************************************/
|
|
|
|
|
|
|
|
// komodo functions that interact with bitcoind C++
|
|
|
|
|
|
|
|
#ifdef _WIN32
|
|
|
|
#include <curl.h>
|
|
|
|
#include <easy.h>
|
|
|
|
#else
|
|
|
|
#include <curl/curl.h>
|
|
|
|
#include <curl/easy.h>
|
|
|
|
#endif
|
|
|
|
|
|
|
|
struct MemoryStruct { char *memory; size_t size; };
|
|
|
|
|
|
|
|
static size_t WriteMemoryCallback(void *ptr,size_t size,size_t nmemb,void *data)
|
|
|
|
{
|
|
|
|
size_t realsize = (size * nmemb);
|
|
|
|
struct MemoryStruct *mem = (struct MemoryStruct *)data;
|
|
|
|
mem->memory = (char *)((ptr != 0) ? realloc(mem->memory,mem->size + realsize + 1) : malloc(mem->size + realsize + 1));
|
|
|
|
if ( mem->memory != 0 )
|
|
|
|
{
|
|
|
|
if ( ptr != 0 )
|
|
|
|
memcpy(&(mem->memory[mem->size]),ptr,realsize);
|
|
|
|
mem->size += realsize;
|
|
|
|
mem->memory[mem->size] = 0;
|
|
|
|
}
|
|
|
|
//printf("got %d bytes\n",(int32_t)(size*nmemb));
|
|
|
|
return(realsize);
|
|
|
|
}
|
|
|
|
|
|
|
|
char *curl_post(CURL **cHandlep,char *url,char *userpass,char *postfields,char *hdr0,char *hdr1,char *hdr2,char *hdr3)
|
|
|
|
{
|
|
|
|
struct MemoryStruct chunk; CURL *cHandle; long code; struct curl_slist *headers = 0;
|
|
|
|
if ( (cHandle= *cHandlep) == NULL )
|
|
|
|
*cHandlep = cHandle = curl_easy_init();
|
|
|
|
else curl_easy_reset(cHandle);
|
|
|
|
//#ifdef DEBUG
|
|
|
|
//curl_easy_setopt(cHandle,CURLOPT_VERBOSE, 1);
|
|
|
|
//#endif
|
|
|
|
curl_easy_setopt(cHandle,CURLOPT_USERAGENT,"mozilla/4.0");//"Mozilla/4.0 (compatible; )");
|
|
|
|
curl_easy_setopt(cHandle,CURLOPT_SSL_VERIFYPEER,0);
|
|
|
|
//curl_easy_setopt(cHandle,CURLOPT_SSLVERSION,1);
|
|
|
|
curl_easy_setopt(cHandle,CURLOPT_URL,url);
|
|
|
|
curl_easy_setopt(cHandle,CURLOPT_CONNECTTIMEOUT,10);
|
|
|
|
if ( userpass != 0 && userpass[0] != 0 )
|
|
|
|
curl_easy_setopt(cHandle,CURLOPT_USERPWD,userpass);
|
|
|
|
if ( postfields != 0 && postfields[0] != 0 )
|
|
|
|
{
|
|
|
|
curl_easy_setopt(cHandle,CURLOPT_POST,1);
|
|
|
|
curl_easy_setopt(cHandle,CURLOPT_POSTFIELDS,postfields);
|
|
|
|
}
|
|
|
|
if ( hdr0 != NULL && hdr0[0] != 0 )
|
|
|
|
{
|
|
|
|
//printf("HDR0.(%s) HDR1.(%s) HDR2.(%s) HDR3.(%s)\n",hdr0!=0?hdr0:"",hdr1!=0?hdr1:"",hdr2!=0?hdr2:"",hdr3!=0?hdr3:"");
|
|
|
|
headers = curl_slist_append(headers,hdr0);
|
|
|
|
if ( hdr1 != 0 && hdr1[0] != 0 )
|
|
|
|
headers = curl_slist_append(headers,hdr1);
|
|
|
|
if ( hdr2 != 0 && hdr2[0] != 0 )
|
|
|
|
headers = curl_slist_append(headers,hdr2);
|
|
|
|
if ( hdr3 != 0 && hdr3[0] != 0 )
|
|
|
|
headers = curl_slist_append(headers,hdr3);
|
|
|
|
} //headers = curl_slist_append(0,"Expect:");
|
|
|
|
if ( headers != 0 )
|
|
|
|
curl_easy_setopt(cHandle,CURLOPT_HTTPHEADER,headers);
|
|
|
|
//res = curl_easy_perform(cHandle);
|
|
|
|
memset(&chunk,0,sizeof(chunk));
|
|
|
|
curl_easy_setopt(cHandle,CURLOPT_WRITEFUNCTION,WriteMemoryCallback);
|
|
|
|
curl_easy_setopt(cHandle,CURLOPT_WRITEDATA,(void *)&chunk);
|
|
|
|
curl_easy_perform(cHandle);
|
|
|
|
curl_easy_getinfo(cHandle,CURLINFO_RESPONSE_CODE,&code);
|
|
|
|
if ( headers != 0 )
|
|
|
|
curl_slist_free_all(headers);
|
|
|
|
if ( code != 200 )
|
|
|
|
printf("(%s) server responded with code %ld (%s)\n",url,code,chunk.memory);
|
|
|
|
return(chunk.memory);
|
|
|
|
}
|
|
|
|
|
|
|
|
char *komodo_issuemethod(char *method,char *params)
|
|
|
|
{
|
|
|
|
static void *cHandle; extern char USERPASS[1024]; extern uint16_t BITCOIND_PORT;
|
|
|
|
char url[512],*retstr=0,postdata[8192];
|
|
|
|
if ( strlen(params) < sizeof(postdata)-128 )
|
|
|
|
{
|
|
|
|
if ( params == 0 )
|
|
|
|
params = (char *)"[]";
|
|
|
|
sprintf(url,(char *)"http://127.0.0.1:%u",BITCOIND_PORT);
|
|
|
|
sprintf(postdata,"{\"method\":\"%s\",\"params\":%s}",method,params);
|
|
|
|
retstr = curl_post(&cHandle,url,USERPASS,postdata,0,0,0,0);
|
|
|
|
}
|
|
|
|
return(retstr);
|
|
|
|
}
|
|
|
|
|
|
|
|
uint32_t komodo_txtime(uint256 hash)
|
|
|
|
{
|
|
|
|
CTransaction tx;
|
|
|
|
uint256 hashBlock;
|
|
|
|
if (!GetTransaction(hash, tx,
|
|
|
|
#ifndef KOMODO_ZCASH
|
|
|
|
Params().GetConsensus(),
|
|
|
|
#endif
|
|
|
|
hashBlock, true))
|
|
|
|
{
|
|
|
|
//printf("null GetTransaction\n");
|
|
|
|
return(tx.nLockTime);
|
|
|
|
}
|
|
|
|
return(0);
|
|
|
|
}
|
|
|
|
|
|
|
|
void komodo_disconnect(CBlockIndex *pindex,CBlock& block)
|
|
|
|
{
|
|
|
|
komodo_init();
|
|
|
|
//uint256 zero;
|
|
|
|
//printf("disconnect ht.%d\n",pindex->nHeight);
|
|
|
|
//memset(&zero,0,sizeof(zero));
|
|
|
|
//komodo_stateupdate(-pindex->nHeight,0,0,0,zero,0,0,0,0);
|
|
|
|
}
|
|
|
|
|
|
|
|
int32_t komodo_block2height(CBlock *block)
|
|
|
|
{
|
|
|
|
int32_t i,n,height = 0; uint8_t *ptr;
|
|
|
|
komodo_init();
|
|
|
|
#ifdef KOMODO_ZCASH
|
|
|
|
ptr = (uint8_t *)block->vtx[0].vin[0].scriptSig.data();
|
|
|
|
#else
|
|
|
|
ptr = (uint8_t *)&block->vtx[0].vin[0].scriptSig[0];
|
|
|
|
#endif
|
|
|
|
if ( block->vtx[0].vin[0].scriptSig.size() > 5 )
|
|
|
|
{
|
|
|
|
//for (i=0; i<6; i++)
|
|
|
|
// printf("%02x",ptr[i]);
|
|
|
|
n = ptr[0];
|
|
|
|
for (i=0; i<n; i++)
|
|
|
|
{
|
|
|
|
//03bb81000101(bb 187) (81 48001) (00 12288256) <- coinbase.6 ht.12288256
|
|
|
|
height += ((uint32_t)ptr[i+1] << (i*8));
|
|
|
|
//printf("(%02x %x %d) ",ptr[i+1],((uint32_t)ptr[i+1] << (i*8)),height);
|
|
|
|
}
|
|
|
|
//printf(" <- coinbase.%d ht.%d\n",(int32_t)block->vtx[0].vin[0].scriptSig.size(),height);
|
|
|
|
}
|
|
|
|
return(height);
|
|
|
|
}
|
|
|
|
|
|
|
|
void komodo_block2pubkey33(uint8_t *pubkey33,CBlock& block)
|
|
|
|
{
|
|
|
|
#ifdef KOMODO_ZCASH
|
|
|
|
uint8_t *ptr = (uint8_t *)block.vtx[0].vout[0].scriptPubKey.data();
|
|
|
|
#else
|
|
|
|
uint8_t *ptr = (uint8_t *)&block.vtx[0].vout[0].scriptPubKey[0];
|
|
|
|
#endif
|
|
|
|
komodo_init();
|
|
|
|
memcpy(pubkey33,ptr+1,33);
|
|
|
|
}
|
|
|
|
|
|
|
|
void komodo_index2pubkey33(uint8_t *pubkey33,CBlockIndex *pindex,int32_t height)
|
|
|
|
{
|
|
|
|
CBlock block;
|
|
|
|
komodo_init();
|
|
|
|
memset(pubkey33,0,33);
|
|
|
|
if ( pindex != 0 )
|
|
|
|
{
|
|
|
|
if ( ReadBlockFromDisk(block,(const CBlockIndex *)pindex
|
|
|
|
#ifndef KOMODO_ZCASH
|
|
|
|
,Params().GetConsensus()
|
|
|
|
#endif
|
|
|
|
) != 0 )
|
|
|
|
{
|
|
|
|
komodo_block2pubkey33(pubkey33,block);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
// height -> pubkey33
|
|
|
|
//printf("extending chaintip komodo_index2pubkey33 height.%d need to get pubkey33\n",height);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
int32_t komodo_checkpoint(int32_t *notarized_heightp,int32_t nHeight,uint256 hash)
|
|
|
|
{
|
|
|
|
int32_t notarized_height; uint256 notarized_hash,notarized_desttxid; CBlockIndex *notary;
|
|
|
|
notarized_height = komodo_notarizeddata(chainActive.Tip()->nHeight,¬arized_hash,¬arized_desttxid);
|
|
|
|
*notarized_heightp = notarized_height;
|
|
|
|
if ( notarized_height >= 0 && notarized_height <= chainActive.Tip()->nHeight && (notary= mapBlockIndex[notarized_hash]) != 0 )
|
|
|
|
{
|
|
|
|
//printf("nHeight.%d -> (%d %s)\n",chainActive.Tip()->nHeight,notarized_height,notarized_hash.ToString().c_str());
|
|
|
|
if ( notary->nHeight == notarized_height ) // if notarized_hash not in chain, reorg
|
|
|
|
{
|
|
|
|
if ( nHeight < notarized_height )
|
|
|
|
{
|
|
|
|
fprintf(stderr,"nHeight.%d < NOTARIZED_HEIGHT.%d\n",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);
|
|
|
|
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 )
|
|
|
|
fprintf(stderr,"couldnt find notary_hash %s ht.%d\n",notarized_hash.ToString().c_str(),notarized_height);
|
|
|
|
return(0);
|
|
|
|
}
|