/******************************************************************************
* Copyright © 2014 - 2017 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 . *
* *
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
struct dpow_entry * dpow_notaryfind ( struct supernet_info * myinfo , struct dpow_block * bp , int32_t height , int32_t * senderindp , uint8_t * senderpub )
{
int32_t i ;
* senderindp = - 1 ;
for ( i = 0 ; i < bp - > numnotaries ; i + + )
{
if ( memcmp ( bp - > notaries [ i ] . pubkey , senderpub , 33 ) = = 0 )
{
//printf("matches notary.%d\n",i);
* senderindp = i ;
return ( & bp - > notaries [ i ] ) ;
}
}
return ( 0 ) ;
}
void dpow_utxo2entry ( struct dpow_block * bp , struct dpow_entry * ep , struct dpow_utxoentry * up )
{
int32_t i ;
for ( i = 0 ; i < bp - > numnotaries ; i + + )
bp - > notaries [ i ] . othermask | = up - > othermasks [ i ] ;
ep - > commit = up - > commit ;
ep - > height = up - > height ;
ep - > recvmask | = up - > recvmask ;
ep - > bestk = up - > bestk ;
ep - > src . prev_hash = up - > srchash ;
ep - > dest . prev_hash = up - > desthash ;
ep - > src . prev_vout = up - > srcvout ;
ep - > dest . prev_vout = up - > destvout ;
}
void dpow_entry2utxo ( struct dpow_utxoentry * up , struct dpow_block * bp , struct dpow_entry * ep )
{
int32_t i ;
up - > commit = bp - > commit ;
up - > hashmsg = bp - > hashmsg ;
up - > height = bp - > height ;
up - > recvmask = bp - > recvmask ;
up - > bestk = bp - > bestk ;
for ( i = 0 ; i < bp - > numnotaries ; i + + )
up - > othermasks [ i ] = bp - > notaries [ i ] . recvmask ;
for ( i = 0 ; i < 33 ; i + + )
up - > pubkey [ i ] = ep - > pubkey [ i ] ;
up - > commit = ep - > commit ;
up - > height = ep - > height ;
up - > recvmask = ep - > recvmask ;
up - > bestk = ep - > bestk ;
up - > srchash = ep - > src . prev_hash ;
up - > desthash = ep - > dest . prev_hash ;
up - > srcvout = ep - > src . prev_vout ;
up - > destvout = ep - > dest . prev_vout ;
}
int32_t dpow_datahandler ( struct supernet_info * myinfo , struct dpow_info * dp , struct dpow_block * bp , uint8_t nn_senderind , uint32_t channel , uint32_t height , uint8_t * data , int32_t datalen )
{
int32_t i , src_or_dest , myind = - 1 ; bits256 txid , srchash ; struct iguana_info * coin ; char str [ 65 ] , str2 [ 65 ] ;
memset ( srchash . bytes , 0 , sizeof ( srchash ) ) ;
dpow_notaryfind ( myinfo , bp , height , & myind , dp - > minerkey33 ) ;
if ( myind < 0 )
{
//printf("couldnt find myind height.%d | this means your pubkey for this node is not registered and needs to be ratified by majority vote of all notaries\n",height);
return ( - 1 ) ;
}
for ( i = 0 ; i < 32 ; i + + )
srchash . bytes [ i ] = dp - > minerkey33 [ i + 1 ] ;
if ( channel = = DPOW_TXIDCHANNEL | | channel = = DPOW_BTCTXIDCHANNEL )
{
src_or_dest = ( channel = = DPOW_BTCTXIDCHANNEL ) ;
coin = ( src_or_dest ! = 0 ) ? bp - > destcoin : bp - > srccoin ;
//printf("bp.%p datalen.%d\n",bp,datalen);
for ( i = 0 ; i < 32 ; i + + )
srchash . bytes [ i ] = data [ i ] ;
txid = bits256_doublesha256 ( 0 , & data [ 32 ] , datalen - 32 ) ;
init_hexbytes_noT ( bp - > signedtx , & data [ 32 ] , datalen - 32 ) ;
if ( bits256_cmp ( txid , srchash ) = = 0 )
{
//printf("verify (%s) it is properly signed! set ht.%d signedtxid to %s\n",coin->symbol,height,bits256_str(str,txid));
/*if ( channel == DPOW_BTCTXIDCHANNEL )
{
if ( bp - > state < 1000 )
{
bp - > desttxid = txid ;
bp - > state = 1000 ;
dp - > destupdated = 0 ;
dpow_signedtxgen ( myinfo , dp , bp - > srccoin , bp , bp - > bestk , bp - > bestmask , myind , DPOW_SIGCHANNEL , 0 , bp - > isratify ) ;
//dpow_sigscheck(myinfo,dp,bp,DPOW_SIGCHANNEL,myind,0);
}
}
else
{
if ( bp - > state ! = 0xffffffff )
{
bp - > srctxid = txid ;
printf ( " set state elapsed %d COMPLETED %s.(%s) %s.(%s) \n " , ( int32_t ) ( time ( NULL ) - bp - > starttime ) , dp - > symbol , bits256_str ( str , bp - > desttxid ) , dp - > dest , bits256_str ( str2 , txid ) ) ;
bp - > state = 0xffffffff ;
}
} */
}
else
{
init_hexbytes_noT ( bp - > signedtx , data , datalen ) ;
printf ( " txidchannel txid %s mismatch %s (%s) \n " , bits256_str ( str , txid ) , bits256_str ( str2 , srchash ) , bp - > signedtx ) ;
bp - > signedtx [ 0 ] = 0 ;
}
} //else printf("unhandled channel.%x\n",channel);
return ( 0 ) ;
}
int32_t dpow_checkutxo ( struct supernet_info * myinfo , struct dpow_info * dp , struct dpow_block * bp , struct iguana_info * coin , bits256 * txidp , int32_t * voutp , char * coinaddr , char * srccoin )
{
int32_t haveutxo , completed , minutxo , n ; bits256 signedtxid ; cJSON * addresses ; char * rawtx , * sendtx ;
if ( strcmp ( " BTC " , coin - > symbol ) = = 0 )
{
minutxo = 199 ;
n = 10 ;
}
else if ( strcmp ( " KMD " , coin - > symbol ) = = 0 )
{
minutxo = 512 ;
n = 256 ;
}
else
{
minutxo = 49 ;
n = 50 ;
}
if ( ( haveutxo = dpow_haveutxo ( myinfo , coin , txidp , voutp , coinaddr , srccoin ) ) < = minutxo & & time ( NULL ) > dp - > lastsplit + bp - > duration & & ( bp - > myind ! = 0 | | dp - > ratifying = = 0 ) )
{
addresses = cJSON_CreateArray ( ) ;
jaddistr ( addresses , coinaddr ) ;
if ( ( rawtx = iguana_utxoduplicates ( myinfo , coin , dp - > minerkey33 , DPOW_UTXOSIZE , n , & completed , & signedtxid , 0 , addresses ) ) ! = 0 )
{
if ( ( sendtx = dpow_sendrawtransaction ( myinfo , coin , rawtx ) ) ! = 0 )
{
printf ( " sendrawtransaction.(%s) \n " , sendtx ) ;
free ( sendtx ) ;
}
free ( rawtx ) ;
}
free_json ( addresses ) ;
dp - > lastsplit = ( uint32_t ) time ( NULL ) ;
}
if ( bits256_nonz ( * txidp ) = = 0 )
return ( - 1 ) ;
return ( haveutxo ) ;
}
uint32_t Numallocated ;
int32_t dpow_opreturn_parsesrc ( bits256 * blockhashp , int32_t * heightp , bits256 * txidp , char * symbol , bits256 * MoMp , uint32_t * MoMdepthp , uint8_t * opret , int32_t opretlen )
{
int32_t i , c , len , offset = 0 ; uint8_t op ;
symbol [ 0 ] = 0 ;
memset ( blockhashp - > bytes , 0 , sizeof ( * blockhashp ) ) ;
memset ( heightp , 0 , sizeof ( * heightp ) ) ;
memset ( txidp - > bytes , 0 , sizeof ( * txidp ) ) ;
memset ( MoMp - > bytes , 0 , sizeof ( * MoMp ) ) ;
memset ( MoMdepthp , 0 , sizeof ( * MoMdepthp ) ) ;
if ( opret [ offset + + ] = = 0x6a )
{
if ( ( op = opret [ offset + + ] ) < 0x4c )
len = op ;
else if ( op = = 0x4c )
len = opret [ offset + + ] ;
else if ( op = = 0x4d )
{
len = opret [ offset + + ] ;
len = len + ( ( int32_t ) opret [ offset + + ] < < 8 ) ;
} else return ( - 1 ) ;
offset + = iguana_rwbignum ( 0 , & opret [ offset ] , sizeof ( * blockhashp ) , blockhashp - > bytes ) ;
offset + = iguana_rwnum ( 0 , & opret [ offset ] , sizeof ( * heightp ) , ( uint32_t * ) heightp ) ;
offset + = iguana_rwbignum ( 0 , & opret [ offset ] , sizeof ( * txidp ) , txidp - > bytes ) ;
for ( i = 0 ; i < 65 ; i + + )
{
if ( ( c = opret [ offset + + ] ) = = 0 )
{
symbol [ i ] = 0 ;
break ;
}
if ( offset > opretlen )
break ;
symbol [ i ] = c ;
}
if ( offset + sizeof ( bits256 ) + sizeof ( uint32_t ) < = opretlen )
{
offset + = iguana_rwbignum ( 0 , & opret [ offset ] , sizeof ( * MoMp ) , MoMp - > bytes ) ;
offset + = iguana_rwnum ( 0 , & opret [ offset ] , sizeof ( * MoMdepthp ) , ( uint32_t * ) MoMdepthp ) ;
}
printf ( " offset.%d vs len.%d \n " , offset , len ) ;
return ( len ) ;
}
return ( - 1 ) ;
}
int32_t dpow_txhasnotarization ( uint64_t * signedmaskp , int32_t * nothtp , struct supernet_info * myinfo , struct iguana_info * coin , bits256 txid , int32_t height )
{
cJSON * txobj , * vins , * vin , * vouts , * vout , * spentobj , * sobj ; char * hexstr ; uint8_t script [ 35 ] ; bits256 spenttxid ; uint64_t notarymask = 0 ; 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 ;
* nothtp = 0 ;
if ( ( vouts = jarray ( & numvouts , txobj , " vout " ) ) ! = 0 )
{
bits256 blockhash , txid , MoM ; uint32_t MoMdepth ; char symbol [ 65 ] , str [ 65 ] , str2 [ 65 ] , str3 [ 65 ] ;
vout = jitem ( vouts , numvouts - 1 ) ;
if ( ( sobj = jobj ( vout , " scriptPubKey " ) ) ! = 0 & & ( hexstr = jstr ( sobj , " hex " ) ) ! = 0 & & ( len = is_hexstr ( hexstr , 0 ) ) > 36 )
{
len > > = 1 ;
decode_hex ( script , len , hexstr ) ;
if ( dpow_opreturn_parsesrc ( & blockhash , nothtp , & txid , symbol , & MoM , & MoMdepth , script , len ) > 0 )
{
if ( bits256_nonz ( MoM ) = = 0 | | MoMdepth = = 0 | | * nothtp > = height | | * nothtp < 0 )
* nothtp = 0 ;
printf ( " %s.%d notarizationht.%d %s -> %s MoM.%s [%d] \n " , symbol , height , * nothtp , bits256_str ( str , blockhash ) , bits256_str ( str2 , txid ) , bits256_str ( str3 , MoM ) , MoMdepth ) ;
}
}
}
printf ( " numnotaries.%d %s hasnotarization.%d ht.%d MUSTFIX notht.%d \n " , numnotaries , coin - > symbol , hasnotarization , height , * nothtp ) ;
}
}
}
}
free_json ( txobj ) ;
}
if ( hasnotarization ! = 0 )
( * signedmaskp ) = notarymask ;
return ( hasnotarization ) ;
}
int32_t dpow_hasnotarization ( uint64_t * signedmaskp , int32_t * nothtp , struct supernet_info * myinfo , struct iguana_info * coin , cJSON * blockjson , int32_t ht )
{
int32_t i , n , hasnotarization = 0 ; bits256 txid ; cJSON * txarray ;
* nothtp = 0 ;
* signedmaskp = 0 ;
if ( ( txarray = jarray ( & n , blockjson , " tx " ) ) ! = 0 )
{
for ( i = 0 ; i < n ; i + + )
{
txid = jbits256i ( txarray , i ) ;
hasnotarization + = dpow_txhasnotarization ( signedmaskp , nothtp , myinfo , coin , txid , ht ) ;
}
}
return ( hasnotarization ) ;
}
bits256 dpow_calcMoM ( uint32_t * MoMdepthp , struct supernet_info * myinfo , struct iguana_info * coin , int32_t height )
{
bits256 MoM , blockhash , merkle , * merkles ; cJSON * blockjson ; uint64_t signedmask ; int32_t breakht = 0 , notht = 0 , ht , maxdepth = 1440 , MoMdepth = 0 ;
memset ( MoM . bytes , 0 , sizeof ( MoM ) ) ;
blockhash = dpow_getblockhash ( myinfo , coin , height ) ;
//printf("start MoM calc %s height.%d\n",coin->symbol,height);
if ( ( blockjson = dpow_getblock ( myinfo , coin , blockhash ) ) ! = 0 )
{
merkle = jbits256 ( blockjson , " merkleroot " ) ;
free_json ( blockjson ) ;
if ( bits256_nonz ( merkle ) ! = 0 )
{
merkles = calloc ( 3 * maxdepth + 1 , sizeof ( * merkles ) ) ;
merkles [ MoMdepth + + ] = merkle ;
ht = height - MoMdepth ;
while ( MoMdepth < maxdepth & & ht > breakht & & ht > 0 )
{
fprintf ( stderr , " %s.%d " , coin - > symbol , ht ) ;
blockhash = dpow_getblockhash ( myinfo , coin , ht ) ;
if ( ( blockjson = dpow_getblock ( myinfo , coin , blockhash ) ) ! = 0 )
{
if ( breakht = = 0 & & dpow_hasnotarization ( & signedmask , & notht , myinfo , coin , blockjson , ht ) > 0 )
{
breakht = notht ;
//free_json(blockjson);
printf ( " %s has notarization at %d for breakht.%d \n " , coin - > symbol , ht , notht ) ;
}
merkle = jbits256 ( blockjson , " merkleroot " ) ;
free_json ( blockjson ) ;
if ( bits256_nonz ( merkle ) ! = 0 )
merkles [ MoMdepth + + ] = merkle ;
else
{
printf ( " %s MoMdepth.%d ht.%d from height.%d, null merkleroot \n " , coin - > symbol , MoMdepth , ht , height ) ;
MoMdepth = 0 ;
break ;
}
}
else
{
printf ( " %s MoMdepth.%d ht.%d from height.%d, no blockhash \n " , coin - > symbol , MoMdepth , ht , height ) ;
MoMdepth = 0 ;
break ;
}
ht = height - MoMdepth ;
}
if ( MoMdepth > 0 )
{
MoM = iguana_merkle ( coin - > symbol , merkles , MoMdepth ) ;
char str [ 65 ] ; printf ( " %s from height.%d ht.%d MoMdepth.%d -> MoM %s \n " , coin - > symbol , height , ht , MoMdepth , bits256_str ( str , MoM ) ) ;
}
else
{
printf ( " unexpected %s from height.%d MoMdepth.%d vs max.%d \n " , coin - > symbol , height , MoMdepth , maxdepth ) ;
MoMdepth = 0 ;
}
free ( merkles ) ;
} else printf ( " %s.ht%d null merkles \n " , coin - > symbol , height ) ;
} else printf ( " %s.ht%d null block \n " , coin - > symbol , height ) ;
* MoMdepthp = MoMdepth ;
//printf("done MoM calc %s height.%d MoMdepth.%d\n",coin->symbol,height,MoMdepth);
return ( MoM ) ;
}
void dpow_statemachinestart ( void * ptr )
{
void * * ptrs = ptr ;
struct supernet_info * myinfo ; struct dpow_info * dp ; struct dpow_checkpoint checkpoint ;
int32_t i , j , ht , extralen , destprevvout0 , srcprevvout0 , numratified = 0 , kmdheight , myind = - 1 ; uint8_t extras [ 10000 ] , pubkeys [ 64 ] [ 33 ] ; cJSON * ratified = 0 , * item ; struct iguana_info * src , * dest ; char * jsonstr , * handle , * hexstr , str [ 65 ] , str2 [ 65 ] , srcaddr [ 64 ] , destaddr [ 64 ] ; bits256 zero , MoM , merkleroot , srchash , destprevtxid0 , srcprevtxid0 ; struct dpow_block * bp ; struct dpow_entry * ep = 0 ; uint32_t MoMdepth , duration , minsigs , starttime , srctime ;
memset ( & zero , 0 , sizeof ( zero ) ) ;
MoM = zero ;
srcprevtxid0 = destprevtxid0 = zero ;
srcprevvout0 = destprevvout0 = - 1 ;
myinfo = ptrs [ 0 ] ;
dp = ptrs [ 1 ] ;
minsigs = ( uint32_t ) ( long ) ptrs [ 2 ] ;
duration = ( uint32_t ) ( long ) ptrs [ 3 ] ;
jsonstr = ptrs [ 4 ] ;
kmdheight = - 1 ;
memcpy ( & checkpoint , & ptrs [ 5 ] , sizeof ( checkpoint ) ) ;
src = iguana_coinfind ( dp - > symbol ) ;
dest = iguana_coinfind ( dp - > dest ) ;
dpow_getchaintip ( myinfo , & merkleroot , & srchash , & srctime , dp - > desttx , & dp - > numdesttx , dest ) ;
dpow_getchaintip ( myinfo , & merkleroot , & srchash , & srctime , dp - > srctx , & dp - > numsrctx , src ) ;
if ( src = = 0 | | dest = = 0 )
{
printf ( " null coin ptr? (%s %p or %s %p) \n " , dp - > symbol , src , dp - > dest , dest ) ;
free ( ptr ) ;
return ;
}
MoMdepth = 0 ;
if ( strcmp ( src - > symbol , " KMD " ) = = 0 )
kmdheight = checkpoint . blockhash . height ;
else if ( strcmp ( dest - > symbol , " KMD " ) = = 0 )
{
kmdheight = dest - > longestchain ;
//portable_mutex_lock(&myinfo->MoM_mutex);
MoM = dpow_calcMoM ( & MoMdepth , myinfo , src , checkpoint . blockhash . height ) ;
//portable_mutex_unlock(&myinfo->MoM_mutex);
}
if ( ( bp = dp - > blocks [ checkpoint . blockhash . height ] ) = = 0 )
{
bp = calloc ( 1 , sizeof ( * bp ) ) ;
//printf("allocate bp for %s ht.%d -> %s\n",src->symbol,checkpoint.blockhash.height,dest->symbol);
Numallocated + + ;
bp - > MoM = MoM ;
bp - > MoMdepth = MoMdepth ;
bp - > minsigs = minsigs ;
bp - > duration = duration ;
bp - > srccoin = src ;
bp - > destcoin = dest ;
bp - > myind = - 1 ;
bp - > opret_symbol = dp - > symbol ;
if ( jsonstr ! = 0 & & ( ratified = cJSON_Parse ( jsonstr ) ) ! = 0 )
{
bp - > isratify = 1 ;
if ( ( numratified = cJSON_GetArraySize ( ratified ) ) > 0 )
{
if ( numratified > 64 )
{
fprintf ( stderr , " cant ratify more than 64 notaries ratified has %d \n " , numratified ) ;
free ( ptr ) ;
free_json ( ratified ) ;
return ;
}
for ( i = 0 ; i < numratified ; i + + )
{
item = jitem ( ratified , i ) ;
hexstr = handle = 0 ;
if ( ( hexstr = jstr ( item , " pubkey " ) ) ! = 0 & & is_hexstr ( hexstr , 0 ) = = 66 )
{
decode_hex ( bp - > ratified_pubkeys [ i ] , 33 , hexstr ) ;
for ( j = 0 ; j < i ; j + + )
if ( memcmp ( bp - > ratified_pubkeys [ j ] , bp - > ratified_pubkeys [ i ] , 33 ) = = 0 )
{
printf ( " ratification.%d is the same as %d, reject this donkey \n " , j , i ) ;
exit ( - 1 ) ;
}
if ( ( handle = jstr ( item , " handle " ) ) ! = 0 )
safecopy ( bp - > handles [ i ] , handle , sizeof ( bp - > handles [ i ] ) ) ;
if ( i = = 0 )
{
destprevtxid0 = jbits256 ( item , " destprevtxid0 " ) ;
destprevvout0 = jint ( item , " destprevvout0 " ) ;
srcprevtxid0 = jbits256 ( item , " srcprevtxid0 " ) ;
srcprevvout0 = jint ( item , " srcprevvout0 " ) ;
if ( bits256_nonz ( destprevtxid0 ) ! = 0 & & bits256_nonz ( srcprevtxid0 ) ! = 0 )
bp - > require0 = 1 ;
}
}
else
{
printf ( " break loop hexstr.%p handle.%p \n " , hexstr , handle ) ;
break ;
}
}
if ( i = = numratified )
{
bp - > numratified = numratified ;
bp - > ratified = ratified ;
printf ( " numratified.%d %s \n " , numratified , jprint ( ratified , 0 ) ) ;
} else printf ( " i.%d numratified.%d \n " , i , numratified ) ;
}
free_json ( ratified ) ;
}
bp - > bestk = - 1 ;
dp - > blocks [ checkpoint . blockhash . height ] = bp ;
bp - > beacon = rand256 ( 0 ) ;
vcalc_sha256 ( 0 , bp - > commit . bytes , bp - > beacon . bytes , sizeof ( bp - > beacon ) ) ;
}
if ( bp - > isratify ! = 0 & & dp - > ratifying ! = 0 )
{
printf ( " new ratification starting dp->ratifying.%d \n " , dp - > ratifying ) ;
dp - > ratifying + + ;
while ( dp - > ratifying > 1 )
sleep ( 3 ) ;
printf ( " other ratifications stopped \n " ) ;
}
if ( dp - > ratifying ! = 0 & & bp - > isratify = = 0 )
{
printf ( " skip notarization ht.%d when ratifying \n " , bp - > height ) ;
free ( ptr ) ;
return ;
}
dp - > ratifying + = bp - > isratify ;
bitcoin_address ( srcaddr , src - > chain - > pubtype , dp - > minerkey33 , 33 ) ;
bitcoin_address ( destaddr , dest - > chain - > pubtype , dp - > minerkey33 , 33 ) ;
if ( kmdheight > = 0 )
{
ht = kmdheight ; ///strcmp("KMD",src->symbol) == 0 ? kmdheight : bp->height;
if ( strcmp ( " KMD " , dest - > symbol ) = = 0 )
{
bp - > numnotaries = komodo_notaries ( dest - > symbol , pubkeys , ht ) ;
}
else
{
if ( ht = = 0 )
ht = strcmp ( " KMD " , src - > symbol ) = = 0 ? src - > longestchain : dest - > longestchain ;
bp - > numnotaries = komodo_notaries ( src - > symbol , pubkeys , ht ) ;
}
for ( i = 0 ; i < bp - > numnotaries ; i + + )
{
//int32_t j; for (j=0; j<33; j++)
// printf("%02x",pubkeys[i][j]);
//printf(" <= pubkey[%d]\n",i);
memcpy ( bp - > notaries [ i ] . pubkey , pubkeys [ i ] , 33 ) ;
if ( strcmp ( " KMD " , src - > symbol ) = = 0 )
memcpy ( myinfo - > notaries [ i ] , pubkeys [ i ] , 33 ) ;
if ( memcmp ( bp - > notaries [ i ] . pubkey , dp - > minerkey33 , 33 ) = = 0 )
{
myind = i ;
ep = & bp - > notaries [ myind ] ;
for ( j = 0 ; j < 33 ; j + + )
printf ( " %02x " , dp - > minerkey33 [ j ] ) ;
printf ( " MYIND.%d <<<<<<<<<<<<<<<<<<<<<< \n " , myind ) ;
}
}
if ( strcmp ( " KMD " , src - > symbol ) = = 0 )
myinfo - > numnotaries = bp - > numnotaries ;
if ( myind < 0 | | ep = = 0 )
{
printf ( " minerkey33-> " ) ;
for ( i = 0 ; i < 33 ; i + + )
printf ( " %02x " , dp - > minerkey33 [ i ] ) ;
printf ( " statemachinestart this node %s %s is not official notary numnotaries.%d kmdht.%d bpht.%d \n " , srcaddr , destaddr , bp - > numnotaries , kmdheight , bp - > height ) ;
free ( ptr ) ;
dp - > ratifying - = bp - > isratify ;
return ;
}
printf ( " myind.%d \n " , myind ) ;
}
else
{
printf ( " statemachinestart no kmdheight.%d \n " , kmdheight ) ;
free ( ptr ) ;
dp - > ratifying - = bp - > isratify ;
return ;
}
bp - > myind = myind ;
printf ( " [%d] notarize %s->%s %s ht.%d minsigs.%d duration.%d start.%u \n " , bp - > myind , dp - > symbol , dp - > dest , bits256_str ( str , checkpoint . blockhash . hash ) , checkpoint . blockhash . height , minsigs , duration , checkpoint . timestamp ) ;
if ( bp - > isratify ! = 0 & & memcmp ( bp - > notaries [ 0 ] . pubkey , bp - > ratified_pubkeys [ 0 ] , 33 ) ! = 0 )
{
for ( i = 0 ; i < 33 ; i + + )
printf ( " %02x " , bp - > notaries [ 0 ] . pubkey [ i ] ) ;
printf ( " current vs " ) ;
for ( i = 0 ; i < 33 ; i + + )
printf ( " %02x " , bp - > ratified_pubkeys [ 0 ] [ i ] ) ;
printf ( " new, cant change notary0 \n " ) ;
dp - > ratifying - = bp - > isratify ;
free ( ptr ) ;
return ;
}
//printf(" myind.%d myaddr.(%s %s)\n",myind,srcaddr,destaddr);
if ( myind = = 0 & & bits256_nonz ( destprevtxid0 ) ! = 0 & & bits256_nonz ( srcprevtxid0 ) ! = 0 & & destprevvout0 > = 0 & & srcprevvout0 > = 0 )
{
ep - > dest . prev_hash = destprevtxid0 ;
ep - > dest . prev_vout = destprevvout0 ;
ep - > src . prev_hash = srcprevtxid0 ;
ep - > src . prev_vout = srcprevvout0 ;
bp - > notaries [ myind ] . ratifysrcutxo = srcprevtxid0 ;
bp - > notaries [ myind ] . ratifysrcvout = srcprevvout0 ;
bp - > notaries [ myind ] . ratifydestutxo = destprevtxid0 ;
bp - > notaries [ myind ] . ratifydestvout = destprevvout0 ;
printf ( " Use override utxo %s/v%d %s/v%d \n " , bits256_str ( str , destprevtxid0 ) , destprevvout0 , bits256_str ( str2 , srcprevtxid0 ) , srcprevvout0 ) ;
}
else
{
if ( dpow_checkutxo ( myinfo , dp , bp , bp - > destcoin , & ep - > dest . prev_hash , & ep - > dest . prev_vout , destaddr , src - > symbol ) < 0 )
{
printf ( " dont have %s %s utxo, please send funds \n " , dp - > dest , destaddr ) ;
dp - > ratifying - = bp - > isratify ;
free ( ptr ) ;
return ;
}
if ( dpow_checkutxo ( myinfo , dp , bp , bp - > srccoin , & ep - > src . prev_hash , & ep - > src . prev_vout , srcaddr , " " ) < 0 )
{
printf ( " dont have %s %s utxo, please send funds \n " , dp - > symbol , srcaddr ) ;
dp - > ratifying - = bp - > isratify ;
free ( ptr ) ;
return ;
}
if ( bp - > isratify ! = 0 )
{
bp - > notaries [ myind ] . ratifysrcutxo = ep - > src . prev_hash ;
bp - > notaries [ myind ] . ratifysrcvout = ep - > src . prev_vout ;
bp - > notaries [ myind ] . ratifydestutxo = ep - > dest . prev_hash ;
bp - > notaries [ myind ] . ratifydestvout = ep - > dest . prev_vout ;
}
}
bp - > recvmask | = ( 1LL < < myind ) ;
bp - > notaries [ myind ] . othermask | = ( 1LL < < myind ) ;
dp - > checkpoint = checkpoint ;
bp - > height = checkpoint . blockhash . height ;
bp - > timestamp = checkpoint . timestamp ;
bp - > hashmsg = checkpoint . blockhash . hash ;
bp - > myind = myind ;
while ( bp - > isratify = = 0 & & dp - > destupdated = = 0 )
{
if ( ( checkpoint . blockhash . height % 100 ) ! = 0 & & dp - > checkpoint . blockhash . height > checkpoint . blockhash . height )
{
printf ( " abort %s ht.%d due to new checkpoint.%d \n " , dp - > symbol , checkpoint . blockhash . height , dp - > checkpoint . blockhash . height ) ;
dp - > ratifying - = bp - > isratify ;
free ( ptr ) ;
return ;
}
sleep ( 1 ) ;
}
starttime = ( uint32_t ) time ( NULL ) ;
if ( bp - > isratify = = 0 )
{
//if ( (starttime= checkpoint.timestamp) == 0 )
bp - > starttime = starttime ;
extralen = dpow_paxpending ( extras , & bp - > paxwdcrc , bp - > MoM , bp - > MoMdepth ) ;
bp - > notaries [ bp - > myind ] . paxwdcrc = bp - > paxwdcrc ;
}
printf ( " PAXWDCRC.%x myind.%d isratify.%d DPOW.%s statemachine checkpoint.%d %s start.%u+dur.%d vs %ld \n " , bp - > paxwdcrc , bp - > myind , bp - > isratify , src - > symbol , checkpoint . blockhash . height , bits256_str ( str , checkpoint . blockhash . hash ) , starttime , bp - > duration , time ( NULL ) ) ;
for ( i = 0 ; i < sizeof ( srchash ) ; i + + )
srchash . bytes [ i ] = dp - > minerkey33 [ i + 1 ] ;
//printf("start utxosync start.%u %u\n",starttime,(uint32_t)time(NULL));
//dpow_utxosync(myinfo,dp,bp,0,myind,srchash);
//printf("done utxosync start.%u %u\n",starttime,(uint32_t)time(NULL));
while ( time ( NULL ) < starttime + bp - > duration & & src ! = 0 & & dest ! = 0 & & bp - > state ! = 0xffffffff )
{
if ( bp - > isratify = = 0 )
{
if ( myinfo - > DPOWS [ 0 ] . ratifying ! = 0 )
{
printf ( " break due to already ratifying \n " ) ;
break ;
}
extralen = dpow_paxpending ( extras , & bp - > paxwdcrc , bp - > MoM , bp - > MoMdepth ) ;
bp - > notaries [ bp - > myind ] . paxwdcrc = bp - > paxwdcrc ;
}
sleep ( 13 ) ;
if ( dp - > checkpoint . blockhash . height > checkpoint . blockhash . height )
{
if ( bp - > isratify = = 0 )
{
printf ( " abort %s ht.%d due to new checkpoint.%d \n " , dp - > symbol , checkpoint . blockhash . height , dp - > checkpoint . blockhash . height ) ;
break ;
}
}
if ( dp - > ratifying > 1 )
{
printf ( " new ratification started. abort ht.%d \n " , bp - > height ) ;
break ;
}
if ( bp - > isratify = = 0 )
{
bits256 checkhash ;
checkhash = dpow_getblockhash ( myinfo , bp - > srccoin , bp - > height ) ;
if ( bits256_cmp ( checkhash , bp - > hashmsg ) ! = 0 )
{
printf ( " %s ht.%d %s got reorged to %s, abort notarization \n " , bp - > srccoin - > symbol , bp - > height , bits256_str ( str , bp - > hashmsg ) , bits256_str ( str2 , checkhash ) ) ;
bp - > state = 0xffffffff ;
}
}
if ( bp - > state ! = 0xffffffff )
{
dpow_send ( myinfo , dp , bp , srchash , bp - > hashmsg , 0 , bp - > height , ( void * ) " ping " , 0 ) ;
dpow_nanomsg_update ( myinfo ) ;
}
else
{
dp - > lastnotarized = checkpoint . blockhash . hash ;
printf ( " notarized %s %s \n " , dp - > symbol , bits256_str ( str , checkpoint . blockhash . hash ) ) ;
}
if ( 0 & & dp - > cancelratify ! = 0 & & bp - > isratify ! = 0 )
{
printf ( " abort pending ratify \n " ) ;
break ;
}
}
printf ( " [%d] END isratify.%d:%d bestk.%d %llx sigs.%llx state.%x machine ht.%d completed state.%x %s.%s %s.%s recvmask.%llx paxwdcrc.%x %p %p \n " , Numallocated , bp - > isratify , dp - > ratifying , bp - > bestk , ( long long ) bp - > bestmask , ( long long ) ( bp - > bestk > = 0 ? bp - > destsigsmasks [ bp - > bestk ] : 0 ) , bp - > state , bp - > height , bp - > state , dp - > dest , bits256_str ( str , bp - > desttxid ) , dp - > symbol , bits256_str ( str2 , bp - > srctxid ) , ( long long ) bp - > recvmask , bp - > paxwdcrc , src , dest ) ;
dp - > lastrecvmask = bp - > recvmask ;
dp - > ratifying - = bp - > isratify ;
// dp->blocks[bp->height] = 0;
bp - > state = 0xffffffff ;
free ( ptr ) ;
}