You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

421 lines
18 KiB

8 years ago
/******************************************************************************
* 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. *
* *
******************************************************************************/
8 years ago
struct dpow_entry *dpow_notaryfind(struct supernet_info *myinfo,struct dpow_block *bp,int32_t height,int32_t *senderindp,uint8_t *senderpub)
8 years ago
{
int32_t i;
*senderindp = -1;
for (i=0; i<bp->numnotaries; i++)
{
if ( memcmp(bp->notaries[i].pubkey,senderpub,33) == 0 )
{
8 years ago
//printf("matches notary.%d\n",i);
8 years ago
*senderindp = i;
return(&bp->notaries[i]);
}
}
return(0);
}
8 years ago
8 years ago
void dpow_utxo2entry(struct dpow_block *bp,struct dpow_entry *ep,struct dpow_utxoentry *up)
{
int32_t i;
8 years ago
for (i=0; i<bp->numnotaries; i++)
8 years ago
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;
8 years ago
for (i=0; i<bp->numnotaries; i++)
8 years ago
up->othermasks[i] = bp->notaries[i].recvmask;
8 years ago
for (i=0; i<33; i++)
up->pubkey[i] = ep->pubkey[i];
8 years ago
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;
}
8 years ago
/*void dpow_utxosync(struct supernet_info *myinfo,struct dpow_info *dp,struct dpow_block *bp,uint64_t recvmask,int32_t myind,bits256 srchash)
8 years ago
{
8 years ago
uint32_t i,j,r; int32_t len; struct dpow_utxoentry U; uint8_t utxodata[sizeof(U)+2];
8 years ago
if ( (bp->recvmask ^ recvmask) != 0 )
{
if ( ((1LL << myind) & recvmask) == 0 )
8 years ago
{
8 years ago
i = myind;
8 years ago
//printf("utxosync bp->%llx != %llx, myind.%d\n",(long long)bp->recvmask,(long long)recvmask,myind);
8 years ago
}
8 years ago
else
{
r = (rand() % bp->numnotaries);
8 years ago
for (j=0; j<bp->numnotaries; j++)
8 years ago
{
8 years ago
i = DPOW_MODIND(bp,j+r);
8 years ago
if ( ((1LL << i) & bp->recvmask) != 0 && ((1LL << i) & recvmask) == 0 )
break;
}
8 years ago
//printf("utxosync bp->%llx != %llx, random pick.%d\n",(long long)bp->recvmask,(long long)recvmask,i);
8 years ago
}
8 years ago
memset(&U,0,sizeof(U));
dpow_entry2utxo(&U,bp,&bp->notaries[i]);
8 years ago
//char str[65],str2[65];
//printf("send.(%s %s)\n",bits256_str(str,bp->notaries[i].dest.prev_hash),bits256_str(str2,bp->notaries[i].src.prev_hash));
8 years ago
if ( (len= dpow_rwutxobuf(1,utxodata,&U,bp)) > 0 )
8 years ago
dpow_send(myinfo,dp,bp,srchash,bp->hashmsg,DPOW_UTXOCHANNEL,bp->height,utxodata,len);
8 years ago
}
8 years ago
}*/
8 years ago
8 years ago
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)
8 years ago
{
8 years ago
int32_t i,src_or_dest,myind = -1; bits256 txid,srchash; struct iguana_info *coin; char str[65],str2[65];
8 years ago
dpow_notaryfind(myinfo,bp,height,&myind,dp->minerkey33);
8 years ago
if ( myind < 0 )
8 years ago
{
8 years ago
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);
8 years ago
return(-1);
8 years ago
}
8 years ago
for (i=0; i<32; i++)
8 years ago
srchash.bytes[i] = dp->minerkey33[i+1];
8 years ago
if ( channel == DPOW_TXIDCHANNEL || channel == DPOW_BTCTXIDCHANNEL )
8 years ago
{
8 years ago
src_or_dest = (channel == DPOW_BTCTXIDCHANNEL);
coin = (src_or_dest != 0) ? bp->destcoin : bp->srccoin;
8 years ago
//printf("bp.%p datalen.%d\n",bp,datalen);
for (i=0; i<32; i++)
srchash.bytes[i] = data[i];
8 years ago
txid = bits256_doublesha256(0,&data[32],datalen-32);
init_hexbytes_noT(bp->signedtx,&data[32],datalen-32);
if ( bits256_cmp(txid,srchash) == 0 )
8 years ago
{
8 years ago
//printf("verify (%s) it is properly signed! set ht.%d signedtxid to %s\n",coin->symbol,height,bits256_str(str,txid));
8 years ago
if ( src_or_dest != 0 )
8 years ago
{
8 years ago
if ( bp->state < 1000 )
{
bp->desttxid = txid;
bp->state = 1000;
dp->destupdated = 0;
8 years ago
dpow_signedtxgen(myinfo,dp,bp->srccoin,bp,bp->bestk,bp->bestmask,myind,DPOW_SIGCHANNEL,0,bp->isratify);
8 years ago
//dpow_sigscheck(myinfo,dp,bp,DPOW_SIGCHANNEL,myind,0);
}
8 years ago
}
8 years ago
else
{
8 years ago
if ( bp->state != 0xffffffff )
{
bp->srctxid = txid;
8 years ago
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));
8 years ago
bp->state = 0xffffffff;
}
8 years ago
}
}
8 years ago
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;
}
8 years ago
} //else printf("unhandled channel.%x\n",channel);
8 years ago
return(0);
8 years ago
}
8 years ago
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)
8 years ago
{
8 years ago
int32_t haveutxo,completed,minutxo,n; bits256 signedtxid; cJSON *addresses; char *rawtx,*sendtx;
if ( strcmp("BTC",coin->symbol) == 0 )
{
minutxo = 9;
n = 50;
}
else
{
minutxo = 49;
n = 10;
}
if ( (haveutxo= dpow_haveutxo(myinfo,coin,txidp,voutp,coinaddr)) <= minutxo && time(NULL) > dp->lastsplit+bp->duration )
8 years ago
{
addresses = cJSON_CreateArray();
jaddistr(addresses,coinaddr);
8 years ago
if ( (rawtx= iguana_utxoduplicates(myinfo,coin,dp->minerkey33,DPOW_UTXOSIZE,n,&completed,&signedtxid,0,addresses)) != 0 )
8 years ago
{
if ( (sendtx= dpow_sendrawtransaction(myinfo,coin,rawtx)) != 0 )
{
printf("sendrawtransaction.(%s)\n",sendtx);
free(sendtx);
}
free(rawtx);
}
free_json(addresses);
8 years ago
dp->lastsplit = (uint32_t)time(NULL);
8 years ago
}
if ( bits256_nonz(*txidp) == 0 )
return(-1);
return(haveutxo);
}
8 years ago
void dpow_statemachinestart(void *ptr)
{
8 years ago
void **ptrs = ptr;
struct supernet_info *myinfo; struct dpow_info *dp; struct dpow_checkpoint checkpoint;
8 years ago
int32_t i,destprevvout0,srcprevvout0,numratified=0,kmdheight,myind = -1; uint8_t 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,srchash,destprevtxid0,srcprevtxid0; struct dpow_block *bp; struct dpow_entry *ep = 0; uint32_t duration,minsigs,starttime;
8 years ago
memset(&zero,0,sizeof(zero));
8 years ago
srcprevtxid0 = destprevtxid0 = zero;
srcprevvout0 = destprevvout0 = -1;
8 years ago
myinfo = ptrs[0];
dp = ptrs[1];
8 years ago
minsigs = (uint32_t)(long)ptrs[2];
duration = (uint32_t)(long)ptrs[3];
8 years ago
jsonstr = ptrs[4];
8 years ago
kmdheight = -1;
8 years ago
memcpy(&checkpoint,&ptrs[5],sizeof(checkpoint));
8 years ago
printf("statemachinestart %s->%s %s ht.%d minsigs.%d duration.%d start.%u\n",dp->symbol,dp->dest,bits256_str(str,checkpoint.blockhash.hash),checkpoint.blockhash.height,minsigs,duration,checkpoint.timestamp);
8 years ago
src = iguana_coinfind(dp->symbol);
dest = iguana_coinfind(dp->dest);
8 years ago
if ( src == 0 || dest == 0 )
{
printf("null coin ptr? (%s %p or %s %p)\n",dp->symbol,src,dp->dest,dest);
return;
}
8 years ago
if ( strcmp(src->symbol,"KMD") == 0 )
kmdheight = checkpoint.blockhash.height;
else if ( strcmp(dest->symbol,"KMD") == 0 )
kmdheight = dest->longestchain;
8 years ago
if ( (bp= dp->blocks[checkpoint.blockhash.height]) == 0 )
8 years ago
{
8 years ago
bp = calloc(1,sizeof(*bp));
8 years ago
bp->minsigs = minsigs;
8 years ago
bp->duration = duration;
8 years ago
bp->srccoin = src;
bp->destcoin = dest;
bp->opret_symbol = dp->symbol;
8 years ago
if ( jsonstr != 0 && (ratified= cJSON_Parse(jsonstr)) != 0 )
8 years ago
{
8 years ago
bp->isratify = 1;
8 years ago
if ( (numratified= cJSON_GetArraySize(ratified)) > 0 )
8 years ago
{
for (i=0; i<numratified; i++)
{
item = jitem(ratified,i);
8 years ago
hexstr = handle = 0;
8 years ago
if ( (hexstr= jstr(item,"pubkey")) != 0 && is_hexstr(hexstr,0) == 66 )
8 years ago
{
decode_hex(bp->ratified_pubkeys[i],33,hexstr);
8 years ago
if ( (handle= jstr(item,"handle")) != 0 )
safecopy(bp->handles[i],handle,sizeof(bp->handles[i]));
8 years ago
if ( i == 0 )
{
destprevtxid0 = jbits256(item,"destprevtxid0");
destprevvout0 = jint(item,"destprevvout0");
srcprevtxid0 = jbits256(item,"srcprevtxid0");
srcprevvout0 = jint(item,"srcprevvout0");
8 years ago
bp->require0 = 1;
8 years ago
}
8 years ago
}
else
{
printf("break loop hexstr.%p handle.%p\n",hexstr,handle);
break;
}
8 years ago
}
if ( i == numratified )
{
bp->numratified = numratified;
8 years ago
bp->ratified = ratified;
8 years ago
printf("numratified.%d %s\n",numratified,jprint(ratified,0));
8 years ago
}
8 years ago
else
{
printf("i.%d numratified.%d\n",i,numratified);
free_json(ratified);
}
8 years ago
}
}
8 years ago
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));
8 years ago
/*if ( checkpoint.blockhash.height >= DPOW_FIRSTRATIFY && dp->blocks[checkpoint.blockhash.height - DPOW_FIRSTRATIFY] != 0 )
8 years ago
{
8 years ago
printf("purge %s.%d\n",dp->dest,checkpoint.blockhash.height - DPOW_FIRSTRATIFY);
free(dp->blocks[checkpoint.blockhash.height - DPOW_FIRSTRATIFY]);
dp->blocks[checkpoint.blockhash.height - DPOW_FIRSTRATIFY] = 0;
8 years ago
}*/
8 years ago
}
8 years ago
bitcoin_address(srcaddr,src->chain->pubtype,dp->minerkey33,33);
bitcoin_address(destaddr,dest->chain->pubtype,dp->minerkey33,33);
if ( kmdheight >= 0 )
8 years ago
{
8 years ago
bp->numnotaries = komodo_notaries(src->symbol,pubkeys,strcmp("KMD",src->symbol) == 0 ? kmdheight : bp->height);
8 years ago
for (i=0; i<bp->numnotaries; i++)
{
8 years ago
//int32_t j; for (j=0; j<33; j++)
// printf("%02x",pubkeys[i][j]);
//printf(" <= pubkey[%d]\n",i);
8 years ago
memcpy(bp->notaries[i].pubkey,pubkeys[i],33);
if ( memcmp(bp->notaries[i].pubkey,dp->minerkey33,33) == 0 )
{
myind = i;
ep = &bp->notaries[myind];
}
}
if ( myind < 0 || ep == 0 )
8 years ago
{
8 years ago
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\n",srcaddr,destaddr,bp->numnotaries);
free(ptr);
return;
8 years ago
}
}
8 years ago
else
8 years ago
{
8 years ago
printf("statemachinestart no kmdheight.%d\n",kmdheight);
8 years ago
free(ptr);
return;
8 years ago
}
8 years ago
if ( bp->isratify != 0 && memcmp(bp->notaries[0].pubkey,bp->ratified_pubkeys[0],33) != 0 )
{
8 years ago
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");
8 years ago
return;
}
8 years ago
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 )
8 years ago
{
8 years ago
ep->dest.prev_hash = destprevtxid0;
ep->dest.prev_vout = destprevvout0;
ep->src.prev_hash = srcprevtxid0;
ep->src.prev_vout = srcprevvout0;
8 years ago
bp->notaries[myind].ratifysrcutxo = srcprevtxid0;
bp->notaries[myind].ratifysrcvout = srcprevvout0;
bp->notaries[myind].ratifydestutxo = destprevtxid0;
bp->notaries[myind].ratifydestvout = destprevvout0;
8 years ago
printf("Use override utxo %s/v%d %s/v%d\n",bits256_str(str,destprevtxid0),destprevvout0,bits256_str(str2,srcprevtxid0),srcprevvout0);
8 years ago
}
8 years ago
else
8 years ago
{
8 years ago
if ( dpow_checkutxo(myinfo,dp,bp,bp->destcoin,&ep->dest.prev_hash,&ep->dest.prev_vout,destaddr) < 0 )
{
printf("dont have %s %s utxo, please send funds\n",dp->dest,destaddr);
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);
free(ptr);
return;
}
8 years ago
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;
}
8 years ago
}
bp->recvmask |= (1LL << myind);
8 years ago
bp->notaries[myind].othermask |= (1LL << myind);
8 years ago
dp->checkpoint = checkpoint;
8 years ago
bp->height = checkpoint.blockhash.height;
bp->timestamp = checkpoint.timestamp;
bp->hashmsg = checkpoint.blockhash.hash;
8 years ago
bp->myind = myind;
8 years ago
while ( bp->isratify == 0 && dp->destupdated == 0 )
8 years ago
{
8 years ago
if ( dp->checkpoint.blockhash.height > checkpoint.blockhash.height )
8 years ago
{
printf("abort ht.%d due to new checkpoint.%d\n",checkpoint.blockhash.height,dp->checkpoint.blockhash.height);
return;
}
sleep(1);
}
8 years ago
if ( bp->isratify == 0 || (starttime= checkpoint.timestamp) == 0 )
8 years ago
bp->starttime = starttime = (uint32_t)time(NULL);
8 years ago
printf("isratify.%d DPOW.%s statemachine checkpoint.%d %s start.%u\n",bp->isratify,src->symbol,checkpoint.blockhash.height,bits256_str(str,checkpoint.blockhash.hash),checkpoint.timestamp);
8 years ago
for (i=0; i<sizeof(srchash); i++)
8 years ago
srchash.bytes[i] = dp->minerkey33[i+1];
8 years ago
//printf("start utxosync start.%u %u\n",starttime,(uint32_t)time(NULL));
8 years ago
//dpow_utxosync(myinfo,dp,bp,0,myind,srchash);
8 years ago
//printf("done utxosync start.%u %u\n",starttime,(uint32_t)time(NULL));
8 years ago
while ( time(NULL) < starttime+bp->duration && src != 0 && dest != 0 && bp->state != 0xffffffff )
8 years ago
{
8 years ago
sleep(1);
8 years ago
if ( dp->checkpoint.blockhash.height > checkpoint.blockhash.height )
8 years ago
{
8 years ago
if ( bp->isratify == 0 )
{
printf("abort ht.%d due to new checkpoint.%d\n",checkpoint.blockhash.height,dp->checkpoint.blockhash.height);
break;
}
8 years ago
/*else if ( strcmp(dp->symbol,"KMD") == 0 )
8 years ago
{
bp->bestk = -1;
8 years ago
bp->bestmask = 0;
8 years ago
bp->height = ((dp->checkpoint.blockhash.height / 10) % (DPOW_FIRSTRATIFY/10)) * 10;
printf("new rotation ht.%d\n",bp->height);
8 years ago
dp->blocks[checkpoint.blockhash.height] = 0;
8 years ago
checkpoint.blockhash.height = dp->checkpoint.blockhash.height;
8 years ago
dp->blocks[checkpoint.blockhash.height] = bp;
8 years ago
}*/
8 years ago
}
8 years ago
if ( bp->state != 0xffffffff )
8 years ago
{
8 years ago
/*int32_t len; struct dpow_utxoentry U; uint8_t utxodata[sizeof(U)+2];
8 years ago
memset(&U,0,sizeof(U));
dpow_entry2utxo(&U,bp,&bp->notaries[myind]);
if ( (len= dpow_rwutxobuf(1,utxodata,&U,bp)) > 0 )
dpow_send(myinfo,dp,bp,srchash,bp->hashmsg,DPOW_UTXOCHANNEL,bp->height,utxodata,len);
8 years ago
else*/
8 years ago
{
8 years ago
dpow_send(myinfo,dp,bp,srchash,bp->hashmsg,0,bp->height,(void *)"ping",0);
8 years ago
}
8 years ago
}
8 years ago
if ( 0 && dp->cancelratify != 0 && bp->isratify != 0 )
8 years ago
{
printf("abort pending ratify\n");
8 years ago
break;
8 years ago
}
8 years ago
}
8 years ago
printf("isratify.%d bestk.%d %llx sigs.%llx state machine ht.%d completed state.%x %s.%s %s.%s recvmask.%llx\n",bp->isratify,bp->bestk,(long long)bp->bestmask,(long long)(bp->bestk>=0?bp->destsigsmasks[bp->bestk]:0),bp->height,bp->state,dp->dest,bits256_str(str,bp->desttxid),dp->symbol,bits256_str(str2,bp->srctxid),(long long)bp->recvmask);
8 years ago
dp->lastrecvmask = bp->recvmask;
8 years ago
free(ptr);
}
8 years ago