diff --git a/app/upgrade.go b/app/upgrade.go index dc087b564..d9bc26935 100644 --- a/app/upgrade.go +++ b/app/upgrade.go @@ -200,7 +200,7 @@ func getCosmosSDKv44UpgradeHandler(app *WasmApp) upgradeData { // Custom modules "burner": 1, // the burner module has no state but it implements AppModule so its better to put it here - "configuration": 1, + "configuration": 1, // the configuration module will be updated to version 2 (adding the escrow conf) "starname": 1, "wasm": 1, diff --git a/x/configuration/genesis.go b/x/configuration/genesis.go index 79c8210bb..a7fa0ed0e 100644 --- a/x/configuration/genesis.go +++ b/x/configuration/genesis.go @@ -2,7 +2,6 @@ package configuration import ( sdk "github.com/cosmos/cosmos-sdk/types" - "github.com/iov-one/starnamed/x/configuration/types" ) diff --git a/x/configuration/migrations/v2/migrate.go b/x/configuration/migrations/v2/migrate.go new file mode 100644 index 000000000..774f9fe93 --- /dev/null +++ b/x/configuration/migrations/v2/migrate.go @@ -0,0 +1,42 @@ +package v2 + +import ( + "fmt" + "github.com/cosmos/cosmos-sdk/codec" + sdk "github.com/cosmos/cosmos-sdk/types" + "github.com/iov-one/starnamed/x/configuration/types" +) + +// MigrateStore performs in-place store migrations from version 1 to version 2 +// This adds the escrow parameters to the configuration +func MigrateStore(ctx sdk.Context, storeKey sdk.StoreKey, cdc codec.BinaryCodec) error { + store := ctx.KVStore(storeKey) + + confBytes := store.Get([]byte(types.ConfigKey)) + if confBytes == nil { + return fmt.Errorf("no configuration available") + } + + feesBytes := store.Get([]byte(types.FeeKey)) + if feesBytes == nil { + return fmt.Errorf("no fees available") + } + + defaultState := types.DefaultGenesisState() + + // Get the default state for the configuration + config := defaultState.Config + // Overwrite with the values present in the chain for old fields + cdc.MustUnmarshal(confBytes, &config) + + // Get the default state for the fees + fees := defaultState.Fees + // Overwrite with the values present in the chain for old fields + cdc.MustUnmarshal(feesBytes, &fees) + + // Write back the configuration and the fees + store.Set([]byte(types.ConfigKey), cdc.MustMarshal(&config)) + store.Set([]byte(types.FeeKey), cdc.MustMarshal(&fees)) + + return nil +} \ No newline at end of file diff --git a/x/configuration/migrator.go b/x/configuration/migrator.go new file mode 100644 index 000000000..ff47121d1 --- /dev/null +++ b/x/configuration/migrator.go @@ -0,0 +1,21 @@ +package configuration + +import ( + sdk "github.com/cosmos/cosmos-sdk/types" + v2 "github.com/iov-one/starnamed/x/configuration/migrations/v2" +) + +// Migrator is a struct for handling in-place store migrations. +type Migrator struct { + keeper Keeper +} + +// NewMigrator returns a new Migrator. +func NewMigrator(keeper Keeper) Migrator { + return Migrator{keeper: keeper} +} + +// Migrate1to2 migrates from version 1 to 2. +func (m Migrator) Migrate1to2(ctx sdk.Context) error { + return v2.MigrateStore(ctx, m.keeper.storeKey, m.keeper.cdc) +} \ No newline at end of file diff --git a/x/configuration/module.go b/x/configuration/module.go index 135dd9643..d8334700f 100644 --- a/x/configuration/module.go +++ b/x/configuration/module.go @@ -3,6 +3,7 @@ package configuration import ( "context" "encoding/json" + sdkerrors "github.com/cosmos/cosmos-sdk/types/errors" "github.com/cosmos/cosmos-sdk/client" "github.com/cosmos/cosmos-sdk/codec" @@ -43,7 +44,7 @@ func (AppModuleBasic) Name() string { return types.ModuleName } // DefaultGenesis returns default genesis state as raw bytes for the configuration module. func (AppModuleBasic) DefaultGenesis(cdc codec.JSONCodec) json.RawMessage { - defaultGenesisState := DefaultGenesisState() + defaultGenesisState := types.DefaultGenesisState() return cdc.MustMarshalJSON(&defaultGenesisState) } @@ -54,7 +55,7 @@ func (b AppModuleBasic) ValidateGenesis(marshaler codec.JSONCodec, config client if err != nil { return err } - return ValidateGenesis(data) + return types.ValidateGenesis(data) } // RegisterRESTRoutes registers the REST routes for the configuration module. @@ -97,6 +98,11 @@ func (AppModule) Name() string { return types.ModuleName } // RegisterServices allows a module to register services func (a AppModule) RegisterServices(configurator module.Configurator) { types.RegisterQueryServer(configurator.QueryServer(), NewQuerier(&a.keeper)) + + m := NewMigrator(a.keeper) + if err := configurator.RegisterMigration(types.ModuleName, 1, m.Migrate1to2); err != nil { + panic(sdkerrors.Wrapf(err, "Error while registering the configuration module migration from version 1 to 2")) + } } // LegacyQuerierHandler provides an sdk.Querier object that uses the legacy amino codec. @@ -138,4 +144,4 @@ func (a AppModule) ExportGenesis(ctx sdk.Context, cdc codec.JSONCodec) json.RawM } // ConsensusVersion implements AppModule/ConsensusVersion. -func (AppModule) ConsensusVersion() uint64 { return 1 } +func (AppModule) ConsensusVersion() uint64 { return 2 } diff --git a/x/configuration/types/genesis.go b/x/configuration/types/genesis.go new file mode 100644 index 000000000..059136eab --- /dev/null +++ b/x/configuration/types/genesis.go @@ -0,0 +1,63 @@ +package types + +import ( + sdk "github.com/cosmos/cosmos-sdk/types" +) + +// NewGenesisState is GenesisState constructor +func NewGenesisState(conf Config, fees *Fees) GenesisState { + return GenesisState{ + Config: conf, + Fees: *fees, + } +} + +// ValidateGenesis makes sure that the genesis state is valid +func ValidateGenesis(data GenesisState) error { + conf := data.Config + if err := conf.Validate(); err != nil { + return err + } + if err := data.Fees.Validate(); err != nil { + return err + } + return nil +} + +// DefaultGenesisState returns the default genesis state +// TODO this needs to be updated, although it will be imported from iovns chain +func DefaultGenesisState() GenesisState { + // set default configs + config := Config{ + Configurer: "star1d3lhm5vtta78cm7c7ytzqh7z5pcgktmautntqv", // msig1 + ValidDomainName: "^[-_a-z0-9]{4,16}$", + ValidAccountName: "^[-_\\.a-z0-9]{1,64}$", + ValidURI: "^[-a-z0-9A-Z:]+$", + ValidResource: "^[a-z0-9A-Z]+$", + DomainRenewalPeriod: 31557600 * 1e9, + DomainRenewalCountMax: 2, + DomainGracePeriod: 2592000 * 1e9, + AccountRenewalPeriod: 31557600 * 1e9, + AccountRenewalCountMax: 3, + AccountGracePeriod: 2592000 * 1e9, + ResourcesMax: 3, + CertificateSizeMax: 10000, + CertificateCountMax: 3, + MetadataSizeMax: 86400, + EscrowCommission: sdk.NewDecFromInt(sdk.NewInt(1)).QuoInt(sdk.NewInt(100)), // 1% + EscrowBroker: "star1nrnx8mft8mks3l2akduxdjlf8rwqs8r9l36a78", // to IOV msig account + EscrowMaxPeriod: 7890000 * 1e9, // 3 months + } + // set fees + // add domain module fees + feeCoinDenom := "tiov" // set coin denom used for fees + // generate new fees + fees := NewFees() + // set default fees + fees.SetDefaults(feeCoinDenom) + // return genesis + return GenesisState{ + Config: config, + Fees: *fees, + } +} diff --git a/x/escrow/test/suite.go b/x/escrow/test/suite.go index bca305cd0..a8c5ffcf7 100644 --- a/x/escrow/test/suite.go +++ b/x/escrow/test/suite.go @@ -2,6 +2,7 @@ package test import ( "encoding/hex" + configurationtypes "github.com/iov-one/starnamed/x/configuration/types" "strings" "testing" "time" @@ -213,7 +214,7 @@ func NewTestKeeper(coinHolders []sdk.AccAddress, isModuleEnabled bool) (keeper.K defaultFees.SetDefaults(Denom) configKeeper.SetFees(ctx, defaultFees) - defaultConfig := configuration.DefaultGenesisState().Config + defaultConfig := configurationtypes.DefaultGenesisState().Config configKeeper.SetConfig(ctx, defaultConfig) // register blocked addresses