From d3fc4bec60f47fd83ec672995177cf6833895bfe Mon Sep 17 00:00:00 2001 From: dimiandre Date: Wed, 24 Aug 2022 23:28:12 +0200 Subject: [PATCH 01/13] Update mint module * Halving time now is based on the total supply instead of fixed blocks per year param. * Better round block provisions during phase changes --- proto/juno/mint/mint.proto | 5 ++ x/mint/abci.go | 16 ++++-- x/mint/types/mint.pb.go | 99 ++++++++++++++++++++++++++++---------- x/mint/types/minter.go | 14 ++++-- 4 files changed, 102 insertions(+), 32 deletions(-) diff --git a/proto/juno/mint/mint.proto b/proto/juno/mint/mint.proto index f6892a7da..3184ad927 100644 --- a/proto/juno/mint/mint.proto +++ b/proto/juno/mint/mint.proto @@ -18,6 +18,11 @@ message Minter { (gogoproto.customtype) = "github.com/cosmos/cosmos-sdk/types.Dec", (gogoproto.nullable) = false ]; + string target_supply = 5 [ + (gogoproto.moretags) = "yaml:\"target_supply\"", + (gogoproto.customtype) = "github.com/cosmos/cosmos-sdk/types.Int", + (gogoproto.nullable) = false + ]; } // Params holds parameters for the mint module. diff --git a/x/mint/abci.go b/x/mint/abci.go index 15096f844..82589d3e7 100644 --- a/x/mint/abci.go +++ b/x/mint/abci.go @@ -21,21 +21,31 @@ func BeginBlocker(ctx sdk.Context, k keeper.Keeper) { return } + logger := k.Logger(ctx) + // fetch stored params params := k.GetParams(ctx) currentBlock := uint64(ctx.BlockHeight()) - nextPhase := minter.NextPhase(params, currentBlock) + // fetch current total supply + totalSupply := k.TokenSupply(ctx, params.MintDenom) + + // check if we need to change phase + nextPhase := minter.NextPhase(params, totalSupply) + + logger.Debug("New Block", "Height", ctx.BlockHeight(), "Current Total Supply", totalSupply, "Current Phase", minter.Phase) if nextPhase != minter.Phase { // store new inflation rate by phase newInflation := minter.PhaseInflationRate(nextPhase) - totalSupply := k.TokenSupply(ctx, params.MintDenom) minter.Inflation = newInflation minter.Phase = nextPhase minter.StartPhaseBlock = currentBlock minter.AnnualProvisions = minter.NextAnnualProvisions(params, totalSupply) + minter.TargetSupply = totalSupply.Add(minter.AnnualProvisions.TruncateInt()) k.SetMinter(ctx, minter) + logger.Info("New inflation phase started!", "Current Supply", totalSupply, "Target Supply", minter.TargetSupply, "Annual Provisions", minter.AnnualProvisions, "Height", ctx.BlockHeight()) + // inflation phase end if minter.Inflation.Equal(sdk.ZeroDec()) { return @@ -43,7 +53,7 @@ func BeginBlocker(ctx sdk.Context, k keeper.Keeper) { } // mint coins, update supply - mintedCoin := minter.BlockProvision(params) + mintedCoin := minter.BlockProvision(params, totalSupply) mintedCoins := sdk.NewCoins(mintedCoin) err := k.MintCoins(ctx, mintedCoins) diff --git a/x/mint/types/mint.pb.go b/x/mint/types/mint.pb.go index f852ffa89..3626f0ffb 100644 --- a/x/mint/types/mint.pb.go +++ b/x/mint/types/mint.pb.go @@ -32,6 +32,7 @@ type Minter struct { StartPhaseBlock uint64 `protobuf:"varint,3,opt,name=start_phase_block,json=startPhaseBlock,proto3" json:"start_phase_block,omitempty" yaml:"start_phase_block"` // current annual expected provisions AnnualProvisions github_com_cosmos_cosmos_sdk_types.Dec `protobuf:"bytes,4,opt,name=annual_provisions,json=annualProvisions,proto3,customtype=github.com/cosmos/cosmos-sdk/types.Dec" json:"annual_provisions" yaml:"annual_provisions"` + TargetSupply github_com_cosmos_cosmos_sdk_types.Int `protobuf:"bytes,5,opt,name=target_supply,json=targetSupply,proto3,customtype=github.com/cosmos/cosmos-sdk/types.Int" json:"target_supply" yaml:"target_supply"` } func (m *Minter) Reset() { *m = Minter{} } @@ -143,31 +144,33 @@ func init() { func init() { proto.RegisterFile("juno/mint/mint.proto", fileDescriptor_e0bccce3b583aa44) } var fileDescriptor_e0bccce3b583aa44 = []byte{ - // 371 bytes of a gzipped FileDescriptorProto - 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0x94, 0x92, 0xcf, 0x4a, 0xc3, 0x30, - 0x1c, 0xc7, 0xdb, 0x39, 0x07, 0x0d, 0xc8, 0x5c, 0x19, 0x52, 0x86, 0xb6, 0xa3, 0x07, 0xd9, 0x41, - 0xdb, 0x83, 0xb7, 0x1d, 0xbb, 0x21, 0x22, 0x0a, 0xa5, 0x37, 0xbd, 0x94, 0xac, 0x8b, 0x5b, 0x5d, - 0x9b, 0xd4, 0x24, 0x53, 0xf7, 0x16, 0x1e, 0x3d, 0xfa, 0x06, 0xbe, 0xc6, 0x8e, 0x3b, 0x8a, 0x87, - 0x22, 0xdb, 0x1b, 0xec, 0x09, 0x24, 0x89, 0x30, 0x71, 0x27, 0x2f, 0x49, 0x7e, 0x1f, 0xbe, 0xfc, - 0xfe, 0x7c, 0xf3, 0x03, 0xcd, 0xfb, 0x29, 0x26, 0x7e, 0x9e, 0x62, 0x2e, 0x0f, 0xaf, 0xa0, 0x84, - 0x13, 0xd3, 0x10, 0xd4, 0x13, 0xa0, 0xd5, 0x1c, 0x91, 0x11, 0x91, 0xd4, 0x17, 0x2f, 0x25, 0x70, - 0xdf, 0x2b, 0xa0, 0x76, 0x9d, 0x62, 0x8e, 0xa8, 0x79, 0x05, 0x8c, 0x14, 0xdf, 0x65, 0x90, 0xa7, - 0x04, 0x5b, 0x7a, 0x5b, 0xef, 0x18, 0x81, 0x37, 0x2f, 0x1d, 0xed, 0xb3, 0x74, 0x8e, 0x47, 0x29, - 0x1f, 0x4f, 0x07, 0x5e, 0x42, 0x72, 0x3f, 0x21, 0x2c, 0x27, 0xec, 0xe7, 0x3a, 0x65, 0xc3, 0x89, - 0xcf, 0x67, 0x05, 0x62, 0x5e, 0x1f, 0x25, 0xd1, 0x26, 0x81, 0xd9, 0x04, 0xbb, 0xc5, 0x18, 0x32, - 0x64, 0x55, 0xda, 0x7a, 0xa7, 0x1a, 0xa9, 0xc0, 0xbc, 0x00, 0x0d, 0xc6, 0x21, 0xe5, 0xb1, 0x0c, - 0xe3, 0x41, 0x46, 0x92, 0x89, 0xb5, 0x23, 0x14, 0xc1, 0xe1, 0xba, 0x74, 0xac, 0x19, 0xcc, 0xb3, - 0xae, 0xbb, 0x25, 0x71, 0xa3, 0xba, 0x64, 0xa1, 0x40, 0x81, 0x20, 0xe6, 0x13, 0x68, 0x40, 0x8c, - 0xa7, 0x30, 0x8b, 0x0b, 0x4a, 0x1e, 0x53, 0x96, 0x12, 0xcc, 0xac, 0xaa, 0xec, 0xfa, 0xf2, 0x7f, - 0x5d, 0x6f, 0xea, 0x6e, 0x25, 0x74, 0xa3, 0x7d, 0xc5, 0xc2, 0x0d, 0x7a, 0x00, 0xb5, 0x10, 0x52, - 0x98, 0x33, 0xf3, 0x08, 0x00, 0xe1, 0x6c, 0x3c, 0x44, 0x98, 0xe4, 0xca, 0xb1, 0xc8, 0x10, 0xa4, - 0x2f, 0x80, 0x19, 0x80, 0xba, 0x6c, 0x9e, 0xc5, 0x05, 0xa2, 0xf1, 0x0c, 0x41, 0xaa, 0xbc, 0x08, - 0x5a, 0xeb, 0xd2, 0x39, 0x50, 0x15, 0xff, 0x08, 0xdc, 0x68, 0x4f, 0x91, 0x10, 0xd1, 0x1b, 0x04, - 0x69, 0xb7, 0xfa, 0xfa, 0xe6, 0x68, 0xc1, 0xf9, 0x7c, 0x69, 0xeb, 0x8b, 0xa5, 0xad, 0x7f, 0x2d, - 0x6d, 0xfd, 0x65, 0x65, 0x6b, 0x8b, 0x95, 0xad, 0x7d, 0xac, 0x6c, 0xed, 0xf6, 0xe4, 0xd7, 0x88, - 0x3d, 0x39, 0x5b, 0x8f, 0x60, 0x4e, 0x61, 0xc2, 0x99, 0x2f, 0x17, 0xe2, 0x59, 0xad, 0x84, 0x1c, - 0x76, 0x50, 0x93, 0x7f, 0x7e, 0xf6, 0x1d, 0x00, 0x00, 0xff, 0xff, 0x73, 0x44, 0xd1, 0xbe, 0x2c, - 0x02, 0x00, 0x00, + // 410 bytes of a gzipped FileDescriptorProto + 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0x94, 0x92, 0xb1, 0xae, 0xd3, 0x30, + 0x14, 0x86, 0x13, 0x6e, 0x6f, 0xa5, 0x58, 0x5c, 0x95, 0x5a, 0x11, 0x8a, 0x2a, 0x48, 0xaa, 0x0c, + 0xa8, 0x03, 0x24, 0x03, 0x5b, 0xc7, 0xb4, 0xaa, 0x00, 0x81, 0x14, 0x85, 0x09, 0x96, 0xc8, 0x4d, + 0x4d, 0x1a, 0x9a, 0xd8, 0xc1, 0x76, 0x80, 0xbc, 0x05, 0x23, 0x03, 0x03, 0x8f, 0xd3, 0xb1, 0x23, + 0x62, 0x88, 0x50, 0xfb, 0x06, 0x7d, 0x02, 0x64, 0x1b, 0x51, 0xb8, 0x9d, 0xba, 0x24, 0xfe, 0x3f, + 0xfd, 0x3a, 0xbf, 0x8f, 0xcf, 0x01, 0xf6, 0xfb, 0x86, 0xd0, 0xb0, 0x2a, 0x88, 0x50, 0x9f, 0xa0, + 0x66, 0x54, 0x50, 0x68, 0x49, 0x1a, 0x48, 0x30, 0xb2, 0x73, 0x9a, 0x53, 0x45, 0x43, 0x79, 0xd2, + 0x06, 0xff, 0xdb, 0x15, 0xe8, 0xbf, 0x2a, 0x88, 0xc0, 0x0c, 0xbe, 0x04, 0x56, 0x41, 0xde, 0x95, + 0x48, 0x14, 0x94, 0x38, 0xe6, 0xd8, 0x9c, 0x58, 0x51, 0xb0, 0xed, 0x3c, 0xe3, 0x67, 0xe7, 0x3d, + 0xca, 0x0b, 0xb1, 0x6e, 0x96, 0x41, 0x46, 0xab, 0x30, 0xa3, 0xbc, 0xa2, 0xfc, 0xcf, 0xef, 0x09, + 0x5f, 0x6d, 0x42, 0xd1, 0xd6, 0x98, 0x07, 0x73, 0x9c, 0x25, 0xa7, 0x02, 0xd0, 0x06, 0xd7, 0xf5, + 0x1a, 0x71, 0xec, 0xdc, 0x19, 0x9b, 0x93, 0x5e, 0xa2, 0x05, 0x7c, 0x06, 0x86, 0x5c, 0x20, 0x26, + 0x52, 0x25, 0xd3, 0x65, 0x49, 0xb3, 0x8d, 0x73, 0x25, 0x1d, 0xd1, 0x83, 0x63, 0xe7, 0x39, 0x2d, + 0xaa, 0xca, 0xa9, 0x7f, 0x66, 0xf1, 0x93, 0x81, 0x62, 0xb1, 0x44, 0x91, 0x24, 0xf0, 0x13, 0x18, + 0x22, 0x42, 0x1a, 0x54, 0xa6, 0x35, 0xa3, 0x1f, 0x0b, 0x5e, 0x50, 0xc2, 0x9d, 0x9e, 0xba, 0xf5, + 0x8b, 0xcb, 0x6e, 0x7d, 0xca, 0x3d, 0x2b, 0xe8, 0x27, 0xf7, 0x34, 0x8b, 0xff, 0x22, 0xb8, 0x01, + 0x37, 0x02, 0xb1, 0x1c, 0x8b, 0x94, 0x37, 0x75, 0x5d, 0xb6, 0xce, 0xb5, 0x0a, 0x5d, 0x5c, 0x10, + 0xfa, 0x9c, 0x88, 0x63, 0xe7, 0xd9, 0x3a, 0xf4, 0xbf, 0x62, 0x7e, 0x72, 0x57, 0xeb, 0xd7, 0x5a, + 0x7e, 0x00, 0xfd, 0x18, 0x31, 0x54, 0x71, 0xf8, 0x10, 0x00, 0x39, 0xc6, 0x74, 0x85, 0x09, 0xad, + 0xf4, 0x78, 0x12, 0x4b, 0x92, 0xb9, 0x04, 0x30, 0x02, 0x03, 0xf5, 0x52, 0x3c, 0xad, 0x31, 0x4b, + 0x5b, 0x8c, 0x98, 0x7e, 0xf8, 0x68, 0x74, 0xec, 0xbc, 0xfb, 0x3a, 0xe9, 0x96, 0xc1, 0x4f, 0x6e, + 0x34, 0x89, 0x31, 0x7b, 0x83, 0x11, 0x9b, 0xf6, 0xbe, 0x7e, 0xf7, 0x8c, 0x68, 0xb1, 0xdd, 0xbb, + 0xe6, 0x6e, 0xef, 0x9a, 0xbf, 0xf6, 0xae, 0xf9, 0xe5, 0xe0, 0x1a, 0xbb, 0x83, 0x6b, 0xfc, 0x38, + 0xb8, 0xc6, 0xdb, 0xc7, 0xff, 0xb4, 0x36, 0x53, 0x3d, 0xcd, 0x28, 0x11, 0x0c, 0x65, 0x82, 0x87, + 0x6a, 0xfb, 0x3e, 0xeb, 0xfd, 0x53, 0x4d, 0x2e, 0xfb, 0x6a, 0xc1, 0x9e, 0xfe, 0x0e, 0x00, 0x00, + 0xff, 0xff, 0xcf, 0xa2, 0xd3, 0xd4, 0x99, 0x02, 0x00, 0x00, } func (m *Minter) Marshal() (dAtA []byte, err error) { @@ -190,6 +193,16 @@ func (m *Minter) MarshalToSizedBuffer(dAtA []byte) (int, error) { _ = i var l int _ = l + { + size := m.TargetSupply.Size() + i -= size + if _, err := m.TargetSupply.MarshalTo(dAtA[i:]); err != nil { + return 0, err + } + i = encodeVarintMint(dAtA, i, uint64(size)) + } + i-- + dAtA[i] = 0x2a { size := m.AnnualProvisions.Size() i -= size @@ -285,6 +298,8 @@ func (m *Minter) Size() (n int) { } l = m.AnnualProvisions.Size() n += 1 + l + sovMint(uint64(l)) + l = m.TargetSupply.Size() + n += 1 + l + sovMint(uint64(l)) return n } @@ -445,6 +460,40 @@ func (m *Minter) Unmarshal(dAtA []byte) error { return err } iNdEx = postIndex + case 5: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field TargetSupply", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowMint + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + stringLen |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + intStringLen := int(stringLen) + if intStringLen < 0 { + return ErrInvalidLengthMint + } + postIndex := iNdEx + intStringLen + if postIndex < 0 { + return ErrInvalidLengthMint + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + if err := m.TargetSupply.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + return err + } + iNdEx = postIndex default: iNdEx = preIndex skippy, err := skipMint(dAtA[iNdEx:]) diff --git a/x/mint/types/minter.go b/x/mint/types/minter.go index cf17b2726..14b14f24e 100644 --- a/x/mint/types/minter.go +++ b/x/mint/types/minter.go @@ -70,14 +70,13 @@ func (m Minter) PhaseInflationRate(phase uint64) sdk.Dec { } // NextPhase returns the new phase. -func (m Minter) NextPhase(params Params, currentBlock uint64) uint64 { +func (m Minter) NextPhase(params Params, currentSupply sdk.Int) uint64 { nonePhase := m.Phase == 0 if nonePhase { return 1 } - blockNewPhase := m.StartPhaseBlock + params.BlocksPerYear - if blockNewPhase > currentBlock { + if currentSupply.LT(m.TargetSupply) { return m.Phase } @@ -92,7 +91,14 @@ func (m Minter) NextAnnualProvisions(_ Params, totalSupply sdk.Int) sdk.Dec { // BlockProvision returns the provisions for a block based on the annual // provisions rate. -func (m Minter) BlockProvision(params Params) sdk.Coin { +func (m Minter) BlockProvision(params Params, totalSupply sdk.Int) sdk.Coin { provisionAmt := m.AnnualProvisions.QuoInt(sdk.NewInt(int64(params.BlocksPerYear))) + + // Because of rounding, we might mint too many tokens in this phase, let's limit it + futureSupply := totalSupply.Add(provisionAmt.TruncateInt()) + if futureSupply.GT(m.TargetSupply) { + return sdk.NewCoin(params.MintDenom, m.TargetSupply.Sub(totalSupply)) + } + return sdk.NewCoin(params.MintDenom, provisionAmt.TruncateInt()) } From f734102550f4650d7b998ec15f5a0fee330c1e6d Mon Sep 17 00:00:00 2001 From: Jacob Gadikian Date: Thu, 25 Aug 2022 23:34:17 +0700 Subject: [PATCH 02/13] lints --- x/mint/simulation/genesis_test.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/x/mint/simulation/genesis_test.go b/x/mint/simulation/genesis_test.go index b5f7c5b71..b3415388c 100644 --- a/x/mint/simulation/genesis_test.go +++ b/x/mint/simulation/genesis_test.go @@ -46,7 +46,7 @@ func TestRandomizedGenState(t *testing.T) { require.Equal(t, "0.170000000000000000", mintGenesis.Minter.NextAnnualProvisions(mintGenesis.Params, sdk.OneInt()).String()) require.Equal(t, "0.400000000000000000", mintGenesis.Minter.PhaseInflationRate(1).String()) require.Equal(t, "0.170000000000000000", mintGenesis.Minter.Inflation.String()) - require.Equal(t, uint64(1), mintGenesis.Minter.NextPhase(mintGenesis.Params, 1)) + require.Equal(t, uint64(1), mintGenesis.Minter.NextPhase(mintGenesis.Params, sdk.NewInt(1))) require.Equal(t, uint64(0), mintGenesis.Minter.Phase) require.Equal(t, "0.000000000000000000", mintGenesis.Minter.AnnualProvisions.String()) } From 3bd7929d830c6d52334635357761c77adb92a047 Mon Sep 17 00:00:00 2001 From: Jacob Gadikian Date: Thu, 25 Aug 2022 23:39:21 +0700 Subject: [PATCH 03/13] total supply.... --- x/mint/types/minter_test.go | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/x/mint/types/minter_test.go b/x/mint/types/minter_test.go index 4b5079c4a..62f1992b0 100644 --- a/x/mint/types/minter_test.go +++ b/x/mint/types/minter_test.go @@ -130,10 +130,11 @@ func BenchmarkBlockProvision(b *testing.B) { s1 := rand.NewSource(100) r1 := rand.New(s1) minter.AnnualProvisions = sdk.NewDec(r1.Int63n(1000000)) + totalSupply := sdk.NewInt(100000000000000) // run the BlockProvision function b.N times for n := 0; n < b.N; n++ { - minter.BlockProvision(params) + minter.BlockProvision(params, totalSupply) } } From f450ecc1d71415c91c8ec1008f78e7f6b8bd7da0 Mon Sep 17 00:00:00 2001 From: Jacob Gadikian Date: Fri, 26 Aug 2022 00:17:19 +0700 Subject: [PATCH 04/13] more tests --- x/mint/types/minter_test.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/x/mint/types/minter_test.go b/x/mint/types/minter_test.go index 62f1992b0..69d07f557 100644 --- a/x/mint/types/minter_test.go +++ b/x/mint/types/minter_test.go @@ -81,7 +81,7 @@ func TestNextPhase(t *testing.T) { minter.StartPhaseBlock = tc.startPhaseBlock params.BlocksPerYear = tc.blocksYear - phase := minter.NextPhase(params, tc.currentBlock) + phase := minter.NextPhase(params, sdk.NewIntFromUint64(tc.currentBlock)) require.True(t, phase == tc.expPhase, "Test Index: %v\nPhase: %v\nExpected: %v\n", i, phase, tc.expPhase) From 4db15efeb64d88d0e0d4913690e5506e3b8f54b7 Mon Sep 17 00:00:00 2001 From: dimiandre Date: Thu, 25 Aug 2022 21:36:01 +0200 Subject: [PATCH 05/13] fix tests --- x/mint/types/minter.go | 4 +++- x/mint/types/minter_test.go | 35 ++++++++++++++++++----------------- 2 files changed, 21 insertions(+), 18 deletions(-) diff --git a/x/mint/types/minter.go b/x/mint/types/minter.go index 14b14f24e..995c1db60 100644 --- a/x/mint/types/minter.go +++ b/x/mint/types/minter.go @@ -8,12 +8,13 @@ import ( // NewMinter returns a new Minter object with the given inflation and annual // provisions values. -func NewMinter(inflation, annualProvisions sdk.Dec, phase, startPhaseBlock uint64) Minter { +func NewMinter(inflation, annualProvisions sdk.Dec, phase, startPhaseBlock uint64, targetSupply sdk.Int) Minter { return Minter{ Inflation: inflation, AnnualProvisions: annualProvisions, Phase: phase, StartPhaseBlock: startPhaseBlock, + TargetSupply: targetSupply, } } @@ -24,6 +25,7 @@ func InitialMinter(inflation sdk.Dec) Minter { sdk.NewDec(0), 0, 0, + sdk.NewInt(0), ) } diff --git a/x/mint/types/minter_test.go b/x/mint/types/minter_test.go index 69d07f557..46dde6d7c 100644 --- a/x/mint/types/minter_test.go +++ b/x/mint/types/minter_test.go @@ -63,25 +63,22 @@ func TestNextPhase(t *testing.T) { blocksPerYear := uint64(100) tests := []struct { currentBlock, currentPhase, startPhaseBlock, blocksYear, expPhase uint64 + currentSupply sdk.Int + targetSupply sdk.Int }{ - {1, 0, 0, blocksPerYear, 1}, - {50, 1, 1, blocksPerYear, 1}, - {99, 1, 1, blocksPerYear, 1}, - {100, 1, 1, blocksPerYear, 1}, - {101, 1, 1, blocksPerYear, 2}, - // increase blocks_per_year - {102, 2, 101, blocksPerYear * 2, 2}, - {201, 2, 101, blocksPerYear * 2, 2}, - {299, 2, 101, blocksPerYear * 2, 2}, - {300, 2, 101, blocksPerYear * 2, 2}, - {301, 2, 101, blocksPerYear * 2, 3}, + {1, 0, 0, blocksPerYear, 1, sdk.NewInt(10000), sdk.NewInt(14000)}, + {50, 1, 1, blocksPerYear, 1, sdk.NewInt(12000), sdk.NewInt(14000)}, + {99, 1, 1, blocksPerYear, 1, sdk.NewInt(13960), sdk.NewInt(11400000)}, + {100, 1, 1, blocksPerYear, 2, sdk.NewInt(14000), sdk.NewInt(14000)}, + {101, 1, 1, blocksPerYear, 2, sdk.NewInt(16000), sdk.NewInt(14000)}, } for i, tc := range tests { minter.Phase = tc.currentPhase minter.StartPhaseBlock = tc.startPhaseBlock + minter.TargetSupply = tc.targetSupply params.BlocksPerYear = tc.blocksYear - phase := minter.NextPhase(params, sdk.NewIntFromUint64(tc.currentBlock)) + phase := minter.NextPhase(params, tc.currentSupply) require.True(t, phase == tc.expPhase, "Test Index: %v\nPhase: %v\nExpected: %v\n", i, phase, tc.expPhase) @@ -97,15 +94,18 @@ func TestBlockProvision(t *testing.T) { tests := []struct { annualProvisions int64 expProvisions int64 + totalSupply sdk.Int }{ - {secondsPerYear / 5, 1}, - {secondsPerYear/5 + 1, 1}, - {(secondsPerYear / 5) * 2, 2}, - {(secondsPerYear / 5) / 2, 0}, + {secondsPerYear / 5, 1, sdk.NewInt(1)}, + {secondsPerYear/5 + 1, 1, sdk.NewInt(1)}, + {(secondsPerYear / 5) * 2, 2, sdk.NewInt(1)}, + {(secondsPerYear / 5) / 2, 0, sdk.NewInt(1)}, } for i, tc := range tests { minter.AnnualProvisions = sdk.NewDec(tc.annualProvisions) - provisions := minter.BlockProvision(params) + minter.TargetSupply = tc.totalSupply.Add(minter.AnnualProvisions.TruncateInt()) + + provisions := minter.BlockProvision(params, tc.totalSupply) expProvisions := sdk.NewCoin(params.MintDenom, sdk.NewInt(tc.expProvisions)) @@ -131,6 +131,7 @@ func BenchmarkBlockProvision(b *testing.B) { r1 := rand.New(s1) minter.AnnualProvisions = sdk.NewDec(r1.Int63n(1000000)) totalSupply := sdk.NewInt(100000000000000) + minter.TargetSupply = sdk.NewInt(200000000000000) // run the BlockProvision function b.N times for n := 0; n < b.N; n++ { From 8e0d3e7a052095affcf202aae36ae81eadc7ec73 Mon Sep 17 00:00:00 2001 From: dimiandre Date: Thu, 25 Aug 2022 21:43:36 +0200 Subject: [PATCH 06/13] fix genesis test and decoder test --- x/mint/simulation/decoder_test.go | 2 +- x/mint/simulation/genesis_test.go | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/x/mint/simulation/decoder_test.go b/x/mint/simulation/decoder_test.go index f2cc1f851..d34c93e19 100644 --- a/x/mint/simulation/decoder_test.go +++ b/x/mint/simulation/decoder_test.go @@ -17,7 +17,7 @@ func TestDecodeStore(t *testing.T) { cdc := app.MakeEncodingConfig().Marshaler dec := simulation.NewDecodeStore(cdc) - minter := types.NewMinter(sdk.OneDec(), sdk.NewDec(15), 1, 1) + minter := types.NewMinter(sdk.OneDec(), sdk.NewDec(15), 1, 1, sdk.NewInt(1)) kvPairs := kv.Pairs{ Pairs: []kv.Pair{ diff --git a/x/mint/simulation/genesis_test.go b/x/mint/simulation/genesis_test.go index b3415388c..d1d747e92 100644 --- a/x/mint/simulation/genesis_test.go +++ b/x/mint/simulation/genesis_test.go @@ -42,7 +42,7 @@ func TestRandomizedGenState(t *testing.T) { require.Equal(t, uint64(6311520), mintGenesis.Params.BlocksPerYear) require.Equal(t, "stake", mintGenesis.Params.MintDenom) - require.Equal(t, "0stake", mintGenesis.Minter.BlockProvision(mintGenesis.Params).String()) + require.Equal(t, "0stake", mintGenesis.Minter.BlockProvision(mintGenesis.Params, sdk.NewInt(0)).String()) require.Equal(t, "0.170000000000000000", mintGenesis.Minter.NextAnnualProvisions(mintGenesis.Params, sdk.OneInt()).String()) require.Equal(t, "0.400000000000000000", mintGenesis.Minter.PhaseInflationRate(1).String()) require.Equal(t, "0.170000000000000000", mintGenesis.Minter.Inflation.String()) From 514eb52d31f9346d474b81b48c060a840a650747 Mon Sep 17 00:00:00 2001 From: Jacob Gadikian Date: Fri, 26 Aug 2022 05:06:52 +0700 Subject: [PATCH 07/13] superlinter settings --- .github/workflows/superlinter.yml | 1 + 1 file changed, 1 insertion(+) diff --git a/.github/workflows/superlinter.yml b/.github/workflows/superlinter.yml index b5dc83467..3c296a82b 100644 --- a/.github/workflows/superlinter.yml +++ b/.github/workflows/superlinter.yml @@ -19,5 +19,6 @@ jobs: uses: github/super-linter@v4 env: VALIDATE_ALL_CODEBASE: false + VALIDATE_GO: false DEFAULT_BRANCH: "main" GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} From f238b07da0370e801b6048a05a58c3f4b7742c54 Mon Sep 17 00:00:00 2001 From: dimiandre Date: Fri, 26 Aug 2022 20:50:35 +0200 Subject: [PATCH 08/13] lint proto --- proto/juno/mint/mint.proto | 19 +++++++++++++------ 1 file changed, 13 insertions(+), 6 deletions(-) diff --git a/proto/juno/mint/mint.proto b/proto/juno/mint/mint.proto index 3184ad927..22e29c15e 100644 --- a/proto/juno/mint/mint.proto +++ b/proto/juno/mint/mint.proto @@ -1,17 +1,22 @@ syntax = "proto3"; -package juno.mint; -option go_package = "github.com/CosmosContracts/juno/x/mint/types"; +package juno.mint; import "gogoproto/gogo.proto"; +option go_package = "github.com/CosmosContracts/juno/x/mint/types"; + // Minter represents the minting state. message Minter { // current annual inflation rate - string inflation = 1 - [(gogoproto.customtype) = "github.com/cosmos/cosmos-sdk/types.Dec", (gogoproto.nullable) = false]; + string inflation = 1 [ + (gogoproto.customtype) = "github.com/cosmos/cosmos-sdk/types.Dec", + (gogoproto.nullable) = false + ]; uint64 phase = 2; - uint64 start_phase_block = 3 [(gogoproto.moretags) = "yaml:\"start_phase_block\""]; + uint64 start_phase_block = 3 [ + (gogoproto.moretags) = "yaml:\"start_phase_block\"" + ]; // current annual expected provisions string annual_provisions = 4 [ (gogoproto.moretags) = "yaml:\"annual_provisions\"", @@ -32,5 +37,7 @@ message Params { // type of coin to mint string mint_denom = 1; // expected blocks per year - uint64 blocks_per_year = 2 [(gogoproto.moretags) = "yaml:\"blocks_per_year\""]; + uint64 blocks_per_year = 2 [ + (gogoproto.moretags) = "yaml:\"blocks_per_year\"" + ]; } From 98b7e89a5a7bb79d26604ccad1ae4a87d0d0ee53 Mon Sep 17 00:00:00 2001 From: dimiandre Date: Fri, 26 Aug 2022 20:59:34 +0200 Subject: [PATCH 09/13] ignore generated files with superlinter --- .github/workflows/superlinter.yml | 2 ++ 1 file changed, 2 insertions(+) diff --git a/.github/workflows/superlinter.yml b/.github/workflows/superlinter.yml index 3c296a82b..e24972967 100644 --- a/.github/workflows/superlinter.yml +++ b/.github/workflows/superlinter.yml @@ -20,5 +20,7 @@ jobs: env: VALIDATE_ALL_CODEBASE: false VALIDATE_GO: false + IGNORE_GENERATED_FILES: true + FILTER_REGEX_EXCLUDE: .*.pb.go DEFAULT_BRANCH: "main" GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} From 39e489580d706d266ea5ed506c3062a701c6e3be Mon Sep 17 00:00:00 2001 From: dimiandre Date: Wed, 31 Aug 2022 21:02:24 +0200 Subject: [PATCH 10/13] add migration for mint module --- x/mint/keeper/migrator.go | 23 ++++++++++++++++++++ x/mint/migrations/v2/migrate.go | 38 +++++++++++++++++++++++++++++++++ x/mint/module.go | 8 ++++++- 3 files changed, 68 insertions(+), 1 deletion(-) create mode 100644 x/mint/keeper/migrator.go create mode 100644 x/mint/migrations/v2/migrate.go diff --git a/x/mint/keeper/migrator.go b/x/mint/keeper/migrator.go new file mode 100644 index 000000000..e44736da5 --- /dev/null +++ b/x/mint/keeper/migrator.go @@ -0,0 +1,23 @@ +package keeper + +import ( + v2 "github.com/CosmosContracts/juno/v10/x/mint/migrations/v2" + sdk "github.com/cosmos/cosmos-sdk/types" +) + +// Migrator is a struct for handling in-place state migrations. +type Migrator struct { + keeper Keeper +} + +func NewMigrator(k Keeper) Migrator { + return Migrator{ + keeper: k, + } +} + +// Migrate migrates the x/mint module state from the consensus version 1 to +// version 2. Specifically, it take calculate target supply for the current phase +func (m Migrator) Migrate1to2(ctx sdk.Context) error { + return v2.Migrate(ctx, ctx.KVStore(m.keeper.storeKey), m.keeper.cdc) +} diff --git a/x/mint/migrations/v2/migrate.go b/x/mint/migrations/v2/migrate.go new file mode 100644 index 000000000..636909b36 --- /dev/null +++ b/x/mint/migrations/v2/migrate.go @@ -0,0 +1,38 @@ +package v2 + +import ( + "github.com/CosmosContracts/juno/v10/x/mint/types" + "github.com/cosmos/cosmos-sdk/codec" + sdk "github.com/cosmos/cosmos-sdk/types" +) + +const ( + ModuleName = "mint" +) + +// Migrate migrates the x/mint module state from the consensus version 1 to +// version 2. Specifically, it take calculate target supply for the current phase +func Migrate( + ctx sdk.Context, + store sdk.KVStore, + cdc codec.BinaryCodec, +) error { + + // Get minter + var minter types.Minter + b := store.Get(types.MinterKey) + if b == nil { + panic("stored minter should not have been nil") + } + + cdc.MustUnmarshal(b, &minter) + + // Calculate target supply + minter.TargetSupply = sdk.NewInt(1) + + // Save new minter + bz := cdc.MustMarshal(&minter) + store.Set(types.MinterKey, bz) + + return nil +} diff --git a/x/mint/module.go b/x/mint/module.go index 1925b9c01..1adb96e4a 100644 --- a/x/mint/module.go +++ b/x/mint/module.go @@ -126,6 +126,12 @@ func (am AppModule) LegacyQuerierHandler(legacyQuerierCdc *codec.LegacyAmino) sd // module-specific gRPC queries. func (am AppModule) RegisterServices(cfg module.Configurator) { types.RegisterQueryServer(cfg.QueryServer(), am.keeper) + + m := keeper.NewMigrator(am.keeper) + + if err := cfg.RegisterMigration(types.ModuleName, 1, m.Migrate1to2); err != nil { + panic(fmt.Sprintf("failed to migrate x/%s from version 1 to 2: %v", types.ModuleName, err)) + } } // InitGenesis performs genesis initialization for the mint module. It returns @@ -146,7 +152,7 @@ func (am AppModule) ExportGenesis(ctx sdk.Context, cdc codec.JSONCodec) json.Raw } // ConsensusVersion implements AppModule/ConsensusVersion. -func (AppModule) ConsensusVersion() uint64 { return 1 } +func (AppModule) ConsensusVersion() uint64 { return 2 } // BeginBlock returns the begin blocker for the mint module. func (am AppModule) BeginBlock(ctx sdk.Context, _ abci.RequestBeginBlock) { From e5c5f17649d1448a5ebf4b7f13cc246d45ee3df5 Mon Sep 17 00:00:00 2001 From: dimiandre Date: Thu, 1 Sep 2022 12:49:01 +0200 Subject: [PATCH 11/13] change upgrade name, calculate target supply --- app/app.go | 2 +- x/mint/migrations/v2/migrate.go | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/app/app.go b/app/app.go index bb87f99b3..9a553ee21 100644 --- a/app/app.go +++ b/app/app.go @@ -840,7 +840,7 @@ func (app *App) RegisterTendermintService(clientCtx client.Context) { // RegisterUpgradeHandlers returns upgrade handlers func (app *App) RegisterUpgradeHandlers(cfg module.Configurator) { - app.UpgradeKeeper.SetUpgradeHandler("MigrateTraces", + app.UpgradeKeeper.SetUpgradeHandler("v10", func(ctx sdk.Context, _ upgradetypes.Plan, fromVM module.VersionMap) (module.VersionMap, error) { // transfer module consensus version has been bumped to 2 return app.mm.RunMigrations(ctx, cfg, fromVM) diff --git a/x/mint/migrations/v2/migrate.go b/x/mint/migrations/v2/migrate.go index 636909b36..8282c0743 100644 --- a/x/mint/migrations/v2/migrate.go +++ b/x/mint/migrations/v2/migrate.go @@ -28,7 +28,7 @@ func Migrate( cdc.MustUnmarshal(b, &minter) // Calculate target supply - minter.TargetSupply = sdk.NewInt(1) + minter.TargetSupply = minter.AnnualProvisions.Add(minter.AnnualProvisions.Quo(minter.Inflation)).TruncateInt() // Save new minter bz := cdc.MustMarshal(&minter) From 886b8c839b46f1c0945f37e589cf614213260a66 Mon Sep 17 00:00:00 2001 From: Alex Lynham Date: Mon, 5 Sep 2022 21:09:16 +0100 Subject: [PATCH 12/13] Remove extra logging, add extra test case and a couple of comments --- x/mint/abci.go | 5 ----- x/mint/keeper/migrator.go | 4 ++-- x/mint/types/minter_test.go | 40 ++++++++++++++++++++++++++++++++++++- 3 files changed, 41 insertions(+), 8 deletions(-) diff --git a/x/mint/abci.go b/x/mint/abci.go index 82589d3e7..913d4cbf7 100644 --- a/x/mint/abci.go +++ b/x/mint/abci.go @@ -21,8 +21,6 @@ func BeginBlocker(ctx sdk.Context, k keeper.Keeper) { return } - logger := k.Logger(ctx) - // fetch stored params params := k.GetParams(ctx) currentBlock := uint64(ctx.BlockHeight()) @@ -33,7 +31,6 @@ func BeginBlocker(ctx sdk.Context, k keeper.Keeper) { // check if we need to change phase nextPhase := minter.NextPhase(params, totalSupply) - logger.Debug("New Block", "Height", ctx.BlockHeight(), "Current Total Supply", totalSupply, "Current Phase", minter.Phase) if nextPhase != minter.Phase { // store new inflation rate by phase newInflation := minter.PhaseInflationRate(nextPhase) @@ -44,8 +41,6 @@ func BeginBlocker(ctx sdk.Context, k keeper.Keeper) { minter.TargetSupply = totalSupply.Add(minter.AnnualProvisions.TruncateInt()) k.SetMinter(ctx, minter) - logger.Info("New inflation phase started!", "Current Supply", totalSupply, "Target Supply", minter.TargetSupply, "Annual Provisions", minter.AnnualProvisions, "Height", ctx.BlockHeight()) - // inflation phase end if minter.Inflation.Equal(sdk.ZeroDec()) { return diff --git a/x/mint/keeper/migrator.go b/x/mint/keeper/migrator.go index e44736da5..7c163c99c 100644 --- a/x/mint/keeper/migrator.go +++ b/x/mint/keeper/migrator.go @@ -16,8 +16,8 @@ func NewMigrator(k Keeper) Migrator { } } -// Migrate migrates the x/mint module state from the consensus version 1 to -// version 2. Specifically, it take calculate target supply for the current phase +// Migrate migrates the x/mint module state from the consensus version +// 1 to version 2 func (m Migrator) Migrate1to2(ctx sdk.Context) error { return v2.Migrate(ctx, ctx.KVStore(m.keeper.storeKey), m.keeper.cdc) } diff --git a/x/mint/types/minter_test.go b/x/mint/types/minter_test.go index 46dde6d7c..0adc08510 100644 --- a/x/mint/types/minter_test.go +++ b/x/mint/types/minter_test.go @@ -68,9 +68,14 @@ func TestNextPhase(t *testing.T) { }{ {1, 0, 0, blocksPerYear, 1, sdk.NewInt(10000), sdk.NewInt(14000)}, {50, 1, 1, blocksPerYear, 1, sdk.NewInt(12000), sdk.NewInt(14000)}, - {99, 1, 1, blocksPerYear, 1, sdk.NewInt(13960), sdk.NewInt(11400000)}, + // if targetSupply is > currentSupply it doesn't + // matter how much by + {99, 1, 1, blocksPerYear, 1, sdk.NewInt(13960), sdk.NewInt(1140000)}, {100, 1, 1, blocksPerYear, 2, sdk.NewInt(14000), sdk.NewInt(14000)}, {101, 1, 1, blocksPerYear, 2, sdk.NewInt(16000), sdk.NewInt(14000)}, + // since currentSupply is larger than targetSupply + // next phase returns phase + 1 regardless of inputs + {102, 2, 101, blocksPerYear, 3, sdk.NewInt(29000), sdk.NewInt(14000)}, } for i, tc := range tests { minter.Phase = tc.currentPhase @@ -100,6 +105,8 @@ func TestBlockProvision(t *testing.T) { {secondsPerYear/5 + 1, 1, sdk.NewInt(1)}, {(secondsPerYear / 5) * 2, 2, sdk.NewInt(1)}, {(secondsPerYear / 5) / 2, 0, sdk.NewInt(1)}, + {(secondsPerYear / 5) * 3, 3, sdk.NewInt(1)}, + {(secondsPerYear / 5) * 7, 7, sdk.NewInt(2)}, } for i, tc := range tests { minter.AnnualProvisions = sdk.NewDec(tc.annualProvisions) @@ -116,6 +123,37 @@ func TestBlockProvision(t *testing.T) { } } +func TestBlockProvisionRounding(t *testing.T) { + minter := InitialMinter(sdk.NewDecWithPrec(1, 1)) + params := DefaultParams() + + secondsPerYear := int64(60 * 60 * 8766) + + tests := []struct { + annualProvisions int64 + expProvisions int64 + totalSupply sdk.Int + }{ + {(secondsPerYear / 5) * 7200, 0, sdk.NewInt(7000)}, + } + for i, tc := range tests { + // if provision amount + total current supply + // (totalSupply) exceeds target supply it should + // return targetSupply - totalSupply, i.e. zero + minter.AnnualProvisions = sdk.NewDec(tc.annualProvisions) + minter.TargetSupply = tc.totalSupply + + provisions := minter.BlockProvision(params, tc.totalSupply) + + expProvisions := sdk.NewCoin(params.MintDenom, + sdk.NewInt(tc.expProvisions)) + + require.True(t, expProvisions.IsEqual(provisions), + "test: %v\n\tExp: %v\n\tGot: %v\n", + i, tc.expProvisions, provisions) + } +} + // Benchmarking :) // previously using sdk.Int operations: // BenchmarkBlockProvision-4 5000000 220 ns/op From 78d3b6aba9446646085da45bbf97b5f0ece074c4 Mon Sep 17 00:00:00 2001 From: Alex Lynham Date: Mon, 5 Sep 2022 22:21:15 +0100 Subject: [PATCH 13/13] Hopefully shut the linter up --- x/mint/types/minter_test.go | 37 ++++++++----------------------------- 1 file changed, 8 insertions(+), 29 deletions(-) diff --git a/x/mint/types/minter_test.go b/x/mint/types/minter_test.go index 0adc08510..4688ee9b1 100644 --- a/x/mint/types/minter_test.go +++ b/x/mint/types/minter_test.go @@ -107,41 +107,20 @@ func TestBlockProvision(t *testing.T) { {(secondsPerYear / 5) / 2, 0, sdk.NewInt(1)}, {(secondsPerYear / 5) * 3, 3, sdk.NewInt(1)}, {(secondsPerYear / 5) * 7, 7, sdk.NewInt(2)}, - } - for i, tc := range tests { - minter.AnnualProvisions = sdk.NewDec(tc.annualProvisions) - minter.TargetSupply = tc.totalSupply.Add(minter.AnnualProvisions.TruncateInt()) - - provisions := minter.BlockProvision(params, tc.totalSupply) - - expProvisions := sdk.NewCoin(params.MintDenom, - sdk.NewInt(tc.expProvisions)) - - require.True(t, expProvisions.IsEqual(provisions), - "test: %v\n\tExp: %v\n\tGot: %v\n", - i, tc.expProvisions, provisions) - } -} - -func TestBlockProvisionRounding(t *testing.T) { - minter := InitialMinter(sdk.NewDecWithPrec(1, 1)) - params := DefaultParams() - - secondsPerYear := int64(60 * 60 * 8766) - - tests := []struct { - annualProvisions int64 - expProvisions int64 - totalSupply sdk.Int - }{ + // we special case this below to trigger the + // conditional in BlockProvision {(secondsPerYear / 5) * 7200, 0, sdk.NewInt(7000)}, } for i, tc := range tests { + minter.AnnualProvisions = sdk.NewDec(tc.annualProvisions) // if provision amount + total current supply // (totalSupply) exceeds target supply it should // return targetSupply - totalSupply, i.e. zero - minter.AnnualProvisions = sdk.NewDec(tc.annualProvisions) - minter.TargetSupply = tc.totalSupply + if i == 6 { + minter.TargetSupply = tc.totalSupply + } else { + minter.TargetSupply = tc.totalSupply.Add(minter.AnnualProvisions.TruncateInt()) + } provisions := minter.BlockProvision(params, tc.totalSupply)