Skip to content

Commit 139a4b8

Browse files
make block reward not depend on difficulty
1 parent 33115e3 commit 139a4b8

5 files changed

Lines changed: 21 additions & 129 deletions

File tree

src/main.cpp

Lines changed: 12 additions & 119 deletions
Original file line numberDiff line numberDiff line change
@@ -952,132 +952,25 @@ CBigNum inline GetProofOfStakeLimit(int nHeight, unsigned int nTime)
952952
return bnProofOfWorkLimit; // return bnProofOfWorkLimit of none matched
953953
}
954954

955-
// miner's coin base reward based on nBits
956-
int64 GetProofOfWorkReward(unsigned int nBits)
955+
// miner's coin base reward
956+
int64 GetProofOfWorkReward()
957957
{
958-
CBigNum bnSubsidyLimit = MAX_MINT_PROOF_OF_WORK;
958+
int64 nSubsidy = 10000 * COIN;
959959

960-
CBigNum bnTarget;
961-
bnTarget.SetCompact(nBits);
962-
CBigNum bnTargetLimit = bnProofOfWorkLimit;
963-
bnTargetLimit.SetCompact(bnTargetLimit.GetCompact());
964-
965-
// NovaCoin: subsidy is cut in half every 64x multiply of PoW difficulty
966-
// A reasonably continuous curve is used to avoid shock to market
967-
// (nSubsidyLimit / nSubsidy) ** 6 == bnProofOfWorkLimit / bnTarget
968-
//
969-
// Human readable form:
970-
//
971-
// nSubsidy = 100 / (diff ^ 1/6)
972-
CBigNum bnLowerBound = CENT;
973-
CBigNum bnUpperBound = bnSubsidyLimit;
974-
while (bnLowerBound + CENT <= bnUpperBound)
975-
{
976-
CBigNum bnMidValue = (bnLowerBound + bnUpperBound) / 2;
977-
if (fDebug && GetBoolArg("-printcreation"))
978-
printf("GetProofOfWorkReward() : lower=%"PRI64d" upper=%"PRI64d" mid=%"PRI64d"\n", bnLowerBound.getuint64(), bnUpperBound.getuint64(), bnMidValue.getuint64());
979-
if (bnMidValue * bnMidValue * bnMidValue * bnMidValue * bnMidValue * bnMidValue * bnTargetLimit > bnSubsidyLimit * bnSubsidyLimit * bnSubsidyLimit * bnSubsidyLimit * bnSubsidyLimit * bnSubsidyLimit * bnTarget)
980-
bnUpperBound = bnMidValue;
981-
else
982-
bnLowerBound = bnMidValue;
983-
}
984-
985-
int64 nSubsidy = bnUpperBound.getuint64();
986-
987-
nSubsidy = (nSubsidy / CENT) * CENT;
988960
if (fDebug && GetBoolArg("-printcreation"))
989-
printf("GetProofOfWorkReward() : create=%s nBits=0x%08x nSubsidy=%"PRI64d"\n", FormatMoney(nSubsidy).c_str(), nBits, nSubsidy);
961+
printf("GetProofOfWorkReward() : create=%s nSubsidy=%"PRI64d"\n", FormatMoney(nSubsidy).c_str(), nSubsidy);
990962

991-
return min(nSubsidy, MAX_MINT_PROOF_OF_WORK);
963+
return nSubsidy;
992964
}
993965

994-
// miner's coin stake reward based on nBits and coin age spent (coin-days)
995-
int64 GetProofOfStakeReward(int64 nCoinAge, unsigned int nBits, unsigned int nTime, bool bCoinYearOnly)
966+
// miner's coin stake reward based on coin age spent (coin-days)
967+
int64 GetProofOfStakeReward(int64 nCoinAge)
996968
{
997-
int64 nRewardCoinYear, nSubsidy, nSubsidyLimit = 10 * COIN;
998-
999-
if(fTestNet || nTime > STAKE_SWITCH_TIME)
1000-
{
1001-
// Stage 2 of emission process is PoS-based. It will be active on mainNet since 20 Jun 2013.
1002-
1003-
CBigNum bnRewardCoinYearLimit = MAX_MINT_PROOF_OF_STAKE; // Base stake mint rate, 100% year interest
1004-
CBigNum bnTarget;
1005-
bnTarget.SetCompact(nBits);
1006-
CBigNum bnTargetLimit = GetProofOfStakeLimit(0, nTime);
1007-
bnTargetLimit.SetCompact(bnTargetLimit.GetCompact());
1008-
1009-
// NovaCoin: A reasonably continuous curve is used to avoid shock to market
1010-
1011-
CBigNum bnLowerBound = 1 * CENT, // Lower interest bound is 1% per year
1012-
bnUpperBound = bnRewardCoinYearLimit, // Upper interest bound is 100% per year
1013-
bnMidPart, bnRewardPart;
1014-
1015-
while (bnLowerBound + CENT <= bnUpperBound)
1016-
{
1017-
CBigNum bnMidValue = (bnLowerBound + bnUpperBound) / 2;
1018-
if (fDebug && GetBoolArg("-printcreation"))
1019-
printf("GetProofOfStakeReward() : lower=%"PRI64d" upper=%"PRI64d" mid=%"PRI64d"\n", bnLowerBound.getuint64(), bnUpperBound.getuint64(), bnMidValue.getuint64());
1020-
1021-
if(!fTestNet && nTime < STAKECURVE_SWITCH_TIME)
1022-
{
1023-
//
1024-
// Until 20 Oct 2013: reward for coin-year is cut in half every 64x multiply of PoS difficulty
1025-
//
1026-
// (nRewardCoinYearLimit / nRewardCoinYear) ** 6 == bnProofOfStakeLimit / bnTarget
1027-
//
1028-
// Human readable form: nRewardCoinYear = 1 / (posdiff ^ 1/6)
1029-
//
1030-
1031-
bnMidPart = bnMidValue * bnMidValue * bnMidValue * bnMidValue * bnMidValue * bnMidValue;
1032-
bnRewardPart = bnRewardCoinYearLimit * bnRewardCoinYearLimit * bnRewardCoinYearLimit * bnRewardCoinYearLimit * bnRewardCoinYearLimit * bnRewardCoinYearLimit;
1033-
}
1034-
else
1035-
{
1036-
//
1037-
// Since 20 Oct 2013: reward for coin-year is cut in half every 8x multiply of PoS difficulty
1038-
//
1039-
// (nRewardCoinYearLimit / nRewardCoinYear) ** 3 == bnProofOfStakeLimit / bnTarget
1040-
//
1041-
// Human readable form: nRewardCoinYear = 1 / (posdiff ^ 1/3)
1042-
//
1043-
1044-
bnMidPart = bnMidValue * bnMidValue * bnMidValue;
1045-
bnRewardPart = bnRewardCoinYearLimit * bnRewardCoinYearLimit * bnRewardCoinYearLimit;
1046-
}
1047-
1048-
if (bnMidPart * bnTargetLimit > bnRewardPart * bnTarget)
1049-
bnUpperBound = bnMidValue;
1050-
else
1051-
bnLowerBound = bnMidValue;
1052-
}
1053-
1054-
nRewardCoinYear = bnUpperBound.getuint64();
1055-
nRewardCoinYear = min((nRewardCoinYear / CENT) * CENT, MAX_MINT_PROOF_OF_STAKE);
1056-
}
1057-
else
1058-
{
1059-
// Old creation amount per coin-year, 5% fixed stake mint rate
1060-
nRewardCoinYear = 5 * CENT;
1061-
}
1062-
1063-
if(bCoinYearOnly)
1064-
return nRewardCoinYear;
1065-
1066-
nSubsidy = nCoinAge * nRewardCoinYear * 33 / (365 * 33 + 8);
1067-
1068-
// Set reasonable reward limit for large inputs since 20 Oct 2013
1069-
//
1070-
// This will stimulate large holders to use smaller inputs, that's good for the network protection
1071-
if(fTestNet || STAKECURVE_SWITCH_TIME < nTime)
1072-
{
1073-
if (fDebug && GetBoolArg("-printcreation") && nSubsidyLimit < nSubsidy)
1074-
printf("GetProofOfStakeReward(): %s is greater than %s, coinstake reward will be truncated\n", FormatMoney(nSubsidy).c_str(), FormatMoney(nSubsidyLimit).c_str());
1075-
1076-
nSubsidy = min(nSubsidy, nSubsidyLimit);
1077-
}
969+
int64 nSubsidy = nCoinAge * COIN_YEAR_REWARD * 33 / (365 * 33 + 8);
1078970

1079971
if (fDebug && GetBoolArg("-printcreation"))
1080-
printf("GetProofOfStakeReward(): create=%s nCoinAge=%"PRI64d" nBits=%d\n", FormatMoney(nSubsidy).c_str(), nCoinAge, nBits);
972+
printf("GetProofOfStakeReward(): create=%s nCoinAge=%"PRI64d"\n", FormatMoney(nSubsidy).c_str(), nCoinAge);
973+
1081974
return nSubsidy;
1082975
}
1083976

@@ -1489,7 +1382,7 @@ bool CTransaction::ConnectInputs(CTxDB& txdb, MapPrevTx inputs, map<uint256, CTx
14891382
return error("ConnectInputs() : %s unable to get coin age for coinstake", GetHash().ToString().substr(0,10).c_str());
14901383

14911384
int64 nStakeReward = GetValueOut() - nValueIn;
1492-
int64 nCalculatedStakeReward = GetProofOfStakeReward(nCoinAge, pindexBlock->nBits, nTime) - GetMinFee() + MIN_TX_FEE;
1385+
int64 nCalculatedStakeReward = GetProofOfStakeReward(nCoinAge) - GetMinFee() + MIN_TX_FEE;
14931386

14941387
if (nStakeReward > nCalculatedStakeReward)
14951388
return DoS(100, error("ConnectInputs() : coinstake pays too much(actual=%"PRI64d" vs calculated=%"PRI64d")", nStakeReward, nCalculatedStakeReward));
@@ -2156,7 +2049,7 @@ bool CBlock::CheckBlock(bool fCheckPOW, bool fCheckMerkleRoot, bool fCheckSig) c
21562049
}
21572050
else
21582051
{
2159-
int64 nReward = GetProofOfWorkReward(nBits);
2052+
int64 nReward = GetProofOfWorkReward();
21602053
// Check coinbase reward
21612054
if (vtx[0].GetValueOut() > nReward)
21622055
return DoS(50, error("CheckBlock() : coinbase reward exceeded (actual=%"PRI64d" vs calculated=%"PRI64d")",

src/main.h

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -34,8 +34,7 @@ static const unsigned int MAX_INV_SZ = 50000;
3434
static const int64 MIN_TX_FEE = CENT;
3535
static const int64 MIN_RELAY_TX_FEE = CENT;
3636
static const int64 MAX_MONEY = 2000000000 * COIN;
37-
static const int64 MAX_MINT_PROOF_OF_WORK = 100 * COIN;
38-
static const int64 MAX_MINT_PROOF_OF_STAKE = 1 * COIN;
37+
static const int64 COIN_YEAR_REWARD = 1 * CENT; // 1% per year
3938

4039
static const unsigned int ENTROPY_SWITCH_TIME = 1362791041; // Sat, 09 Mar 2013 01:04:01 GMT
4140
static const unsigned int STAKE_SWITCH_TIME = 1371686400; // Thu, 20 Jun 2013 00:00:00 GMT
@@ -117,8 +116,8 @@ bool LoadExternalBlockFile(FILE* fileIn);
117116

118117
bool CheckProofOfWork(uint256 hash, unsigned int nBits);
119118
unsigned int GetNextTargetRequired(const CBlockIndex* pindexLast, bool fProofOfStake);
120-
int64 GetProofOfWorkReward(unsigned int nBits);
121-
int64 GetProofOfStakeReward(int64 nCoinAge, unsigned int nBits, unsigned int nTime, bool bCoinYearOnly=false);
119+
int64 GetProofOfWorkReward();
120+
int64 GetProofOfStakeReward(int64 nCoinAge);
122121
unsigned int ComputeMinWork(unsigned int nBase, int64 nTime);
123122
unsigned int ComputeMinStake(unsigned int nBase, int64 nTime, unsigned int nBlockTime);
124123
int GetNumBlocksOfPeers();

src/miner.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -355,7 +355,7 @@ CBlock* CreateNewBlock(CWallet* pwallet, bool fProofOfStake)
355355
printf("CreateNewBlock(): total size %"PRI64u"\n", nBlockSize);
356356

357357
if (!fProofOfStake)
358-
pblock->vtx[0].vout[0].nValue = GetProofOfWorkReward(pblock->nBits);
358+
pblock->vtx[0].vout[0].nValue = GetProofOfWorkReward();
359359

360360
// Fill in header
361361
pblock->hashPrevBlock = pindexPrev->GetBlockHash();

src/rpcmining.cpp

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -32,7 +32,7 @@ Value getsubsidy(const Array& params, bool fHelp)
3232
nBits = GetNextTargetRequired(pindexBest, false);
3333
}
3434

35-
return (uint64_t)GetProofOfWorkReward(nBits);
35+
return (uint64_t)GetProofOfWorkReward();
3636
}
3737

3838
Value getmininginfo(const Array& params, bool fHelp)
@@ -55,7 +55,7 @@ Value getmininginfo(const Array& params, bool fHelp)
5555
diff.push_back(Pair("search-interval", (int)nLastCoinStakeSearchInterval));
5656
obj.push_back(Pair("difficulty", diff));
5757

58-
obj.push_back(Pair("blockvalue", (uint64_t)GetProofOfWorkReward(GetLastBlockIndex(pindexBest, false)->nBits)));
58+
obj.push_back(Pair("blockvalue", (uint64_t)GetProofOfWorkReward()));
5959
obj.push_back(Pair("netmhashps", GetPoWMHashPS()));
6060
obj.push_back(Pair("netstakeweight", GetPoSKernelPS()));
6161
obj.push_back(Pair("errors", GetWarnings("statusbar")));
@@ -66,7 +66,7 @@ Value getmininginfo(const Array& params, bool fHelp)
6666
weight.push_back(Pair("combined", (uint64_t)nWeight));
6767
obj.push_back(Pair("stakeweight", weight));
6868

69-
obj.push_back(Pair("stakeinterest", (uint64_t)GetProofOfStakeReward(0, GetLastBlockIndex(pindexBest, true)->nBits, GetLastBlockIndex(pindexBest, true)->nTime, true)));
69+
obj.push_back(Pair("stakeinterest", (uint64_t)COIN_YEAR_REWARD));
7070
obj.push_back(Pair("testnet", fTestNet));
7171
return obj;
7272
}

src/wallet.cpp

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1552,7 +1552,7 @@ bool CWallet::CreateCoinStake(const CKeyStore& keystore, unsigned int nBits, int
15521552
{
15531553
// The following combine threshold is important to security
15541554
// Should not be adjusted if you don't understand the consequences
1555-
int64 nCombineThreshold = GetProofOfWorkReward(GetLastBlockIndex(pindexBest, false)->nBits) / 3;
1555+
int64 nCombineThreshold = GetProofOfWorkReward() / 3;
15561556

15571557
CBigNum bnTargetPerCoinDay;
15581558
bnTargetPerCoinDay.SetCompact(nBits);
@@ -1751,7 +1751,7 @@ bool CWallet::CreateCoinStake(const CKeyStore& keystore, unsigned int nBits, int
17511751
CTxDB txdb("r");
17521752
if (!txNew.GetCoinAge(txdb, nCoinAge))
17531753
return error("CreateCoinStake : failed to calculate coin age");
1754-
nCredit += GetProofOfStakeReward(nCoinAge, nBits, txNew.nTime);
1754+
nCredit += GetProofOfStakeReward(nCoinAge);
17551755
}
17561756

17571757
int64 nMinFee = 0;

0 commit comments

Comments
 (0)