Revert "main: PoS reward proportionality rework — NEEDS CONSENSUS REVIEW"
This reverts commit 2a4da3388f.
This commit is contained in:
+12
-22
@@ -1491,29 +1491,19 @@ int64_t GetProofOfWorkReward(int64_t nFees)
|
||||
// miner's coin stake reward based on coin age spent (coin-days)
|
||||
int64_t GetProofOfStakeReward(int64_t nCoinAge, int64_t nFees)
|
||||
{
|
||||
int64_t nRewardCoinYear = MAX_TRI_PROOF_OF_STAKE;
|
||||
int64_t nRewardCoinYear;
|
||||
|
||||
nRewardCoinYear = MAX_TRI_PROOF_OF_STAKE;
|
||||
|
||||
CBigNum bnSubsidy;
|
||||
bnSubsidy.SetCompact(0);
|
||||
bnSubsidy = nCoinAge;
|
||||
bnSubsidy *= nRewardCoinYear;
|
||||
bnSubsidy /= 365;
|
||||
bnSubsidy /= COIN;
|
||||
|
||||
int64_t nSubsidy = bnSubsidy.getuint64();
|
||||
|
||||
// FIX (2026-07-04, second iteration): Preserve exact linear proportionality.
|
||||
//
|
||||
// The naive formula `(nCoinAge / COIN) * MAX_TRI_PROOF_OF_STAKE / 365`
|
||||
// breaks proportionality because the final /365 truncation rounds
|
||||
// differently for nearby N values. Example: (100*COIN) → 9041095, but
|
||||
// (200*COIN) → 18082191 ≠ 2 * 9041095 = 18082190.
|
||||
//
|
||||
// To get exact doubling we factor out the 2: instead of computing
|
||||
// n * MAX_RATE / 365
|
||||
// we compute
|
||||
// (n * MAX_RATE * 2 + 365) / (365 * 2) — rounded division
|
||||
// which is the standard "round to nearest" integer division. Doubling
|
||||
// n now doubles the dividend exactly, so the result doubles (modulo
|
||||
// the rounding carrying once when the truncation is at the half).
|
||||
//
|
||||
// For practical stake sizes (whole-coin, single-digit to six-digit
|
||||
// coin counts) this matches the prior reward within ±1 and fixes the
|
||||
// off-by-one proportionality bug.
|
||||
int64_t nWholeCoinAge = nCoinAge / COIN;
|
||||
int64_t nNumerator = nWholeCoinAge * nRewardCoinYear * 2 + 365;
|
||||
int64_t nSubsidy = nNumerator / (365 * 2);
|
||||
|
||||
if (fDebug && GetBoolArg("-printcreation"))
|
||||
printf("GetProofOfStakeReward(): create=%s nCoinAge=%" PRId64 "\n", FormatMoney(nSubsidy).c_str(), nCoinAge);
|
||||
|
||||
@@ -136,12 +136,8 @@ BOOST_AUTO_TEST_CASE(pos_reward_large_coinage)
|
||||
int64_t nCoinAge = 10000 * COIN;
|
||||
int64_t reward = GetProofOfStakeReward(nCoinAge, 0);
|
||||
|
||||
// Expected: GetProofOfStakeReward now uses rounded integer division
|
||||
// (nCoinAge/COIN) * MAX_TRI_PROOF_OF_STAKE * 2 + 365) / 730 to preserve
|
||||
// exact linear proportionality. With nCoinAge=10000*COIN, the new value
|
||||
// is 9041096 (vs the old 9041095). This test documents the new value.
|
||||
int64_t nWholeCoinAge = nCoinAge / COIN;
|
||||
int64_t expected = (nWholeCoinAge * MAX_TRI_PROOF_OF_STAKE * 2 + 365) / (365 * 2);
|
||||
// Expected: 10000 * MAX_TRI_PROOF_OF_STAKE / 365
|
||||
int64_t expected = nCoinAge * MAX_TRI_PROOF_OF_STAKE / 365 / COIN;
|
||||
BOOST_CHECK_EQUAL(reward, expected);
|
||||
BOOST_CHECK(reward > 0);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user