Skip to content

Commit

Permalink
feat(x/photon): migration (#55)
Browse files Browse the repository at this point in the history
Relates to #44

- perform module migration to add the photon module in the upgrade
module version map
- register the photon denom metata in the bank module
- add a storeloader for the photon module (required for all new modules)
  • Loading branch information
tbruyelle authored Nov 28, 2024
1 parent 1537446 commit 24a15ad
Show file tree
Hide file tree
Showing 6 changed files with 118 additions and 13 deletions.
3 changes: 2 additions & 1 deletion app/app.go
Original file line number Diff line number Diff line change
Expand Up @@ -51,14 +51,15 @@ import (
"github.com/atomone-hub/atomone/app/keepers"
"github.com/atomone-hub/atomone/app/params"
"github.com/atomone-hub/atomone/app/upgrades"
v2 "github.com/atomone-hub/atomone/app/upgrades/v2"
govtypes "github.com/atomone-hub/atomone/x/gov/types"
)

var (
// DefaultNodeHome default home directories for the application daemon
DefaultNodeHome string

Upgrades = []upgrades.Upgrade{}
Upgrades = []upgrades.Upgrade{v2.Upgrade}
)

var (
Expand Down
23 changes: 23 additions & 0 deletions app/upgrades/v2/constants.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
package v2

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

"github.com/atomone-hub/atomone/app/upgrades"
photontypes "github.com/atomone-hub/atomone/x/photon/types"
)

const (
UpgradeName = "v2"
)

var Upgrade = upgrades.Upgrade{
UpgradeName: UpgradeName,
CreateUpgradeHandler: CreateUpgradeHandler,
StoreUpgrades: store.StoreUpgrades{
Added: []string{
// new module added in v2
photontypes.ModuleName,
},
},
}
66 changes: 66 additions & 0 deletions app/upgrades/v2/upgrades.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,66 @@
package v2

import (
sdk "github.com/cosmos/cosmos-sdk/types"
"github.com/cosmos/cosmos-sdk/types/module"
bankkeeper "github.com/cosmos/cosmos-sdk/x/bank/keeper"
banktypes "github.com/cosmos/cosmos-sdk/x/bank/types"
upgradetypes "github.com/cosmos/cosmos-sdk/x/upgrade/types"

"github.com/atomone-hub/atomone/app/keepers"
)

// CreateUpgradeHandler returns a upgrade handler for AtomOne v2
// which executes the following migrations:
// - add new denom metadata for photon in the bank module store.
func CreateUpgradeHandler(
mm *module.Manager,
configurator module.Configurator,
keepers *keepers.AppKeepers,
) upgradetypes.UpgradeHandler {
return func(ctx sdk.Context, plan upgradetypes.Plan, vm module.VersionMap) (module.VersionMap, error) {
ctx.Logger().Info("Starting module migrations...")
// RunMigrations will detect the add of the photon module, will initiate
// its genesis and will fill the versionMap with its consensus version.
vm, err := mm.RunMigrations(ctx, configurator, vm)
if err != nil {
return vm, err
}
// Add the photon denom metadata to the bank module store
setPhotonDenomMetadata(ctx, keepers.BankKeeper)
ctx.Logger().Info("Upgrade complete")
return vm, nil
}
}

func setPhotonDenomMetadata(ctx sdk.Context, bk bankkeeper.Keeper) {
ctx.Logger().Info("Adding photon denom metadata...")
bk.SetDenomMetaData(ctx, banktypes.Metadata{
Base: "uphoton",
Display: "photon",
Name: "AtomOne Photon",
Symbol: "PHOTON",
Description: "The fee token of AtomOne Hub",
DenomUnits: []*banktypes.DenomUnit{
{
Denom: "uphoton",
Exponent: 0,
Aliases: []string{
"microphoton",
},
},
{
Denom: "mphoton",
Exponent: 3,
Aliases: []string{
"milliphoton",
},
},
{
Denom: "photon",
Exponent: 6,
},
},
})
ctx.Logger().Info("Photon denom metadata added")
}
8 changes: 4 additions & 4 deletions x/photon/keeper/msg_server.go
Original file line number Diff line number Diff line change
Expand Up @@ -42,14 +42,14 @@ func (k msgServer) MintPhoton(goCtx context.Context, msg *types.MsgMintPhoton) (
uphotonSupply = k.bankKeeper.GetSupply(ctx, types.Denom).Amount.ToLegacyDec()
conversionRate = k.conversionRate(ctx, bondDenomSupply, uphotonSupply)
bondDenomToBurn = msg.Amount
uphotonToMint = bondDenomToBurn.Amount.ToLegacyDec().Mul(conversionRate)
uphotonToMint = bondDenomToBurn.Amount.ToLegacyDec().Mul(conversionRate).RoundInt()
)
// If no photon to mint, do not burn bondDenomToBurn, returns an error
if uphotonToMint.IsZero() {
return nil, types.ErrNoMintablePhotons
return nil, types.ErrZeroMintPhotons
}
// If photonToMint + photonSupply > photonMaxSupply, returns an error
if uphotonSupply.Add(uphotonToMint).GT(sdk.NewDec(types.MaxSupply)) {
if uphotonSupply.Add(uphotonToMint.ToLegacyDec()).GT(sdk.NewDec(types.MaxSupply)) {
return nil, types.ErrNotEnoughPhotons
}

Expand All @@ -60,7 +60,7 @@ func (k msgServer) MintPhoton(goCtx context.Context, msg *types.MsgMintPhoton) (
// 4) move PHOTONs from this module address to msg signer address
var (
coinsToBurn = sdk.NewCoins(bondDenomToBurn)
coinsToMint = sdk.NewCoins(sdk.NewCoin(types.Denom, uphotonToMint.RoundInt()))
coinsToMint = sdk.NewCoins(sdk.NewCoin(types.Denom, uphotonToMint))
)
// 1) Send atone to photon module for burn
to, err := sdk.AccAddressFromBech32(msg.ToAddress)
Expand Down
18 changes: 17 additions & 1 deletion x/photon/keeper/msg_server_test.go
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
package keeper_test

import (
"math"
"testing"

"github.com/stretchr/testify/require"
Expand Down Expand Up @@ -64,7 +65,7 @@ func TestMsgServerMintPhoton(t *testing.T) {
Return(sdk.NewInt64Coin(appparams.BondDenom, atoneSupply))
m.BankKeeper.EXPECT().GetSupply(ctx, types.Denom).Return(sdk.NewInt64Coin(types.Denom, types.MaxSupply))
},
expectedErr: "no more photon can be minted",
expectedErr: "no mintable photon after rounding, try higher burn",
},
{
name: "fail: photon_supply+minted>max",
Expand All @@ -81,6 +82,21 @@ func TestMsgServerMintPhoton(t *testing.T) {
},
expectedErr: "not enough photon can be minted",
},
{
name: "fail: atone_supply >> photon_supply",
params: types.Params{MintDisabled: false},
msg: &types.MsgMintPhoton{
ToAddress: toAddress.String(),
Amount: sdk.NewInt64Coin(appparams.BondDenom, 1),
},
setup: func(ctx sdk.Context, m testutil.Mocks) {
m.StakingKeeper.EXPECT().BondDenom(ctx).Return(appparams.BondDenom)
m.BankKeeper.EXPECT().GetSupply(ctx, appparams.BondDenom).
Return(sdk.NewInt64Coin(appparams.BondDenom, math.MaxInt))
m.BankKeeper.EXPECT().GetSupply(ctx, types.Denom).Return(sdk.NewInt64Coin(types.Denom, 0))
},
expectedErr: "no mintable photon after rounding, try higher burn",
},
{
name: "ok: photon_supply=0",
params: types.Params{MintDisabled: false},
Expand Down
13 changes: 6 additions & 7 deletions x/photon/types/errors.go
Original file line number Diff line number Diff line change
Expand Up @@ -6,11 +6,10 @@ import (

// x/photon module sentinel errors
var (
ErrMintDisabled = sdkerrors.Register(ModuleName, 1, "photon mint disabled") //nolint:staticcheck
ErrBurnInvalidDenom = sdkerrors.Register(ModuleName, 2, "invalid burned amount denom: expected bond denom") //nolint:staticcheck
ErrNoMintablePhotons = sdkerrors.Register(ModuleName, 3, "no more photon can be minted") //nolint:staticcheck
ErrNotEnoughPhotons = sdkerrors.Register(ModuleName, 4, "not enough photon can be minted") //nolint:staticcheck
ErrTooManyFeeCoins = sdkerrors.Register(ModuleName, 5, "too many fee coins, only accepts fees in one denom") //nolint:staticcheck
ErrInvalidFeeToken = sdkerrors.Register(ModuleName, 6, "invalid fee token") //nolint:staticcheck

ErrMintDisabled = sdkerrors.Register(ModuleName, 1, "photon mint disabled") //nolint:staticcheck
ErrBurnInvalidDenom = sdkerrors.Register(ModuleName, 2, "invalid burned amount denom: expected bond denom") //nolint:staticcheck
ErrZeroMintPhotons = sdkerrors.Register(ModuleName, 3, "no mintable photon after rounding, try higher burn") //nolint:staticcheck
ErrNotEnoughPhotons = sdkerrors.Register(ModuleName, 4, "not enough photon can be minted") //nolint:staticcheck
ErrTooManyFeeCoins = sdkerrors.Register(ModuleName, 5, "too many fee coins, only accepts fees in one denom") //nolint:staticcheck
ErrInvalidFeeToken = sdkerrors.Register(ModuleName, 6, "invalid fee token") //nolint:staticcheck
)

0 comments on commit 24a15ad

Please sign in to comment.