diff --git a/data/bookkeeping/block_test.go b/data/bookkeeping/block_test.go index 14d75e437c..a60ca210c9 100644 --- a/data/bookkeeping/block_test.go +++ b/data/bookkeeping/block_test.go @@ -461,3 +461,65 @@ func TestInitialRewardsRateCalculation(t *testing.T) { consensusParams.InitialRewardsRateCalculation = true require.True(t, runTest()) } + +func performRewardsRateCalculation( + t *testing.T, consensusParams config.ConsensusParams, + curRewardsState RewardsState, + incentivePoolBalance uint64, totalRewardUnits uint64, startingRound uint64) { + require.GreaterOrEqual(t, incentivePoolBalance, consensusParams.MinBalance) + + for rnd := startingRound; rnd < startingRound+uint64(consensusParams.RewardsRateRefreshInterval)*3; rnd++ { + nextRewardState := curRewardsState.NextRewardsState(basics.Round(rnd), consensusParams, basics.MicroAlgos{Raw: incentivePoolBalance}, totalRewardUnits) + // adjust the incentive pool balance + var ot basics.OverflowTracker + + // get number of rewards per unit + rewardsPerUnit := ot.Sub(nextRewardState.RewardsLevel, curRewardsState.RewardsLevel) + require.False(t, ot.Overflowed) + + // subtract the total dispersed funds from the pool balance + incentivePoolBalance = ot.Sub(incentivePoolBalance, ot.Mul(totalRewardUnits, rewardsPerUnit)) + require.False(t, ot.Overflowed) + + require.GreaterOrEqual(t, incentivePoolBalance, consensusParams.MinBalance) + // prepare for the next iteration + curRewardsState = nextRewardState + } +} + +// TestInitialRewardsRateCalculationRealValues performs a similar to test for initial rewards calculations but uses +// real values taken from mainnet +func TestInitialRewardsRateCalculationRealValues(t *testing.T) { + partitiontest.PartitionTest(t) + + tests := []struct { + name string + rewardsRate uint64 + rewardsLevel uint64 + rewardsResidue uint64 + rewardsRecalculationRound basics.Round + incentivePoolBalance uint64 + totalRewardUnits uint64 + startingRound uint64 + }{ + // Real values gathered from mainnet + {"1", 0, 215332, 0, 18500000, config.Consensus[protocol.ConsensusCurrentVersion].MinBalance, 6756334087, 18063999}, + {"2", 24000000, 215332, 545321700, 18500000, 10464550021728, 6756334087, 18063999}, + {"3", 24000000, 215332, 521321700, 18500000, 10464550021728, 6756334078, 18063998}, + {"4", 24000000, 215332, 401321700, 18500000, 10464550021728, 6756334079, 18063994}, + } + for _, test := range tests { + t.Run(test.name, func(t *testing.T) { + consensusParams := config.Consensus[protocol.ConsensusCurrentVersion] + + curRewardsState := RewardsState{ + RewardsLevel: test.rewardsLevel, + RewardsResidue: test.rewardsResidue, + RewardsRecalculationRound: test.rewardsRecalculationRound, + RewardsRate: test.rewardsRate, + } + + performRewardsRateCalculation(t, consensusParams, curRewardsState, test.incentivePoolBalance, test.totalRewardUnits, test.startingRound) + }) + } +}