try to add PoS% to staking loop, to adjust staking difficulty

This commit is contained in:
blackjok3r
2019-01-22 14:39:29 +08:00
parent 2c3247e8f1
commit 8324e606cd
4 changed files with 135 additions and 106 deletions

View File

@@ -94,9 +94,9 @@ void *chainparams_commandline(void *ptr);
extern char ASSETCHAINS_SYMBOL[KOMODO_ASSETCHAIN_MAXLEN];
extern uint16_t ASSETCHAINS_P2PPORT,ASSETCHAINS_RPCPORT;
extern uint32_t ASSETCHAIN_INIT, ASSETCHAINS_MAGIC, ASSETCHAINS_EQUIHASH, ASSETCHAINS_VERUSHASH, ASSETCHAINS_VERUSHASHV2;
extern uint32_t ASSETCHAIN_INIT, ASSETCHAINS_MAGIC, ASSETCHAINS_VERUSHASHV2, ASSETCHAINS_ALGO, ASSETCHAINS_EQUIHASH, ASSETCHAINS_VERUSHASH;
extern int32_t VERUS_BLOCK_POSUNITS, ASSETCHAINS_LWMAPOS, ASSETCHAINS_SAPLING, ASSETCHAINS_OVERWINTER;
extern uint64_t ASSETCHAINS_SUPPLY, ASSETCHAINS_ALGO;
extern uint64_t ASSETCHAINS_SUPPLY;
const arith_uint256 maxUint = UintToArith256(uint256S("ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff"));
@@ -268,7 +268,7 @@ void *chainparams_commandline(void *ptr)
mainParams.pchMessageStart[2] = (ASSETCHAINS_MAGIC >> 16) & 0xff;
mainParams.pchMessageStart[3] = (ASSETCHAINS_MAGIC >> 24) & 0xff;
fprintf(stderr,">>>>>>>>>> %s: p2p.%u rpc.%u magic.%08x %u %u coins\n",ASSETCHAINS_SYMBOL,ASSETCHAINS_P2PPORT,ASSETCHAINS_RPCPORT,ASSETCHAINS_MAGIC,ASSETCHAINS_MAGIC,(uint32_t)ASSETCHAINS_SUPPLY);
if (ASSETCHAINS_ALGO == ASSETCHAINS_VERUSHASH || ASSETCHAINS_ALGO == ASSETCHAINS_VERUSHASHV2)
if (ASSETCHAINS_ALGO == ASSETCHAINS_VERUSHASH)
{
// this is only good for 60 second blocks with an averaging window of 45. for other parameters, use:
// nLwmaAjustedWeight = (N+1)/2 * (0.9989^(500/nPowAveragingWindow)) * nPowTargetSpacing
@@ -276,6 +276,14 @@ void *chainparams_commandline(void *ptr)
mainParams.consensus.nPowAveragingWindow = 45;
mainParams.consensus.powAlternate = uint256S("00000f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f");
}
else if (ASSETCHAINS_ALGO == ASSETCHAINS_VERUSHASHV2)
{
// this is only good for 60 second blocks with an averaging window of 45. for other parameters, use:
// nLwmaAjustedWeight = (N+1)/2 * (0.9989^(500/nPowAveragingWindow)) * nPowTargetSpacing
mainParams.consensus.nLwmaAjustedWeight = 1350;
mainParams.consensus.nPowAveragingWindow = 45;
mainParams.consensus.powAlternate = uint256S("000000ff0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f");
}
if (ASSETCHAINS_LWMAPOS != 0)
{

View File

@@ -1253,95 +1253,6 @@ uint32_t komodo_stakehash(uint256 *hashp,char *address,uint8_t *hashbuf,uint256
return(addrhash.uints[0]);
}
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)
{
bool fNegative,fOverflow; uint8_t hashbuf[256]; char address[64]; bits256 addrhash; arith_uint256 hashval,mindiff,ratio,coinage256; uint256 hash,pasthash; int32_t diff=0,segid,minage,i,iter=0; uint32_t txtime,segid32,winner = 0 ; uint64_t value,coinage;
txtime = komodo_txtime2(&value,txid,vout,address);
if ( validateflag == 0 )
{
//fprintf(stderr,"blocktime.%u -> ",blocktime);
if ( blocktime < prevtime+3 )
blocktime = prevtime+3;
if ( blocktime < GetAdjustedTime()-60 )
blocktime = GetAdjustedTime()+30;
//fprintf(stderr,"blocktime.%u txtime.%u\n",blocktime,txtime);
}
if ( value == 0 || txtime == 0 || blocktime == 0 || prevtime == 0 )
{
//fprintf(stderr,"komodo_stake null %.8f %u %u %u\n",dstr(value),txtime,blocktime,prevtime);
return(0);
}
if ( value < SATOSHIDEN )
return(0);
value /= SATOSHIDEN;
mindiff.SetCompact(STAKING_MIN_DIFF,&fNegative,&fOverflow);
ratio = (mindiff / bnTarget);
if ( (minage= nHeight*3) > 6000 ) // about 100 blocks
minage = 6000;
komodo_segids(hashbuf,nHeight-101,100);
segid32 = komodo_stakehash(&hash,address,hashbuf,txid,vout);
segid = ((nHeight + segid32) & 0x3f);
for (iter=0; iter<600; iter++)
{
if ( blocktime+iter+segid*2 < txtime+minage )
continue;
diff = (iter + blocktime - txtime - minage);
if ( diff < 0 )
diff = 60;
else if ( diff > 3600*24*30 )
{
//printf("diff.%d (iter.%d blocktime.%u txtime.%u minage.%d)\n",(int32_t)diff,iter,blocktime,txtime,(int32_t)minage);
diff = 3600*24*30;
}
if ( iter > 0 )
diff += segid*2;
coinage = (value * diff);
if ( ASSETCHAINS_ALGO == ASSETCHAINS_VERUSHASH || ASSETCHAINS_ALGO == ASSETCHAINS_VERUSHASHV2 )
{
if ( blocktime+iter+segid*2 > prevtime+200 )
coinage *= ((blocktime+iter+segid*2) - (prevtime+120));
}
if ( blocktime+iter+segid*2 > prevtime+480 )
coinage *= ((blocktime+iter+segid*2) - (prevtime+400));
coinage256 = arith_uint256(coinage+1);
hashval = ratio * (UintToArith256(hash) / coinage256);
if ( hashval <= bnTarget )
{
winner = 1;
if ( validateflag == 0 )
{
//fprintf(stderr,"winner blocktime.%u iter.%d segid.%d\n",blocktime,iter,segid);
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 ");
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 v%d diff.%d\n",segid,iter,winner,(long long)coinage,(int32_t)(blocktime - txtime),nHeight,blocktime,(int32_t)value,(int32_t)diff);*/
break;
}
}
//fprintf(stderr,"iterated until i.%d winner.%d\n",i,winner);
if ( 0 && validateflag != 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 v%d diff.%d ht.%d\n",segid,iter,winner,(long long)coinage,(int32_t)(blocktime - txtime),nHeight,blocktime,(int32_t)value,(int32_t)diff,nHeight);
}
if ( nHeight < 10 )
return(blocktime);
return(blocktime * winner);
}
arith_uint256 komodo_PoWtarget(int32_t *percPoSp,arith_uint256 target,int32_t height,int32_t goalperc)
{
int32_t oldflag = 0,dispflag = 1;
@@ -1380,7 +1291,17 @@ arith_uint256 komodo_PoWtarget(int32_t *percPoSp,arith_uint256 target,int32_t he
fprintf(stderr," %d, ",percPoS);
}
if ( m+n < 100 )
percPoS = ((percPoS * n) + (goalperc * (100-n))) / 100;
{
// We do actual PoS % at the start. Requires coin distribution in first 10 blocks!
if ( ASSETCHAINS_ALGO == ASSETCHAINS_VERUSHASH || ASSETCHAINS_ALGO == ASSETCHAINS_VERUSHASHV2 )
percPoS = (percPoS*100) / (m+n);
else
// This seems to be inverse. The actual PoS % is backwards in the first 100 blocks.
// I dont't understand the math here, or why its backwards, so I am just disabling it for VerusHash.
// No doubt this is probably wrong for equihash aswell, we may need to test an equihash chain with the rule above.
// Need to ask james what the deal is here! Seems to be causeing ALL the problems.
percPoS = ((percPoS * n) + (goalperc * (100-n))) / 100;
}
if ( dispflag != 0 && ASSETCHAINS_STAKED < 100 )
fprintf(stderr," -> %d%% percPoS vs goalperc.%d ht.%d\n",percPoS,goalperc,height);
*percPoSp = percPoS;
@@ -1444,9 +1365,104 @@ arith_uint256 komodo_PoWtarget(int32_t *percPoSp,arith_uint256 target,int32_t he
return(bnTarget);
}
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,int32_t PoSperc)
{
bool fNegative,fOverflow; uint8_t hashbuf[256]; char address[64]; bits256 addrhash; arith_uint256 hashval,mindiff,ratio,coinage256; uint256 hash,pasthash; int32_t diff=0,segid,minage,i,iter=0; uint32_t txtime,segid32,winner = 0 ; uint64_t value,coinage;
txtime = komodo_txtime2(&value,txid,vout,address);
if ( validateflag == 0 )
{
//fprintf(stderr,"blocktime.%u -> ",blocktime);
if ( blocktime < prevtime+3 )
blocktime = prevtime+3;
if ( blocktime < GetAdjustedTime()-60 )
blocktime = GetAdjustedTime()+30;
//fprintf(stderr,"blocktime.%u txtime.%u\n",blocktime,txtime);
}
if ( value == 0 || txtime == 0 || blocktime == 0 || prevtime == 0 )
{
//fprintf(stderr,"komodo_stake null %.8f %u %u %u\n",dstr(value),txtime,blocktime,prevtime);
return(0);
}
if ( value < SATOSHIDEN )
return(0);
value /= SATOSHIDEN;
mindiff.SetCompact(STAKING_MIN_DIFF,&fNegative,&fOverflow);
ratio = (mindiff / bnTarget);
if ( (minage= nHeight*3) > 6000 ) // about 100 blocks
minage = 6000;
komodo_segids(hashbuf,nHeight-101,100);
segid32 = komodo_stakehash(&hash,address,hashbuf,txid,vout);
segid = ((nHeight + segid32) & 0x3f);
for (iter=0; iter<600; iter++)
{
if ( blocktime+iter+segid*2 < txtime+minage )
continue;
diff = (iter + blocktime - txtime - minage);
if ( diff < 0 )
diff = 60;
else if ( diff > 3600*24*30 )
{
//printf("diff.%d (iter.%d blocktime.%u txtime.%u minage.%d)\n",(int32_t)diff,iter,blocktime,txtime,(int32_t)minage);
diff = 3600*24*30;
}
if ( iter > 0 )
diff += segid*2;
coinage = (value * diff);
if ( ASSETCHAINS_ALGO == ASSETCHAINS_VERUSHASH || ASSETCHAINS_ALGO == ASSETCHAINS_VERUSHASHV2 )
{
fprintf(stderr, "PoS % is: %i% vs. %i% \n", PoSperc, ASSETCHAINS_STAKED);
if ( PoSperc < ASSETCHAINS_STAKED )
{
// This means we are under PoS % required and we need some extra help getting an elegible utxo.
// Likley there is some math required here to make it work properly. But getting the data here is no1 priority.
coinage = coinage * 1000;
}
}
// leave this here for now...
if ( blocktime+iter+segid*2 > prevtime+480 )
coinage *= ((blocktime+iter+segid*2) - (prevtime+400));
coinage256 = arith_uint256(coinage+1);
hashval = ratio * (UintToArith256(hash) / coinage256);
if ( hashval <= bnTarget )
{
winner = 1;
if ( validateflag == 0 )
{
//fprintf(stderr,"winner blocktime.%u iter.%d segid.%d\n",blocktime,iter,segid);
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 ");
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 v%d diff.%d\n",segid,iter,winner,(long long)coinage,(int32_t)(blocktime - txtime),nHeight,blocktime,(int32_t)value,(int32_t)diff);*/
break;
}
}
//fprintf(stderr,"iterated until i.%d winner.%d\n",i,winner);
if ( 0 && validateflag != 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 v%d diff.%d ht.%d\n",segid,iter,winner,(long long)coinage,(int32_t)(blocktime - txtime),nHeight,blocktime,(int32_t)value,(int32_t)diff,nHeight);
}
if ( nHeight < 10 )
return(blocktime);
return(blocktime * winner);
}
int32_t komodo_is_PoSblock(int32_t slowflag,int32_t height,CBlock *pblock,arith_uint256 bnTarget,arith_uint256 bhash)
{
CBlockIndex *previndex,*pindex; char voutaddr[64],destaddr[64]; uint256 txid; uint32_t txtime,prevtime=0; int32_t vout,PoSperc,txn_count,eligible=0,isPoS = 0,segid; uint64_t value; CTxDestination voutaddress;
CBlockIndex *previndex,*pindex; char voutaddr[64],destaddr[64]; uint256 txid; uint32_t txtime,prevtime=0; int32_t vout,PoSperc,txn_count,eligible=0,isPoS = 0,segid; uint64_t value; CTxDestination voutaddress; arith_uint256 POWTarget;
if ( ASSETCHAINS_STAKED == 100 && height <= 100 )
return(1);
BlockMap::const_iterator it = mapBlockIndex.find(pblock->GetHash());
@@ -1457,6 +1473,8 @@ int32_t komodo_is_PoSblock(int32_t slowflag,int32_t height,CBlock *pblock,arith_
return(0);
else return(1);
}
// Get PoSperc and POW Target. for later.
POWTarget = komodo_PoWtarget(&PoSperc,bnTarget,height,ASSETCHAINS_STAKED);
txn_count = pblock->vtx.size();
if ( txn_count > 1 && pblock->vtx[txn_count-1].vin.size() == 1 && pblock->vtx[txn_count-1].vout.size() == 1 )
{
@@ -1470,7 +1488,7 @@ int32_t komodo_is_PoSblock(int32_t slowflag,int32_t height,CBlock *pblock,arith_
{
if ( komodo_isPoS(pblock) != 0 )
{
eligible = komodo_stake(1,bnTarget,height,txid,vout,pblock->nTime,prevtime+27,(char *)"");
eligible = komodo_stake(1,bnTarget,height,txid,vout,pblock->nTime,prevtime+27,(char *)"",PoSperc);
}
if ( eligible == 0 || eligible > pblock->nTime )
{
@@ -1515,8 +1533,7 @@ int32_t komodo_is_PoSblock(int32_t slowflag,int32_t height,CBlock *pblock,arith_
}
else
{
bnTarget = komodo_PoWtarget(&PoSperc,bnTarget,height,ASSETCHAINS_STAKED);
if ( bhash < bnTarget )
if ( bhash < POWTarget )
{
//fprintf(stderr,"ht.%d isPoS but meets PoW diff!\n",height);
isPoS = 0;
@@ -2085,10 +2102,11 @@ uint32_t komodo_eligible(arith_uint256 bnTarget,arith_uint256 ratio,struct komod
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)
{
static struct komodo_staking *array; static int32_t numkp,maxkp; static uint32_t lasttime;
set<CBitcoinAddress> setAddress; struct komodo_staking *kp; int32_t winners,segid,minage,nHeight,counter=0,i,m,siglen=0,nMinDepth = 1,nMaxDepth = 99999999; vector<COutput> vecOutputs; uint32_t block_from_future_rejecttime,besttime,eligible,eligible2,earliest = 0; CScript best_scriptPubKey; arith_uint256 mindiff,ratio,bnTarget; CBlockIndex *tipindex,*pindex; CTxDestination address; bool fNegative,fOverflow; uint8_t hashbuf[256]; CTransaction tx; uint256 hashBlock;
int32_t PoSperc;
set<CBitcoinAddress> setAddress; struct komodo_staking *kp; int32_t winners,segid,minage,nHeight,counter=0,i,m,siglen=0,nMinDepth = 1,nMaxDepth = 99999999; vector<COutput> vecOutputs; uint32_t block_from_future_rejecttime,besttime,eligible,eligible2,earliest = 0; CScript best_scriptPubKey; arith_uint256 mindiff,ratio,bnTarget,tmpTarget; CBlockIndex *tipindex,*pindex; CTxDestination address; bool fNegative,fOverflow; uint8_t hashbuf[256]; CTransaction tx; uint256 hashBlock;
if (!EnsureWalletIsAvailable(0))
return 0;
bnTarget.SetCompact(nBits, &fNegative, &fOverflow);
mindiff.SetCompact(STAKING_MIN_DIFF,&fNegative,&fOverflow);
ratio = (mindiff / bnTarget);
@@ -2100,6 +2118,8 @@ int32_t komodo_staked(CMutableTransaction &txNew,uint32_t nBits,uint32_t *blockt
if ( (tipindex= chainActive.Tip()) == 0 )
return(0);
nHeight = tipindex->GetHeight() + 1;
// Get the PoS% so we can pass it to komodo_stake, this is to adjust PoS dofficulty when it is under the target %!
tmpTarget = komodo_PoWtarget(&PoSperc,bnTarget,nHeight,ASSETCHAINS_STAKED);
if ( (minage= nHeight*3) > 6000 ) // about 100 blocks
minage = 6000;
komodo_segids(hashbuf,nHeight-101,100);
@@ -2119,7 +2139,7 @@ int32_t komodo_staked(CMutableTransaction &txNew,uint32_t nBits,uint32_t *blockt
}
}
if ( time(NULL) > lasttime+600 || array == 0 || resetstaker )
if ( resetstaker || array == 0 || time(NULL) > lasttime+600 )
{
LOCK2(cs_main, pwalletMain->cs_wallet);
pwalletMain->AvailableCoins(vecOutputs, false, NULL, true);
@@ -2175,14 +2195,14 @@ int32_t komodo_staked(CMutableTransaction &txNew,uint32_t nBits,uint32_t *blockt
kp = &array[i];
if ( (eligible2= komodo_eligible(bnTarget,ratio,kp,nHeight,*blocktimep,(uint32_t)tipindex->nTime+27,minage,hashbuf)) == 0 )
continue;
eligible = komodo_stake(0,bnTarget,nHeight,kp->txid,kp->vout,0,(uint32_t)tipindex->nTime+27,kp->address);
eligible = komodo_stake(0,bnTarget,nHeight,kp->txid,kp->vout,0,(uint32_t)tipindex->nTime+27,kp->address,PoSperc);
//fprintf(stderr,"i.%d %u vs %u\n",i,eligible2,eligible);
if ( eligible > 0 )
{
besttime = m = 0;
if ( eligible == komodo_stake(1,bnTarget,nHeight,kp->txid,kp->vout,eligible,(uint32_t)tipindex->nTime+27,kp->address) )
if ( eligible == komodo_stake(1,bnTarget,nHeight,kp->txid,kp->vout,eligible,(uint32_t)tipindex->nTime+27,kp->address,PoSperc) )
{
while ( eligible == komodo_stake(1,bnTarget,nHeight,kp->txid,kp->vout,eligible,(uint32_t)tipindex->nTime+27,kp->address) )
while ( eligible == komodo_stake(1,bnTarget,nHeight,kp->txid,kp->vout,eligible,(uint32_t)tipindex->nTime+27,kp->address,PoSperc) )
{
besttime = eligible;
eligible--;

View File

@@ -82,9 +82,8 @@ uint32_t ASSETCHAINS_NONCESHIFT[] = {32,16,16};
uint32_t ASSETCHAINS_HASHESPERROUND[] = {1,4096,4096};
uint32_t ASSETCHAINS_ALGO = _ASSETCHAINS_EQUIHASH;
// min diff returned from GetNextWorkRequired needs to be added here for each algo, so they can work with ac_staked.
// VerusHash v1 and 1.1 use a custom tuned number or PoW blocks all are 1s.
uint32_t ASSETCHAINS_MINDIFF[] = {537857807,486648905,486648905};
uint32_t ASSETCHAINS_MINDIFF[] = {537857807,503381775,503381775};
// ^ wrong!
// Verus proof of stake controls
int32_t ASSETCHAINS_LWMAPOS = 0; // percentage of blocks should be PoS
int32_t VERUS_BLOCK_POSUNITS = 1024; // one block is 1000 units

View File

@@ -134,6 +134,8 @@ unsigned int lwmaCalculateNextWorkRequired(const CBlockIndex* pindexLast, const
bnLimit = UintToArith256(params.powAlternate);
unsigned int nProofOfWorkLimit = bnLimit.GetCompact();
printf("PoWLimit: %u\n", nProofOfWorkLimit);
// Find the first block in the averaging interval as we total the linearly weighted average
const CBlockIndex* pindexFirst = pindexLast;