|
@ -58,81 +58,6 @@ void dpow_checkpointset(struct supernet_info *myinfo,struct dpow_checkpoint *che |
|
|
checkpoint->blockhash.height = height; |
|
|
checkpoint->blockhash.height = height; |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
int32_t dpow_txhasnotarization(struct supernet_info *myinfo,struct iguana_info *coin,bits256 txid) |
|
|
|
|
|
{ |
|
|
|
|
|
cJSON *txobj,*vins,*vin,*vouts,*vout,*spentobj,*sobj; char *hexstr; uint8_t script[35]; bits256 spenttxid; uint64_t notarymask; int32_t i,j,numnotaries,len,spentvout,numvins,numvouts,hasnotarization = 0; |
|
|
|
|
|
if ( (txobj= dpow_gettransaction(myinfo,coin,txid)) != 0 ) |
|
|
|
|
|
{ |
|
|
|
|
|
if ( (vins= jarray(&numvins,txobj,"vin")) != 0 ) |
|
|
|
|
|
{ |
|
|
|
|
|
if ( numvins >= DPOW_MIN_ASSETCHAIN_SIGS ) |
|
|
|
|
|
{ |
|
|
|
|
|
notarymask = numnotaries = 0; |
|
|
|
|
|
for (i=0; i<numvins; i++) |
|
|
|
|
|
{ |
|
|
|
|
|
vin = jitem(vins,i); |
|
|
|
|
|
spenttxid = jbits256(vin,"txid"); |
|
|
|
|
|
spentvout = jint(vin,"vout"); |
|
|
|
|
|
if ( (spentobj= dpow_gettransaction(myinfo,coin,spenttxid)) != 0 ) |
|
|
|
|
|
{ |
|
|
|
|
|
if ( (vouts= jarray(&numvouts,spentobj,"vout")) != 0 ) |
|
|
|
|
|
{ |
|
|
|
|
|
if ( spentvout < numvouts ) |
|
|
|
|
|
{ |
|
|
|
|
|
vout = jitem(vouts,spentvout); |
|
|
|
|
|
if ( (sobj= jobj(vout,"scriptPubKey")) != 0 && (hexstr= jstr(sobj,"hex")) != 0 && (len= is_hexstr(hexstr,0)) == sizeof(script)*2 ) |
|
|
|
|
|
{ |
|
|
|
|
|
len >>= 1; |
|
|
|
|
|
decode_hex(script,len,hexstr); |
|
|
|
|
|
if ( script[0] == 33 && script[34] == 0xac ) |
|
|
|
|
|
{ |
|
|
|
|
|
for (j=0; j<Notaries_num; j++) |
|
|
|
|
|
{ |
|
|
|
|
|
if ( strncmp(Notaries_elected[j][1],hexstr+2,66) == 0 ) |
|
|
|
|
|
{ |
|
|
|
|
|
if ( ((1LL << j) & notarymask) == 0 ) |
|
|
|
|
|
{ |
|
|
|
|
|
printf("n%d ",j); |
|
|
|
|
|
numnotaries++; |
|
|
|
|
|
notarymask |= (1LL << j); |
|
|
|
|
|
break; |
|
|
|
|
|
} |
|
|
|
|
|
} |
|
|
|
|
|
} |
|
|
|
|
|
} |
|
|
|
|
|
} |
|
|
|
|
|
} |
|
|
|
|
|
} |
|
|
|
|
|
free_json(spentobj); |
|
|
|
|
|
} |
|
|
|
|
|
} |
|
|
|
|
|
if ( numnotaries > 0 ) |
|
|
|
|
|
{ |
|
|
|
|
|
if ( numnotaries >= DPOW_MIN_ASSETCHAIN_SIGS ) |
|
|
|
|
|
hasnotarization = 1; |
|
|
|
|
|
printf("numnotaries.%d %s hasnotarization.%d\n",numnotaries,coin->symbol,hasnotarization); |
|
|
|
|
|
} |
|
|
|
|
|
} |
|
|
|
|
|
} |
|
|
|
|
|
free_json(txobj); |
|
|
|
|
|
} |
|
|
|
|
|
return(hasnotarization); |
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
int32_t dpow_hasnotarization(struct supernet_info *myinfo,struct iguana_info *coin,cJSON *blockjson) |
|
|
|
|
|
{ |
|
|
|
|
|
int32_t i,n,hasnotarization = 0; bits256 txid; cJSON *txarray; |
|
|
|
|
|
if ( (txarray= jarray(&n,blockjson,"tx")) != 0 ) |
|
|
|
|
|
{ |
|
|
|
|
|
for (i=0; i<n; i++) |
|
|
|
|
|
{ |
|
|
|
|
|
txid = jbits256i(txarray,i); |
|
|
|
|
|
hasnotarization += dpow_txhasnotarization(myinfo,coin,txid); |
|
|
|
|
|
} |
|
|
|
|
|
} |
|
|
|
|
|
return(hasnotarization); |
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
void dpow_srcupdate(struct supernet_info *myinfo,struct dpow_info *dp,int32_t height,bits256 hash,uint32_t timestamp,uint32_t blocktime) |
|
|
void dpow_srcupdate(struct supernet_info *myinfo,struct dpow_info *dp,int32_t height,bits256 hash,uint32_t timestamp,uint32_t blocktime) |
|
|
{ |
|
|
{ |
|
|
void **ptrs; char str[65]; cJSON *blockjson; struct iguana_info *coin; struct dpow_checkpoint checkpoint; int32_t freq,minsigs,i,ht; struct dpow_block *bp; |
|
|
void **ptrs; char str[65]; cJSON *blockjson; struct iguana_info *coin; struct dpow_checkpoint checkpoint; int32_t freq,minsigs,i,ht; struct dpow_block *bp; |
|
@ -151,7 +76,7 @@ void dpow_srcupdate(struct supernet_info *myinfo,struct dpow_info *dp,int32_t he |
|
|
else freq = 1; |
|
|
else freq = 1; |
|
|
} |
|
|
} |
|
|
dpow_fifoupdate(myinfo,dp->srcfifo,dp->last); |
|
|
dpow_fifoupdate(myinfo,dp->srcfifo,dp->last); |
|
|
if ( strcmp(dp->dest,"KMD") == 0 ) |
|
|
if ( strcmp(dp->dest,"KMD") == 0 || strcmp(dp->dest,"CHAIN") == 0 ) |
|
|
{ |
|
|
{ |
|
|
//if ( dp->SRCREALTIME == 0 )
|
|
|
//if ( dp->SRCREALTIME == 0 )
|
|
|
// return;
|
|
|
// return;
|
|
@ -162,9 +87,9 @@ void dpow_srcupdate(struct supernet_info *myinfo,struct dpow_info *dp,int32_t he |
|
|
{ |
|
|
{ |
|
|
if ( (blockjson= dpow_getblock(myinfo,coin,hash)) != 0 ) |
|
|
if ( (blockjson= dpow_getblock(myinfo,coin,hash)) != 0 ) |
|
|
{ |
|
|
{ |
|
|
if ( dpow_hasnotarization(myinfo,coin,blockjson) <= 0 ) |
|
|
height = jint(blockjson,"height"); |
|
|
|
|
|
if ( dpow_hasnotarization(myinfo,coin,blockjson,height) <= 0 ) |
|
|
{ |
|
|
{ |
|
|
height = jint(blockjson,"height"); |
|
|
|
|
|
blocktime = juint(blockjson,"time"); |
|
|
blocktime = juint(blockjson,"time"); |
|
|
free_json(blockjson); |
|
|
free_json(blockjson); |
|
|
if ( height > 0 && blocktime > 0 ) |
|
|
if ( height > 0 && blocktime > 0 ) |
|
@ -197,7 +122,7 @@ void dpow_srcupdate(struct supernet_info *myinfo,struct dpow_info *dp,int32_t he |
|
|
ptrs[0] = (void *)myinfo; |
|
|
ptrs[0] = (void *)myinfo; |
|
|
ptrs[1] = (void *)dp; |
|
|
ptrs[1] = (void *)dp; |
|
|
ptrs[2] = (void *)(uint64_t)minsigs; |
|
|
ptrs[2] = (void *)(uint64_t)minsigs; |
|
|
if ( strcmp(dp->dest,"KMD") != 0 ) |
|
|
if ( strcmp(dp->dest,"KMD") != 0 && strcmp(dp->dest,"CHAIN") != 0 ) |
|
|
ptrs[3] = (void *)DPOW_DURATION; |
|
|
ptrs[3] = (void *)DPOW_DURATION; |
|
|
else ptrs[3] = (void *)(DPOW_DURATION * 60); // essentially try forever for assetchains
|
|
|
else ptrs[3] = (void *)(DPOW_DURATION * 60); // essentially try forever for assetchains
|
|
|
ptrs[4] = 0; |
|
|
ptrs[4] = 0; |
|
@ -272,7 +197,7 @@ void dpow_destupdate(struct supernet_info *myinfo,struct dpow_info *dp,int32_t h |
|
|
|
|
|
|
|
|
void iguana_dPoWupdate(struct supernet_info *myinfo,struct dpow_info *dp) |
|
|
void iguana_dPoWupdate(struct supernet_info *myinfo,struct dpow_info *dp) |
|
|
{ |
|
|
{ |
|
|
int32_t height,num; uint32_t blocktime; bits256 blockhash; struct iguana_info *src,*dest; |
|
|
int32_t height,num; uint32_t blocktime; bits256 blockhash,merkleroot; struct iguana_info *src,*dest; |
|
|
//fprintf(stderr,"dp.%p dPoWupdate (%s -> %s)\n",dp,dp!=0?dp->symbol:"",dp!=0?dp->dest:"");
|
|
|
//fprintf(stderr,"dp.%p dPoWupdate (%s -> %s)\n",dp,dp!=0?dp->symbol:"",dp!=0?dp->dest:"");
|
|
|
//if ( strcmp(dp->symbol,"KMD") == 0 )
|
|
|
//if ( strcmp(dp->symbol,"KMD") == 0 )
|
|
|
{ |
|
|
{ |
|
@ -284,7 +209,7 @@ void iguana_dPoWupdate(struct supernet_info *myinfo,struct dpow_info *dp) |
|
|
if ( src != 0 && dest != 0 ) |
|
|
if ( src != 0 && dest != 0 ) |
|
|
{ |
|
|
{ |
|
|
dp->numdesttx = sizeof(dp->desttx)/sizeof(*dp->desttx); |
|
|
dp->numdesttx = sizeof(dp->desttx)/sizeof(*dp->desttx); |
|
|
if ( (height= dpow_getchaintip(myinfo,&blockhash,&blocktime,dp->desttx,&dp->numdesttx,dest)) != dp->destchaintip.blockhash.height && height >= 0 ) |
|
|
if ( (height= dpow_getchaintip(myinfo,&merkleroot,&blockhash,&blocktime,dp->desttx,&dp->numdesttx,dest)) != dp->destchaintip.blockhash.height && height >= 0 ) |
|
|
{ |
|
|
{ |
|
|
char str[65]; |
|
|
char str[65]; |
|
|
if ( strcmp(dp->symbol,"KMD") == 0 )//|| height != dp->destchaintip.blockhash.height+1 )
|
|
|
if ( strcmp(dp->symbol,"KMD") == 0 )//|| height != dp->destchaintip.blockhash.height+1 )
|
|
@ -297,13 +222,13 @@ void iguana_dPoWupdate(struct supernet_info *myinfo,struct dpow_info *dp) |
|
|
} else dpow_destupdate(myinfo,dp,height,blockhash,(uint32_t)time(NULL),blocktime); |
|
|
} else dpow_destupdate(myinfo,dp,height,blockhash,(uint32_t)time(NULL),blocktime); |
|
|
} // else printf("error getchaintip for %s\n",dp->dest);
|
|
|
} // else printf("error getchaintip for %s\n",dp->dest);
|
|
|
dp->numsrctx = sizeof(dp->srctx)/sizeof(*dp->srctx); |
|
|
dp->numsrctx = sizeof(dp->srctx)/sizeof(*dp->srctx); |
|
|
if ( strcmp(dp->dest,"KMD") == 0 && dp->SRCHEIGHT < src->longestchain ) |
|
|
if ( (strcmp(dp->dest,"KMD") == 0 || strcmp(dp->dest,"CHAIN") == 0) && dp->SRCHEIGHT < src->longestchain ) |
|
|
{ |
|
|
{ |
|
|
//fprintf(stderr,"[I ");
|
|
|
//fprintf(stderr,"[I ");
|
|
|
dp->SRCHEIGHT = dpow_issuer_iteration(dp,src,dp->SRCHEIGHT,&dp->SRCREALTIME); |
|
|
dp->SRCHEIGHT = dpow_issuer_iteration(dp,src,dp->SRCHEIGHT,&dp->SRCREALTIME); |
|
|
//fprintf(stderr," %d] ",dp->SRCHEIGHT);
|
|
|
//fprintf(stderr," %d] ",dp->SRCHEIGHT);
|
|
|
} |
|
|
} |
|
|
if ( (height= dpow_getchaintip(myinfo,&blockhash,&blocktime,dp->srctx,&dp->numsrctx,src)) != dp->last.blockhash.height && height >= 0 ) |
|
|
if ( (height= dpow_getchaintip(myinfo,&merkleroot,&blockhash,&blocktime,dp->srctx,&dp->numsrctx,src)) != dp->last.blockhash.height && height >= 0 ) |
|
|
{ |
|
|
{ |
|
|
//char str[65]; printf("[%s].%d %s %s height.%d vs last.%d\n",dp->dest,dp->SRCHEIGHT,dp->symbol,bits256_str(str,blockhash),height,dp->last.blockhash.height);
|
|
|
//char str[65]; printf("[%s].%d %s %s height.%d vs last.%d\n",dp->dest,dp->SRCHEIGHT,dp->symbol,bits256_str(str,blockhash),height,dp->last.blockhash.height);
|
|
|
if ( dp->lastheight == 0 ) |
|
|
if ( dp->lastheight == 0 ) |
|
@ -360,9 +285,9 @@ void dpow_addresses() |
|
|
#include "../includes/iguana_apideclares.h" |
|
|
#include "../includes/iguana_apideclares.h" |
|
|
#include "../includes/iguana_apideclares2.h" |
|
|
#include "../includes/iguana_apideclares2.h" |
|
|
|
|
|
|
|
|
TWO_STRINGS(iguana,dpow,symbol,pubkey) |
|
|
THREE_STRINGS(iguana,dpow,symbol,dest,pubkey) |
|
|
{ |
|
|
{ |
|
|
char *retstr,srcaddr[64],destaddr[64]; struct iguana_info *src,*dest; cJSON *ismine; int32_t i,srcvalid,destvalid; struct dpow_info *dp = &myinfo->DPOWS[myinfo->numdpows]; |
|
|
char *retstr,srcaddr[64],destaddr[64]; struct iguana_info *src,*destcoin; cJSON *ismine; int32_t i,srcvalid,destvalid; struct dpow_info *dp = &myinfo->DPOWS[myinfo->numdpows]; |
|
|
destvalid = srcvalid = 0; |
|
|
destvalid = srcvalid = 0; |
|
|
if ( myinfo->NOTARY.RELAYID < 0 ) |
|
|
if ( myinfo->NOTARY.RELAYID < 0 ) |
|
|
{ |
|
|
{ |
|
@ -380,21 +305,22 @@ TWO_STRINGS(iguana,dpow,symbol,pubkey) |
|
|
return(clonestr("{\"error\":\"need 33 byte pubkey\"}")); |
|
|
return(clonestr("{\"error\":\"need 33 byte pubkey\"}")); |
|
|
if ( symbol == 0 || symbol[0] == 0 ) |
|
|
if ( symbol == 0 || symbol[0] == 0 ) |
|
|
symbol = "KMD"; |
|
|
symbol = "KMD"; |
|
|
|
|
|
if ( dest == 0 || dest[0] == 0 ) |
|
|
|
|
|
{ |
|
|
|
|
|
if ( strcmp(symbol,"KMD") == 0 ) |
|
|
|
|
|
dest = "BTC"; |
|
|
|
|
|
else dest = "KMD"; |
|
|
|
|
|
} |
|
|
//if ( myinfo->numdpows == 1 )
|
|
|
//if ( myinfo->numdpows == 1 )
|
|
|
// komodo_assetcoins(-1);
|
|
|
// komodo_assetcoins(-1);
|
|
|
if ( iguana_coinfind(symbol) == 0 ) |
|
|
if ( iguana_coinfind(symbol) == 0 ) |
|
|
return(clonestr("{\"error\":\"cant dPoW an inactive coin\"}")); |
|
|
return(clonestr("{\"error\":\"cant dPoW an inactive coin\"}")); |
|
|
if ( strcmp(symbol,"KMD") == 0 && iguana_coinfind("BTC") == 0 ) |
|
|
if ( strcmp(symbol,"KMD") == 0 && iguana_coinfind("BTC") == 0 ) |
|
|
return(clonestr("{\"error\":\"cant dPoW KMD without BTC\"}")); |
|
|
return(clonestr("{\"error\":\"cant dPoW KMD without BTC\"}")); |
|
|
else if ( myinfo->numdpows == 0 && strcmp(symbol,"KMD") != 0 && iguana_coinfind("KMD") == 0 ) |
|
|
else if ( iguana_coinfind(dest) == 0 ) |
|
|
return(clonestr("{\"error\":\"cant dPoW without KMD\"}")); |
|
|
return(clonestr("{\"error\":\"cant dPoW without KMD (dest)\"}")); |
|
|
if ( myinfo->numdpows > 1 ) |
|
|
if ( myinfo->numdpows > 1 ) |
|
|
{ |
|
|
{ |
|
|
if ( strcmp(symbol,"KMD") == 0 || iguana_coinfind("BTC") == 0 ) |
|
|
|
|
|
{ |
|
|
|
|
|
dp->symbol[0] = 0; |
|
|
|
|
|
return(clonestr("{\"error\":\"cant dPoW KMD or BTC again\"}")); |
|
|
|
|
|
} |
|
|
|
|
|
for (i=1; i<myinfo->numdpows; i++) |
|
|
for (i=1; i<myinfo->numdpows; i++) |
|
|
if ( strcmp(symbol,myinfo->DPOWS[i].symbol) == 0 ) |
|
|
if ( strcmp(symbol,myinfo->DPOWS[i].symbol) == 0 ) |
|
|
{ |
|
|
{ |
|
@ -410,14 +336,14 @@ TWO_STRINGS(iguana,dpow,symbol,pubkey) |
|
|
} |
|
|
} |
|
|
else |
|
|
else |
|
|
{ |
|
|
{ |
|
|
strcpy(dp->dest,"KMD"); |
|
|
strcpy(dp->dest,dest); |
|
|
dp->srcconfirms = DPOW_THIRDPARTY_CONFIRMS; |
|
|
dp->srcconfirms = DPOW_THIRDPARTY_CONFIRMS; |
|
|
} |
|
|
} |
|
|
if ( dp->srcconfirms > DPOW_FIFOSIZE ) |
|
|
if ( dp->srcconfirms > DPOW_FIFOSIZE ) |
|
|
dp->srcconfirms = DPOW_FIFOSIZE; |
|
|
dp->srcconfirms = DPOW_FIFOSIZE; |
|
|
src = iguana_coinfind(dp->symbol); |
|
|
src = iguana_coinfind(dp->symbol); |
|
|
dest = iguana_coinfind(dp->dest); |
|
|
destcoin = iguana_coinfind(dp->dest); |
|
|
if ( src == 0 || dest == 0 ) |
|
|
if ( src == 0 || destcoin == 0 ) |
|
|
{ |
|
|
{ |
|
|
dp->symbol[0] = 0; |
|
|
dp->symbol[0] = 0; |
|
|
return(clonestr("{\"error\":\"source coin or dest coin not there\"}")); |
|
|
return(clonestr("{\"error\":\"source coin or dest coin not there\"}")); |
|
@ -435,8 +361,8 @@ TWO_STRINGS(iguana,dpow,symbol,pubkey) |
|
|
free(retstr); |
|
|
free(retstr); |
|
|
retstr = 0; |
|
|
retstr = 0; |
|
|
} |
|
|
} |
|
|
bitcoin_address(destaddr,dest->chain->pubtype,dp->minerkey33,33); |
|
|
bitcoin_address(destaddr,destcoin->chain->pubtype,dp->minerkey33,33); |
|
|
if ( (retstr= dpow_validateaddress(myinfo,dest,destaddr)) != 0 ) |
|
|
if ( (retstr= dpow_validateaddress(myinfo,destcoin,destaddr)) != 0 ) |
|
|
{ |
|
|
{ |
|
|
json = cJSON_Parse(retstr); |
|
|
json = cJSON_Parse(retstr); |
|
|
if ( (ismine= jobj(json,"ismine")) != 0 && is_cJSON_True(ismine) != 0 ) |
|
|
if ( (ismine= jobj(json,"ismine")) != 0 && is_cJSON_True(ismine) != 0 ) |
|
|