github.com/cosmos/cosmos-sdk@v0.50.10/x/mint/types/minter_test.go (about)

     1  package types
     2  
     3  import (
     4  	"math/rand"
     5  	"testing"
     6  
     7  	"github.com/stretchr/testify/require"
     8  
     9  	"cosmossdk.io/math"
    10  
    11  	sdk "github.com/cosmos/cosmos-sdk/types"
    12  )
    13  
    14  func TestNextInflation(t *testing.T) {
    15  	minter := DefaultInitialMinter()
    16  	params := DefaultParams()
    17  	blocksPerYr := math.LegacyNewDec(int64(params.BlocksPerYear))
    18  
    19  	// Governing Mechanism:
    20  	//    inflationRateChangePerYear = (1- BondedRatio/ GoalBonded) * MaxInflationRateChange
    21  
    22  	tests := []struct {
    23  		bondedRatio, setInflation, expChange math.LegacyDec
    24  	}{
    25  		// with 0% bonded atom supply the inflation should increase by InflationRateChange
    26  		{math.LegacyZeroDec(), math.LegacyNewDecWithPrec(7, 2), params.InflationRateChange.Quo(blocksPerYr)},
    27  
    28  		// 100% bonded, starting at 20% inflation and being reduced
    29  		// (1 - (1/0.67))*(0.13/8667)
    30  		{
    31  			math.LegacyOneDec(), math.LegacyNewDecWithPrec(20, 2),
    32  			math.LegacyOneDec().Sub(math.LegacyOneDec().Quo(params.GoalBonded)).Mul(params.InflationRateChange).Quo(blocksPerYr),
    33  		},
    34  
    35  		// 50% bonded, starting at 10% inflation and being increased
    36  		{
    37  			math.LegacyNewDecWithPrec(5, 1), math.LegacyNewDecWithPrec(10, 2),
    38  			math.LegacyOneDec().Sub(math.LegacyNewDecWithPrec(5, 1).Quo(params.GoalBonded)).Mul(params.InflationRateChange).Quo(blocksPerYr),
    39  		},
    40  
    41  		// test 7% minimum stop (testing with 100% bonded)
    42  		{math.LegacyOneDec(), math.LegacyNewDecWithPrec(7, 2), math.LegacyZeroDec()},
    43  		{math.LegacyOneDec(), math.LegacyNewDecWithPrec(700000001, 10), math.LegacyNewDecWithPrec(-1, 10)},
    44  
    45  		// test 20% maximum stop (testing with 0% bonded)
    46  		{math.LegacyZeroDec(), math.LegacyNewDecWithPrec(20, 2), math.LegacyZeroDec()},
    47  		{math.LegacyZeroDec(), math.LegacyNewDecWithPrec(1999999999, 10), math.LegacyNewDecWithPrec(1, 10)},
    48  
    49  		// perfect balance shouldn't change inflation
    50  		{math.LegacyNewDecWithPrec(67, 2), math.LegacyNewDecWithPrec(15, 2), math.LegacyZeroDec()},
    51  	}
    52  	for i, tc := range tests {
    53  		minter.Inflation = tc.setInflation
    54  
    55  		inflation := minter.NextInflationRate(params, tc.bondedRatio)
    56  		diffInflation := inflation.Sub(tc.setInflation)
    57  
    58  		require.True(t, diffInflation.Equal(tc.expChange),
    59  			"Test Index: %v\nDiff:  %v\nExpected: %v\n", i, diffInflation, tc.expChange)
    60  	}
    61  }
    62  
    63  func TestBlockProvision(t *testing.T) {
    64  	minter := InitialMinter(math.LegacyNewDecWithPrec(1, 1))
    65  	params := DefaultParams()
    66  
    67  	secondsPerYear := int64(60 * 60 * 8766)
    68  
    69  	tests := []struct {
    70  		annualProvisions int64
    71  		expProvisions    int64
    72  	}{
    73  		{secondsPerYear / 5, 1},
    74  		{secondsPerYear/5 + 1, 1},
    75  		{(secondsPerYear / 5) * 2, 2},
    76  		{(secondsPerYear / 5) / 2, 0},
    77  	}
    78  	for i, tc := range tests {
    79  		minter.AnnualProvisions = math.LegacyNewDec(tc.annualProvisions)
    80  		provisions := minter.BlockProvision(params)
    81  
    82  		expProvisions := sdk.NewCoin(params.MintDenom,
    83  			math.NewInt(tc.expProvisions))
    84  
    85  		require.True(t, expProvisions.IsEqual(provisions),
    86  			"test: %v\n\tExp: %v\n\tGot: %v\n",
    87  			i, tc.expProvisions, provisions)
    88  	}
    89  }
    90  
    91  // Benchmarking :)
    92  // previously using math.Int operations:
    93  // BenchmarkBlockProvision-4 5000000 220 ns/op
    94  //
    95  // using math.LegacyDec operations: (current implementation)
    96  // BenchmarkBlockProvision-4 3000000 429 ns/op
    97  func BenchmarkBlockProvision(b *testing.B) {
    98  	b.ReportAllocs()
    99  	minter := InitialMinter(math.LegacyNewDecWithPrec(1, 1))
   100  	params := DefaultParams()
   101  
   102  	s1 := rand.NewSource(100)
   103  	r1 := rand.New(s1)
   104  	minter.AnnualProvisions = math.LegacyNewDec(r1.Int63n(1000000))
   105  
   106  	// run the BlockProvision function b.N times
   107  	for n := 0; n < b.N; n++ {
   108  		minter.BlockProvision(params)
   109  	}
   110  }
   111  
   112  // Next inflation benchmarking
   113  // BenchmarkNextInflation-4 1000000 1828 ns/op
   114  func BenchmarkNextInflation(b *testing.B) {
   115  	b.ReportAllocs()
   116  	minter := InitialMinter(math.LegacyNewDecWithPrec(1, 1))
   117  	params := DefaultParams()
   118  	bondedRatio := math.LegacyNewDecWithPrec(1, 1)
   119  
   120  	// run the NextInflationRate function b.N times
   121  	for n := 0; n < b.N; n++ {
   122  		minter.NextInflationRate(params, bondedRatio)
   123  	}
   124  }
   125  
   126  // Next annual provisions benchmarking
   127  // BenchmarkNextAnnualProvisions-4 5000000 251 ns/op
   128  func BenchmarkNextAnnualProvisions(b *testing.B) {
   129  	b.ReportAllocs()
   130  	minter := InitialMinter(math.LegacyNewDecWithPrec(1, 1))
   131  	params := DefaultParams()
   132  	totalSupply := math.NewInt(100000000000000)
   133  
   134  	// run the NextAnnualProvisions function b.N times
   135  	for n := 0; n < b.N; n++ {
   136  		minter.NextAnnualProvisions(params, totalSupply)
   137  	}
   138  }