Skip to content

Commit

Permalink
Merge branch 'master' into mat/add-more-test
Browse files Browse the repository at this point in the history
  • Loading branch information
Unique-Divine authored Dec 1, 2023
2 parents 0a2c1c8 + 31f78b0 commit 5b6655a
Show file tree
Hide file tree
Showing 14 changed files with 285 additions and 56 deletions.
13 changes: 12 additions & 1 deletion CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,17 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0

## [Unreleased]

### Features
### Features

* [#1670](https://github.com/NibiruChain/nibiru/pull/1670) - feat(inflation): Make inflation polynomial

### State Machine Breaking

* [#1682](https://github.com/NibiruChain/nibiru/pull/1682) - feat: add upgrade handler for v1.1.0

## [v1.0.0](https://github.com/NibiruChain/nibiru/releases/tag/v1.0.0)

### Features

* [#1596](https://github.com/NibiruChain/nibiru/pull/1596) - epic(tokenfactory): State transitions, collections, genesis import and export, and app wiring
* [#1607](https://github.com/NibiruChain/nibiru/pull/1607) - Token factory transaction messages for CreateDenom, ChangeAdmin, and UpdateModuleParams
Expand All @@ -50,6 +60,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
* [#1656](https://github.com/NibiruChain/nibiru/pull/1656) - feat(perp): Make the collateral denom a stateful collections.Item
* [#1663](https://github.com/NibiruChain/nibiru/pull/1663) - feat(perp): Add volume based rebates
* [#1670](https://github.com/NibiruChain/nibiru/pull/1670) - feat(inflation): Make inflation polynomial
* [#1683](https://github.com/NibiruChain/nibiru/pull/1683) - feat(perp): Add `StartDnREpoch` to `AfterEpochEnd` hook

### State Machine Breaking

Expand Down
2 changes: 2 additions & 0 deletions app/app.go
Original file line number Diff line number Diff line change
Expand Up @@ -171,6 +171,8 @@ func NewNibiruApp(

app.initModuleManager(encodingConfig, skipGenesisInvariants)

app.setupUpgrades()

// NOTE: Any module instantiated in the module manager that is later modified
// must be passed by reference here.

Expand Down
7 changes: 4 additions & 3 deletions app/keepers.go
Original file line number Diff line number Diff line change
Expand Up @@ -626,6 +626,9 @@ func orderedModuleNames() []string {
// --------------------------------------------------------------------
// Cosmos-SDK modules
//
// NOTE: (BeginBlocker requirement): upgrade module must occur first
upgradetypes.ModuleName,

// NOTE (InitGenesis requirement): Capability module must occur
// first so that it can initialize any capabilities, allowing other
// modules that want to create or claim capabilities afterwards in
Expand Down Expand Up @@ -654,7 +657,6 @@ func orderedModuleNames() []string {
authz.ModuleName,
feegrant.ModuleName,
paramstypes.ModuleName,
upgradetypes.ModuleName,
vestingtypes.ModuleName,

// --------------------------------------------------------------------
Expand Down Expand Up @@ -707,7 +709,6 @@ func (app *NibiruApp) initModuleManager(
app.initAppModules(encodingConfig, skipGenesisInvariants)...,
)

// Init module orders for hooks and genesis
orderedModules := orderedModuleNames()
app.mm.SetOrderBeginBlockers(orderedModules...)
app.mm.SetOrderEndBlockers(orderedModules...)
Expand Down Expand Up @@ -743,7 +744,7 @@ func (app *NibiruApp) initModuleManager(
}
}

// ModuleBasicManager: The app's collection of module.AppModuleBasic
// ModuleBasicManager The app's collection of module.AppModuleBasic
// implementations. These set up non-dependant module elements, such as codec
// registration and genesis verification.
func ModuleBasicManager() module.BasicManager {
Expand Down
42 changes: 42 additions & 0 deletions app/upgrades.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
package app

import (
"fmt"

upgradetypes "github.com/cosmos/cosmos-sdk/x/upgrade/types"

"github.com/NibiruChain/nibiru/app/upgrades"
"github.com/NibiruChain/nibiru/app/upgrades/v1_1_0"
)

var Upgrades = []upgrades.Upgrade{
v1_1_0.Upgrade,
}

func (app *NibiruApp) setupUpgrades() {
app.setUpgradeHandlers()
app.setUpgradeStoreLoaders()
}

func (app *NibiruApp) setUpgradeHandlers() {
for _, u := range Upgrades {
app.upgradeKeeper.SetUpgradeHandler(u.UpgradeName, u.CreateUpgradeHandler())
}
}

func (app *NibiruApp) setUpgradeStoreLoaders() {
upgradeInfo, err := app.upgradeKeeper.ReadUpgradeInfoFromDisk()
if err != nil {
panic(fmt.Sprintf("failed to read upgrade info from disk: %s", err.Error()))

Check warning on line 30 in app/upgrades.go

View check run for this annotation

Codecov / codecov/patch

app/upgrades.go#L30

Added line #L30 was not covered by tests
}

if app.upgradeKeeper.IsSkipHeight(upgradeInfo.Height) {
return
}

Check warning on line 35 in app/upgrades.go

View check run for this annotation

Codecov / codecov/patch

app/upgrades.go#L34-L35

Added lines #L34 - L35 were not covered by tests

for _, u := range Upgrades {
if upgradeInfo.Name == u.UpgradeName {
app.SetStoreLoader(upgradetypes.UpgradeStoreLoader(upgradeInfo.Height, &u.StoreUpgrades))
}

Check warning on line 40 in app/upgrades.go

View check run for this annotation

Codecov / codecov/patch

app/upgrades.go#L39-L40

Added lines #L39 - L40 were not covered by tests
}
}
14 changes: 14 additions & 0 deletions app/upgrades/types.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
package upgrades

import (
store "github.com/cosmos/cosmos-sdk/store/types"
"github.com/cosmos/cosmos-sdk/x/upgrade/types"
)

type Upgrade struct {
UpgradeName string

CreateUpgradeHandler func() types.UpgradeHandler

StoreUpgrades store.StoreUpgrades
}
21 changes: 21 additions & 0 deletions app/upgrades/v1_1_0/constants.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
package v1_1_0

import (
"github.com/cosmos/cosmos-sdk/store/types"
upgradetypes "github.com/cosmos/cosmos-sdk/x/upgrade/types"

"github.com/NibiruChain/nibiru/app/upgrades"
inflationtypes "github.com/NibiruChain/nibiru/x/inflation/types"
)

const UpgradeName = "v1.1.0"

var Upgrade = upgrades.Upgrade{
UpgradeName: UpgradeName,
CreateUpgradeHandler: func() upgradetypes.UpgradeHandler {
return nil
},
StoreUpgrades: types.StoreUpgrades{
Added: []string{inflationtypes.ModuleName},
},
}
2 changes: 2 additions & 0 deletions proto/nibiru/perp/v2/genesis.proto
Original file line number Diff line number Diff line change
Expand Up @@ -65,6 +65,8 @@ message GenesisState {

repeated DNRAllocation rebates_allocations = 12 [ (gogoproto.nullable) = false ];

string dnr_epoch_name = 14;

message GlobalVolume {
uint64 epoch = 1;
string volume = 2 [
Expand Down
20 changes: 20 additions & 0 deletions x/perp/v2/keeper/dnr.go
Original file line number Diff line number Diff line change
Expand Up @@ -68,6 +68,26 @@ func (intKeyEncoder) Decode(b []byte) (int, math.Int) {

func (intKeyEncoder) Stringify(key math.Int) string { return key.String() }

// maybeUpdateDnREpoch checks if the current epoch hook call matches the
// epoch name that targets discounts and rebates, if it does then we simply
// invoke the StartNewEpoch function to kickstart a new epoch.
// This method is invoked by the AfterEpochEnd hook.
func (k Keeper) maybeUpdateDnREpoch(ctx sdk.Context, epochIdentifier string, number uint64) {
// if epoch name is empty, we just assume DnR is not enabled.
referenceEpochName := k.DnREpochName.GetOr(ctx, "")
if referenceEpochName != epochIdentifier {
return
}
// kickstart new epoch
k.Logger(ctx).Info("updating dnr epoch", "epochIdentifier", epochIdentifier, "number", number)
err := k.StartNewEpoch(ctx, number)
if err != nil {
// in case of error we panic in this case, because state may have been updated
// in a corrupted way.
panic(err)

Check warning on line 87 in x/perp/v2/keeper/dnr.go

View check run for this annotation

Codecov / codecov/patch

x/perp/v2/keeper/dnr.go#L85-L87

Added lines #L85 - L87 were not covered by tests
}
}

// StartNewEpoch is called by the epochs hooks when a new 30day epoch starts.
func (k Keeper) StartNewEpoch(ctx sdk.Context, identifier uint64) error {
// set the current epoch
Expand Down
50 changes: 50 additions & 0 deletions x/perp/v2/keeper/dnr_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,9 @@ import (

"cosmossdk.io/math"
sdk "github.com/cosmos/cosmos-sdk/types"
"github.com/stretchr/testify/require"

"github.com/NibiruChain/nibiru/app"

"github.com/NibiruChain/nibiru/x/common/asset"
"github.com/NibiruChain/nibiru/x/common/denoms"
Expand Down Expand Up @@ -251,3 +254,50 @@ func TestRebates(t *testing.T) {
}
NewTestSuite(t).WithTestCases(tests...).Run()
}

type actionFn func(app *app.NibiruApp, ctx sdk.Context) (outCtx sdk.Context, err error, isMandatory bool)

func (f actionFn) Do(app *app.NibiruApp, ctx sdk.Context) (outCtx sdk.Context, err error, isMandatory bool) {
return f(app, ctx)
}

func TestDnREpoch(t *testing.T) {
dnrEpochIdentifierIs := func(identifier string) actionFn {
return func(app *app.NibiruApp, ctx sdk.Context) (outCtx sdk.Context, err error, isMandatory bool) {
app.PerpKeeperV2.DnREpochName.Set(ctx, identifier)
return ctx, nil, false
}
}

triggerEpoch := func(identifier string, epoch uint64) actionFn {
return func(app *app.NibiruApp, ctx sdk.Context) (outCtx sdk.Context, err error, isMandatory bool) {
app.PerpKeeperV2.AfterEpochEnd(ctx, identifier, epoch)
return ctx, nil, false
}
}

expectDnREpoch := func(epoch uint64) actionFn {
return func(app *app.NibiruApp, ctx sdk.Context) (outCtx sdk.Context, err error, isMandatory bool) {
require.Equal(t, epoch, app.PerpKeeperV2.DnREpoch.GetOr(ctx, 0))
return ctx, nil, false
}
}

tests := TestCases{
TC("DnR epoch with valid identifier").
When(
dnrEpochIdentifierIs("monthly"),
triggerEpoch("monthly", 1)).
Then(
expectDnREpoch(1),
),
TC("DnR epoch with invalid identifier").
When(
dnrEpochIdentifierIs("monthly"),
triggerEpoch("weekly", 1)).
Then(
expectDnREpoch(0),
),
}
NewTestSuite(t).WithTestCases(tests...).Run()
}
3 changes: 2 additions & 1 deletion x/perp/v2/keeper/hooks.go
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,8 @@ import (
func (k Keeper) BeforeEpochStart(_ sdk.Context, _ string, _ uint64) {
}

func (k Keeper) AfterEpochEnd(ctx sdk.Context, epochIdentifier string, _ uint64) {
func (k Keeper) AfterEpochEnd(ctx sdk.Context, epochIdentifier string, number uint64) {
k.maybeUpdateDnREpoch(ctx, epochIdentifier, number)
for _, market := range k.Markets.Iterate(ctx, collections.Range[collections.Pair[asset.Pair, uint64]]{}).Values() {
if !market.Enabled || epochIdentifier != market.FundingRateEpochId {
return
Expand Down
8 changes: 7 additions & 1 deletion x/perp/v2/keeper/keeper.go
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,8 @@ type Keeper struct {

Positions collections.Map[collections.Pair[collections.Pair[asset.Pair, uint64], sdk.AccAddress], types.Position]
ReserveSnapshots collections.Map[collections.Pair[asset.Pair, time.Time], types.ReserveSnapshot]
DnREpoch collections.Item[uint64]
DnREpoch collections.Item[uint64] // Keeps track of the current DnR epoch.
DnREpochName collections.Item[string] // Keeps track of the current DnR epoch identifier, provided by x/epoch.
GlobalVolumes collections.Map[uint64, math.Int] // Keeps track of global volumes for each epoch.
TraderVolumes collections.Map[collections.Pair[sdk.AccAddress, uint64], math.Int] // Keeps track of user volumes for each epoch.
GlobalDiscounts collections.Map[math.Int, math.LegacyDec] // maps a volume level to a discount
Expand Down Expand Up @@ -128,6 +129,10 @@ func NewKeeper(
storeKey, NamespaceCollateral,
common.StringValueEncoder,
),
DnREpochName: collections.NewItem(
storeKey, NamespaceDnrEpochName,
common.StringValueEncoder,
),
}
k.Admin = admin{&k}
return k
Expand All @@ -146,6 +151,7 @@ const (
NamespaceRebatesAllocations
NamespaceMarketLastVersion
NamespaceCollateral
NamespaceDnrEpochName
)

func (k Keeper) Logger(ctx sdk.Context) log.Logger {
Expand Down
3 changes: 3 additions & 0 deletions x/perp/v2/module/genesis.go
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,8 @@ func InitGenesis(ctx sdk.Context, k keeper.Keeper, genState types.GenesisState)

k.DnREpoch.Set(ctx, genState.DnrEpoch)

k.DnREpochName.Set(ctx, genState.DnrEpochName)

for _, m := range genState.Markets {
k.SaveMarket(ctx, m)
}
Expand Down Expand Up @@ -123,6 +125,7 @@ func ExportGenesis(ctx sdk.Context, k keeper.Keeper) *types.GenesisState {
}
genesis.ReserveSnapshots = k.ReserveSnapshots.Iterate(ctx, collections.PairRange[asset.Pair, time.Time]{}).Values()
genesis.DnrEpoch = k.DnREpoch.GetOr(ctx, 0)
genesis.DnrEpochName = k.DnREpochName.GetOr(ctx, "")

// export volumes
volumes := k.TraderVolumes.Iterate(ctx, collections.PairRange[sdk.AccAddress, uint64]{})
Expand Down
4 changes: 4 additions & 0 deletions x/perp/v2/module/genesis_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -104,6 +104,8 @@ func RunTestGenesis(t *testing.T, tc TestCase) {
Epoch: 0,
Amount: sdk.NewCoins(sdk.NewCoin(denoms.NUSD, sdk.NewInt(1_000_000))),
})
app.PerpKeeperV2.DnREpochName.Set(ctx, "weekly")
app.PerpKeeperV2.DnREpoch.Set(ctx, 1)

// create some positions
for _, position := range tc.positions {
Expand Down Expand Up @@ -151,6 +153,8 @@ func RunTestGenesis(t *testing.T, tc TestCase) {
require.Equal(t, genState.CollateralDenom, genStateAfterInit.CollateralDenom)
require.Equal(t, genState.GlobalVolumes, genStateAfterInit.GlobalVolumes)
require.Equal(t, genState.RebatesAllocations, genStateAfterInit.RebatesAllocations)
require.Equal(t, genState.DnrEpochName, genStateAfterInit.DnrEpochName)
require.Equal(t, genState.DnrEpoch, genStateAfterInit.DnrEpoch)
}

func TestNewAppModuleBasic(t *testing.T) {
Expand Down
Loading

0 comments on commit 5b6655a

Please sign in to comment.