Cleanup assetchains mining options
This commit is contained in:
@@ -1046,3 +1046,279 @@ 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
|
||||
|
||||
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 )
|
||||
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);
|
||||
}
|
||||
|
||||
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 ( 0 )
|
||||
{
|
||||
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 ( 0 )
|
||||
{
|
||||
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,CBlock *pblock,arith_uint256 bnTarget)
|
||||
{
|
||||
CBlockIndex *previndex; char voutaddr[64],destaddr[64]; uint256 txid; uint32_t prevtime=0; int32_t vout,txn_count,isPoS = 0;
|
||||
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)block.nTime,(int32_t)(eligible - block.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(address).ToString().c_str());
|
||||
if ( strcmp(destaddr,voutaddr) == 0 && pblock->vtx[txn_count-1].vout[0].value == 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].value));
|
||||
} 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)
|
||||
{
|
||||
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;
|
||||
if ( height == 0 )
|
||||
return(0);
|
||||
if ( !CheckEquihashSolution(pblock, Params()) )
|
||||
{
|
||||
fprintf(stderr,"komodo_checkPOW slowflag.%d ht.%d CheckEquihashSolution failed\n",slowflag,height);
|
||||
return(-1);
|
||||
}
|
||||
bnTarget.SetCompact(pblock->nBits,&fNegative,&fOverflow);
|
||||
bhash = UintToArith256(pblock->GetHash());
|
||||
komodo_block2pubkey33(pubkey33,pblock);
|
||||
if ( slowflag != 0 )
|
||||
{
|
||||
if ( !CheckProofOfWork(height,pubkey33,bhash,pblock->nBits,Params().GetConsensus(),pblock->nTime) )
|
||||
return state.DoS(1, error("CheckBlock: proof of work failed"),REJECT_INVALID, "high-hash");
|
||||
}
|
||||
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,&block,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 *)&hashval)[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 ( isPoSblock < 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);
|
||||
}
|
||||
|
||||
|
||||
@@ -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 ( 0 )
|
||||
{
|
||||
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;
|
||||
@@ -867,59 +720,6 @@ 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);
|
||||
}
|
||||
|
||||
58
src/main.cpp
58
src/main.cpp
@@ -2801,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);
|
||||
|
||||
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;
|
||||
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 )
|
||||
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),block.vtx[0].vout.size());
|
||||
}
|
||||
}
|
||||
if ( block.vtx[0].GetValueOut() > blockReward+1 )
|
||||
@@ -3765,42 +3765,7 @@ 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_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);
|
||||
}
|
||||
if ( ASSETCHAINS_STAKED != 0 ) // add PoS/PoW checks
|
||||
return(0);
|
||||
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);
|
||||
}
|
||||
int32_t komodo_checkPOW(int32_t slowflag,CBlock *pblock,int32_t height);
|
||||
|
||||
bool CheckBlock(int32_t height,CBlockIndex *pindex,const CBlock& block, CValidationState& state,
|
||||
libzcash::ProofVerifier& verifier,
|
||||
@@ -3816,11 +3781,14 @@ bool CheckBlock(int32_t height,CBlockIndex *pindex,const CBlock& block, CValidat
|
||||
fprintf(stderr,"checkblockheader error PoW.%d\n",fCheckPOW);
|
||||
return false;
|
||||
}
|
||||
if ( fCheckPOW && !CheckEquihashSolution(&block, Params()) )
|
||||
return state.DoS(100, error("CheckBlock: 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");
|
||||
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 ( komodo_checkPOW(1,&block,height) < 0 ) // checks Equihash
|
||||
return state.DoS(100, error("CheckBlock: failed slow_checkPOW"),REJECT_INVALID, "failed-slow_checkPOW");
|
||||
}
|
||||
// Check the merkle root.
|
||||
if (fCheckMerkleRoot) {
|
||||
bool mutated;
|
||||
@@ -4133,7 +4101,7 @@ bool ProcessNewBlock(int32_t height,CValidationState &state, CNode* pfrom, CBloc
|
||||
LOCK(cs_main);
|
||||
bool fRequested = MarkBlockAsReceived(pblock->GetHash());
|
||||
fRequested |= fForceProcessing;
|
||||
if ( checked != 0 && komodo_fast_checkPOW(pblock,height) < 0 )
|
||||
if ( checked != 0 && komodo_checkPOW(0,pblock,height) < 0 )
|
||||
checked = 0;
|
||||
if (!checked)
|
||||
{
|
||||
|
||||
@@ -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)
|
||||
@@ -428,33 +428,9 @@ CBlockTemplate* CreateNewBlock(const CScript& scriptPubKeyIn)
|
||||
// Add fees
|
||||
txNew.vout[0].nValue += nFees;
|
||||
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;
|
||||
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);
|
||||
@@ -669,7 +645,7 @@ arith_uint256 komodo_PoWtarget(int32_t *percPoSp,arith_uint256 target,int32_t he
|
||||
int32_t FOUND_BLOCK,KOMODO_MAYBEMINED;
|
||||
extern int32_t KOMODO_LASTMINED;
|
||||
int32_t roundrobin_delay;
|
||||
arith_uint256 HASHTarget;
|
||||
arith_uint256 HASHTarget,HASHTarget_POW;
|
||||
|
||||
#ifdef ENABLE_WALLET
|
||||
void static BitcoinMiner(CWallet *pwallet)
|
||||
@@ -875,7 +851,7 @@ void static BitcoinMiner()
|
||||
sleep(60);
|
||||
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--)
|
||||
fprintf(stderr,"%02x",((uint8_t *)&HASHTarget)[z]);
|
||||
fprintf(stderr," PoW for staked coin %p\n",&HASHTarget);
|
||||
@@ -904,7 +880,10 @@ void static BitcoinMiner()
|
||||
crypto_generichash_blake2b_update(&curr_state,pblock->nNonce.begin(),pblock->nNonce.size());
|
||||
// (x_1, x_2, ...) = A(I, V, n, k)
|
||||
LogPrint("pow", "Running Equihash solver \"%s\" with nNonce = %s\n",solver, pblock->nNonce.ToString());
|
||||
arith_uint256 hashTarget = HASHTarget;
|
||||
arith_uint256 hashTarget;
|
||||
if ( NOTARY_PUBKEY33[0] == 0 && ASSETCHAINS_STAKED > 0 && ASSETCHAINS_STAKED < 100 )
|
||||
hashTarget = HASHTarget_POW;
|
||||
else hashTarget = HASHTarget;
|
||||
int32_t z; for (z=31; z>=0; z--)
|
||||
fprintf(stderr,"%02x",((uint8_t *)&hashTarget)[z]);
|
||||
fprintf(stderr," running solver\n");
|
||||
@@ -920,17 +899,25 @@ void static BitcoinMiner()
|
||||
LogPrint("pow", "- Checking solution against target\n");
|
||||
pblock->nSolution = soln;
|
||||
solutionTargetChecks.increment();
|
||||
if ( h > HASHTarget )
|
||||
return false;
|
||||
if ( NOTARY_PUBKEY33[0] == 0 && ASSETCHAINS_STAKED > 0 && ASSETCHAINS_STAKED < 100 )
|
||||
{
|
||||
if ( h > HASHTarget_POW )
|
||||
return false;
|
||||
}
|
||||
else
|
||||
{
|
||||
if ( h > HASHTarget )
|
||||
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,"%02x",((uint8_t *)&HASHTarget)[z]);
|
||||
fprintf(stderr," hashTarget ");
|
||||
for (z=31; z>=16; z--)
|
||||
fprintf(stderr,"%02x",((uint8_t *)&HASHTarget)[z]);
|
||||
fprintf(stderr," HASHTarget\n");
|
||||
fprintf(stderr,"%02x",((uint8_t *)&HASHTarget_POW)[z]);
|
||||
fprintf(stderr," POW\n");
|
||||
CValidationState state;
|
||||
if ( !TestBlockValidity(state, *pblock, chainActive.Tip(), true, false))
|
||||
{
|
||||
@@ -958,7 +945,7 @@ void static BitcoinMiner()
|
||||
{
|
||||
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)(pblock->nTime - GetAdjustedTime()));
|
||||
while ( GetAdjustedTime() < pblock->nTime )
|
||||
sleep(1);
|
||||
}
|
||||
@@ -1093,13 +1080,14 @@ void static BitcoinMiner()
|
||||
// Update nNonce and nTime
|
||||
pblock->nNonce = ArithToUint256(UintToArith256(pblock->nNonce) + 1);
|
||||
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:
|
||||
HASHTarget.SetCompact(pblock->nBits);
|
||||
HASHTarget_POW = komodo_PoWtarget(&percPoS,HASHTarget,Mining_height,ASSETCHAINS_STAKED);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -206,9 +206,6 @@ bool CheckProofOfWork(int32_t height,uint8_t *pubkey33,uint256 hash,unsigned int
|
||||
for (i=0; i<33; i++)
|
||||
printf("%02x",origpubkey33[i]);
|
||||
printf(" <- origpubkey\n");
|
||||
for (i=0; i<66; i++)
|
||||
printf("%d ",mids[i]);
|
||||
printf(" minerids from ht.%d\n",height);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user