23
src/komodo.h
23
src/komodo.h
@@ -121,7 +121,7 @@ int32_t komodo_parsestatefile(struct komodo_state *sp,FILE *fp,char *symbol,char
|
|||||||
MoMdepth = 0;
|
MoMdepth = 0;
|
||||||
}
|
}
|
||||||
//if ( matched != 0 ) global independent states -> inside *sp
|
//if ( matched != 0 ) global independent states -> inside *sp
|
||||||
komodo_eventadd_notarized(sp,symbol,ht,dest,notarized_hash,notarized_desttxid,notarized_height);//,MoM,MoMdepth);
|
komodo_eventadd_notarized(sp,symbol,ht,dest,notarized_hash,notarized_desttxid,notarized_height,MoM,MoMdepth);
|
||||||
}
|
}
|
||||||
else if ( func == 'U' ) // deprecated
|
else if ( func == 'U' ) // deprecated
|
||||||
{
|
{
|
||||||
@@ -266,7 +266,7 @@ int32_t komodo_parsestatefiledata(struct komodo_state *sp,uint8_t *filedata,long
|
|||||||
memset(&MoM,0,sizeof(MoM));
|
memset(&MoM,0,sizeof(MoM));
|
||||||
MoMdepth = 0;
|
MoMdepth = 0;
|
||||||
}
|
}
|
||||||
komodo_eventadd_notarized(sp,symbol,ht,dest,notarized_hash,notarized_desttxid,notarized_height);//,MoM,MoMdepth);
|
komodo_eventadd_notarized(sp,symbol,ht,dest,notarized_hash,notarized_desttxid,notarized_height,MoM,MoMdepth);
|
||||||
}
|
}
|
||||||
else if ( func == 'U' ) // deprecated
|
else if ( func == 'U' ) // deprecated
|
||||||
{
|
{
|
||||||
@@ -482,10 +482,9 @@ void komodo_stateupdate(int32_t height,uint8_t notarypubs[][33],uint8_t numnotar
|
|||||||
//printf("ht.%d func N ht.%d errs.%d\n",height,NOTARIZED_HEIGHT,errs);
|
//printf("ht.%d func N ht.%d errs.%d\n",height,NOTARIZED_HEIGHT,errs);
|
||||||
if ( sp != 0 )
|
if ( sp != 0 )
|
||||||
{
|
{
|
||||||
//if ( sp->MoMdepth > 0 && sp->MoM != zero )
|
if ( sp->MoMdepth > 0 && sp->MoM != zero )
|
||||||
// fputc('M',fp);
|
fputc('M',fp);
|
||||||
//else
|
else fputc('N',fp);
|
||||||
fputc('N',fp);
|
|
||||||
if ( fwrite(&height,1,sizeof(height),fp) != sizeof(height) )
|
if ( fwrite(&height,1,sizeof(height),fp) != sizeof(height) )
|
||||||
errs++;
|
errs++;
|
||||||
if ( fwrite(&sp->NOTARIZED_HEIGHT,1,sizeof(sp->NOTARIZED_HEIGHT),fp) != sizeof(sp->NOTARIZED_HEIGHT) )
|
if ( fwrite(&sp->NOTARIZED_HEIGHT,1,sizeof(sp->NOTARIZED_HEIGHT),fp) != sizeof(sp->NOTARIZED_HEIGHT) )
|
||||||
@@ -494,14 +493,14 @@ void komodo_stateupdate(int32_t height,uint8_t notarypubs[][33],uint8_t numnotar
|
|||||||
errs++;
|
errs++;
|
||||||
if ( fwrite(&sp->NOTARIZED_DESTTXID,1,sizeof(sp->NOTARIZED_DESTTXID),fp) != sizeof(sp->NOTARIZED_DESTTXID) )
|
if ( fwrite(&sp->NOTARIZED_DESTTXID,1,sizeof(sp->NOTARIZED_DESTTXID),fp) != sizeof(sp->NOTARIZED_DESTTXID) )
|
||||||
errs++;
|
errs++;
|
||||||
/*if ( sp->MoMdepth > 0 && sp->MoM != zero )
|
if ( sp->MoMdepth > 0 && sp->MoM != zero )
|
||||||
{
|
{
|
||||||
if ( fwrite(&sp->MoM,1,sizeof(sp->MoM),fp) != sizeof(sp->MoM) )
|
if ( fwrite(&sp->MoM,1,sizeof(sp->MoM),fp) != sizeof(sp->MoM) )
|
||||||
errs++;
|
errs++;
|
||||||
if ( fwrite(&sp->MoMdepth,1,sizeof(sp->MoMdepth),fp) != sizeof(sp->MoMdepth) )
|
if ( fwrite(&sp->MoMdepth,1,sizeof(sp->MoMdepth),fp) != sizeof(sp->MoMdepth) )
|
||||||
errs++;
|
errs++;
|
||||||
}*/
|
}
|
||||||
komodo_eventadd_notarized(sp,symbol,height,dest,sp->NOTARIZED_HASH,sp->NOTARIZED_DESTTXID,sp->NOTARIZED_HEIGHT);//,sp->MoM,sp->MoMdepth);
|
komodo_eventadd_notarized(sp,symbol,height,dest,sp->NOTARIZED_HASH,sp->NOTARIZED_DESTTXID,sp->NOTARIZED_HEIGHT,sp->MoM,sp->MoMdepth);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
fflush(fp);
|
fflush(fp);
|
||||||
@@ -680,7 +679,7 @@ int32_t komodo_voutupdate(int32_t *isratificationp,int32_t notaryid,uint8_t *scr
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
//komodo_rwccdata(ASSETCHAINS_SYMBOL,1,&ccdata,&MoMoMdata);
|
komodo_rwccdata(ASSETCHAINS_SYMBOL,1,&ccdata,&MoMoMdata);
|
||||||
//printf("[%s] matched.%d VALID (%s) MoM.%s [%d]\n",ASSETCHAINS_SYMBOL,matched,ccdata.symbol,MoM.ToString().c_str(),MoMdepth);
|
//printf("[%s] matched.%d VALID (%s) MoM.%s [%d]\n",ASSETCHAINS_SYMBOL,matched,ccdata.symbol,MoM.ToString().c_str(),MoMdepth);
|
||||||
}
|
}
|
||||||
if ( MoMoMdata.pairs != 0 )
|
if ( MoMoMdata.pairs != 0 )
|
||||||
@@ -688,8 +687,8 @@ int32_t komodo_voutupdate(int32_t *isratificationp,int32_t notaryid,uint8_t *scr
|
|||||||
memset(&ccdata,0,sizeof(ccdata));
|
memset(&ccdata,0,sizeof(ccdata));
|
||||||
memset(&MoMoMdata,0,sizeof(MoMoMdata));
|
memset(&MoMoMdata,0,sizeof(MoMoMdata));
|
||||||
}
|
}
|
||||||
//else if ( ASSETCHAINS_SYMBOL[0] == 0 && matched != 0 && notarized != 0 && validated != 0 )
|
else if ( ASSETCHAINS_SYMBOL[0] == 0 && matched != 0 && notarized != 0 && validated != 0 )
|
||||||
// komodo_rwccdata((char *)"KMD",1,&ccdata,0);
|
komodo_rwccdata((char *)"KMD",1,&ccdata,0);
|
||||||
if ( matched != 0 && *notarizedheightp > sp->NOTARIZED_HEIGHT && *notarizedheightp < height )
|
if ( matched != 0 && *notarizedheightp > sp->NOTARIZED_HEIGHT && *notarizedheightp < height )
|
||||||
{
|
{
|
||||||
sp->NOTARIZED_HEIGHT = *notarizedheightp;
|
sp->NOTARIZED_HEIGHT = *notarizedheightp;
|
||||||
|
|||||||
@@ -1044,3 +1044,302 @@ int32_t komodo_validate_interest(const CTransaction &tx,int32_t txheight,uint32_
|
|||||||
return(0);
|
return(0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
komodo_checkPOW (fast) is called early in the process and should only refer to data immediately available. it is a filter to prevent bad blocks from going into the local DB
|
||||||
|
|
||||||
|
komodo_checkPOW (slow) is called right before connecting blocks so all prior blocks can be assumed to be there and all checks must pass
|
||||||
|
|
||||||
|
commission must be in coinbase.vout[1] and must be >= 10000 sats
|
||||||
|
PoS stake must be without txfee and in the last tx in the block at vout[0]
|
||||||
|
PoW mining on PoS chain must solve a harder diff that adjusts, but never less than KOMODO_POWMINMULT
|
||||||
|
*/
|
||||||
|
#define KOMODO_POWMINMULT 16
|
||||||
|
|
||||||
|
uint64_t komodo_commission(const CBlock *pblock)
|
||||||
|
{
|
||||||
|
int32_t i,j,n=0,txn_count; uint64_t commission,total = 0;
|
||||||
|
txn_count = pblock->vtx.size();
|
||||||
|
for (i=0; i<txn_count; i++)
|
||||||
|
{
|
||||||
|
n = pblock->vtx[i].vout.size();
|
||||||
|
for (j=0; j<n; j++)
|
||||||
|
{
|
||||||
|
//fprintf(stderr,"(%d %.8f).%d ",i,dstr(block.vtx[i].vout[j].nValue),j);
|
||||||
|
if ( i != 0 || j != 1 )
|
||||||
|
total += pblock->vtx[i].vout[j].nValue;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
//fprintf(stderr,"txn.%d n.%d commission total %.8f -> %.8f\n",txn_count,n,dstr(total),dstr((total * ASSETCHAINS_COMMISSION) / COIN));
|
||||||
|
commission = ((total * ASSETCHAINS_COMMISSION) / COIN);
|
||||||
|
if ( commission < 10000 )
|
||||||
|
commission = 0;
|
||||||
|
return(commission);
|
||||||
|
}
|
||||||
|
|
||||||
|
uint32_t komodo_stake(int32_t validateflag,arith_uint256 bnTarget,int32_t nHeight,uint256 txid,int32_t vout,uint32_t blocktime,uint32_t prevtime,char *destaddr)
|
||||||
|
{
|
||||||
|
CBlockIndex *pindex; uint8_t hashbuf[128]; char address[64]; bits256 addrhash; arith_uint256 hashval; uint256 hash,pasthash; int64_t diff=0; int32_t segid,minage,i,iter=0; uint32_t txtime,winner = 0; uint64_t value,coinage,supply = ASSETCHAINS_SUPPLY + nHeight*ASSETCHAINS_REWARD/SATOSHIDEN;
|
||||||
|
txtime = komodo_txtime(&value,txid,vout,address);
|
||||||
|
if ( value == 0 || txtime == 0 || blocktime == 0 || prevtime == 0 )
|
||||||
|
return(0);
|
||||||
|
if ( (minage= nHeight*3) > 6000 )
|
||||||
|
minage = 6000;
|
||||||
|
if ( blocktime < prevtime+57 )
|
||||||
|
blocktime = prevtime+57;
|
||||||
|
if ( blocktime > txtime+minage && (pindex= komodo_chainactive(nHeight>200?nHeight-200:1)) != 0 )
|
||||||
|
{
|
||||||
|
vcalc_sha256(0,(uint8_t *)&addrhash,(uint8_t *)address,(int32_t)strlen(address));
|
||||||
|
segid = ((nHeight + addrhash.uints[0]) & 0x3f);
|
||||||
|
pasthash = pindex->GetBlockHash();
|
||||||
|
memcpy(hashbuf,&pasthash,sizeof(pasthash));
|
||||||
|
memcpy(&hashbuf[sizeof(pasthash)],&addrhash,sizeof(addrhash));
|
||||||
|
vcalc_sha256(0,(uint8_t *)&hash,hashbuf,(int32_t)sizeof(uint256)*2);
|
||||||
|
//fprintf(stderr,"(%s) vs. (%s) %s %.8f txtime.%u\n",address,destaddr,hash.ToString().c_str(),dstr(value),txtime);
|
||||||
|
for (iter=0; iter<3600; iter++)
|
||||||
|
{
|
||||||
|
diff = (iter + blocktime - txtime - minage);
|
||||||
|
if ( diff > 3600*24 )
|
||||||
|
break;
|
||||||
|
coinage = (value * diff) * ((diff >> 16) + 1);
|
||||||
|
hashval = arith_uint256(supply * 64) * (UintToArith256(hash) / arith_uint256(coinage+1));
|
||||||
|
if ( hashval <= bnTarget )
|
||||||
|
{
|
||||||
|
winner = 1;
|
||||||
|
if ( validateflag == 0 )
|
||||||
|
{
|
||||||
|
blocktime += iter;
|
||||||
|
blocktime += segid * 2;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
if ( validateflag != 0 )
|
||||||
|
{
|
||||||
|
for (i=31; i>=24; i--)
|
||||||
|
fprintf(stderr,"%02x",((uint8_t *)&hashval)[i]);
|
||||||
|
fprintf(stderr," vs target ");
|
||||||
|
for (i=31; i>=24; i--)
|
||||||
|
fprintf(stderr,"%02x",((uint8_t *)&bnTarget)[i]);
|
||||||
|
fprintf(stderr," segid.%d iter.%d winner.%d coinage.%llu %d ht.%d gap.%d %.8f diff.%d\n",segid,iter,winner,(long long)coinage,(int32_t)(blocktime - txtime),nHeight,(int32_t)(blocktime - prevtime),dstr(value),(int32_t)diff);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
//fprintf(stderr,"iterated until i.%d winner.%d\n",i,winner);
|
||||||
|
if ( 0 )
|
||||||
|
{
|
||||||
|
for (i=31; i>=24; i--)
|
||||||
|
fprintf(stderr,"%02x",((uint8_t *)&hashval)[i]);
|
||||||
|
fprintf(stderr," vs ");
|
||||||
|
for (i=31; i>=24; i--)
|
||||||
|
fprintf(stderr,"%02x",((uint8_t *)&bnTarget)[i]);
|
||||||
|
fprintf(stderr," segid.%d iter.%d winner.%d coinage.%llu %d ht.%d t.%u %.8f diff.%d\n",segid,iter,winner,(long long)coinage,(int32_t)(blocktime - txtime),nHeight,blocktime,dstr(value),(int32_t)diff);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if ( nHeight < 2 )
|
||||||
|
return(blocktime);
|
||||||
|
return(blocktime * winner);
|
||||||
|
}
|
||||||
|
|
||||||
|
arith_uint256 komodo_PoWtarget(int32_t *percPoSp,arith_uint256 target,int32_t height,int32_t goalperc)
|
||||||
|
{
|
||||||
|
CBlockIndex *pindex; arith_uint256 bnTarget,hashval,sum,ave; bool fNegative,fOverflow; int32_t i,n,ht,percPoS,diff,val;
|
||||||
|
*percPoSp = percPoS = 0;
|
||||||
|
if ( height < 3 )
|
||||||
|
return(target);
|
||||||
|
sum = arith_uint256(0);
|
||||||
|
ave = sum;
|
||||||
|
for (i=n=0; i<100; i++)
|
||||||
|
{
|
||||||
|
ht = height - 100 + i;
|
||||||
|
if ( (pindex= komodo_chainactive(ht)) != 0 )
|
||||||
|
{
|
||||||
|
bnTarget.SetCompact(pindex->nBits,&fNegative,&fOverflow);
|
||||||
|
bnTarget = (bnTarget / arith_uint256(KOMODO_POWMINMULT));
|
||||||
|
hashval = UintToArith256(pindex->GetBlockHash());
|
||||||
|
if ( hashval <= bnTarget ) // PoW is never as easy as PoS/64, some PoS will be counted as PoW
|
||||||
|
{
|
||||||
|
fprintf(stderr,"1");
|
||||||
|
sum += hashval;
|
||||||
|
n++;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
percPoS++;
|
||||||
|
fprintf(stderr,"0");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
fprintf(stderr," -> %d%% percPoS ht.%d\n",percPoS,height);
|
||||||
|
*percPoSp = percPoS;
|
||||||
|
target = (target / arith_uint256(KOMODO_POWMINMULT));
|
||||||
|
if ( n > 0 )
|
||||||
|
{
|
||||||
|
ave = (sum / arith_uint256(n));
|
||||||
|
if ( ave > target )
|
||||||
|
ave = target;
|
||||||
|
} else return(target);
|
||||||
|
if ( percPoS < goalperc ) // increase PoW diff -> lower bnTarget
|
||||||
|
{
|
||||||
|
bnTarget = (ave * arith_uint256(percPoS * percPoS)) / arith_uint256((goalperc) * (goalperc));
|
||||||
|
/*if ( height > 1165 )
|
||||||
|
{
|
||||||
|
if ( height > 1180 )
|
||||||
|
{
|
||||||
|
if ( height > 1230 )
|
||||||
|
bnTarget = (ave * arith_uint256(percPoS * percPoS)) / arith_uint256((goalperc) * (goalperc));
|
||||||
|
else bnTarget = (ave * arith_uint256(percPoS * percPoS)) / arith_uint256(goalperc * goalperc);
|
||||||
|
}
|
||||||
|
else bnTarget = (ave * arith_uint256(goalperc * goalperc)) / arith_uint256(2 * (percPoS + goalperc) * (percPoS + goalperc));
|
||||||
|
} else bnTarget = (ave * arith_uint256(goalperc)) / arith_uint256(percPoS + goalperc);*/
|
||||||
|
if ( 1 )
|
||||||
|
{
|
||||||
|
for (i=31; i>=24; i--)
|
||||||
|
fprintf(stderr,"%02x",((uint8_t *)&ave)[i]);
|
||||||
|
fprintf(stderr," increase diff -> ");
|
||||||
|
for (i=31; i>=24; i--)
|
||||||
|
fprintf(stderr,"%02x",((uint8_t *)&bnTarget)[i]);
|
||||||
|
fprintf(stderr," floor diff ");
|
||||||
|
for (i=31; i>=24; i--)
|
||||||
|
fprintf(stderr,"%02x",((uint8_t *)&target)[i]);
|
||||||
|
fprintf(stderr," ht.%d percPoS.%d vs goal.%d -> diff %d\n",height,percPoS,goalperc,goalperc - percPoS);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if ( percPoS > goalperc ) // decrease PoW diff -> raise bnTarget
|
||||||
|
{
|
||||||
|
bnTarget = ((ave * arith_uint256(goalperc)) + (target * arith_uint256(percPoS))) / arith_uint256(percPoS + goalperc);
|
||||||
|
if ( 1 )
|
||||||
|
{
|
||||||
|
for (i=31; i>=24; i--)
|
||||||
|
fprintf(stderr,"%02x",((uint8_t *)&ave)[i]);
|
||||||
|
fprintf(stderr," decrease diff -> ");
|
||||||
|
for (i=31; i>=24; i--)
|
||||||
|
fprintf(stderr,"%02x",((uint8_t *)&bnTarget)[i]);
|
||||||
|
fprintf(stderr," floor diff ");
|
||||||
|
for (i=31; i>=24; i--)
|
||||||
|
fprintf(stderr,"%02x",((uint8_t *)&target)[i]);
|
||||||
|
fprintf(stderr," ht.%d percPoS.%d vs goal.%d -> diff %d\n",height,percPoS,goalperc,goalperc - percPoS);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else bnTarget = ave; // recent ave is perfect
|
||||||
|
return(bnTarget);
|
||||||
|
}
|
||||||
|
|
||||||
|
int32_t komodo_is_PoSblock(int32_t slowflag,int32_t height,CBlock *pblock,arith_uint256 bnTarget)
|
||||||
|
{
|
||||||
|
CBlockIndex *previndex; char voutaddr[64],destaddr[64]; uint256 txid; uint32_t txtime,prevtime=0; int32_t vout,txn_count,eligible,isPoS = 0; uint64_t value; CTxDestination voutaddress;
|
||||||
|
txn_count = pblock->vtx.size();
|
||||||
|
if ( txn_count > 1 )
|
||||||
|
{
|
||||||
|
if ( prevtime == 0 )
|
||||||
|
{
|
||||||
|
if ( (previndex= mapBlockIndex[pblock->hashPrevBlock]) != 0 )
|
||||||
|
prevtime = (uint32_t)previndex->nTime;
|
||||||
|
}
|
||||||
|
txid = pblock->vtx[txn_count-1].vin[0].prevout.hash;
|
||||||
|
vout = pblock->vtx[txn_count-1].vin[0].prevout.n;
|
||||||
|
if ( prevtime != 0 )
|
||||||
|
{
|
||||||
|
eligible = komodo_stake(1,bnTarget,height,txid,vout,pblock->nTime,prevtime,(char *)"");
|
||||||
|
if ( eligible == 0 || eligible > pblock->nTime )
|
||||||
|
{
|
||||||
|
fprintf(stderr,"komodo_is_PoSblock PoS failure ht.%d eligible.%u vs blocktime.%u, lag.%d -> check to see if it is PoW block\n",height,eligible,(uint32_t)pblock->nTime,(int32_t)(eligible - pblock->nTime));
|
||||||
|
} else isPoS = 1;
|
||||||
|
}
|
||||||
|
else if ( slowflag == 0 ) // maybe previous block is not seen yet, do the best approx
|
||||||
|
{
|
||||||
|
txtime = komodo_txtime(&value,txid,vout,destaddr);
|
||||||
|
if ( ExtractDestination(pblock->vtx[txn_count-1].vout[0].scriptPubKey,voutaddress) )
|
||||||
|
{
|
||||||
|
strcpy(voutaddr,CBitcoinAddress(voutaddress).ToString().c_str());
|
||||||
|
if ( strcmp(destaddr,voutaddr) == 0 && pblock->vtx[txn_count-1].vout[0].nValue == value )
|
||||||
|
isPoS = 1; // close enough for a pre-filter
|
||||||
|
else fprintf(stderr,"komodo_is_PoSblock ht.%d (%s) != (%s) or %.8f != %.8f\n",height,destaddr,voutaddr,dstr(value),dstr(pblock->vtx[txn_count-1].vout[0].nValue));
|
||||||
|
} else fprintf(stderr,"komodo_is_PoSblock ht.%d couldnt extract voutaddress\n",height);
|
||||||
|
} else return(-1);
|
||||||
|
}
|
||||||
|
return(isPoS);
|
||||||
|
}
|
||||||
|
|
||||||
|
int32_t komodo_checkPOW(int32_t slowflag,CBlock *pblock,int32_t height)
|
||||||
|
{
|
||||||
|
uint256 hash; arith_uint256 bnTarget,bhash; bool fNegative,fOverflow; uint8_t *script,pubkey33[33],pubkeys[64][33]; int32_t i,PoSperc,is_PoSblock=0,n,failed = 0,notaryid = -1; int64_t checktoshis,value; CBlockIndex *pprev;
|
||||||
|
if ( !CheckEquihashSolution(pblock, Params()) )
|
||||||
|
{
|
||||||
|
fprintf(stderr,"komodo_checkPOW slowflag.%d ht.%d CheckEquihashSolution failed\n",slowflag,height);
|
||||||
|
return(-1);
|
||||||
|
}
|
||||||
|
hash = pblock->GetHash();
|
||||||
|
if ( height == 0 )
|
||||||
|
{
|
||||||
|
if ( (pprev= mapBlockIndex[pblock->hashPrevBlock]) != 0 )
|
||||||
|
height = pprev->nHeight + 1;
|
||||||
|
fprintf(stderr,"komodo_checkPOW slowflag.%d ht.%d zeroheight\n",slowflag,height);
|
||||||
|
//if ( height == 0 )
|
||||||
|
return(0);
|
||||||
|
}
|
||||||
|
bnTarget.SetCompact(pblock->nBits,&fNegative,&fOverflow);
|
||||||
|
bhash = UintToArith256(hash);
|
||||||
|
komodo_block2pubkey33(pubkey33,pblock);
|
||||||
|
if ( bhash > bnTarget )
|
||||||
|
{
|
||||||
|
failed = 1;
|
||||||
|
if ( ASSETCHAINS_SYMBOL[0] == 0 ) // for the fast case
|
||||||
|
{
|
||||||
|
if ( (n= komodo_notaries(pubkeys,height,pblock->nTime)) > 0 )
|
||||||
|
{
|
||||||
|
for (i=0; i<n; i++)
|
||||||
|
if ( memcmp(pubkey33,pubkeys[i],33) == 0 )
|
||||||
|
{
|
||||||
|
notaryid = i;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if ( ASSETCHAINS_STAKED != 0 && height >= 2 ) // must PoS or have at least 16x better PoW
|
||||||
|
{
|
||||||
|
if ( (is_PoSblock= komodo_is_PoSblock(slowflag,height,pblock,bnTarget)) == 0 )
|
||||||
|
{
|
||||||
|
if ( ASSETCHAINS_STAKED == 100 && height > 100 ) // only PoS allowed!
|
||||||
|
return(-1);
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if ( slowflag != 0 )
|
||||||
|
bnTarget = komodo_PoWtarget(&PoSperc,bnTarget,height,ASSETCHAINS_STAKED);
|
||||||
|
else bnTarget = (bnTarget / arith_uint256(KOMODO_POWMINMULT)); // lower bound
|
||||||
|
if ( bhash > bnTarget )
|
||||||
|
{
|
||||||
|
for (i=31; i>=16; i--)
|
||||||
|
fprintf(stderr,"%02x",((uint8_t *)&bhash)[i]);
|
||||||
|
fprintf(stderr," > ");
|
||||||
|
for (i=31; i>=16; i--)
|
||||||
|
fprintf(stderr,"%02x",((uint8_t *)&bnTarget)[i]);
|
||||||
|
fprintf(stderr," ht.%d PoW diff violation PoSperc.%d vs goalperc.%d\n",height,PoSperc,(int32_t)ASSETCHAINS_STAKED);
|
||||||
|
return(-1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else if ( is_PoSblock < 0 )
|
||||||
|
return(-1);
|
||||||
|
}
|
||||||
|
if ( failed == 0 && ASSETCHAINS_OVERRIDE_PUBKEY33[0] != 0 && ASSETCHAINS_COMMISSION != 0 )
|
||||||
|
{
|
||||||
|
checktoshis = komodo_commission(pblock);
|
||||||
|
if ( checktoshis > 10000 && pblock->vtx[0].vout.size() != 2 )
|
||||||
|
return(-1);
|
||||||
|
else if ( checktoshis != 0 )
|
||||||
|
{
|
||||||
|
script = (uint8_t *)pblock->vtx[0].vout[1].scriptPubKey.data();
|
||||||
|
if ( script[0] != 33 || script[34] != OP_CHECKSIG || memcmp(script+1,ASSETCHAINS_OVERRIDE_PUBKEY33,33) != 0 )
|
||||||
|
return(-1);
|
||||||
|
if ( pblock->vtx[0].vout[1].nValue != checktoshis )
|
||||||
|
{
|
||||||
|
fprintf(stderr,"checktoshis %.8f vs actual vout[1] %.8f\n",dstr(checktoshis),dstr(pblock->vtx[0].vout[1].nValue));
|
||||||
|
return(-1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
fprintf(stderr,"komodo_checkPOW slowflag.%d ht.%d notaryid.%d failed.%d\n",slowflag,height,notaryid,failed);
|
||||||
|
if ( failed != 0 && notaryid < 0 )
|
||||||
|
return(-1);
|
||||||
|
else return(0);
|
||||||
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -37,7 +37,7 @@ struct komodo_event *komodo_eventadd(struct komodo_state *sp,int32_t height,char
|
|||||||
return(ep);
|
return(ep);
|
||||||
}
|
}
|
||||||
|
|
||||||
void komodo_eventadd_notarized(struct komodo_state *sp,char *symbol,int32_t height,char *dest,uint256 notarized_hash,uint256 notarized_desttxid,int32_t notarizedheight)//,uint256 MoM,int32_t MoMdepth)
|
void komodo_eventadd_notarized(struct komodo_state *sp,char *symbol,int32_t height,char *dest,uint256 notarized_hash,uint256 notarized_desttxid,int32_t notarizedheight,uint256 MoM,int32_t MoMdepth)
|
||||||
{
|
{
|
||||||
struct komodo_event_notarized N;
|
struct komodo_event_notarized N;
|
||||||
if ( NOTARY_PUBKEY33[0] != 0 && komodo_verifynotarization(symbol,dest,height,notarizedheight,notarized_hash,notarized_desttxid) != 0 )
|
if ( NOTARY_PUBKEY33[0] != 0 && komodo_verifynotarization(symbol,dest,height,notarizedheight,notarized_hash,notarized_desttxid) != 0 )
|
||||||
@@ -53,12 +53,12 @@ void komodo_eventadd_notarized(struct komodo_state *sp,char *symbol,int32_t heig
|
|||||||
N.blockhash = notarized_hash;
|
N.blockhash = notarized_hash;
|
||||||
N.desttxid = notarized_desttxid;
|
N.desttxid = notarized_desttxid;
|
||||||
N.notarizedheight = notarizedheight;
|
N.notarizedheight = notarizedheight;
|
||||||
//N.MoM = MoM;
|
N.MoM = MoM;
|
||||||
//N.MoMdepth = MoMdepth;
|
N.MoMdepth = MoMdepth;
|
||||||
strncpy(N.dest,dest,sizeof(N.dest)-1);
|
strncpy(N.dest,dest,sizeof(N.dest)-1);
|
||||||
komodo_eventadd(sp,height,symbol,KOMODO_EVENT_NOTARIZED,(uint8_t *)&N,sizeof(N));
|
komodo_eventadd(sp,height,symbol,KOMODO_EVENT_NOTARIZED,(uint8_t *)&N,sizeof(N));
|
||||||
if ( sp != 0 )
|
if ( sp != 0 )
|
||||||
komodo_notarized_update(sp,height,notarizedheight,notarized_hash,notarized_desttxid);//,MoM,MoMdepth);
|
komodo_notarized_update(sp,height,notarizedheight,notarized_hash,notarized_desttxid,MoM,MoMdepth);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -650,153 +650,6 @@ int32_t komodo_bannedset(int32_t *indallvoutsp,uint256 *array,int32_t max)
|
|||||||
|
|
||||||
void komodo_passport_iteration();
|
void komodo_passport_iteration();
|
||||||
|
|
||||||
uint64_t komodo_commission(const CBlock &block)
|
|
||||||
{
|
|
||||||
int32_t i,j,n=0,txn_count; uint64_t total = 0;
|
|
||||||
txn_count = block.vtx.size();
|
|
||||||
for (i=0; i<txn_count; i++)
|
|
||||||
{
|
|
||||||
n = block.vtx[i].vout.size();
|
|
||||||
for (j=0; j<n; j++)
|
|
||||||
{
|
|
||||||
//fprintf(stderr,"(%d %.8f).%d ",i,dstr(block.vtx[i].vout[j].nValue),j);
|
|
||||||
if ( i != 0 || j != 1 )
|
|
||||||
{
|
|
||||||
total += block.vtx[i].vout[j].nValue;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
//fprintf(stderr,"txn.%d n.%d commission total %.8f -> %.8f\n",txn_count,n,dstr(total),dstr((total * ASSETCHAINS_COMMISSION) / COIN));
|
|
||||||
return((total * ASSETCHAINS_COMMISSION) / COIN);
|
|
||||||
}
|
|
||||||
|
|
||||||
uint32_t komodo_stake(int32_t validateflag,arith_uint256 bnTarget,int32_t nHeight,uint256 txid,int32_t vout,uint32_t blocktime,uint32_t prevtime,char *destaddr)
|
|
||||||
{
|
|
||||||
CBlockIndex *pindex; uint8_t hashbuf[128]; char address[64]; bits256 addrhash; arith_uint256 hashval; uint256 hash,pasthash; int64_t diff=0; int32_t segid,minage,i,iter=0; uint32_t txtime,winner = 0; uint64_t value,coinage,supply = ASSETCHAINS_SUPPLY + nHeight*ASSETCHAINS_REWARD/SATOSHIDEN;
|
|
||||||
txtime = komodo_txtime(&value,txid,vout,address);
|
|
||||||
if ( value == 0 || txtime == 0 )
|
|
||||||
return(0);
|
|
||||||
if ( (minage= nHeight*3) > 6000 )
|
|
||||||
minage = 6000;
|
|
||||||
if ( blocktime > txtime+minage && (pindex= komodo_chainactive(nHeight>200?nHeight-200:1)) != 0 )
|
|
||||||
{
|
|
||||||
vcalc_sha256(0,(uint8_t *)&addrhash,(uint8_t *)address,(int32_t)strlen(address));
|
|
||||||
segid = ((nHeight + addrhash.uints[0]) & 0x3f);
|
|
||||||
pasthash = pindex->GetBlockHash();
|
|
||||||
memcpy(hashbuf,&pasthash,sizeof(pasthash));
|
|
||||||
memcpy(&hashbuf[sizeof(pasthash)],&addrhash,sizeof(addrhash));
|
|
||||||
vcalc_sha256(0,(uint8_t *)&hash,hashbuf,(int32_t)sizeof(uint256)*2);
|
|
||||||
//fprintf(stderr,"(%s) vs. (%s) %s %.8f txtime.%u\n",address,destaddr,hash.ToString().c_str(),dstr(value),txtime);
|
|
||||||
for (iter=0; iter<3600; iter++)
|
|
||||||
{
|
|
||||||
diff = (iter + blocktime - txtime - minage);
|
|
||||||
if ( diff > 3600*24 )
|
|
||||||
break;
|
|
||||||
coinage = (value * diff) * ((diff >> 16) + 1);
|
|
||||||
hashval = arith_uint256(supply * 64) * (UintToArith256(hash) / arith_uint256(coinage+1));
|
|
||||||
if ( hashval <= bnTarget )
|
|
||||||
{
|
|
||||||
winner = 1;
|
|
||||||
if ( validateflag == 0 )
|
|
||||||
{
|
|
||||||
blocktime += iter;
|
|
||||||
blocktime += segid * 2;
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
if ( validateflag != 0 )
|
|
||||||
{
|
|
||||||
for (i=31; i>=24; i--)
|
|
||||||
fprintf(stderr,"%02x",((uint8_t *)&hashval)[i]);
|
|
||||||
fprintf(stderr," vs target ");
|
|
||||||
for (i=31; i>=24; i--)
|
|
||||||
fprintf(stderr,"%02x",((uint8_t *)&bnTarget)[i]);
|
|
||||||
fprintf(stderr," segid.%d iter.%d winner.%d coinage.%llu %d ht.%d gap.%d %.8f diff.%d\n",segid,iter,winner,(long long)coinage,(int32_t)(blocktime - txtime),nHeight,(int32_t)(blocktime - prevtime),dstr(value),(int32_t)diff);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
//fprintf(stderr,"iterated until i.%d winner.%d\n",i,winner);
|
|
||||||
if ( 0 )
|
|
||||||
{
|
|
||||||
for (i=31; i>=24; i--)
|
|
||||||
fprintf(stderr,"%02x",((uint8_t *)&hashval)[i]);
|
|
||||||
fprintf(stderr," vs ");
|
|
||||||
for (i=31; i>=24; i--)
|
|
||||||
fprintf(stderr,"%02x",((uint8_t *)&bnTarget)[i]);
|
|
||||||
fprintf(stderr," segid.%d iter.%d winner.%d coinage.%llu %d ht.%d t.%u %.8f diff.%d\n",segid,iter,winner,(long long)coinage,(int32_t)(blocktime - txtime),nHeight,blocktime,dstr(value),(int32_t)diff);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if ( nHeight < 2 )
|
|
||||||
return(blocktime);
|
|
||||||
return(blocktime * winner);
|
|
||||||
}
|
|
||||||
|
|
||||||
#define KOMODO_POWMINMULT 16
|
|
||||||
arith_uint256 komodo_PoWtarget(int32_t *percPoSp,arith_uint256 target,int32_t height,int32_t goalperc)
|
|
||||||
{
|
|
||||||
CBlockIndex *pindex; arith_uint256 bnTarget,hashval,sum,ave; bool fNegative,fOverflow; int32_t i,n,ht,percPoS,diff;
|
|
||||||
*percPoSp = percPoS = 0;
|
|
||||||
sum = arith_uint256(0);
|
|
||||||
ave = sum;
|
|
||||||
for (i=n=0; i<100; i++)
|
|
||||||
{
|
|
||||||
ht = height - 100 + i;
|
|
||||||
if ( (pindex= komodo_chainactive(ht)) != 0 )
|
|
||||||
{
|
|
||||||
bnTarget.SetCompact(pindex->nBits,&fNegative,&fOverflow);
|
|
||||||
bnTarget = (bnTarget / arith_uint256(KOMODO_POWMINMULT));
|
|
||||||
hashval = UintToArith256(pindex->GetBlockHash());
|
|
||||||
if ( hashval <= bnTarget ) // PoW is never as easy as PoS/64, some PoS will be counted as PoW
|
|
||||||
{
|
|
||||||
sum += hashval;
|
|
||||||
n++;
|
|
||||||
} else percPoS++;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
*percPoSp = percPoS;
|
|
||||||
target = (target / arith_uint256(KOMODO_POWMINMULT));
|
|
||||||
if ( n > 0 )
|
|
||||||
{
|
|
||||||
ave = (sum / arith_uint256(n));
|
|
||||||
if ( ave > target )
|
|
||||||
ave = target;
|
|
||||||
} else return(target);
|
|
||||||
if ( percPoS < goalperc ) // increase PoW diff -> lower bnTarget
|
|
||||||
{
|
|
||||||
bnTarget = (ave * arith_uint256(goalperc)) / arith_uint256(percPoS + goalperc);
|
|
||||||
if ( 1 )
|
|
||||||
{
|
|
||||||
for (i=31; i>=24; i--)
|
|
||||||
fprintf(stderr,"%02x",((uint8_t *)&ave)[i]);
|
|
||||||
fprintf(stderr," increase diff -> ");
|
|
||||||
for (i=31; i>=24; i--)
|
|
||||||
fprintf(stderr,"%02x",((uint8_t *)&bnTarget)[i]);
|
|
||||||
fprintf(stderr," floor diff ");
|
|
||||||
for (i=31; i>=24; i--)
|
|
||||||
fprintf(stderr,"%02x",((uint8_t *)&target)[i]);
|
|
||||||
fprintf(stderr," ht.%d percPoS.%d vs goal.%d -> diff %d\n",height,percPoS,goalperc,goalperc - percPoS);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else if ( percPoS > goalperc ) // decrease PoW diff -> raise bnTarget
|
|
||||||
{
|
|
||||||
bnTarget = ((ave * arith_uint256(goalperc)) + (target * arith_uint256(percPoS))) / arith_uint256(percPoS + goalperc);
|
|
||||||
if ( 1 )
|
|
||||||
{
|
|
||||||
for (i=31; i>=24; i--)
|
|
||||||
fprintf(stderr,"%02x",((uint8_t *)&ave)[i]);
|
|
||||||
fprintf(stderr," decrease diff -> ");
|
|
||||||
for (i=31; i>=24; i--)
|
|
||||||
fprintf(stderr,"%02x",((uint8_t *)&bnTarget)[i]);
|
|
||||||
fprintf(stderr," floor diff ");
|
|
||||||
for (i=31; i>=24; i--)
|
|
||||||
fprintf(stderr,"%02x",((uint8_t *)&target)[i]);
|
|
||||||
fprintf(stderr," ht.%d percPoS.%d vs goal.%d -> diff %d\n",height,percPoS,goalperc,goalperc - percPoS);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else bnTarget = ave; // recent ave is perfect
|
|
||||||
return(bnTarget);
|
|
||||||
}
|
|
||||||
|
|
||||||
int32_t komodo_check_deposit(int32_t height,const CBlock& block,uint32_t prevtime) // verify above block is valid pax pricing
|
int32_t komodo_check_deposit(int32_t height,const CBlock& block,uint32_t prevtime) // verify above block is valid pax pricing
|
||||||
{
|
{
|
||||||
static uint256 array[64]; static int32_t numbanned,indallvouts;
|
static uint256 array[64]; static int32_t numbanned,indallvouts;
|
||||||
@@ -867,59 +720,6 @@ int32_t komodo_check_deposit(int32_t height,const CBlock& block,uint32_t prevtim
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
if ( ASSETCHAINS_STAKED != 0 && height >= 2 )
|
|
||||||
{
|
|
||||||
arith_uint256 bnTarget,hashval; int32_t PoSperc; bool fNegative,fOverflow; CBlockIndex *previndex; uint32_t eligible,isPoS = 0;
|
|
||||||
bnTarget.SetCompact(block.nBits, &fNegative, &fOverflow);
|
|
||||||
if ( txn_count > 1 )
|
|
||||||
{
|
|
||||||
if ( prevtime == 0 )
|
|
||||||
{
|
|
||||||
if ( (previndex= mapBlockIndex[block.hashPrevBlock]) != 0 )
|
|
||||||
prevtime = (uint32_t)previndex->nTime;
|
|
||||||
}
|
|
||||||
eligible = komodo_stake(1,bnTarget,height,block.vtx[txn_count-1].vin[0].prevout.hash,block.vtx[txn_count-1].vin[0].prevout.n,block.nTime,prevtime,(char *)"");
|
|
||||||
if ( eligible == 0 || eligible > block.nTime )
|
|
||||||
{
|
|
||||||
fprintf(stderr,"PoS failure ht.%d eligible.%u vs blocktime.%u, lag.%d -> check to see if it is PoW block\n",height,eligible,(uint32_t)block.nTime,(int32_t)(eligible - block.nTime));
|
|
||||||
} else isPoS = 1;
|
|
||||||
}
|
|
||||||
if ( isPoS == 0 && height > 100 )
|
|
||||||
{
|
|
||||||
if ( ASSETCHAINS_STAKED == 100 )
|
|
||||||
{
|
|
||||||
fprintf(stderr,"ht.%d 100%% PoS after height 100 rule violated for -ac_staking=100\n",height);
|
|
||||||
return(-1);
|
|
||||||
}
|
|
||||||
// check PoW
|
|
||||||
bnTarget = komodo_PoWtarget(&PoSperc,bnTarget,height,ASSETCHAINS_STAKED);
|
|
||||||
hashval = UintToArith256(block.GetHash());
|
|
||||||
if ( hashval > bnTarget )
|
|
||||||
{
|
|
||||||
/*for (i=31; i>=0; i--)
|
|
||||||
fprintf(stderr,"%02x",((uint8_t *)&hashval)[i]);
|
|
||||||
fprintf(stderr," > ");
|
|
||||||
for (i=31; i>=0; i--)
|
|
||||||
fprintf(stderr,"%02x",((uint8_t *)&bnTarget)[i]);
|
|
||||||
fprintf(stderr," ht.%d PoW diff violation PoSperc.%d vs goalperc.%d\n",height,PoSperc,(int32_t)ASSETCHAINS_STAKED);*/
|
|
||||||
return(-1);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if ( ASSETCHAINS_OVERRIDE_PUBKEY33[0] != 0 && ASSETCHAINS_COMMISSION != 0 && block.vtx[0].vout.size() > 1 )
|
|
||||||
{
|
|
||||||
script = (uint8_t *)block.vtx[0].vout[1].scriptPubKey.data();
|
|
||||||
if ( script[0] != 33 || script[34] != OP_CHECKSIG || memcmp(script+1,ASSETCHAINS_OVERRIDE_PUBKEY33,33) != 0 )
|
|
||||||
return(-1);
|
|
||||||
if ( (checktoshis = komodo_commission(block)) != 0 )
|
|
||||||
{
|
|
||||||
if ( block.vtx[0].vout[1].nValue != checktoshis )
|
|
||||||
{
|
|
||||||
fprintf(stderr,"checktoshis %.8f vs actual vout[1] %.8f\n",dstr(checktoshis),dstr(block.vtx[0].vout[1].nValue));
|
|
||||||
return(-1);
|
|
||||||
} else return(0);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if ( overflow != 0 || total > 0 )
|
if ( overflow != 0 || total > 0 )
|
||||||
return(-1);
|
return(-1);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -493,7 +493,7 @@ int32_t komodo_notarizeddata(int32_t nHeight,uint256 *notarized_hashp,uint256 *n
|
|||||||
return(0);
|
return(0);
|
||||||
}
|
}
|
||||||
|
|
||||||
void komodo_notarized_update(struct komodo_state *sp,int32_t nHeight,int32_t notarized_height,uint256 notarized_hash,uint256 notarized_desttxid)//,uint256 MoM,int32_t MoMdepth)
|
void komodo_notarized_update(struct komodo_state *sp,int32_t nHeight,int32_t notarized_height,uint256 notarized_hash,uint256 notarized_desttxid,uint256 MoM,int32_t MoMdepth)
|
||||||
{
|
{
|
||||||
struct notarized_checkpoint *np;
|
struct notarized_checkpoint *np;
|
||||||
if ( notarized_height >= nHeight )
|
if ( notarized_height >= nHeight )
|
||||||
@@ -511,8 +511,8 @@ void komodo_notarized_update(struct komodo_state *sp,int32_t nHeight,int32_t not
|
|||||||
sp->NOTARIZED_HEIGHT = np->notarized_height = notarized_height;
|
sp->NOTARIZED_HEIGHT = np->notarized_height = notarized_height;
|
||||||
sp->NOTARIZED_HASH = np->notarized_hash = notarized_hash;
|
sp->NOTARIZED_HASH = np->notarized_hash = notarized_hash;
|
||||||
sp->NOTARIZED_DESTTXID = np->notarized_desttxid = notarized_desttxid;
|
sp->NOTARIZED_DESTTXID = np->notarized_desttxid = notarized_desttxid;
|
||||||
//sp->MoM = np->MoM = MoM;
|
sp->MoM = np->MoM = MoM;
|
||||||
//sp->MoMdepth = np->MoMdepth = MoMdepth;
|
sp->MoMdepth = np->MoMdepth = MoMdepth;
|
||||||
portable_mutex_unlock(&komodo_mutex);
|
portable_mutex_unlock(&komodo_mutex);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
101
src/main.cpp
101
src/main.cpp
@@ -1677,7 +1677,7 @@ bool ReadBlockFromDisk(int32_t height,CBlock& block, const CDiskBlockPos& pos,bo
|
|||||||
return error("%s: Deserialize or I/O error - %s at %s", __func__, e.what(), pos.ToString());
|
return error("%s: Deserialize or I/O error - %s at %s", __func__, e.what(), pos.ToString());
|
||||||
}
|
}
|
||||||
// Check the header
|
// Check the header
|
||||||
if ( checkPOW != 0 )
|
if ( 0 && checkPOW != 0 )
|
||||||
{
|
{
|
||||||
komodo_block2pubkey33(pubkey33,(CBlock *)&block);
|
komodo_block2pubkey33(pubkey33,(CBlock *)&block);
|
||||||
if (!(CheckEquihashSolution(&block, Params()) && CheckProofOfWork(height,pubkey33,block.GetHash(), block.nBits, Params().GetConsensus(),block.nTime)))
|
if (!(CheckEquihashSolution(&block, Params()) && CheckProofOfWork(height,pubkey33,block.GetHash(), block.nBits, Params().GetConsensus(),block.nTime)))
|
||||||
@@ -2585,8 +2585,11 @@ bool ConnectBlock(const CBlock& block, CValidationState& state, CBlockIndex* pin
|
|||||||
auto disabledVerifier = libzcash::ProofVerifier::Disabled();
|
auto disabledVerifier = libzcash::ProofVerifier::Disabled();
|
||||||
|
|
||||||
// Check it again to verify JoinSplit proofs, and in case a previous version let a bad block in
|
// Check it again to verify JoinSplit proofs, and in case a previous version let a bad block in
|
||||||
if (!CheckBlock(pindex->nHeight,pindex,block, state, fExpensiveChecks ? verifier : disabledVerifier, fCheckPOW, !fJustCheck)) //!fJustCheck, !fJustCheck))
|
if (!CheckBlock(pindex->nHeight,pindex,block, state, fExpensiveChecks ? verifier : disabledVerifier, fCheckPOW, !fJustCheck))
|
||||||
|
{
|
||||||
|
fprintf(stderr,"checkblock failure in connectblock\n");
|
||||||
return false;
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
// verify that the view's current state corresponds to the previous block
|
// verify that the view's current state corresponds to the previous block
|
||||||
uint256 hashPrevBlock = pindex->pprev == NULL ? uint256() : pindex->pprev->GetBlockHash();
|
uint256 hashPrevBlock = pindex->pprev == NULL ? uint256() : pindex->pprev->GetBlockHash();
|
||||||
@@ -2798,14 +2801,14 @@ bool ConnectBlock(const CBlock& block, CValidationState& state, CBlockIndex* pin
|
|||||||
LogPrint("bench", " - Connect %u transactions: %.2fms (%.3fms/tx, %.3fms/txin) [%.2fs]\n", (unsigned)block.vtx.size(), 0.001 * (nTime1 - nTimeStart), 0.001 * (nTime1 - nTimeStart) / block.vtx.size(), nInputs <= 1 ? 0 : 0.001 * (nTime1 - nTimeStart) / (nInputs-1), nTimeConnect * 0.000001);
|
LogPrint("bench", " - Connect %u transactions: %.2fms (%.3fms/tx, %.3fms/txin) [%.2fs]\n", (unsigned)block.vtx.size(), 0.001 * (nTime1 - nTimeStart), 0.001 * (nTime1 - nTimeStart) / block.vtx.size(), nInputs <= 1 ? 0 : 0.001 * (nTime1 - nTimeStart) / (nInputs-1), nTimeConnect * 0.000001);
|
||||||
|
|
||||||
CAmount blockReward = nFees + GetBlockSubsidy(pindex->nHeight, chainparams.GetConsensus()) + sum;
|
CAmount blockReward = nFees + GetBlockSubsidy(pindex->nHeight, chainparams.GetConsensus()) + sum;
|
||||||
if ( ASSETCHAINS_OVERRIDE_PUBKEY33[0] != 0 && ASSETCHAINS_COMMISSION != 0 && block.vtx[0].vout.size() > 1 )
|
if ( ASSETCHAINS_OVERRIDE_PUBKEY33[0] != 0 && ASSETCHAINS_COMMISSION != 0 )
|
||||||
{
|
{
|
||||||
uint64_t checktoshis;
|
uint64_t checktoshis;
|
||||||
if ( (checktoshis = komodo_commission(block)) != 0 )
|
if ( (checktoshis= komodo_commission((CBlock *)&block)) != 0 )
|
||||||
{
|
{
|
||||||
if ( block.vtx[0].vout.size() == 2 && block.vtx[0].vout[1].nValue == checktoshis )
|
if ( block.vtx[0].vout.size() == 2 && block.vtx[0].vout[1].nValue == checktoshis )
|
||||||
blockReward += checktoshis;
|
blockReward += checktoshis;
|
||||||
else fprintf(stderr,"checktoshis %.8f vs actual vout[1] %.8f\n",dstr(checktoshis),dstr(block.vtx[0].vout[1].nValue));
|
else fprintf(stderr,"checktoshis %.8f numvouts %d\n",dstr(checktoshis),(int32_t)block.vtx[0].vout.size());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if ( block.vtx[0].GetValueOut() > blockReward+1 )
|
if ( block.vtx[0].GetValueOut() > blockReward+1 )
|
||||||
@@ -3762,60 +3765,38 @@ bool CheckBlockHeader(int32_t height,CBlockIndex *pindex, const CBlockHeader& bl
|
|||||||
}
|
}
|
||||||
|
|
||||||
int32_t komodo_check_deposit(int32_t height,const CBlock& block,uint32_t prevtime);
|
int32_t komodo_check_deposit(int32_t height,const CBlock& block,uint32_t prevtime);
|
||||||
|
int32_t komodo_checkPOW(int32_t slowflag,CBlock *pblock,int32_t height);
|
||||||
int32_t komodo_fast_checkPOW(CBlock *pblock,int32_t height)
|
|
||||||
{
|
|
||||||
arith_uint256 bnTarget; bool fNegative,fOverflow; uint8_t pubkey33[33],pubkeys[64][33]; int32_t i,n,failed = 0,notaryid = -1;
|
|
||||||
if ( height == 0 )
|
|
||||||
return(0);
|
|
||||||
if ( !CheckEquihashSolution(pblock, Params()) )
|
|
||||||
{
|
|
||||||
fprintf(stderr,"komodo_fast_checkPOW ht.%d CheckEquihashSolution failed\n",height);
|
|
||||||
return(-1);
|
|
||||||
}
|
|
||||||
bnTarget.SetCompact(pblock->nBits,&fNegative,&fOverflow);
|
|
||||||
if ( UintToArith256(pblock->GetHash()) > bnTarget )
|
|
||||||
{
|
|
||||||
failed = 1;
|
|
||||||
if ( ASSETCHAINS_SYMBOL[0] == 0 )
|
|
||||||
{
|
|
||||||
komodo_block2pubkey33(pubkey33,pblock);
|
|
||||||
if ( (n= komodo_notaries(pubkeys,height,pblock->nTime)) > 0 )
|
|
||||||
{
|
|
||||||
for (i=0; i<n; i++)
|
|
||||||
if ( memcmp(pubkey33,pubkeys[i],33) == 0 )
|
|
||||||
{
|
|
||||||
notaryid = i;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
fprintf(stderr,"komodo_fast_checkPOW ht.%d notaryid.%d failed.%d\n",height,notaryid,failed);
|
|
||||||
if ( failed != 0 && notaryid < 0 )
|
|
||||||
return(-1);
|
|
||||||
else return(0);
|
|
||||||
}
|
|
||||||
|
|
||||||
bool CheckBlock(int32_t height,CBlockIndex *pindex,const CBlock& block, CValidationState& state,
|
bool CheckBlock(int32_t height,CBlockIndex *pindex,const CBlock& block, CValidationState& state,
|
||||||
libzcash::ProofVerifier& verifier,
|
libzcash::ProofVerifier& verifier,
|
||||||
bool fCheckPOW, bool fCheckMerkleRoot)
|
bool fCheckPOW, bool fCheckMerkleRoot)
|
||||||
{
|
{
|
||||||
uint8_t pubkey33[33];
|
uint8_t pubkey33[33]; uint256 hash;
|
||||||
// These are checks that are independent of context.
|
// These are checks that are independent of context.
|
||||||
|
hash = block.GetHash();
|
||||||
|
|
||||||
// Check that the header is valid (particularly PoW). This is mostly
|
// Check that the header is valid (particularly PoW). This is mostly
|
||||||
// redundant with the call in AcceptBlockHeader.
|
// redundant with the call in AcceptBlockHeader.
|
||||||
if (!CheckBlockHeader(height,pindex,block,state,fCheckPOW))
|
if (!CheckBlockHeader(height,pindex,block,state,fCheckPOW))
|
||||||
{
|
{
|
||||||
//fprintf(stderr,"checkblockheader error PoW.%d\n",fCheckPOW);
|
fprintf(stderr,"checkblockheader error PoW.%d\n",fCheckPOW);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
if ( fCheckPOW && !CheckEquihashSolution(&block, Params()) )
|
if ( fCheckPOW )
|
||||||
return state.DoS(100, error("CheckBlock: Equihash solution invalid"),REJECT_INVALID, "invalid-solution");
|
{
|
||||||
komodo_block2pubkey33(pubkey33,(CBlock *)&block);
|
//if ( !CheckEquihashSolution(&block, Params()) )
|
||||||
if ( fCheckPOW && !CheckProofOfWork(height,pubkey33,block.GetHash(), block.nBits, Params().GetConsensus(),block.nTime) )
|
// return state.DoS(100, error("CheckBlock: Equihash solution invalid"),REJECT_INVALID, "invalid-solution");
|
||||||
return state.DoS(1, error("CheckBlock: proof of work failed"),REJECT_INVALID, "high-hash");
|
komodo_block2pubkey33(pubkey33,(CBlock *)&block);
|
||||||
|
if ( !CheckProofOfWork(height,pubkey33,hash,block.nBits,Params().GetConsensus(),block.nTime) )
|
||||||
|
{
|
||||||
|
int32_t z; for (z=31; z>=0; z--)
|
||||||
|
fprintf(stderr,"%02x",((uint8_t *)&hash)[z]);
|
||||||
|
fprintf(stderr," failed hash ht.%d\n",height);
|
||||||
|
return state.DoS(50, error("CheckBlock: proof of work failed"),REJECT_INVALID, "high-hash");
|
||||||
|
}
|
||||||
|
if ( komodo_checkPOW(1,(CBlock *)&block,height) < 0 ) // checks Equihash
|
||||||
|
return state.DoS(100, error("CheckBlock: failed slow_checkPOW"),REJECT_INVALID, "failed-slow_checkPOW");
|
||||||
|
}
|
||||||
// Check the merkle root.
|
// Check the merkle root.
|
||||||
if (fCheckMerkleRoot) {
|
if (fCheckMerkleRoot) {
|
||||||
bool mutated;
|
bool mutated;
|
||||||
@@ -3868,8 +3849,8 @@ bool CheckBlock(int32_t height,CBlockIndex *pindex,const CBlock& block, CValidat
|
|||||||
REJECT_INVALID, "bad-blk-sigops", true);
|
REJECT_INVALID, "bad-blk-sigops", true);
|
||||||
if ( komodo_check_deposit(height,block,(pindex==0||pindex->pprev==0)?0:pindex->pprev->nTime) < 0 )
|
if ( komodo_check_deposit(height,block,(pindex==0||pindex->pprev==0)?0:pindex->pprev->nTime) < 0 )
|
||||||
{
|
{
|
||||||
static uint32_t counter;
|
//static uint32_t counter;
|
||||||
if ( counter++ < 100 && ASSETCHAINS_STAKED == 0 )
|
//if ( counter++ < 100 && ASSETCHAINS_STAKED == 0 )
|
||||||
fprintf(stderr,"check deposit rejection\n");
|
fprintf(stderr,"check deposit rejection\n");
|
||||||
return(false);
|
return(false);
|
||||||
}
|
}
|
||||||
@@ -4035,7 +4016,7 @@ bool AcceptBlock(CBlock& block, CValidationState& state, CBlockIndex** ppindex,
|
|||||||
CBlockIndex *&pindex = *ppindex;
|
CBlockIndex *&pindex = *ppindex;
|
||||||
if (!AcceptBlockHeader(block, state, &pindex))
|
if (!AcceptBlockHeader(block, state, &pindex))
|
||||||
{
|
{
|
||||||
//fprintf(stderr,"AcceptBlockHeader rejected\n");
|
fprintf(stderr,"AcceptBlockHeader rejected\n");
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
if ( pindex == 0 )
|
if ( pindex == 0 )
|
||||||
@@ -4116,7 +4097,7 @@ static bool IsSuperMajority(int minVersion, const CBlockIndex* pstart, unsigned
|
|||||||
|
|
||||||
void komodo_currentheight_set(int32_t height);
|
void komodo_currentheight_set(int32_t height);
|
||||||
|
|
||||||
bool ProcessNewBlock(int32_t height,CValidationState &state, CNode* pfrom, CBlock* pblock, bool fForceProcessing, CDiskBlockPos *dbp)
|
bool ProcessNewBlock(bool from_miner,int32_t height,CValidationState &state, CNode* pfrom, CBlock* pblock, bool fForceProcessing, CDiskBlockPos *dbp)
|
||||||
{
|
{
|
||||||
// Preliminary checks
|
// Preliminary checks
|
||||||
bool checked;
|
bool checked;
|
||||||
@@ -4128,8 +4109,11 @@ bool ProcessNewBlock(int32_t height,CValidationState &state, CNode* pfrom, CBloc
|
|||||||
LOCK(cs_main);
|
LOCK(cs_main);
|
||||||
bool fRequested = MarkBlockAsReceived(pblock->GetHash());
|
bool fRequested = MarkBlockAsReceived(pblock->GetHash());
|
||||||
fRequested |= fForceProcessing;
|
fRequested |= fForceProcessing;
|
||||||
if ( checked != 0 && komodo_fast_checkPOW(pblock,height) < 0 )
|
if ( checked != 0 && komodo_checkPOW(from_miner && ASSETCHAINS_STAKED == 0,pblock,height) < 0 )
|
||||||
|
{
|
||||||
checked = 0;
|
checked = 0;
|
||||||
|
fprintf(stderr,"passed checkblock but failed checkPOW.%d\n",from_miner && ASSETCHAINS_STAKED == 0);
|
||||||
|
}
|
||||||
if (!checked)
|
if (!checked)
|
||||||
{
|
{
|
||||||
if ( pfrom != 0 )
|
if ( pfrom != 0 )
|
||||||
@@ -4167,26 +4151,25 @@ bool TestBlockValidity(CValidationState &state, const CBlock& block, CBlockIndex
|
|||||||
indexDummy.nHeight = pindexPrev->nHeight + 1;
|
indexDummy.nHeight = pindexPrev->nHeight + 1;
|
||||||
// JoinSplit proofs are verified in ConnectBlock
|
// JoinSplit proofs are verified in ConnectBlock
|
||||||
auto verifier = libzcash::ProofVerifier::Disabled();
|
auto verifier = libzcash::ProofVerifier::Disabled();
|
||||||
|
|
||||||
// NOTE: CheckBlockHeader is called by CheckBlock
|
// NOTE: CheckBlockHeader is called by CheckBlock
|
||||||
if (!ContextualCheckBlockHeader(block, state, pindexPrev))
|
if (!ContextualCheckBlockHeader(block, state, pindexPrev))
|
||||||
{
|
{
|
||||||
fprintf(stderr,"TestBlockValidity failure A\n");
|
fprintf(stderr,"TestBlockValidity failure A checkPOW.%d\n",fCheckPOW);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
if (!CheckBlock(indexDummy.nHeight,0,block, state, verifier, fCheckPOW, fCheckMerkleRoot))
|
if (!CheckBlock(indexDummy.nHeight,0,block, state, verifier, fCheckPOW, fCheckMerkleRoot))
|
||||||
{
|
{
|
||||||
//fprintf(stderr,"TestBlockValidity failure B\n");
|
fprintf(stderr,"TestBlockValidity failure B checkPOW.%d\n",fCheckPOW);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
if (!ContextualCheckBlock(block, state, pindexPrev))
|
if (!ContextualCheckBlock(block, state, pindexPrev))
|
||||||
{
|
{
|
||||||
//fprintf(stderr,"TestBlockValidity failure C\n");
|
fprintf(stderr,"TestBlockValidity failure C checkPOW.%d\n",fCheckPOW);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
if (!ConnectBlock(block, state, &indexDummy, viewNew, true,fCheckPOW))
|
if (!ConnectBlock(block, state, &indexDummy, viewNew, true,fCheckPOW))
|
||||||
{
|
{
|
||||||
//fprintf(stderr,"TestBlockValidity failure D\n");
|
fprintf(stderr,"TestBlockValidity failure D checkPOW.%d\n",fCheckPOW);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
assert(state.IsValid());
|
assert(state.IsValid());
|
||||||
@@ -4930,7 +4913,7 @@ bool LoadExternalBlockFile(FILE* fileIn, CDiskBlockPos *dbp)
|
|||||||
// process in case the block isn't known yet
|
// process in case the block isn't known yet
|
||||||
if (mapBlockIndex.count(hash) == 0 || (mapBlockIndex[hash]->nStatus & BLOCK_HAVE_DATA) == 0) {
|
if (mapBlockIndex.count(hash) == 0 || (mapBlockIndex[hash]->nStatus & BLOCK_HAVE_DATA) == 0) {
|
||||||
CValidationState state;
|
CValidationState state;
|
||||||
if (ProcessNewBlock(0,state, NULL, &block, true, dbp))
|
if (ProcessNewBlock(0,0,state, NULL, &block, true, dbp))
|
||||||
nLoaded++;
|
nLoaded++;
|
||||||
if (state.IsError())
|
if (state.IsError())
|
||||||
break;
|
break;
|
||||||
@@ -4952,7 +4935,7 @@ bool LoadExternalBlockFile(FILE* fileIn, CDiskBlockPos *dbp)
|
|||||||
LogPrintf("%s: Processing out of order child %s of %s\n", __func__, block.GetHash().ToString(),
|
LogPrintf("%s: Processing out of order child %s of %s\n", __func__, block.GetHash().ToString(),
|
||||||
head.ToString());
|
head.ToString());
|
||||||
CValidationState dummy;
|
CValidationState dummy;
|
||||||
if (ProcessNewBlock(0,dummy, NULL, &block, true, &it->second))
|
if (ProcessNewBlock(0,0,dummy, NULL, &block, true, &it->second))
|
||||||
{
|
{
|
||||||
nLoaded++;
|
nLoaded++;
|
||||||
queue.push_back(block.GetHash());
|
queue.push_back(block.GetHash());
|
||||||
@@ -6037,7 +6020,7 @@ bool static ProcessMessage(CNode* pfrom, string strCommand, CDataStream& vRecv,
|
|||||||
// Such an unrequested block may still be processed, subject to the
|
// Such an unrequested block may still be processed, subject to the
|
||||||
// conditions in AcceptBlock().
|
// conditions in AcceptBlock().
|
||||||
bool forceProcessing = pfrom->fWhitelisted && !IsInitialBlockDownload();
|
bool forceProcessing = pfrom->fWhitelisted && !IsInitialBlockDownload();
|
||||||
ProcessNewBlock(0,state, pfrom, &block, forceProcessing, NULL);
|
ProcessNewBlock(0,0,state, pfrom, &block, forceProcessing, NULL);
|
||||||
int nDoS;
|
int nDoS;
|
||||||
if (state.IsInvalid(nDoS)) {
|
if (state.IsInvalid(nDoS)) {
|
||||||
pfrom->PushMessage("reject", strCommand, state.GetRejectCode(),
|
pfrom->PushMessage("reject", strCommand, state.GetRejectCode(),
|
||||||
|
|||||||
@@ -190,7 +190,7 @@ void UnregisterNodeSignals(CNodeSignals& nodeSignals);
|
|||||||
* @param[out] dbp If pblock is stored to disk (or already there), this will be set to its location.
|
* @param[out] dbp If pblock is stored to disk (or already there), this will be set to its location.
|
||||||
* @return True if state.IsValid()
|
* @return True if state.IsValid()
|
||||||
*/
|
*/
|
||||||
bool ProcessNewBlock(int32_t height,CValidationState &state, CNode* pfrom, CBlock* pblock, bool fForceProcessing, CDiskBlockPos *dbp);
|
bool ProcessNewBlock(bool from_miner,int32_t height,CValidationState &state, CNode* pfrom, CBlock* pblock, bool fForceProcessing, CDiskBlockPos *dbp);
|
||||||
/** Check whether enough disk space is available for an incoming block */
|
/** Check whether enough disk space is available for an incoming block */
|
||||||
bool CheckDiskSpace(uint64_t nAdditionalBytes = 0);
|
bool CheckDiskSpace(uint64_t nAdditionalBytes = 0);
|
||||||
/** Open a block file (blk?????.dat) */
|
/** Open a block file (blk?????.dat) */
|
||||||
|
|||||||
118
src/miner.cpp
118
src/miner.cpp
@@ -119,7 +119,7 @@ int32_t komodo_is_issuer();
|
|||||||
int32_t komodo_gateway_deposits(CMutableTransaction *txNew,char *symbol,int32_t tokomodo);
|
int32_t komodo_gateway_deposits(CMutableTransaction *txNew,char *symbol,int32_t tokomodo);
|
||||||
int32_t komodo_isrealtime(int32_t *kmdheightp);
|
int32_t komodo_isrealtime(int32_t *kmdheightp);
|
||||||
int32_t komodo_validate_interest(const CTransaction &tx,int32_t txheight,uint32_t nTime,int32_t dispflag);
|
int32_t komodo_validate_interest(const CTransaction &tx,int32_t txheight,uint32_t nTime,int32_t dispflag);
|
||||||
uint64_t komodo_commission(const CBlock &block);
|
uint64_t komodo_commission(const CBlock *block);
|
||||||
int32_t komodo_staked(CMutableTransaction &txNew,uint32_t nBits,uint32_t *blocktimep,uint32_t *txtimep,uint256 *utxotxidp,int32_t *utxovoutp,uint64_t *utxovaluep,uint8_t *utxosig);
|
int32_t komodo_staked(CMutableTransaction &txNew,uint32_t nBits,uint32_t *blocktimep,uint32_t *txtimep,uint256 *utxotxidp,int32_t *utxovoutp,uint64_t *utxovaluep,uint8_t *utxosig);
|
||||||
|
|
||||||
CBlockTemplate* CreateNewBlock(const CScript& scriptPubKeyIn)
|
CBlockTemplate* CreateNewBlock(const CScript& scriptPubKeyIn)
|
||||||
@@ -384,7 +384,7 @@ CBlockTemplate* CreateNewBlock(const CScript& scriptPubKeyIn)
|
|||||||
|
|
||||||
nLastBlockTx = nBlockTx;
|
nLastBlockTx = nBlockTx;
|
||||||
nLastBlockSize = nBlockSize;
|
nLastBlockSize = nBlockSize;
|
||||||
blocktime = std::max(pindexPrev->GetMedianTimePast()+1, GetAdjustedTime());
|
blocktime = 1 + std::max(pindexPrev->GetMedianTimePast()+1, GetAdjustedTime());
|
||||||
//pblock->nTime = blocktime + 1;
|
//pblock->nTime = blocktime + 1;
|
||||||
pblock->nBits = GetNextWorkRequired(pindexPrev, pblock, Params().GetConsensus());
|
pblock->nBits = GetNextWorkRequired(pindexPrev, pblock, Params().GetConsensus());
|
||||||
//LogPrintf("CreateNewBlock(): total size %u blocktime.%u nBits.%08x\n", nBlockSize,blocktime,pblock->nBits);
|
//LogPrintf("CreateNewBlock(): total size %u blocktime.%u nBits.%08x\n", nBlockSize,blocktime,pblock->nBits);
|
||||||
@@ -429,32 +429,8 @@ CBlockTemplate* CreateNewBlock(const CScript& scriptPubKeyIn)
|
|||||||
txNew.vout[0].nValue += nFees;
|
txNew.vout[0].nValue += nFees;
|
||||||
txNew.vin[0].scriptSig = CScript() << nHeight << OP_0;
|
txNew.vin[0].scriptSig = CScript() << nHeight << OP_0;
|
||||||
|
|
||||||
/*if ( ASSETCHAINS_SYMBOL[0] == 0 )
|
|
||||||
{
|
|
||||||
int32_t i,opretlen; uint8_t opret[256],*ptr;
|
|
||||||
if ( (nHeight % 60) == 0 || komodo_gateway_deposits(&txNew,(char *)"KMD",1) == 0 )
|
|
||||||
{
|
|
||||||
if ( (opretlen= komodo_pax_opreturn((int32_t)nHeight,opret,sizeof(opret))) > 0 ) // have pricefeed
|
|
||||||
{
|
|
||||||
txNew.vout.resize(2);
|
|
||||||
txNew.vout[1].scriptPubKey.resize(opretlen);
|
|
||||||
ptr = (uint8_t *)txNew.vout[1].scriptPubKey.data();
|
|
||||||
for (i=0; i<opretlen; i++)
|
|
||||||
ptr[i] = opret[i];
|
|
||||||
txNew.vout[1].nValue = 0;
|
|
||||||
//fprintf(stderr,"opretlen.%d\n",opretlen);
|
|
||||||
} //else printf("null opretlen for prices\n");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else if ( komodo_is_issuer() != 0 )
|
|
||||||
{
|
|
||||||
komodo_gateway_deposits(&txNew,ASSETCHAINS_SYMBOL,0);
|
|
||||||
if ( txNew.vout.size() > 1 )
|
|
||||||
fprintf(stderr,"%s txNew numvouts.%d\n",ASSETCHAINS_SYMBOL,(int32_t)txNew.vout.size());
|
|
||||||
}*/
|
|
||||||
|
|
||||||
pblock->vtx[0] = txNew;
|
pblock->vtx[0] = txNew;
|
||||||
if ( ASSETCHAINS_SYMBOL[0] != 0 && ASSETCHAINS_OVERRIDE_PUBKEY33[0] != 0 && ASSETCHAINS_COMMISSION != 0 && (commission= komodo_commission(pblocktemplate->block)) != 0 )
|
if ( ASSETCHAINS_SYMBOL[0] != 0 && ASSETCHAINS_OVERRIDE_PUBKEY33[0] != 0 && ASSETCHAINS_COMMISSION != 0 && (commission= komodo_commission((CBlock*)&pblocktemplate->block)) != 0 )
|
||||||
{
|
{
|
||||||
int32_t i; uint8_t *ptr;
|
int32_t i; uint8_t *ptr;
|
||||||
txNew.vout.resize(2);
|
txNew.vout.resize(2);
|
||||||
@@ -655,11 +631,24 @@ static bool ProcessBlockFound(CBlock* pblock)
|
|||||||
|
|
||||||
// Process this block the same as if we had received it from another node
|
// Process this block the same as if we had received it from another node
|
||||||
CValidationState state;
|
CValidationState state;
|
||||||
if (!ProcessNewBlock(chainActive.Tip()->nHeight+1,state, NULL, pblock, true, NULL))
|
if (!ProcessNewBlock(1,chainActive.Tip()->nHeight+1,state, NULL, pblock, true, NULL))
|
||||||
return error("KomodoMiner: ProcessNewBlock, block not accepted");
|
return error("KomodoMiner: ProcessNewBlock, block not accepted");
|
||||||
|
|
||||||
TrackMinedBlock(pblock->GetHash());
|
TrackMinedBlock(pblock->GetHash());
|
||||||
|
if ( ASSETCHAINS_STAKED != 0 )
|
||||||
|
{
|
||||||
|
fprintf(stderr,"broadcast new block t.%u\n",(uint32_t)time(NULL));
|
||||||
|
{
|
||||||
|
LOCK(cs_vNodes);
|
||||||
|
BOOST_FOREACH(CNode* pnode, vNodes)
|
||||||
|
{
|
||||||
|
if ( pnode->hSocket == INVALID_SOCKET )
|
||||||
|
continue;
|
||||||
|
pnode->PushMessage("block", *pblock);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
fprintf(stderr,"finished broadcast new block t.%u\n",(uint32_t)time(NULL));
|
||||||
|
}
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -669,7 +658,7 @@ arith_uint256 komodo_PoWtarget(int32_t *percPoSp,arith_uint256 target,int32_t he
|
|||||||
int32_t FOUND_BLOCK,KOMODO_MAYBEMINED;
|
int32_t FOUND_BLOCK,KOMODO_MAYBEMINED;
|
||||||
extern int32_t KOMODO_LASTMINED;
|
extern int32_t KOMODO_LASTMINED;
|
||||||
int32_t roundrobin_delay;
|
int32_t roundrobin_delay;
|
||||||
arith_uint256 HASHTarget;
|
arith_uint256 HASHTarget,HASHTarget_POW;
|
||||||
|
|
||||||
#ifdef ENABLE_WALLET
|
#ifdef ENABLE_WALLET
|
||||||
void static BitcoinMiner(CWallet *pwallet)
|
void static BitcoinMiner(CWallet *pwallet)
|
||||||
@@ -870,15 +859,15 @@ void static BitcoinMiner()
|
|||||||
if ( ASSETCHAINS_STAKED != 0 && NOTARY_PUBKEY33[0] == 0 )
|
if ( ASSETCHAINS_STAKED != 0 && NOTARY_PUBKEY33[0] == 0 )
|
||||||
{
|
{
|
||||||
int32_t percPoS,z;
|
int32_t percPoS,z;
|
||||||
if ( Mining_height <= 100 )
|
/*if ( Mining_height <= 100 )
|
||||||
{
|
{
|
||||||
sleep(60);
|
sleep(60);
|
||||||
continue;
|
continue;
|
||||||
}
|
}*/
|
||||||
HASHTarget = komodo_PoWtarget(&percPoS,HASHTarget,Mining_height,ASSETCHAINS_STAKED);
|
HASHTarget_POW = komodo_PoWtarget(&percPoS,HASHTarget,Mining_height,ASSETCHAINS_STAKED);
|
||||||
for (z=31; z>=0; z--)
|
for (z=31; z>=0; z--)
|
||||||
fprintf(stderr,"%02x",((uint8_t *)&HASHTarget)[z]);
|
fprintf(stderr,"%02x",((uint8_t *)&HASHTarget_POW)[z]);
|
||||||
fprintf(stderr," PoW for staked coin\n");
|
fprintf(stderr," PoW for staked coin PoS %d%% vs target %d%%\n",percPoS,(int32_t)ASSETCHAINS_STAKED);
|
||||||
}
|
}
|
||||||
while (true)
|
while (true)
|
||||||
{
|
{
|
||||||
@@ -904,8 +893,10 @@ void static BitcoinMiner()
|
|||||||
crypto_generichash_blake2b_update(&curr_state,pblock->nNonce.begin(),pblock->nNonce.size());
|
crypto_generichash_blake2b_update(&curr_state,pblock->nNonce.begin(),pblock->nNonce.size());
|
||||||
// (x_1, x_2, ...) = A(I, V, n, k)
|
// (x_1, x_2, ...) = A(I, V, n, k)
|
||||||
LogPrint("pow", "Running Equihash solver \"%s\" with nNonce = %s\n",solver, pblock->nNonce.ToString());
|
LogPrint("pow", "Running Equihash solver \"%s\" with nNonce = %s\n",solver, pblock->nNonce.ToString());
|
||||||
arith_uint256 hashTarget = HASHTarget;
|
arith_uint256 hashTarget;
|
||||||
//fprintf(stderr,"running solver\n");
|
if ( NOTARY_PUBKEY33[0] == 0 && ASSETCHAINS_STAKED > 0 && ASSETCHAINS_STAKED < 100 )
|
||||||
|
hashTarget = HASHTarget_POW;
|
||||||
|
else hashTarget = HASHTarget;
|
||||||
std::function<bool(std::vector<unsigned char>)> validBlock =
|
std::function<bool(std::vector<unsigned char>)> validBlock =
|
||||||
#ifdef ENABLE_WALLET
|
#ifdef ENABLE_WALLET
|
||||||
[&pblock, &hashTarget, &pwallet, &reservekey, &m_cs, &cancelSolver, &chainparams]
|
[&pblock, &hashTarget, &pwallet, &reservekey, &m_cs, &cancelSolver, &chainparams]
|
||||||
@@ -913,20 +904,31 @@ void static BitcoinMiner()
|
|||||||
[&pblock, &hashTarget, &m_cs, &cancelSolver, &chainparams]
|
[&pblock, &hashTarget, &m_cs, &cancelSolver, &chainparams]
|
||||||
#endif
|
#endif
|
||||||
(std::vector<unsigned char> soln) {
|
(std::vector<unsigned char> soln) {
|
||||||
|
int32_t z; arith_uint256 h; CBlock B;
|
||||||
// Write the solution to the hash and compute the result.
|
// Write the solution to the hash and compute the result.
|
||||||
LogPrint("pow", "- Checking solution against target\n");
|
LogPrint("pow", "- Checking solution against target\n");
|
||||||
pblock->nSolution = soln;
|
pblock->nSolution = soln;
|
||||||
solutionTargetChecks.increment();
|
solutionTargetChecks.increment();
|
||||||
if ( UintToArith256(pblock->GetHash()) > HASHTarget )
|
B = *pblock;
|
||||||
{
|
h = UintToArith256(B.GetHash());
|
||||||
//if ( ASSETCHAINS_SYMBOL[0] != 0 )
|
if ( h > hashTarget )
|
||||||
// fprintf(stderr," missed target\n");
|
|
||||||
return false;
|
return false;
|
||||||
}
|
/*for (z=31; z>=16; z--)
|
||||||
|
fprintf(stderr,"%02x",((uint8_t *)&h)[z]);
|
||||||
|
fprintf(stderr," mined ");
|
||||||
|
for (z=31; z>=16; z--)
|
||||||
|
fprintf(stderr,"%02x",((uint8_t *)&HASHTarget)[z]);
|
||||||
|
fprintf(stderr," hashTarget ");
|
||||||
|
for (z=31; z>=16; z--)
|
||||||
|
fprintf(stderr,"%02x",((uint8_t *)&HASHTarget_POW)[z]);
|
||||||
|
fprintf(stderr," POW\n");*/
|
||||||
CValidationState state;
|
CValidationState state;
|
||||||
if ( !TestBlockValidity(state, *pblock, chainActive.Tip(), true, false))
|
if ( !TestBlockValidity(state,B, chainActive.Tip(), true, false))
|
||||||
{
|
{
|
||||||
fprintf(stderr,"Invalid block mined, try again\n");
|
h = UintToArith256(B.GetHash());
|
||||||
|
for (z=31; z>=0; z--)
|
||||||
|
fprintf(stderr,"%02x",((uint8_t *)&h)[z]);
|
||||||
|
fprintf(stderr," Invalid block mined, try again\n");
|
||||||
return(false);
|
return(false);
|
||||||
}
|
}
|
||||||
if ( ASSETCHAINS_STAKED == 0 )
|
if ( ASSETCHAINS_STAKED == 0 )
|
||||||
@@ -948,13 +950,13 @@ void static BitcoinMiner()
|
|||||||
{
|
{
|
||||||
if ( NOTARY_PUBKEY33[0] != 0 )
|
if ( NOTARY_PUBKEY33[0] != 0 )
|
||||||
{
|
{
|
||||||
printf("need to wait %d seconds to submit\n",(int32_t)(pblock->nTime - GetAdjustedTime()));
|
printf("need to wait %d seconds to submit staked block\n",(int32_t)(B.nTime - GetAdjustedTime()));
|
||||||
while ( GetAdjustedTime() < pblock->nTime )
|
while ( GetAdjustedTime() < B.nTime )
|
||||||
sleep(1);
|
sleep(1);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
uint256 tmp = pblock->GetHash();
|
uint256 tmp = B.GetHash();
|
||||||
int32_t z; for (z=31; z>=0; z--)
|
int32_t z; for (z=31; z>=0; z--)
|
||||||
fprintf(stderr,"%02x",((uint8_t *)&tmp)[z]);
|
fprintf(stderr,"%02x",((uint8_t *)&tmp)[z]);
|
||||||
fprintf(stderr," mined block!\n");
|
fprintf(stderr," mined block!\n");
|
||||||
@@ -964,11 +966,11 @@ void static BitcoinMiner()
|
|||||||
// Found a solution
|
// Found a solution
|
||||||
SetThreadPriority(THREAD_PRIORITY_NORMAL);
|
SetThreadPriority(THREAD_PRIORITY_NORMAL);
|
||||||
LogPrintf("KomodoMiner:\n");
|
LogPrintf("KomodoMiner:\n");
|
||||||
LogPrintf("proof-of-work found \n hash: %s \ntarget: %s\n", pblock->GetHash().GetHex(), HASHTarget.GetHex());
|
LogPrintf("proof-of-work found \n hash: %s \ntarget: %s\n", B.GetHash().GetHex(), HASHTarget.GetHex());
|
||||||
#ifdef ENABLE_WALLET
|
#ifdef ENABLE_WALLET
|
||||||
if (ProcessBlockFound(pblock, *pwallet, reservekey)) {
|
if (ProcessBlockFound(&B, *pwallet, reservekey)) {
|
||||||
#else
|
#else
|
||||||
if (ProcessBlockFound(pblock)) {
|
if (ProcessBlockFound(&B)) {
|
||||||
#endif
|
#endif
|
||||||
// Ignore chain updates caused by us
|
// Ignore chain updates caused by us
|
||||||
std::lock_guard<std::mutex> lock{m_cs};
|
std::lock_guard<std::mutex> lock{m_cs};
|
||||||
@@ -1083,13 +1085,17 @@ void static BitcoinMiner()
|
|||||||
// Update nNonce and nTime
|
// Update nNonce and nTime
|
||||||
pblock->nNonce = ArithToUint256(UintToArith256(pblock->nNonce) + 1);
|
pblock->nNonce = ArithToUint256(UintToArith256(pblock->nNonce) + 1);
|
||||||
pblock->nBits = savebits;
|
pblock->nBits = savebits;
|
||||||
if ( ASSETCHAINS_STAKED == 0 || NOTARY_PUBKEY33[0] == 0 )
|
/*if ( NOTARY_PUBKEY33[0] == 0 )
|
||||||
UpdateTime(pblock, chainparams.GetConsensus(), pindexPrev);
|
|
||||||
if (chainparams.GetConsensus().fPowAllowMinDifficultyBlocks)
|
|
||||||
{
|
{
|
||||||
// Changing pblock->nTime can change work required on testnet:
|
int32_t percPoS;
|
||||||
HASHTarget.SetCompact(pblock->nBits);
|
UpdateTime(pblock, chainparams.GetConsensus(), pindexPrev);
|
||||||
}
|
if (chainparams.GetConsensus().fPowAllowMinDifficultyBlocks)
|
||||||
|
{
|
||||||
|
// Changing pblock->nTime can change work required on testnet:
|
||||||
|
HASHTarget.SetCompact(pblock->nBits);
|
||||||
|
HASHTarget_POW = komodo_PoWtarget(&percPoS,HASHTarget,Mining_height,ASSETCHAINS_STAKED);
|
||||||
|
}
|
||||||
|
}*/
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
24
src/pow.cpp
24
src/pow.cpp
@@ -136,6 +136,9 @@ bool CheckProofOfWork(int32_t height,uint8_t *pubkey33,uint256 hash,unsigned int
|
|||||||
extern int32_t KOMODO_REWIND;
|
extern int32_t KOMODO_REWIND;
|
||||||
bool fNegative,fOverflow; uint8_t origpubkey33[33]; int32_t i,nonzpkeys=0,nonz=0,special=0,special2=0,notaryid=-1,flag = 0, mids[66]; uint32_t tiptime,blocktimes[66];
|
bool fNegative,fOverflow; uint8_t origpubkey33[33]; int32_t i,nonzpkeys=0,nonz=0,special=0,special2=0,notaryid=-1,flag = 0, mids[66]; uint32_t tiptime,blocktimes[66];
|
||||||
arith_uint256 bnTarget; uint8_t pubkeys[66][33];
|
arith_uint256 bnTarget; uint8_t pubkeys[66][33];
|
||||||
|
//for (i=31; i>=0; i--)
|
||||||
|
// fprintf(stderr,"%02x",((uint8_t *)&hash)[i]);
|
||||||
|
//fprintf(stderr," checkpow\n");
|
||||||
memcpy(origpubkey33,pubkey33,33);
|
memcpy(origpubkey33,pubkey33,33);
|
||||||
memset(blocktimes,0,sizeof(blocktimes));
|
memset(blocktimes,0,sizeof(blocktimes));
|
||||||
tiptime = komodo_chainactive_timestamp();
|
tiptime = komodo_chainactive_timestamp();
|
||||||
@@ -192,23 +195,20 @@ bool CheckProofOfWork(int32_t height,uint8_t *pubkey33,uint256 hash,unsigned int
|
|||||||
return true;
|
return true;
|
||||||
if ( ASSETCHAINS_SYMBOL[0] != 0 || height > 792000 )
|
if ( ASSETCHAINS_SYMBOL[0] != 0 || height > 792000 )
|
||||||
{
|
{
|
||||||
if ( 0 && height > 792000 )
|
//if ( 0 && height > 792000 )
|
||||||
{
|
{
|
||||||
for (i=31; i>=0; i--)
|
for (i=31; i>=0; i--)
|
||||||
printf("%02x",((uint8_t *)&hash)[i]);
|
fprintf(stderr,"%02x",((uint8_t *)&hash)[i]);
|
||||||
printf(" hash vs ");
|
fprintf(stderr," hash vs ");
|
||||||
for (i=31; i>=0; i--)
|
for (i=31; i>=0; i--)
|
||||||
printf("%02x",((uint8_t *)&bnTarget)[i]);
|
fprintf(stderr,"%02x",((uint8_t *)&bnTarget)[i]);
|
||||||
printf(" ht.%d special.%d notaryid.%d ht.%d mod.%d error\n",height,special,notaryid,height,(height % 35));
|
fprintf(stderr," ht.%d special.%d notaryid.%d mod.%d error\n",height,special,notaryid,(height % 35));
|
||||||
for (i=0; i<33; i++)
|
for (i=0; i<33; i++)
|
||||||
printf("%02x",pubkey33[i]);
|
fprintf(stderr,"%02x",pubkey33[i]);
|
||||||
printf(" <- pubkey\n");
|
fprintf(stderr," <- pubkey\n");
|
||||||
for (i=0; i<33; i++)
|
for (i=0; i<33; i++)
|
||||||
printf("%02x",origpubkey33[i]);
|
fprintf(stderr,"%02x",origpubkey33[i]);
|
||||||
printf(" <- origpubkey\n");
|
fprintf(stderr," <- origpubkey\n");
|
||||||
for (i=0; i<66; i++)
|
|
||||||
printf("%d ",mids[i]);
|
|
||||||
printf(" minerids from ht.%d\n",height);
|
|
||||||
}
|
}
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -267,7 +267,7 @@ UniValue generate(const UniValue& params, bool fHelp)
|
|||||||
}
|
}
|
||||||
endloop:
|
endloop:
|
||||||
CValidationState state;
|
CValidationState state;
|
||||||
if (!ProcessNewBlock(chainActive.Tip()->nHeight+1,state, NULL, pblock, true, NULL))
|
if (!ProcessNewBlock(1,chainActive.Tip()->nHeight+1,state, NULL, pblock, true, NULL))
|
||||||
throw JSONRPCError(RPC_INTERNAL_ERROR, "ProcessNewBlock, block not accepted");
|
throw JSONRPCError(RPC_INTERNAL_ERROR, "ProcessNewBlock, block not accepted");
|
||||||
++nHeight;
|
++nHeight;
|
||||||
blockHashes.push_back(pblock->GetHash().GetHex());
|
blockHashes.push_back(pblock->GetHash().GetHex());
|
||||||
@@ -807,7 +807,7 @@ UniValue submitblock(const UniValue& params, bool fHelp)
|
|||||||
CValidationState state;
|
CValidationState state;
|
||||||
submitblock_StateCatcher sc(block.GetHash());
|
submitblock_StateCatcher sc(block.GetHash());
|
||||||
RegisterValidationInterface(&sc);
|
RegisterValidationInterface(&sc);
|
||||||
bool fAccepted = ProcessNewBlock(chainActive.Tip()->nHeight+1,state, NULL, &block, true, NULL);
|
bool fAccepted = ProcessNewBlock(1,chainActive.Tip()->nHeight+1,state, NULL, &block, true, NULL);
|
||||||
UnregisterValidationInterface(&sc);
|
UnregisterValidationInterface(&sc);
|
||||||
if (fBlockPresent)
|
if (fBlockPresent)
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -242,7 +242,7 @@ BOOST_AUTO_TEST_CASE(CreateNewBlock_validity)
|
|||||||
|
|
||||||
CValidationState state;
|
CValidationState state;
|
||||||
|
|
||||||
if (ProcessNewBlock(state, NULL, pblock, true, NULL) && state.IsValid()) {
|
if (ProcessNewBlock(1,state, NULL, pblock, true, NULL) && state.IsValid()) {
|
||||||
goto foundit;
|
goto foundit;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -261,7 +261,7 @@ BOOST_AUTO_TEST_CASE(CreateNewBlock_validity)
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
CValidationState state;
|
CValidationState state;
|
||||||
BOOST_CHECK(ProcessNewBlock(state, NULL, pblock, true, NULL));
|
BOOST_CHECK(ProcessNewBlock(1,state, NULL, pblock, true, NULL));
|
||||||
BOOST_CHECK_MESSAGE(state.IsValid(), state.GetRejectReason());
|
BOOST_CHECK_MESSAGE(state.IsValid(), state.GetRejectReason());
|
||||||
pblock->hashPrevBlock = pblock->GetHash();
|
pblock->hashPrevBlock = pblock->GetHash();
|
||||||
|
|
||||||
|
|||||||
@@ -4494,7 +4494,9 @@ int32_t komodo_staked(CMutableTransaction &txNew,uint32_t nBits,uint32_t *blockt
|
|||||||
if ( eligible > 0 )
|
if ( eligible > 0 )
|
||||||
{
|
{
|
||||||
if ( eligible != komodo_stake(1,bnTarget,(uint32_t)tipindex->nHeight+1,out.tx->GetHash(),out.i,eligible,(uint32_t)tipindex->nTime,(char *)CBitcoinAddress(address).ToString().c_str()) )
|
if ( eligible != komodo_stake(1,bnTarget,(uint32_t)tipindex->nHeight+1,out.tx->GetHash(),out.i,eligible,(uint32_t)tipindex->nTime,(char *)CBitcoinAddress(address).ToString().c_str()) )
|
||||||
fprintf(stderr,"validation of winning blocktime failed %u -> eligible.%u\n",*blocktimep,eligible);
|
{
|
||||||
|
//fprintf(stderr,"tip.%d validation of winning blocktime failed %u -> eligible.%u\n",(uint32_t)tipindex->nHeight,*blocktimep,eligible);
|
||||||
|
}
|
||||||
else if ( earliest == 0 || eligible < earliest || (eligible == earliest && (*utxovaluep == 0 || nValue < *utxovaluep)) )
|
else if ( earliest == 0 || eligible < earliest || (eligible == earliest && (*utxovaluep == 0 || nValue < *utxovaluep)) )
|
||||||
{
|
{
|
||||||
earliest = eligible;
|
earliest = eligible;
|
||||||
|
|||||||
@@ -414,7 +414,7 @@ void CWallet::ChainTip(const CBlockIndex *pindex, const CBlock *pblock,
|
|||||||
{
|
{
|
||||||
if (added) {
|
if (added) {
|
||||||
IncrementNoteWitnesses(pindex, pblock, tree);
|
IncrementNoteWitnesses(pindex, pblock, tree);
|
||||||
} else if ( ASSETCHAINS_SYMBOL[0] == 0 || nWitnessCacheSize > 1 ){
|
} else if ( nWitnessCacheSize > 1 ){ //ASSETCHAINS_SYMBOL[0] == 0 ||
|
||||||
DecrementNoteWitnesses(pindex);
|
DecrementNoteWitnesses(pindex);
|
||||||
} else fprintf(stderr,"would have decremented %s nWitnessCacheSize.%d\n",ASSETCHAINS_SYMBOL,(int32_t)nWitnessCacheSize);
|
} else fprintf(stderr,"would have decremented %s nWitnessCacheSize.%d\n",ASSETCHAINS_SYMBOL,(int32_t)nWitnessCacheSize);
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user