}
// select stake target limit according to hard-coded conditions
-CBigNum static GetProofOfStakeLimit(int nHeight, unsigned int nTime)
+CBigNum inline GetProofOfStakeLimit(int nHeight, unsigned int nTime)
{
if(fTestNet) // separate proof of stake target limit for testnet
return bnProofOfStakeLimit;
// miner's coin stake reward based on nBits and coin age spent (coin-days)
int64 GetProofOfStakeReward(int64 nCoinAge, unsigned int nBits, unsigned int nTime, bool bCoinYearOnly)
{
- int64 nRewardCoinYear;
+ int64 nRewardCoinYear, nSubsidy;
if(fTestNet || nTime > STAKE_SWITCH_TIME)
{
CBigNum bnTargetLimit = GetProofOfStakeLimit(0, nTime);
bnTargetLimit.SetCompact(bnTargetLimit.GetCompact());
- // NovaCoin: reward for coin-year is cut in half every 64x multiply of PoS difficulty
- // A reasonably continuous curve is used to avoid shock to market
- // (nRewardCoinYearLimit / nRewardCoinYear) ** 6 == bnProofOfStakeLimit / bnTarget
- //
- // Human readable form:
- //
- // nRewardCoinYear = 1 / (posdiff ^ 1/6)
+ // NovaCoin: A reasonably continuous curve is used to avoid shock to market
+
+ CBigNum bnLowerBound = 1 * CENT, // Lower interest bound is 1% per year
+ bnUpperBound = bnRewardCoinYearLimit, // Upper interest bound is 100% per year
+ bnMidPart, bnRewardPart;
- CBigNum bnLowerBound = 1 * CENT; // Lower interest bound is 1% per year
- CBigNum bnUpperBound = bnRewardCoinYearLimit;
while (bnLowerBound + CENT <= bnUpperBound)
{
CBigNum bnMidValue = (bnLowerBound + bnUpperBound) / 2;
if (fDebug && GetBoolArg("-printcreation"))
printf("GetProofOfStakeReward() : lower=%"PRI64d" upper=%"PRI64d" mid=%"PRI64d"\n", bnLowerBound.getuint64(), bnUpperBound.getuint64(), bnMidValue.getuint64());
- if (bnMidValue * bnMidValue * bnMidValue * bnMidValue * bnMidValue * bnMidValue * bnTargetLimit > bnRewardCoinYearLimit * bnRewardCoinYearLimit * bnRewardCoinYearLimit * bnRewardCoinYearLimit * bnRewardCoinYearLimit * bnRewardCoinYearLimit * bnTarget)
+
+ if(!fTestNet && nTime < STAKECURVE_SWITCH_TIME)
+ {
+ //
+ // Until 20 Oct 2013: reward for coin-year is cut in half every 64x multiply of PoS difficulty
+ //
+ // (nRewardCoinYearLimit / nRewardCoinYear) ** 6 == bnProofOfStakeLimit / bnTarget
+ //
+ // Human readable form: nRewardCoinYear = 1 / (posdiff ^ 1/6)
+ //
+
+ bnMidPart = bnMidValue * bnMidValue * bnMidValue * bnMidValue * bnMidValue * bnMidValue * bnTargetLimit;
+ bnRewardPart = bnRewardCoinYearLimit * bnRewardCoinYearLimit * bnRewardCoinYearLimit * bnRewardCoinYearLimit * bnRewardCoinYearLimit * bnRewardCoinYearLimit * bnTarget;
+ }
+ else
+ {
+ //
+ // Since 20 Oct 2013: reward for coin-year is cut in half every 8x multiply of PoS difficulty
+ //
+ // (nRewardCoinYearLimit / nRewardCoinYear) ** 3 == bnProofOfStakeLimit / bnTarget
+ //
+ // Human readable form: nRewardCoinYear = 1 / (posdiff ^ 1/3)
+ //
+
+ bnMidPart = bnMidValue * bnMidValue * bnMidValue * bnTargetLimit;
+ bnRewardPart = bnRewardCoinYearLimit * bnRewardCoinYearLimit * bnRewardCoinYearLimit * bnTarget;
+ }
+
+ if (bnMidPart > bnRewardPart)
bnUpperBound = bnMidValue;
else
bnLowerBound = bnMidValue;
if(bCoinYearOnly)
return nRewardCoinYear;
- int64 nSubsidy = nCoinAge * 33 / (365 * 33 + 8) * nRewardCoinYear;
+ // Fix problem with proof-of-stake rewards calculation since 20 Sep 2013
+ if(nTime < CHAINCHECKS_SWITCH_TIME)
+ nSubsidy = nCoinAge * 33 / (365 * 33 + 8) * nRewardCoinYear;
+ else
+ nSubsidy = nCoinAge * nRewardCoinYear * 33 / (365 * 33 + 8);
if (fDebug && GetBoolArg("-printcreation"))
printf("GetProofOfStakeReward(): create=%s nCoinAge=%"PRI64d" nBits=%d\n", FormatMoney(nSubsidy).c_str(), nCoinAge, nBits);
static const int64 nTargetTimespan = 7 * 24 * 60 * 60; // one week
// get proof of work blocks max spacing according to hard-coded conditions
-int64 static GetTargetSpacingWorkMax(int nHeight, unsigned int nTime)
+int64 inline GetTargetSpacingWorkMax(int nHeight, unsigned int nTime)
{
if(nTime > TARGETS_SWITCH_TIME)
return 3 * nStakeTargetSpacing; // 30 minutes on mainNet since 20 Jul 2013 00:00:00