@@ -659,7 +659,7 @@ int32_t komodo_block2height(CBlock *block)
|
||||
return(height);
|
||||
}
|
||||
|
||||
void komodo_block2pubkey33(uint8_t *pubkey33,CBlock *block)
|
||||
int32_t komodo_block2pubkey33(uint8_t *pubkey33,CBlock *block)
|
||||
{
|
||||
int32_t n;
|
||||
if ( KOMODO_LOADINGBLOCKS == 0 )
|
||||
@@ -675,8 +675,12 @@ void komodo_block2pubkey33(uint8_t *pubkey33,CBlock *block)
|
||||
//komodo_init(0);
|
||||
n = block->vtx[0].vout[0].scriptPubKey.size();
|
||||
if ( n == 35 )
|
||||
{
|
||||
memcpy(pubkey33,ptr+1,33);
|
||||
return(1);
|
||||
}
|
||||
}
|
||||
return(0);
|
||||
}
|
||||
|
||||
int32_t komodo_blockload(CBlock& block,CBlockIndex *pindex)
|
||||
@@ -1031,3 +1035,313 @@ int32_t komodo_validate_interest(const CTransaction &tx,int32_t txheight,uint32_
|
||||
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. The more blocks we can filter out at this stage, the less junk in the local DB that will just get purged later on.
|
||||
|
||||
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");
|
||||
}
|
||||
if ( (i % 10) == 9 )
|
||||
fprintf(stderr," %d, ",percPoS);
|
||||
}
|
||||
}
|
||||
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,possible,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();
|
||||
bnTarget.SetCompact(pblock->nBits,&fNegative,&fOverflow);
|
||||
bhash = UintToArith256(hash);
|
||||
possible = komodo_block2pubkey33(pubkey33,pblock);
|
||||
//fprintf(stderr,"height.%d slowflag.%d possible.%d cmp.%d\n",height,slowflag,possible,bhash > bnTarget);
|
||||
if ( height == 0 )
|
||||
{
|
||||
if ( slowflag != 0 )
|
||||
return(0);
|
||||
if ( (pprev= mapBlockIndex[pblock->hashPrevBlock]) != 0 )
|
||||
height = pprev->nHeight + 1;
|
||||
if ( height == 0 )
|
||||
return(0);
|
||||
}
|
||||
if ( (ASSETCHAINS_SYMBOL[0] != 0 || height > 792000) && bhash > bnTarget )
|
||||
{
|
||||
failed = 1;
|
||||
if ( height > 0 && 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 ( possible == 0 || ASSETCHAINS_SYMBOL[0] != 0 )
|
||||
{
|
||||
fprintf(stderr,"pow violation and no chance it is notary ht.%d %s\n",height,hash.ToString().c_str());
|
||||
return(-1);
|
||||
}
|
||||
}
|
||||
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 possible.%d slowflag.%d ht.%d notaryid.%d failed.%d\n",possible,slowflag,height,notaryid,failed);
|
||||
if ( failed != 0 && possible == 0 && notaryid < 0 )
|
||||
return(-1);
|
||||
else return(0);
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -650,153 +650,6 @@ int32_t komodo_bannedset(int32_t *indallvoutsp,uint256 *array,int32_t max)
|
||||
|
||||
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
|
||||
{
|
||||
static uint256 array[64]; static int32_t numbanned,indallvouts;
|
||||
@@ -854,7 +707,7 @@ int32_t komodo_check_deposit(int32_t height,const CBlock& block,uint32_t prevtim
|
||||
{
|
||||
if ( overflow != 0 || total > COIN/10 )
|
||||
{
|
||||
//fprintf(stderr,">>>>>>>> <<<<<<<<<< ht.%d illegal nonz output %.8f n.%d\n",height,dstr(block.vtx[0].vout[1].nValue),n);
|
||||
fprintf(stderr,">>>>>>>> <<<<<<<<<< ht.%d illegal nonz output %.8f n.%d\n",height,dstr(block.vtx[0].vout[1].nValue),n);
|
||||
if ( height >= activation )
|
||||
return(-1);
|
||||
}
|
||||
@@ -867,65 +720,12 @@ int32_t komodo_check_deposit(int32_t height,const CBlock& block,uint32_t prevtim
|
||||
}
|
||||
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 )
|
||||
return(-1);
|
||||
}
|
||||
return(0);
|
||||
}
|
||||
/*
|
||||
/*
|
||||
//fprintf(stderr,"ht.%d n.%d nValue %.8f (%d %d %d)\n",height,n,dstr(block.vtx[0].vout[1].nValue),KOMODO_PAX,komodo_isrealtime(&ht),KOMODO_PASSPORT_INITDONE);
|
||||
offset += komodo_scriptitemlen(&opretlen,&script[offset]);
|
||||
//printf("offset.%d opretlen.%d [%02x %02x %02x %02x]\n",offset,opretlen,script[0],script[1],script[2],script[3]);
|
||||
@@ -1972,7 +1772,7 @@ void komodo_passport_iteration()
|
||||
if ( expired == 0 && KOMODO_PASSPORT_INITDONE == 0 )
|
||||
{
|
||||
KOMODO_PASSPORT_INITDONE = 1;
|
||||
printf("done PASSPORT %s refid.%d\n",ASSETCHAINS_SYMBOL,refid);
|
||||
printf("READY for RPC calls at %u! done PASSPORT %s refid.%d\n",(uint32_t)time(NULL),ASSETCHAINS_SYMBOL,refid);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
332
src/main.cpp
332
src/main.cpp
@@ -55,7 +55,7 @@ CCriticalSection cs_main;
|
||||
extern uint8_t NOTARY_PUBKEY33[33];
|
||||
extern int32_t KOMODO_LOADINGBLOCKS,KOMODO_LONGESTCHAIN;
|
||||
int32_t KOMODO_NEWBLOCKS;
|
||||
void komodo_block2pubkey33(uint8_t *pubkey33,CBlock *block);
|
||||
int32_t komodo_block2pubkey33(uint8_t *pubkey33,CBlock *block);
|
||||
|
||||
BlockMap mapBlockIndex;
|
||||
CChain chainActive;
|
||||
@@ -1603,7 +1603,7 @@ bool ReadBlockFromDisk(int32_t height,CBlock& block, const CDiskBlockPos& pos)
|
||||
if (filein.IsNull())
|
||||
{
|
||||
//fprintf(stderr,"readblockfromdisk err A\n");
|
||||
return false;//error("ReadBlockFromDisk: OpenBlockFile failed for %s", pos.ToString());
|
||||
return error("ReadBlockFromDisk: OpenBlockFile failed for %s", pos.ToString());
|
||||
}
|
||||
|
||||
// Read block
|
||||
@@ -2449,9 +2449,13 @@ bool ConnectBlock(const CBlock& block, CValidationState& state, CBlockIndex* pin
|
||||
auto verifier = libzcash::ProofVerifier::Strict();
|
||||
auto disabledVerifier = libzcash::ProofVerifier::Disabled();
|
||||
|
||||
int32_t futureblock;
|
||||
// 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(&futureblock,pindex->nHeight,pindex,block, state, fExpensiveChecks ? verifier : disabledVerifier, fCheckPOW, !fJustCheck) || futureblock != 0 )
|
||||
{
|
||||
//fprintf(stderr,"checkblock failure in connectblock futureblock.%d\n",futureblock);
|
||||
return false;
|
||||
}
|
||||
|
||||
// verify that the view's current state corresponds to the previous block
|
||||
uint256 hashPrevBlock = pindex->pprev == NULL ? uint256() : pindex->pprev->GetBlockHash();
|
||||
@@ -2604,7 +2608,7 @@ bool ConnectBlock(const CBlock& block, CValidationState& state, CBlockIndex* pin
|
||||
if ( ASSETCHAINS_OVERRIDE_PUBKEY33[0] != 0 && ASSETCHAINS_COMMISSION != 0 && block.vtx[0].vout.size() > 1 )
|
||||
{
|
||||
uint64_t checktoshis;
|
||||
if ( (checktoshis = komodo_commission(block)) != 0 )
|
||||
if ( (checktoshis= komodo_commission((const CBlock *)&block)) != 0 )
|
||||
{
|
||||
if ( block.vtx[0].vout.size() == 2 && block.vtx[0].vout[1].nValue == checktoshis )
|
||||
blockReward += checktoshis;
|
||||
@@ -3307,9 +3311,21 @@ CBlockIndex* AddToBlockIndex(const CBlockHeader& block)
|
||||
// Check for duplicate
|
||||
uint256 hash = block.GetHash();
|
||||
BlockMap::iterator it = mapBlockIndex.find(hash);
|
||||
BlockMap::iterator miPrev = mapBlockIndex.find(block.hashPrevBlock);
|
||||
if (it != mapBlockIndex.end())
|
||||
return it->second;
|
||||
|
||||
{
|
||||
if ( it->second != 0 ) // vNodes.size() >= KOMODO_LIMITED_NETWORKSIZE, change behavior to allow komodo_ensure to work
|
||||
{
|
||||
// this is the strange case where somehow the hash is in the mapBlockIndex via as yet undetermined process, but the pindex for the hash is not there. Theoretically it is due to processing the block headers, but I have seen it get this case without having received it from the block headers or anywhere else... jl777
|
||||
//fprintf(stderr,"addtoblockindex already there %p\n",it->second);
|
||||
return it->second;
|
||||
}
|
||||
if ( miPrev != mapBlockIndex.end() && (*miPrev).second == 0 )
|
||||
{
|
||||
//fprintf(stderr,"edge case of both block and prevblock in the strange state\n");
|
||||
return(0); // return here to avoid the state of pindex->nHeight not set and pprev NULL
|
||||
}
|
||||
}
|
||||
// Construct new block index object
|
||||
CBlockIndex* pindexNew = new CBlockIndex(block);
|
||||
assert(pindexNew);
|
||||
@@ -3319,11 +3335,11 @@ CBlockIndex* AddToBlockIndex(const CBlockHeader& block)
|
||||
pindexNew->nSequenceId = 0;
|
||||
BlockMap::iterator mi = mapBlockIndex.insert(make_pair(hash, pindexNew)).first;
|
||||
pindexNew->phashBlock = &((*mi).first);
|
||||
BlockMap::iterator miPrev = mapBlockIndex.find(block.hashPrevBlock);
|
||||
if (miPrev != mapBlockIndex.end())
|
||||
{
|
||||
pindexNew->pprev = (*miPrev).second;
|
||||
pindexNew->nHeight = pindexNew->pprev->nHeight + 1;
|
||||
if ( (pindexNew->pprev= (*miPrev).second) != 0 )
|
||||
pindexNew->nHeight = pindexNew->pprev->nHeight + 1;
|
||||
else fprintf(stderr,"unexpected null pprev %s\n",hash.ToString().c_str());
|
||||
pindexNew->BuildSkip();
|
||||
}
|
||||
pindexNew->nChainWork = (pindexNew->pprev ? pindexNew->pprev->nChainWork : 0) + GetBlockProof(*pindexNew);
|
||||
@@ -3332,7 +3348,8 @@ CBlockIndex* AddToBlockIndex(const CBlockHeader& block)
|
||||
pindexBestHeader = pindexNew;
|
||||
|
||||
setDirtyBlockIndex.insert(pindexNew);
|
||||
|
||||
//fprintf(stderr,"added to block index %s %p\n",hash.ToString().c_str(),pindexNew);
|
||||
mi->second = pindexNew;
|
||||
return pindexNew;
|
||||
}
|
||||
|
||||
@@ -3488,7 +3505,7 @@ bool FindUndoPos(CValidationState &state, int nFile, CDiskBlockPos &pos, unsigne
|
||||
return true;
|
||||
}
|
||||
|
||||
bool CheckBlockHeader(int32_t height,CBlockIndex *pindex, const CBlockHeader& blockhdr, CValidationState& state, bool fCheckPOW)
|
||||
bool CheckBlockHeader(int32_t *futureblockp,int32_t height,CBlockIndex *pindex, const CBlockHeader& blockhdr, CValidationState& state, bool fCheckPOW)
|
||||
{
|
||||
// Check timestamp
|
||||
if ( 0 )
|
||||
@@ -3506,9 +3523,30 @@ bool CheckBlockHeader(int32_t height,CBlockIndex *pindex, const CBlockHeader& bl
|
||||
fprintf(stderr," <- chainTip\n");
|
||||
}
|
||||
}
|
||||
*futureblockp = 0;
|
||||
if (blockhdr.GetBlockTime() > GetAdjustedTime() + 60)
|
||||
{
|
||||
CBlockIndex *tipindex;
|
||||
//fprintf(stderr,"ht.%d future block %u vs time.%u + 60\n",height,(uint32_t)blockhdr.GetBlockTime(),(uint32_t)GetAdjustedTime());
|
||||
if ( (tipindex= chainActive.Tip()) != 0 && tipindex->GetBlockHash() == blockhdr.hashPrevBlock && blockhdr.GetBlockTime() < GetAdjustedTime() + 60 + 5 )
|
||||
{
|
||||
//fprintf(stderr,"it is the next block, let's wait for %d seconds\n",GetAdjustedTime() + 60 - blockhdr.GetBlockTime());
|
||||
while ( blockhdr.GetBlockTime() > GetAdjustedTime() + 60 )
|
||||
sleep(1);
|
||||
//fprintf(stderr,"now its valid\n");
|
||||
}
|
||||
else
|
||||
{
|
||||
if (blockhdr.GetBlockTime() < GetAdjustedTime() + 600)
|
||||
*futureblockp = 1;
|
||||
LogPrintf("CheckBlockHeader block from future %d error\n",blockhdr.GetBlockTime() - GetAdjustedTime());
|
||||
return false; //state.Invalid(error("CheckBlockHeader(): block timestamp too far in the future"),REJECT_INVALID, "time-too-new");
|
||||
}
|
||||
}
|
||||
/*if (blockhdr.GetBlockTime() > GetAdjustedTime() + 60)
|
||||
return state.Invalid(error("CheckBlockHeader(): block timestamp too far in the future"),REJECT_INVALID, "time-too-new");
|
||||
else if ( ASSETCHAINS_STAKED != 0 && pindex != 0 && pindex->pprev != 0 && pindex->nTime <= pindex->pprev->nTime )
|
||||
else*/
|
||||
if ( ASSETCHAINS_STAKED != 0 && pindex != 0 && pindex->pprev != 0 && pindex->nTime <= pindex->pprev->nTime )
|
||||
{
|
||||
fprintf(stderr,"ht.%d %u vs ht.%d %u, is not monotonic\n",pindex->nHeight,pindex->nTime,pindex->pprev->nHeight,pindex->pprev->nTime);
|
||||
return state.Invalid(error("CheckBlockHeader(): block timestamp needs to always increase"),REJECT_INVALID, "time-too-new");
|
||||
@@ -3563,25 +3601,43 @@ int32_t komodo_reverify_blockcheck(CValidationState& state,int32_t height,CBlock
|
||||
return(0);
|
||||
}
|
||||
|
||||
bool CheckBlock(int32_t height,CBlockIndex *pindex,const CBlock& block, CValidationState& state,
|
||||
bool CheckBlock(int32_t *futureblockp,int32_t height,CBlockIndex *pindex,const CBlock& block, CValidationState& state,
|
||||
libzcash::ProofVerifier& verifier,
|
||||
bool fCheckPOW, bool fCheckMerkleRoot)
|
||||
{
|
||||
uint8_t pubkey33[33];
|
||||
uint8_t pubkey33[33]; uint256 hash;
|
||||
// These are checks that are independent of context.
|
||||
|
||||
// Check that the header is valid (particularly PoW). This is mostly
|
||||
// redundant with the call in AcceptBlockHeader.
|
||||
if (!CheckBlockHeader(height,pindex,block,state,fCheckPOW))
|
||||
hash = block.GetHash();
|
||||
|
||||
// Check that the header is valid (particularly PoW). This is mostly redundant with the call in AcceptBlockHeader.
|
||||
if (!CheckBlockHeader(futureblockp,height,pindex,block,state,fCheckPOW))
|
||||
{
|
||||
//fprintf(stderr,"checkblockheader error PoW.%d\n",fCheckPOW);
|
||||
return false;
|
||||
if ( *futureblockp == 0 )
|
||||
{
|
||||
LogPrintf("CheckBlock header error\n");
|
||||
return false;
|
||||
}
|
||||
}
|
||||
if ( fCheckPOW && !CheckEquihashSolution(&block, Params()) )
|
||||
if ( fCheckPOW )
|
||||
{
|
||||
//if ( !CheckEquihashSolution(&block, Params()) )
|
||||
// return state.DoS(100, error("CheckBlock: Equihash solution invalid"),REJECT_INVALID, "invalid-solution");
|
||||
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");
|
||||
}
|
||||
/*if ( fCheckPOW && !CheckEquihashSolution(&block, Params()) )
|
||||
return state.DoS(100, error("CheckBlockHeader(): Equihash solution invalid"),REJECT_INVALID, "invalid-solution");
|
||||
komodo_block2pubkey33(pubkey33,(CBlock *)&block);
|
||||
if ( fCheckPOW && !CheckProofOfWork(height,pubkey33,block.GetHash(), block.nBits, Params().GetConsensus(),block.nTime) )
|
||||
return state.DoS(1, error("CheckBlock(): proof of work failed"),REJECT_INVALID, "high-hash");
|
||||
return state.DoS(1, error("CheckBlock(): proof of work failed"),REJECT_INVALID, "high-hash");*/
|
||||
// Check the merkle root.
|
||||
if (fCheckMerkleRoot) {
|
||||
bool mutated;
|
||||
@@ -3742,70 +3798,93 @@ bool ContextualCheckBlock(const CBlock& block, CValidationState& state, CBlockIn
|
||||
return true;
|
||||
}
|
||||
|
||||
bool AcceptBlockHeader(const CBlockHeader& block, CValidationState& state, CBlockIndex** ppindex)
|
||||
bool AcceptBlockHeader(int32_t *futureblockp,const CBlockHeader& block, CValidationState& state, CBlockIndex** ppindex)
|
||||
{
|
||||
static uint256 zero;
|
||||
const CChainParams& chainparams = Params();
|
||||
AssertLockHeld(cs_main);
|
||||
|
||||
// Check for duplicate
|
||||
uint256 hash = block.GetHash();
|
||||
BlockMap::iterator miSelf = mapBlockIndex.find(hash);
|
||||
CBlockIndex *pindex = NULL;
|
||||
if (miSelf != mapBlockIndex.end()) {
|
||||
if (miSelf != mapBlockIndex.end())
|
||||
{
|
||||
// Block header is already known.
|
||||
pindex = miSelf->second;
|
||||
if ( (pindex= miSelf->second) == 0 )
|
||||
miSelf->second = pindex = AddToBlockIndex(block);
|
||||
if (ppindex)
|
||||
*ppindex = pindex;
|
||||
if ( pindex != 0 && pindex->nStatus & BLOCK_FAILED_MASK )
|
||||
return state.Invalid(error("%s: block is marked invalid", __func__), 0, "duplicate");
|
||||
return true;
|
||||
}
|
||||
|
||||
if (!CheckBlockHeader(*ppindex!=0?(*ppindex)->nHeight:0,*ppindex, block, state,0))
|
||||
if (!CheckBlockHeader(futureblockp,*ppindex!=0?(*ppindex)->nHeight:0,*ppindex, block, state,0))
|
||||
{
|
||||
fprintf(stderr,"CheckBlockHeader failed\n");
|
||||
return false;
|
||||
if ( *futureblockp == 0 )
|
||||
{
|
||||
LogPrintf("AcceptBlockHeader CheckBlockHeader error\n");
|
||||
return false;
|
||||
}
|
||||
}
|
||||
// Get prev block index
|
||||
CBlockIndex* pindexPrev = NULL;
|
||||
if (hash != chainparams.GetConsensus().hashGenesisBlock) {
|
||||
if (hash != chainparams.GetConsensus().hashGenesisBlock)
|
||||
{
|
||||
BlockMap::iterator mi = mapBlockIndex.find(block.hashPrevBlock);
|
||||
if (mi == mapBlockIndex.end())
|
||||
{
|
||||
return state.DoS(10, error("%s: prev block not found", __func__), 0, "bad-prevblk");
|
||||
LogPrintf("AcceptBlockHeader hashPrevBlock %s not found\n",block.hashPrevBlock.ToString().c_str());
|
||||
return(false);
|
||||
//return state.DoS(10, error("%s: prev block not found", __func__), 0, "bad-prevblk");
|
||||
}
|
||||
pindexPrev = (*mi).second;
|
||||
if (pindexPrev == 0 || (pindexPrev->nStatus & BLOCK_FAILED_MASK) )
|
||||
if (pindexPrev == 0 )
|
||||
{
|
||||
LogPrintf("AcceptBlockHeader hashPrevBlock %s no pindexPrev\n",block.hashPrevBlock.ToString().c_str());
|
||||
return(false);
|
||||
}
|
||||
if ( (pindexPrev->nStatus & BLOCK_FAILED_MASK) )
|
||||
return state.DoS(100, error("%s: prev block invalid", __func__), REJECT_INVALID, "bad-prevblk");
|
||||
}
|
||||
if (!ContextualCheckBlockHeader(block, state, pindexPrev))
|
||||
{
|
||||
//fprintf(stderr,"ContextualCheckBlockHeader failed\n");
|
||||
//fprintf(stderr,"AcceptBlockHeader ContextualCheckBlockHeader failed\n");
|
||||
LogPrintf("AcceptBlockHeader ContextualCheckBlockHeader failed\n");
|
||||
return false;
|
||||
}
|
||||
if (pindex == NULL)
|
||||
{
|
||||
if ( (pindex= AddToBlockIndex(block)) == 0 )
|
||||
fprintf(stderr,"couldnt add to block index\n");
|
||||
if ( (pindex= AddToBlockIndex(block)) != 0 )
|
||||
{
|
||||
miSelf = mapBlockIndex.find(hash);
|
||||
if (miSelf != mapBlockIndex.end())
|
||||
miSelf->second = pindex;
|
||||
//fprintf(stderr,"AcceptBlockHeader couldnt add to block index\n");
|
||||
}
|
||||
}
|
||||
if (ppindex)
|
||||
*ppindex = pindex;
|
||||
return true;
|
||||
}
|
||||
|
||||
bool AcceptBlock(CBlock& block, CValidationState& state, CBlockIndex** ppindex, bool fRequested, CDiskBlockPos* dbp)
|
||||
bool AcceptBlock(int32_t *futureblockp,CBlock& block, CValidationState& state, CBlockIndex** ppindex, bool fRequested, CDiskBlockPos* dbp)
|
||||
{
|
||||
const CChainParams& chainparams = Params();
|
||||
AssertLockHeld(cs_main);
|
||||
|
||||
CBlockIndex *&pindex = *ppindex;
|
||||
if (!AcceptBlockHeader(block, state, &pindex))
|
||||
if (!AcceptBlockHeader(futureblockp,block, state, &pindex))
|
||||
{
|
||||
//fprintf(stderr,"AcceptBlockHeader rejected\n");
|
||||
return false;
|
||||
if ( *futureblockp == 0 )
|
||||
{
|
||||
LogPrintf("AcceptBlock AcceptBlockHeader error\n");
|
||||
return false;
|
||||
}
|
||||
}
|
||||
if ( pindex == 0 )
|
||||
{
|
||||
//fprintf(stderr,"unexpected AcceptBlock error null pindex\n");
|
||||
LogPrintf("AcceptBlock null pindex error\n");
|
||||
return false;
|
||||
}
|
||||
//fprintf(stderr,"acceptblockheader passed\n");
|
||||
@@ -3819,10 +3898,11 @@ bool AcceptBlock(CBlock& block, CValidationState& state, CBlockIndex** ppindex,
|
||||
// blocks which are too close in height to the tip. Apply this test
|
||||
// regardless of whether pruning is enabled; it should generally be safe to
|
||||
// not process unrequested blocks.
|
||||
bool fTooFarAhead = (pindex->nHeight > int(chainActive.Height() + MIN_BLOCKS_TO_KEEP));
|
||||
bool fTooFarAhead = (pindex->nHeight > int(chainActive.Height() + BLOCK_DOWNLOAD_WINDOW)); //MIN_BLOCKS_TO_KEEP));
|
||||
|
||||
// TODO: deal better with return value and error conditions for duplicate
|
||||
// and unrequested blocks.
|
||||
//fprintf(stderr,"Accept %s flags already.%d requested.%d morework.%d farahead.%d\n",pindex->GetBlockHash().ToString().c_str(),fAlreadyHave,fRequested,fHasMoreWork,fTooFarAhead);
|
||||
if (fAlreadyHave) return true;
|
||||
if (!fRequested) { // If we didn't ask for it:
|
||||
if (pindex->nTx != 0) return true; // This is a previously-processed block that was pruned
|
||||
@@ -3832,18 +3912,20 @@ bool AcceptBlock(CBlock& block, CValidationState& state, CBlockIndex** ppindex,
|
||||
|
||||
// See method docstring for why this is always disabled
|
||||
auto verifier = libzcash::ProofVerifier::Disabled();
|
||||
if ((!CheckBlock(pindex->nHeight,pindex,block, state, verifier,0)) || !ContextualCheckBlock(block, state, pindex->pprev))
|
||||
if ((!CheckBlock(futureblockp,pindex->nHeight,pindex,block, state, verifier,0)) || !ContextualCheckBlock(block, state, pindex->pprev))
|
||||
{
|
||||
if (state.IsInvalid() && !state.CorruptionPossible()) {
|
||||
pindex->nStatus |= BLOCK_FAILED_VALID;
|
||||
setDirtyBlockIndex.insert(pindex);
|
||||
if ( *futureblockp == 0 )
|
||||
{
|
||||
if (state.IsInvalid() && !state.CorruptionPossible()) {
|
||||
pindex->nStatus |= BLOCK_FAILED_VALID;
|
||||
setDirtyBlockIndex.insert(pindex);
|
||||
}
|
||||
LogPrintf("AcceptBlock CheckBlock or ContextualCheckBlock error\n");
|
||||
return false;
|
||||
}
|
||||
fprintf(stderr,"CheckBlock or ContextualCheckBlock failed\n");
|
||||
return false;
|
||||
}
|
||||
|
||||
int nHeight = pindex->nHeight;
|
||||
|
||||
// Write block to history file
|
||||
try {
|
||||
unsigned int nBlockSize = ::GetSerializeSize(block, SER_DISK, CLIENT_VERSION);
|
||||
@@ -3863,8 +3945,10 @@ bool AcceptBlock(CBlock& block, CValidationState& state, CBlockIndex** ppindex,
|
||||
|
||||
if (fCheckForPruning)
|
||||
FlushStateToDisk(state, FLUSH_STATE_NONE); // we just allocated more disk space for block files
|
||||
|
||||
return true;
|
||||
if ( *futureblockp == 0 )
|
||||
return true;
|
||||
LogPrintf("AcceptBlock block from future error\n");
|
||||
return false;
|
||||
}
|
||||
|
||||
static bool IsSuperMajority(int minVersion, const CBlockIndex* pstart, unsigned nRequired, const Consensus::Params& consensusParams)
|
||||
@@ -3881,21 +3965,105 @@ static bool IsSuperMajority(int minVersion, const CBlockIndex* pstart, unsigned
|
||||
|
||||
void komodo_currentheight_set(int32_t height);
|
||||
|
||||
bool ProcessNewBlock(int32_t height,CValidationState &state, CNode* pfrom, CBlock* pblock, bool fForceProcessing, CDiskBlockPos *dbp)
|
||||
CBlockIndex *komodo_ensure(CBlock *pblock,uint256 hash)
|
||||
{
|
||||
CBlockIndex *pindex;
|
||||
BlockMap::iterator miSelf = mapBlockIndex.find(hash);
|
||||
if ( miSelf != mapBlockIndex.end() )
|
||||
{
|
||||
if ( (pindex= miSelf->second) == 0 ) // create pindex so first Accept block doesnt fail
|
||||
{
|
||||
miSelf->second = AddToBlockIndex(*pblock);
|
||||
//fprintf(stderr,"Block header %s is already known, but without pindex -> ensured %p\n",hash.ToString().c_str(),miSelf->second);
|
||||
}
|
||||
if ( hash != Params().GetConsensus().hashGenesisBlock )
|
||||
{
|
||||
miSelf = mapBlockIndex.find(pblock->hashPrevBlock);
|
||||
if ( miSelf != mapBlockIndex.end() )
|
||||
{
|
||||
if ( miSelf->second == 0 )
|
||||
{
|
||||
miSelf->second = InsertBlockIndex(pblock->hashPrevBlock);
|
||||
fprintf(stderr,"autocreate previndex %s\n",pblock->hashPrevBlock.ToString().c_str());
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
CBlockIndex *oldkomodo_ensure(CBlock *pblock,uint256 hash)
|
||||
{
|
||||
CBlockIndex *pindex=0,*previndex=0;
|
||||
if ( (pindex= mapBlockIndex[hash]) == 0 )
|
||||
{
|
||||
pindex = new CBlockIndex();
|
||||
if (!pindex)
|
||||
throw runtime_error("komodo_ensure: new CBlockIndex failed");
|
||||
BlockMap::iterator mi = mapBlockIndex.insert(make_pair(hash, pindex)).first;
|
||||
pindex->phashBlock = &((*mi).first);
|
||||
}
|
||||
BlockMap::iterator miSelf = mapBlockIndex.find(hash);
|
||||
if ( miSelf == mapBlockIndex.end() )
|
||||
{
|
||||
LogPrintf("komodo_ensure unexpected missing hash %s\n",hash.ToString().c_str());
|
||||
return(0);
|
||||
}
|
||||
if ( miSelf->second == 0 ) // create pindex so first Accept block doesnt fail
|
||||
{
|
||||
if ( pindex == 0 )
|
||||
{
|
||||
pindex = AddToBlockIndex(*pblock);
|
||||
fprintf(stderr,"ensure call addtoblockindex, got %p\n",pindex);
|
||||
}
|
||||
if ( pindex != 0 )
|
||||
{
|
||||
miSelf->second = pindex;
|
||||
LogPrintf("Block header %s is already known, but without pindex -> ensured %p\n",hash.ToString().c_str(),miSelf->second);
|
||||
} else LogPrintf("komodo_ensure unexpected null pindex\n");
|
||||
}
|
||||
/*if ( hash != Params().GetConsensus().hashGenesisBlock )
|
||||
{
|
||||
miSelf = mapBlockIndex.find(pblock->hashPrevBlock);
|
||||
if ( miSelf == mapBlockIndex.end() )
|
||||
previndex = InsertBlockIndex(pblock->hashPrevBlock);
|
||||
if ( (miSelf= mapBlockIndex.find(pblock->hashPrevBlock)) != mapBlockIndex.end() )
|
||||
{
|
||||
if ( miSelf->second == 0 ) // create pindex so first Accept block doesnt fail
|
||||
{
|
||||
if ( previndex == 0 )
|
||||
previndex = InsertBlockIndex(pblock->hashPrevBlock);
|
||||
if ( previndex != 0 )
|
||||
{
|
||||
miSelf->second = previndex;
|
||||
LogPrintf("autocreate previndex %s\n",pblock->hashPrevBlock.ToString().c_str());
|
||||
} else LogPrintf("komodo_ensure unexpected null previndex\n");
|
||||
}
|
||||
} else LogPrintf("komodo_ensure unexpected null miprev\n");
|
||||
}
|
||||
}*/
|
||||
return(pindex);
|
||||
}
|
||||
|
||||
bool ProcessNewBlock(bool from_miner,int32_t height,CValidationState &state, CNode* pfrom, CBlock* pblock, bool fForceProcessing, CDiskBlockPos *dbp)
|
||||
{
|
||||
// Preliminary checks
|
||||
bool checked;
|
||||
bool checked; uint256 hash; int32_t futureblock=0;
|
||||
auto verifier = libzcash::ProofVerifier::Disabled();
|
||||
hash = pblock->GetHash();
|
||||
//fprintf(stderr,"process newblock %s\n",hash.ToString().c_str());
|
||||
if ( chainActive.Tip() != 0 )
|
||||
komodo_currentheight_set(chainActive.Tip()->nHeight);
|
||||
if ( ASSETCHAINS_SYMBOL[0] == 0 )
|
||||
checked = CheckBlock(height!=0?height:komodo_block2height(pblock),0,*pblock, state, verifier,0);
|
||||
else checked = CheckBlock(height!=0?height:komodo_block2height(pblock),0,*pblock, state, verifier,0);
|
||||
checked = CheckBlock(&futureblock,height!=0?height:komodo_block2height(pblock),0,*pblock, state, verifier,0);
|
||||
{
|
||||
LOCK(cs_main);
|
||||
bool fRequested = MarkBlockAsReceived(pblock->GetHash());
|
||||
bool fRequested = MarkBlockAsReceived(hash);
|
||||
fRequested |= fForceProcessing;
|
||||
if (!checked)
|
||||
if ( checked != 0 && komodo_checkPOW(from_miner && ASSETCHAINS_STAKED == 0,pblock,height) < 0 )
|
||||
{
|
||||
checked = 0;
|
||||
fprintf(stderr,"passed checkblock but failed checkPOW.%d\n",from_miner && ASSETCHAINS_STAKED == 0);
|
||||
}
|
||||
if (!checked && futureblock == 0)
|
||||
{
|
||||
if ( pfrom != 0 )
|
||||
{
|
||||
@@ -3903,19 +4071,24 @@ bool ProcessNewBlock(int32_t height,CValidationState &state, CNode* pfrom, CBloc
|
||||
}
|
||||
return error("%s: CheckBlock FAILED", __func__);
|
||||
}
|
||||
|
||||
// Store to disk
|
||||
CBlockIndex *pindex = NULL;
|
||||
bool ret = AcceptBlock(*pblock, state, &pindex, fRequested, dbp);
|
||||
if ( 1 )
|
||||
{
|
||||
// without the komodo_ensure call, it is quite possible to get a non-error but null pindex returned from AcceptBlockHeader. In a 2 node network, it will be a long time before that block is reprocessed. Even though restarting makes it rescan, it seems much better to keep the nodes in sync
|
||||
komodo_ensure(pblock,hash);
|
||||
}
|
||||
bool ret = AcceptBlock(&futureblock,*pblock, state, &pindex, fRequested, dbp);
|
||||
if (pindex && pfrom) {
|
||||
mapBlockSource[pindex->GetBlockHash()] = pfrom->GetId();
|
||||
}
|
||||
CheckBlockIndex();
|
||||
if (!ret)
|
||||
if (!ret && futureblock == 0)
|
||||
return error("%s: AcceptBlock FAILED", __func__);
|
||||
//else fprintf(stderr,"added block %s %p\n",pindex->GetBlockHash().ToString().c_str(),pindex->pprev);
|
||||
}
|
||||
|
||||
if (!ActivateBestChain(state, pblock))
|
||||
if (futureblock == 0 && !ActivateBestChain(state, pblock))
|
||||
return error("%s: ActivateBestChain failed", __func__);
|
||||
|
||||
return true;
|
||||
@@ -3932,30 +4105,31 @@ bool TestBlockValidity(CValidationState &state, const CBlock& block, CBlockIndex
|
||||
indexDummy.nHeight = pindexPrev->nHeight + 1;
|
||||
// JoinSplit proofs are verified in ConnectBlock
|
||||
auto verifier = libzcash::ProofVerifier::Disabled();
|
||||
|
||||
// NOTE: CheckBlockHeader is called by CheckBlock
|
||||
if (!ContextualCheckBlockHeader(block, state, pindexPrev))
|
||||
{
|
||||
fprintf(stderr,"TestBlockValidity failure A\n");
|
||||
//fprintf(stderr,"TestBlockValidity failure A checkPOW.%d\n",fCheckPOW);
|
||||
return false;
|
||||
}
|
||||
if (!CheckBlock(indexDummy.nHeight,0,block, state, verifier, fCheckPOW, fCheckMerkleRoot))
|
||||
int32_t futureblock;
|
||||
if (!CheckBlock(&futureblock,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;
|
||||
}
|
||||
if (!ContextualCheckBlock(block, state, pindexPrev))
|
||||
{
|
||||
//fprintf(stderr,"TestBlockValidity failure C\n");
|
||||
//fprintf(stderr,"TestBlockValidity failure C checkPOW.%d\n",fCheckPOW);
|
||||
return false;
|
||||
}
|
||||
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;
|
||||
}
|
||||
assert(state.IsValid());
|
||||
|
||||
if ( futureblock != 0 )
|
||||
return(false);
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -4103,7 +4277,7 @@ FILE* OpenDiskFile(const CDiskBlockPos &pos, const char *prefix, bool fReadOnly)
|
||||
while ( fread(ignore,1,incr,file) == incr )
|
||||
fprintf(stderr,".");
|
||||
free(ignore);
|
||||
fprintf(stderr,"blk.%d loaded %ld bytes set fpos.%ld loading.%d\n",(int)pos.nFile,(long)ftell(file),(long)fpos,KOMODO_LOADINGBLOCKS);
|
||||
//fprintf(stderr,"blk.%d loaded %ld bytes set fpos.%ld loading.%d\n",(int)pos.nFile,(long)ftell(file),(long)fpos,KOMODO_LOADINGBLOCKS);
|
||||
}
|
||||
}
|
||||
fseek(file,fpos,SEEK_SET);
|
||||
@@ -4347,7 +4521,8 @@ bool CVerifyDB::VerifyDB(CCoinsView *coinsview, int nCheckLevel, int nCheckDepth
|
||||
if (!ReadBlockFromDisk(block, pindex))
|
||||
return error("VerifyDB(): *** ReadBlockFromDisk failed at %d, hash=%s", pindex->nHeight, pindex->GetBlockHash().ToString());
|
||||
// check level 1: verify block validity
|
||||
if (nCheckLevel >= 1 && !CheckBlock(pindex->nHeight,pindex,block, state, verifier,0))
|
||||
int32_t futureblock;
|
||||
if (nCheckLevel >= 1 && !CheckBlock(&futureblock,pindex->nHeight,pindex,block, state, verifier,0))
|
||||
return error("VerifyDB(): *** found bad block at %d, hash=%s\n", pindex->nHeight, pindex->GetBlockHash().ToString());
|
||||
// check level 2: verify undo validity
|
||||
if (nCheckLevel >= 2 && pindex) {
|
||||
@@ -4682,7 +4857,7 @@ bool LoadExternalBlockFile(FILE* fileIn, CDiskBlockPos *dbp)
|
||||
// process in case the block isn't known yet
|
||||
if (mapBlockIndex.count(hash) == 0 || (mapBlockIndex[hash]->nStatus & BLOCK_HAVE_DATA) == 0) {
|
||||
CValidationState state;
|
||||
if (ProcessNewBlock(0,state, NULL, &block, true, dbp))
|
||||
if (ProcessNewBlock(0,0,state, NULL, &block, true, dbp))
|
||||
nLoaded++;
|
||||
if (state.IsError())
|
||||
break;
|
||||
@@ -4704,7 +4879,7 @@ bool LoadExternalBlockFile(FILE* fileIn, CDiskBlockPos *dbp)
|
||||
LogPrintf("%s: Processing out of order child %s of %s\n", __func__, block.GetHash().ToString(),
|
||||
head.ToString());
|
||||
CValidationState dummy;
|
||||
if (ProcessNewBlock(0,dummy, NULL, &block, true, &it->second))
|
||||
if (ProcessNewBlock(0,0,dummy, NULL, &block, true, &it->second))
|
||||
{
|
||||
nLoaded++;
|
||||
queue.push_back(block.GetHash());
|
||||
@@ -5575,12 +5750,6 @@ bool static ProcessMessage(CNode* pfrom, string strCommand, CDataStream& vRecv,
|
||||
}
|
||||
pfrom->PushMessage("headers", vHeaders);
|
||||
}
|
||||
/*else if ( NOTARY_PUBKEY33[0] != 0 )
|
||||
{
|
||||
static uint32_t counter;
|
||||
if ( counter++ < 3 )
|
||||
fprintf(stderr,"you can ignore redundant getheaders from peer.%d %d prev.%d\n",(int32_t)pfrom->id,(int32_t)(pindex ? pindex->nHeight : -1),pfrom->lasthdrsreq);
|
||||
}*/
|
||||
}
|
||||
|
||||
|
||||
@@ -5744,9 +5913,10 @@ bool static ProcessMessage(CNode* pfrom, string strCommand, CDataStream& vRecv,
|
||||
Misbehaving(pfrom->GetId(), 20);
|
||||
return error("non-continuous headers sequence");
|
||||
}
|
||||
if (!AcceptBlockHeader(header, state, &pindexLast)) {
|
||||
int32_t futureblock;
|
||||
if (!AcceptBlockHeader(&futureblock,header, state, &pindexLast)) {
|
||||
int nDoS;
|
||||
if (state.IsInvalid(nDoS))
|
||||
if (state.IsInvalid(nDoS) && futureblock == 0)
|
||||
{
|
||||
if (nDoS > 0)
|
||||
Misbehaving(pfrom->GetId(), nDoS/nDoS);
|
||||
@@ -5789,7 +5959,7 @@ bool static ProcessMessage(CNode* pfrom, string strCommand, CDataStream& vRecv,
|
||||
// Such an unrequested block may still be processed, subject to the
|
||||
// conditions in AcceptBlock().
|
||||
bool forceProcessing = pfrom->fWhitelisted && !IsInitialBlockDownload();
|
||||
ProcessNewBlock(0,state, pfrom, &block, forceProcessing, NULL);
|
||||
ProcessNewBlock(0,0,state, pfrom, &block, forceProcessing, NULL);
|
||||
int nDoS;
|
||||
if (state.IsInvalid(nDoS)) {
|
||||
pfrom->PushMessage("reject", strCommand, state.GetRejectCode(),
|
||||
|
||||
10
src/main.h
10
src/main.h
@@ -183,7 +183,7 @@ void UnregisterNodeSignals(CNodeSignals& nodeSignals);
|
||||
* @param[out] dbp If pblock is stored to disk (or already there), this will be set to its location.
|
||||
* @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 */
|
||||
bool CheckDiskSpace(uint64_t nAdditionalBytes = 0);
|
||||
/** Open a block file (blk?????.dat) */
|
||||
@@ -450,8 +450,8 @@ bool DisconnectBlock(CBlock& block, CValidationState& state, CBlockIndex* pindex
|
||||
bool ConnectBlock(const CBlock& block, CValidationState& state, CBlockIndex* pindex, CCoinsViewCache& coins, bool fJustCheck = false,bool fCheckPOW = false);
|
||||
|
||||
/** Context-independent validity checks */
|
||||
bool CheckBlockHeader(int32_t height,CBlockIndex *pindex,const CBlockHeader& block, CValidationState& state, bool fCheckPOW = true);
|
||||
bool CheckBlock(int32_t height,CBlockIndex *pindex,const CBlock& block, CValidationState& state,
|
||||
bool CheckBlockHeader(int32_t *futureblockp,int32_t height,CBlockIndex *pindex,const CBlockHeader& block, CValidationState& state, bool fCheckPOW = true);
|
||||
bool CheckBlock(int32_t *futureblockp,int32_t height,CBlockIndex *pindex,const CBlock& block, CValidationState& state,
|
||||
libzcash::ProofVerifier& verifier,
|
||||
bool fCheckPOW = true, bool fCheckMerkleRoot = true);
|
||||
|
||||
@@ -469,8 +469,8 @@ bool TestBlockValidity(CValidationState &state, const CBlock& block, CBlockIndex
|
||||
* - The only caller of AcceptBlock verifies JoinSplit proofs elsewhere.
|
||||
* If dbp is non-NULL, the file is known to already reside on disk
|
||||
*/
|
||||
bool AcceptBlock(CBlock& block, CValidationState& state, CBlockIndex **pindex, bool fRequested, CDiskBlockPos* dbp);
|
||||
bool AcceptBlockHeader(const CBlockHeader& block, CValidationState& state, CBlockIndex **ppindex= NULL);
|
||||
bool AcceptBlock(int32_t *futureblockp,CBlock& block, CValidationState& state, CBlockIndex **pindex, bool fRequested, CDiskBlockPos* dbp);
|
||||
bool AcceptBlockHeader(int32_t *futureblockp,const CBlockHeader& block, CValidationState& state, CBlockIndex **ppindex= NULL);
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -119,7 +119,7 @@ int32_t komodo_is_issuer();
|
||||
int32_t komodo_gateway_deposits(CMutableTransaction *txNew,char *symbol,int32_t tokomodo);
|
||||
int32_t komodo_isrealtime(int32_t *kmdheightp);
|
||||
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);
|
||||
|
||||
CBlockTemplate* CreateNewBlock(const CScript& scriptPubKeyIn)
|
||||
@@ -454,7 +454,7 @@ CBlockTemplate* CreateNewBlock(const CScript& scriptPubKeyIn)
|
||||
}*/
|
||||
|
||||
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;
|
||||
txNew.vout.resize(2);
|
||||
@@ -655,7 +655,7 @@ static bool ProcessBlockFound(CBlock* pblock)
|
||||
|
||||
// Process this block the same as if we had received it from another node
|
||||
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");
|
||||
|
||||
TrackMinedBlock(pblock->GetHash());
|
||||
|
||||
@@ -267,7 +267,7 @@ UniValue generate(const UniValue& params, bool fHelp)
|
||||
}
|
||||
endloop:
|
||||
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");
|
||||
++nHeight;
|
||||
blockHashes.push_back(pblock->GetHash().GetHex());
|
||||
@@ -807,7 +807,7 @@ UniValue submitblock(const UniValue& params, bool fHelp)
|
||||
CValidationState state;
|
||||
submitblock_StateCatcher sc(block.GetHash());
|
||||
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);
|
||||
if (fBlockPresent)
|
||||
{
|
||||
|
||||
@@ -242,7 +242,7 @@ BOOST_AUTO_TEST_CASE(CreateNewBlock_validity)
|
||||
|
||||
CValidationState state;
|
||||
|
||||
if (ProcessNewBlock(state, NULL, pblock, true, NULL) && state.IsValid()) {
|
||||
if (ProcessNewBlock(1,0,state, NULL, pblock, true, NULL) && state.IsValid()) {
|
||||
goto foundit;
|
||||
}
|
||||
|
||||
@@ -261,7 +261,7 @@ BOOST_AUTO_TEST_CASE(CreateNewBlock_validity)
|
||||
*/
|
||||
|
||||
CValidationState state;
|
||||
BOOST_CHECK(ProcessNewBlock(state, NULL, pblock, true, NULL));
|
||||
BOOST_CHECK(ProcessNewBlock(1,0,state, NULL, pblock, true, NULL));
|
||||
BOOST_CHECK_MESSAGE(state.IsValid(), state.GetRejectReason());
|
||||
pblock->hashPrevBlock = pblock->GetHash();
|
||||
|
||||
|
||||
Reference in New Issue
Block a user