diff --git a/demo/app/app.go b/demo/app/app.go index fb17fcf0..40e3e1a5 100644 --- a/demo/app/app.go +++ b/demo/app/app.go @@ -112,7 +112,7 @@ import ( ibcfee "github.com/cosmos/ibc-go/v7/modules/apps/29-fee" ibcfeekeeper "github.com/cosmos/ibc-go/v7/modules/apps/29-fee/keeper" ibcfeetypes "github.com/cosmos/ibc-go/v7/modules/apps/29-fee/types" - transfer "github.com/cosmos/ibc-go/v7/modules/apps/transfer" + "github.com/cosmos/ibc-go/v7/modules/apps/transfer" ibctransferkeeper "github.com/cosmos/ibc-go/v7/modules/apps/transfer/keeper" ibctransfertypes "github.com/cosmos/ibc-go/v7/modules/apps/transfer/types" ibc "github.com/cosmos/ibc-go/v7/modules/core" @@ -871,12 +871,6 @@ func NewMeshApp( if err := app.WasmKeeper.InitializePinnedCodes(ctx); err != nil { tmos.Exit(fmt.Sprintf("failed initialize pinned codes %s", err)) } - - // todo: remove set-params and initialize via genesis - if err := app.MeshSecKeeper.SetParams(ctx, meshsectypes.DefaultParams(sdk.DefaultBondDenom)); err != nil { - tmos.Exit(fmt.Sprintf("failed to set mesh params: %s", err)) - } - } return app @@ -1094,6 +1088,7 @@ func initParamsKeeper(appCodec codec.BinaryCodec, legacyAmino *codec.LegacyAmino paramsKeeper.Subspace(icahosttypes.SubModuleName) paramsKeeper.Subspace(icacontrollertypes.SubModuleName) paramsKeeper.Subspace(wasm.ModuleName) + paramsKeeper.Subspace(meshsectypes.ModuleName) return paramsKeeper } diff --git a/docs/proto/proto-docs.md b/docs/proto/proto-docs.md index c43a980e..1841ad19 100644 --- a/docs/proto/proto-docs.md +++ b/docs/proto/proto-docs.md @@ -8,6 +8,9 @@ - [Params](#osmosis.meshsecurity.v1beta1.Params) - [VirtualStakingMaxCapInfo](#osmosis.meshsecurity.v1beta1.VirtualStakingMaxCapInfo) +- [osmosis/meshsecurity/v1beta1/genesis.proto](#osmosis/meshsecurity/v1beta1/genesis.proto) + - [GenesisState](#osmosis.meshsecurity.v1beta1.GenesisState) + - [osmosis/meshsecurity/v1beta1/query.proto](#osmosis/meshsecurity/v1beta1/query.proto) - [QueryParamsRequest](#osmosis.meshsecurity.v1beta1.QueryParamsRequest) - [QueryParamsResponse](#osmosis.meshsecurity.v1beta1.QueryParamsResponse) @@ -69,6 +72,37 @@ virtual staking max cap + + + + + + + + + + + +
+ +## osmosis/meshsecurity/v1beta1/genesis.proto + + + + + +### GenesisState +GenesisState defines meshsecurity module's genesis state. + + +| Field | Type | Label | Description | +| ----- | ---- | ----- | ----------- | +| `params` | [Params](#osmosis.meshsecurity.v1beta1.Params) | | | + + + + + diff --git a/proto/osmosis/meshsecurity/v1beta1/genesis.proto b/proto/osmosis/meshsecurity/v1beta1/genesis.proto new file mode 100644 index 00000000..3b70c15c --- /dev/null +++ b/proto/osmosis/meshsecurity/v1beta1/genesis.proto @@ -0,0 +1,18 @@ +syntax = "proto3"; +package osmosis.meshsecurity.v1beta1; + +import "osmosis/meshsecurity/v1beta1/meshsecurity.proto"; +import "gogoproto/gogo.proto"; +import "amino/amino.proto"; + +option go_package = "github.com/osmosis-labs/mesh-security-sdk/x/meshsecurity/types"; +option (gogoproto.goproto_getters_all) = false; +option (gogoproto.equal_all) = false; + +// GenesisState defines meshsecurity module's genesis state. +message GenesisState { + option (gogoproto.equal) = true; + + Params params = 1 + [ (gogoproto.nullable) = false, (amino.dont_omitempty) = true ]; +} diff --git a/x/meshsecurity/keeper/genesis.go b/x/meshsecurity/keeper/genesis.go new file mode 100644 index 00000000..e669d0c3 --- /dev/null +++ b/x/meshsecurity/keeper/genesis.go @@ -0,0 +1,18 @@ +package keeper + +import ( + sdk "github.com/cosmos/cosmos-sdk/types" + + "github.com/osmosis-labs/mesh-security-sdk/x/meshsecurity/types" +) + +func (k Keeper) InitGenesis(ctx sdk.Context, data types.GenesisState) { + if err := k.SetParams(ctx, data.Params); err != nil { + panic(err) + } +} + +func (k Keeper) ExportGenesis(ctx sdk.Context) *types.GenesisState { + params := k.GetParams(ctx) + return types.NewGenesisState(params) +} diff --git a/x/meshsecurity/keeper/genesis_test.go b/x/meshsecurity/keeper/genesis_test.go new file mode 100644 index 00000000..1b4b5792 --- /dev/null +++ b/x/meshsecurity/keeper/genesis_test.go @@ -0,0 +1,67 @@ +package keeper + +import ( + "cosmossdk.io/math" + sdk "github.com/cosmos/cosmos-sdk/types" + "github.com/stretchr/testify/assert" + "github.com/stretchr/testify/require" + "testing" + + "github.com/osmosis-labs/mesh-security-sdk/x/meshsecurity/types" +) + +func TestInitGenesis(t *testing.T) { + specs := map[string]struct { + state types.GenesisState + expErr bool + }{ + "custom param, should pass": { + state: types.GenesisState{ + Params: types.Params{ + TotalContractsMaxCap: sdk.NewCoin(sdk.DefaultBondDenom, math.NewInt(15_000_000_000)), + EpochLength: 2_000, + MaxGasEndBlocker: 600_000, + }, + }, + expErr: false, + }, + "custom small value param, should pass": { + state: types.GenesisState{ + Params: types.Params{ + TotalContractsMaxCap: sdk.NewCoin(sdk.DefaultBondDenom, math.NewInt(1_000_000)), + EpochLength: 20, + MaxGasEndBlocker: 10_000, + }, + }, + expErr: false, + }, + } + + for name, spec := range specs { + t.Run(name, func(t *testing.T) { + pCtx, keepers := CreateDefaultTestInput(t) + k := keepers.MeshKeeper + + k.InitGenesis(pCtx, spec.state) + + p := k.GetParams(pCtx) + assert.Equal(t, spec.state.Params.MaxGasEndBlocker, p.MaxGasEndBlocker) + assert.Equal(t, spec.state.Params.EpochLength, p.EpochLength) + assert.Equal(t, spec.state.Params.TotalContractsMaxCap, p.TotalContractsMaxCap) + }) + } +} + +func TestExportGenesis(t *testing.T) { + pCtx, keepers := CreateDefaultTestInput(t) + k := keepers.MeshKeeper + params := types.DefaultParams(sdk.DefaultBondDenom) + + err := k.SetParams(pCtx, params) + require.NoError(t, err) + + exported := k.ExportGenesis(pCtx) + assert.Equal(t, params.MaxGasEndBlocker, exported.Params.MaxGasEndBlocker) + assert.Equal(t, params.EpochLength, exported.Params.EpochLength) + assert.Equal(t, params.TotalContractsMaxCap, exported.Params.TotalContractsMaxCap) +} diff --git a/x/meshsecurity/module.go b/x/meshsecurity/module.go index 7732b2d8..c717c5d6 100644 --- a/x/meshsecurity/module.go +++ b/x/meshsecurity/module.go @@ -3,6 +3,7 @@ package meshsecurity import ( "context" "encoding/json" + "fmt" abci "github.com/cometbft/cometbft/abci/types" @@ -49,12 +50,17 @@ func (AppModuleBasic) Name() string { // DefaultGenesis returns default genesis state as raw bytes for the mesh-security // module. func (AppModuleBasic) DefaultGenesis(cdc codec.JSONCodec) json.RawMessage { - return nil + return cdc.MustMarshalJSON(types.DefaultGenesisState(sdk.DefaultBondDenom)) } // ValidateGenesis performs genesis state validation for the mesh-security module. -func (b AppModuleBasic) ValidateGenesis(marshaler codec.JSONCodec, _ client.TxEncodingConfig, message json.RawMessage) error { - return nil +func (b AppModuleBasic) ValidateGenesis(cdc codec.JSONCodec, _ client.TxEncodingConfig, bz json.RawMessage) error { + var data types.GenesisState + if err := cdc.UnmarshalJSON(bz, &data); err != nil { + return fmt.Errorf("failed to unmarshal %s genesis state: %w", types.ModuleName, err) + } + + return types.ValidateGenesis(&data) } // GetTxCmd returns the root tx command for the mesh-security module. @@ -111,6 +117,20 @@ func (am AppModule) RegisterServices(cfg module.Configurator) { func (am AppModule) RegisterInvariants(ir sdk.InvariantRegistry) { } +// InitGenesis performs genesis initialization for the mesh-security module. It returns +// no validator updates. +func (am AppModule) InitGenesis(ctx sdk.Context, cdc codec.JSONCodec, bz json.RawMessage) []abci.ValidatorUpdate { + var data types.GenesisState + cdc.MustUnmarshalJSON(bz, &data) + am.k.InitGenesis(ctx, data) + return []abci.ValidatorUpdate{} +} + +// ExportGenesis returns the exported genesis state as raw bytes for the mesh-security +func (am AppModule) ExportGenesis(ctx sdk.Context, cdc codec.JSONCodec) json.RawMessage { + return cdc.MustMarshalJSON(am.k.ExportGenesis(ctx)) +} + // QuerierRoute returns the bank module's querier route name. func (AppModule) QuerierRoute() string { return types.RouterKey diff --git a/x/meshsecurity/types/genesis.go b/x/meshsecurity/types/genesis.go new file mode 100644 index 00000000..76545112 --- /dev/null +++ b/x/meshsecurity/types/genesis.go @@ -0,0 +1,15 @@ +package types + +func NewGenesisState(params Params) *GenesisState { + return &GenesisState{ + Params: params, + } +} + +func DefaultGenesisState(denom string) *GenesisState { + return NewGenesisState(DefaultParams(denom)) +} + +func ValidateGenesis(gs *GenesisState) error { + return gs.Params.ValidateBasic() +} diff --git a/x/meshsecurity/types/genesis.pb.go b/x/meshsecurity/types/genesis.pb.go new file mode 100644 index 00000000..5575e806 --- /dev/null +++ b/x/meshsecurity/types/genesis.pb.go @@ -0,0 +1,357 @@ +// Code generated by protoc-gen-gogo. DO NOT EDIT. +// source: osmosis/meshsecurity/v1beta1/genesis.proto + +package types + +import ( + fmt "fmt" + io "io" + math "math" + math_bits "math/bits" + + _ "github.com/cosmos/cosmos-sdk/types/tx/amino" + _ "github.com/cosmos/gogoproto/gogoproto" + proto "github.com/cosmos/gogoproto/proto" +) + +// Reference imports to suppress errors if they are not otherwise used. +var ( + _ = proto.Marshal + _ = fmt.Errorf + _ = math.Inf +) + +// This is a compile-time assertion to ensure that this generated file +// is compatible with the proto package it is being compiled against. +// A compilation error at this line likely means your copy of the +// proto package needs to be updated. +const _ = proto.GoGoProtoPackageIsVersion3 // please upgrade the proto package + +// GenesisState defines meshsecurity module's genesis state. +type GenesisState struct { + Params Params `protobuf:"bytes,1,opt,name=params,proto3" json:"params"` +} + +func (m *GenesisState) Reset() { *m = GenesisState{} } +func (m *GenesisState) String() string { return proto.CompactTextString(m) } +func (*GenesisState) ProtoMessage() {} +func (*GenesisState) Descriptor() ([]byte, []int) { + return fileDescriptor_e38a457d5139d73a, []int{0} +} + +func (m *GenesisState) XXX_Unmarshal(b []byte) error { + return m.Unmarshal(b) +} + +func (m *GenesisState) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + if deterministic { + return xxx_messageInfo_GenesisState.Marshal(b, m, deterministic) + } else { + b = b[:cap(b)] + n, err := m.MarshalToSizedBuffer(b) + if err != nil { + return nil, err + } + return b[:n], nil + } +} + +func (m *GenesisState) XXX_Merge(src proto.Message) { + xxx_messageInfo_GenesisState.Merge(m, src) +} + +func (m *GenesisState) XXX_Size() int { + return m.Size() +} + +func (m *GenesisState) XXX_DiscardUnknown() { + xxx_messageInfo_GenesisState.DiscardUnknown(m) +} + +var xxx_messageInfo_GenesisState proto.InternalMessageInfo + +func init() { + proto.RegisterType((*GenesisState)(nil), "osmosis.meshsecurity.v1beta1.GenesisState") +} + +func init() { + proto.RegisterFile("osmosis/meshsecurity/v1beta1/genesis.proto", fileDescriptor_e38a457d5139d73a) +} + +var fileDescriptor_e38a457d5139d73a = []byte{ + // 247 bytes of a gzipped FileDescriptorProto + 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xe2, 0xd2, 0xca, 0x2f, 0xce, 0xcd, + 0x2f, 0xce, 0x2c, 0xd6, 0xcf, 0x4d, 0x2d, 0xce, 0x28, 0x4e, 0x4d, 0x2e, 0x2d, 0xca, 0x2c, 0xa9, + 0xd4, 0x2f, 0x33, 0x4c, 0x4a, 0x2d, 0x49, 0x34, 0xd4, 0x4f, 0x4f, 0xcd, 0x4b, 0x2d, 0xce, 0x2c, + 0xd6, 0x2b, 0x28, 0xca, 0x2f, 0xc9, 0x17, 0x92, 0x81, 0xaa, 0xd5, 0x43, 0x56, 0xab, 0x07, 0x55, + 0x2b, 0xa5, 0x8f, 0xd7, 0x24, 0x14, 0x2d, 0x60, 0xe3, 0xa4, 0x44, 0xd2, 0xf3, 0xd3, 0xf3, 0xc1, + 0x4c, 0x7d, 0x10, 0x0b, 0x2a, 0x2a, 0x98, 0x98, 0x9b, 0x99, 0x97, 0xaf, 0x0f, 0x26, 0x21, 0x42, + 0x4a, 0xb1, 0x5c, 0x3c, 0xee, 0x10, 0x87, 0x04, 0x97, 0x24, 0x96, 0xa4, 0x0a, 0xb9, 0x73, 0xb1, + 0x15, 0x24, 0x16, 0x25, 0xe6, 0x16, 0x4b, 0x30, 0x2a, 0x30, 0x6a, 0x70, 0x1b, 0xa9, 0xe8, 0xe1, + 0x73, 0x98, 0x5e, 0x00, 0x58, 0xad, 0x13, 0xe7, 0x89, 0x7b, 0xf2, 0x0c, 0x2b, 0x9e, 0x6f, 0xd0, + 0x62, 0x0c, 0x82, 0x6a, 0xb7, 0x62, 0x79, 0xb1, 0x40, 0x9e, 0xd1, 0x29, 0xe1, 0xc4, 0x43, 0x39, + 0x86, 0x15, 0x8f, 0xe4, 0x18, 0x4e, 0x3c, 0x92, 0x63, 0xbc, 0xf0, 0x48, 0x8e, 0xf1, 0xc1, 0x23, + 0x39, 0xc6, 0x09, 0x8f, 0xe5, 0x18, 0x2e, 0x3c, 0x96, 0x63, 0xb8, 0xf1, 0x58, 0x8e, 0x21, 0xca, + 0x2e, 0x3d, 0xb3, 0x24, 0xa3, 0x34, 0x49, 0x2f, 0x39, 0x3f, 0x17, 0xe6, 0x4b, 0xdd, 0x9c, 0xc4, + 0x24, 0x88, 0x57, 0x75, 0x61, 0x16, 0xea, 0x16, 0xa7, 0x64, 0xeb, 0x57, 0xa0, 0x7a, 0xbf, 0xa4, + 0xb2, 0x20, 0xb5, 0x38, 0x89, 0x0d, 0xec, 0x0f, 0x63, 0x40, 0x00, 0x00, 0x00, 0xff, 0xff, 0x75, + 0x0f, 0xd3, 0x37, 0x6d, 0x01, 0x00, 0x00, +} + +func (this *GenesisState) Equal(that interface{}) bool { + if that == nil { + return this == nil + } + + that1, ok := that.(*GenesisState) + if !ok { + that2, ok := that.(GenesisState) + if ok { + that1 = &that2 + } else { + return false + } + } + if that1 == nil { + return this == nil + } else if this == nil { + return false + } + if !this.Params.Equal(&that1.Params) { + return false + } + return true +} + +func (m *GenesisState) Marshal() (dAtA []byte, err error) { + size := m.Size() + dAtA = make([]byte, size) + n, err := m.MarshalToSizedBuffer(dAtA[:size]) + if err != nil { + return nil, err + } + return dAtA[:n], nil +} + +func (m *GenesisState) MarshalTo(dAtA []byte) (int, error) { + size := m.Size() + return m.MarshalToSizedBuffer(dAtA[:size]) +} + +func (m *GenesisState) MarshalToSizedBuffer(dAtA []byte) (int, error) { + i := len(dAtA) + _ = i + var l int + _ = l + { + size, err := m.Params.MarshalToSizedBuffer(dAtA[:i]) + if err != nil { + return 0, err + } + i -= size + i = encodeVarintGenesis(dAtA, i, uint64(size)) + } + i-- + dAtA[i] = 0xa + return len(dAtA) - i, nil +} + +func encodeVarintGenesis(dAtA []byte, offset int, v uint64) int { + offset -= sovGenesis(v) + base := offset + for v >= 1<<7 { + dAtA[offset] = uint8(v&0x7f | 0x80) + v >>= 7 + offset++ + } + dAtA[offset] = uint8(v) + return base +} + +func (m *GenesisState) Size() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + l = m.Params.Size() + n += 1 + l + sovGenesis(uint64(l)) + return n +} + +func sovGenesis(x uint64) (n int) { + return (math_bits.Len64(x|1) + 6) / 7 +} + +func sozGenesis(x uint64) (n int) { + return sovGenesis(uint64((x << 1) ^ uint64((int64(x) >> 63)))) +} + +func (m *GenesisState) Unmarshal(dAtA []byte) error { + l := len(dAtA) + iNdEx := 0 + for iNdEx < l { + preIndex := iNdEx + var wire uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowGenesis + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + wire |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + fieldNum := int32(wire >> 3) + wireType := int(wire & 0x7) + if wireType == 4 { + return fmt.Errorf("proto: GenesisState: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: GenesisState: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + case 1: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Params", wireType) + } + var msglen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowGenesis + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + msglen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if msglen < 0 { + return ErrInvalidLengthGenesis + } + postIndex := iNdEx + msglen + if postIndex < 0 { + return ErrInvalidLengthGenesis + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + if err := m.Params.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + return err + } + iNdEx = postIndex + default: + iNdEx = preIndex + skippy, err := skipGenesis(dAtA[iNdEx:]) + if err != nil { + return err + } + if (skippy < 0) || (iNdEx+skippy) < 0 { + return ErrInvalidLengthGenesis + } + if (iNdEx + skippy) > l { + return io.ErrUnexpectedEOF + } + iNdEx += skippy + } + } + + if iNdEx > l { + return io.ErrUnexpectedEOF + } + return nil +} + +func skipGenesis(dAtA []byte) (n int, err error) { + l := len(dAtA) + iNdEx := 0 + depth := 0 + for iNdEx < l { + var wire uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return 0, ErrIntOverflowGenesis + } + if iNdEx >= l { + return 0, io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + wire |= (uint64(b) & 0x7F) << shift + if b < 0x80 { + break + } + } + wireType := int(wire & 0x7) + switch wireType { + case 0: + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return 0, ErrIntOverflowGenesis + } + if iNdEx >= l { + return 0, io.ErrUnexpectedEOF + } + iNdEx++ + if dAtA[iNdEx-1] < 0x80 { + break + } + } + case 1: + iNdEx += 8 + case 2: + var length int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return 0, ErrIntOverflowGenesis + } + if iNdEx >= l { + return 0, io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + length |= (int(b) & 0x7F) << shift + if b < 0x80 { + break + } + } + if length < 0 { + return 0, ErrInvalidLengthGenesis + } + iNdEx += length + case 3: + depth++ + case 4: + if depth == 0 { + return 0, ErrUnexpectedEndOfGroupGenesis + } + depth-- + case 5: + iNdEx += 4 + default: + return 0, fmt.Errorf("proto: illegal wireType %d", wireType) + } + if iNdEx < 0 { + return 0, ErrInvalidLengthGenesis + } + if depth == 0 { + return iNdEx, nil + } + } + return 0, io.ErrUnexpectedEOF +} + +var ( + ErrInvalidLengthGenesis = fmt.Errorf("proto: negative length found during unmarshaling") + ErrIntOverflowGenesis = fmt.Errorf("proto: integer overflow") + ErrUnexpectedEndOfGroupGenesis = fmt.Errorf("proto: unexpected end of group") +) diff --git a/x/meshsecurity/types/genesis_test.go b/x/meshsecurity/types/genesis_test.go new file mode 100644 index 00000000..6f2c3b00 --- /dev/null +++ b/x/meshsecurity/types/genesis_test.go @@ -0,0 +1,90 @@ +package types + +import ( + "cosmossdk.io/math" + sdk "github.com/cosmos/cosmos-sdk/types" + "github.com/stretchr/testify/assert" + "testing" +) + +func TestValidateGenesis(t *testing.T) { + specs := map[string]struct { + state GenesisState + expErr bool + }{ + "default params": { + state: *DefaultGenesisState(sdk.DefaultBondDenom), + expErr: false, + }, + "custom param, should pass": { + state: GenesisState{ + Params: Params{ + TotalContractsMaxCap: sdk.NewCoin(sdk.DefaultBondDenom, math.NewInt(15_000_000_000)), + EpochLength: 2_000, + MaxGasEndBlocker: 600_000, + }, + }, + expErr: false, + }, + "custom small value param, should pass": { + state: GenesisState{ + Params: Params{ + TotalContractsMaxCap: sdk.NewCoin(sdk.DefaultBondDenom, math.NewInt(1_000_000)), + EpochLength: 20, + MaxGasEndBlocker: 10_000, + }, + }, + expErr: false, + }, + "invalid epoch length, should fail": { + state: GenesisState{ + Params: Params{ + TotalContractsMaxCap: sdk.NewCoin(sdk.DefaultBondDenom, math.NewInt(15_000_000_000)), + EpochLength: 0, + MaxGasEndBlocker: 600_000, + }, + }, + expErr: true, + }, + "invalid max gas length, should fail": { + state: GenesisState{ + Params: Params{ + TotalContractsMaxCap: sdk.NewCoin(sdk.DefaultBondDenom, math.NewInt(15_000_000_000)), + EpochLength: 10, + MaxGasEndBlocker: 0, + }, + }, + expErr: true, + }, + "invalid max cap coin denom, should fail": { + state: GenesisState{ + Params: Params{ + TotalContractsMaxCap: sdk.Coin{Denom: "invalid denom test", Amount: math.Int{}}, + EpochLength: 10, + MaxGasEndBlocker: 0, + }, + }, + expErr: true, + }, + "invalid max cap coin amount, should fail": { + state: GenesisState{ + Params: Params{ + TotalContractsMaxCap: sdk.Coin{Denom: sdk.DefaultBondDenom, Amount: math.NewInt(-100)}, + EpochLength: 10, + MaxGasEndBlocker: 0, + }, + }, + expErr: true, + }, + } + for name, spec := range specs { + t.Run(name, func(t *testing.T) { + err := ValidateGenesis(&spec.state) + if spec.expErr { + assert.Error(t, err) + } else { + assert.NoError(t, err) + } + }) + } +}