Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat(incentives): rollapp gauges upgrade handler and burn creation fee #1113

Merged
4 changes: 2 additions & 2 deletions app/apptesting/test_suite.go
Original file line number Diff line number Diff line change
Expand Up @@ -117,8 +117,8 @@ func (s *KeeperTestHelper) CreateSequencerByPubkey(ctx sdk.Context, rollappId st
func (s *KeeperTestHelper) PostStateUpdate(ctx sdk.Context, rollappId, seqAddr string, startHeight, numOfBlocks uint64) (lastHeight uint64, err error) {
var bds rollapptypes.BlockDescriptors
bds.BD = make([]rollapptypes.BlockDescriptor, numOfBlocks)
for k := 0; k < int(numOfBlocks); k++ {
bds.BD[k] = rollapptypes.BlockDescriptor{Height: startHeight + uint64(k), Timestamp: time.Now().UTC()}
for k := uint64(0); k < numOfBlocks; k++ {
bds.BD[k] = rollapptypes.BlockDescriptor{Height: startHeight + k, Timestamp: time.Now().UTC()}
}

updateState := rollapptypes.MsgUpdateState{
Expand Down
1 change: 0 additions & 1 deletion app/keepers/keepers.go
Original file line number Diff line number Diff line change
Expand Up @@ -378,7 +378,6 @@ func (a *AppKeepers) InitKeepers(
a.BankKeeper,
a.LockupKeeper,
a.EpochsKeeper,
a.DistrKeeper,
a.TxFeesKeeper,
a.RollappKeeper,
)
Expand Down
19 changes: 16 additions & 3 deletions app/upgrades/v4/upgrade.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,6 @@ package v4
import (
"github.com/cometbft/cometbft/crypto"
"github.com/cosmos/cosmos-sdk/baseapp"
epochskeeper "github.com/osmosis-labs/osmosis/v15/x/epochs/keeper"

sdk "github.com/cosmos/cosmos-sdk/types"
"github.com/cosmos/cosmos-sdk/types/module"
Expand All @@ -23,8 +22,8 @@ import (

evmtypes "github.com/evmos/ethermint/x/evm/types"
feemarkettypes "github.com/evmos/ethermint/x/feemarket/types"
epochskeeper "github.com/osmosis-labs/osmosis/v15/x/epochs/keeper"

// Ethermint modules
"github.com/dymensionxyz/dymension/v3/app/keepers"
"github.com/dymensionxyz/dymension/v3/app/upgrades"
delayedackkeeper "github.com/dymensionxyz/dymension/v3/x/delayedack/keeper"
Expand Down Expand Up @@ -66,7 +65,9 @@ func CreateUpgradeHandler(
}
migrateIncentivesParams(ctx, keepers.IncentivesKeeper)

// TODO: create rollapp gauges for each existing rollapp (https://github.com/dymensionxyz/dymension/issues/1005)
if err := migrateRollappGauges(ctx, keepers.RollappKeeper, keepers.IncentivesKeeper); err != nil {
return nil, err
}

// Start running the module migrations
logger.Debug("running module migrations ...")
Expand Down Expand Up @@ -139,6 +140,18 @@ func migrateRollappParams(ctx sdk.Context, rollappkeeper *rollappkeeper.Keeper)
rollappkeeper.SetParams(ctx, params)
}

// migrateRollappGauges creates a gauge for each rollapp in the store
func migrateRollappGauges(ctx sdk.Context, rollappkeeper *rollappkeeper.Keeper, incentivizeKeeper *incentiveskeeper.Keeper) error {
rollapps := rollappkeeper.GetAllRollapps(ctx)
for _, rollapp := range rollapps {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

should we not skip frozen rollapps?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I prefer not.
It doesn't really matter, as this gaguge won't be active for frozen rollapp, but it breaks the assumption of rollapp gauge for each rollapp

_, err := incentivizeKeeper.CreateRollappGauge(ctx, rollapp.RollappId)
if err != nil {
return err
}
}
return nil
}

func migrateRollapps(ctx sdk.Context, rollappkeeper *rollappkeeper.Keeper) error {
list := rollappkeeper.GetAllRollapps(ctx)
for _, oldRollapp := range list {
Expand Down
40 changes: 38 additions & 2 deletions app/upgrades/v4/upgrade_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -121,9 +121,12 @@ func (s *UpgradeTestSuite) TestUpgrade() {
return
}

s.validateStreamerMigration()
// Check rollapp gauges
if err = s.validateRollappGaugesMigration(); err != nil {
return
}

// TODO: check for rollapp gauges creation
s.validateStreamerMigration()

return
},
Expand Down Expand Up @@ -192,6 +195,39 @@ func (s *UpgradeTestSuite) validateRollappsMigration(numRoll int) error {
return nil
}

// validate rollapp gauges
func (s *UpgradeTestSuite) validateRollappGaugesMigration() error {
rollappMap := make(map[string]bool) // Create a map to store rollappId<->gaugeCreated

rollapps := s.App.RollappKeeper.GetAllRollapps(s.Ctx)
for _, rollapp := range rollapps {
rollappMap[rollapp.RollappId] = false // false until gauge is validated
}

gauges := s.App.IncentivesKeeper.GetGauges(s.Ctx)
if len(gauges) != len(rollapps) {
return fmt.Errorf("rollapp gauges not created for all rollapps")
mtsitrin marked this conversation as resolved.
Show resolved Hide resolved
}

// Check that for each rollapp there exists a rollapp gauge
for _, gauge := range gauges {
if gauge.GetRollapp() != nil {
gaugeExists, ok := rollappMap[gauge.GetRollapp().RollappId]
if !ok {
return fmt.Errorf("rollapp gauge for unknown rollapp %s", gauge.GetRollapp().RollappId)
}

if gaugeExists {
return fmt.Errorf("rollapp gauge for rollapp %s already created", gauge.GetRollapp().RollappId)
}

rollappMap[gauge.GetRollapp().RollappId] = true
}
}

return nil
}

func (s *UpgradeTestSuite) validateSequencersMigration(numSeq int) error {
testSeqs := s.seedSequencers(numSeq)
expectSequencers := make([]sequencertypes.Sequencer, len(testSeqs))
Expand Down
3 changes: 2 additions & 1 deletion x/incentives/client/cli/cli_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,9 +5,10 @@ import (

"github.com/cosmos/cosmos-sdk/types/query"

"github.com/osmosis-labs/osmosis/v15/osmoutils/osmocli"

"github.com/dymensionxyz/dymension/v3/x/incentives/client/cli"
"github.com/dymensionxyz/dymension/v3/x/incentives/types"
"github.com/osmosis-labs/osmosis/v15/osmoutils/osmocli"
)

func TestGetCmdGauges(t *testing.T) {
Expand Down
3 changes: 2 additions & 1 deletion x/incentives/client/cli/query.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,9 @@ package cli
import (
"github.com/spf13/cobra"

"github.com/dymensionxyz/dymension/v3/x/incentives/types"
"github.com/osmosis-labs/osmosis/v15/osmoutils/osmocli"

"github.com/dymensionxyz/dymension/v3/x/incentives/types"
)

// GetQueryCmd returns the query commands for this module.
Expand Down
5 changes: 2 additions & 3 deletions x/incentives/keeper/distribute.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,11 +4,10 @@ import (
"fmt"

errorsmod "cosmossdk.io/errors"

sdk "github.com/cosmos/cosmos-sdk/types"
sdkerrors "github.com/cosmos/cosmos-sdk/types/errors"
"github.com/dymensionxyz/dymension/v3/x/incentives/types"

sdk "github.com/cosmos/cosmos-sdk/types"
"github.com/dymensionxyz/dymension/v3/x/incentives/types"
)

// Distribute distributes coins from an array of gauges.
Expand Down
5 changes: 0 additions & 5 deletions x/incentives/keeper/export_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -35,8 +35,3 @@ func (k Keeper) MoveUpcomingGaugeToActiveGauge(ctx sdk.Context, gauge types.Gaug
func (k Keeper) MoveActiveGaugeToFinishedGauge(ctx sdk.Context, gauge types.Gauge) error {
return k.moveActiveGaugeToFinishedGauge(ctx, gauge)
}

// ChargeFeeIfSufficientFeeDenomBalance see chargeFeeIfSufficientFeeDenomBalance spec.
func (k Keeper) ChargeFeeIfSufficientFeeDenomBalance(ctx sdk.Context, address sdk.AccAddress, fee sdk.Int, gaugeCoins sdk.Coins) error {
return k.chargeFeeIfSufficientFeeDenomBalance(ctx, address, fee, gaugeCoins)
}
9 changes: 1 addition & 8 deletions x/incentives/keeper/gauge.go
Original file line number Diff line number Diff line change
Expand Up @@ -110,14 +110,7 @@ func (k Keeper) CreateGauge(ctx sdk.Context, isPerpetual bool, owner sdk.AccAddr
return 0, fmt.Errorf("denom does not exist: %s", distrTo.Denom)
}

gauge := types.Gauge{
Id: k.GetLastGaugeID(ctx) + 1,
IsPerpetual: isPerpetual,
DistributeTo: &types.Gauge_Asset{Asset: &distrTo},
Coins: coins,
StartTime: startTime,
NumEpochsPaidOver: numEpochsPaidOver,
}
gauge := types.NewAssetGauge(k.GetLastGaugeID(ctx)+1, isPerpetual, distrTo, coins, startTime, numEpochsPaidOver)

if err := k.bk.SendCoinsFromAccountToModule(ctx, owner, types.ModuleName, gauge.Coins); err != nil {
return 0, err
Expand Down
9 changes: 1 addition & 8 deletions x/incentives/keeper/gauge_rollapp.go
Original file line number Diff line number Diff line change
Expand Up @@ -16,14 +16,7 @@ func (k Keeper) CreateRollappGauge(ctx sdk.Context, rollappId string) (uint64, e
return 0, fmt.Errorf("rollapp %s not found", rollappId)
}

gauge := types.Gauge{
Id: k.GetLastGaugeID(ctx) + 1,
IsPerpetual: true,
DistributeTo: &types.Gauge_Rollapp{
Rollapp: &types.RollappGauge{RollappId: rollappId},
},
NumEpochsPaidOver: 1,
}
gauge := types.NewRollappGauge(k.GetLastGaugeID(ctx)+1, rollappId)

err := k.setGauge(ctx, &gauge)
if err != nil {
Expand Down
97 changes: 0 additions & 97 deletions x/incentives/keeper/gauge_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,6 @@ import (
sdk "github.com/cosmos/cosmos-sdk/types"
"github.com/stretchr/testify/suite"

"github.com/dymensionxyz/dymension/v3/app/apptesting"
"github.com/dymensionxyz/dymension/v3/x/incentives/types"
lockuptypes "github.com/dymensionxyz/dymension/v3/x/lockup/types"
)
Expand Down Expand Up @@ -225,99 +224,3 @@ func (suite *KeeperTestSuite) TestGaugeOperations() {
}
}
}

func (suite *KeeperTestSuite) TestChargeFeeIfSufficientFeeDenomBalance() {
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

const baseFee = int64(100)

testcases := map[string]struct {
accountBalanceToFund sdk.Coin
feeToCharge int64
gaugeCoins sdk.Coins

expectError bool
}{
"fee + base denom gauge coin == acount balance, success": {
accountBalanceToFund: sdk.NewCoin("adym", sdk.NewInt(baseFee)),
feeToCharge: baseFee / 2,
gaugeCoins: sdk.NewCoins(sdk.NewCoin("adym", sdk.NewInt(baseFee/2))),
},
"fee + base denom gauge coin < acount balance, success": {
accountBalanceToFund: sdk.NewCoin("adym", sdk.NewInt(baseFee)),
feeToCharge: baseFee/2 - 1,
gaugeCoins: sdk.NewCoins(sdk.NewCoin("adym", sdk.NewInt(baseFee/2))),
},
"fee + base denom gauge coin > acount balance, error": {
accountBalanceToFund: sdk.NewCoin("adym", sdk.NewInt(baseFee)),
feeToCharge: baseFee/2 + 1,
gaugeCoins: sdk.NewCoins(sdk.NewCoin("adym", sdk.NewInt(baseFee/2))),
expectError: true,
},
"fee + base denom gauge coin < acount balance, custom values, success": {
accountBalanceToFund: sdk.NewCoin("adym", sdk.NewInt(11793193112)),
feeToCharge: 55,
gaugeCoins: sdk.NewCoins(sdk.NewCoin("adym", sdk.NewInt(328812))),
},
"account funded with coins other than base denom, error": {
accountBalanceToFund: sdk.NewCoin("usdc", sdk.NewInt(baseFee)),
feeToCharge: baseFee,
gaugeCoins: sdk.NewCoins(sdk.NewCoin("adym", sdk.NewInt(baseFee/2))),
expectError: true,
},
"fee == account balance, no gauge coins, success": {
accountBalanceToFund: sdk.NewCoin("adym", sdk.NewInt(baseFee)),
feeToCharge: baseFee,
},
"gauge coins == account balance, no fee, success": {
accountBalanceToFund: sdk.NewCoin("adym", sdk.NewInt(baseFee)),
gaugeCoins: sdk.NewCoins(sdk.NewCoin("adym", sdk.NewInt(baseFee))),
},
"fee == account balance, gauge coins in denom other than base, success": {
accountBalanceToFund: sdk.NewCoin("adym", sdk.NewInt(baseFee)),
feeToCharge: baseFee,
gaugeCoins: sdk.NewCoins(sdk.NewCoin("usdc", sdk.NewInt(baseFee*2))),
},
"fee + gauge coins == account balance, multiple gauge coins, one in denom other than base, success": {
accountBalanceToFund: sdk.NewCoin("adym", sdk.NewInt(baseFee)),
feeToCharge: baseFee / 2,
gaugeCoins: sdk.NewCoins(sdk.NewCoin("usdc", sdk.NewInt(baseFee*2)), sdk.NewCoin("adym", sdk.NewInt(baseFee/2))),
},
}

for name, tc := range testcases {
suite.Run(name, func() {
suite.SetupTest()

err := suite.App.TxFeesKeeper.SetBaseDenom(suite.Ctx, "adym")
suite.Require().NoError(err)

testAccount := apptesting.CreateRandomAccounts(1)[0]
ctx := suite.Ctx
incentivesKeepers := suite.App.IncentivesKeeper
bankKeeper := suite.App.BankKeeper

// Pre-fund account.
// suite.FundAcc(testAccount, testutil.DefaultAcctFunds)
suite.FundAcc(testAccount, sdk.NewCoins(tc.accountBalanceToFund))

oldBalanceAmount := bankKeeper.GetBalance(ctx, testAccount, "adym").Amount

// System under test.
err = incentivesKeepers.ChargeFeeIfSufficientFeeDenomBalance(ctx, testAccount, sdk.NewInt(tc.feeToCharge), tc.gaugeCoins)

// Assertions.
newBalanceAmount := bankKeeper.GetBalance(ctx, testAccount, "adym").Amount
if tc.expectError {
suite.Require().Error(err)

// check account balance unchanged
suite.Require().Equal(oldBalanceAmount, newBalanceAmount)
} else {
suite.Require().NoError(err)

// check account balance changed.
expectedNewBalanceAmount := oldBalanceAmount.Sub(sdk.NewInt(tc.feeToCharge))
suite.Require().Equal(expectedNewBalanceAmount.String(), newBalanceAmount.String())
}
})
}
}
4 changes: 1 addition & 3 deletions x/incentives/keeper/keeper.go
Original file line number Diff line number Diff line change
Expand Up @@ -22,13 +22,12 @@ type Keeper struct {
bk types.BankKeeper
lk types.LockupKeeper
ek types.EpochKeeper
ck types.CommunityPoolKeeper
tk types.TxFeesKeeper
rk types.RollappKeeper
}

// NewKeeper returns a new instance of the incentive module keeper struct.
func NewKeeper(storeKey storetypes.StoreKey, paramSpace paramtypes.Subspace, bk types.BankKeeper, lk types.LockupKeeper, ek types.EpochKeeper, ck types.CommunityPoolKeeper, txfk types.TxFeesKeeper, rk types.RollappKeeper) *Keeper {
func NewKeeper(storeKey storetypes.StoreKey, paramSpace paramtypes.Subspace, bk types.BankKeeper, lk types.LockupKeeper, ek types.EpochKeeper, txfk types.TxFeesKeeper, rk types.RollappKeeper) *Keeper {
if !paramSpace.HasKeyTable() {
paramSpace = paramSpace.WithKeyTable(types.ParamKeyTable())
}
Expand All @@ -39,7 +38,6 @@ func NewKeeper(storeKey storetypes.StoreKey, paramSpace paramtypes.Subspace, bk
bk: bk,
lk: lk,
ek: ek,
ck: ck,
tk: txfk,
rk: rk,
}
Expand Down
Loading
Loading