diff --git a/api/canto/govshuttle/v1/genesis.pulsar.go b/api/canto/govshuttle/v1/genesis.pulsar.go index 80ed05d08..d67a924c1 100644 --- a/api/canto/govshuttle/v1/genesis.pulsar.go +++ b/api/canto/govshuttle/v1/genesis.pulsar.go @@ -14,14 +14,16 @@ import ( ) var ( - md_GenesisState protoreflect.MessageDescriptor - fd_GenesisState_params protoreflect.FieldDescriptor + md_GenesisState protoreflect.MessageDescriptor + fd_GenesisState_params protoreflect.FieldDescriptor + fd_GenesisState_port_contract_addr protoreflect.FieldDescriptor ) func init() { file_canto_govshuttle_v1_genesis_proto_init() md_GenesisState = File_canto_govshuttle_v1_genesis_proto.Messages().ByName("GenesisState") fd_GenesisState_params = md_GenesisState.Fields().ByName("params") + fd_GenesisState_port_contract_addr = md_GenesisState.Fields().ByName("port_contract_addr") } var _ protoreflect.Message = (*fastReflection_GenesisState)(nil) @@ -95,6 +97,12 @@ func (x *fastReflection_GenesisState) Range(f func(protoreflect.FieldDescriptor, return } } + if x.PortContractAddr != "" { + value := protoreflect.ValueOfString(x.PortContractAddr) + if !f(fd_GenesisState_port_contract_addr, value) { + return + } + } } // Has reports whether a field is populated. @@ -112,6 +120,8 @@ func (x *fastReflection_GenesisState) Has(fd protoreflect.FieldDescriptor) bool switch fd.FullName() { case "canto.govshuttle.v1.GenesisState.params": return x.Params != nil + case "canto.govshuttle.v1.GenesisState.port_contract_addr": + return x.PortContractAddr != "" default: if fd.IsExtension() { panic(fmt.Errorf("proto3 declared messages do not support extensions: canto.govshuttle.v1.GenesisState")) @@ -130,6 +140,8 @@ func (x *fastReflection_GenesisState) Clear(fd protoreflect.FieldDescriptor) { switch fd.FullName() { case "canto.govshuttle.v1.GenesisState.params": x.Params = nil + case "canto.govshuttle.v1.GenesisState.port_contract_addr": + x.PortContractAddr = "" default: if fd.IsExtension() { panic(fmt.Errorf("proto3 declared messages do not support extensions: canto.govshuttle.v1.GenesisState")) @@ -149,6 +161,9 @@ func (x *fastReflection_GenesisState) Get(descriptor protoreflect.FieldDescripto case "canto.govshuttle.v1.GenesisState.params": value := x.Params return protoreflect.ValueOfMessage(value.ProtoReflect()) + case "canto.govshuttle.v1.GenesisState.port_contract_addr": + value := x.PortContractAddr + return protoreflect.ValueOfString(value) default: if descriptor.IsExtension() { panic(fmt.Errorf("proto3 declared messages do not support extensions: canto.govshuttle.v1.GenesisState")) @@ -171,6 +186,8 @@ func (x *fastReflection_GenesisState) Set(fd protoreflect.FieldDescriptor, value switch fd.FullName() { case "canto.govshuttle.v1.GenesisState.params": x.Params = value.Message().Interface().(*Params) + case "canto.govshuttle.v1.GenesisState.port_contract_addr": + x.PortContractAddr = value.Interface().(string) default: if fd.IsExtension() { panic(fmt.Errorf("proto3 declared messages do not support extensions: canto.govshuttle.v1.GenesisState")) @@ -196,6 +213,8 @@ func (x *fastReflection_GenesisState) Mutable(fd protoreflect.FieldDescriptor) p x.Params = new(Params) } return protoreflect.ValueOfMessage(x.Params.ProtoReflect()) + case "canto.govshuttle.v1.GenesisState.port_contract_addr": + panic(fmt.Errorf("field port_contract_addr of message canto.govshuttle.v1.GenesisState is not mutable")) default: if fd.IsExtension() { panic(fmt.Errorf("proto3 declared messages do not support extensions: canto.govshuttle.v1.GenesisState")) @@ -212,6 +231,8 @@ func (x *fastReflection_GenesisState) NewField(fd protoreflect.FieldDescriptor) case "canto.govshuttle.v1.GenesisState.params": m := new(Params) return protoreflect.ValueOfMessage(m.ProtoReflect()) + case "canto.govshuttle.v1.GenesisState.port_contract_addr": + return protoreflect.ValueOfString("") default: if fd.IsExtension() { panic(fmt.Errorf("proto3 declared messages do not support extensions: canto.govshuttle.v1.GenesisState")) @@ -285,6 +306,10 @@ func (x *fastReflection_GenesisState) ProtoMethods() *protoiface.Methods { l = options.Size(x.Params) n += 1 + l + runtime.Sov(uint64(l)) } + l = len(x.PortContractAddr) + if l > 0 { + n += 1 + l + runtime.Sov(uint64(l)) + } if x.unknownFields != nil { n += len(x.unknownFields) } @@ -314,6 +339,13 @@ func (x *fastReflection_GenesisState) ProtoMethods() *protoiface.Methods { i -= len(x.unknownFields) copy(dAtA[i:], x.unknownFields) } + if len(x.PortContractAddr) > 0 { + i -= len(x.PortContractAddr) + copy(dAtA[i:], x.PortContractAddr) + i = runtime.EncodeVarint(dAtA, i, uint64(len(x.PortContractAddr))) + i-- + dAtA[i] = 0x12 + } if x.Params != nil { encoded, err := options.Marshal(x.Params) if err != nil { @@ -413,6 +445,38 @@ func (x *fastReflection_GenesisState) ProtoMethods() *protoiface.Methods { return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, err } iNdEx = postIndex + case 2: + if wireType != 2 { + return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, fmt.Errorf("proto: wrong wireType = %d for field PortContractAddr", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, runtime.ErrIntOverflow + } + if iNdEx >= l { + return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + stringLen |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + intStringLen := int(stringLen) + if intStringLen < 0 { + return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, runtime.ErrInvalidLength + } + postIndex := iNdEx + intStringLen + if postIndex < 0 { + return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, runtime.ErrInvalidLength + } + if postIndex > l { + return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, io.ErrUnexpectedEOF + } + x.PortContractAddr = string(dAtA[iNdEx:postIndex]) + iNdEx = postIndex default: iNdEx = preIndex skippy, err := runtime.Skip(dAtA[iNdEx:]) @@ -467,7 +531,8 @@ type GenesisState struct { sizeCache protoimpl.SizeCache unknownFields protoimpl.UnknownFields - Params *Params `protobuf:"bytes,1,opt,name=params,proto3" json:"params,omitempty"` // this line is used by starport scaffolding # genesis/proto/state + Params *Params `protobuf:"bytes,1,opt,name=params,proto3" json:"params,omitempty"` + PortContractAddr string `protobuf:"bytes,2,opt,name=port_contract_addr,json=portContractAddr,proto3" json:"port_contract_addr,omitempty"` // this line is used by starport scaffolding # genesis/proto/state } func (x *GenesisState) Reset() { @@ -497,6 +562,13 @@ func (x *GenesisState) GetParams() *Params { return nil } +func (x *GenesisState) GetPortContractAddr() string { + if x != nil { + return x.PortContractAddr + } + return "" +} + var File_canto_govshuttle_v1_genesis_proto protoreflect.FileDescriptor var file_canto_govshuttle_v1_genesis_proto_rawDesc = []byte{ @@ -507,25 +579,27 @@ var file_canto_govshuttle_v1_genesis_proto_rawDesc = []byte{ 0x6f, 0x74, 0x6f, 0x2f, 0x67, 0x6f, 0x67, 0x6f, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x1a, 0x24, 0x63, 0x61, 0x6e, 0x74, 0x6f, 0x2f, 0x67, 0x6f, 0x76, 0x73, 0x68, 0x75, 0x74, 0x74, 0x6c, 0x65, 0x2f, 0x76, 0x31, 0x2f, 0x67, 0x6f, 0x76, 0x73, 0x68, 0x75, 0x74, 0x74, 0x6c, 0x65, 0x2e, 0x70, - 0x72, 0x6f, 0x74, 0x6f, 0x22, 0x49, 0x0a, 0x0c, 0x47, 0x65, 0x6e, 0x65, 0x73, 0x69, 0x73, 0x53, + 0x72, 0x6f, 0x74, 0x6f, 0x22, 0x77, 0x0a, 0x0c, 0x47, 0x65, 0x6e, 0x65, 0x73, 0x69, 0x73, 0x53, 0x74, 0x61, 0x74, 0x65, 0x12, 0x39, 0x0a, 0x06, 0x70, 0x61, 0x72, 0x61, 0x6d, 0x73, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1b, 0x2e, 0x63, 0x61, 0x6e, 0x74, 0x6f, 0x2e, 0x67, 0x6f, 0x76, 0x73, 0x68, 0x75, 0x74, 0x74, 0x6c, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x50, 0x61, 0x72, 0x61, 0x6d, - 0x73, 0x42, 0x04, 0xc8, 0xde, 0x1f, 0x00, 0x52, 0x06, 0x70, 0x61, 0x72, 0x61, 0x6d, 0x73, 0x42, - 0xc8, 0x01, 0x0a, 0x17, 0x63, 0x6f, 0x6d, 0x2e, 0x63, 0x61, 0x6e, 0x74, 0x6f, 0x2e, 0x67, 0x6f, - 0x76, 0x73, 0x68, 0x75, 0x74, 0x74, 0x6c, 0x65, 0x2e, 0x76, 0x31, 0x42, 0x0c, 0x47, 0x65, 0x6e, - 0x65, 0x73, 0x69, 0x73, 0x50, 0x72, 0x6f, 0x74, 0x6f, 0x50, 0x01, 0x5a, 0x31, 0x63, 0x6f, 0x73, - 0x6d, 0x6f, 0x73, 0x73, 0x64, 0x6b, 0x2e, 0x69, 0x6f, 0x2f, 0x61, 0x70, 0x69, 0x2f, 0x63, 0x61, - 0x6e, 0x74, 0x6f, 0x2f, 0x67, 0x6f, 0x76, 0x73, 0x68, 0x75, 0x74, 0x74, 0x6c, 0x65, 0x2f, 0x76, - 0x31, 0x3b, 0x67, 0x6f, 0x76, 0x73, 0x68, 0x75, 0x74, 0x74, 0x6c, 0x65, 0x76, 0x31, 0xa2, 0x02, - 0x03, 0x43, 0x47, 0x58, 0xaa, 0x02, 0x13, 0x43, 0x61, 0x6e, 0x74, 0x6f, 0x2e, 0x47, 0x6f, 0x76, - 0x73, 0x68, 0x75, 0x74, 0x74, 0x6c, 0x65, 0x2e, 0x56, 0x31, 0xca, 0x02, 0x13, 0x43, 0x61, 0x6e, - 0x74, 0x6f, 0x5c, 0x47, 0x6f, 0x76, 0x73, 0x68, 0x75, 0x74, 0x74, 0x6c, 0x65, 0x5c, 0x56, 0x31, - 0xe2, 0x02, 0x1f, 0x43, 0x61, 0x6e, 0x74, 0x6f, 0x5c, 0x47, 0x6f, 0x76, 0x73, 0x68, 0x75, 0x74, - 0x74, 0x6c, 0x65, 0x5c, 0x56, 0x31, 0x5c, 0x47, 0x50, 0x42, 0x4d, 0x65, 0x74, 0x61, 0x64, 0x61, - 0x74, 0x61, 0xea, 0x02, 0x15, 0x43, 0x61, 0x6e, 0x74, 0x6f, 0x3a, 0x3a, 0x47, 0x6f, 0x76, 0x73, - 0x68, 0x75, 0x74, 0x74, 0x6c, 0x65, 0x3a, 0x3a, 0x56, 0x31, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, - 0x6f, 0x33, + 0x73, 0x42, 0x04, 0xc8, 0xde, 0x1f, 0x00, 0x52, 0x06, 0x70, 0x61, 0x72, 0x61, 0x6d, 0x73, 0x12, + 0x2c, 0x0a, 0x12, 0x70, 0x6f, 0x72, 0x74, 0x5f, 0x63, 0x6f, 0x6e, 0x74, 0x72, 0x61, 0x63, 0x74, + 0x5f, 0x61, 0x64, 0x64, 0x72, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x10, 0x70, 0x6f, 0x72, + 0x74, 0x43, 0x6f, 0x6e, 0x74, 0x72, 0x61, 0x63, 0x74, 0x41, 0x64, 0x64, 0x72, 0x42, 0xc8, 0x01, + 0x0a, 0x17, 0x63, 0x6f, 0x6d, 0x2e, 0x63, 0x61, 0x6e, 0x74, 0x6f, 0x2e, 0x67, 0x6f, 0x76, 0x73, + 0x68, 0x75, 0x74, 0x74, 0x6c, 0x65, 0x2e, 0x76, 0x31, 0x42, 0x0c, 0x47, 0x65, 0x6e, 0x65, 0x73, + 0x69, 0x73, 0x50, 0x72, 0x6f, 0x74, 0x6f, 0x50, 0x01, 0x5a, 0x31, 0x63, 0x6f, 0x73, 0x6d, 0x6f, + 0x73, 0x73, 0x64, 0x6b, 0x2e, 0x69, 0x6f, 0x2f, 0x61, 0x70, 0x69, 0x2f, 0x63, 0x61, 0x6e, 0x74, + 0x6f, 0x2f, 0x67, 0x6f, 0x76, 0x73, 0x68, 0x75, 0x74, 0x74, 0x6c, 0x65, 0x2f, 0x76, 0x31, 0x3b, + 0x67, 0x6f, 0x76, 0x73, 0x68, 0x75, 0x74, 0x74, 0x6c, 0x65, 0x76, 0x31, 0xa2, 0x02, 0x03, 0x43, + 0x47, 0x58, 0xaa, 0x02, 0x13, 0x43, 0x61, 0x6e, 0x74, 0x6f, 0x2e, 0x47, 0x6f, 0x76, 0x73, 0x68, + 0x75, 0x74, 0x74, 0x6c, 0x65, 0x2e, 0x56, 0x31, 0xca, 0x02, 0x13, 0x43, 0x61, 0x6e, 0x74, 0x6f, + 0x5c, 0x47, 0x6f, 0x76, 0x73, 0x68, 0x75, 0x74, 0x74, 0x6c, 0x65, 0x5c, 0x56, 0x31, 0xe2, 0x02, + 0x1f, 0x43, 0x61, 0x6e, 0x74, 0x6f, 0x5c, 0x47, 0x6f, 0x76, 0x73, 0x68, 0x75, 0x74, 0x74, 0x6c, + 0x65, 0x5c, 0x56, 0x31, 0x5c, 0x47, 0x50, 0x42, 0x4d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, + 0xea, 0x02, 0x15, 0x43, 0x61, 0x6e, 0x74, 0x6f, 0x3a, 0x3a, 0x47, 0x6f, 0x76, 0x73, 0x68, 0x75, + 0x74, 0x74, 0x6c, 0x65, 0x3a, 0x3a, 0x56, 0x31, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33, } var ( diff --git a/api/canto/govshuttle/v1/govshuttle.pulsar.go b/api/canto/govshuttle/v1/govshuttle.pulsar.go index 5c92fb478..d1b8f200b 100644 --- a/api/canto/govshuttle/v1/govshuttle.pulsar.go +++ b/api/canto/govshuttle/v1/govshuttle.pulsar.go @@ -3074,6 +3074,8 @@ func (*Params) Descriptor() ([]byte, []int) { // Define this object so that the govshuttle.pb.go file is generate, implements // govtypes.Content +// Deprecated: This legacy proposal is deprecated in favor of Msg-based gov +// proposals, see MsgLendingMarketProposal. type LendingMarketProposal struct { state protoimpl.MessageState sizeCache protoimpl.SizeCache @@ -3127,6 +3129,8 @@ func (x *LendingMarketProposal) GetMetadata() *LendingMarketMetadata { } // treasury proposal type, +// Deprecated: This legacy proposal is deprecated in favor of Msg-based gov +// proposals, see MsgTreasuryProposal. type TreasuryProposal struct { state protoimpl.MessageState sizeCache protoimpl.SizeCache diff --git a/app/amino_test.go b/app/amino_test.go index de4f48d8a..7369d11b7 100644 --- a/app/amino_test.go +++ b/app/amino_test.go @@ -29,6 +29,7 @@ import ( coinswapapi "github.com/Canto-Network/Canto/v7/api/canto/coinswap/v1" csrapi "github.com/Canto-Network/Canto/v7/api/canto/csr/v1" + govshuttleapi "github.com/Canto-Network/Canto/v7/api/canto/govshuttle/v1" inflationapi "github.com/Canto-Network/Canto/v7/api/canto/inflation/v1" onboardingapi "github.com/Canto-Network/Canto/v7/api/canto/onboarding/v1" "github.com/Canto-Network/Canto/v7/x/coinswap" @@ -38,6 +39,7 @@ import ( "github.com/Canto-Network/Canto/v7/x/epochs" "github.com/Canto-Network/Canto/v7/x/erc20" "github.com/Canto-Network/Canto/v7/x/govshuttle" + govshuttletypes "github.com/Canto-Network/Canto/v7/x/govshuttle/types" "github.com/Canto-Network/Canto/v7/x/inflation" inflationtypes "github.com/Canto-Network/Canto/v7/x/inflation/types" "github.com/Canto-Network/Canto/v7/x/onboarding" @@ -94,6 +96,10 @@ func TestAminoJSON_Equivalence(t *testing.T) { // onboarding GenType(&onboardingtypes.MsgUpdateParams{}, &onboardingapi.MsgUpdateParams{}, GenOpts.WithDisallowNil()), GenType(&onboardingtypes.Params{}, &onboardingapi.Params{}, GenOpts.WithDisallowNil()), + + // govshuttle + GenType(&govshuttletypes.LendingMarketProposal{}, &govshuttleapi.LendingMarketProposal{}, GenOpts.WithDisallowNil()), + GenType(&govshuttletypes.TreasuryProposal{}, &govshuttleapi.TreasuryProposal{}, GenOpts.WithDisallowNil()), } for _, tt := range testedMsgs { diff --git a/app/app.go b/app/app.go index d7814a750..3ed85b3a0 100644 --- a/app/app.go +++ b/app/app.go @@ -421,7 +421,7 @@ func NewCanto( ethermint.ProtoAccount, maccPerms, authcodec.NewBech32Codec(sdk.GetConfig().GetBech32AccountAddrPrefix()), - sdk.Bech32MainPrefix, + sdk.GetConfig().GetBech32AccountAddrPrefix(), authtypes.NewModuleAddress(govtypes.ModuleName).String(), ) app.BankKeeper = bankkeeper.NewBaseKeeper( @@ -761,7 +761,7 @@ func NewCanto( erc20.NewAppModule(app.Erc20Keeper, app.AccountKeeper), epochs.NewAppModule(appCodec, app.EpochsKeeper), onboarding.NewAppModule(*app.OnboardingKeeper), - govshuttle.NewAppModule(app.GovshuttleKeeper, app.AccountKeeper), + govshuttle.NewAppModule(app.GovshuttleKeeper, app.AccountKeeper, app.AccountKeeper.AddressCodec()), csr.NewAppModule(app.CSRKeeper, app.AccountKeeper), coinswap.NewAppModule(appCodec, app.CoinswapKeeper, app.AccountKeeper, app.BankKeeper), ) diff --git a/go.mod b/go.mod index fa138747d..9431e2e3c 100644 --- a/go.mod +++ b/go.mod @@ -9,7 +9,9 @@ require ( cosmossdk.io/client/v2 v2.0.0-beta.1 cosmossdk.io/collections v0.4.0 cosmossdk.io/core v0.12.0 + cosmossdk.io/errors v1.0.1 cosmossdk.io/log v1.3.1 + cosmossdk.io/math v1.3.0 cosmossdk.io/simapp v0.0.0-20231103111158-e83a20081ced cosmossdk.io/store v1.1.0 cosmossdk.io/tools/confix v0.1.0 @@ -39,8 +41,12 @@ require ( github.com/rakyll/statik v0.1.7 github.com/spf13/cast v1.6.0 github.com/spf13/cobra v1.8.0 + github.com/spf13/pflag v1.0.5 + github.com/spf13/viper v1.18.2 github.com/stretchr/testify v1.9.0 go.opencensus.io v0.24.0 + golang.org/x/exp v0.0.0-20240404231335-c0f41cb1a7a0 + golang.org/x/sync v0.7.0 google.golang.org/genproto/googleapis/api v0.0.0-20240227224415-6ceb2ff114de google.golang.org/grpc v1.63.2 google.golang.org/protobuf v1.33.0 @@ -146,8 +152,6 @@ require ( ) require ( - cosmossdk.io/errors v1.0.1 - cosmossdk.io/math v1.3.0 filippo.io/edwards25519 v1.0.0 // indirect github.com/99designs/keyring v1.2.2 // indirect github.com/DataDog/zstd v1.5.5 // indirect @@ -229,8 +233,6 @@ require ( github.com/sasha-s/go-deadlock v0.3.1 // indirect github.com/shirou/gopsutil v3.21.4-0.20210419000835-c7a38de76ee5+incompatible // indirect github.com/spf13/afero v1.11.0 // indirect - github.com/spf13/pflag v1.0.5 // indirect - github.com/spf13/viper v1.18.2 github.com/status-im/keycard-go v0.2.0 // indirect github.com/subosito/gotenv v1.6.0 // indirect github.com/syndtr/goleveldb v1.0.1-0.20220721030215-126854af5e6d // indirect @@ -239,9 +241,7 @@ require ( github.com/zondax/hid v0.9.2 // indirect go.etcd.io/bbolt v1.3.8 // indirect golang.org/x/crypto v0.22.0 // indirect - golang.org/x/exp v0.0.0-20240404231335-c0f41cb1a7a0 golang.org/x/net v0.24.0 // indirect - golang.org/x/sync v0.7.0 golang.org/x/sys v0.19.0 // indirect golang.org/x/term v0.19.0 // indirect golang.org/x/text v0.14.0 // indirect diff --git a/init.sh b/init.sh index fd9793517..6a3d44cd2 100755 --- a/init.sh +++ b/init.sh @@ -30,7 +30,10 @@ cantod init $MONIKER --chain-id $CHAINID # Change parameter token denominations to acanto cat $HOME/.cantod/config/genesis.json | jq '.app_state["staking"]["params"]["bond_denom"]="acanto"' > $HOME/.cantod/config/tmp_genesis.json && mv $HOME/.cantod/config/tmp_genesis.json $HOME/.cantod/config/genesis.json cat $HOME/.cantod/config/genesis.json | jq '.app_state["crisis"]["constant_fee"]["denom"]="acanto"' > $HOME/.cantod/config/tmp_genesis.json && mv $HOME/.cantod/config/tmp_genesis.json $HOME/.cantod/config/genesis.json -cat $HOME/.cantod/config/genesis.json | jq '.app_state["gov"]["deposit_params"]["min_deposit"][0]["denom"]="acanto"' > $HOME/.cantod/config/tmp_genesis.json && mv $HOME/.cantod/config/tmp_genesis.json $HOME/.cantod/config/genesis.json +cat $HOME/.cantod/config/genesis.json | jq '.app_state["coinswap"]["params"]["pool_creation_fee"]["denom"]="acanto"' > $HOME/.cantod/config/tmp_genesis.json && mv $HOME/.cantod/config/tmp_genesis.json $HOME/.cantod/config/genesis.json +cat $HOME/.cantod/config/genesis.json | jq '.app_state["coinswap"]["standard_denom"]="acanto"' > $HOME/.cantod/config/tmp_genesis.json && mv $HOME/.cantod/config/tmp_genesis.json $HOME/.cantod/config/genesis.json +cat $HOME/.cantod/config/genesis.json | jq '.app_state["gov"]["params"]["min_deposit"][0]["denom"]="acanto"' > $HOME/.cantod/config/tmp_genesis.json && mv $HOME/.cantod/config/tmp_genesis.json $HOME/.cantod/config/genesis.json +cat $HOME/.cantod/config/genesis.json | jq '.app_state["gov"]["params"]["expedited_min_deposit"][0]["denom"]="acanto"' > $HOME/.cantod/config/tmp_genesis.json && mv $HOME/.cantod/config/tmp_genesis.json $HOME/.cantod/config/genesis.json cat $HOME/.cantod/config/genesis.json | jq '.app_state["evm"]["params"]["evm_denom"]="acanto"' > $HOME/.cantod/config/tmp_genesis.json && mv $HOME/.cantod/config/tmp_genesis.json $HOME/.cantod/config/genesis.json cat $HOME/.cantod/config/genesis.json | jq '.app_state["inflation"]["params"]["mint_denom"]="acanto"' > $HOME/.cantod/config/tmp_genesis.json && mv $HOME/.cantod/config/tmp_genesis.json $HOME/.cantod/config/genesis.json diff --git a/proto/canto/govshuttle/v1/genesis.proto b/proto/canto/govshuttle/v1/genesis.proto index 5bc4b9a87..6413d5ca2 100644 --- a/proto/canto/govshuttle/v1/genesis.proto +++ b/proto/canto/govshuttle/v1/genesis.proto @@ -10,5 +10,6 @@ option go_package = "github.com/Canto-Network/Canto/v7/x/govshuttle/types"; // GenesisState defines the govshuttle module's genesis state. message GenesisState { Params params = 1 [ (gogoproto.nullable) = false ]; + string port_contract_addr = 2; // this line is used by starport scaffolding # genesis/proto/state } diff --git a/proto/canto/govshuttle/v1/govshuttle.proto b/proto/canto/govshuttle/v1/govshuttle.proto index 98eb34ddd..0c1ac4353 100644 --- a/proto/canto/govshuttle/v1/govshuttle.proto +++ b/proto/canto/govshuttle/v1/govshuttle.proto @@ -11,6 +11,8 @@ message Params { option (gogoproto.goproto_stringer) = false; } // Define this object so that the govshuttle.pb.go file is generate, implements // govtypes.Content +// Deprecated: This legacy proposal is deprecated in favor of Msg-based gov +// proposals, see MsgLendingMarketProposal. message LendingMarketProposal { option (gogoproto.equal) = false; option (cosmos_proto.implements_interface) = @@ -25,6 +27,8 @@ message LendingMarketProposal { } // treasury proposal type, +// Deprecated: This legacy proposal is deprecated in favor of Msg-based gov +// proposals, see MsgTreasuryProposal. message TreasuryProposal { option (gogoproto.equal) = false; option (cosmos_proto.implements_interface) = diff --git a/x/govshuttle/client/cli/tx.go b/x/govshuttle/client/cli/tx.go index e0db33d8c..b868f6dd8 100644 --- a/x/govshuttle/client/cli/tx.go +++ b/x/govshuttle/client/cli/tx.go @@ -6,24 +6,26 @@ import ( "github.com/spf13/cobra" + addresscodec "cosmossdk.io/core/address" + errorsmod "cosmossdk.io/errors" "github.com/cosmos/cosmos-sdk/client" + "github.com/cosmos/cosmos-sdk/client/flags" "github.com/cosmos/cosmos-sdk/client/tx" sdk "github.com/cosmos/cosmos-sdk/types" + "github.com/cosmos/cosmos-sdk/types/address" "github.com/cosmos/cosmos-sdk/version" - "github.com/cosmos/cosmos-sdk/x/gov/client/cli" - govtypes "github.com/cosmos/cosmos-sdk/x/gov/types/v1beta1" - - errorsmod "cosmossdk.io/errors" "github.com/Canto-Network/Canto/v7/x/govshuttle/types" ) var ( DefaultRelativePacketTimeoutTimestamp = uint64((time.Duration(10) * time.Minute).Nanoseconds()) + + FlagAuthority = "authority" ) // NewTxCmd returns a root CLI command handler for certain modules/govshuttle transaction commands. -func NewTxCmd() *cobra.Command { +func NewTxCmd(ac addresscodec.Codec) *cobra.Command { txCmd := &cobra.Command{ Use: types.ModuleName, Short: "govshuttle subcommands", @@ -32,12 +34,15 @@ func NewTxCmd() *cobra.Command { RunE: client.ValidateCmd, } - txCmd.AddCommand() + txCmd.AddCommand( + NewLendingMarketProposalCmd(ac), + NewTreasuryProposalCmd(ac), + ) return txCmd } // NewRegisterCoinProposalCmd implements the command to submit a community-pool-spend proposal -func NewLendingMarketProposalCmd() *cobra.Command { +func NewLendingMarketProposalCmd(ac addresscodec.Codec) *cobra.Command { cmd := &cobra.Command{ Use: "lending-market [metadata]", Args: cobra.ExactArgs(1), @@ -51,9 +56,9 @@ Where metadata.json contains (example): { "Account": ["address_1", "address_2"], - "PropId": 1, + "PropId": 1, "values": ["canto", "osmo"], - "calldatas: ["calldata1", "calldata2"], + "calldatas": ["calldata1", "calldata2"], "signatures": ["func1", "func2"] }`, version.AppName, ), @@ -63,22 +68,7 @@ Where metadata.json contains (example): return err } - title, err := cmd.Flags().GetString(cli.FlagTitle) - if err != nil { - return err - } - - description, err := cmd.Flags().GetString(cli.FlagDescription) - if err != nil { - return err - } - - depositStr, err := cmd.Flags().GetString(cli.FlagDeposit) - if err != nil { - return err - } - - deposit, err := sdk.ParseCoinsNormalized(depositStr) + proposal, err := ReadGovPropFlags(clientCtx, cmd.Flags()) if err != nil { return err } @@ -88,40 +78,37 @@ Where metadata.json contains (example): return errorsmod.Wrap(err, "Failure to parse JSON object") } - from := clientCtx.GetFromAddress() - - content := types.NewLendingMarketProposal(title, description, &propMetaData) - - msg, err := govtypes.NewMsgSubmitProposal(content, deposit, from) - if err != nil { - return err + authority, _ := cmd.Flags().GetString(FlagAuthority) + if authority != "" { + if _, err = ac.StringToBytes(authority); err != nil { + return fmt.Errorf("invalid authority address: %w", err) + } + } else { + authority = sdk.AccAddress(address.Module("gov")).String() } - //if err := msg.ValidateBasic(); err != nil { - // return err - //} + if err := proposal.SetMsgs([]sdk.Msg{ + &types.MsgLendingMarketProposal{ + Authority: authority, + Title: proposal.Title, + Description: proposal.Summary, + Metadata: &propMetaData, + }, + }); err != nil { + return fmt.Errorf("failed to create submit lending market proposal message: %w", err) + } - return tx.GenerateOrBroadcastTxCLI(clientCtx, cmd.Flags(), msg) + return tx.GenerateOrBroadcastTxCLI(clientCtx, cmd.Flags(), proposal) }, } + flags.AddTxFlagsToCmd(cmd) + AddGovPropFlagsToCmd(cmd) - cmd.Flags().String(cli.FlagTitle, "", "title of proposal") - cmd.Flags().String(cli.FlagDescription, "", "description of proposal") - cmd.Flags().String(cli.FlagDeposit, "1aevmos", "deposit of proposal") - if err := cmd.MarkFlagRequired(cli.FlagTitle); err != nil { - panic(err) - } - if err := cmd.MarkFlagRequired(cli.FlagDescription); err != nil { - panic(err) - } - if err := cmd.MarkFlagRequired(cli.FlagDeposit); err != nil { - panic(err) - } return cmd } // Register TreasuryProposal submit cmd -func NewTreasuryProposalCmd() *cobra.Command { +func NewTreasuryProposalCmd(ac addresscodec.Codec) *cobra.Command { cmd := &cobra.Command{ Use: "treasury-proposal [metadata]", Args: cobra.ExactArgs(1), @@ -135,7 +122,7 @@ Where metadata.json contains (example): { "recipient": "0xfffffff...", - "PropID": 1, + "PropID": 1, "amount": 1, "denom": "canto/note" }`, version.AppName, @@ -146,22 +133,7 @@ Where metadata.json contains (example): return err } - title, err := cmd.Flags().GetString(cli.FlagTitle) - if err != nil { - return err - } - - description, err := cmd.Flags().GetString(cli.FlagDescription) - if err != nil { - return err - } - - depositStr, err := cmd.Flags().GetString(cli.FlagDeposit) - if err != nil { - return err - } - - deposit, err := sdk.ParseCoinsNormalized(depositStr) + proposal, err := ReadGovPropFlags(clientCtx, cmd.Flags()) if err != nil { return err } @@ -171,34 +143,31 @@ Where metadata.json contains (example): return errorsmod.Wrap(err, "Failure to parse JSON object") } - from := clientCtx.GetFromAddress() - - content := types.NewTreasuryProposal(title, description, &propMetaData) - - msg, err := govtypes.NewMsgSubmitProposal(content, deposit, from) - if err != nil { - return err + authority, _ := cmd.Flags().GetString(FlagAuthority) + if authority != "" { + if _, err = ac.StringToBytes(authority); err != nil { + return fmt.Errorf("invalid authority address: %w", err) + } + } else { + authority = sdk.AccAddress(address.Module("gov")).String() } - //if err := msg.ValidateBasic(); err != nil { - // return err - //} + if err := proposal.SetMsgs([]sdk.Msg{ + &types.MsgTreasuryProposal{ + Authority: authority, + Title: proposal.Title, + Description: proposal.Summary, + Metadata: &propMetaData, + }, + }); err != nil { + return fmt.Errorf("failed to create submit treasury proposal message: %w", err) + } - return tx.GenerateOrBroadcastTxCLI(clientCtx, cmd.Flags(), msg) + return tx.GenerateOrBroadcastTxCLI(clientCtx, cmd.Flags(), proposal) }, } + flags.AddTxFlagsToCmd(cmd) + AddGovPropFlagsToCmd(cmd) - cmd.Flags().String(cli.FlagTitle, "", "title of proposal") - cmd.Flags().String(cli.FlagDescription, "", "description of proposal") - cmd.Flags().String(cli.FlagDeposit, "1aevmos", "deposit of proposal") - if err := cmd.MarkFlagRequired(cli.FlagTitle); err != nil { - panic(err) - } - if err := cmd.MarkFlagRequired(cli.FlagDescription); err != nil { - panic(err) - } - if err := cmd.MarkFlagRequired(cli.FlagDeposit); err != nil { - panic(err) - } return cmd } diff --git a/x/govshuttle/client/cli/utils.go b/x/govshuttle/client/cli/utils.go index 91ec5835b..9a67d09b4 100644 --- a/x/govshuttle/client/cli/utils.go +++ b/x/govshuttle/client/cli/utils.go @@ -1,12 +1,20 @@ package cli import ( - "encoding/json" - "io/ioutil" + "fmt" + "os" "path/filepath" - "github.com/Canto-Network/Canto/v7/x/govshuttle/types" + "github.com/spf13/cobra" + "github.com/spf13/pflag" + + "github.com/cosmos/cosmos-sdk/client" "github.com/cosmos/cosmos-sdk/codec" + sdk "github.com/cosmos/cosmos-sdk/types" + "github.com/cosmos/cosmos-sdk/x/gov/client/cli" + govv1 "github.com/cosmos/cosmos-sdk/x/gov/types/v1" + + "github.com/Canto-Network/Canto/v7/x/govshuttle/types" ) // PARSING METADATA ACCORDING TO PROPOSAL STRUCT IN GOVTYPES TYPE IN govshuttle @@ -15,17 +23,13 @@ import ( func ParseLendingMarketMetadata(cdc codec.JSONCodec, metadataFile string) (types.LendingMarketMetadata, error) { propMetaData := types.LendingMarketMetadata{} - contents, err := ioutil.ReadFile(filepath.Clean(metadataFile)) + contents, err := os.ReadFile(filepath.Clean(metadataFile)) if err != nil { return propMetaData, err } - // if err = cdc.UnmarshalJSON(contents, &propMetaData); err != nil { - // return propMetaData, err - // } - - if err = json.Unmarshal(contents, &propMetaData); err != nil { - return types.LendingMarketMetadata{}, err + if err = cdc.UnmarshalJSON(contents, &propMetaData); err != nil { + return propMetaData, err } propMetaData.PropId = 0 @@ -36,20 +40,71 @@ func ParseLendingMarketMetadata(cdc codec.JSONCodec, metadataFile string) (types func ParseTreasuryMetadata(cdc codec.JSONCodec, metadataFile string) (types.TreasuryProposalMetadata, error) { propMetaData := types.TreasuryProposalMetadata{} - contents, err := ioutil.ReadFile(filepath.Clean(metadataFile)) + contents, err := os.ReadFile(filepath.Clean(metadataFile)) if err != nil { return propMetaData, err } - // if err = cdc.UnmarshalJSON(contents, &propMetaData); err != nil { - // return propMetaData, err - // } - - if err = json.Unmarshal(contents, &propMetaData); err != nil { - return types.TreasuryProposalMetadata{}, err + if err = cdc.UnmarshalJSON(contents, &propMetaData); err != nil { + return propMetaData, err } propMetaData.PropID = 0 return propMetaData, nil } + +// AddGovPropFlagsToCmd adds flags for defining MsgSubmitProposal fields. +// +// See also ReadGovPropFlags. +// ref. github.com/cosmos/cosmos-sdk/x/gov/client/cli/util.go::AddGovPropFlagsToCmd +func AddGovPropFlagsToCmd(cmd *cobra.Command) { + cmd.Flags().String(cli.FlagTitle, "", "title of proposal") + cmd.Flags().String(cli.FlagDescription, "", "description of proposal") + cmd.Flags().String(cli.FlagDeposit, "1acanto", "deposit of proposal") + cmd.Flags().String(FlagAuthority, "", "The address of the upgrade module authority (defaults to gov)") + + if err := cmd.MarkFlagRequired(cli.FlagTitle); err != nil { + panic(err) + } + if err := cmd.MarkFlagRequired(cli.FlagDescription); err != nil { + panic(err) + } + if err := cmd.MarkFlagRequired(cli.FlagDeposit); err != nil { + panic(err) + } +} + +// ReadGovPropFlags parses a MsgSubmitProposal from the provided context and flags. +// Setting the messages is up to the caller. +// +// See also AddGovPropFlagsToCmd. +// ref. github.com/cosmos/cosmos-sdk/x/gov/client/cli/util.go::ReadGovPropFlags +func ReadGovPropFlags(clientCtx client.Context, flagSet *pflag.FlagSet) (*govv1.MsgSubmitProposal, error) { + rv := &govv1.MsgSubmitProposal{} + + deposit, err := flagSet.GetString(cli.FlagDeposit) + if err != nil { + return nil, fmt.Errorf("could not read deposit: %w", err) + } + if len(deposit) > 0 { + rv.InitialDeposit, err = sdk.ParseCoinsNormalized(deposit) + if err != nil { + return nil, fmt.Errorf("invalid deposit: %w", err) + } + } + + rv.Title, err = flagSet.GetString(cli.FlagTitle) + if err != nil { + return nil, fmt.Errorf("could not read title: %w", err) + } + + rv.Summary, err = flagSet.GetString(cli.FlagDescription) + if err != nil { + return nil, fmt.Errorf("could not read summary: %w", err) + } + + rv.Proposer = clientCtx.GetFromAddress().String() + + return rv, nil +} diff --git a/x/govshuttle/genesis.go b/x/govshuttle/genesis.go index cfd606383..cc41f5495 100644 --- a/x/govshuttle/genesis.go +++ b/x/govshuttle/genesis.go @@ -1,10 +1,12 @@ package govshuttle import ( - "github.com/Canto-Network/Canto/v7/x/govshuttle/keeper" - "github.com/Canto-Network/Canto/v7/x/govshuttle/types" sdk "github.com/cosmos/cosmos-sdk/types" authkeeper "github.com/cosmos/cosmos-sdk/x/auth/keeper" + "github.com/ethereum/go-ethereum/common" + + "github.com/Canto-Network/Canto/v7/x/govshuttle/keeper" + "github.com/Canto-Network/Canto/v7/x/govshuttle/types" ) // InitGenesis initializes the capability module's state from a provided genesis @@ -13,6 +15,11 @@ func InitGenesis(ctx sdk.Context, k keeper.Keeper, accountKeeper authkeeper.Acco // this line is used by starport scaffolding # genesis/module/init k.SetParams(ctx, genState.Params) + if genState.PortContractAddr != "" { + portAddr := common.HexToAddress(genState.PortContractAddr) + k.SetPort(ctx, portAddr) + } + if acc := accountKeeper.GetModuleAccount(ctx, types.ModuleName); acc == nil { panic("the govshuttle module account has not been set") } @@ -23,6 +30,10 @@ func ExportGenesis(ctx sdk.Context, k keeper.Keeper) *types.GenesisState { genesis := types.DefaultGenesis() genesis.Params = k.GetParams(ctx) + if portAddr, ok := k.GetPort(ctx); ok { + genesis.PortContractAddr = portAddr.String() + } + // this line is used by starport scaffolding # genesis/module/export return genesis diff --git a/x/govshuttle/genesis_test.go b/x/govshuttle/genesis_test.go index 13baacd83..0f79071b4 100644 --- a/x/govshuttle/genesis_test.go +++ b/x/govshuttle/genesis_test.go @@ -1,28 +1,106 @@ package govshuttle_test import ( + // "encoding/json" "testing" - //keepertest "github.com/Canto-Network/Canto/v2/testutil/keeper" - //"github.com/Canto-Network/Canto/v2/testutil/nullify" - // "github.com/Canto-Network/Canto/v2/x/govshuttle" - // "github.com/Canto-Network/Canto/v2/x/govshuttle/types" - // "github.com/stretchr/testify/require" + + "github.com/stretchr/testify/require" + "github.com/stretchr/testify/suite" + + "github.com/ethereum/go-ethereum/common" + + "cosmossdk.io/log" + dbm "github.com/cosmos/cosmos-db" + simtestutil "github.com/cosmos/cosmos-sdk/testutil/sims" + sdk "github.com/cosmos/cosmos-sdk/types" + + "github.com/Canto-Network/Canto/v7/app" + "github.com/Canto-Network/Canto/v7/x/govshuttle" ) -func TestGenesis(t *testing.T) { - // genesisState := types.GenesisState{ - // Params: types.DefaultParams(), +type GenesisTestSuite struct { + suite.Suite //top level testing suite + + appA *app.Canto + ctxA sdk.Context + + appB *app.Canto + ctxB sdk.Context +} + +var s *GenesisTestSuite + +func TestGenesisTestSuite(t *testing.T) { + s = new(GenesisTestSuite) + suite.Run(t, s) +} + +func (suite *GenesisTestSuite) DoSetupTest(t require.TestingT) { + suite.appA = app.NewCanto( + log.NewNopLogger(), + dbm.NewMemDB(), + nil, + true, + map[int64]bool{}, + app.DefaultNodeHome, + 0, + true, + simtestutil.NewAppOptionsWithFlagHome(app.DefaultNodeHome), + ) + suite.ctxA = suite.appA.NewContext(true) + + suite.appB = app.NewCanto( + log.NewNopLogger(), + dbm.NewMemDB(), + nil, + true, + map[int64]bool{}, + app.DefaultNodeHome, + 0, + true, + simtestutil.NewAppOptionsWithFlagHome(app.DefaultNodeHome), + ) + suite.ctxB = suite.appB.NewContext(true) +} + +func (suite *GenesisTestSuite) SetupTest() { + suite.DoSetupTest(suite.T()) +} + +func (suite *GenesisTestSuite) TestGenesis() { + testCases := []struct { + name string + portAddr common.Address + malleate func(portAddr common.Address) + }{ + { + "empty port contract address", + common.Address{}, + func(_ common.Address) {}, + }, + { + "non-empty port contract address", + common.HexToAddress("0x648a5Aa0C4FbF2C1CF5a3B432c2766EeaF8E402d"), + func(portAddr common.Address) { + suite.appA.GovshuttleKeeper.SetPort(suite.ctxA, portAddr) + }, + }, + } + + for _, tc := range testCases { + suite.Run(tc.name, func() { + suite.SetupTest() - // // this line is used by starport scaffolding # genesis/test/state - // } + tc.malleate(tc.portAddr) - // k, ctx := keepertest.govshuttleKeeper(t) - // govshuttle.InitGenesis(ctx, *k, genesisState) - // got := govshuttle.ExportGenesis(ctx, *k) - // require.NotNil(t, got) + portAddr, _ := suite.appA.GovshuttleKeeper.GetPort(suite.ctxA) + suite.Require().Equal(tc.portAddr, portAddr) - // nullify.Fill(&genesisState) - // nullify.Fill(got) + genesisState := govshuttle.ExportGenesis(suite.ctxA, suite.appA.GovshuttleKeeper) - // this line is used by starport scaffolding # genesis/test/assert + govshuttle.InitGenesis(suite.ctxB, suite.appB.GovshuttleKeeper, suite.appB.AccountKeeper, *genesisState) + portAddr, _ = suite.appB.GovshuttleKeeper.GetPort(suite.ctxB) + suite.Require().Equal(tc.portAddr, portAddr) + }) + } } diff --git a/x/govshuttle/keeper/keeper_test.go b/x/govshuttle/keeper/keeper_test.go index 41348bc0c..647ef6cba 100644 --- a/x/govshuttle/keeper/keeper_test.go +++ b/x/govshuttle/keeper/keeper_test.go @@ -4,23 +4,33 @@ import ( "encoding/json" "math/big" "testing" + "time" + "github.com/stretchr/testify/require" "github.com/stretchr/testify/suite" "github.com/Canto-Network/Canto/v7/app" + "github.com/Canto-Network/Canto/v7/x/govshuttle/types" + abci "github.com/cometbft/cometbft/abci/types" + "github.com/cometbft/cometbft/crypto/tmhash" + tmproto "github.com/cometbft/cometbft/proto/tendermint/types" + tmversion "github.com/cometbft/cometbft/proto/tendermint/version" + "github.com/cometbft/cometbft/version" + "github.com/cosmos/cosmos-sdk/baseapp" "github.com/cosmos/cosmos-sdk/crypto/keyring" + "github.com/cosmos/cosmos-sdk/crypto/keys/ed25519" sdk "github.com/cosmos/cosmos-sdk/types" + stakingkeeper "github.com/cosmos/cosmos-sdk/x/staking/keeper" + stakingtypes "github.com/cosmos/cosmos-sdk/x/staking/types" "github.com/ethereum/go-ethereum/common" "github.com/ethereum/go-ethereum/common/hexutil" "github.com/ethereum/go-ethereum/crypto" "github.com/evmos/ethermint/server/config" evm "github.com/evmos/ethermint/x/evm/types" feemarkettypes "github.com/evmos/ethermint/x/feemarket/types" - "github.com/stretchr/testify/require" //used for deploying contracts "github.com/Canto-Network/Canto/v7/contracts" - "github.com/Canto-Network/Canto/v7/x/erc20/types" ethtypes "github.com/ethereum/go-ethereum/core/types" ) @@ -34,6 +44,7 @@ type KeeperTestSuite struct { queryClient types.QueryClient queryClientEvm evm.QueryClient signer keyring.Signer + validator stakingtypes.Validator } var s *KeeperTestSuite @@ -45,14 +56,63 @@ func TestKeeperTestSuite(t *testing.T) { // Test Helpers func (suite *KeeperTestSuite) DoSetupTest(t require.TestingT) { - checkTx := false - feemarketGenesis := feemarkettypes.DefaultGenesisState() feemarketGenesis.Params.EnableHeight = 1 feemarketGenesis.Params.NoBaseFee = false - //init app - suite.app = app.Setup(checkTx, feemarketGenesis) + // init app + suite.app = app.Setup(false, feemarketGenesis) + + // consensus key + pubKey := ed25519.GenPrivKey().PubKey() + consAddress := sdk.ConsAddress(pubKey.Address()) + + suite.ctx = suite.app.BaseApp.NewContextLegacy(false, tmproto.Header{ + Height: 1, + ChainID: "canto_9001-1", + Time: time.Now().UTC(), + ProposerAddress: consAddress.Bytes(), + + Version: tmversion.Consensus{ + Block: version.BlockProtocol, + }, + LastBlockId: tmproto.BlockID{ + Hash: tmhash.Sum([]byte("block_id")), + PartSetHeader: tmproto.PartSetHeader{ + Total: 11, + Hash: tmhash.Sum([]byte("partset_header")), + }, + }, + AppHash: tmhash.Sum([]byte("app")), + DataHash: tmhash.Sum([]byte("data")), + EvidenceHash: tmhash.Sum([]byte("evidence")), + ValidatorsHash: tmhash.Sum([]byte("validators")), + NextValidatorsHash: tmhash.Sum([]byte("next_validators")), + ConsensusHash: tmhash.Sum([]byte("consensus")), + LastResultsHash: tmhash.Sum([]byte("last_result")), + }) + + queryHelper := baseapp.NewQueryServerTestHelper(suite.ctx, suite.app.InterfaceRegistry()) + types.RegisterQueryServer(queryHelper, suite.app.GovshuttleKeeper) + suite.queryClient = types.NewQueryClient(queryHelper) + + // Set Validator + valAddr := sdk.ValAddress(pubKey.Address().Bytes()) + validator, err := stakingtypes.NewValidator(valAddr.String(), pubKey, stakingtypes.Description{}) + suite.NoError(err) + + validator = stakingkeeper.TestingUpdateValidator(suite.app.StakingKeeper, suite.ctx, validator, true) + valbz, err := suite.app.StakingKeeper.ValidatorAddressCodec().StringToBytes(validator.GetOperator()) + suite.NoError(err) + suite.app.StakingKeeper.Hooks().AfterValidatorCreated(suite.ctx, valbz) + err = suite.app.StakingKeeper.SetValidatorByConsAddr(suite.ctx, validator) + suite.NoError(err) + suite.validator = validator + + stakingParams, err := suite.app.StakingKeeper.GetParams(suite.ctx) + suite.NoError(err) + stakingParams.BondDenom = "acanto" + suite.app.StakingKeeper.SetParams(suite.ctx, stakingParams) } func (suite *KeeperTestSuite) SetupTest() { @@ -118,3 +178,26 @@ func (suite *KeeperTestSuite) DeployCaller() (common.Address, error) { func (suite *KeeperTestSuite) DeployCallee() { } + +func (suite *KeeperTestSuite) Commit() { + suite.CommitAfter(time.Nanosecond) +} + +func (suite *KeeperTestSuite) CommitAfter(t time.Duration) { + header := suite.ctx.BlockHeader() + header.Time = header.Time.Add(t) + suite.app.FinalizeBlock(&abci.RequestFinalizeBlock{ + Height: header.Height, + Time: header.Time, + ProposerAddress: suite.ctx.BlockHeader().ProposerAddress, + }) + suite.app.Commit() + + // update ctx + header.Height += 1 + suite.ctx = suite.app.BaseApp.NewUncachedContext(false, header) + + queryHelper := baseapp.NewQueryServerTestHelper(suite.ctx, suite.app.InterfaceRegistry()) + evm.RegisterQueryServer(queryHelper, suite.app.EvmKeeper) + suite.queryClientEvm = evm.NewQueryClient(queryHelper) +} diff --git a/x/govshuttle/keeper/msg_server.go b/x/govshuttle/keeper/msg_server.go index d0eb7ca41..94f12454b 100644 --- a/x/govshuttle/keeper/msg_server.go +++ b/x/govshuttle/keeper/msg_server.go @@ -3,8 +3,11 @@ package keeper import ( "context" - "github.com/Canto-Network/Canto/v7/x/govshuttle/types" + errorsmod "cosmossdk.io/errors" sdk "github.com/cosmos/cosmos-sdk/types" + govtypes "github.com/cosmos/cosmos-sdk/x/gov/types" + + "github.com/Canto-Network/Canto/v7/x/govshuttle/types" ) type msgServer struct { @@ -19,15 +22,13 @@ func NewMsgServerImpl(keeper Keeper) types.MsgServer { var _ types.MsgServer = msgServer{} -func (k Keeper) LendingMarketProposal(goCtx context.Context, req *types.MsgLendingMarketProposal) (*types.MsgLendingMarketProposalResponse, error) { - ctx := sdk.UnwrapSDKContext(goCtx) - legacyProposal := types.LendingMarketProposal{ - Title: req.Title, - Description: req.Description, - Metadata: req.Metadata, +func (k Keeper) LendingMarketProposal(ctx context.Context, req *types.MsgLendingMarketProposal) (*types.MsgLendingMarketProposalResponse, error) { + if k.GetAuthority() != req.Authority { + return nil, errorsmod.Wrapf(govtypes.ErrInvalidSigner, "invalid authority; expected %s, got %s", k.GetAuthority(), req.Authority) } - _, err := k.AppendLendingMarketProposal(ctx, &legacyProposal) + sdkCtx := sdk.UnwrapSDKContext(ctx) + _, err := k.AppendLendingMarketProposal(sdkCtx, req) if err != nil { return nil, err } @@ -35,17 +36,13 @@ func (k Keeper) LendingMarketProposal(goCtx context.Context, req *types.MsgLendi return &types.MsgLendingMarketProposalResponse{}, nil } -func (k Keeper) TreasuryProposal(goCtx context.Context, req *types.MsgTreasuryProposal) (*types.MsgTreasuryProposalResponse, error) { - ctx := sdk.UnwrapSDKContext(goCtx) - legacyTreasuryProposal := types.TreasuryProposal{ - Title: req.Title, - Description: req.Description, - Metadata: req.Metadata, +func (k Keeper) TreasuryProposal(ctx context.Context, req *types.MsgTreasuryProposal) (*types.MsgTreasuryProposalResponse, error) { + if k.GetAuthority() != req.Authority { + return nil, errorsmod.Wrapf(govtypes.ErrInvalidSigner, "invalid authority; expected %s, got %s", k.GetAuthority(), req.Authority) } - legacyProposal := legacyTreasuryProposal.FromTreasuryToLendingMarket() - - _, err := k.AppendLendingMarketProposal(ctx, legacyProposal) + sdkCtx := sdk.UnwrapSDKContext(ctx) + _, err := k.AppendLendingMarketProposal(sdkCtx, req.FromTreasuryToLendingMarket()) if err != nil { return nil, err } diff --git a/x/govshuttle/keeper/msg_server_test.go b/x/govshuttle/keeper/msg_server_test.go index 7253f3a95..e6344f385 100644 --- a/x/govshuttle/keeper/msg_server_test.go +++ b/x/govshuttle/keeper/msg_server_test.go @@ -1,17 +1,266 @@ package keeper_test import ( - "context" - "testing" + "encoding/hex" + "encoding/json" + "fmt" + "math" + "math/big" - //sdk "github.com/cosmos/cosmos-sdk/types" - "github.com/Canto-Network/Canto/v7/x/govshuttle/types" - //"github.com/Canto-Network/Canto/v2/x/govshuttle/keeper" - //keepertest "github.com/Canto-Network/Canto/v2/testutil/keeper" + "github.com/ethereum/go-ethereum/common" + + sdkmath "cosmossdk.io/math" + sdk "github.com/cosmos/cosmos-sdk/types" + authtypes "github.com/cosmos/cosmos-sdk/x/auth/types" + govtypes "github.com/cosmos/cosmos-sdk/x/gov/types" + govtypesv1 "github.com/cosmos/cosmos-sdk/x/gov/types/v1" + stakingtypes "github.com/cosmos/cosmos-sdk/x/staking/types" + + "github.com/evmos/ethermint/crypto/ethsecp256k1" + "github.com/evmos/ethermint/server/config" + evmtypes "github.com/evmos/ethermint/x/evm/types" + + "github.com/Canto-Network/Canto/v7/contracts" + "github.com/Canto-Network/Canto/v7/testutil" + govshuttletypes "github.com/Canto-Network/Canto/v7/x/govshuttle/types" ) -func setupMsgServer(t testing.TB) (types.MsgServer, context.Context) { - //k, ctx := keepertest.govshuttleKeeper(t) - //return keeper.NewMsgServerImpl(*k), sdk.WrapSDKContext(ctx) - return nil, nil +type ProposalResult struct { + Id *big.Int `json:"id"` + Title string `json:"title"` + Desc string `json:"desc"` + Targets []common.Address `json:"targets"` + Values []*big.Int `json:"values"` + Signatures []string `json:"signatures"` + Calldatas [][]byte `json:"calldatas"` +} + +func (suite *KeeperTestSuite) TestMsgExecutionByProposal() { + suite.SetupTest() + + // get denom + stakingParams, err := suite.app.StakingKeeper.GetParams(suite.ctx) + suite.Require().NoError(err) + denom := stakingParams.BondDenom + + // change mindeposit for denom + govParams, err := suite.app.GovKeeper.Params.Get(suite.ctx) + suite.Require().NoError(err) + govParams.MinDeposit = []sdk.Coin{sdk.NewCoin(denom, sdkmath.NewInt(1))} + err = suite.app.GovKeeper.Params.Set(suite.ctx, govParams) + suite.Require().NoError(err) + + // create account + privKey, err := ethsecp256k1.GenerateKey() + suite.Require().NoError(err) + proposer := sdk.AccAddress(privKey.PubKey().Address().Bytes()) + + // deligate to validator + initAmount := sdkmath.NewInt(int64(math.Pow10(18)) * 2) + initBalance := sdk.NewCoins(sdk.NewCoin(denom, initAmount)) + testutil.FundAccount(suite.app.BankKeeper, suite.ctx, proposer, initBalance) + shares, err := suite.app.StakingKeeper.Delegate(suite.ctx, proposer, sdk.DefaultPowerReduction, stakingtypes.Unbonded, suite.validator, true) + suite.Require().NoError(err) + suite.Require().True(shares.GT(sdkmath.LegacyNewDec(0))) + + testCases := []struct { + name string + msg sdk.Msg + checkFunc func(uint64, sdk.Msg) + expectErr bool + }{ + { + "fail - MsgLendingMarketProposal - authority check", + &govshuttletypes.MsgLendingMarketProposal{ + Authority: "canto1yrmjye0zyfvr0lthc6fwq7qlwg9e8muftxa630", + Title: "lending market proposal test", + Description: "lending market proposal test description", + Metadata: &govshuttletypes.LendingMarketMetadata{ + Account: []string{"0x20F72265e2225837fd77C692e0781f720B93eF89", "0xf6Db2570A2417188a5788D6d5Fd9faAa5B1fE555"}, + PropId: 1, + Values: []uint64{1234, 5678}, + Calldatas: []string{hex.EncodeToString([]byte("calldata1")), hex.EncodeToString([]byte("calldata2"))}, + Signatures: []string{"sig1", "sig2"}, + }, + }, + func(uint64, sdk.Msg) {}, + true, + }, + { + "ok - MsgLendingMarketProposal", + &govshuttletypes.MsgLendingMarketProposal{ + Authority: authtypes.NewModuleAddress(govtypes.ModuleName).String(), + Title: "lending market proposal test", + Description: "lending market proposal test description", + Metadata: &govshuttletypes.LendingMarketMetadata{ + Account: []string{"0x20F72265e2225837fd77C692e0781f720B93eF89", "0xf6Db2570A2417188a5788D6d5Fd9faAa5B1fE555"}, + PropId: 1, + Values: []uint64{1234, 5678}, + Calldatas: []string{hex.EncodeToString([]byte("calldata1")), hex.EncodeToString([]byte("calldata2"))}, + Signatures: []string{"sig1", "sig2"}, + }, + }, + func(proposalId uint64, msg sdk.Msg) { + proposal, err := suite.app.GovKeeper.Proposals.Get(suite.ctx, proposalId) + suite.Require().NoError(err) + suite.Require().Equal(govtypesv1.ProposalStatus_PROPOSAL_STATUS_PASSED, proposal.Status) + + proposalMsg, ok := msg.(*govshuttletypes.MsgLendingMarketProposal) + suite.Require().True(ok) + + targets := []common.Address{} + for _, acc := range proposalMsg.Metadata.Account { + targets = append(targets, common.HexToAddress(acc)) + } + + values := []*big.Int{} + for _, value := range proposalMsg.Metadata.Values { + values = append(values, big.NewInt(int64(value))) + } + + calldatas := [][]byte{} + for _, calldata := range proposalMsg.Metadata.Calldatas { + c, err := hex.DecodeString(calldata) + suite.Require().NoError(err) + + calldatas = append(calldatas, c) + } + + suite.checkQueryPropResult( + proposalId, + ProposalResult{ + Id: big.NewInt(int64(proposalMsg.Metadata.PropId)), + Title: proposalMsg.Title, + Desc: proposalMsg.Description, + Targets: targets, + Values: values, + Signatures: proposalMsg.Metadata.Signatures, + Calldatas: calldatas, + }, + ) + }, + false, + }, + { + "fail - MsgTreasuryProposal - authority check", + &govshuttletypes.MsgTreasuryProposal{ + Authority: "canto1yrmjye0zyfvr0lthc6fwq7qlwg9e8muftxa630", + Title: "treasury proposal test", + Description: "treasury proposal test description", + Metadata: &govshuttletypes.TreasuryProposalMetadata{ + PropID: 2, + Recipient: "0x20F72265e2225837fd77C692e0781f720B93eF89", + Amount: 1234, + Denom: "acanto", + }, + }, + func(uint64, sdk.Msg) {}, + true, + }, + { + "ok - MsgTreasuryProposal", + &govshuttletypes.MsgTreasuryProposal{ + Authority: authtypes.NewModuleAddress(govtypes.ModuleName).String(), + Title: "treasury proposal test", + Description: "treasury proposal test description", + Metadata: &govshuttletypes.TreasuryProposalMetadata{ + PropID: 2, + Recipient: "0x20F72265e2225837fd77C692e0781f720B93eF89", + Amount: 1234, + Denom: "acanto", + }, + }, + func(proposalId uint64, msg sdk.Msg) { + proposal, err := suite.app.GovKeeper.Proposals.Get(suite.ctx, proposalId) + suite.Require().NoError(err) + suite.Require().Equal(govtypesv1.ProposalStatus_PROPOSAL_STATUS_PASSED, proposal.Status) + + proposalMsg, ok := msg.(*govshuttletypes.MsgTreasuryProposal) + suite.Require().True(ok) + + targets := []common.Address{common.HexToAddress(proposalMsg.Metadata.Recipient)} + values := []*big.Int{big.NewInt(int64(proposalMsg.Metadata.Amount))} + signatures := []string{proposalMsg.Metadata.Denom} + calldatas := [][]byte{} + + suite.checkQueryPropResult( + proposalId, + ProposalResult{ + Id: big.NewInt(int64(proposalMsg.Metadata.PropID)), + Title: proposalMsg.Title, + Desc: proposalMsg.Description, + Targets: targets, + Values: values, + Signatures: signatures, + Calldatas: calldatas, + }, + ) + }, + false, + }, + } + + for _, tc := range testCases { + suite.Run(tc.name, func() { + // submit proposal + proposal, err := suite.app.GovKeeper.SubmitProposal(suite.ctx, []sdk.Msg{tc.msg}, "", "test", "description", proposer, false) + if tc.expectErr { + suite.Require().Error(err) + } else { + suite.Require().NoError(err) + suite.Commit() + + ok, err := suite.app.GovKeeper.AddDeposit(suite.ctx, proposal.Id, proposer, govParams.MinDeposit) + suite.Require().NoError(err) + suite.Require().True(ok) + suite.Commit() + + err = suite.app.GovKeeper.AddVote(suite.ctx, proposal.Id, proposer, govtypesv1.NewNonSplitVoteOption(govtypesv1.OptionYes), "") + suite.Require().NoError(err) + suite.CommitAfter(*govParams.VotingPeriod) + + // check proposal result + tc.checkFunc(proposal.Id, tc.msg) + } + }) + } +} + +func (suite *KeeperTestSuite) checkQueryPropResult(propId uint64, expectedResult ProposalResult) { + // make calldata + data, err := contracts.ProposalStoreContract.ABI.Pack("QueryProp", big.NewInt(int64(propId))) + suite.Require().NoError(err) + + // get port contract address + portAddr, ok := suite.app.GovshuttleKeeper.GetPort(suite.ctx) + suite.Require().True(ok) + + txArgs := map[string]interface{}{ + "to": portAddr, + "data": fmt.Sprintf("0x%x", data), + } + txArgsJson, err := json.Marshal(txArgs) + suite.Require().NoError(err) + + // query to contract + req := &evmtypes.EthCallRequest{ + Args: txArgsJson, + GasCap: config.DefaultGasCap, + } + rpcRes, err := suite.app.EvmKeeper.EthCall(suite.ctx, req) + suite.Require().NoError(err) + + queryRes, err := contracts.ProposalStoreContract.ABI.Unpack("QueryProp", rpcRes.Ret) + suite.Require().NoError(err) + + // marshal and unmarshal to get ProposalResult + var res ProposalResult + b, err := json.Marshal(queryRes[0]) + suite.Require().NoError(err) + json.Unmarshal(b, &res) + + suite.Require().Equal( + expectedResult, + res, + ) } diff --git a/x/govshuttle/keeper/proposals.go b/x/govshuttle/keeper/proposals.go index b8e893579..b3fb3913a 100644 --- a/x/govshuttle/keeper/proposals.go +++ b/x/govshuttle/keeper/proposals.go @@ -16,7 +16,7 @@ import ( ) // method for appending govshuttle proposal types to the govshuttle Map contract -func (k *Keeper) AppendLendingMarketProposal(ctx sdk.Context, lm *types.LendingMarketProposal) (*types.LendingMarketProposal, error) { +func (k *Keeper) AppendLendingMarketProposal(ctx sdk.Context, lm *types.MsgLendingMarketProposal) (*types.MsgLendingMarketProposal, error) { m := lm.GetMetadata() var err error if m.GetPropId() == 0 { @@ -33,7 +33,7 @@ func (k *Keeper) AppendLendingMarketProposal(ctx sdk.Context, lm *types.LendingM if !found { addr, err = k.DeployMapContract(ctx, lm) if err != nil { - return &types.LendingMarketProposal{}, err + return nil, err } // set the port address in state k.SetPort(ctx, addr) @@ -50,8 +50,7 @@ func (k *Keeper) AppendLendingMarketProposal(ctx sdk.Context, lm *types.LendingM return lm, nil } -func (k Keeper) DeployMapContract(ctx sdk.Context, lm *types.LendingMarketProposal) (common.Address, error) { - +func (k Keeper) DeployMapContract(ctx sdk.Context, lm *types.MsgLendingMarketProposal) (common.Address, error) { m := lm.GetMetadata() ctorArgs, err := contracts.ProposalStoreContract.ABI.Pack("", sdkmath.NewIntFromUint64(m.GetPropId()).BigInt(), lm.GetTitle(), lm.GetDescription(), ToAddress(m.GetAccount()), diff --git a/x/govshuttle/module.go b/x/govshuttle/module.go index c439f7964..39544f205 100644 --- a/x/govshuttle/module.go +++ b/x/govshuttle/module.go @@ -11,6 +11,7 @@ import ( abci "github.com/cometbft/cometbft/abci/types" + "cosmossdk.io/core/address" "cosmossdk.io/core/appmodule" "github.com/cosmos/cosmos-sdk/client" "github.com/cosmos/cosmos-sdk/codec" @@ -38,13 +39,9 @@ var ( // AppModuleBasic // ---------------------------------------------------------------------------- -// AppModuleBasic implements the AppModuleBasic interface for the capability module. +// AppModule implements the sdk.AppModuleBasic interface. type AppModuleBasic struct { - cdc codec.BinaryCodec -} - -func NewAppModuleBasic(cdc codec.BinaryCodec) AppModuleBasic { - return AppModuleBasic{cdc: cdc} + ac address.Codec } // Name returns the capability module's name. @@ -86,7 +83,7 @@ func (AppModuleBasic) RegisterGRPCGatewayRoutes(clientCtx client.Context, mux *r // GetTxCmd returns the capability module's root tx command. func (a AppModuleBasic) GetTxCmd() *cobra.Command { - return cli.NewTxCmd() + return cli.NewTxCmd(a.ac) } // GetQueryCmd returns the capability module's root query command. @@ -98,7 +95,7 @@ func (AppModuleBasic) GetQueryCmd() *cobra.Command { // AppModule // ---------------------------------------------------------------------------- -// AppModule implements the AppModule interface for the capability module. +// AppModule implements the sdk.AppModule interface. type AppModule struct { AppModuleBasic @@ -109,9 +106,10 @@ type AppModule struct { func NewAppModule( k keeper.Keeper, ak authkeeper.AccountKeeper, + ac address.Codec, ) AppModule { return AppModule{ - AppModuleBasic: AppModuleBasic{}, + AppModuleBasic: AppModuleBasic{ac: ac}, keeper: k, accountkeeper: ak, } @@ -131,6 +129,7 @@ func (am AppModule) Name() string { // RegisterServices registers a GRPC query service to respond to the // module-specific GRPC queries. func (am AppModule) RegisterServices(cfg module.Configurator) { + types.RegisterMsgServer(cfg.MsgServer(), keeper.NewMsgServerImpl(am.keeper)) types.RegisterQueryServer(cfg.QueryServer(), am.keeper) } diff --git a/x/govshuttle/types/codec.go b/x/govshuttle/types/codec.go index 4913b1f5c..203105388 100644 --- a/x/govshuttle/types/codec.go +++ b/x/govshuttle/types/codec.go @@ -2,6 +2,7 @@ package types import ( "github.com/cosmos/cosmos-sdk/codec" + "github.com/cosmos/cosmos-sdk/codec/legacy" codectypes "github.com/cosmos/cosmos-sdk/codec/types" cryptocodec "github.com/cosmos/cosmos-sdk/crypto/codec" sdk "github.com/cosmos/cosmos-sdk/types" @@ -20,13 +21,6 @@ var ( // The actual codec used for serialization should be provided to modules/erc20 and // defined at the application level. ModuleCdc = codec.NewProtoCodec(codectypes.NewInterfaceRegistry()) - - // AminoCdc is a amino codec created to support amino JSON compatible msgs. - AminoCdc = codec.NewAminoCodec(amino) -) - -const ( - msgUpdateParams = "canto/MsgUpdateParams" ) // NOTE: This is required for the GetSignBytes function @@ -46,6 +40,8 @@ func RegisterInterfaces(registry codectypes.InterfaceRegistry) { (*sdk.Msg)(nil), &LendingMarketProposal{}, &TreasuryProposal{}, + &MsgLendingMarketProposal{}, + &MsgTreasuryProposal{}, ) registry.RegisterImplementations( @@ -58,6 +54,8 @@ func RegisterInterfaces(registry codectypes.InterfaceRegistry) { } func RegisterLegacyAminoCodec(cdc *codec.LegacyAmino) { - cdc.RegisterConcrete(&LendingMarketProposal{}, "canto/LendingMarketProposal", nil) - cdc.RegisterConcrete(&TreasuryProposal{}, "canto/TreasuryProposal", nil) + legacy.RegisterAminoMsg(cdc, &LendingMarketProposal{}, "canto/LendingMarketProposal") + legacy.RegisterAminoMsg(cdc, &TreasuryProposal{}, "canto/TreasuryProposal") + legacy.RegisterAminoMsg(cdc, &MsgLendingMarketProposal{}, "canto/MsgLendingMarketProposal") + legacy.RegisterAminoMsg(cdc, &MsgTreasuryProposal{}, "canto/MsgTreasuryProposal") } diff --git a/x/govshuttle/types/genesis.pb.go b/x/govshuttle/types/genesis.pb.go index a804df3e4..cda4eb257 100644 --- a/x/govshuttle/types/genesis.pb.go +++ b/x/govshuttle/types/genesis.pb.go @@ -25,7 +25,8 @@ const _ = proto.GoGoProtoPackageIsVersion3 // please upgrade the proto package // GenesisState defines the govshuttle module's genesis state. type GenesisState struct { - Params Params `protobuf:"bytes,1,opt,name=params,proto3" json:"params"` + Params Params `protobuf:"bytes,1,opt,name=params,proto3" json:"params"` + PortContractAddr string `protobuf:"bytes,2,opt,name=port_contract_addr,json=portContractAddr,proto3" json:"port_contract_addr,omitempty"` } func (m *GenesisState) Reset() { *m = GenesisState{} } @@ -68,6 +69,13 @@ func (m *GenesisState) GetParams() Params { return Params{} } +func (m *GenesisState) GetPortContractAddr() string { + if m != nil { + return m.PortContractAddr + } + return "" +} + func init() { proto.RegisterType((*GenesisState)(nil), "canto.govshuttle.v1.GenesisState") } @@ -75,20 +83,23 @@ func init() { func init() { proto.RegisterFile("canto/govshuttle/v1/genesis.proto", fileDescriptor_356493b1fc5972f0) } var fileDescriptor_356493b1fc5972f0 = []byte{ - // 208 bytes of a gzipped FileDescriptorProto + // 247 bytes of a gzipped FileDescriptorProto 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xe2, 0x52, 0x4c, 0x4e, 0xcc, 0x2b, 0xc9, 0xd7, 0x4f, 0xcf, 0x2f, 0x2b, 0xce, 0x28, 0x2d, 0x29, 0xc9, 0x49, 0xd5, 0x2f, 0x33, 0xd4, 0x4f, 0x4f, 0xcd, 0x4b, 0x2d, 0xce, 0x2c, 0xd6, 0x2b, 0x28, 0xca, 0x2f, 0xc9, 0x17, 0x12, 0x06, 0x2b, 0xd1, 0x43, 0x28, 0xd1, 0x2b, 0x33, 0x94, 0x12, 0x49, 0xcf, 0x4f, 0xcf, 0x07, 0xcb, 0xeb, - 0x83, 0x58, 0x10, 0xa5, 0x52, 0x2a, 0x58, 0x4d, 0x43, 0x68, 0x04, 0xab, 0x52, 0xf2, 0xe4, 0xe2, + 0x83, 0x58, 0x10, 0xa5, 0x52, 0x2a, 0x58, 0x4d, 0x43, 0x68, 0x04, 0xab, 0x52, 0x2a, 0xe7, 0xe2, 0x71, 0x87, 0xd8, 0x10, 0x5c, 0x92, 0x58, 0x92, 0x2a, 0x64, 0xc9, 0xc5, 0x56, 0x90, 0x58, 0x94, 0x98, 0x5b, 0x2c, 0xc1, 0xa8, 0xc0, 0xa8, 0xc1, 0x6d, 0x24, 0xad, 0x87, 0xc5, 0x46, 0xbd, 0x00, - 0xb0, 0x12, 0x27, 0x96, 0x13, 0xf7, 0xe4, 0x19, 0x82, 0xa0, 0x1a, 0x9c, 0xfc, 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, 0x24, 0x3d, 0xb3, 0x24, 0xa3, 0x34, 0x49, 0x2f, - 0x39, 0x3f, 0x57, 0xdf, 0x19, 0x64, 0x9c, 0xae, 0x5f, 0x6a, 0x49, 0x79, 0x7e, 0x51, 0x36, 0x84, - 0xa7, 0x5f, 0x66, 0xae, 0x5f, 0x81, 0xec, 0xd0, 0x92, 0xca, 0x82, 0xd4, 0xe2, 0x24, 0x36, 0xb0, - 0x0b, 0x8d, 0x01, 0x01, 0x00, 0x00, 0xff, 0xff, 0xba, 0xa8, 0x69, 0x0f, 0x17, 0x01, 0x00, 0x00, + 0xb0, 0x12, 0x27, 0x96, 0x13, 0xf7, 0xe4, 0x19, 0x82, 0xa0, 0x1a, 0x84, 0x74, 0xb8, 0x84, 0x0a, + 0xf2, 0x8b, 0x4a, 0xe2, 0x93, 0xf3, 0xf3, 0x4a, 0x8a, 0x12, 0x93, 0x4b, 0xe2, 0x13, 0x53, 0x52, + 0x8a, 0x24, 0x98, 0x14, 0x18, 0x35, 0x38, 0x83, 0x04, 0x40, 0x32, 0xce, 0x50, 0x09, 0xc7, 0x94, + 0x94, 0x22, 0x27, 0xbf, 0x13, 0x8f, 0xe4, 0x18, 0x2f, 0x3c, 0x92, 0x63, 0x7c, 0xf0, 0x48, 0x8e, + 0x71, 0xc2, 0x63, 0x39, 0x86, 0x0b, 0x8f, 0xe5, 0x18, 0x6e, 0x3c, 0x96, 0x63, 0x88, 0x32, 0x49, + 0xcf, 0x2c, 0xc9, 0x28, 0x4d, 0xd2, 0x4b, 0xce, 0xcf, 0xd5, 0x77, 0x06, 0x59, 0xae, 0xeb, 0x97, + 0x5a, 0x52, 0x9e, 0x5f, 0x94, 0x0d, 0xe1, 0xe9, 0x97, 0x99, 0xeb, 0x57, 0x20, 0x7b, 0xab, 0xa4, + 0xb2, 0x20, 0xb5, 0x38, 0x89, 0x0d, 0xec, 0x1f, 0x63, 0x40, 0x00, 0x00, 0x00, 0xff, 0xff, 0x66, + 0x33, 0x38, 0xcd, 0x45, 0x01, 0x00, 0x00, } func (m *GenesisState) Marshal() (dAtA []byte, err error) { @@ -111,6 +122,13 @@ func (m *GenesisState) MarshalToSizedBuffer(dAtA []byte) (int, error) { _ = i var l int _ = l + if len(m.PortContractAddr) > 0 { + i -= len(m.PortContractAddr) + copy(dAtA[i:], m.PortContractAddr) + i = encodeVarintGenesis(dAtA, i, uint64(len(m.PortContractAddr))) + i-- + dAtA[i] = 0x12 + } { size, err := m.Params.MarshalToSizedBuffer(dAtA[:i]) if err != nil { @@ -143,6 +161,10 @@ func (m *GenesisState) Size() (n int) { _ = l l = m.Params.Size() n += 1 + l + sovGenesis(uint64(l)) + l = len(m.PortContractAddr) + if l > 0 { + n += 1 + l + sovGenesis(uint64(l)) + } return n } @@ -214,6 +236,38 @@ func (m *GenesisState) Unmarshal(dAtA []byte) error { return err } iNdEx = postIndex + case 2: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field PortContractAddr", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowGenesis + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + stringLen |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + intStringLen := int(stringLen) + if intStringLen < 0 { + return ErrInvalidLengthGenesis + } + postIndex := iNdEx + intStringLen + if postIndex < 0 { + return ErrInvalidLengthGenesis + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.PortContractAddr = string(dAtA[iNdEx:postIndex]) + iNdEx = postIndex default: iNdEx = preIndex skippy, err := skipGenesis(dAtA[iNdEx:]) diff --git a/x/govshuttle/types/govshuttle.pb.go b/x/govshuttle/types/govshuttle.pb.go index ccb21068f..132fa1afd 100644 --- a/x/govshuttle/types/govshuttle.pb.go +++ b/x/govshuttle/types/govshuttle.pb.go @@ -62,6 +62,8 @@ var xxx_messageInfo_Params proto.InternalMessageInfo // Define this object so that the govshuttle.pb.go file is generate, implements // govtypes.Content +// Deprecated: This legacy proposal is deprecated in favor of Msg-based gov +// proposals, see MsgLendingMarketProposal. type LendingMarketProposal struct { // title Title string `protobuf:"bytes,1,opt,name=title,proto3" json:"title,omitempty"` @@ -124,6 +126,8 @@ func (m *LendingMarketProposal) GetMetadata() *LendingMarketMetadata { } // treasury proposal type, +// Deprecated: This legacy proposal is deprecated in favor of Msg-based gov +// proposals, see MsgTreasuryProposal. type TreasuryProposal struct { Title string `protobuf:"bytes,1,opt,name=title,proto3" json:"title,omitempty"` Description string `protobuf:"bytes,2,opt,name=description,proto3" json:"description,omitempty"` diff --git a/x/govshuttle/types/proposal.go b/x/govshuttle/types/proposal.go index 93bd05b74..1aeaec250 100644 --- a/x/govshuttle/types/proposal.go +++ b/x/govshuttle/types/proposal.go @@ -105,3 +105,22 @@ func (tp *TreasuryProposal) FromTreasuryToLendingMarket() *LendingMarketProposal Metadata: &lm, } } + +func (tp *MsgTreasuryProposal) FromTreasuryToLendingMarket() *MsgLendingMarketProposal { + m := tp.GetMetadata() + + lm := LendingMarketMetadata{ + Account: []string{m.GetRecipient()}, + PropId: m.GetPropID(), + Values: []uint64{m.GetAmount()}, + Calldatas: nil, + Signatures: []string{m.GetDenom()}, + } + + return &MsgLendingMarketProposal{ + Authority: tp.GetAuthority(), + Title: tp.GetTitle(), + Description: tp.GetDescription(), + Metadata: &lm, + } +}